diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index eca554dcb0c..10dc8c41a1f 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -317,7 +317,9 @@ if(lying || weakened) message = "[src] flops and flails around on the floor." else - var/obj/item/weapon/grab/G = get_active_hand() + var/obj/item/weapon/grab/G + if(istype(get_active_hand(), /obj/item/weapon/grab)) + G = get_active_hand() if(G && G.affecting) var/turf/oldloc = loc var/turf/newloc = G.affecting.loc diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1556211cb5b..7775830b4a0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1255,6 +1255,54 @@ else germ_level += n +/mob/living/carbon/human/proc/check_and_regenerate_organs(var/mob/living/carbon/human/H) //Regenerates missing limbs/organs. + var/list/types_of_int_organs = list() //This will hold all the types of organs in the mob before rejuvenation. + for(var/obj/item/organ/internal/I in H.internal_organs) + types_of_int_organs |= I.type //Compiling the list of organ types. It is possible for organs to be missing from this list if they are absent from the mob. + + //Removing stumps. + for(var/obj/item/organ/organ in H.contents) + if(istype(organ, /obj/item/organ/external/stump)) //Get rid of all stumps. + qdel(organ) + H.contents -= organ //Making sure the list entry is removed. + for(var/obj/item/organ/organ in H.organs) + if(istype(organ, /obj/item/organ/external/stump)) + qdel(organ) + H.organs -= organ //Making sure the list entry is removed. + for(var/organ_name in H.organs_by_name) + var/obj/item/organ/organ = H.organs_by_name[organ_name] + if(istype(organ, /obj/item/organ/external/stump) || !organ) //The !organ check is to account for mechanical limb (prostheses) losses, since those are handled in a way that leaves indexed but null list entries instead of stumps. + qdel(organ) + H.organs_by_name -= organ_name //Making sure the list entry is removed. + + //Replacing lost limbs with the species default. + var/mob/living/carbon/human/temp_holder + for(var/limb_type in H.species.has_limbs) + if(!(limb_type in H.organs_by_name)) + var/list/organ_data = H.species.has_limbs[limb_type] + var/limb_path = organ_data["path"] + var/obj/item/organ/external/O = new limb_path(temp_holder) + if(H.get_limb_by_name(O.name)) //Check to see if the user already has an limb with the same name as the 'missing limb'. If they do, skip regrowth. + continue //In an example, this will prevent duplication of the mob's right arm if the mob is a Human and they have a Diona right arm, since, + //while the limb with the name 'right_arm' the mob has may not be listed in their species' bodyparts definition, it is still viable and has the appropriate limb name. + else + O = new limb_path(H) //Create the limb on the player. + O.owner = H + H.organs |= H.organs_by_name[O.limb_name] + + //Replacing lost organs with the species default. + temp_holder = new /mob/living/carbon/human() + for(var/index in H.species.has_organ) + var/organ = H.species.has_organ[index] + if(!(organ in types_of_int_organs)) //If the mob is missing this particular organ... + var/obj/item/organ/internal/I = new organ(temp_holder) //Create the organ inside our holder so we can check it before implantation. + if(H.get_organ_slot(I.slot)) //Check to see if the user already has an organ in the slot the 'missing organ' belongs to. If they do, skip implantation. + continue //In an example, this will prevent duplication of the mob's eyes if the mob is a Human and they have Nucleation eyes, since, + //while the organ in the eyes slot may not be listed in the mob's species' organs definition, it is still viable and fits in the appropriate organ slot. + else + I = new organ(H) //Create the organ inside the player. + I.insert(H) + /mob/living/carbon/human/revive() if(species && !(species.flags & NO_BLOOD)) @@ -1262,9 +1310,18 @@ vessel.add_reagent(blood_reagent, max_blood-vessel.total_volume) fixblood() - // Fix up all organs. - // This will ignore any prosthetics in the prefs currently. - species.create_organs(src) + //Fix up all organs and replace lost ones. + restore_all_organs() //Rejuvenate and reset all existing organs. + check_and_regenerate_organs(src) //Regenerate limbs and organs only if they're really missing. + surgeries.Cut() //End all surgeries. + update_revive() + + if(species.name != "Skeleton" && (SKELETON in mutations)) + mutations.Remove(SKELETON) + if(NOCLONE in mutations) + mutations.Remove(NOCLONE) + if(HUSK in mutations) + mutations.Remove(HUSK) if(!client || !key) //Don't boot out anyone already in the mob. for (var/obj/item/organ/internal/brain/H in world) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 00398c0f0fa..65d100dc420 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -280,6 +280,17 @@ male_scream_sound = 'sound/voice/shriek1.ogg' female_scream_sound = 'sound/voice/shriek1.ogg' + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, + "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used + ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. + suicide_messages = list( "is attempting to bite their tongue off!", "is jamming their claws into their eye sockets!", @@ -370,8 +381,8 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "eyes" = /obj/item/organ/internal/eyes, - "stack" = /obj/item/organ/internal/stack/vox - ) + "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used + ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. suicide_messages = list( "is attempting to bite their tongue off!", diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 1b5f6c25735..45bc15b1d51 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -574,6 +574,8 @@ var/global/list/damage_icon_parts = list() UpdateDamageIcon() update_icons() update_fire() + force_update_limbs() + update_tail_layer(0) /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 12473f1d9e8..f28e884f92f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -320,7 +320,6 @@ /mob/living/proc/revive() rejuvenate() - buckled = initial(src.buckled) if(iscarbon(src)) var/mob/living/carbon/C = src @@ -348,6 +347,8 @@ timeofdeath = 0 /mob/living/proc/rejuvenate() + var/mob/living/carbon/human/human_mob = null //Get this declared for use later. + // shut down various types of badness setToxLoss(0) setOxyLoss(0) @@ -366,6 +367,7 @@ drowsyness = 0 radiation = 0 druggy = 0 + hallucination = 0 nutrition = 400 bodytemperature = 310 sdisabilities = 0 @@ -380,7 +382,13 @@ fire_stacks = 0 on_fire = 0 suiciding = 0 - buckled = initial(src.buckled) + if(buckled) //Unbuckle the mob and clear the alerts. + buckled.buckled_mob = null + buckled = null + anchored = initial(src.anchored) + update_canmove() + clear_alert("buckled") + post_buckle_mob(src) if(iscarbon(src)) var/mob/living/carbon/C = src @@ -392,12 +400,13 @@ // restore all of the human's blood and reset their shock stage if(ishuman(src)) - var/mob/living/carbon/human/human_mob = src + human_mob = src human_mob.restore_blood() human_mob.shock_stage = 0 human_mob.decaylevel = 0 restore_all_organs() + surgeries.Cut() //End all surgeries. if(stat == DEAD) dead_mob_list -= src living_mob_list += src @@ -406,6 +415,9 @@ stat = CONSCIOUS update_fire() regenerate_icons() + if(human_mob) + human_mob.update_eyes() + human_mob.update_dna() return /mob/living/proc/UpdateDamageIcon() diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index 29bd9801b26..a61537f1985 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -40,4 +40,9 @@ return O /proc/is_int_organ(atom/A) - return istype(A, /obj/item/organ/internal) \ No newline at end of file + return istype(A, /obj/item/organ/internal) + +/mob/living/carbon/human/proc/get_limb_by_name(limb_name) //Look for a limb with the given limb name in the source mob, and return it if found. + for(var/obj/item/organ/external/O in organs) + if(limb_name == O.limb_name) + return O diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 3bce602694a..9c1398c6405 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -176,7 +176,12 @@ var/list/organ_cache = list() /obj/item/organ/proc/rejuvenate() damage = 0 germ_level = 0 - status &= ~ORGAN_DEAD + if(status & ORGAN_ROBOT) //Robotic organs stay robotic. + status = ORGAN_ROBOT + else if (status & ORGAN_ASSISTED) //Assisted organs stay assisted. + status = ORGAN_ASSISTED + else + status = 0 if(!owner) processing_objects |= src diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index ac96bd0f775..d0245c224d9 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -308,14 +308,20 @@ This function completely restores a damaged organ to perfect condition. */ /obj/item/organ/external/rejuvenate() damage_state = "00" - if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic. - status = 128 + if(status & ORGAN_ROBOT) //Robotic organs stay robotic. + status = ORGAN_ROBOT + else if (status & ORGAN_ASSISTED) //Assisted organs stay assisted. + status = ORGAN_ASSISTED else status = 0 germ_level = 0 perma_injury = 0 brute_dam = 0 burn_dam = 0 + open = 0 //Closing all wounds. + wounds.Cut() //Clears all wounds! Good as new. + if(istype(src, /obj/item/organ/external/head) && disfigured) //If their head's disfigured, refigure it. + disfigured = 0 // handle internal organs for(var/obj/item/organ/internal/current_organ in internal_organs)