Merge pull request #8615 from Ghommie/Ghommie-cit45

Virtual reality componentization.
This commit is contained in:
kevinz000
2019-10-10 02:09:51 -07:00
committed by GitHub
58 changed files with 1013 additions and 910 deletions
+8
View File
@@ -121,8 +121,13 @@
#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
// /mind signals
#define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to(): (new_character, old_character)
// /mob signals
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize() (can_reenter_corpse)
#define COMPONENT_BLOCK_GHOSTING 1
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources)
#define COMPONENT_BLOCK_MAGIC 1
@@ -132,6 +137,7 @@
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey()
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list)
#define COMPONENT_UPPERCASE_SPEECH 1
@@ -159,6 +165,8 @@
#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag)
#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
// /machinery signals
#define COMSIG_MACHINE_EJECT_OCCUPANT "eject_occupant" //from base of obj/machinery/dropContents() (occupant)
// /obj/item signals
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
+1 -1
View File
@@ -511,7 +511,7 @@
G_found.client.prefs.copy_to(new_character)
new_character.dna.update_dna_identity()
new_character.key = G_found.key
G_found.transfer_ckey(new_character, FALSE)
return new_character
+1 -1
View File
@@ -46,7 +46,7 @@
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
friend.key = C.key
C.transfer_ckey(friend, FALSE)
friend_initialized = TRUE
else
qdel(src)
@@ -26,7 +26,7 @@
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
stranger_backseat.key = C.key
C.transfer_ckey(stranger_backseat, FALSE)
log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.")
message_admins("[ADMIN_LOOKUPFLW(stranger_backseat)] became [ADMIN_LOOKUPFLW(owner)]'s split personality.")
else
@@ -184,7 +184,7 @@
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s brainwashed mind?", null, null, null, 75, stranger_backseat)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
stranger_backseat.key = C.key
C.transfer_ckey(stranger_backseat, FALSE)
else
qdel(src)
+128
View File
@@ -0,0 +1,128 @@
/datum/component/virtual_reality
dupe_mode = COMPONENT_DUPE_ALLOWED //mindswap memes, shouldn't stack up otherwise.
var/datum/mind/mastermind // where is my mind t. pixies
var/datum/mind/current_mind
var/obj/machinery/vr_sleeper/vr_sleeper
var/datum/action/quit_vr/quit_action
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/component/virtual_reality/inception //The component works on a very fragile link betwixt mind, ckey and death.
/datum/component/virtual_reality/Initialize(mob/M, obj/machinery/vr_sleeper/gaming_pod, yolo = FALSE, new_char = TRUE)
if(!ismob(parent) || !istype(M))
return COMPONENT_INCOMPATIBLE
var/mob/vr_M = parent
mastermind = M.mind
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/switch_player)
RegisterSignal(mastermind, COMSIG_MIND_TRANSFER, .proc/switch_player)
you_die_in_the_game_you_die_for_real = yolo
quit_action = new()
if(gaming_pod)
vr_sleeper = gaming_pod
RegisterSignal(vr_sleeper, COMSIG_ATOM_EMAG_ACT, .proc/you_only_live_once)
RegisterSignal(vr_sleeper, COMSIG_MACHINE_EJECT_OCCUPANT, .proc/revert_to_reality)
vr_M.ckey = M.ckey
var/datum/component/virtual_reality/clusterfk = M.GetComponent(/datum/component/virtual_reality)
if(clusterfk && !clusterfk.inception)
clusterfk.inception = src
SStgui.close_user_uis(M, src)
/datum/component/virtual_reality/RegisterWithParent()
var/mob/M = parent
current_mind = M.mind
quit_action.Grant(M)
RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality)
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter)
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote)
RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote)
mastermind.current.audiovisual_redirect = M
if(vr_sleeper)
vr_sleeper.vr_mob = M
/datum/component/virtual_reality/UnregisterFromParent()
quit_action.Remove(parent)
UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE))
UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER)
UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER)
current_mind = null
mastermind.current.audiovisual_redirect = null
/datum/component/virtual_reality/proc/switch_player(datum/source, mob/new_mob, mob/old_mob)
if(vr_sleeper || !new_mob.mind)
// Machineries currently don't deal up with the occupant being polymorphed et similar... Or did something fuck up?
revert_to_reality()
return
old_mob.audiovisual_redirect = null
new_mob.audiovisual_redirect = parent
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
if(source != quit_action)
return COMPONENT_ACTION_BLOCK_TRIGGER
revert_to_reality(signal_source)
/datum/component/virtual_reality/proc/you_only_live_once()
if(you_die_in_the_game_you_die_for_real || vr_sleeper?.only_current_user_can_interact)
return FALSE
you_die_in_the_game_you_die_for_real = TRUE
return TRUE
/datum/component/virtual_reality/proc/pass_me_the_remote(datum/source, mob/new_mob)
if(new_mob == mastermind.current)
revert_to_reality(source)
return TRUE
new_mob.TakeComponent(src)
return TRUE
/datum/component/virtual_reality/PostTransfer()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/virtual_reality/proc/revert_to_reality(datum/source)
quit_it()
/datum/component/virtual_reality/proc/game_over(datum/source)
quit_it(TRUE, TRUE)
/datum/component/virtual_reality/proc/be_a_quitter(datum/source, can_reenter_corpse)
quit_it()
return COMPONENT_BLOCK_GHOSTING
/datum/component/virtual_reality/proc/virtual_reality_in_a_virtual_reality(mob/player, killme = FALSE, datum/component/virtual_reality/yo_dawg)
var/mob/M = parent
quit_it(FALSE, killme, player, yo_dawg)
yo_dawg.inception = null
if(killme)
M.death(FALSE)
/datum/component/virtual_reality/proc/quit_it(deathcheck = FALSE, cleanup = FALSE, mob/override)
var/mob/M = parent
var/mob/dreamer = override ? override : mastermind.current
if(!mastermind)
to_chat(M, "<span class='warning'>You feel a dreadful sensation, something terrible happened. You try to wake up, but you find yourself unable to...</span>")
else
var/key_transfer = FALSE
if(inception?.parent)
inception.virtual_reality_in_a_virtual_reality(dreamer, cleanup, src)
else
key_transfer = TRUE
if(key_transfer)
M.transfer_ckey(dreamer, FALSE)
dreamer.stop_sound_channel(CHANNEL_HEARTBEAT)
dreamer.audiovisual_redirect = null
if(deathcheck && you_die_in_the_game_you_die_for_real)
to_chat(mastermind, "<span class='warning'>You feel everything fading away...</span>")
dreamer.death(FALSE)
if(cleanup)
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
if(cleanbot)
LAZYADD(cleanbot.corpse_party, M)
if(vr_sleeper)
vr_sleeper.vr_mob = null
vr_sleeper = null
qdel(src)
/datum/component/virtual_reality/Destroy()
var/datum/action/quit_vr/delet_me = quit_action
. = ..()
qdel(delet_me)
+2 -2
View File
@@ -67,7 +67,7 @@
if(affected_mob.mind)
affected_mob.mind.transfer_to(new_mob)
else
new_mob.key = affected_mob.key
affected_mob.transfer_ckey(new_mob)
new_mob.name = affected_mob.real_name
new_mob.real_name = new_mob.name
@@ -82,7 +82,7 @@
to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.")
affected_mob.ghostize(0)
affected_mob.key = C.key
C.transfer_ckey(affected_mob)
else
to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!")
new_mob.death()
+5 -3
View File
@@ -19,9 +19,9 @@
- IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you.
- When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting
a ghost to become a xeno during an event). Simply assign the key or ckey like you've always done.
a ghost to become a xeno during an event), use this mob proc.
new_mob.key = key
mob.transfer_ckey(new_mob)
The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple!
However if you want that mind to have any special properties like being a traitor etc you will have to do that
@@ -89,6 +89,7 @@
return language_holder
/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0)
var/old_character = current
if(current) // remove ourself from our old body's mind variable
current.mind = null
SStgui.on_transfer(current, new_character)
@@ -99,7 +100,7 @@
if(key)
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
new_character.ghostize(TRUE, TRUE) //we'll need to ghostize so that key isn't mobless.
else
key = new_character.key
@@ -123,6 +124,7 @@
transfer_martial_arts(new_character)
if(active || force_key_move)
new_character.key = key //now transfer the key to link the client to our new body
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
//CIT CHANGE - makes arousal update when transfering bodies
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
@@ -8,7 +8,7 @@
ruletype = "Midround"
/// If the ruleset should be restricted from ghost roles.
var/restrict_ghost_roles = TRUE
/// What type the ruleset is restricted to.
/// What type the ruleset is restricted to.
var/required_type = /mob/living/carbon/human
var/list/living_players = list()
var/list/living_antags = list()
@@ -101,7 +101,7 @@
log_game("DYNAMIC: Polling [possible_volunteers.len] players to apply for the [name] ruleset.")
candidates = pollGhostCandidates("The mode is looking for volunteers to become [antag_flag] for [name]", antag_flag, SSticker.mode, antag_flag, poll_time = 300)
if(!candidates || candidates.len <= 0)
message_admins("The ruleset [name] received no applications.")
log_game("DYNAMIC: The ruleset [name] received no applications.")
@@ -194,7 +194,7 @@
..()
for(var/mob/living/player in living_players)
if(issilicon(player)) // Your assigned role doesn't change when you are turned into a silicon.
living_players -= player
living_players -= player
continue
if(is_centcom_level(player.z))
living_players -= player // We don't autotator people in CentCom
@@ -407,7 +407,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/generate_ruleset_body(mob/applicant)
var/obj/vent = pick_n_take(vents)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = applicant.key
applicant.transfer_ckey(new_xeno, FALSE)
message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by the midround ruleset.")
log_game("DYNAMIC: [key_name(new_xeno)] was spawned as an alien by the midround ruleset.")
return new_xeno
+2
View File
@@ -186,6 +186,7 @@ Class Procs:
if(isliving(A))
var/mob/living/L = A
L.update_canmove()
SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant)
occupant = null
/obj/machinery/proc/can_be_occupant(atom/movable/am)
@@ -498,6 +499,7 @@ Class Procs:
/obj/machinery/Exited(atom/movable/AM, atom/newloc)
. = ..()
if (AM == occupant)
SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant)
occupant = null
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
+1 -1
View File
@@ -52,7 +52,7 @@
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
H.key = C.key
C.transfer_ckey(H)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
-61
View File
@@ -1,61 +0,0 @@
/mob/living/carbon/human/virtual_reality
var/datum/mind/real_mind // where is my mind t. pixies
var/obj/machinery/vr_sleeper/vr_sleeper
var/datum/action/quit_vr/quit_action
/mob/living/carbon/human/virtual_reality/Initialize()
. = ..()
quit_action = new()
quit_action.Grant(src)
/mob/living/carbon/human/virtual_reality/death()
revert_to_reality()
..()
/mob/living/carbon/human/virtual_reality/Destroy()
revert_to_reality()
return ..()
/mob/living/carbon/human/virtual_reality/Life()
. = ..()
if(real_mind)
var/mob/living/real_me = real_mind.current
if (real_me && real_me.stat == CONSCIOUS)
return
revert_to_reality(FALSE)
/mob/living/carbon/human/virtual_reality/ghostize()
stack_trace("Ghostize was called on a virtual reality mob")
/mob/living/carbon/human/virtual_reality/ghost()
set category = "OOC"
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
revert_to_reality(FALSE)
/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(deathchecks = TRUE)
if(real_mind && mind)
real_mind.current.audiovisual_redirect = null
real_mind.current.ckey = ckey
real_mind.current.stop_sound_channel(CHANNEL_HEARTBEAT)
if(deathchecks && vr_sleeper)
if(vr_sleeper.you_die_in_the_game_you_die_for_real)
to_chat(real_mind, "<span class='warning'>You feel everything fading away...</span>")
real_mind.current.death(0)
if(deathchecks && vr_sleeper)
vr_sleeper.vr_human = null
vr_sleeper = null
real_mind = null
/datum/action/quit_vr
name = "Quit Virtual Reality"
icon_icon = 'icons/mob/actions/actions_vr.dmi'
button_icon_state = "logout"
/datum/action/quit_vr/Trigger()
if(..())
if(istype(owner, /mob/living/carbon/human/virtual_reality))
var/mob/living/carbon/human/virtual_reality/VR = owner
VR.revert_to_reality(FALSE)
else
Remove(owner)
+44
View File
@@ -0,0 +1,44 @@
/mob/proc/build_virtual_character(mob/M)
mind_initialize()
if(!M)
return FALSE
name = M.name
real_name = M.real_name
mind.name = M.real_name
return TRUE
/mob/living/carbon/build_virtual_character(mob/M)
. = ..()
if(!.)
return
if(iscarbon(M))
var/mob/living/carbon/C = M
C.dna?.transfer_identity(src)
/mob/living/carbon/human/build_virtual_character(mob/M, datum/outfit/outfit)
. = ..()
if(!.)
return
var/mob/living/carbon/human/H
if(ishuman(M))
H = M
socks = H ? H.socks : random_socks()
socks_color = H ? H.socks_color : random_color()
undershirt = H ? H.undershirt : random_undershirt(M.gender)
shirt_color = H ? H.shirt_color : random_color()
underwear = H ? H.underwear : random_underwear(M.gender)
undie_color = H ? H.undie_color : random_color()
give_genitals(TRUE)
if(outfit)
var/datum/outfit/O = new outfit()
O.equip(src)
/datum/action/quit_vr
name = "Quit Virtual Reality"
icon_icon = 'icons/mob/actions/actions_vr.dmi'
button_icon_state = "logout"
/datum/action/quit_vr/Trigger() //this merely a trigger for /datum/component/virtual_reality
. = ..()
if(!.)
Remove(owner)
+56 -69
View File
@@ -1,5 +1,3 @@
//Glorified teleporter that puts you in a new human body.
// it's """VR"""
/obj/machinery/vr_sleeper
@@ -12,9 +10,10 @@
circuit = /obj/item/circuitboard/machine/vr_sleeper
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/effect_system/spark_spread/sparks
var/mob/living/carbon/human/virtual_reality/vr_human
var/mob/living/vr_mob
var/virtual_mob_type = /mob/living/carbon/human
var/vr_category = "default" //Specific category of spawn points to pick from
var/allow_creating_vr_humans = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/allow_creating_vr_mobs = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/only_current_user_can_interact = FALSE
/obj/machinery/vr_sleeper/Initialize()
@@ -44,7 +43,7 @@
/obj/machinery/vr_sleeper/Destroy()
open_machine()
cleanup_vr_human()
cleanup_vr_mob()
QDEL_NULL(sparks)
return ..()
@@ -58,8 +57,9 @@
/obj/machinery/vr_sleeper/emag_act(mob/user)
. = ..()
if(you_die_in_the_game_you_die_for_real)
if(!(obj_flags & EMAGGED))
return
obj_flags |= EMAGGED
you_die_in_the_game_you_die_for_real = TRUE
sparks.start()
addtimer(CALLBACK(src, .proc/emagNotify), 150)
@@ -69,12 +69,11 @@
icon_state = "[initial(icon_state)][state_open ? "-open" : ""]"
/obj/machinery/vr_sleeper/open_machine()
if(!state_open)
if(vr_human)
vr_human.revert_to_reality(FALSE)
if(occupant)
SStgui.close_user_uis(occupant, src)
..()
if(state_open)
return
if(occupant)
SStgui.close_user_uis(occupant, src)
return ..()
/obj/machinery/vr_sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
@@ -94,22 +93,20 @@
if("vr_connect")
var/mob/living/carbon/human/human_occupant = occupant
if(human_occupant && human_occupant.mind && usr == occupant)
to_chat(occupant, "<span class='warning'>Transferring to virtual reality...</span>")
if(vr_human && vr_human.stat == CONSCIOUS && !vr_human.real_mind)
SStgui.close_user_uis(occupant, src)
human_occupant.audiovisual_redirect = vr_human
vr_human.real_mind = human_occupant.mind
vr_human.ckey = human_occupant.ckey
to_chat(vr_human, "<span class='notice'>Transfer successful! You are now playing as [vr_human] in VR!</span>")
if(vr_mob && (!istype(vr_mob) || !vr_mob.InCritical()) && !vr_mob.GetComponent(/datum/component/virtual_reality))
vr_mob.AddComponent(/datum/component/virtual_reality, human_occupant, src, you_die_in_the_game_you_die_for_real)
to_chat(vr_mob, "<span class='notice'>Transfer successful! You are now playing as [vr_mob] in VR!</span>")
else
if(allow_creating_vr_humans)
if(allow_creating_vr_mobs)
to_chat(occupant, "<span class='warning'>Virtual avatar not found, attempting to create one...</span>")
var/obj/effect/landmark/vr_spawn/V = get_vr_spawnpoint()
var/turf/T = get_turf(V)
if(T)
SStgui.close_user_uis(occupant, src)
build_virtual_human(occupant, T, V.vr_outfit)
to_chat(vr_human, "<span class='notice'>Transfer successful! You are now playing as [vr_human] in VR!</span>")
new_player(occupant, T, V.vr_outfit)
to_chat(vr_mob, "<span class='notice'>Transfer successful! You are now playing as [vr_mob] in VR!</span>")
else
to_chat(occupant, "<span class='warning'>Virtual world misconfigured, aborting transfer</span>")
else
@@ -117,8 +114,8 @@
. = TRUE
if("delete_avatar")
if(!occupant || usr == occupant)
if(vr_human)
cleanup_vr_human()
if(vr_mob)
cleanup_vr_mob()
else
to_chat(usr, "<span class='warning'>The VR Sleeper's safeties prevent you from doing that.</span>")
. = TRUE
@@ -131,19 +128,22 @@
/obj/machinery/vr_sleeper/ui_data(mob/user)
var/list/data = list()
if(vr_human && !QDELETED(vr_human))
if(vr_mob && !QDELETED(vr_mob))
data["can_delete_avatar"] = TRUE
var/status
switch(vr_human.stat)
if(CONSCIOUS)
status = "Conscious"
if(DEAD)
status = "Dead"
if(UNCONSCIOUS)
status = "Unconscious"
if(SOFT_CRIT)
status = "Barely Conscious"
data["vr_avatar"] = list("name" = vr_human.name, "status" = status, "health" = vr_human.health, "maxhealth" = vr_human.maxHealth)
data["vr_avatar"] = list("name" = vr_mob.name)
data["isliving"] = istype(vr_mob)
if(data["isliving"])
var/status
switch(vr_mob.stat)
if(CONSCIOUS)
status = "Conscious"
if(DEAD)
status = "Dead"
if(UNCONSCIOUS)
status = "Unconscious"
if(SOFT_CRIT)
status = "Barely Conscious"
data["vr_avatar"] += list("status" = status, "health" = vr_mob.health, "maxhealth" = vr_mob.maxHealth)
data["toggle_open"] = state_open
data["emagged"] = you_die_in_the_game_you_die_for_real
data["isoccupant"] = (user == occupant)
@@ -157,40 +157,25 @@
for(var/obj/effect/landmark/vr_spawn/V in GLOB.landmarks_list)
GLOB.vr_spawnpoints[V.vr_category] = V
/obj/machinery/vr_sleeper/proc/build_virtual_human(mob/living/carbon/human/H, location, var/datum/outfit/outfit, transfer = TRUE)
if(H)
cleanup_vr_human()
vr_human = new /mob/living/carbon/human/virtual_reality(location)
vr_human.mind_initialize()
vr_human.vr_sleeper = src
vr_human.real_mind = H.mind
H.dna.transfer_identity(vr_human)
vr_human.name = H.name
vr_human.real_name = H.real_name
vr_human.socks = H.socks
vr_human.socks_color = H.socks_color
vr_human.undershirt = H.undershirt
vr_human.shirt_color = H.shirt_color
vr_human.underwear = H.underwear
vr_human.undie_color = H.undie_color
vr_human.updateappearance(TRUE, TRUE, TRUE)
vr_human.give_genitals(TRUE) //CITADEL ADD
if(outfit)
var/datum/outfit/O = new outfit()
O.equip(vr_human)
if(transfer && H.mind)
SStgui.close_user_uis(H, src)
H.audiovisual_redirect = vr_human
vr_human.ckey = H.ckey
/obj/machinery/vr_sleeper/proc/new_player(mob/living/carbon/human/H, location, datum/outfit/outfit, transfer = TRUE)
if(!H)
return
cleanup_vr_mob()
vr_mob = new virtual_mob_type(location)
if(vr_mob.build_virtual_character(H, outfit))
var/mob/living/carbon/human/vr_H = vr_mob
vr_H.updateappearance(TRUE, TRUE, TRUE)
if(!transfer || !H.mind)
return
vr_mob.AddComponent(/datum/component/virtual_reality, H, src, you_die_in_the_game_you_die_for_real)
/obj/machinery/vr_sleeper/proc/cleanup_vr_human()
if(vr_human)
vr_human.vr_sleeper = null // Prevents race condition where a new human could get created out of order and set to null.
QDEL_NULL(vr_human)
/obj/machinery/vr_sleeper/proc/cleanup_vr_mob()
if(vr_mob)
QDEL_NULL(vr_mob)
/obj/machinery/vr_sleeper/proc/emagNotify()
if(vr_human)
vr_human.Dizzy(10)
if(vr_mob)
vr_mob.Dizzy(10)
/obj/effect/landmark/vr_spawn //places you can spawn in VR, auto selected by the vr_sleeper during get_vr_spawnpoint()
var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc.
@@ -222,6 +207,7 @@
color = "#00FF00"
invisibility = INVISIBILITY_ABSTRACT
var/area/vr_area
var/list/corpse_party
/obj/effect/vr_clean_master/Initialize()
. = ..()
@@ -234,7 +220,8 @@
qdel(casing)
for(var/obj/effect/decal/cleanable/C in vr_area)
qdel(C)
for (var/mob/living/carbon/human/virtual_reality/H in vr_area)
if (H.stat == DEAD && !H.vr_sleeper && !H.real_mind)
qdel(H)
for (var/A in corpse_party)
var/mob/M = A
if(get_area(M) == vr_area && M.stat == DEAD)
qdel(M)
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
+1 -1
View File
@@ -61,7 +61,7 @@
to_chat(body, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(body)])")
body.ghostize(0)
body.key = C.key
C.transfer_ckey(body)
new /obj/effect/temp_visual/gravpush(get_turf(body))
/obj/effect/fun_balloon/sentience/emergency_shuttle
+1 -1
View File
@@ -744,7 +744,7 @@
var/mob/chosen = players[1]
if (chosen.client)
chosen.client.prefs.copy_to(spawnedMob)
spawnedMob.key = chosen.key
chosen.transfer_ckey(spawnedMob)
players -= chosen
if (ishuman(spawnedMob) && ispath(humanoutfit, /datum/outfit))
var/mob/living/carbon/human/H = spawnedMob
+1 -1
View File
@@ -306,7 +306,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/mob/living/silicon/pai/pai = new(card)
pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
pai.real_name = pai.name
pai.key = choice.key
choice.transfer_ckey(pai)
card.setPersonality(pai)
for(var/datum/paiCandidate/candidate in SSpai.candidates)
if(candidate.key == choice.key)
+1 -1
View File
@@ -412,7 +412,7 @@
//Spawn the body
var/mob/living/carbon/human/ERTOperative = new ertemplate.mobtype(spawnloc)
chosen_candidate.client.prefs.copy_to(ERTOperative)
ERTOperative.key = chosen_candidate.key
chosen_candidate.transfer_ckey(ERTOperative)
if(ertemplate.enforce_human || ERTOperative.dna.species.dangerous_existence) // Don't want any exploding plasmemes
ERTOperative.set_species(/datum/species/human)
+3 -3
View File
@@ -384,7 +384,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
//Now to give them their mind back.
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_xeno.key = G_found.key
G_found.transfer_ckey(new_xeno, FALSE)
to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.</span>"
message_admins(msg)
@@ -397,7 +397,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/mob/living/carbon/monkey/new_monkey = new
SSjob.SendToLateJoin(new_monkey)
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_monkey.key = G_found.key
G_found.transfer_ckey(new_monkey, FALSE)
to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.</span>"
message_admins(msg)
@@ -437,7 +437,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!new_character.mind.assigned_role)
new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
new_character.key = G_found.key
G_found.transfer_ckey(new_character, FALSE)
/*
The code below functions with the assumption that the mob is already a traitor if they have a special role.
@@ -15,7 +15,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/antag_memory = ""//These will be removed with antag datum
var/antag_moodlet //typepath of moodlet that the mob will gain with their status
var/can_hijack = HIJACK_NEUTRAL //If these antags are alone on shuttle hijack happens.
//Antag panel properties
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
@@ -87,7 +87,7 @@ GLOBAL_LIST_EMPTY(antagonists)
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
owner.current.ghostize(0)
owner.current.key = C.key
C.transfer_ckey(owner.current, FALSE)
/datum/antagonist/proc/on_removal()
remove_innate_effects()
+1 -1
View File
@@ -172,7 +172,7 @@
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/mob/dead/observer/C = pick(candidates)
blobber.key = C.key
C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
to_chat(blobber, "<b>You are a blobbernaut!</b>")
@@ -349,7 +349,7 @@
to_chat(L, "<span class='userdanger'>Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.")
L.ghostize(0)
L.key = C.key
C.transfer_ckey(L, FALSE)
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
@@ -55,7 +55,7 @@
pre_spawn()
visible_message(creation_message)
var/mob/living/construct = new construct_type(get_turf(src))
construct.key = user.key
user.transfer_ckey(construct, FALSE)
post_spawn(construct)
qdel(user)
qdel(src)
@@ -64,7 +64,7 @@
message_admins("<span class='danger'>Admin [key_name_admin(user)] directly became the Eminence of the cult!</span>")
log_admin("Admin [key_name(user)] made themselves the Eminence.")
var/mob/camera/eminence/eminence = new(get_turf(src))
eminence.key = user.key
user.transfer_ckey(eminence, FALSE)
hierophant_message("<span class='bold large_brass'>Ratvar has directly assigned the Eminence!</span>")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
@@ -138,7 +138,7 @@
playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE)
var/mob/camera/eminence/eminence = new(get_turf(src))
eminence_nominee = pick(candidates)
eminence.key = eminence_nominee.key
eminence_nominee.transfer_ckey(eminence)
hierophant_message("<span class='bold large_brass'>A ghost has ascended into the Eminence!</span>")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
@@ -45,7 +45,7 @@
return FALSE
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
R.key = O.key
O.transfer_ckey(R, FALSE)
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
+2 -2
View File
@@ -575,7 +575,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.")
mob_to_revive.ghostize(0)
mob_to_revive.key = C.key
C.transfer_ckey(mob_to_revive, FALSE)
else
fail_invoke()
return
@@ -870,7 +870,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("<span class='warning'>A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.</span>")
to_chat(user, "<span class='cultitalic'>Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...</span>")
var/obj/structure/emergency_shield/invoker/N = new(T)
new_human.key = ghost_to_spawn.key
ghost_to_spawn.transfer_ckey(new_human, FALSE)
SSticker.mode.add_cultist(new_human.mind, 0)
to_chat(new_human, "<span class='cultitalic'><b>You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.</b></span>")
@@ -146,7 +146,7 @@
/mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob)
if(ascended || user.mind.soulOwner == src.mind)
var/mob/living/simple_animal/imp/S = new(get_turf(loc))
S.key = user.key
user.transfer_ckey(S, FALSE)
S.mind.assigned_role = "Imp"
S.mind.special_role = "Imp"
var/datum/objective/newobjective = new
@@ -18,7 +18,7 @@
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
virus.key = selected.key
selected.transfer_ckey(virus, FALSE)
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by an event.")
log_game("[key_name(virus)] was spawned as a sentient disease by an event.")
@@ -377,14 +377,15 @@
/obj/item/ectoplasm/revenant/proc/reform()
if(QDELETED(src) || QDELETED(revenant) || inert)
return
var/key_of_revenant
var/key_of_revenant = FALSE
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
forceMove(drop_location()) //In case it's in a backpack or someone's hand
revenant.forceMove(loc)
if(old_key)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
key_of_revenant = old_key
M.transfer_ckey(revenant.key, FALSE)
key_of_revenant = TRUE
break
if(!key_of_revenant)
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
@@ -396,22 +397,21 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/mob/dead/observer/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
C.transfer_ckey(revenant.key, FALSE)
if(!revenant.key)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = TRUE
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
message_admins("[key_of_revenant] has been [old_key == key_of_revenant ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == key_of_revenant ? "re":""]made as a revenant by reforming ectoplasm.")
message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
revenant.essence = essence
revenant.essence_regen_cap = essence
revenant.death_reset()
revenant.key = key_of_revenant
revenant = null
qdel(src)
@@ -52,7 +52,7 @@
return MAP_ERROR
var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs))
revvie.key = selected.key
selected.transfer_ckey(revvie, FALSE)
message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by an event.")
log_game("[key_name(revvie)] was spawned as a revenant by an event.")
spawned_mobs += revvie
@@ -218,7 +218,7 @@
newstruct.master = stoner
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
newstruct.key = target.key
target.transfer_ckey(newstruct)
var/obj/screen/alert/bloodsense/BS
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
@@ -243,7 +243,7 @@
S.canmove = FALSE//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.key = T.key
T.transfer_ckey(S)
S.language_holder = U.language_holder.copy(S)
if(U)
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
@@ -133,7 +133,7 @@
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Wizard Academy Defender")
current_wizard.ghostize() // on the off chance braindead defender gets back in
current_wizard.key = C.key
C.transfer_ckey(current_wizard, FALSE)
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
var/turf/T = src.loc
@@ -272,7 +272,7 @@
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
H.key = C.key
C.transfer_ckey(H, FALSE)
var/obj/effect/proc_holder/spell/targeted/summonmob/S = new
S.target_mob = H
+1 -1
View File
@@ -77,7 +77,7 @@
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
santa.key = C.key
C.transfer_ckey(santa, FALSE)
santa.equipOutfit(/datum/outfit/santa)
santa.update_icons()
+1 -1
View File
@@ -48,7 +48,7 @@
spawned_animals++
SA.key = SG.key
SG.transfer_ckey(SA, FALSE)
SA.grant_all_languages(TRUE)
+1 -1
View File
@@ -23,7 +23,7 @@
I.name = I.dna.real_name
I.updateappearance(mutcolor_update=1)
I.domutcheck()
I.key = C.key
C.transfer_ckey(I, FALSE)
var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
if(!master.wiz_team)
master.create_wiz_team()
File diff suppressed because it is too large Load Diff
+18 -12
View File
@@ -260,16 +260,16 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above.
*/
/mob/proc/ghostize(can_reenter_corpse = 1)
if(key)
if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
ghost.key = key
return ghost
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE)
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
transfer_ckey(ghost, FALSE)
return ghost
/*
This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues.
@@ -280,6 +280,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
// CITADEL EDIT
if(istype(loc, /obj/machinery/cryopod))
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
@@ -306,6 +309,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
@@ -348,7 +354,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
client.change_view(CONFIG_GET(string/default_view))
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
mind.current.key = key
transfer_ckey(mind.current, FALSE)
return 1
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
@@ -628,7 +634,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>Someone has taken this body while you were choosing!</span>")
return 0
target.key = key
transfer_ckey(target, FALSE)
target.faction = list("neutral")
return 1
+1 -1
View File
@@ -42,7 +42,7 @@
if(brainmob.mind)
brainmob.mind.transfer_to(C)
else
C.key = brainmob.key
brainmob.transfer_ckey(C)
QDEL_NULL(brainmob)
@@ -87,7 +87,7 @@
var/atom/xeno_loc = get_turf(owner)
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
new_xeno.key = ghost.key
ghost.transfer_ckey(new_xeno, FALSE)
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
new_xeno.canmove = 0 //so we don't move during the bursting animation
new_xeno.notransform = 1
+1 -1
View File
@@ -912,7 +912,7 @@
if(mind)
mind.transfer_to(new_mob)
else
new_mob.key = key
transfer_ckey(new_mob)
for(var/para in hasparasites())
var/mob/living/simple_animal/hostile/guardian/G = para
+1 -1
View File
@@ -192,7 +192,7 @@
/mob/proc/makePAI(delold)
var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src))
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
pai.key = key
transfer_ckey(pai)
pai.name = name
card.setPersonality(pai)
if(delold)
@@ -915,7 +915,7 @@ Pass a positive integer as an argument to override a bot's default speed.
if(mind && paicard.pai)
mind.transfer_to(paicard.pai)
else if(paicard.pai)
paicard.pai.key = key
transfer_ckey(paicard.pai)
else
ghostize(0) // The pAI card that just got ejected was dead.
key = null
@@ -160,7 +160,7 @@
if(mind)
mind.transfer_to(R, 1)
else
R.key = key
transfer_ckey(R)
qdel(src)
@@ -61,5 +61,5 @@
var/obj/item/new_hat = new hat_type(D)
D.equip_to_slot_or_del(new_hat, SLOT_HEAD)
D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
D.key = user.key
user.transfer_ckey(D, FALSE)
qdel(src)
@@ -429,9 +429,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
G.ghostize(0)
G.ghostize(FALSE)
G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person
G.key = C.key
C.transfer_ckey(G)
G.reset = 1
switch(G.namedatum.theme)
if("tech")
@@ -90,7 +90,7 @@
if(key)
to_chat(user, "<span class='notice'>Someone else already took this spider.</span>")
return 1
key = user.key
user.transfer_ckey(src, FALSE)
return 1
//nursemaids - these create webs and eggs
@@ -585,7 +585,7 @@ Difficulty: Very Hard
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_helper == "Yes" && !QDELETED(src) && isobserver(user))
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
W.key = user.key
user.transfer_ckey(W, FALSE)
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
@@ -649,7 +649,7 @@ Difficulty: Very Hard
L.heal_overall_damage(heal_power, heal_power)
new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF")
/mob/living/simple_animal/hostile/lightgeist/ghostize()
/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, send_the_signal = TRUE)
. = ..()
if(.)
death()
@@ -916,7 +916,7 @@
if(mind)
mind.transfer_to(G)
else
G.key = key
transfer_ckey(G)
..(gibbed)
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
@@ -198,7 +198,7 @@
if(src.mind)
src.mind.transfer_to(new_slime)
else
new_slime.key = src.key
transfer_ckey(new_slime)
qdel(src)
else
to_chat(src, "<i>I am not ready to reproduce yet...</i>")
+7 -1
View File
@@ -444,7 +444,13 @@
// M.Login() //wat
return
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
if(!ckey)
return FALSE
if(send_signal)
SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
new_mob.ckey = ckey
return TRUE
/mob/verb/cancel_camera()
set name = "Cancel Camera View"
+2 -2
View File
@@ -429,8 +429,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
var/mob/dead/observer/C = pick(candidates)
to_chat(M, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(M)])")
M.ghostize(0)
M.key = C.key
M.ghostize(FALSE, TRUE)
C.transfer_ckey(M, FALSE)
return TRUE
else
to_chat(M, "There were no ghosts willing to take control.")
@@ -53,7 +53,7 @@
if(mind && isliving(M))
mind.transfer_to(M, 1) // second argument to force key move to new mob
else
M.key = key
transfer_ckey(M)
if(delete_old_mob)
QDEL_IN(src, 1)
+44 -66
View File
@@ -382,7 +382,7 @@
mind.active = FALSE
mind.transfer_to(R)
else if(transfer_after)
R.key = key
transfer_ckey(R)
R.apply_pref_name("cyborg")
@@ -401,7 +401,7 @@
qdel(src)
//human -> alien
/mob/living/carbon/human/proc/Alienize()
/mob/living/carbon/human/proc/Alienize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -425,13 +425,16 @@
new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
new_xeno.a_intent = INTENT_HARM
new_xeno.key = key
if(mind && mind_transfer)
mind.transfer_to(new_xeno)
else
transfer_ckey(new_xeno)
to_chat(new_xeno, "<B>You are now an alien.</B>")
. = new_xeno
qdel(src)
/mob/living/carbon/human/proc/slimeize(reproduce as num)
/mob/living/carbon/human/proc/slimeize(reproduce, mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -457,20 +460,26 @@
else
new_slime = new /mob/living/simple_animal/slime(loc)
new_slime.a_intent = INTENT_HARM
new_slime.key = key
if(mind && mind_transfer)
mind.transfer_to(new_slime)
else
transfer_ckey(new_slime)
to_chat(new_slime, "<B>You are now a slime. Skreee!</B>")
. = new_slime
qdel(src)
/mob/proc/become_overmind(starting_points = 60)
/mob/proc/become_overmind(starting_points = 60, mind_transfer = FALSE)
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
B.key = key
if(mind && mind_transfer)
mind.transfer_to(B)
else
transfer_ckey(B)
. = B
qdel(src)
/mob/living/carbon/human/proc/corgize()
/mob/living/carbon/human/proc/corgize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -485,13 +494,16 @@
var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc)
new_corgi.a_intent = INTENT_HARM
new_corgi.key = key
if(mind && mind_transfer)
mind.transfer_to(new_corgi)
else
transfer_ckey(new_corgi)
to_chat(new_corgi, "<B>You are now a Corgi. Yap Yap!</B>")
. = new_corgi
qdel(src)
/mob/living/carbon/proc/gorillize()
/mob/living/carbon/proc/gorillize(mind_transfer = TRUE)
if(notransform)
return
@@ -509,22 +521,22 @@
invisibility = INVISIBILITY_MAXIMUM
var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src))
new_gorilla.a_intent = INTENT_HARM
if(mind)
if(mind && mind_transfer)
mind.transfer_to(new_gorilla)
else
new_gorilla.key = key
transfer_ckey(new_gorilla)
to_chat(new_gorilla, "<B>You are now a gorilla. Ooga ooga!</B>")
. = new_gorilla
qdel(src)
/mob/living/carbon/human/Animalize()
/mob/living/carbon/human/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
if(!safe_animal(mobpath))
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
if(!mobpath)
return
if(mind)
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
if(notransform)
return
@@ -532,8 +544,8 @@
dropItemToGround(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
canmove = FALSE
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -541,8 +553,10 @@
qdel(t)
var/mob/new_mob = new mobpath(src.loc)
new_mob.key = key
if(mind && mind_transfer)
mind.transfer_to(new_mob)
else
transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
@@ -550,59 +564,23 @@
. = new_mob
qdel(src)
/mob/proc/Animalize()
/mob/proc/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
if(!safe_animal(mobpath))
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
if(!mobpath)
return
if(mind)
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
var/mob/new_mob = new mobpath(src.loc)
new_mob.key = key
if(mind && mind_transfer)
mind.transfer_to(new_mob)
else
transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
to_chat(new_mob, "You feel more... animalistic")
. = new_mob
qdel(src)
/* Certain mob types have problems and should not be allowed to be controlled by players.
*
* This proc is here to force coders to manually place their mob in this list, hopefully tested.
* This also gives a place to explain -why- players shouldnt be turn into certain mobs and hopefully someone can fix them.
*/
/mob/proc/safe_animal(MP)
//Bad mobs! - Remember to add a comment explaining what's wrong with the mob
if(!MP)
return 0 //Sanity, this should never happen.
if(ispath(MP, /mob/living/simple_animal/hostile/construct))
return 0 //Verbs do not appear for players.
//Good mobs!
if(ispath(MP, /mob/living/simple_animal/pet/cat))
return 1
if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi))
return 1
if(ispath(MP, /mob/living/simple_animal/crab))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/carp))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/mushroom))
return 1
if(ispath(MP, /mob/living/simple_animal/shade))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/killertomato))
return 1
if(ispath(MP, /mob/living/simple_animal/mouse))
return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak)
if(ispath(MP, /mob/living/simple_animal/hostile/bear))
return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak)
if(ispath(MP, /mob/living/simple_animal/parrot))
return 1 //Parrots are no longer unfinished! -Nodrak
//Not in here? Must be untested!
return 0
@@ -681,7 +681,7 @@
var/list/candidates = pollCandidatesForMob("Do you want to play as [SM.name]?", ROLE_SENTIENCE, null, ROLE_SENTIENCE, 50, SM, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
SM.key = C.key
C.transfer_ckey(SM, FALSE)
SM.mind.enslave_mind_to_creator(user)
SM.sentience_act()
to_chat(SM, "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>")
@@ -70,12 +70,12 @@ Also, you never added distance checking after target is selected. I've went ahea
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize(0)
var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
caster.key = ghost.key //have to transfer the key since the mind was not active
ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
@@ -38,7 +38,7 @@
return
to_chat(user, "<span class='notice'>You decide to wake up the banana spider...</span>")
awakening = 1
spawn(30)
if(!QDELETED(src))
var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc))
@@ -98,7 +98,7 @@
if(be_spider == "No" || QDELETED(src) || !isobserver(user))
return
sentience_act()
key = user.key
user.transfer_ckey(src, FALSE)
density = TRUE
/mob/living/simple_animal/banana_spider/ComponentInitialize()
@@ -86,7 +86,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
candies = shuffle(candies)//Shake those ghosts up!
for(var/mob/dead/observer/C2 in candies)
if(C2.key && C2)
SM.key = C2.key
C2.transfer_ckey(SM, FALSE)
message_admins("Ghost candidate found! [C2] key [C2.key] is becoming a clone of [M] key: [M.key] (They agreed to respect the character they're becoming, and agreed to not ERP without express permission from the original.)")
log_game("FERMICHEM: [M] ckey: [M.key] is creating a clone, controlled by [C2]")
break
+2 -1
View File
@@ -382,6 +382,7 @@
#include "code\datums\components\swarming.dm"
#include "code\datums\components\thermite.dm"
#include "code\datums\components\uplink.dm"
#include "code\datums\components\virtual_reality.dm"
#include "code\datums\components\wearertargeting.dm"
#include "code\datums\components\wet_floor.dm"
#include "code\datums\components\decals\blood.dm"
@@ -2884,7 +2885,7 @@
#include "code\modules\vending\toys.dm"
#include "code\modules\vending\wardrobes.dm"
#include "code\modules\vending\youtool.dm"
#include "code\modules\VR\vr_human.dm"
#include "code\modules\VR\vr_mob.dm"
#include "code\modules\VR\vr_sleeper.dm"
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
+8 -6
View File
@@ -22,12 +22,14 @@
<ui-section label='Name'>
{{data.vr_avatar.name}}
</ui-section>
<ui-section label='Status'>
{{data.vr_avatar.status}}
</ui-section>
<ui-section label='Health'>
<ui-bar min='0' max='{{adata.vr_avatar.maxhealth}}' value='{{adata.vr_avatar.health}}' state='{{healthState(adata.vr_avatar.health)}}'>{{Math.round(adata.vr_avatar.health)}}/{{adata.vr_avatar.maxhealth}}</ui-bar>
</ui-section>
{{#if data.isliving}}
<ui-section label='Status'>
{{data.vr_avatar.status}}
</ui-section>
<ui-section label='Health'>
<ui-bar min='0' max='{{adata.vr_avatar.maxhealth}}' value='{{adata.vr_avatar.health}}' state='{{healthState(adata.vr_avatar.health)}}'>{{Math.round(adata.vr_avatar.health)}}/{{adata.vr_avatar.maxhealth}}</ui-bar>
</ui-section>
{{/if}}
</ui-display>
{{else}}
<ui-display title='Virtual Avatar'>