Adds examine messages to disembodied & robot heads (#40999)

cl ShizCalev
tweak: Added some examine messages to disembodied heads indicating if it's missing eyes, or if it's brain is nonfunctional.
tweak: Added some examine messages to cyborg parts to indicate their current construction status.
tweak: You can now remove the power cell and cut the wiring out of a cyborg chest during construction.
/cl

Small indicator to help alleviate some minor wastes of time (such as folks bringing suicider's heads to the roboticist instead of the chef.)

Added some missing destroy handling, fixed vars not being set and unset properly, cleaned up some duplicate code in human/examine handling for departed souls.
This commit is contained in:
ShizCalev
2018-10-27 13:10:55 +13:00
committed by oranges
parent 38fb5d11c4
commit 17d894fcba
8 changed files with 180 additions and 63 deletions
+4 -4
View File
@@ -433,7 +433,7 @@
if(!GLOB.admin_objective_list)
generate_admin_objective_list()
if(old_objective)
if(old_objective.name in GLOB.admin_objective_list)
def_value = old_objective.name
@@ -451,7 +451,7 @@
target_antag.objectives += new_objective
message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]")
log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]")
else
else
if(old_objective.type == selected_type)
//Edit the old
old_objective.admin_edit(usr)
@@ -652,8 +652,8 @@
S.updateButtonIcon()
INVOKE_ASYNC(S, /obj/effect/proc_holder/spell.proc/start_recharge)
/datum/mind/proc/get_ghost(even_if_they_cant_reenter)
for(var/mob/dead/observer/G in GLOB.dead_mob_list)
/datum/mind/proc/get_ghost(even_if_they_cant_reenter, ghosts_with_clients)
for(var/mob/dead/observer/G in (ghosts_with_clients ? GLOB.player_list : GLOB.dead_mob_list))
if(G.mind == src)
if(G.can_reenter_corpse || even_if_they_cant_reenter)
return G
+1 -1
View File
@@ -122,7 +122,7 @@
if(suicided)
to_chat(user, "<span class='info'>It's started turning slightly grey. They must not have been able to handle the stress of it all.</span>")
else if(brainmob)
if(brainmob.client)
if(brainmob.get_ghost(FALSE, TRUE))
if(brain_death || brainmob.health <= HEALTH_THRESHOLD_DEAD)
to_chat(user, "<span class='info'>It's lifeless and severely damaged.</span>")
else if(damaged_brain)
@@ -115,17 +115,8 @@
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
if(getorgan(/obj/item/organ/brain))
if(!key)
var/foundghost = 0
if(mind)
for(var/mob/dead/observer/G in GLOB.player_list)
if(G.mind == mind)
foundghost = 1
if (G.can_reenter_corpse == 0)
foundghost = 0
break
if(!foundghost)
msg += " and [t_his] soul has departed"
if(!key && !get_ghost(FALSE, TRUE))
msg += " and [t_his] soul has departed"
msg += "...</span>\n"
if(get_bodypart(BODY_ZONE_HEAD) && !getorgan(/obj/item/organ/brain))
+2 -2
View File
@@ -664,9 +664,9 @@
/mob/proc/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //For sec bot threat assessment
return 0
/mob/proc/get_ghost(even_if_they_cant_reenter = 0)
/mob/proc/get_ghost(even_if_they_cant_reenter, ghosts_with_clients)
if(mind)
return mind.get_ghost(even_if_they_cant_reenter)
return mind.get_ghost(even_if_they_cant_reenter, ghosts_with_clients)
/mob/proc/grab_ghost(force)
if(mind)
+2 -3
View File
@@ -439,13 +439,12 @@
var/obj/item/cavity_item
/obj/item/bodypart/chest/Destroy()
if(cavity_item)
qdel(cavity_item)
QDEL_NULL(cavity_item)
return ..()
/obj/item/bodypart/chest/drop_organs(mob/user, violent_removal)
if(cavity_item)
cavity_item.forceMove(user.loc)
cavity_item.forceMove(drop_location())
cavity_item = null
..()
@@ -158,6 +158,14 @@
LB.eyes = src
..()
/obj/item/organ/ears/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)
LB.ears = src
..()
/obj/item/organ/tongue/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)
LB.tongue = src
..()
/obj/item/bodypart/chest/drop_limb(special)
if(special)
..()
@@ -312,6 +320,13 @@
brain.Insert(C) //Now insert the brain proper
brain = null //No more brain in the head
if(tongue)
tongue = null
if(ears)
ears = null
if(eyes)
eyes = null
if(ishuman(C))
var/mob/living/carbon/human/H = C
H.hair_color = hair_color
+59 -2
View File
@@ -16,6 +16,9 @@
var/mob/living/brain/brainmob = null //The current occupant.
var/obj/item/organ/brain/brain = null //The brain organ
var/obj/item/organ/eyes/eyes
var/obj/item/organ/ears/ears
var/obj/item/organ/tongue/tongue
//Limb appearance info:
var/real_name = "" //Replacement name
@@ -28,11 +31,65 @@
var/facial_hair_style = "Shaved"
//Eye Colouring
var/obj/item/organ/eyes/eyes = null
var/lip_style = null
var/lip_color = "white"
/obj/item/bodypart/head/Destroy()
QDEL_NULL(brainmob) //order is sensitive, see warning in handle_atom_del() below
QDEL_NULL(brain)
QDEL_NULL(eyes)
QDEL_NULL(ears)
QDEL_NULL(tongue)
return ..()
/obj/item/bodypart/head/handle_atom_del(atom/A)
if(A == brain)
brain = null
update_icon_dropped()
if(!QDELETED(brainmob)) //this shouldn't happen without badminnery.
message_admins("Brainmob: ([brainmob]) was left stranded in [src] at [ADMIN_VERBOSEJMP(src)] without a brain!")
log_game("Brainmob: ([brainmob]) was left stranded in [src] at [AREACOORD(src)] without a brain!")
if(A == brainmob)
brainmob = null
if(A == eyes)
eyes = null
update_icon_dropped()
if(A == ears)
ears = null
if(A == tongue)
tongue = null
return ..()
/obj/item/bodypart/head/examine(mob/user)
..()
if(status == BODYPART_ORGANIC)
if(!brain)
to_chat(user, "<span class='info'>The brain has been removed from [src].</span>")
else if(brain.suicided || brainmob?.suiciding)
to_chat(user, "<span class='info'>There's a pretty dumb expression on [real_name]'s face; they must have really hated life. There is no hope of recovery.</span>")
else if(brain.brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD)
to_chat(user, "<span class='info'>It seems to be leaking some kind of... clear fluid? The brain inside must be in pretty bad shape... There is no coming back from that.</span>")
else if(brainmob)
if(brainmob.get_ghost(FALSE, TRUE))
to_chat(user, "<span class='info'>It's muscles are still twitching slightly... It still seems to have a bit of life left to it.</span>")
else
to_chat(user, "<span class='info'>It seems seems particularly lifeless. Perhaps there'll be a chance for them later.</span>")
else if(brain?.decoy_override)
to_chat(user, "<span class='info'>It seems seems particularly lifeless. Perhaps there'll be a chance for them later.</span>")
else
to_chat(user, "<span class='info'>It seems completely devoid of life.</span>")
if(!eyes)
to_chat(user, "<span class='info'>[real_name]'s eyes appear to have been removed.</span>")
if(!ears)
to_chat(user, "<span class='info'>[real_name]'s ears appear to have been removed.</span>")
if(!tongue)
to_chat(user, "<span class='info'>[real_name]'s tongue appears to have been removed.</span>")
/obj/item/bodypart/head/can_dismember(obj/item/I)
if(!((owner.stat == DEAD) || owner.InFullCritical()))
return FALSE
@@ -114,44 +114,82 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
var/wired = 0
var/wired = FALSE
var/obj/item/stock_parts/cell/cell = null
/obj/item/bodypart/chest/robot/handle_atom_del(atom/A)
if(A == cell)
cell = null
return ..()
/obj/item/bodypart/chest/robot/Destroy()
QDEL_NULL(cell)
return ..()
/obj/item/bodypart/chest/robot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stock_parts/cell))
if(src.cell)
if(cell)
to_chat(user, "<span class='warning'>You have already inserted a cell!</span>")
return
else
if(!user.transferItemToLoc(W, src))
return
src.cell = W
cell = W
to_chat(user, "<span class='notice'>You insert the cell.</span>")
else if(istype(W, /obj/item/stack/cable_coil))
if(src.wired)
if(wired)
to_chat(user, "<span class='warning'>You have already inserted wire!</span>")
return
var/obj/item/stack/cable_coil/coil = W
if (coil.use(1))
src.wired = 1
wired = TRUE
to_chat(user, "<span class='notice'>You insert the wire.</span>")
else
to_chat(user, "<span class='warning'>You need one length of coil to wire it!</span>")
else
return ..()
/obj/item/bodypart/chest/robot/Destroy()
if(cell)
qdel(cell)
cell = null
return ..()
/obj/item/bodypart/chest/robot/wirecutter_act(mob/living/user, obj/item/I)
if(!wired)
return
. = TRUE
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>You cut the wires out of [src].</span>")
new /obj/item/stack/cable_coil(drop_location(), 1)
wired = FALSE
/obj/item/bodypart/chest/robot/screwdriver_act(mob/living/user, obj/item/I)
..()
. = TRUE
if(!cell)
to_chat(user, "<span class='warning'>There's no power cell installed in [src]!</span>")
return
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>Remove [cell] from [src].</span>")
cell.forceMove(drop_location())
cell = null
/obj/item/bodypart/chest/robot/examine(mob/user)
..()
if(cell)
to_chat(user, "It has a [cell] inserted.")
to_chat(user, "<span class='info'>You can use a <b>screwdriver</b> to remove [cell].</span>")
else
to_chat(user, "<span class='info'>It has an empty port for a <b>power cell</b>.</span>")
if(wired)
to_chat(user, "Its all wired up[cell ? " and ready for usage" : ""].")
to_chat(user, "<span class='info'>You can use <b>wirecutters</b> to remove the wiring.</span>")
else
to_chat(user, "<span class='info'>It has a couple spots that still need to be <b>wired</b>.</span>")
/obj/item/bodypart/chest/robot/drop_organs(mob/user, violent_removal)
if(wired)
new /obj/item/stack/cable_coil(user.loc, 1)
new /obj/item/stack/cable_coil(drop_location(), 1)
wired = FALSE
if(cell)
cell.forceMove(user.loc)
cell.forceMove(drop_location())
cell = null
..()
@@ -180,11 +218,36 @@
var/obj/item/assembly/flash/handheld/flash2 = null
/obj/item/bodypart/head/robot/handle_atom_del(atom/A)
if(A == flash1)
flash1 = null
if(A == flash2)
flash2 = null
return ..()
/obj/item/bodypart/head/robot/Destroy()
QDEL_NULL(flash1)
QDEL_NULL(flash2)
return ..()
/obj/item/bodypart/head/robot/examine(mob/user)
..()
if(!flash1 && !flash2)
to_chat(user, "<span class='info'>It has two empty eye sockets for <b>flashes</b>.</span>")
else
var/single_flash = FALSE
if(!flash1 || !flash2)
single_flash = TRUE
to_chat(user, "One of it's eye sockets are currently occupied by a flash.")
to_chat(user, "<span class='info'>It has an empty eye socket for another <b>flash</b>.</span>")
else
to_chat(user, "It has two eye sockets occupied by flashes.")
to_chat(user, "<span class='notice'>You can remove the seated flash[single_flash ? "":"es"] with a <b>crowbar</b>.</span>")
/obj/item/bodypart/head/robot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/assembly/flash/handheld))
var/obj/item/assembly/flash/handheld/F = W
if(src.flash1 && src.flash2)
if(flash1 && flash2)
to_chat(user, "<span class='warning'>You have already inserted the eyes!</span>")
return
else if(F.crit_fail)
@@ -193,36 +256,28 @@
else
if(!user.transferItemToLoc(F, src))
return
if(src.flash1)
src.flash2 = F
else
src.flash1 = F
to_chat(user, "<span class='notice'>You insert the flash into the eye socket.</span>")
else if(W.tool_behaviour == TOOL_CROWBAR)
if(flash1 || flash2)
W.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the flash from [src].</span>")
if(flash1)
flash1.forceMove(user.loc)
flash1 = null
if(flash2)
flash2.forceMove(user.loc)
flash2 = null
else
to_chat(user, "<span class='warning'>There is no flash to remove from [src].</span>")
else
return ..()
/obj/item/bodypart/head/robot/Destroy()
if(flash1)
qdel(flash1)
flash1 = null
if(flash2)
qdel(flash2)
flash2 = null
flash2 = F
else
flash1 = F
to_chat(user, "<span class='notice'>You insert the flash into the eye socket.</span>")
return
return ..()
/obj/item/bodypart/head/robot/crowbar_act(mob/living/user, obj/item/I)
if(flash1 || flash2)
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the flash from [src].</span>")
if(flash1)
flash1.forceMove(drop_location())
flash1 = null
if(flash2)
flash2.forceMove(drop_location())
flash2 = null
else
to_chat(user, "<span class='warning'>There is no flash to remove from [src].</span>")
return TRUE
/obj/item/bodypart/head/robot/drop_organs(mob/user, violent_removal)
if(flash1)