From d71573e7499742b8b3317581d218efecb5dbde80 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Fri, 18 Dec 2015 18:23:58 +1030 Subject: [PATCH 1/4] Further work on properly integrating, updating and fixing prosthetic options. WIP Allowed heads/bodies to be prosthetic. Removed IPC. Refactored some flags. --- code/ZAS/Phoron.dm | 10 +- code/__defines/chemistry.dm | 1 - code/__defines/species_languages.dm | 6 +- code/_helpers/mobs.dm | 26 +- code/datums/datacore.dm | 6 +- code/datums/disease.dm | 2 +- .../datums/diseases/advance/symptoms/vomit.dm | 33 +-- code/datums/diseases/appendicitis.dm | 10 +- code/game/atoms.dm | 2 +- code/game/dna/dna2_helpers.dm | 9 +- .../gamemodes/changeling/powers/absorb.dm | 4 +- .../gamemodes/changeling/powers/revive.dm | 2 +- code/game/gamemodes/cult/runes.dm | 4 +- code/game/jobs/job/silicon.dm | 2 +- code/game/machinery/adv_med.dm | 4 +- code/game/machinery/bioprinter.dm | 4 +- code/game/machinery/cloning.dm | 2 +- code/game/machinery/computer/cloning.dm | 6 +- code/game/machinery/doors/airlock.dm | 2 +- code/game/machinery/iv_drip.dm | 4 +- code/game/machinery/suit_storage_unit.dm | 6 +- .../objects/effects/decals/Cleanable/misc.dm | 8 +- code/game/objects/items.dm | 2 +- .../objects/items/weapons/material/shards.dm | 8 +- code/game/objects/items/weapons/tools.dm | 11 +- code/game/objects/structures/morgue.dm | 2 +- code/modules/admin/admin_verbs.dm | 7 +- .../preference_setup/general/01_basic.dm | 2 +- .../preference_setup/general/03_body.dm | 79 +++++- code/modules/client/preferences.dm | 10 +- .../clothing/under/accessories/accessory.dm | 8 +- code/modules/mob/language/station.dm | 10 +- code/modules/mob/living/carbon/brain/MMI.dm | 2 +- .../mob/living/carbon/brain/brain_item.dm | 21 +- code/modules/mob/living/carbon/breathe.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 8 + .../mob/living/carbon/carbon_powers.dm | 24 +- .../mob/living/carbon/human/appearance.dm | 34 ++- code/modules/mob/living/carbon/human/death.dm | 4 +- code/modules/mob/living/carbon/human/emote.dm | 2 +- .../mob/living/carbon/human/examine.dm | 31 ++- code/modules/mob/living/carbon/human/human.dm | 86 +++--- .../mob/living/carbon/human/human_damage.dm | 54 ++-- .../mob/living/carbon/human/human_defense.dm | 4 +- .../mob/living/carbon/human/human_defines.dm | 1 + .../mob/living/carbon/human/human_movement.dm | 4 +- .../mob/living/carbon/human/human_organs.dm | 7 +- .../mob/living/carbon/human/inventory.dm | 1 - code/modules/mob/living/carbon/human/life.dm | 99 ++++--- .../carbon/human/species/outsider/shadow.dm | 2 +- .../carbon/human/species/outsider/vox.dm | 16 +- .../living/carbon/human/species/species.dm | 21 +- .../carbon/human/species/station/golem.dm | 2 +- .../carbon/human/species/station/monkey.dm | 16 +- .../carbon/human/species/station/slime.dm | 2 +- .../carbon/human/species/station/station.dm | 100 ++----- .../human/species/xenomorphs/alien_species.dm | 18 +- .../mob/living/carbon/human/unarmed_attack.dm | 13 +- .../mob/living/carbon/human/update_icons.dm | 4 +- .../mob/living/carbon/metroid/powers.dm | 2 +- code/modules/mob/living/carbon/shock.dm | 2 +- code/modules/mob/living/living.dm | 48 ++++ code/modules/mob/living/living_defines.dm | 1 + .../mob/living/silicon/robot/drone/drone.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 8 +- .../simple_animal/borer/borer_powers.dm | 2 +- code/modules/mob/mob_defines.dm | 1 - code/modules/mob/mob_grab_specials.dm | 2 +- .../mob/new_player/preferences_setup.dm | 75 ++++-- code/modules/mob/transform_procs.dm | 4 +- code/modules/organs/blood.dm | 18 +- code/modules/organs/misc.dm | 13 +- code/modules/organs/organ.dm | 78 +++--- code/modules/organs/organ_external.dm | 246 ++++++++++++------ code/modules/organs/organ_icon.dm | 8 +- code/modules/organs/organ_internal.dm | 9 +- code/modules/organs/pain.dm | 20 +- code/modules/organs/robolimbs.dm | 1 - code/modules/organs/subtypes/diona.dm | 16 -- code/modules/organs/subtypes/machine.dm | 145 +++-------- code/modules/power/cable.dm | 12 +- code/modules/projectiles/projectile/change.dm | 6 +- .../Chemistry-Reagents-Core.dm | 6 +- .../Chemistry-Reagents-Dispenser.dm | 2 +- .../Chemistry-Reagents-Food-Drinks.dm | 9 +- .../Chemistry-Reagents-Medicine.dm | 2 +- .../Chemistry-Reagents-Toxins.dm | 5 + .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/surgery/bones.dm | 1 - code/modules/surgery/generic.dm | 7 +- code/modules/surgery/organs_internal.dm | 6 +- code/modules/surgery/robotics.dm | 8 +- code/modules/virus2/admin.dm | 2 +- code/modules/virus2/disease2.dm | 4 +- code/modules/virus2/helpers.dm | 2 +- code/modules/virus2/items_devices.dm | 2 +- icons/mob/human_races/cyberlimbs/bishop.dmi | Bin 950 -> 1442 bytes .../human_races/cyberlimbs/hesphaistos.dmi | Bin 935 -> 1431 bytes icons/mob/human_races/cyberlimbs/ipc.dmi | Bin 1716 -> 1717 bytes icons/mob/human_races/cyberlimbs/xion.dmi | Bin 901 -> 1397 bytes icons/mob/human_races/cyberlimbs/zenghu.dmi | Bin 849 -> 1362 bytes icons/mob/human_races/r_machine.dmi | Bin 2120 -> 0 bytes 102 files changed, 925 insertions(+), 722 deletions(-) delete mode 100644 icons/mob/human_races/r_machine.dmi diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index ff03f947e19..cffa28a1fc2 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -116,10 +116,6 @@ obj/var/contaminated = 0 /mob/living/carbon/human/proc/burn_eyes() - //The proc that handles eye burning. - if(!species.has_organ["eyes"]) - return - var/obj/item/organ/eyes/E = internal_organs_by_name["eyes"] if(E) if(prob(20)) src << "Your eyes burn!" @@ -143,15 +139,15 @@ obj/var/contaminated = 0 //Checks if the suit is adequately sealed. var/coverage = 0 for(var/obj/item/protection in list(wear_suit, gloves, shoes)) - if(!protection) + if(!protection) continue if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD)) return 0 coverage |= protection.body_parts_covered - + if(vsc.plc.PHORONGUARD_ONLY) return 1 - + return BIT_TEST_ALL(coverage, UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS) /mob/living/carbon/human/proc/suit_contamination() diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 31bdcc94694..3c1be97566f 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -23,7 +23,6 @@ #define IS_UNATHI 4 #define IS_TAJARA 5 #define IS_XENOS 6 -#define IS_MACHINE 7 #define CE_STABLE "stable" // Inaprovaline #define CE_ANTIBIOTIC "antibiotic" // Spaceacilin diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index e204cdb977a..9dc9ecd0fd7 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -1,12 +1,10 @@ // Species flags. -#define NO_BLOOD 0x1 // Vessel var is not filled with blood, cannot bleed out. -#define NO_BREATHE 0x2 // Cannot suffocate or take oxygen loss. +#define NO_MINOR_CUT 0x1 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows) +#define IS_PLANT 0x2 // Is a treeperson. #define NO_SCAN 0x4 // Cannot be scanned in a DNA machine/genome-stolen. #define NO_PAIN 0x8 // Cannot suffer halloss/recieves deceptive health indicator. #define NO_SLIP 0x10 // Cannot fall over. #define NO_POISON 0x20 // Cannot not suffer toxloss. -#define IS_PLANT 0x40 // Is a treeperson. -#define NO_MINOR_CUT 0x80 // Can step on broken glass with no ill-effects. Either thick skin (diona/vox), cut resistant (slimes) or incorporeal (shadows) // unused: 0x8000 - higher than this will overflow // Species spawn flags diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 6e2a7fae360..96b50fc6c5f 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -29,10 +29,13 @@ proc/random_hair_style(gender, species = "Human") var/list/valid_hairstyles = list() for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] - if(gender == MALE && S.gender == FEMALE) - continue - if(gender == FEMALE && S.gender == MALE) - continue + + if(gender != NEUTER) + if(gender == MALE && S.gender == FEMALE) + continue + if(gender == FEMALE && S.gender == MALE) + continue + if( !(species in S.species_allowed)) continue valid_hairstyles[hairstyle] = hair_styles_list[hairstyle] @@ -48,10 +51,13 @@ proc/random_facial_hair_style(gender, species = "Human") var/list/valid_facialhairstyles = list() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - if(gender == MALE && S.gender == FEMALE) - continue - if(gender == FEMALE && S.gender == MALE) - continue + + if(gender != NEUTER) + if(gender == MALE && S.gender == FEMALE) + continue + if(gender == FEMALE && S.gender == MALE) + continue + if( !(species in S.species_allowed)) continue @@ -61,12 +67,12 @@ proc/random_facial_hair_style(gender, species = "Human") f_style = pick(valid_facialhairstyles) return f_style - + proc/sanitize_name(name, species = "Human") var/datum/species/current_species if(species) current_species = all_species[species] - + return current_species ? current_species.sanitize_name(name) : sanitizeName(name) proc/random_name(gender, species = "Human") diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 5c86505da7e..f748fdd53e7 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -222,6 +222,7 @@ locked += L return +// TODO. proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role) var/icon/preview_icon = null @@ -258,7 +259,10 @@ proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role) if(!H.species || H.species.flags & HAS_SKIN_COLOR) preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s") + var/use_eye_icon = "eyes_s" + var/obj/item/organ/external/head/temp_head = H.get_organ("head") + if(temp_head) use_eye_icon = temp_head.eye_icon + var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = use_eye_icon) if (H.species.flags & HAS_EYE_COLOR) eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) diff --git a/code/datums/disease.dm b/code/datums/disease.dm index 606acdef99e..453cd0d8bdc 100644 --- a/code/datums/disease.dm +++ b/code/datums/disease.dm @@ -57,7 +57,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease // Some species are immune to viruses entirely. if(affected_mob && istype(affected_mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = affected_mob - if(H.species.virus_immune) + if(H.species.get_virus_immune(H)) cure() return age++ diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index 1f62065ef99..ecfd2deb815 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -27,29 +27,15 @@ Bonus stage_speed = 0 transmittable = 1 level = 3 + var/bloodvomit /datum/symptom/vomit/Activate(var/datum/disease/advance/A) ..() if(prob(SYMPTOM_ACTIVATION_PROB / 2)) var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - M << "[pick("You feel nauseous.", "You feel like you're going to throw up!")]" - else - Vomit(M) - + spawn M.vomit(M, bloodvomit) return -/datum/symptom/vomit/proc/Vomit(var/mob/living/M) - - M.visible_message("[M] vomits on the floor!") - - M.nutrition -= 20 - M.adjustToxLoss(-3) - - var/turf/pos = get_turf(M) - pos.add_vomit_floor(M) - playsound(pos, 'sound/effects/splat.ogg', 50, 1) /* ////////////////////////////////////// @@ -78,17 +64,4 @@ Bonus stage_speed = -1 transmittable = 1 level = 4 - -/datum/symptom/vomit/blood/Vomit(var/mob/living/M) - - M.Stun(1) - M.visible_message("[M] vomits on the floor!") - - // They lose blood and health. - var/brute_dam = M.getBruteLoss() - if(brute_dam < 50) - M.adjustBruteLoss(3) - - var/turf/simulated/pos = get_turf(M) - pos.add_blood_floor(M) - playsound(pos, 'sound/effects/splat.ogg', 50, 1) \ No newline at end of file + bloodvomit = 1 diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index b4f2b1a38ab..d6f05d33ef0 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -33,13 +33,9 @@ affected_mob.adjustToxLoss(1) if(stage > 2) if(prob(1)) - if (affected_mob.nutrition > 100) - var/mob/living/carbon/human/H = affected_mob - H.vomit() - else - affected_mob << "You gag as you want to throw up, but there's nothing in your stomach!" - affected_mob.Weaken(10) - affected_mob.adjustToxLoss(3) + var/mob/living/carbon/human/H = affected_mob + spawn H.vomit() + if(stage > 3) if(prob(1) && ishuman(affected_mob)) var/mob/living/carbon/human/H = affected_mob diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1a9d246215e..f219e1d6c76 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -400,7 +400,7 @@ its easier to just keep the beam vertical. M.dna.real_name = M.real_name M.check_dna() if (M.species) - blood_color = M.species.blood_color + blood_color = M.species.get_blood_colour(M) . = 1 return 1 diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index ce6320cd88c..98acc1d335d 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -150,10 +150,11 @@ H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. - if (dna.GetUIState(DNA_UI_GENDER)) - H.gender = FEMALE - else - H.gender = MALE + if(H.gender != NEUTER) + if (dna.GetUIState(DNA_UI_GENDER)) + H.gender = FEMALE + else + H.gender = MALE //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 7d5a42e7e82..0c13276f12d 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -19,8 +19,8 @@ return var/mob/living/carbon/human/T = G.affecting - if(!istype(T)) - src << "[T] is not compatible with our biology." + if(!istype(T) || T.isSynthetic()) + src << "\The [T] is not compatible with our biology." return if(T.species.flags & NO_SCAN) diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 465088a06ae..f67df60f2a1 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -23,7 +23,7 @@ C.radiation = 0 C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss()) C.reagents.clear_reagents() - C.restore_all_organs() //Covers things like fractures and other things not covered by the above. + C.restore_all_organs(ignore_prosthetic_prefs=1) //Covers things like fractures and other things not covered by the above. if(ishuman(C)) var/mob/living/carbon/human/H = src H.restore_blood() diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index aafcd791e50..760a2d4833b 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -162,8 +162,8 @@ var/list/sacrificed = list() target.adjustBrainLoss(rand(1,5)) initial_message = 1 - if (target.species && (target.species.flags & NO_PAIN)) - target.visible_message("The markings below [target] glow a bloody red.") + if (!target.can_feel_pain()) + target.visible_message("The markings below \the [target] glow a bloody red.") else target.visible_message("[target] writhes in pain as the markings below \him glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.") diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm index 6cec7149e97..b64508499ca 100644 --- a/code/game/jobs/job/silicon.dm +++ b/code/game/jobs/job/silicon.dm @@ -40,7 +40,7 @@ supervisors = "your laws and the AI" //Nodrak selection_color = "#ddffdd" minimal_player_age = 1 - alt_titles = list("Android", "Robot") + alt_titles = list("Robot", "Drone") account_allowed = 0 economic_modifier = 0 diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index af922271d95..64393c2bc46 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -399,9 +399,9 @@ for(var/obj/item/organ/i in occ["internal_organs"]) var/mech = "" - if(i.robotic == 1) + if(i.status & ORGAN_ASSISTED) mech = "Assisted:" - if(i.robotic == 2) + if(i.status & ORGAN_ROBOT) mech = "Mechanical:" var/infection = "None" diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 23d00318ea8..0bb7dd19357 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -41,7 +41,7 @@ var/obj/item/organ/O = new new_organ(get_turf(src)) if(prints_prosthetics) - O.robotic = 2 + O.robotize() else if(loaded_dna) visible_message("The printer injects the stored DNA into the biomass..") O.transplant_data = list() @@ -80,5 +80,5 @@ user << "\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]" qdel(W) return - + return..() \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index a2b2b633254..d3c152fa25a 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -16,7 +16,7 @@ //They need a brain! if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(H.species.has_organ["brain"] && !H.has_brain()) + if(!H.has_brain()) continue if(M.ckey == find_key) selected = M diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 857832d2f59..83b6f2ce861 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -353,11 +353,15 @@ if (!subject.has_brain()) if(istype(subject, /mob/living/carbon/human)) var/mob/living/carbon/human/H = subject - if(H.species.has_organ["brain"]) + if(H.should_have_organ("brain")) scantemp = "Error: No signs of intelligence detected." else scantemp = "Error: No signs of intelligence detected." return + + if(subject.isSynthetic()) + scantemp = "Error: Subject is not organic." + return if (subject.suiciding == 1) scantemp = "Error: Subject's brain is not responding to scanning stimuli." return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d32c7e45ee9..c2758a7ffd9 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -943,7 +943,7 @@ About the new airlock wires panel: /mob/living/carbon/airlock_crush(var/crush_damage) . = ..() - if (!(species && (species.flags & NO_PAIN))) + if(can_feel_pain()) emote("scream") /mob/living/silicon/robot/airlock_crush(var/crush_damage) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index c1b160c94bd..0fec7a9c1b2 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -106,7 +106,7 @@ if(NOCLONE in T.mutations) return - if(T.species.flags & NO_BLOOD) + if(!T.should_have_organ("heart")) return // If the human is losing too much blood, beep. @@ -165,4 +165,4 @@ /obj/machinery/iv_drip/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(height && istype(mover) && mover.checkpass(PASSTABLE)) //allow bullets, beams, thrown objects, mice, drones, and the like through. return 1 - return ..() + return ..() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 703760ddf0a..d3fe17a0689 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -333,16 +333,14 @@ OCCUPANT.apply_effect(50, IRRADIATE) var/obj/item/organ/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs if (!rad_organ) + if (OCCUPANT.can_feel_pain()) + OCCUPANT.emote("scream") if(src.issuperUV) var/burndamage = rand(28,35) OCCUPANT.take_organ_damage(0,burndamage) - if (!(OCCUPANT.species && (OCCUPANT.species.flags & NO_PAIN))) - OCCUPANT.emote("scream") else var/burndamage = rand(6,10) OCCUPANT.take_organ_damage(0,burndamage) - if (!(OCCUPANT.species && (OCCUPANT.species.flags & NO_PAIN))) - OCCUPANT.emote("scream") if(i==3) //End of the cycle if(!src.issuperUV) if(src.HELMET) diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index c70a5ab9fc6..250e8f350ee 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -102,10 +102,10 @@ random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") var/list/viruses = list() - Destroy() - for(var/datum/disease/D in viruses) - D.cure(0) - ..() +/obj/effect/decal/cleanable/vomit/Destroy() + for(var/datum/disease/D in viruses) + D.cure(0) + return ..() /obj/effect/decal/cleanable/tomato_smudge name = "tomato smudge" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 25320136b92..eeed37b9e72 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -465,7 +465,7 @@ var/list/global/slot_flags_enumeration = list( eyes.damage += rand(3,4) if(eyes.damage >= eyes.min_bruised_damage) if(M.stat != 2) - if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly + if(!(eyes.status & ORGAN_ROBOT)) //robot eyes bleeding might be a bit silly M << "Your eyes start to bleed profusely!" if(prob(50)) if(M.stat != 2) diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index 65bb1d4ebc6..bb4b80c1b80 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -64,10 +64,10 @@ ..() if(isliving(AM)) var/mob/M = AM - + if(M.buckled) //wheelchairs, office chairs, rollerbeds return - + M << "You step on \the [src]!" playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds if(ishuman(M)) @@ -78,7 +78,7 @@ if( H.shoes || ( H.wear_suit && (H.wear_suit.body_parts_covered & FEET) ) ) return - + var/list/check = list("l_foot", "r_foot") while(check.len) var/picked = pick(check) @@ -89,7 +89,7 @@ if(affecting.take_damage(5, 0)) H.UpdateDamageIcon() H.updatehealth() - if(!(H.species.flags & NO_PAIN)) + if(affecting.can_feel_pain()) H.Weaken(3) return check -= picked diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 282e7bece66..0e1f0dadc3e 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -422,14 +422,18 @@ icon_state = "red_crowbar" item_state = "crowbar_red" +/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone) + if(ishuman(A) && user.a_intent == I_HELP) + return + return ..() + /obj/item/weapon/weldingtool/afterattack(var/mob/M, var/mob/user) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] - if (!S) return - if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) + if(!S || !(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) return ..() if(S.brute_dam) @@ -438,10 +442,9 @@ user.visible_message("\The [user] patches some dents on \the [M]'s [S.name] with \the [src].") else if(S.open != 2) user << "The damage is far too severe to patch over externally." - return 1 else if(S.open != 2) user << "Nothing to fix!" - + return else return ..() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 9f8eed2eb57..949cbc1ff67 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -324,7 +324,7 @@ M.emote("scream") else var/mob/living/carbon/C = M - if (!(C.species && (C.species.flags & NO_PAIN))) + if (C.can_feel_pain()) C.emote("scream") //Logging for this causes runtimes resulting in the cremator locking up. Commenting it out until that's figured out. diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index e959c1991bd..19302f8d30c 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -880,12 +880,15 @@ var/list/admin_verbs_mentor = list( if(new_fstyle) M.f_style = new_fstyle - var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") + var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neuter") if (new_gender) if(new_gender == "Male") M.gender = MALE - else + else if (new_gender == "Female") M.gender = FEMALE + else + M.gender = NEUTER + M.update_hair() M.update_body() M.check_dna(M) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 440cf90e59c..0f993b0fca9 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -1,7 +1,7 @@ /datum/category_item/player_setup_item/general/basic name = "Basic" sort_order = 1 - var/list/valid_player_genders = list(MALE, FEMALE) + var/list/valid_player_genders = list(MALE, FEMALE, NEUTER, PLURAL) /datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S) S["real_name"] >> pref.real_name diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 07530881fe3..720a3d3c075 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -75,8 +75,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O /datum/category_item/player_setup_item/general/body/content(var/mob/user) pref.update_preview_icon() if(pref.preview_icon_front && pref.preview_icon_side) - user << browse_rsc(pref.preview_icon_front, "previewicon.png") - user << browse_rsc(pref.preview_icon_side, "previewicon2.png") + user << browse_rsc(pref.preview_icon_front, "preview_icon.png") + user << browse_rsc(pref.preview_icon_side, "preview_icon2.png") var/mob_species = all_species[pref.species] . += "
Body " @@ -87,7 +87,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(has_flag(mob_species, HAS_SKIN_TONE)) . += "Skin Tone: [-pref.s_tone + 35]/220
" . += "Needs Glasses: [pref.disabilities & NEARSIGHTED ? "Yes" : "No"]
" - . += "Limbs: Adjust
" + . += "Limbs: Adjust Reset
" . += "Internal Organs: Adjust
" //display limbs below @@ -96,6 +96,13 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/status = pref.organ_data[name] var/organ_name = null switch(name) + + if("torso") + organ_name = "torso" + if("groin") + organ_name = "groin" + if("head") + organ_name = "head" if("l_arm") organ_name = "left arm" if("r_arm") @@ -116,6 +123,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O organ_name = "heart" if("eyes") organ_name = "eyes" + if("brain") + organ_name = "brain" if(status == "cyborg") ++ind @@ -136,7 +145,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O ++ind if(ind > 1) . += ", " - . += "\tMechanical [organ_name]" + . += "\tSynthetic [organ_name]" else if(status == "assisted") ++ind if(ind > 1) @@ -148,6 +157,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "\tSurgically altered [organ_name]" if("eyes") . += "\tRetinal overlayed [organ_name]" + if("brain") + . += "\tAssisted-interface [organ_name]" else . += "\tMechanically assisted [organ_name]" if(!ind) @@ -155,7 +166,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else . += "

" - . += "
Preview
" + . += "
Preview
" . += "
" . += "Hair
" @@ -252,6 +263,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.b_hair = 0//hex2num(copytext(new_hair, 6, 8)) pref.s_tone = 0 + reset_limbs() // Safety for species with incompatible manufacturers; easier than trying to do it case by case. return TOPIC_REFRESH else if(href_list["hair_color"]) @@ -334,8 +346,12 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.f_style = new_f_style return TOPIC_REFRESH + else if(href_list["reset_limbs"]) + reset_limbs() + return TOPIC_REFRESH + else if(href_list["limbs"]) - var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand") + var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand","Full Body") if(!limb_name && !CanUseTopic(user)) return TOPIC_NOACTION var/limb = null @@ -366,6 +382,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if("Right Hand") limb = "r_hand" third_limb = "r_arm" + if("Full Body") + limb = "torso" + var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis") if(!new_state && !CanUseTopic(user)) return TOPIC_NOACTION @@ -378,6 +397,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.organ_data[third_limb] = null pref.rlimb_data[third_limb] = null if("Amputated") + + if(limb == "torso") + return + pref.organ_data[limb] = "amputated" pref.rlimb_data[limb] = null if(second_limb) @@ -397,17 +420,31 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in usable_manufacturers if(!choice) return + pref.rlimb_data[limb] = choice pref.organ_data[limb] = "cyborg" + if(second_limb) pref.rlimb_data[second_limb] = choice pref.organ_data[second_limb] = "cyborg" if(third_limb && pref.organ_data[third_limb] == "amputated") pref.organ_data[third_limb] = null + + if(limb == "torso") + for(var/other_limb in list("l_foot","r_foot","l_hand","r_hand","l_leg","r_leg","l_arm","r_arm","groin","head")) + if(pref.organ_data[other_limb]) + continue + pref.organ_data[other_limb] = "cyborg" + pref.rlimb_data[other_limb] = choice + if(!pref.organ_data["brain"]) + pref.organ_data["brain"] = "assisted" + for(var/internal_organ in list("heart","eyes")) + pref.organ_data[internal_organ] = "mechanical" + return TOPIC_REFRESH else if(href_list["organs"]) - var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes") + var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes", "Brain") if(!organ_name) return var/organ = null @@ -416,12 +453,20 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O organ = "heart" if("Eyes") organ = "eyes" + if("Brain") + if(pref.organ_data["head"] != "cyborg") + user << "You may only select an assisted or synthetic brain if you have a full prosthetic body." + return + organ = "brain" var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical") if(!new_state) return switch(new_state) if("Normal") + if(pref.organ_data["torso"] == "cyborg") + user << "A character with a synthetic body may only use synthetic organs." + return pref.organ_data[organ] = null if("Assisted") pref.organ_data[organ] = "assisted" @@ -436,6 +481,18 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return ..() +/datum/category_item/player_setup_item/general/body/proc/reset_limbs() + + for(var/organ in pref.organ_data) + pref.organ_data[organ] = null + while(null in pref.organ_data) + pref.organ_data -= null + + for(var/organ in pref.rlimb_data) + pref.rlimb_data[organ] = null + while(null in pref.rlimb_data) + pref.rlimb_data -= null + /datum/category_item/player_setup_item/general/body/proc/SetSpecies(mob/user) if(!pref.species_preview || !(pref.species_preview in all_species)) pref.species_preview = "Human" @@ -455,10 +512,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "
Often present on human stations." if(current_species.spawn_flags & IS_WHITELISTED) dat += "
Whitelist restricted." - if(current_species.flags & NO_BLOOD) - dat += "
Does not have blood." - if(current_species.flags & NO_BREATHE) - dat += "
Does not breathe." + if(!current_species.has_organ["heart"]) + dat += "
Does not have a circulatory system." + if(!current_species.has_organ["lungs"]) + dat += "
Does not have a respiratory system." if(current_species.flags & NO_SCAN) dat += "
Does not have DNA." if(current_species.flags & NO_PAIN) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 6bc9b888459..b4060b221fb 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -310,6 +310,8 @@ datum/preferences var/status = organ_data[name] var/obj/item/organ/external/O = character.organs_by_name[name] + if(name == "torso" && !O) + O = character.organs_by_name["chest"] if(O) O.status = 0 if(status == "amputated") @@ -334,20 +336,14 @@ datum/preferences I.robotize() character.underwear = underwear - character.undershirt = undershirt - character.socks = socks if(backbag > 4 || backbag < 1) backbag = 1 //Same as above character.backbag = backbag - //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(character.gender in list(PLURAL, NEUTER)) - if(isliving(src)) //Ghosts get neuter by default - message_admins("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.") - character.gender = MALE + character.update_body() /datum/preferences/proc/open_load_dialog(mob/user) var/dat = "" diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 5610a23f638..f57b9c9be29 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -99,10 +99,9 @@ var/sound = "heartbeat" var/sound_strength = "cannot hear" var/heartbeat = 0 - if(M.species && M.species.has_organ["heart"]) - var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"] - if(heart && !heart.robotic) - heartbeat = 1 + var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"] + if(heart && !(heart.status & ORGAN_ROBOT)) + heartbeat = 1 if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) sound_strength = "cannot hear" sound = "anything" @@ -112,7 +111,6 @@ sound_strength = "hear" sound = "no heartbeat" if(heartbeat) - var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"] if(heart.is_bruised() || M.getOxyLoss() > 50) sound = "[pick("odd noises in","weak")] heartbeat" else diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index cc477f0ee7d..d237f36b090 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -96,13 +96,13 @@ /datum/language/machine name = "Encoded Audio Language" - desc = "A language of encoded tones that allow for IPCs to communicate auditorily between each other in a manner that allows for easier transfer of information." - speech_verb = "beeps" - ask_verb = "beeps" - exclaim_verb = "loudly beeps" + desc = "A efficient language of encoded tones developed by synthetics and cyborgs." + speech_verb = "whistles" + ask_verb = "chirps" + exclaim_verb = "whistles loudly" colour = "changeling" key = "6" - flags = RESTRICTED | NO_STUTTER + flags = NO_STUTTER syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz") space_chance = 10 diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 07004f97546..03de410f5ee 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -60,7 +60,7 @@ brainobj = O brainobj.loc = src - name = "Man-Machine Interface: [brainmob.real_name]" + name = "man-machine interface ([brainmob.real_name])" icon_state = "mmi_full" locked = 1 diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 543c3d339f3..fc1e7778adb 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -15,6 +15,25 @@ attack_verb = list("attacked", "slapped", "whacked") var/mob/living/carbon/brain/brainmob = null + +/obj/item/organ/brain/robotize() + replace_self_with(/obj/item/organ/mmi_holder/posibrain) + +/obj/item/organ/brain/mechassist() + replace_self_with(/obj/item/organ/mmi_holder) + +/obj/item/organ/brain/proc/replace_self_with(replace_path) + if(!owner) + new replace_path(src.loc) + qdel(src) + return + owner.internal_organs_by_name[organ_tag] = new replace_path(owner, 1) + owner.internal_organs -= src + while(null in owner.internal_organs_by_name) + owner.internal_organs_by_name -= null + while(null in owner.internal_organs) + owner.internal_organs -= null + /obj/item/organ/pariah_brain name = "brain remnants" desc = "Did someone tread on this? It looks useless for cloning or cyborgification." @@ -93,13 +112,11 @@ /obj/item/organ/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." - robotic = 2 icon = 'icons/mob/slimes.dmi' icon_state = "green slime extract" /obj/item/organ/brain/golem name = "chem" desc = "A tightly furled roll of paper, covered with indecipherable runes." - robotic = 2 icon = 'icons/obj/wizard.dmi' icon_state = "scroll" diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm index 20f86d4dde0..fa87736f26c 100644 --- a/code/modules/mob/living/carbon/breathe.dm +++ b/code/modules/mob/living/carbon/breathe.dm @@ -7,7 +7,7 @@ /mob/living/carbon/proc/breathe() //if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return - if(species && (species.flags & NO_BREATHE) || does_not_breathe) return + if(!should_have_organ("lungs") || does_not_breathe) return var/datum/gas_mixture/breath = null diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index fd6fd0f6580..f0b09f88d62 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -472,3 +472,11 @@ if(!species) return null return species.default_language ? all_languages[species.default_language] : null + +/mob/living/carbon/proc/should_have_organ(var/organ_check) + return 0 + +/mob/living/carbon/proc/can_feel_pain(var/check_organ) + if(isSynthetic()) + return 0 + return !(species.flags & NO_PAIN) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon_powers.dm b/code/modules/mob/living/carbon/carbon_powers.dm index 65fcbc7b17e..f1360504ef6 100644 --- a/code/modules/mob/living/carbon/carbon_powers.dm +++ b/code/modules/mob/living/carbon/carbon_powers.dm @@ -8,7 +8,7 @@ var/mob/living/simple_animal/borer/B = has_brain_worms() if(B && B.host_brain) - src << "\red You withdraw your probosci, releasing control of [B.host_brain]" + src << "You withdraw your probosci, releasing control of [B.host_brain]" B.detatch() @@ -17,7 +17,7 @@ verbs -= /mob/living/carbon/proc/spawn_larvae else - src << "\red ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !" + src << "ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !" //Brain slug proc for tormenting the host. /mob/living/carbon/proc/punish_host() @@ -31,13 +31,12 @@ return if(B.host_brain.ckey) - src << "\red You send a punishing spike of psychic agony lancing into your host's brain." - - if (species && (species.flags & NO_PAIN)) - B.host_brain << "\red You feel a strange sensation as a foreign influence prods your mind." - src << "\red It doesn't seem to be as effective as you hoped." + src << "You send a punishing spike of psychic agony lancing into your host's brain." + if (!can_feel_pain()) + B.host_brain << "You feel a strange sensation as a foreign influence prods your mind." + src << "It doesn't seem to be as effective as you hoped." else - B.host_brain << "\red Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!" + B.host_brain << "Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!" /mob/living/carbon/proc/spawn_larvae() set category = "Abilities" @@ -50,15 +49,14 @@ return if(B.chemicals >= 100) - src << "\red Your host twitches and quivers as you rapidly excrete a larva from your sluglike body." - visible_message("\red [src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") + src << "Your host twitches and quivers as you rapidly excrete a larva from your sluglike body." + visible_message("\The [src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!") B.chemicals -= 100 B.has_reproduced = 1 - new /obj/effect/decal/cleanable/vomit(get_turf(src)) - playsound(loc, 'sound/effects/splat.ogg', 50, 1) + vomit(1) new /mob/living/simple_animal/borer(get_turf(src)) else - src << "You do not have enough chemicals stored to reproduce." + src << "You do not have enough chemicals stored to reproduce." return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 5f9d7e827cf..cf404df6ffe 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -157,30 +157,44 @@ return valid_species /mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1) + + var/use_species = species.get_bodytype() + var/obj/item/organ/external/head/H = get_organ("head") + if(H) use_species = H.species.get_bodytype() + var/list/valid_hairstyles = new() for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] - if(check_gender && gender == MALE && S.gender == FEMALE) - continue - if(check_gender && gender == FEMALE && S.gender == MALE) - continue - if(!(species.get_bodytype() in S.species_allowed)) + if(check_gender && gender != NEUTER) + if(gender == MALE && S.gender == FEMALE) + continue + else if(gender == FEMALE && S.gender == MALE) + continue + + if(!(use_species in S.species_allowed)) continue valid_hairstyles += hairstyle return valid_hairstyles /mob/living/carbon/human/proc/generate_valid_facial_hairstyles() + + var/use_species = species.get_bodytype() + var/obj/item/organ/external/head/H = get_organ("head") + if(H) use_species = H.species.get_bodytype() + var/list/valid_facial_hairstyles = new() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - if(gender == MALE && S.gender == FEMALE) - continue - if(gender == FEMALE && S.gender == MALE) - continue - if(!(species.get_bodytype() in S.species_allowed)) + if(gender != NEUTER) + if(gender == MALE && S.gender == FEMALE) + continue + else if(gender == FEMALE && S.gender == MALE) + continue + + if(!(use_species in S.species_allowed)) continue valid_facial_hairstyles += facialhairstyle diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index ff7255523d3..a01a8f4ee86 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -15,7 +15,7 @@ I.throw_at(get_edge_target_turf(src,pick(alldirs)), rand(1,3), round(30/I.w_class)) ..(species.gibbed_anim) - gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color) + gibs(loc, viruses, dna, null, species.get_flesh_colour(src), species.get_blood_colour(src)) /mob/living/carbon/human/dust() if(species) @@ -68,7 +68,7 @@ if(wearing_rig) wearing_rig.notify_ai("Warning: user death event. Mobility control passed to integrated intelligence system.") - return ..(gibbed,species.death_message) + return ..(gibbed,species.get_death_message(src)) /mob/living/carbon/human/proc/ChangeToHusk() if(HUSK in mutations) return diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index c1abe448f33..65099437548 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -207,7 +207,7 @@ m_type = 2 if ("deathgasp") - message = "[species.death_message]" + message = "[species.get_death_message()]" m_type = 1 if ("giggle") diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 07619bff1f3..650a72014e2 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -38,9 +38,21 @@ CRASH("Gender datum was null; key was '[(skipjumpsuit && skipface) ? PLURAL : gender]'") msg += "[src.name]" - if(species.name != "Human") - msg += ", a [species.name]" - msg += "!\n" + + + var/is_synth = isSynthetic() + if(is_synth) + var/use_gender = "a synthetic" + if(gender == MALE) + use_gender = "an android" + else if(gender == FEMALE) + use_gender = "a gynoid" + + msg += ", [use_gender]!" + + else if(species.name != "Human") + msg += ", \a [species.name]!" + msg += "
" //uniform if(w_uniform && !skipjumpsuit) @@ -230,11 +242,12 @@ if(getBrainLoss() >= 60) msg += "[T.He] [T.has] a stupid expression on [T.his] face.\n" - if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD) + var/ssd_msg = species.get_ssd(src) + if(ssd_msg && (!should_have_organ("brain") || has_brain()) && stat != DEAD) if(!key) - msg += "[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.\n" + msg += "[T.He] [T.is] [ssd_msg]. It doesn't look like [T.he] [T.is] waking up anytime soon.\n" else if(!client) - msg += "[T.He] [T.is] [species.show_ssd].\n" + msg += "[T.He] [T.is] [ssd_msg].\n" var/list/wound_flavor_text = list() var/list/is_destroyed = list() @@ -261,12 +274,12 @@ is_destroyed["[temp.name]"] = 1 wound_flavor_text["[temp.name]"] = "[T.He] [T.is] missing [T.his] [temp.name].\n" continue - if(temp.status & ORGAN_ROBOT) + if(!is_synth && temp.status & ORGAN_ROBOT) if(!(temp.brute_dam + temp.burn_dam)) - wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a robot [temp.name]!\n" + wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name]!\n" continue else - wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a robot [temp.name]. It has[temp.get_wounds_desc()]!\n" + wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name]. It has[temp.get_wounds_desc()]!\n" else if(temp.wounds.len > 0 || temp.open) if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ]) var/obj/item/organ/external/parent = organs_by_name[temp.parent_organ] diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index eef1b952458..68662204a31 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -654,18 +654,12 @@ ///eyecheck() ///Returns a number between -1 to 2 /mob/living/carbon/human/eyecheck() - var/number = 0 - - if(!species.has_organ["eyes"]) //No eyes, can't hurt them. - return 2 - if(internal_organs_by_name["eyes"]) // Eyes are fucked, not a 'weak point'. - var/obj/item/organ/I = internal_organs_by_name["eyes"] - if(I.status & ORGAN_CUT_AWAY) - return 2 - else + var/obj/item/organ/I = internal_organs_by_name["eyes"] + if(!I || I.status & (ORGAN_CUT_AWAY|ORGAN_DESTROYED)) return 2 + var/number = 0 if(istype(src.head, /obj/item/clothing/head/welding)) if(!src.head:up) number += 2 @@ -690,8 +684,6 @@ //Used by various things that knock people out by applying blunt trauma to the head. //Checks that the species has a "head" (brain containing organ) and that hit_zone refers to it. /mob/living/carbon/human/proc/headcheck(var/target_zone, var/brain_tag = "brain") - if(!species.has_organ[brain_tag]) - return 0 var/obj/item/organ/affecting = internal_organs_by_name[brain_tag] @@ -745,38 +737,16 @@ xylophone=0 return -/mob/living/carbon/human/proc/check_has_mouth() +/mob/living/proc/check_has_mouth() + return 1 + +/mob/living/carbon/human/check_has_mouth() // Todo, check stomach organ when implemented. var/obj/item/organ/external/head/H = get_organ("head") if(!H || !H.can_intake_reagents) return 0 return 1 -/mob/living/carbon/human/proc/vomit() - - if(!check_has_mouth()) - return - - if(!lastpuke) - lastpuke = 1 - src << "You feel nauseous..." - spawn(150) //15 seconds until second warning - src << "You feel like you are about to throw up!" - spawn(100) //and you have 10 more for mad dash to the bucket - Stun(5) - - src.visible_message("[src] throws up!","You throw up!") - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - - var/turf/location = loc - if (istype(location, /turf/simulated)) - location.add_vomit_floor(src, 1) - - nutrition -= 40 - adjustToxLoss(-3) - spawn(350) //wait 35 seconds before next volley - lastpuke = 0 - /mob/living/carbon/human/proc/morph() set name = "Morph" set category = "Superpower" @@ -846,12 +816,14 @@ if(new_style) f_style = new_style - var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") + var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neutral") if (new_gender) if(new_gender == "Male") gender = MALE - else + else if(new_gender == "Female") gender = FEMALE + else + gender = NEUTER regenerate_icons() check_dna() @@ -936,13 +908,12 @@ /mob/living/carbon/human/revive() - if(species && !(species.flags & NO_BLOOD)) + if(should_have_organ("heart")) vessel.add_reagent("blood",560-vessel.total_volume) fixblood() - // Fix up all organs. - // This will ignore any prosthetics in the prefs currently. - species.create_organs(src) + species.create_organs(src) // Reset our organs/limbs. + restore_all_organs() // Reapply robotics/amputated status from preferences. if(!client || !key) //Don't boot out anyone already in the mob. for (var/obj/item/organ/brain/H in world) @@ -1057,7 +1028,7 @@ for(var/obj/item/O in organ.implants) if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad. // All kinds of embedded objects cause bleeding. - if(species.flags & NO_PAIN) + if(!can_feel_pain(organ.limb_name)) src << "You feel [O] moving inside your [organ.name]." else var/msg = pick( \ @@ -1067,7 +1038,7 @@ src << msg organ.take_damage(rand(1,3), 0, 0) - if(!(organ.status & ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //There is no blood in protheses. + if(!(organ.status & ORGAN_ROBOT) && !should_have_organ("heart")) //There is no blood in protheses. organ.status |= ORGAN_BLEEDING src.adjustToxLoss(rand(1,3)) @@ -1302,11 +1273,15 @@ /mob/living/carbon/human/getDNA() if(species.flags & NO_SCAN) return null + if(isSynthetic()) + return ..() /mob/living/carbon/human/setDNA() if(species.flags & NO_SCAN) return + if(isSynthetic()) + return ..() /mob/living/carbon/human/has_brain() @@ -1423,3 +1398,24 @@ pulling_punches = !pulling_punches src << "You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"]." return + +/mob/living/carbon/human/should_have_organ(var/organ_check) + + var/obj/item/organ/external/affecting + if(organ_check in list("heart","lungs")) + affecting = organs_by_name["chest"] + else if(organ_check in list("liver","kidneys")) + affecting = organs_by_name["groin"] + + if(affecting && (affecting.status & ORGAN_ROBOT)) + return 0 + return (species && species.has_organ[organ_check]) + +/mob/living/carbon/human/can_feel_pain(var/obj/item/organ/check_organ) + if(isSynthetic()) + return 0 + if(check_organ) + if(!istype(check_organ)) + return 0 + return check_organ.can_feel_pain() + return !(species.flags & NO_PAIN) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 377581d09b0..517bc79a414 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -13,7 +13,7 @@ total_brute += O.brute_dam total_burn += O.burn_dam - var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss()) + var/oxy_l = getOxyLoss() var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss()) var/clone_l = getCloneLoss() @@ -28,7 +28,7 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(should_have_organ("brain")) var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.take_damage(amount) @@ -42,7 +42,7 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(should_have_organ("brain")) var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.damage = min(max(amount, 0),(maxHealth*2)) @@ -56,7 +56,7 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(should_have_organ("brain")) var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(sponge) brainloss = min(sponge.damage,maxHealth*2) @@ -142,12 +142,12 @@ ..() /mob/living/carbon/human/getCloneLoss() - if(species.flags & (NO_SCAN)) + if((species.flags & NO_SCAN) || isSynthetic()) cloneloss = 0 return ..() /mob/living/carbon/human/setCloneLoss(var/amount) - if(species.flags & (NO_SCAN)) + if((species.flags & NO_SCAN) || isSynthetic()) cloneloss = 0 else ..() @@ -155,7 +155,7 @@ /mob/living/carbon/human/adjustCloneLoss(var/amount) ..() - if(species.flags & (NO_SCAN)) + if((species.flags & NO_SCAN) || isSynthetic()) cloneloss = 0 return @@ -189,37 +189,37 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/getOxyLoss() - if(species.flags & NO_BREATHE) + if(!should_have_organ("lungs")) oxyloss = 0 return ..() /mob/living/carbon/human/adjustOxyLoss(var/amount) - if(species.flags & NO_BREATHE) + if(!should_have_organ("lungs")) oxyloss = 0 else amount = amount*species.oxy_mod ..(amount) /mob/living/carbon/human/setOxyLoss(var/amount) - if(species.flags & NO_BREATHE) + if(!should_have_organ("lungs")) oxyloss = 0 else ..() /mob/living/carbon/human/getToxLoss() - if(species.flags & NO_POISON) + if((species.flags & NO_POISON) || isSynthetic()) toxloss = 0 return ..() /mob/living/carbon/human/adjustToxLoss(var/amount) - if(species.flags & NO_POISON) + if((species.flags & NO_POISON) || isSynthetic()) toxloss = 0 else amount = amount*species.toxins_mod ..(amount) /mob/living/carbon/human/setToxLoss(var/amount) - if(species.flags & NO_POISON) + if((species.flags & NO_POISON) || isSynthetic()) toxloss = 0 else ..() @@ -321,7 +321,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t This function restores the subjects blood to max. */ /mob/living/carbon/human/proc/restore_blood() - if(!(species.flags & NO_BLOOD)) + if(should_have_organ("heart")) var/blood_volume = vessel.get_reagent_amount("blood") vessel.add_reagent("blood",560.0-blood_volume) @@ -329,9 +329,9 @@ This function restores the subjects blood to max. /* This function restores all organs. */ -/mob/living/carbon/human/restore_all_organs() +/mob/living/carbon/human/restore_all_organs(var/ignore_prosthetic_prefs) for(var/obj/item/organ/external/current_organ in organs) - current_organ.rejuvenate() + current_organ.rejuvenate(ignore_prosthetic_prefs) /mob/living/carbon/human/proc/HealDamage(zone, brute, burn) var/obj/item/organ/external/E = get_organ(zone) @@ -354,14 +354,19 @@ This function restores all organs. if(Debug2) world.log << "## DEBUG: human/apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]." - //visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]") + var/obj/item/organ/external/organ = null + if(isorgan(def_zone)) + organ = def_zone + else + if(!def_zone) def_zone = ran_zone(def_zone) + organ = get_organ(check_zone(def_zone)) //Handle other types of damage if((damagetype != BRUTE) && (damagetype != BURN)) - if(damagetype == HALLOSS && !(species && (species.flags & NO_PAIN))) - if ((damage > 25 && prob(20)) || (damage > 50 && prob(60))) - emote("scream") - + if(damagetype == HALLOSS) + if((damage > 25 && prob(20)) || (damage > 50 && prob(60))) + if(organ && organ.can_feel_pain()) + emote("scream") ..(damage, damagetype, def_zone, blocked) return 1 @@ -371,12 +376,7 @@ This function restores all organs. if(blocked >= 100) return 0 - var/obj/item/organ/external/organ = null - if(isorgan(def_zone)) - organ = def_zone - else - if(!def_zone) def_zone = ran_zone(def_zone) - organ = get_organ(check_zone(def_zone)) + if(!organ) return 0 if(blocked) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e34a4de79e6..b516852074d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -61,7 +61,7 @@ emp_act emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!") else var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.name]!") + emote("me", 1, "[affected.can_feel_pain() ? "" : emote_scream]drops what they were holding in their [affected.name]!") ..(stun_amount, agony_amount, def_zone) @@ -223,7 +223,7 @@ emp_act //Harder to score a stun but if you do it lasts a bit longer if(prob(effective_force)) apply_effect(20, PARALYZE, armor) - visible_message("[src] [species.knockout_message]") + visible_message("[src] [species.get_knockout_message(src)]") else //Easier to score a stun but lasts less time if(prob(effective_force + 10)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 7ed171a1f1d..f116ae17f03 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -83,6 +83,7 @@ var/list/flavor_texts = list() var/gunshot_residue var/pulling_punches // Are you trying not to hurt your opponent? + var/full_prosthetic // We are a robutt. mob_bump_flag = HUMAN mob_push_flags = ~HEAVY diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index ca81defe0f9..c8011cb059b 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -16,7 +16,7 @@ var/health_deficiency = (100 - health) if(health_deficiency >= 40) tally += (health_deficiency / 25) - if (!(species && (species.flags & NO_PAIN))) + if(can_feel_pain()) if(halloss >= 10) tally += (halloss / 10) //halloss shouldn't slow you down if you can't even feel it var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80 @@ -42,7 +42,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) tally += 4 - if(E.status & ORGAN_SPLINTED) + else if(E.status & ORGAN_SPLINTED) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index d69f6e57cc2..cab9b5a1c2a 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -68,6 +68,7 @@ if (istype(buckled, /obj/structure/bed)) return + var/limb_pain for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot")) var/obj/item/organ/external/E = organs_by_name[limb_tag] if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD))) @@ -88,6 +89,8 @@ else if (E.is_dislocated()) stance_damage += 0.5 + if(E) limb_pain = E.can_feel_pain() + // Canes and crutches help you stand (if the latter is ever added) // One cane mitigates a broken leg+foot, or a missing foot. // Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you. @@ -99,7 +102,7 @@ // standing is poor if(stance_damage >= 4 || (stance_damage >= 2 && prob(5))) if(!(lying || resting)) - if(species && !(species.flags & NO_PAIN)) + if(limb_pain) emote("scream") custom_emote(1, "collapses!") Weaken(5) //can't emote while weakened, apparently. @@ -145,7 +148,7 @@ drop_from_inventory(r_hand) var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!") + emote("me", 1, "[(E.can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") else if(E.is_malfunctioning()) switch(E.body_part) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index ae66cf3fe0e..c3d0568b808 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -40,7 +40,6 @@ This saves us from having to call add_fingerprint() any time something is put in /mob/living/carbon/human/proc/has_organ(name) var/obj/item/organ/external/O = organs_by_name[name] - return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump()) /mob/living/carbon/human/proc/has_organ_for_slot(slot) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 97327c4bbdb..8e77023fe7a 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -254,6 +254,12 @@ radiation = Clamp(radiation,0,100) if (radiation) + + // TODO. + if(isSynthetic()) + radiation = 0 + return + var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs if(rad_organ && !rad_organ.is_broken()) var/rads = radiation/25 @@ -365,7 +371,7 @@ var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa // Lung damage increases the minimum safe pressure. - if(species.has_organ["lungs"]) + if(should_have_organ("lungs")) var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] if(isnull(L)) safe_pressure_min = INFINITY //No lungs, how are you breathing? @@ -831,6 +837,7 @@ return min(1,thermal_protection) /mob/living/carbon/human/handle_chemicals_in_body() + if(in_stasis) return @@ -838,43 +845,48 @@ chem_effects.Cut() analgesic = 0 - if(touching) touching.metabolize() - if(ingested) ingested.metabolize() - if(bloodstr) bloodstr.metabolize() + if(!isSynthetic()) + + if(touching) touching.metabolize() + if(ingested) ingested.metabolize() + if(bloodstr) bloodstr.metabolize() - if(CE_PAINKILLER in chem_effects) - analgesic = chem_effects[CE_PAINKILLER] + if(CE_PAINKILLER in chem_effects) + analgesic = chem_effects[CE_PAINKILLER] - var/total_phoronloss = 0 - for(var/obj/item/I in src) - if(I.contaminated) - total_phoronloss += vsc.plc.CONTAMINATION_LOSS - if(!(status_flags & GODMODE)) adjustToxLoss(total_phoronloss) + var/total_phoronloss = 0 + for(var/obj/item/I in src) + if(I.contaminated) + total_phoronloss += vsc.plc.CONTAMINATION_LOSS + if(!(status_flags & GODMODE)) adjustToxLoss(total_phoronloss) if(status_flags & GODMODE) return 0 //godmode var/obj/item/organ/diona/node/light_organ = locate() in internal_organs - if(light_organ && !light_organ.is_broken()) - var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing - if(isturf(loc)) //else, there's considered to be no light - var/turf/T = loc - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - if(L) - light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights - else - light_amount = 5 - nutrition += light_amount - traumatic_shock -= light_amount - - if(species.flags & IS_PLANT) - if(nutrition > 450) - nutrition = 450 - if(light_amount >= 3) //if there's enough light, heal - adjustBruteLoss(-(round(light_amount/2))) - adjustFireLoss(-(round(light_amount/2))) - adjustToxLoss(-(light_amount)) - adjustOxyLoss(-(light_amount)) - //TODO: heal wounds, heal broken limbs. + + if(!isSynthetic()) + if(light_organ && !light_organ.is_broken()) + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(loc)) //else, there's considered to be no light + var/turf/T = loc + var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T + if(L) + light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights + else + light_amount = 5 + nutrition += light_amount + traumatic_shock -= light_amount + + if(species.flags & IS_PLANT) + if(nutrition > 450) + nutrition = 450 + + if(light_amount >= 3) //if there's enough light, heal + adjustBruteLoss(-(round(light_amount/2))) + adjustFireLoss(-(round(light_amount/2))) + adjustToxLoss(-(light_amount)) + adjustOxyLoss(-(light_amount)) + //TODO: heal wounds, heal broken limbs. if(species.light_dam) var/light_amount = 0 @@ -901,13 +913,14 @@ if(overeatduration > 1) overeatduration -= 2 //doubled the unfat rate - if(species.flags & IS_PLANT && (!light_organ || light_organ.is_broken())) + if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken())) if(nutrition < 200) take_overall_damage(2,0) traumatic_shock++ // TODO: stomach and bloodstream organ. - handle_trace_chems() + if(!isSynthetic()) + handle_trace_chems() updatehealth() @@ -920,7 +933,7 @@ if(status_flags & GODMODE) return 0 //SSD check, if a logged player is awake put them back to sleep! - if(species.show_ssd && !client && !teleop) + if(species.get_ssd(src) && !client && !teleop) Sleeping(2) if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP blinded = 1 @@ -928,7 +941,7 @@ else //ALIVE. LIGHTS ARE ON updatehealth() //TODO - if(health <= config.health_threshold_dead || (species.has_organ["brain"] && !has_brain())) + if(health <= config.health_threshold_dead || (should_have_organ("brain") && !has_brain())) death() blinded = 1 silent = 0 @@ -1248,7 +1261,7 @@ if(2) healths.icon_state = "health7" else //switch(health - halloss) - switch(100 - ((species.flags & NO_PAIN) ? 0 : traumatic_shock)) + switch(100 - (!can_feel_pain() ? 0 : traumatic_shock)) if(100 to INFINITY) healths.icon_state = "health0" if(80 to 100) healths.icon_state = "health1" if(60 to 80) healths.icon_state = "health2" @@ -1410,7 +1423,7 @@ // Puke if toxloss is too high if(!stat) if (getToxLoss() >= 45 && nutrition > 20) - vomit() + spawn vomit() //0.1% chance of playing a scary sound to someone who's in complete darkness if(isturf(loc) && rand(1,1000) == 1) @@ -1484,7 +1497,7 @@ /mob/living/carbon/human/handle_shock() ..() if(status_flags & GODMODE) return 0 //godmode - if(species && species.flags & NO_PAIN) return + if(!can_feel_pain()) return if(health < config.health_threshold_softcrit)// health 0 makes you immediately collapse shock_stage = max(shock_stage, 61) @@ -1535,7 +1548,7 @@ /mob/living/carbon/human/proc/handle_pulse() if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) - if(species && species.flags & NO_BLOOD) + if(!internal_organs_by_name["heart"]) return PULSE_NONE //No blood, no pulse. if(stat == DEAD) @@ -1566,12 +1579,12 @@ return temp /mob/living/carbon/human/proc/handle_heartbeat() - if(pulse == PULSE_NONE || !species.has_organ["heart"]) + if(pulse == PULSE_NONE) return var/obj/item/organ/heart/H = internal_organs_by_name["heart"] - if(!H || H.robotic >=2 ) + if(!H || (H.status & ORGAN_ROBOT)) return if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space)) @@ -1734,7 +1747,7 @@ return slurring /mob/living/carbon/human/handle_stunned() - if(species.flags & NO_PAIN) + if(!can_feel_pain()) stunned = 0 return 0 if(..()) diff --git a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm index 87fe13fb1da..8820ffaf5bd 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm @@ -18,7 +18,7 @@ remains_type = /obj/effect/decal/cleanable/ash death_message = "dissolves into ash..." - flags = NO_BLOOD | NO_SCAN | NO_SLIP | NO_POISON | NO_MINOR_CUT + flags = NO_SCAN | NO_SLIP | NO_POISON | NO_MINOR_CUT spawn_flags = IS_RESTRICTED /datum/species/shadow/handle_death(var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index fa7dda8f576..c1c335a22d7 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -25,7 +25,6 @@ cold_level_2 = 50 cold_level_3 = 0 - eyes = "vox_eyes_s" gluttonous = 2 breath_type = "nitrogen" @@ -45,6 +44,21 @@ /mob/living/carbon/human/proc/leap ) + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest), + "groin" = list("path" = /obj/item/organ/external/groin), + "head" = list("path" = /obj/item/organ/external/head/vox), + "l_arm" = list("path" = /obj/item/organ/external/arm), + "r_arm" = list("path" = /obj/item/organ/external/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/leg), + "r_leg" = list("path" = /obj/item/organ/external/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/hand), + "r_hand" = list("path" = /obj/item/organ/external/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/foot), + "r_foot" = list("path" = /obj/item/organ/external/foot/right) + ) + + has_organ = list( "heart" = /obj/item/organ/heart, "lungs" = /obj/item/organ/lungs, diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index d6e32722b1d..c0722fbca9d 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -19,7 +19,6 @@ var/blood_mask = 'icons/mob/human_races/masks/blood_human.dmi' var/prone_icon // If set, draws this from icobase when mob is prone. - var/eyes = "eyes_s" // Icon for eyes. var/blood_color = "#A10808" // Red. var/flesh_color = "#FFC896" // Pink. var/base_color // Used by changelings. Should also be used for icon previes.. @@ -85,7 +84,7 @@ var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning. var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure. var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative. - var/body_temperature = 310.15 // Non-IS_SYNTHETIC species will try to stabilize at this temperature. + var/body_temperature = 310.15 // Species will try to stabilize at this temperature. // (also affects temperature processing) var/heat_discomfort_level = 315 // Aesthetic messages about feeling warm. @@ -177,6 +176,24 @@ /datum/species/proc/get_bodytype() return name +/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message) + +/datum/species/proc/get_death_message(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message) + +/datum/species/proc/get_ssd(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd) + +/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? "#1F181F" : blood_color) + +/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? 1 : virus_immune) + +/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H) + return ((H && H.isSynthetic()) ? "#575757" : flesh_color) + /datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type) if(!prob(5)) diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index fae7d834e5c..7faf868ac29 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -7,7 +7,7 @@ language = "Sol Common" //todo? unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch) - flags = NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN | NO_POISON | NO_MINOR_CUT + flags = NO_PAIN | NO_SCAN | NO_POISON | NO_MINOR_CUT spawn_flags = IS_RESTRICTED siemens_coefficient = 0 diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index d9d8347550c..77a5f942f0a 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -15,8 +15,6 @@ has_fine_manipulation = 0 show_ssd = null - eyes = "blank_eyes" - gibbed_anim = "gibbed-m" dusted_anim = "dust-m" death_message = "lets out a faint chimper as it collapses and stops moving..." @@ -40,6 +38,20 @@ pass_flags = PASSTABLE + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest), + "groin" = list("path" = /obj/item/organ/external/groin), + "head" = list("path" = /obj/item/organ/external/head/no_eyes), + "l_arm" = list("path" = /obj/item/organ/external/arm), + "r_arm" = list("path" = /obj/item/organ/external/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/leg), + "r_leg" = list("path" = /obj/item/organ/external/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/hand), + "r_hand" = list("path" = /obj/item/organ/external/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/foot), + "r_foot" = list("path" = /obj/item/organ/external/foot/right) + ) + /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) if(H.stat != CONSCIOUS) return diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm index 38db9549323..96a926b14ea 100644 --- a/code/modules/mob/living/carbon/human/species/station/slime.dm +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -8,7 +8,7 @@ language = null //todo? unarmed_types = list(/datum/unarmed_attack/slime_glomp) - flags = NO_SCAN | NO_SLIP | NO_BREATHE | NO_MINOR_CUT + flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT spawn_flags = IS_RESTRICTED siemens_coefficient = 3 //conductive darksight = 3 diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index e5b3ae6b0f4..5fecc7c79bf 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -131,7 +131,6 @@ name_plural = "Skrell" icobase = 'icons/mob/human_races/r_skrell.dmi' deform = 'icons/mob/human_races/r_def_skrell.dmi' - eyes = "skrell_eyes_s" primitive_form = "Neaera" unarmed_types = list(/datum/unarmed_attack/punch) blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ @@ -152,6 +151,20 @@ reagent_tag = IS_SKRELL + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest), + "groin" = list("path" = /obj/item/organ/external/groin), + "head" = list("path" = /obj/item/organ/external/head/skrell), + "l_arm" = list("path" = /obj/item/organ/external/arm), + "r_arm" = list("path" = /obj/item/organ/external/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/leg), + "r_leg" = list("path" = /obj/item/organ/external/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/hand), + "r_hand" = list("path" = /obj/item/organ/external/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/foot), + "r_foot" = list("path" = /obj/item/organ/external/foot/right) + ) + /datum/species/diona name = "Diona" name_plural = "Dionaea" @@ -164,7 +177,6 @@ rarity_value = 3 hud_type = /datum/hud_data/diona siemens_coefficient = 0.3 - eyes = "blank_eyes" show_ssd = "completely quiescent" num_alternate_languages = 1 name_language = "Rootspeak" @@ -189,7 +201,7 @@ has_limbs = list( "chest" = list("path" = /obj/item/organ/external/diona/chest), "groin" = list("path" = /obj/item/organ/external/diona/groin), - "head" = list("path" = /obj/item/organ/external/diona/head), + "head" = list("path" = /obj/item/organ/external/head/no_eyes/diona), "l_arm" = list("path" = /obj/item/organ/external/diona/arm), "r_arm" = list("path" = /obj/item/organ/external/diona/arm/right), "l_leg" = list("path" = /obj/item/organ/external/diona/leg), @@ -217,7 +229,7 @@ body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not - flags = NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | NO_MINOR_CUT + flags = NO_SCAN | IS_PLANT | NO_PAIN | NO_SLIP | NO_MINOR_CUT spawn_flags = CAN_JOIN | IS_WHITELISTED blood_color = "#004400" @@ -254,82 +266,4 @@ else qdel(D) - H.visible_message("[H] splits apart with a wet slithering noise!") - -/datum/species/machine - name = "Machine" - name_plural = "machines" - - blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ - robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ - to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ - generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ - inhuman in outlook and perspective." - - icobase = 'icons/mob/human_races/r_machine.dmi' - deform = 'icons/mob/human_races/r_machine.dmi' - - language = "Encoded Audio Language" - unarmed_types = list(/datum/unarmed_attack/punch) - rarity_value = 2 - num_alternate_languages = 1 // potentially could be 2? - name_language = "Encoded Audio Language" - - eyes = "blank_eyes" - brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150% - burn_mod = 1.875 // So they take 50% extra damage from brute/burn overall. - show_ssd = "flashing a 'system offline' glyph on their monitor" - death_message = "gives one shrill beep before falling lifeless." - knockout_message = "encounters a hardware fault and suddenly reboots!" - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 500 // Gives them about 25 seconds in space before taking damage - heat_level_2 = 1000 - heat_level_3 = 2000 - - passive_temp_gain = 10 // This should cause IPCs to stabilize at ~80 C in a 20 C environment. - - flags = NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_POISON - spawn_flags = CAN_JOIN | IS_WHITELISTED - - blood_color = "#1F181F" - flesh_color = "#575757" - virus_immune = 1 - reagent_tag = IS_MACHINE - - has_organ = list( - "brain" = /obj/item/organ/mmi_holder/posibrain, - "cell" = /obj/item/organ/cell, - "optics" = /obj/item/organ/optical_sensor - ) - - vision_organ = "optics" - - has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest/ipc), - "groin" = list("path" = /obj/item/organ/external/groin/ipc), - "head" = list("path" = /obj/item/organ/external/head/ipc), - "l_arm" = list("path" = /obj/item/organ/external/arm/ipc), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc), - "l_leg" = list("path" = /obj/item/organ/external/leg/ipc), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc), - "l_hand" = list("path" = /obj/item/organ/external/hand/ipc), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc), - "l_foot" = list("path" = /obj/item/organ/external/foot/ipc), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc) - ) - -/datum/species/machine/handle_death(var/mob/living/carbon/human/H) - ..() - H.h_style = "" - spawn(100) - if(H) H.update_hair() - -/datum/species/machine/sanitize_name(var/name) - return sanitizeName(name, allow_numbers = 1) + H.visible_message("\The [H] splits apart with a wet slithering noise!") diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index 1c5e88ce59c..5f6ab38fad5 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -13,8 +13,6 @@ siemens_coefficient = 0 gluttonous = 3 - eyes = "blank_eyes" - brute_mod = 0.5 // Hardened carapace. burn_mod = 2 // Weak to fire. @@ -25,7 +23,7 @@ cold_level_2 = -1 cold_level_3 = -1 - flags = NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT + flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT spawn_flags = IS_RESTRICTED reagent_tag = IS_XENOS @@ -62,6 +60,20 @@ var/weeds_heal_rate = 1 // Health regen on weeds. var/weeds_plasma_rate = 5 // Plasma regen on weeds. + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest), + "groin" = list("path" = /obj/item/organ/external/groin), + "head" = list("path" = /obj/item/organ/external/head/no_eyes), + "l_arm" = list("path" = /obj/item/organ/external/arm), + "r_arm" = list("path" = /obj/item/organ/external/arm/right), + "l_leg" = list("path" = /obj/item/organ/external/leg), + "r_leg" = list("path" = /obj/item/organ/external/leg/right), + "l_hand" = list("path" = /obj/item/organ/external/hand), + "r_hand" = list("path" = /obj/item/organ/external/hand/right), + "l_foot" = list("path" = /obj/item/organ/external/foot), + "r_foot" = list("path" = /obj/item/organ/external/foot/right) + ) + /datum/species/xenos/get_bodytype() return "Xenomorph" diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 92a6089e9f5..f6ecb54ce5b 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -54,7 +54,7 @@ var/global/list/sparring_attack_cache = list() if("l_arm", "l_hand") if (target.l_hand) // Disarm left hand - //Urist McAssistant dropped the macguffin with a scream just sounds odd. Plus it doesn't work with NO_PAIN + //Urist McAssistant dropped the macguffin with a scream just sounds odd. target.visible_message("\The [target.l_hand] was knocked right out of [target]'s grasp!") target.drop_l_hand() if("r_arm", "r_hand") @@ -94,10 +94,13 @@ var/global/list/sparring_attack_cache = list() /datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target) var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] - eyes.take_damage(rand(3,4), 1) - - user.visible_message("[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!") - target << "You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]" + if(eyes) + eyes.take_damage(rand(3,4), 1) + user.visible_message("[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!") + var/eye_pain = eyes.can_feel_pain() + target << "You experience[(eye_pain) ? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(eye_pain)? "." : "!"]" + return + user.visible_message("[user] attempts to press \his [eye_attack_text] into [target]'s eyes, but they don't have any!") /datum/unarmed_attack/bite attack_verb = list("bit") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 8fab9318878..cc112b18d93 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -209,11 +209,11 @@ var/global/list/damage_icon_parts = list() O.update_icon() if(O.damage_state == "00") continue var/icon/DI - var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]" + var/cache_index = "[O.damage_state]/[O.icon_name]/[O.species.get_blood_colour()]/[species.get_bodytype()]" if(damage_icon_parts[cache_index] == null) DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels - DI.Blend(species.blood_color, ICON_MULTIPLY) + DI.Blend(O.species.get_blood_colour(), ICON_MULTIPLY) damage_icon_parts[cache_index] = DI else DI = damage_icon_parts[cache_index] diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm index 8b8e875aecb..2e1cc295950 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/metroid/powers.dm @@ -63,7 +63,7 @@ H.custom_pain(painMes) else if (istype(M, /mob/living/carbon)) var/mob/living/carbon/C = M - if (!(C.species && (C.species.flags & NO_PAIN))) + if (C.can_feel_pain()) M << "[painMes]" gain_nutrition(rand(20,25)) diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index be31d280348..92eccc66df8 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -3,7 +3,7 @@ // proc to find out in how much pain the mob is at the moment /mob/living/carbon/proc/updateshock() - if (species && (species.flags & NO_PAIN)) + if (!can_feel_pain()) src.traumatic_shock = 0 return 0 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ef7a33fd406..f575c6303d1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -813,3 +813,51 @@ default behaviour is: ear_damage = damage if(deaf >= 0) ear_deaf = deaf + +/mob/living/proc/vomit(var/skip_wait, var/blood_vomit) + + if(isSynthetic()) + src << "A sudden, dizzying wave of internal feedback rushes over you!" + src.Weaken(5) + return + + if(!check_has_mouth()) + return + + if(!lastpuke) + + if (nutrition <= 100) + src << "You gag as you want to throw up, but there's nothing in your stomach!" + src.Weaken(10) + src.adjustToxLoss(3) + return + + lastpuke = 1 + src << "You feel nauseous..." + + if(!skip_wait) + sleep(150) //15 seconds until second warning + src << "You feel like you are about to throw up!" + sleep(100) //and you have 10 more for mad dash to the bucket + + Stun(5) + src.visible_message("[src] throws up!","You throw up!") + playsound(loc, 'sound/effects/splat.ogg', 50, 1) + + var/turf/simulated/T = get_turf(src) + if(istype(T)) + if(blood_vomit) + T.add_blood_floor(src) + else + T.add_vomit_floor(src, 1) + + if(blood_vomit) + if(getBruteLoss() < 50) + adjustBruteLoss(3) + else + nutrition -= 40 + adjustToxLoss(-3) + + sleep(350) + lastpuke = 0 + diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 5a671afe992..c547211ecf4 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -43,3 +43,4 @@ var/fire_stacks var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks. + var/lastpuke = 0 diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 6b38a7c4652..14434bfe6e9 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -30,7 +30,7 @@ var/list/mob_hat_cache = list() universal_understand = 1 gender = NEUTER pass_flags = PASSTABLE - braintype = "Robot" + braintype = "Drone" lawupdate = 0 density = 1 req_access = list(access_engine, access_robotics) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 8507053e232..293a55b2224 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -247,7 +247,7 @@ if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately. src << "\red Crisis mode active. Combat module available." modules+="Combat" - modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules + modtype = input("Please, select a module!", "Robot module", null, null) as null|anything in modules if(module) return @@ -267,9 +267,9 @@ modtype = prefix if(istype(mmi, /obj/item/device/mmi/digital/posibrain)) - braintype = "Android" - else if(istype(mmi, /obj/item/device/mmi/digital/robot)) braintype = "Robot" + else if(istype(mmi, /obj/item/device/mmi/digital/robot)) + braintype = "Drone" else braintype = "Cyborg" @@ -911,7 +911,7 @@ if(!(icontype in module_sprites)) icontype = module_sprites[1] else - icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot", icontype, null) in module_sprites + icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot Icon", icontype, null) in module_sprites icon_state = module_sprites[icontype] updateicon() diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index 88be25cc245..05bf7e8eefb 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -77,7 +77,7 @@ if(!E || (E.status & ORGAN_DESTROYED)) src << "\The [H] does not have a head!" - if(!H.species.has_organ["brain"]) + if(!H.should_have_organ("brain")) src << "\The [H] does not seem to have an ear canal to breach." return diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 7885d3e8f73..9503800189c 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -87,7 +87,6 @@ var/canmove = 1 //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas. - var/lastpuke = 0 var/unacidable = 0 var/list/pinned = list() // List of things pinning this creature to walls (see living_defense.dm) var/list/embedded = list() // Embedded items, since simple mobs don't have organs. diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index 44303241dbd..fb51bc15722 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -99,7 +99,7 @@ if(!armor && target.headcheck("head") && prob(damage)) target.apply_effect(20, PARALYZE) - target.visible_message("[target] [target.species.knockout_message]") + target.visible_message("[target] [target.species.get_knockout_message(target)]") playsound(attacker.loc, "swing_hit", 25, 1, -1) attacker.attack_log += text("\[[time_stamp()]\] Headbutted [target.name] ([target.ckey])") diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index a3f81168b78..d20fe8bee22 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -3,8 +3,18 @@ datum/preferences proc/randomize_appearance_for(var/mob/living/carbon/human/H) gender = pick(MALE, FEMALE) s_tone = random_skin_tone() - h_style = random_hair_style(gender, species) - f_style = random_facial_hair_style(gender, species) + + var/use_head_species + var/obj/item/organ/external/head/temp_head = H.get_organ("head") + if(temp_head) + use_head_species = temp_head.species.get_bodytype() + else + use_head_species = H.species.get_bodytype() + + if(use_head_species) + h_style = random_hair_style(gender, species) + f_style = random_facial_hair_style(gender, species) + randomize_hair_color("hair") randomize_hair_color("facial") randomize_eyes_color() @@ -191,37 +201,58 @@ datum/preferences else icobase = 'icons/mob/human_races/r_human.dmi' - preview_icon = new /icon(icobase, "torso_[g]") - preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY) - preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY) - - for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) - if(organ_data[name] == "amputated") continue + preview_icon = new /icon(icobase, "") + for(var/name in list("torso", "groin", "head", "r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) + if(organ_data[name] == "amputated") + continue if(organ_data[name] == "cyborg") var/datum/robolimb/R if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] if(!R) R = basic_robolimb - preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. + if(name in list("torso", "groin", "head")) + preview_icon.Blend(icon(R.icon, "[name]_[g]"), ICON_OVERLAY) + else + preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) continue - preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) + var/icon/limb_icon + if(name in list("torso", "groin", "head")) + limb_icon = new /icon(icobase, "[name]_[g]") + else + limb_icon = new /icon(icobase, "[name]") + // Skin color + if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR)) + limb_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + // Skin tone + if(current_species && (current_species.appearance_flags & HAS_SKIN_TONE)) + if (s_tone >= 0) + limb_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) + else + limb_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + preview_icon.Blend(limb_icon, ICON_OVERLAY) //Tail if(current_species && (current_species.tail)) var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s") + if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR)) + temp.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + if(current_species && (current_species.appearance_flags & HAS_SKIN_TONE)) + if (s_tone >= 0) + temp.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) + else + temp.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) preview_icon.Blend(temp, ICON_OVERLAY) - // Skin color - if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR)) - preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - - // Skin tone - if(current_species && (current_species.appearance_flags & HAS_SKIN_TONE)) - if (s_tone >= 0) - preview_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) - else - preview_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) - - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = current_species ? current_species.eyes : "eyes_s") + // This is absolute garbage but whatever. It will do until this entire file can be rewritten without crashes. + var/use_eye_icon = "eyes_s" + var/list/use_eye_data = current_species.has_limbs["head"] + if(islist(use_eye_data)) + var/use_eye_path = use_eye_data["path"] + var/obj/item/organ/external/head/temp_head = new use_eye_path () + if(istype(temp_head)) + use_eye_icon = temp_head.eye_icon + qdel(temp_head) + + var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = use_eye_icon) if ((current_species && (current_species.appearance_flags & HAS_EYE_COLOR))) eyes_s.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 10b9d0ebbf7..f200766179b 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -145,9 +145,9 @@ O.loc = loc O.job = "Cyborg" if(O.mind.assigned_role == "Cyborg") - if(O.mind.role_alt_title == "Android") + if(O.mind.role_alt_title == "Robot") O.mmi = new /obj/item/device/mmi/digital/posibrain(O) - else if(O.mind.role_alt_title == "Robot") + else if(O.mind.role_alt_title == "Drone") O.mmi = new /obj/item/device/mmi/digital/robot(O) else O.mmi = new /obj/item/device/mmi(O) diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index ebc490601d3..74d2cebce00 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -19,7 +19,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 vessel = new/datum/reagents(600) vessel.my_atom = src - if(species && species.flags & NO_BLOOD) //We want the var for safety but we can do without the actual blood. + if(!should_have_organ("heart")) //We want the var for safety but we can do without the actual blood. return vessel.add_reagent("blood",560) @@ -30,7 +30,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 /mob/living/carbon/human/proc/fixblood() for(var/datum/reagent/blood/B in vessel.reagent_list) if(B.id == "blood") - B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.blood_color,"blood_type"=dna.b_type, \ + B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.get_blood_colour(src),"blood_type"=dna.b_type, \ "resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = list()) B.color = B.data["blood_colour"] @@ -39,7 +39,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 if(in_stasis) return - if(species && species.flags & NO_BLOOD) + if(!should_have_organ("heart")) return if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood. @@ -62,7 +62,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Damaged heart virtually reduces the blood volume, as the blood isn't // being pumped properly anymore. - if(species && species.has_organ["heart"]) + if(species && should_have_organ("heart")) var/obj/item/organ/heart/heart = internal_organs_by_name["heart"] if(!heart) @@ -126,7 +126,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Bleeding out var/blood_max = 0 for(var/obj/item/organ/external/temp in organs) - if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT) + if(!(temp.status & ORGAN_BLEEDING) || (temp.status & ORGAN_ROBOT)) continue for(var/datum/wound/W in temp.wounds) if(W.bleeding()) blood_max += W.damage / 40 @@ -137,7 +137,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Makes a blood drop, leaking amt units of blood from the mob /mob/living/carbon/human/proc/drip(var/amt as num) - if(species && species.flags & NO_BLOOD) //TODO: Make drips come from the reagents instead. + if(!should_have_organ("heart")) //TODO: Make drips come from the reagents instead. return if(!amt) @@ -175,7 +175,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Putting this here due to return shenanigans. if(istype(src,/mob/living/carbon/human)) var/mob/living/carbon/human/H = src - B.data["blood_colour"] = H.species.blood_color + B.data["blood_colour"] = H.species.get_blood_colour(H) B.color = B.data["blood_colour"] var/list/temp_chem = list() @@ -188,7 +188,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //For humans, blood does not appear from blue, it comes from vessels. /mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount) - if(species && species.flags & NO_BLOOD) + if(!should_have_organ("heart")) return null if(vessel.get_reagent_amount("blood") < amount) @@ -216,7 +216,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Transfers blood from reagents to vessel, respecting blood types compatability. /mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount) - if(species.flags & NO_BLOOD) + if(should_have_organ("heart")) reagents.add_reagent("blood", amount, injected.data) reagents.update_total() return diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm index a330e307a38..0ba128c1a6b 100644 --- a/code/modules/organs/misc.dm +++ b/code/modules/organs/misc.dm @@ -46,7 +46,8 @@ /obj/item/organ/stack name = "cortical stack" parent_organ = "head" - robotic = 2 + icon_state = "brain-prosthetic" + organ_tag = "stack" vital = 1 var/backup_time = 0 var/datum/mind/backup @@ -56,15 +57,5 @@ backup_time = world.time if(owner.mind) backup = owner.mind -/obj/item/organ/stack/vox - /obj/item/organ/stack/vox/stack - -/obj/item/organ/stack - name = "cortical stack" - icon_state = "brain-prosthetic" - organ_tag = "stack" - robotic = 2 - -/obj/item/organ/stack/vox name = "vox cortical stack" diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 5165108635e..63c57acb215 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -3,33 +3,37 @@ var/list/organ_cache = list() /obj/item/organ name = "organ" icon = 'icons/obj/surgery.dmi' + germ_level = 0 + + // Strings. + var/organ_tag = "organ" + var/parent_organ = "chest" + + // Appearance. var/dead_icon - var/mob/living/carbon/human/owner = null + + // Status tracking. var/status = 0 var/vital //Lose a vital limb, die immediately. var/damage = 0 // amount of damage to the organ - var/min_bruised_damage = 10 - var/min_broken_damage = 30 - var/max_damage - var/organ_tag = "organ" - - var/parent_organ = "chest" - var/robotic = 0 //For being a robot - var/rejecting // Is this organ already being rejected? - + // Reference data. + var/mob/living/carbon/human/owner = null var/list/transplant_data var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, - // links chemical IDs to number of ticks for which they'll stay in the blood - germ_level = 0 var/datum/dna/dna var/datum/species/species + // Damage vars. + var/min_bruised_damage = 10 + var/min_broken_damage = 30 + var/max_damage + var/rejecting // Is this organ already being rejected? + /obj/item/organ/Destroy() if(!owner) return ..() - if(istype(owner, /mob/living/carbon)) if((owner.internal_organs) && (src in owner.internal_organs)) owner.internal_organs -= src @@ -42,7 +46,7 @@ var/list/organ_cache = list() owner.organs_by_name -= src if(src in owner.contents) owner.contents -= src - + owner = null return ..() /obj/item/organ/proc/update_health() @@ -189,8 +193,25 @@ var/list/organ_cache = list() /obj/item/organ/proc/receive_chem(chemical as obj) return 0 -/obj/item/organ/proc/rejuvenate() +/obj/item/organ/proc/rejuvenate(var/ignore_prosthetic_prefs) damage = 0 + status = 0 + if(!ignore_prosthetic_prefs && owner && owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name) + var/status = owner.client.prefs.organ_data[organ_tag] + if(status == "assisted") + mechassist() + else if(status == "mechanical") + robotize() + +/obj/item/organ/proc/remove_rejuv() + if(owner) + owner.internal_organs -= src + owner.internal_organs_by_name[organ_tag] = null + while(null in owner.internal_organs) + owner.internal_organs -= null + while(null in owner.internal_organs_by_name) + owner.internal_organs_by_name -= null + qdel(src) /obj/item/organ/proc/is_damaged() return damage > 0 @@ -241,19 +262,13 @@ var/list/organ_cache = list() owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1) /obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc - robotic = 2 - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_CUT_AWAY - src.status &= ~ORGAN_DESTROYED - src.status |= ORGAN_ROBOT - src.status |= ORGAN_ASSISTED + status = 0 + status |= ORGAN_ASSISTED + status |= ORGAN_ROBOT /obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc - robotize() - src.status &= ~ORGAN_ROBOT - robotic = 1 + status = 0 + status |= ORGAN_ASSISTED min_bruised_damage = 15 min_broken_damage = 35 @@ -320,8 +335,6 @@ var/list/organ_cache = list() target.internal_organs |= src affected.internal_organs |= src target.internal_organs_by_name[organ_tag] = src - if(robotic) - status |= ORGAN_ROBOT /obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) @@ -335,10 +348,10 @@ var/list/organ_cache = list() /obj/item/organ/proc/bitten(mob/user) - if(robotic) + if(status & ORGAN_ROBOT) return - user << "\blue You take an experimental bite out of \the [src]." + user << "You take an experimental bite out of \the [src]." var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list blood_splatter(src,B,1) @@ -361,6 +374,9 @@ var/list/organ_cache = list() /obj/item/organ/attack_self(mob/user as mob) // Convert it to an edible form, yum yum. - if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth") + if((status & ORGAN_ROBOT) && user.a_intent == "help" && user.zone_sel.selecting == "mouth") bitten(user) return + +/obj/item/organ/proc/can_feel_pain() + return !(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) && !(species.flags & NO_PAIN) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 1e2f7d1e52a..ed9d32f122e 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -14,49 +14,57 @@ dir = SOUTH organ_tag = "limb" - var/brute_mod = 1 - var/burn_mod = 1 + // Strings + var/limb_name + + // Damage vars. + var/brute_mod = 1 // Multiplier for incoming brute damage. + var/burn_mod = 1 // As above for burn. + var/damage_state = "00" // Modifier used for generating the on-mob damage overlay for this limb. + var/brute_dam = 0 // Actual current brute damage. + var/burn_dam = 0 // Actual current burn damage. + var/last_dam = -1 + // Appearance vars. var/icon_name = null var/body_part = null var/icon_position = 0 var/model var/force_icon - var/damage_state = "00" - var/brute_dam = 0 - var/burn_dam = 0 - var/max_size = 0 - var/last_dam = -1 var/icon/mob_icon var/gendered_icon = 0 - var/limb_name - var/disfigured = 0 - var/cannot_amputate - var/cannot_break var/s_tone var/list/s_col var/list/h_col + var/body_hair + + // Wound and structural data. + var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often var/list/wounds = list() var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len! - var/perma_injury = 0 var/obj/item/organ/external/parent var/list/obj/item/organ/external/children var/list/internal_organs = list() // Internal organs of this body part - var/damage_msg = "\red You feel an intense pain" var/broken_description - var/open = 0 - var/stage = 0 - var/cavity = 0 var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails. - var/encased // Needs to be opened with a saw to access the organs. var/list/implants = list() - var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often + + // Joint/state stuff. + var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point + var/can_stand + var/disfigured = 0 + var/cannot_amputate + var/cannot_break var/joint = "joint" // Descriptive string used in dislocation. var/amputation_point // Descriptive string used in amputation. var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. - var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point - var/can_stand - var/body_hair + var/encased // Needs to be opened with a saw to access the organs. + + // Surgery vars. + var/open = 0 + var/stage = 0 + var/cavity = 0 + /obj/item/organ/external/Destroy() if(parent && parent.children) @@ -188,12 +196,6 @@ parent.children = list() parent.children.Add(src) -/obj/item/organ/external/robotize() - ..() - //robit limbs take reduced damage - brute_mod = 0.8 - burn_mod = 0.8 - /**************************************************** DAMAGE PROCS ****************************************************/ @@ -219,7 +221,7 @@ brute -= brute / 2 if(status & ORGAN_BROKEN && prob(40) && brute) - if (!(owner.species && (owner.species.flags & NO_PAIN))) + if(!((species.flags & NO_PAIN) || (status & ORGAN_ROBOT))) owner.emote("scream") //getting hit on broken hand hurts if(used_weapon) add_autopsy_data("[used_weapon]", brute + burn) @@ -316,7 +318,6 @@ if(internal) status &= ~ORGAN_BROKEN - perma_injury = 0 /*if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS)) var/obj/item/organ/external/stump/S = locate() in children @@ -333,13 +334,10 @@ /* This function completely restores a damaged organ to perfect condition. */ -/obj/item/organ/external/rejuvenate() +/obj/item/organ/external/rejuvenate(var/ignore_prosthetic_prefs) damage_state = "00" - if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic. - status = 128 - else - status = 0 - perma_injury = 0 + + status = 0 brute_dam = 0 burn_dam = 0 germ_level = 0 @@ -348,16 +346,44 @@ This function completely restores a damaged organ to perfect condition. // handle internal organs for(var/obj/item/organ/current_organ in internal_organs) - current_organ.rejuvenate() + current_organ.rejuvenate(ignore_prosthetic_prefs) // remove embedded objects and drop them on the floor for(var/obj/implanted_object in implants) if(!istype(implanted_object,/obj/item/weapon/implant)) // We don't want to remove REAL implants. Just shrapnel etc. - implanted_object.loc = owner.loc + implanted_object.loc = get_turf(src) implants -= implanted_object - owner.updatehealth() + if(owner && !ignore_prosthetic_prefs) + if(owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name) + var/status = owner.client.prefs.organ_data[limb_name] + if(status == "amputated") + remove_rejuv() + else if(status == "cyborg") + var/robodata = owner.client.prefs.rlimb_data[limb_name] + if(robodata) + robotize(robodata) + else + robotize() + owner.updatehealth() +/obj/item/organ/external/remove_rejuv() + if(owner) + owner.organs -= src + owner.organs_by_name[limb_name] = null + while(null in owner.organs) + owner.organs -= null + while(null in owner.organs_by_name) + owner.organs_by_name -= null + if(children && children.len) + for(var/obj/item/organ/external/E in children) + E.remove_rejuv() + children.Cut() + + for(var/obj/item/organ/O in contents) + O.remove_rejuv() + + qdel(src) /obj/item/organ/external/proc/createwound(var/type = CUT, var/damage) if(damage == 0) return @@ -384,13 +410,13 @@ This function completely restores a damaged organ to perfect condition. W.open_wound(damage) if(prob(25)) if(status & ORGAN_ROBOT) - owner.visible_message("\red The damage to [owner.name]'s [name] worsens.",\ - "\red The damage to your [name] worsens.",\ - "You hear the screech of abused metal.") + owner.visible_message("The damage to [owner.name]'s [name] worsens.",\ + "The damage to your [name] worsens.",\ + "You hear the screech of abused metal.") else - owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\ - "\red The wound on your [name] widens with a nasty ripping noise.",\ - "You hear a nasty ripping noise, as if flesh is being torn apart.") + owner.visible_message("The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\ + "The wound on your [name] widens with a nasty ripping noise.",\ + "You hear a nasty ripping noise, as if flesh is being torn apart.") return //Creating wound @@ -451,9 +477,6 @@ This function completely restores a damaged organ to perfect condition. if(trace_chemicals[chemID] <= 0) trace_chemicals.Remove(chemID) - if(!(status & ORGAN_BROKEN)) - perma_injury = 0 - //Infections update_germs() else @@ -629,7 +652,7 @@ Note that amputating the affected organ does in fact remove the infection from t else if(W.damage_type == BURN) burn_dam += W.damage - if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && !(H.species.flags & NO_BLOOD))) + if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ("heart"))) W.bleed_timer-- status |= ORGAN_BLEEDING @@ -638,7 +661,7 @@ Note that amputating the affected organ does in fact remove the infection from t number_wounds += W.amount //things tend to bleed if they are CUT OPEN - if (open && !clamped && (H && !(H.species.flags & NO_BLOOD))) + if (open && !clamped && (H && H.should_have_organ("heart"))) status |= ORGAN_BLEEDING //Bone fractures @@ -687,7 +710,7 @@ Note that amputating the affected organ does in fact remove the infection from t ****************************************************/ //Handles dismemberment -/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children) +/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children, var/silent) if(cannot_amputate || !owner) return @@ -762,12 +785,18 @@ Note that amputating the affected organ does in fact remove the infection from t I.loc = get_turf(src) qdel(src) if(DROPLIMB_BLUNT) - var/obj/effect/decal/cleanable/blood/gibs/gore = new victim.species.single_gib_type(get_turf(victim)) - if(victim.species.flesh_color) - gore.fleshcolor = victim.species.flesh_color - if(victim.species.blood_color) - gore.basecolor = victim.species.blood_color - gore.update_icon() + var/obj/effect/decal/cleanable/blood/gibs/gore + if(status & ORGAN_ROBOT) + gore = new /obj/effect/decal/cleanable/blood/gibs/robot(get_turf(victim)) + else + gore = new victim.species.single_gib_type(get_turf(victim)) + if(species) + if(species.get_flesh_colour()) + gore.fleshcolor = species.get_flesh_colour() + if(species.get_blood_colour()) + gore.basecolor = species.get_blood_colour() + gore.update_icon() + gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) for(var/obj/item/organ/I in internal_organs) @@ -849,15 +878,14 @@ Note that amputating the affected organ does in fact remove the infection from t if(owner) owner.visible_message(\ - "\red You hear a loud cracking sound coming from \the [owner].",\ - "\red Something feels like it shattered in your [name]!",\ - "You hear a sickening crack.") - if(owner.species && !(owner.species.flags & NO_PAIN)) + "You hear a loud cracking sound coming from \the [owner].",\ + "Something feels like it shattered in your [name]!",\ + "You hear a sickening crack.") + if(!(species.flags & NO_PAIN)) owner.emote("scream") status |= ORGAN_BROKEN broken_description = pick("broken","fracture","hairline fracture") - perma_injury = brute_dam // Fractures have a chance of getting you out of restraints if (prob(25)) @@ -891,26 +919,55 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -/obj/item/organ/external/robotize(var/company) +/obj/item/organ/external/robotize(var/company, var/ski) + + if(status & ORGAN_ROBOT) + return + ..() + brute_mod = 0.8 + burn_mod = 0.8 + + brute_mod = 0.8 + burn_mod = 0.8 if(company) model = company var/datum/robolimb/R = all_robolimbs[company] - if(species && (species.name in R.species_cannot_use)) + if(!R || (species && (species.name in R.species_cannot_use))) R = basic_robolimb if(R) force_icon = R.icon - name = "[R.company] [initial(name)]" - desc = "[R.desc]" + name = "robotic [initial(name)]" + desc = "[R.desc] It looks like it was produced by [R.company]." - dislocated = -1 //TODO, make robotic limbs a separate type, remove snowflake + dislocated = -1 cannot_break = 1 get_icon() unmutate() - for (var/obj/item/organ/external/T in children) - if(T) - T.robotize() + + for(var/obj/item/organ/external/T in children) + T.robotize(company, 1) + + if(owner) + + if(!skip_prosthetics) + owner.full_prosthetic = null // Will be rechecked next isSynthetic() call. + + for(var/obj/item/organ/thing in src.contents) + if(istype(thing)) + if(thing.vital) + continue + owner.internal_organs_by_name[thing.organ_tag] = null + owner.internal_organs.Remove(thing) + qdel(thing) + + while(null in owner.internal_organs) + owner.internal_organs -= null + while(null in owner.internal_organs_by_name) + owner.internal_organs -= null + + return 1 /obj/item/organ/external/proc/mutate() if(src.status & ORGAN_ROBOT) @@ -923,7 +980,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(owner) owner.update_body() /obj/item/organ/external/proc/get_damage() //returns total damage - return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use max_damage? + return (brute_dam+burn_dam) //could use max_damage? /obj/item/organ/external/proc/has_infected_wound() for(var/datum/wound/W in wounds) @@ -1012,13 +1069,13 @@ Note that amputating the affected organ does in fact remove the infection from t return if(owner) if(type == "brute") - owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s [name].", \ - "\red Your [name] becomes a mangled mess!", \ - "\red You hear a sickening crack.") + owner.visible_message("You hear a sickening cracking sound coming from \the [owner]'s [name].", \ + "Your [name] becomes a mangled mess!", \ + "You hear a sickening crack.") else - owner.visible_message("\red \The [owner]'s [name] melts away, turning into mangled mess!", \ - "\red Your [name] melts away!", \ - "\red You hear a sickening sizzle.") + owner.visible_message("\The [owner]'s [name] melts away, turning into mangled mess!", \ + "Your [name] melts away!", \ + "You hear a sickening sizzle.") disfigured = 1 /obj/item/organ/external/proc/get_wounds_desc() @@ -1098,6 +1155,12 @@ Note that amputating the affected organ does in fact remove the infection from t parent_organ = null encased = "ribcage" +/obj/item/organ/external/chest/robotize() + if(..()) + // Give them a new cell. + owner.internal_organs_by_name["cell"] = new /obj/item/organ/cell(owner,1) + + /obj/item/organ/external/groin name = "lower body" limb_name = "groin" @@ -1224,6 +1287,8 @@ Note that amputating the affected organ does in fact remove the infection from t gendered_icon = 1 encased = "skull" + var/eye_icon = "eyes_s" + /obj/item/organ/external/head/removed() if(owner) name = "[owner.real_name]'s head" @@ -1244,3 +1309,32 @@ Note that amputating the affected organ does in fact remove the infection from t disfigure("brute") if (burn_dam > 40) disfigure("burn") + +/obj/item/organ/external/head/skrell + eye_icon = "skrell_eyes_s" + +/obj/item/organ/external/head/resomi + eye_icon = "eyes_resomi" + +/obj/item/organ/external/head/vox + eye_icon = "vox_eyes_s" + +/obj/item/organ/external/head/no_eyes + eye_icon = "blank_eyes" + +/obj/item/organ/external/head/no_eyes/diona + max_damage = 50 + min_broken_damage = 25 + cannot_break = 1 + amputation_point = "branch" + joint = "structural ligament" + dislocated = -1 + vital = 0 + +/obj/item/organ/external/head/no_eyes/diona/removed() + var/mob/living/carbon/human/H = owner + ..() + if(!istype(H) || !H.organs || !H.organs.len) + H.death() + if(prob(50) && spawn_diona_nymph(get_turf(src))) + qdel(src) \ No newline at end of file diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index bcc8de7694c..4faa7961076 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -53,10 +53,10 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner || !owner.species) return - if(owner.species.has_organ["eyes"]) + if(owner.should_have_organ("eyes")) var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] - if(species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) + if(eye_icon) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', eye_icon) if(eyes) eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) else @@ -91,7 +91,7 @@ var/global/list/limb_icon_cache = list() var/gender if(force_icon) - mob_icon = new /icon(force_icon, "[icon_name]") + mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_f" : ""]") else if(!dna) mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]") diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index 39a8a142cf0..cfd7ec78f71 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -70,6 +70,13 @@ parent_organ = "head" var/list/eye_colour = list(0,0,0) +/obj/item/organ/eyes/robotize() + ..() + name = "optical sensor" + icon = 'icons/obj/robot_component.dmi' + icon_state = "camera" + dead_icon = "camera_broken" + /obj/item/organ/eyes/proc/update_colour() if(!owner) return @@ -109,7 +116,7 @@ if (germ_level > INFECTION_LEVEL_ONE) if(prob(1)) - owner << "\red Your skin itches." + owner << "Your skin itches." if (germ_level > INFECTION_LEVEL_TWO) if(prob(1)) spawn owner.vomit() diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm index e4e024be104..280ea53f491 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/organs/pain.dm @@ -8,9 +8,9 @@ mob/var/next_pain_time = 0 // partname is the name of a body part // amount is a num from 1 to 100 mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0) - if(stat >= 1) + if(stat >= 1) return - if(species && (species.flags & NO_PAIN)) + if(!can_feel_pain()) return if(analgesic > 40) return @@ -25,13 +25,13 @@ mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0 if(burning) switch(amount) if(1 to 10) - msg = "\red Your [partname] burns." + msg = "Your [partname] burns." if(11 to 90) flash_weak_pain() - msg = "\red Your [partname] burns badly!" + msg = "Your [partname] burns badly!" if(91 to 10000) flash_pain() - msg = "\red OH GOD! Your [partname] is on fire!" + msg = "OH GOD! Your [partname] is on fire!" else switch(amount) if(1 to 10) @@ -51,9 +51,9 @@ mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0 // message is the custom message to be displayed // flash_strength is 0 for weak pain flash, 1 for strong pain flash mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength) - if(stat >= 1) + if(stat >= 1) return - if(species.flags & NO_PAIN) + if(!can_feel_pain()) return if(reagents.has_reagent("tramadol")) return @@ -61,9 +61,9 @@ mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength) return if(analgesic) return - var/msg = "\red [message]" + var/msg = "[message]" if(flash_strength >= 1) - msg = "\red [message]" + msg = "[message]" // Anti message spam checks if(msg && ((msg != last_pain_message) || (world.time >= next_pain_time))) @@ -74,7 +74,7 @@ mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength) mob/living/carbon/human/proc/handle_pain() // not when sleeping - if(species.flags & NO_PAIN) return + if(!can_feel_pain()) return if(stat >= 2) return if(analgesic > 70) diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 774f7a5261e..47ae4757350 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -41,4 +41,3 @@ var/global/datum/robolimb/basic_robolimb company = "Morpheus Cyberkinetics" desc = "This limb is simple and functional; no effort has been made to make it look human." icon = 'icons/mob/human_races/cyberlimbs/ipc.dmi' - unavailable_at_chargen = 1 diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm index edef9801c50..5d77383d2aa 100644 --- a/code/modules/organs/subtypes/diona.dm +++ b/code/modules/organs/subtypes/diona.dm @@ -122,22 +122,6 @@ body_part = HAND_RIGHT parent_organ = "r_arm" -/obj/item/organ/external/diona/head - limb_name = "head" - icon_name = "head" - name = "head" - max_damage = 50 - min_broken_damage = 25 - w_class = 3 - body_part = HEAD - parent_organ = "chest" - -/obj/item/organ/external/diona/head/removed() - if(owner) - owner.u_equip(owner.head) - owner.u_equip(owner.l_ear) - ..() - //DIONA ORGANS. /obj/item/organ/external/diona/removed() var/mob/living/carbon/human/H = owner diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index fd94c2c7590..3d551a37601 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -1,77 +1,3 @@ -// IPC limbs. -/obj/item/organ/external/head/ipc - dislocated = -1 - can_intake_reagents = 0 - vital = 0 - max_damage = 50 //made same as arm, since it is not vital - min_broken_damage = 30 - encased = null - -/obj/item/organ/external/head/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/chest/ipc - dislocated = -1 - encased = null -/obj/item/organ/external/chest/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/groin/ipc - dislocated = -1 -/obj/item/organ/external/groin/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/arm/ipc - dislocated = -1 -/obj/item/organ/external/arm/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/arm/right/ipc - dislocated = -1 -/obj/item/organ/external/arm/right/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/leg/ipc - dislocated = -1 -/obj/item/organ/external/leg/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/leg/right/ipc - dislocated = -1 -/obj/item/organ/external/leg/right/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/foot/ipc - dislocated = -1 -/obj/item/organ/external/foot/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/foot/right/ipc - dislocated = -1 -/obj/item/organ/external/foot/right/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/hand/ipc - dislocated = -1 -/obj/item/organ/external/hand/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - -/obj/item/organ/external/hand/right/ipc - dislocated = -1 -/obj/item/organ/external/hand/right/ipc/New() - robotize("Morpheus Cyberkinetics") - ..() - /obj/item/organ/cell name = "microbattery" desc = "A small, powerful cell for use in fully prosthetic bodies." @@ -92,34 +18,59 @@ owner.stat = 0 owner.visible_message("\The [owner] twitches visibly!") -/obj/item/organ/optical_sensor - name = "optical sensor" - organ_tag = "eyes" - parent_organ = "head" - icon = 'icons/obj/robot_component.dmi' - icon_state = "camera" - dead_icon = "camera_broken" - -/obj/item/organ/optical_sensor/New() - robotize() - ..() - // Used for an MMI or posibrain being installed into a human. /obj/item/organ/mmi_holder name = "brain" organ_tag = "brain" - parent_organ = "chest" + parent_organ = "head" vital = 1 var/obj/item/device/mmi/stored_mmi +/obj/item/organ/mmi_holder/Destroy() + stored_mmi = null + return ..() + +/obj/item/organ/mmi_holder/New() + ..() + if(!stored_mmi) + stored_mmi = new(src) + + spawn(1) + + if(!owner) + if(stored_mmi) + stored_mmi.loc = get_turf(src) + qdel(src) + return + + update_from_mmi() + if(stored_mmi.brainmob && owner && owner.stat == DEAD) + owner.stat = 0 + owner.visible_message("\The [owner] twitches visibly!") + /obj/item/organ/mmi_holder/proc/update_from_mmi() + if(!stored_mmi) return + + if(!stored_mmi.brainmob) + stored_mmi.brainmob = new(src) + + stored_mmi.brainmob.real_name = owner.name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + + if(owner) + stored_mmi.name = "[initial(stored_mmi.name)] ([owner.name])" + name = stored_mmi.name desc = stored_mmi.desc icon = stored_mmi.icon icon_state = stored_mmi.icon_state +/obj/item/organ/mmi_holder/removed() + update_from_mmi() + return ..() + /obj/item/organ/mmi_holder/removed(var/mob/living/user) if(stored_mmi) @@ -133,25 +84,9 @@ holder_mob.drop_from_inventory(src) qdel(src) -/obj/item/organ/mmi_holder/New() - ..() - // This is very ghetto way of rebooting an IPC. TODO better way. - spawn(1) - if(owner && owner.stat == DEAD) - owner.stat = 0 - owner.visible_message("\The [owner] twitches visibly!") +/obj/item/organ/mmi_holder/posibrain + name = "positronic brain" /obj/item/organ/mmi_holder/posibrain/New() - robotize() stored_mmi = new /obj/item/device/mmi/digital/posibrain(src) ..() - spawn(1) - if(owner) - stored_mmi.name = "positronic brain ([owner.name])" - stored_mmi.brainmob.real_name = owner.name - stored_mmi.brainmob.name = stored_mmi.brainmob.real_name - stored_mmi.icon_state = "posibrain-occupied" - update_from_mmi() - else - stored_mmi.loc = get_turf(src) - qdel(src) \ No newline at end of file diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 25c8c4827fa..12c48a78262 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -119,6 +119,7 @@ By design, d1 is the smallest direction and d2 is the highest // - Cable coil : merge cables // - Multitool : get the power currently passing through the cable // + /obj/structure/cable/attackby(obj/item/W, mob/user) var/turf/T = src.loc @@ -512,14 +513,18 @@ obj/structure/cable/proc/cableColor(var/colorC) /////////////////////////////////// //you can use wires to heal robotics +/obj/item/stack/cable_coil/attack(var/atom/A, var/mob/living/user, var/def_zone) + if(ishuman(A) && user.a_intent == I_HELP) + return + return ..() + /obj/item/stack/cable_coil/afterattack(var/mob/M, var/mob/user) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] - if (!S) return - if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) + if(!S || !(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) return ..() if(S.burn_dam) @@ -528,10 +533,9 @@ obj/structure/cable/proc/cableColor(var/colorC) user.visible_message("\The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].") else if(S.open != 2) user << "The damage is far too severe to patch over externally." - return 1 else if(S.open != 2) user << "Nothing to fix!" - + return else return ..() diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index c643e94dcc4..45e8910b38c 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -67,9 +67,13 @@ if(M.gender == MALE) H.gender = MALE H.name = pick(first_names_male) - else + else if(M.gender == FEMALE) H.gender = FEMALE H.name = pick(first_names_female) + else + H.gender = NEUTER + H.name = pick(first_names_female|first_names_male) + H.name += " [pick(last_names)]" H.real_name = H.name diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index 4ed12a28464..f13c2169453 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -70,8 +70,10 @@ infect_virus2(M, V.getcopy()) /datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - if(alien == IS_MACHINE) - return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.check_is_prosthetic()) + return if(data && data["viruses"]) for(var/datum/disease/D in data["viruses"]) if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 87897fd9a88..88f314c99d0 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -328,7 +328,7 @@ if(affecting.take_damage(0, removed * power * 0.1)) H.UpdateDamageIcon() if(prob(100 * removed / meltdose)) // Applies disfigurement - if (!(H.species && (H.species.flags & NO_PAIN))) + if (affecting.can_feel_pain()) H.emote("scream") H.status_flags |= DISFIGURED else diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 0bfa1b40067..6c169852b94 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -233,12 +233,13 @@ M.adjustToxLoss(0.5 * removed) /datum/reagent/capsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - if(alien == IS_DIONA || alien == IS_MACHINE) + if(alien == IS_DIONA) return if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && (H.species.flags & (NO_PAIN))) + if(!H.can_feel_pain()) return + if(dose < 5 && (dose == metabolism || prob(5))) M << "Your insides feel uncomfortably hot!" if(dose >= 5) @@ -268,7 +269,7 @@ var/obj/item/safe_thing = null if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(H.species && (H.species.flags & NO_PAIN)) + if(!H.can_feel_pain()) return if(H.head) if(H.head.body_parts_covered & EYES) @@ -314,7 +315,7 @@ /datum/reagent/condensedcapsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && (H.species.flags & (NO_PAIN))) + if(!H.can_feel_pain()) return if(dose == metabolism) M << "You feel like your insides are burning!" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 1c4abbdfe83..b392e789e08 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -274,7 +274,7 @@ var/mob/living/carbon/human/H = M for(var/obj/item/organ/I in H.internal_organs) - if((I.damage > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs + if((I.damage > 0) && !(I.status & ORGAN_ROBOT)) //Peridaxon heals only non-robotic organs I.damage = max(I.damage - removed, 0) /datum/reagent/ryetalyn diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index d981734ec94..3de830f6448 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -234,9 +234,14 @@ affect_blood(M, alien, removed) /datum/reagent/mutagen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + + if(M.isSynthetic()) + return + var/mob/living/carbon/human/H = M if(istype(H) && (H.species.flags & NO_SCAN)) return + if(M.dna) if(prob(removed * 0.1)) // Approx. one mutation per 10 injected/20 ingested/30 touching units randmuti(M) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 19ac8c62fbc..75ef62894dd 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -96,7 +96,7 @@ var/datum/reagent/B if(istype(T, /mob/living/carbon/human)) var/mob/living/carbon/human/H = T - if(H.species && H.species.flags & NO_BLOOD) + if(H.species && !H.should_have_organ("heart")) H.reagents.trans_to_obj(src, amount) else B = T.take_blood(src, amount) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 25addbd40a4..823561b5d87 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -142,7 +142,6 @@ affected.status &= ~ORGAN_BROKEN affected.status &= ~ORGAN_SPLINTED affected.stage = 0 - affected.perma_injury = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index d1becd0cbf9..0fef3de54c2 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -51,9 +51,6 @@ //Could be cleaner ... affected.open = 1 - if(istype(target) && !(target.species.flags & NO_BLOOD)) - affected.status |= ORGAN_BLEEDING - affected.createwound(CUT, 1) affected.clamp() spread_germs_to_organ(affected, user) @@ -91,7 +88,7 @@ "\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",) affected.open = 1 - if(istype(target) && !(target.species.flags & NO_BLOOD)) + if(istype(target) && target.should_have_organ("heart")) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) @@ -133,7 +130,7 @@ "\blue You have made an incision on [target]'s [affected.name] with \the [tool].",) affected.open = 1 - if(istype(target) && !(target.species.flags & NO_BLOOD)) + if(istype(target) && target.should_have_organ("heart")) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index f0025b74290..e074cbcca58 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -91,7 +91,7 @@ for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic < 2) + if(!(I.status & ORGAN_ROBOT)) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) @@ -111,7 +111,7 @@ for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic < 2) + if(!(I.status & ORGAN_ROBOT)) user.visible_message("[user] treats damage to [target]'s [I.name] with [tool_name].", \ "You treat damage to [target]'s [I.name] with [tool_name]." ) I.damage = 0 @@ -285,7 +285,7 @@ if(O.organ_tag == "limb") return 0 - else if(target.species.has_organ[O.organ_tag]) + else if(target.should_have_organ(O.organ_tag)) if(O.damage > (O.max_damage * 0.75)) user << "\The [O.organ_tag] [o_is] in no state to be transplanted." diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 24bc8484722..1ad2aec24f0 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -212,7 +212,7 @@ if(!affected) return var/is_organ_damaged = 0 for(var/obj/item/organ/I in affected.internal_organs) - if(I.damage > 0 && I.robotic >= 2) + if(I.damage > 0 && (I.status & ORGAN_ROBOT)) is_organ_damaged = 1 break return affected.open == 2 && is_organ_damaged @@ -225,7 +225,7 @@ for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic >= 2) + if(I.status & ORGAN_ROBOT) user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ "You start mending the damage to [target]'s [I.name]'s mechanisms." ) @@ -241,7 +241,7 @@ for(var/obj/item/organ/I in affected.internal_organs) if(I && I.damage > 0) - if(I.robotic >= 2) + if(I.status & ORGAN_ROBOT) user.visible_message("[user] repairs [target]'s [I.name] with [tool].", \ "You repair [target]'s [I.name] with [tool]." ) I.damage = 0 @@ -393,7 +393,7 @@ user << "You have no idea what species this person is. Report this on the bug tracker." return SURGERY_FAILURE - if(!target.species.has_organ["brain"]) + if(!target.should_have_organ("brain")) user << "You're pretty sure [target.species.name_plural] don't normally have a brain." return SURGERY_FAILURE diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm index dad0a309255..b36da37d6f7 100644 --- a/code/modules/virus2/admin.dm +++ b/code/modules/virus2/admin.dm @@ -87,7 +87,7 @@ var/f = 1 for(var/k in all_species) var/datum/species/S = all_species[k] - if(S.virus_immune) + if(S.get_virus_immune()) continue if(!f) H += " | " else f = 0 diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 81a57dd3008..b6e56d231bb 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -45,7 +45,7 @@ var/list/res = list() for (var/specie in all_species) var/datum/species/S = all_species[specie] - if(!S.virus_immune) + if(!S.get_virus_immune()) meat += S if(meat.len) var/num = rand(1,meat.len) @@ -71,7 +71,7 @@ // Some species are flat out immune to organic viruses. var/mob/living/carbon/human/H = mob - if(istype(H) && H.species.virus_immune) + if(istype(H) && H.species.get_virus_immune(H)) cure(mob) return diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index 1cd185a32ba..4daae5c5e2c 100644 --- a/code/modules/virus2/helpers.dm +++ b/code/modules/virus2/helpers.dm @@ -4,7 +4,7 @@ proc/infection_check(var/mob/living/carbon/M, var/vector = "Airborne") return 0 var/mob/living/carbon/human/H = M - if(istype(H) && H.species.virus_immune) + if(istype(H) && H.species.get_virus_immune(H)) return 0 var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage. diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm index d318ca9f8ad..69ede1d4946 100644 --- a/code/modules/virus2/items_devices.dm +++ b/code/modules/virus2/items_devices.dm @@ -16,7 +16,7 @@ var/mob/living/carbon/C = M if (istype(C,/mob/living/carbon/human/)) var/mob/living/carbon/human/H = C - if(H.species.flags & NO_BLOOD) + if(!H.should_have_organ("heart")) report("Scan aborted: The target does not have blood.", user) return diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi index 045c3a57249b655882152b59c2144fcae83e2a2c..ebc132f554fa1f0118f3e25323a07e59c1191e90 100644 GIT binary patch delta 1397 zcmY*Wdpy$%6yMZE9@&*gxOr4FkGiHO(k9n#wyxLcTKZ^}>{`ma(!BPQqMN)Q@$s6` zP-q%MF~)kh9@X*kW+A3Q?En^w)zQ(>+S%14D_V01$|r zpVa?Mi3?YWnHZ%gWz5ls$LRa-sC1d{zCFDyUGYj^GbKc&08@+pJYxVP`U|f$Qs7+` z!=$40pkrzw$O4x5N)Pc|fM=EZR1O)hbRyojvfU=vtSYLMsZZ2wcdG8rrs|>+t_9a< zzi>#LQ*?u5m@vU3VtApgJZVCo*WZjJ~_wlpNG}!~tAWM3q>4S!#*tYd3+Jj083Zc1*FyP#p{zQVYhnfwwJVDnOhdzYMhPt?Dfw#5tx63BtM;E-?!H1_g=2WNdg@ zq=^^^YmSpf^EHnY@yu2Kv5BUv6YtP0%o^BPB${mAyOro<8fV)cJyTPrAt5fJRs)%_ z0}(CpK;J3Hh0kY+ocaw@6yOzgSl7_JfuT?V?%WsHGzZ5S(`q0P@IOH$-QmAwJ9+q$fQWFtIIjc3R48Ui2kfz9 zbrL-)_azcnA1$WMO`Um3?PnpCZ5<@VQCC6S@vhzSuc|}bh%xg|-{Y|{kuaPJuM91i?5TW(D3g6#A==xouaEHmMa8T{8CsZJ&A4{Zu_Xq-O=6fN}R zzzf+r(?e3kPB%UE;^&=Lv2bb+o+Zn%sZ>F~E$_KiPwg?^;k8cMNL^Ndau%&^{qx9C ze+k3SwXkG_h&ugD@BpB-??zr)ibxpln^Z5V-=Q}dJu(hd``xwo|MnVk1+FCr=Q=E~ z8d<56PL_`!vYd4@fO|6}H#Hhjd8J>61FtTo5b;t&!B z*;XrZQPsUHhMXV=6b(%X)ic#g+vY50>sP3|5}ClM(A5bTSt6=NaYW~v wCp<>0zX+eWnk%zzg_1g0qOb4#YDGgB1st53kkntoncW(oQO*ue>@UXt3yE)(!vFvP delta 901 zcmV;01A6?T3$_O(iBL{Q4GJ0x0000DNk~Le0002M0002M2m=5B0A&K4H2?qrRFNe> zf5E}QwY9a%%F4sT!@Rt_udlCISXjWo!1QC=-~a#s0d!JMQvg8b*k%9#0FHW8Sad{X zb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1Q`~Iik%5O8Mscr1uwB?md6pW&@>sYkjiI zfemEkOAcfN^UdsGAE_<-p`6iX1BHBZeZyf46c`W14IIWs8~B-Tu20fqpunT{UmOVu z<(tt@&!Gy>PYpsM`R$?s00000e*kc$R#Sjmkq2cwuoa?A2R1_@lY})=h6CFn<>A0~ zNO?H09p%|T>L&k$WSqKG{Jb6#8Nt*PX9MFj2R1NIeev^pNUIGL9bY7{0eLxI5mJ1n znPVhgyEzmB000000002^L!o~k>;KoY|7x53Qe^(I+CJ3(k7c)4=--F>fB&^6xi%YU ztI(%!*1Fe&oJaB2J0$g;#ar>5U3$spO?kz0_MDSr18G|A28O-kB%n;|eT7^H>12Lg z?FP=TkYfXBUhM`Xd0wG;y{`}e000000B*!?t$J=#`}b!5e{ubsPhFDY>5z+FQg_Pr zI(q-!?Ef#XpL?VGe!kq-f7f5>-`oBF#r1Pa^}lcazN5YdJwYa`|G&7tyyf~Sw_%^( zjGqkD6U3ZNEUqu_#woYqFuofb&=cg<>WnY0FCX?-_+f0I@(P)q@x}F}GiD6u-sQKoz@>@0ByzO$avH`n>dW&;?000000001h?J*ksz7fJLRU7=C_WrF^8~mR3 b{y+B%B()QTrkVi^00000NkvXXu0mjfE#0Pg diff --git a/icons/mob/human_races/cyberlimbs/hesphaistos.dmi b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi index 5fbcd15861956af7ea2f167b7e7127212dfa8d89..225b18f5b9cf32ed5839d49c3ae5c441281d1383 100644 GIT binary patch delta 1386 zcmYjPc~H`M6vt~l8%#`Ab0iB|bv;nq%FJU)^PoT!C2NF6OC!Z&D@POgsU4K2iAOr7 zA(_(UMN%nVrEY4YWZ}sg+GU=ZBqa{~7HX#H{qeq^_jxm)&wFpaT-_2w)a4+Y-v$E< z0|*4NA;8}!7y{8yLCBPzmMV+c{*kK3mxXe6u(Y&PK_ZbzB9ZWTd~|d)27|G)vooWH zY*jThP6y*cAl@IwqE*EmRuT-zec5c#g*M8V9%mR7E>w?BR3pzD4gC50x%XNHddG&^ z8K;aY0-FMsXAxIorEvlVdf?t@LS;eHPUtDG3cmc9kQyFOsx^66nnE#fzj*w9@18Qd zT6zu7in^)yV8dVu+rl?H?w<$nZl5a)dIaM_8=eMB$9ZGat*o7Tlb;2E@6)}8X9ey{ zs6=wUcuaDbHo+Nh7s17E?si*;%|C-cw6Os`e-l&67t6)huJ1PXjWC1n+hg8906}gZ z`bKIa5oO-`4w?2f(8?xhurcUC3+FHwrrHkDDal)~vRyNA`iMZ@IAA*yclp#-PHdjO z`LI(jcWZ7=&1qU;EilyN=s4ti6%Kpl)W?0(k|I|IFFPd8Mlr?DtJ9r}YbgbI6pI)8 zR%+72r@`I!7M(DigTH^!&Fr1#oLFsftZ`0Wx}A@gA73NVMsrzRQHY3PeYqzmDX2e2 z!J}I^ZhWnB*f5ub-_m&pQO_ocG zWd3!z2YNMv@?x9F@4CG`EAHGSMtHl+;y|VCi4_=?ys?j+p*A@_A^yy%e1x;^4KyQmn!m@3ZJo=eS7|=#Sg&1x*RbEkj)%n%ehP4vXV76&Z>(%v`f0Un(%LV zTXqp4p4K^AtR2xIlYfNekEk0Z&Q)ocr#7g}u=GP8*%U&9bny#9*wzLkirG~M_aA}q znywIrm@;hI< zLxu~gBLweOYj~LIxJz&#c78!|_bm7RKCW7T8DzRZ*Zrpc^S?wVBDd-0uJOrP^go|^CVa;gp#~n^)%uGv!;L$O_9v&;OMLvV1k8O(VyCqb+)tex1=+c z;e`G(ibvYnK&d2A2WYZ2(x=Nc>qf@_9_W$zrlXGI8xnyqO%qE!lTZK!59J*R!m zZ+t@e%cUU8;-hVDY0~R_xiSpQoM1Ob0(ASJUJpWhuxR1^sZxLy(&O$kSG9#B3XXz`s?&Acw!@D`+)^ zNr;E*(Bv~VBAKq*JHu!GbfA^u;^m6>5`JFXipu-b)ME~%QS-#)m+i9iFe?~sJ ULB!W|h@pxK@WuJmVUA|~4=W~*Y5)KL delta 901 zcmbQvy_{XOGr-TCmrII^fq{Y7)59eQNFM-U4rU;k$~4CmNEuI5HLO2y;DC&b%+k$K zy+9Ghk|4ie28U-i(tw=4s*s2hm(=3qqRfJl%=|nChKf1CVFg8{-@gPGeEj-E%Uf6L z+?n&i8$t~(8b5fXbKXbuBtub8?+y#&Amhu%UJ7#_O*%3uL?L*khTTSu@Xl^y)y*p; zmH_Fs8iwYgN6cJSoKmd!3Jt7rON!$XY!h6%M#E0sbS}r?j=)fn`P1gdJGCVKn4+n@ zZf;c8~DwQoDru7^o(-LU1jI`BeFlkDrW3bpP^-Z!X}M9Yv0y-yUyb8EX5+W zN-O(!Xa0Ql>(iqj9J-O!7JA-q&V6_m{n|UQK0H(?IY=(fR`Og;aqa5Yue_tCx_eJD zln(fG_UqI&by`|QdR503@cubxem(rjS;K>~Go*LK++W`(5Wa7x-SaEg%kOvXse9UA zl?`+U5EN_=T+ZOmxp_`C`y{sd(hKgAWn2X!oq?~fop)AQdG$+XN1eq3izhifwa4bO z{}ouU0hoUPI9|;8(Hs@bDHs$cZ;*!uEq^k=QkG?mZ<@Q?9;(WXSo*x~ZWy9 zgXi6z{FS%lOyJq~G4c?T7#`HDY1;pu=b^*)vVWUD<@oQf-wu|k9k?i|SKUBCaP^WaC<3lTPc z;XYybkO+J*5d?}Uy4lkNZ9k%#FftGi&6y(e2FYKhsB#YONfv>#m3+CZ_;A(Y(+upK z7@6_I;+2;8BOD4Z_+ECXDLfog+$i(y#(NOY*CNIWVmzU!R6ptqi^2o7v6TQ#2fyou zV|`bCsitlEl`y)-uQnM|N@vw__R|z@Z!_BAQ;}q<^me|*_Sp%QA6rl}dLfsx`2B)! z34`|sSiKtjKWcvc++Fe<1ls0`wK?e;Q#4(Ck;FGuy{3HB^+D*+0=J`~SiaF}?u|meg_lZ`hBFkWR$SCsMv2)=b&}4eA;S%Rz=7*1<3|LYLMf#cQU}(t7(-f3T*Gusa?@66lr z>h9Bb4SAkxmP^I=@3JhnFfeFNEa=0m_?P}N2oX8@dSZSf{IB(Y;`+DdyCw~> zfXY-Cq>xtGk(Sp}S?l}L;Tm{gejye?2{^1~_R^`>|D|(6pD+uXng;Kz9E_EJJW=5&s5`#JvW}04+yU@Dv zO9RnHy3d#AH9gdtd^v#Sz^y2dQ$?vm^r zE&x8}pOF|8yu83&vs}NlTlv`I{&P8J&Iw8i-COXqGQ&Lh`0PS}L;uo$cK7jOEh73L zs_#Q03B3?11%9DyiQ6^0n)gA0m5}G1ECW>mLkrtXfKm(--R3-e58alzF*V2s1${M54~I9XKj;#MqH$eR1^0sg&}@Vc$pS{N~9U z@5vroB4~jm$ZS`8;)F(fTcF%x#F*S!5H(WdLVE~O*Yo2~=U8ETV;fc+CrY(0yv7xc zK?~@{Un~A@bcg5xgnHpx8itaG*=K%W?KgKo+5-}v!GIf*7D;$$r2p0DB*J`%yzhvu z+coG(CzqVQqXd6-egF5@}=SmybQv zJE896z61W@L@6^WN{51+q(_=+_9Api(b6$Y>G6)0z&PaguJL+LpuWcXG6VgourNFu zHxYWLy6H=D8Spl%&O2(ID>Is1Ue)R&T=8Zb>09C=9i1`;`On@lj~FQ1Ng!;J|1iY_ zkt@!ES3C!FpL+=7P^@vyo0CP|fpROn(Y>xcuM*)9>Dkfni$7mTCt4+WTaiWuf$}!S z9_OmuiI}XFk!pcYUz>zN6n<#beB>r?7FG@?*C?QML{P0;9qf+7U}jA#m2Dyz5dW4h zn(lx`qbx3Awl0(J%&;9KajEe!k65jji&q1K(4w6CPh~t{DM}*K*@z95&u_PrpcI>@ iYAw>ZvVUf~vUN>`xNhj~78Zd27{uD*Y#v&BCH)DoCmFf` delta 1643 zcmV-x29)`=4YUm(s00001bW%=J06^y0W&i*HpL$eSbVOxyV{&P5bZKvH004NLjnO>{!!Qg5 z;MqQfN%qpewM$6|8Ja5?gB9D5SRjk$`bpZMQ;9Y``1C-iHqW-}2h+TI{RS!tvw4{N z>8#a~JjX5Eu3AM%A@VmAb`0BCk##gze_HuOWna>2Bsar8UwDYDUJFDMf+vJ(VB znM9Et5m`_sVvJPqP(^UZM+U-_|Eb!vL-YCS3MZF_MqX2bCIA2hT1iAfRCt{2om*qu zC=i7;)1abKb(6SFVmtf)|K@_ceQ3;Ftc!!)^R;~`XqaPUWa$9vIsgCw007WFf5hDv zN3|~rH>454DQ)EphkVbG*}e2px0Aq}H1gaM~oikxCx5_MpqUq0}o<8k1jRz&OQ>vAUN@pFFB*@Hq<YMH%4qO>y(|C#0000000000004gt59EIW ze3S4{wdd{!9*6rDm=)f+z=0Pzsm=4$`K(@zb)4R<+I(KzgMxo(vZP&Je>gM}UF09u zFEu%cru>2i&f*g}EqJlWyB5#zpmc$)J8)kYnACIE-N0}@ z(S-V?wlmS_t~*M-O|;4YJyyN}#Qyw*s2B90)K*-_+^@#JAU^;A00000000000002s zwzzMDx1bqyeD2NN9$FW2f4YNNCYn#fp}GkCeu$f%p@zxL(h~kP8RQe#Ws_@8tZ78^ z?x)qpmJ5v8;ghR%Xf%A<9q)`LJUPr}c@LVitaj!(x?vCcY<$tcFA-|)`yZG+ST*oh z!Z-hCP$p6l1>@*nb`NfM8T0LDGS;Vk=;mKhx(X(Sqt|Mw-GXlTnKeOX6BuDn_Dby<&lrkm1qVDx=LHuR(y>HJXtzO@2 zrEi7R@&Et;0000000000;7S+{UE>C~?GEuz!~AG_n*rNf;~nqR3S-mT3^;nwvae{o zV72zOVS5=YTLvUif5Sb<_7Yp>Uq+44@F>H**@LeyFGh`&6zjv~A3EyH#oo|AUnFz` zQhZm#bo3|thqk}xv*)B5i~Yl?R6klv&*SgCO%|ONLJqQme`x48K7N<4rdxEXy|;#c zsF!-&LjV8(006KN)bQP=3uCq)`-fLSfAOb0{+`1>oRig>i2j_<-!uKgxp}RJ5KqYEoJ+ME z>gjO#xge1qe`{h$`~5xz@iG!(3MtCvRGz7XAni6W{9nAzI~!&|X`e6CdvT`$N_0pE zlFI{!A;bH6`JPK@*l@1~1B#QtC<-|6;gJ7{<++Q7e{mdTfw?dX{InUTOp`$IkpLYJ zx%_aHzhgz<`@1ag{k;hMG=GI@`VNW$`FPAdcswdUW?cf8XF3-?F}r-SzZ3^dFTD!Z zq-S$dv@u_H^XatalVj_K$vnRd0bA<}+I~G#jcpUym@)<|yPx@YtyH#wvp!n(V7PUK zS>Uphe^3|blE39=6gS;=Z4JzaLTYKg6KMR=K3o2$K7{Z{ZF@5mllV)xz)`;naCt#s z!vgc|NYw5%rYZlL!XmKc9;B4>SN4VDq32#V`P*LpR|W`HZZ^sg+59lM2<~qEw-x{Z z00000000000002+kw*T3*Lka)@0D!-X{{WXSAdu*hm3sgH002ovPDHLkV1jglA6fta diff --git a/icons/mob/human_races/cyberlimbs/xion.dmi b/icons/mob/human_races/cyberlimbs/xion.dmi index daf10298c217b113fa82934faed2049535e1d128..6c230675c3f84553a723a304fa9f02d07cab7f2b 100644 GIT binary patch delta 1346 zcmZ8hdpOez7~W7c93_>cB&2W-N1k!;7&UC=nBvK0r#Q4}VXo!ApHL|&LpViirx>}_ zTuwEO5Hspn*w|dlC2j7zxU}uid7hs0obQkCeZTjQ@BO~-kMEkY2x4^8!`)RKq5}be zKY{0s;L-k_i{6~&FrBOwAez>8?)0&Jp}m$$b!3WdUAu_h)a>WVJB4HX=7#@!R- zI5mLXD9RJOd}833=%6TEL<}w*4+6y%Wqo)FX|+&G86PA-as?$EZi!*K+B;M2v`NJr zl?yC7AzH2YWF2y0M(=jWawv^p@veds{wOCBsu2wzdn0kK+^K~GYlD#MF3=N5a_ z1e)EPQN;Od-oU6|7?(Uq@7u%s__R&`EWZN;Qqn=foxI|TW{X)@xVBpG{m%>@^UU8)T!E)TsCI7+n}?Si6<_>a`~o3)Y42W2cs){jJRegdK3OZ$n^oBy_j~AV z@ec~Ui69eO%EXl5%hG%bVROShZ__@6r3 z8c3hVWZL^fGbXIZP*Q3Vh6__QqV=3f%Y-w9AxO?nh3^L6$ckMj4Ru2ogZvtMm*DQu z<%kpBw1Z2Tc=NengUqXoT^yb$dMR0I$$Zskb9ipMsG?;dp|R@45*z3R--El*7t!*= z%7`pk3>@>te?DlS-hgEKUVr03L1*7jXb-W~OSAcd5C_H`+FM)4~KViVvj);zI zb=Ycu_WY$J;jV@8yWkFv!(;I4ggqW_@BKxn)5*?fFs$!P(Hz@Dl>RqwLFcQtcj&%( zB?0J+9eY>jAQr;C^4@Tp3^ZWd8Tjy8HiHq1N-2=yZ7^12RswPPY(BLxn3%_4dh35{ z<)}6vGCaD1lu~dxlkpEHL7t8U==DT^UgUh267ReFkASFY=RV4$0RFOG9#mP&HaH{P3&*ZITwePy;u=Tghl$f0x_$bI-+B$i z{h?(oUo06rwmzCAVao515sfGP);AyEzhQ4DSJZOB`Xvv@Ag!Ac(%BteeLNubA8THY A*8l(j delta 846 zcmV-U1F`(|3WWzHiBL{Q4GJ0x0000DNk~Le0002M0002M2m=5B0A&K4H2?qrMUf>& zf55=NE;(6n00001bW%=J06^y0W&i*Hj(SvBbVOxyV{&P5bZKvH004NLQ&wiFEu_#xG zi!&v&s2HS)i!-e#F*g;&Hbkh(Axc$Ie|$z_UJ4P05v8msJ|{Ju2*Zd`RTQ6=pI<_R zVfd6OE4cc(fCCu-Q1xbe6{Q==00071NklVA?*n}s}q%LM=cAj9?VD~FUu8u?a#!{{zB>WyBdOzwDW%dGua)=k}5n3iw#7b-5>sxB6FUvWyl*=NcYXo|Xvdn2C&_lFl>*q0_f4u*+Lx96Hz5)LN5zV!ckh`g)^(7dhu3!2a$l9Gc z=-%cMI3z6dc1K9g5ojxXZ5*4ai)B?88zH-H;1ak1?Zu%G000000000;rVX;QhT9K0 z0{A_@56%CLDSz}VAx@d!$L9aB?0m}nJ~sc4W$!@wZKsXyJ3+qV!{%?M|I000000001h6G|BHARj7Wz<;cS0sn)2 Y16#HY12mq>=>Px#07*qoM6N<$f&dbI*#H0l diff --git a/icons/mob/human_races/cyberlimbs/zenghu.dmi b/icons/mob/human_races/cyberlimbs/zenghu.dmi index a94eacc48a512f131f9f999ad93d7b764135fb2f..7ee24241b9faccd0a2ee27b65a245ddce179e596 100644 GIT binary patch delta 1335 zcmY*VdpOez82-(569;ufoH#hsqEpnNv|JC>IGbWw>EgIFp_prA_H#Qak0nEMv}JM` zlXP5?#6(3GWR%MuETVF0mW*w-ojHG;&iVfMzW4pU@AdHdBk8t|(}Fo(1>3^f1% z&_W${^9BHj0s=g!vLbVf4+koWYc6~zXklTYfLJURhr@Y!dExPRS65d{OG~4+5?93l z66=le0i0)s@d{FP341)&?QBd?bSNPP_IMEx$U~pgPi3nWH#`lE@ z{u;>3XYX|HFS4v5R@51X>UE><^-_xs-LuX|*XuuV%btfG)yYHDL2^}Xbc4#$?4V?@T&UP#ZnQSUFpG=Ndf53u)y*U_WJH9&B31WoWR=%c!MH8s4 zzr}S-m)}Z~J|sSj_hls|*61WAKYx~(1SajsukojP{R$Nc&Xj+V{e>!wmcAga%l#JD znRQM-%E!n>Wzpi66?IK!mT`$s8>;)9?smKGk3-V~VXis($mCmDTAbrmAbP&?hl)2l zq%2|>G*rpa$qIkmVE$U7U}9QN94Bfh%I`mBi-M(ByUl)WqKspp-~Oy4o+pLB)*MtH zLHCn(5OaKlcg?2Hy2McP#b$ajDXhqulXLvbrL7O>Z=tqqPmc@j1Wpposgk+IWj-LM2 zEsy7UVz}wWz^bRs z6@^tVRJzpM$X@yI^2DE0)|i1Z3#j10_GN2&sdvPJ$xd0_T3(Kq6=O>opbvNX!bU*+ zBqkm9r>1PByS_6B${y8F;rl3wR^Rhmy(8v8PsS=!1fs1N=l~C$X;s?LKF4}F#aU3i z^1AGE`-quavtjz?+E#GC?B1-|%~{76Fz@F^xKGby)i4rgXCM_jZtEN_Z%`@?%$+1l z?kaF_fa-9Pdc$%tc%#2!AN@8`j^K`({MVi~&9`~=^x`{>D@|hUL0R?|aBAe{(TD~9 zltH7ZDeJUveVT|UtCBK*>3ne=OBNd@NJNh)j7It692AIEqSd}**$P%EAC~G!;quP4 z^9~5*na$>nJ>7>Cdv#qWCESeksIB)U+P-m!2BG>t4)U{>Gq0+~Nw1}!j+}Es&;Gor z-gp_ZBp9tN?c;&9u)^gLkitK=D$+J7Q1RlK3{XE3mT(()Kn^D6iQuUQj7G4CVN3eg57iBL{Q4GJ0x0000DNk~Le0002M0002M1Oos70HE@5GynhqEs-TI zf55=N!^;e!00001bW%=J06^y0W&i*Hj(SvBbVOxyV{&P5bZKvH004NLQ&wiFEu_#xG zi!&v&s2HS)i!-e#F*g;&Hbkh(Axc$Ie|$z_UJ4P05v8msJ|{Ju2*Zd`RTQ6=pI<_R zVfd6OE4cc(fCCu-Q1xbe6{Q==0006wNklzI&#Y4gk zIr-J=8Byyg6O(0K8&M+bSwDRt7ASkyRF!ZAjh^*WPh!E|qdk6kjt^+`tlz<_T=5=n zD(XZ1000000D#0O#Vz(>XJIxwe}H-Lp;1?6vjg;|x5$kIf&5^TSW-wN?7!LaJ0mGh zZ|rgDhZ@~&mR@~G%d1akz`{GV+i}3Rk(STCoB>O}qT7J1kmnlt7ytkO004l#Sidjl z0iy065*xoC$OHc3cqwUGY5aa558Qj7>h1#?zaPj0{$kmEfc5xt9tf#3e=n{zq}<44 z^o%Wy5 zo2jZI&dl@sEDuEMbxo|~n7U2R@3TA*t&a~V{Q=}`v|iC2$*G<7%q%mz(R%h@!<>f5 z((S*eDsUH9U00000+X8(h w!d|iTh5CKw|9cPc;((YK`r*fc0UiDi?}SK|zN%-500000NkvXX1g=70f+!ep9smFU diff --git a/icons/mob/human_races/r_machine.dmi b/icons/mob/human_races/r_machine.dmi deleted file mode 100644 index 65f66c3238599dc86e3c0b902ee79973bee106ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2120 zcmZ8gXHXLe6HS8jCWst_2q?WsqERWqgepi$0tCWPL<9ng8ajw@1XNI|2MS0p3V0m7 zNKZtNj(|c`)TopIA=0D;o*?LR1JW1ONa;FIt+}0{}oS z1OfzjxXJ$?XB;=hVr_8d6beOERh3)KfcQ+b4hRH-rl#f_E;cd2?A1`w>uynwlCE3PmE3+S=M+Fc<^^K_Cz-D=P#7VPRoWngQT4YiMYs zwtsiaU)GA*0suHRHa1#XTdAqv-Q1S-^hODUk<84IBr%ZluhBy6(GCEk`S%2FL5ajU zhnV>Udj(w$2)RnU2>?XoB~Oe9b;CsXSA$tnKJAGPHJ7|kAX@P1_Xz%huF6$%U7ajF z5zNTRSPzb^Vr$!H1;?sEUlog@uYp*6s6OObc1QBfo1>#HPD{jxBoVQekC`A|H`HyQgwJ{Q_Qf_odS67Uw5& z4PcoPFX}_UqiT~+YQhRvt-kBNT=4wpzD5rUtr^-x$D}p(9M_7d319At#p>EC7Q((|s|b6`6bZ4iQieXK$7CJtb3Kuz9HK~@%nn~^5uTG!q*EZ9!u42| z{gIJiw$82fi9gq&xKY5+J{AHvSGH1c24GK1r`42r$FSOIzO@DM_4|ydAXWSfZT*Sr ztE1AxNUAyO1KHmnP^~pv<9_S!hVsgXui*IEd$L%6V|tl4YB$^=JicsqT_jB&*;@^_ z4HeW(UfF8S_Bw=Cn0vc0&+Pbj&EF#F)(K;@hl9y|ahSgH>x6q_Wv$-#ReSj#nU17O z-0)Tv=%~fuWV^it*Q}?fy*idym<#dsy0ep(4NF?DpwR870%vURd)?Bs%R9U^9*mbK zReX_~1RV?+=`WS-lsDEv`M%BRpTh}@Ok6*nqw~JQ&AUq=`zGer_?F zT#EVtH%iLzLYNC~sFfz*b?n?bTZ{8de3g6rAkpFB#GmTa9648mV7^bZ&$8#Q;L;~*rG*>q&<8ew5- z&v5odSL3^PNO$07Cs^#xcjE~KDSj6Qoi|G-WUyYi?{HigZ_t-3#oF6Wm;0ZjVjN=_ zvCYdp$K8RUj`0~hOAz7me^8M{I_-gN{8hT}rp=Pe9eeLxP|yMSpT~1)BaTx&_8IJ( zfx!oNJP~A$-7&wa!fMhJ8mEP4%$YVhyX{fm_1K6K5gh~E`@a&a!jjGX%siJ#mGY$h zdx`zEG#6Um= zUV1!@&vWg})~amkDuo#+Iw?OrTSHweeE)@>pWvBx%rbcZs8QnBTo|tVf%ALJ^L|xCJ?z{UWBQnj!f(fh zDLF+^)*hs$YE|Owc~dj~Jg`~yVDIm3Cbn=me1@+brNX4k6?xTV66~S|@3S~W%8V|1 ziyZ(L=eCO6D<`wr^ovR25j+#S*0+Zo4sX2}R<=JgO7bGVEBOlvbYc(?W_0f+mc3CkI_TM^*I9i znYnYMAHC`FanXAcdQW{X$E1jNyX_c~S#K7dU|QMG^kSM*76x973KL>FsKgvKVAPnh zWCN;aQ-R@S3IL^P4kz!MQh<2!t%=b!i54}gbj9<)THNc|?Z|^T^M*==A}ZARG;5Ya cbUpMH<(y`4Hg9%x;+Luy&CzDnCYR&>2bWpbb^rhX From 4a92b5ee70bb082a1550b55eb9f3ec8e5e7e8f65 Mon Sep 17 00:00:00 2001 From: NullSnapshot Date: Sun, 25 Oct 2015 18:10:14 -0700 Subject: [PATCH 2/4] Fixes #11350 --- code/game/machinery/rechargestation.dm | 47 ++++++++++++++++++-------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index ac5ae8d8c79..01d3d72dac5 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -103,6 +103,11 @@ R.adjustBruteLoss(-weld_rate) if(wire_rate && R.getFireLoss() && cell.checked_use(wire_power_use * wire_rate * CELLRATE)) R.adjustFireLoss(-wire_rate) + else if(istype(occupant, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = occupant + if(!isnull(H.internal_organs_by_name["cell"] && H.nutrition < 450)) + H.nutrition = min(H.nutrition+10, 450) + /obj/machinery/recharge_station/examine(mob/user) ..(user) @@ -200,22 +205,36 @@ go_in(R) /obj/machinery/recharge_station/proc/go_in(var/mob/living/silicon/robot/R) - if(!istype(R)) - return - if(occupant) - return - if(R.incapacitated()) - return - if(!R.cell) - return + if(istype(R, /mob/living/silicon/robot)) + if(!istype(R)) + return + if(occupant) + return - add_fingerprint(R) - R.reset_view(src) - R.forceMove(src) - occupant = R - update_icon() - return 1 + if(R.incapacitated()) + return + if(!R.cell) + return + + add_fingerprint(R) + R.reset_view(src) + R.forceMove(src) + occupant = R + update_icon() + return 1 + + else if(istype(R, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = R + if(!isnull(H.internal_organs_by_name["cell"])) + add_fingerprint(H) + H.reset_view(src) + H.forceMove(src) + occupant = H + update_icon() + return 1 + else + return /obj/machinery/recharge_station/proc/go_out() if(!occupant) From 87afd2feb22b1fff68c72a962d9b9d62e31f2bb6 Mon Sep 17 00:00:00 2001 From: NullSnapshot Date: Sun, 25 Oct 2015 21:51:31 -0700 Subject: [PATCH 3/4] Fixes: #11351 #11357 #11359 #11361 --- code/__defines/damage_organs.dm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 27a34f10ebe..5fae0f9c488 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -29,7 +29,7 @@ #define FIRE_DAMAGE_MODIFIER 0.0215 // Higher values result in more external fire damage to the skin. (default 0.0215) #define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025) -// Organ defines. +/*// Organ defines. #define ORGAN_CUT_AWAY 1<<0 #define ORGAN_BLEEDING 1<<1 #define ORGAN_BROKEN 1<<2 @@ -38,7 +38,18 @@ #define ORGAN_SPLINTED 1<<5 #define ORGAN_DEAD 1<<6 #define ORGAN_MUTATED 1<<7 -#define ORGAN_ASSISTED 1<<8 +#define ORGAN_ASSISTED 1<<8*/ + +// Organ defines. +#define ORGAN_CUT_AWAY 1 +#define ORGAN_BLEEDING 2 +#define ORGAN_BROKEN 4 +#define ORGAN_DESTROYED 8 +#define ORGAN_ROBOT 16 +#define ORGAN_SPLINTED 32 +#define ORGAN_DEAD 64 +#define ORGAN_MUTATED 128 +#define ORGAN_ASSISTED 256 #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 From f93ea6a78fb3a0d1bcb47104e1e7f435b6598bbd Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Fri, 4 Dec 2015 16:49:21 +1030 Subject: [PATCH 4/4] Tweaks to previous commits. More tweaks to IPC fixes. Merge resolution/compile fixes. Further work on properly integrating, updating and fixing prosthetic options. Repathed internal organs to organ/internal. More work on full synthetics, changelings, overheating. Working on getting organs to qdel properly and spawn properly when robotized. Finalized some overheating values, added remaining prosthetic icons. Finalizing the testing version of the full prosthetic bodies branch. Added suit cyclers to the autolathe and map. Fixing runtime errors. Fixing errors. Changelog. Replacing limb and organ strings with constants. Prevented brainless species from becoming full cyborgs. Fixed issues with brain/MMIs renaming themselves inappropriately. Various fixes and oversights. --- code/ATMOSPHERICS/he_pipes.dm | 2 +- code/ZAS/Airflow.dm | 12 +- code/ZAS/Fire.dm | 44 ++-- code/ZAS/Phoron.dm | 2 +- code/__defines/damage_organs.dm | 29 +-- code/__defines/mobs.dm | 36 ++++ code/_helpers/mobs.dm | 4 +- code/_onclick/hud/screen_objects.dm | 30 +-- code/datums/datacore.dm | 2 +- code/datums/diseases/appendicitis.dm | 2 +- code/game/antagonist/alien/borer.dm | 4 +- code/game/antagonist/station/changeling.dm | 11 + code/game/atoms.dm | 5 +- .../changeling/powers/bioelectrogenesis.dm | 8 +- .../changeling/powers/extract_dna_sting.dm | 13 +- code/game/gamemodes/cult/runes.dm | 4 +- code/game/gamemodes/objective.dm | 2 +- code/game/machinery/autolathe_datums.dm | 5 + code/game/machinery/bioprinter.dm | 10 +- code/game/machinery/bots/mulebot.dm | 12 +- code/game/machinery/doors/airlock.dm | 18 -- code/game/machinery/flasher.dm | 2 +- code/game/machinery/iv_drip.dm | 2 +- code/game/machinery/kitchen/gibber.dm | 17 +- code/game/machinery/portable_turret.dm | 4 +- code/game/machinery/rechargestation.dm | 21 +- code/game/machinery/suit_storage_unit.dm | 2 +- code/game/machinery/turrets.dm | 8 +- code/game/mecha/combat/combat.dm | 2 +- code/game/objects/effects/aliens.dm | 4 +- .../effects/decals/Cleanable/humans.dm | 6 + .../effects/decals/Cleanable/robots.dm | 6 +- code/game/objects/effects/spiders.dm | 4 +- code/game/objects/items.dm | 4 +- code/game/objects/items/devices/flashlight.dm | 2 +- .../objects/items/devices/suit_cooling.dm | 29 +-- code/game/objects/items/robot/robot_parts.dm | 14 +- code/game/objects/items/stacks/medical.dm | 6 +- .../objects/items/weapons/cigs_lighters.dm | 2 +- .../game/objects/items/weapons/clown_items.dm | 2 +- .../items/weapons/grenades/flashbang.dm | 2 +- code/game/objects/items/weapons/handcuffs.dm | 4 +- .../objects/items/weapons/material/kitchen.dm | 2 +- .../objects/items/weapons/storage/fancy.dm | 4 +- .../objects/items/weapons/swords_axes_etc.dm | 4 +- code/game/objects/items/weapons/tape.dm | 12 +- code/game/objects/items/weapons/tools.dm | 4 +- code/game/objects/items/weapons/trays.dm | 4 +- code/game/objects/structures.dm | 10 +- .../stool_bed_chair_nest/alien_nests.dm | 4 +- .../preference_setup/general/03_body.dm | 125 ++++++----- .../client/preference_setup/global/03_pai.dm | 3 + code/modules/client/preferences.dm | 35 ++-- code/modules/clothing/suits/armor.dm | 2 +- .../clothing/under/accessories/accessory.dm | 8 +- code/modules/clothing/under/miscellaneous.dm | 9 +- code/modules/detectivework/tools/rag.dm | 2 +- code/modules/detectivework/tools/swabs.dm | 10 +- code/modules/food/recipes_microwave.dm | 4 +- code/modules/genetics/side_effects.dm | 4 +- code/modules/hydroponics/seed.dm | 2 +- code/modules/library/lib_items.dm | 2 +- code/modules/materials/materials.dm | 2 +- code/modules/mining/abandonedcrates.dm | 12 +- code/modules/mob/language/language.dm | 5 +- code/modules/mob/language/outsider.dm | 2 +- code/modules/mob/language/station.dm | 9 +- .../mob/living/carbon/alien/larva/larva.dm | 2 +- code/modules/mob/living/carbon/brain/MMI.dm | 33 ++- .../mob/living/carbon/brain/brain_item.dm | 73 ++++--- code/modules/mob/living/carbon/brain/death.dm | 2 +- code/modules/mob/living/carbon/breathe.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 2 +- .../mob/living/carbon/human/appearance.dm | 4 +- code/modules/mob/living/carbon/human/death.dm | 2 +- code/modules/mob/living/carbon/human/emote.dm | 32 +++ .../mob/living/carbon/human/examine.dm | 127 +++--------- code/modules/mob/living/carbon/human/human.dm | 68 +++--- .../living/carbon/human/human_attackhand.dm | 2 +- .../mob/living/carbon/human/human_damage.dm | 21 +- .../mob/living/carbon/human/human_defense.dm | 12 +- .../mob/living/carbon/human/human_defines.dm | 5 +- .../mob/living/carbon/human/human_movement.dm | 4 +- .../mob/living/carbon/human/human_organs.dm | 6 +- .../mob/living/carbon/human/inventory.dm | 36 ++-- code/modules/mob/living/carbon/human/life.dm | 81 ++++---- .../carbon/human/species/outsider/vox.dm | 48 ++--- .../living/carbon/human/species/species.dm | 51 ++--- .../carbon/human/species/species_attack.dm | 2 +- .../carbon/human/species/station/golem.dm | 2 +- .../human/species/station/human_subspecies.dm | 12 +- .../carbon/human/species/station/monkey.dm | 22 +- .../carbon/human/species/station/slime.dm | 24 +-- .../carbon/human/species/station/station.dm | 62 +++--- .../human/species/xenomorphs/alien_embryo.dm | 6 +- .../species/xenomorphs/alien_facehugger.dm | 4 +- .../human/species/xenomorphs/alien_powers.dm | 20 +- .../human/species/xenomorphs/alien_species.dm | 86 ++++---- .../mob/living/carbon/human/stripping.dm | 2 +- .../mob/living/carbon/human/unarmed_attack.dm | 18 +- .../mob/living/carbon/human/update_icons.dm | 18 +- .../modules/mob/living/carbon/metroid/life.dm | 8 +- code/modules/mob/living/living.dm | 4 +- code/modules/mob/living/living_defense.dm | 2 +- .../mob/living/silicon/robot/analyzer.dm | 4 +- .../living/silicon/robot/drone/drone_items.dm | 2 +- .../mob/living/simple_animal/borer/borer.dm | 2 +- .../simple_animal/borer/borer_powers.dm | 8 +- .../mob/living/simple_animal/hostile/bear.dm | 2 +- .../mob/living/simple_animal/parrot.dm | 2 +- code/modules/mob/mob.dm | 3 + code/modules/mob/mob_grab.dm | 32 +-- code/modules/mob/mob_grab_specials.dm | 10 +- code/modules/mob/mob_helpers.dm | 116 ++++++----- .../mob/new_player/preferences_setup.dm | 10 +- code/modules/multiz/turf.dm | 12 +- code/modules/organs/blood.dm | 14 +- code/modules/organs/misc.dm | 30 +-- code/modules/organs/organ.dm | 85 +++----- code/modules/organs/organ_external.dm | 194 ++++++++++-------- code/modules/organs/organ_icon.dm | 6 +- code/modules/organs/organ_internal.dm | 95 ++++++--- code/modules/organs/organ_stump.dm | 2 +- code/modules/organs/robolimbs.dm | 16 +- code/modules/organs/subtypes/diona.dm | 102 ++++----- code/modules/organs/subtypes/machine.dm | 76 ++++--- code/modules/organs/subtypes/standard.dm | 30 +-- code/modules/organs/subtypes/xenos.dm | 38 ++-- code/modules/paperwork/paper.dm | 4 +- code/modules/projectiles/gun.dm | 4 +- .../Chemistry-Reagents-Core.dm | 2 +- .../Chemistry-Reagents-Dispenser.dm | 4 +- .../Chemistry-Reagents-Food-Drinks.dm | 2 +- .../Chemistry-Reagents-Medicine.dm | 2 +- .../reagent_containers/food/snacks.dm | 36 ---- .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/surgery/bones.dm | 4 +- code/modules/surgery/face.dm | 4 +- code/modules/surgery/generic.dm | 28 +-- code/modules/surgery/implant.dm | 2 +- code/modules/surgery/organs_internal.dm | 47 ++--- code/modules/surgery/other.dm | 6 +- code/modules/surgery/robotics.dm | 33 ++- code/modules/tables/interactions.dm | 6 +- code/modules/vehicles/cargo_train.dm | 4 +- code/modules/virus2/effect.dm | 2 +- code/modules/virus2/items_devices.dm | 2 +- html/changelogs/Zuhayr-robolimbs.yml | 9 + icons/mob/back.dmi | Bin 47377 -> 50492 bytes icons/mob/human_races/cyberlimbs/bishop.dmi | Bin 1442 -> 4210 bytes .../human_races/cyberlimbs/hesphaistos.dmi | Bin 1431 -> 4054 bytes icons/mob/human_races/cyberlimbs/ipc.dmi | Bin 1717 -> 4379 bytes icons/mob/human_races/cyberlimbs/xion.dmi | Bin 1397 -> 3695 bytes icons/mob/human_races/cyberlimbs/zenghu.dmi | Bin 1362 -> 1363 bytes icons/mob/human_races/r_diona.dmi | Bin 2719 -> 2907 bytes icons/mob/uniform.dmi | Bin 316200 -> 316825 bytes icons/mob/zone_sel.dmi | Bin 1413 -> 961 bytes icons/obj/clothing/uniforms.dmi | Bin 78059 -> 78378 bytes maps/polaris-1.dmm | 25 +-- maps/polaris-2.dmm | 6 +- maps/polaris-5.dmm | 30 +-- 161 files changed, 1385 insertions(+), 1353 deletions(-) create mode 100644 html/changelogs/Zuhayr-robolimbs.yml diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index d78bb828e24..52dedfb0899 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -81,7 +81,7 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging heat_limit = H.species.heat_level_3 if(pipe_air.temperature > heat_limit + 1) - buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, "chest", used_weapon = "Excessive Heat") + buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat") //fancy radiation glowing if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index d14c760d85d..8831f8aa401 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -227,14 +227,14 @@ mob/living/carbon/human/airflow_hit(atom/A) bloody_body(src) var/b_loss = airflow_speed * vsc.airflow_damage - var/blocked = run_armor_check("head","melee") - apply_damage(b_loss/3, BRUTE, "head", blocked, 0, "Airflow") + var/blocked = run_armor_check(BP_HEAD,"melee") + apply_damage(b_loss/3, BRUTE, BP_HEAD, blocked, 0, "Airflow") - blocked = run_armor_check("chest","melee") - apply_damage(b_loss/3, BRUTE, "chest", blocked, 0, "Airflow") + blocked = run_armor_check(BP_TORSO,"melee") + apply_damage(b_loss/3, BRUTE, BP_TORSO, blocked, 0, "Airflow") - blocked = run_armor_check("groin","melee") - apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow") + blocked = run_armor_check(BP_GROIN,"melee") + apply_damage(b_loss/3, BRUTE, BP_GROIN, blocked, 0, "Airflow") if(airflow_speed > 10) Paralyse(round(airflow_speed * vsc.airflow_stun)) diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index dba966e9fb9..7222470f71c 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -65,12 +65,12 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) /zone/proc/remove_liquidfuel(var/used_liquid_fuel, var/remove_fire=0) if(!fuel_objs.len) return - - //As a simplification, we remove fuel equally from all fuel sources. It might be that some fuel sources have more fuel, + + //As a simplification, we remove fuel equally from all fuel sources. It might be that some fuel sources have more fuel, //some have less, but whatever. It will mean that sometimes we will remove a tiny bit less fuel then we intended to. - + var/fuel_to_remove = used_liquid_fuel/(fuel_objs.len*LIQUIDFUEL_AMOUNT_TO_MOL) //convert back to liquid volume units - + for(var/O in fuel_objs) var/obj/effect/decal/cleanable/liquid_fuel/fuel = O if(!istype(fuel)) @@ -188,7 +188,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) return set_dir(pick(cardinal)) - + var/datum/gas_mixture/air_contents = loc.return_air() color = fire_color(air_contents.temperature) set_light(3, 1, color) @@ -209,7 +209,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) var/turf/T = loc if (istype(T)) set_light(0) - + T.fire = null loc = null air_master.active_hotspots.Remove(src) @@ -224,12 +224,12 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) /datum/gas_mixture/proc/zburn(zone/zone, force_burn, no_check = 0) . = 0 if((temperature > PHORON_MINIMUM_BURN_TEMPERATURE || force_burn) && (no_check ||check_recombustability(zone? zone.fuel_objs : null))) - + #ifdef FIREDBG log_debug("***************** FIREDBG *****************") log_debug("Burning [zone? zone.name : "zoneless gas_mixture"]!") #endif - + var/gas_fuel = 0 var/liquid_fuel = 0 var/total_fuel = 0 @@ -278,7 +278,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress var/used_fuel = min(total_reaction_progress, reaction_limit) var/used_oxidizers = used_fuel*(FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT) - + #ifdef FIREDBG log_debug("gas_fuel = [gas_fuel], liquid_fuel = [liquid_fuel], total_oxidizers = [total_oxidizers]") log_debug("fuel_area = [fuel_area], total_fuel = [total_fuel], reaction_limit = [reaction_limit]") @@ -312,12 +312,12 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) //calculate the energy produced by the reaction and then set the new temperature of the mix temperature = (starting_energy + vsc.fire_fuel_energy_release * (used_gas_fuel + used_liquid_fuel)) / heat_capacity() update_values() - + #ifdef FIREDBG log_debug("used_gas_fuel = [used_gas_fuel]; used_liquid_fuel = [used_liquid_fuel]; total = [used_fuel]") log_debug("new temperature = [temperature]; new pressure = [return_pressure()]") #endif - + return firelevel datum/gas_mixture/proc/check_recombustability(list/fuel_objs) @@ -369,19 +369,19 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs) if(total_combustables > 0) //slows down the burning when the concentration of the reactants is low var/damping_multiplier = min(1, active_combustables / (total_moles/group_multiplier)) - + //weight the damping mult so that it only really brings down the firelevel when the ratio is closer to 0 damping_multiplier = 2*damping_multiplier - (damping_multiplier*damping_multiplier) - + //calculates how close the mixture of the reactants is to the optimum //fires burn better when there is more oxidizer -- too much fuel will choke the fire out a bit, reducing firelevel. var/mix_multiplier = 1 / (1 + (5 * ((total_fuel / total_combustables) ** 2))) - + #ifdef FIREDBG ASSERT(damping_multiplier <= 1) ASSERT(mix_multiplier <= 1) #endif - + //toss everything together -- should produce a value between 0 and fire_firelevel_multiplier firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * damping_multiplier @@ -425,10 +425,10 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs) //Always check these damage procs first if fire damage isn't working. They're probably what's wrong. - apply_damage(2.5*mx*head_exposure, BURN, "head", 0, 0, "Fire") - apply_damage(2.5*mx*chest_exposure, BURN, "chest", 0, 0, "Fire") - apply_damage(2.0*mx*groin_exposure, BURN, "groin", 0, 0, "Fire") - apply_damage(0.6*mx*legs_exposure, BURN, "l_leg", 0, 0, "Fire") - apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire") - apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire") - apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire") + apply_damage(2.5*mx*head_exposure, BURN, BP_HEAD, 0, 0, "Fire") + apply_damage(2.5*mx*chest_exposure, BURN, BP_TORSO, 0, 0, "Fire") + apply_damage(2.0*mx*groin_exposure, BURN, BP_GROIN, 0, 0, "Fire") + apply_damage(0.6*mx*legs_exposure, BURN, BP_L_LEG, 0, 0, "Fire") + apply_damage(0.6*mx*legs_exposure, BURN, BP_R_LEG, 0, 0, "Fire") + apply_damage(0.4*mx*arms_exposure, BURN, BP_L_ARM, 0, 0, "Fire") + apply_damage(0.4*mx*arms_exposure, BURN, BP_R_ARM, 0, 0, "Fire") diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index cffa28a1fc2..a29cbee0465 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -116,7 +116,7 @@ obj/var/contaminated = 0 /mob/living/carbon/human/proc/burn_eyes() - var/obj/item/organ/eyes/E = internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = internal_organs_by_name[O_EYES] if(E) if(prob(20)) src << "Your eyes burn!" E.damage += 2.5 diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 5fae0f9c488..09931cb622b 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -29,27 +29,16 @@ #define FIRE_DAMAGE_MODIFIER 0.0215 // Higher values result in more external fire damage to the skin. (default 0.0215) #define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025) -/*// Organ defines. -#define ORGAN_CUT_AWAY 1<<0 -#define ORGAN_BLEEDING 1<<1 -#define ORGAN_BROKEN 1<<2 -#define ORGAN_DESTROYED 1<<3 -#define ORGAN_ROBOT 1<<4 -#define ORGAN_SPLINTED 1<<5 -#define ORGAN_DEAD 1<<6 -#define ORGAN_MUTATED 1<<7 -#define ORGAN_ASSISTED 1<<8*/ - // Organ defines. -#define ORGAN_CUT_AWAY 1 -#define ORGAN_BLEEDING 2 -#define ORGAN_BROKEN 4 -#define ORGAN_DESTROYED 8 -#define ORGAN_ROBOT 16 -#define ORGAN_SPLINTED 32 -#define ORGAN_DEAD 64 -#define ORGAN_MUTATED 128 -#define ORGAN_ASSISTED 256 +#define ORGAN_CUT_AWAY (1<<0) +#define ORGAN_BLEEDING (1<<1) +#define ORGAN_BROKEN (1<<2) +#define ORGAN_DESTROYED (1<<3) +#define ORGAN_ROBOT (1<<4) +#define ORGAN_SPLINTED (1<<5) +#define ORGAN_DEAD (1<<6) +#define ORGAN_MUTATED (1<<7) +#define ORGAN_ASSISTED (1<<8) #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 88d584bbe4b..aa3e1741b52 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -136,3 +136,39 @@ #define INCAPACITATION_DEFAULT (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_FULLY) #define INCAPACITATION_ALL (INCAPACITATION_RESTRAINED|INCAPACITATION_BUCKLED_PARTIALLY|INCAPACITATION_BUCKLED_FULLY) + +// Bodyparts and organs. +#define O_MOUTH "mouth" +#define O_EYES "eyes" +#define O_HEART "heart" +#define O_LUNGS "lungs" +#define O_BRAIN "brain" +#define O_LIVER "liver" +#define O_KIDNEYS "kidneys" +#define O_PLASMA "plasma vessel" +#define O_HIVE "hive node" +#define O_NUTRIENT "nutrient vessel" +#define O_STRATA "neural strata" +#define O_RESPONSE "response node" +#define O_GBLADDER "gas bladder" +#define O_POLYP "polyp segment" +#define O_ANCHOR "anchoring ligament" +#define O_ACID "acid gland" +#define O_EGG "egg sac" +#define O_RESIN "resin spinner" + +#define BP_L_FOOT "l_foot" +#define BP_R_FOOT "r_foot" +#define BP_L_LEG "l_leg" +#define BP_R_LEG "r_leg" +#define BP_L_HAND "l_hand" +#define BP_R_HAND "r_hand" +#define BP_L_ARM "l_arm" +#define BP_R_ARM "r_arm" +#define BP_HEAD "head" +#define BP_TORSO "torso" +#define BP_GROIN "groin" +#define BP_ALL list(BP_GROIN, BP_TORSO, BP_HEAD, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG) + +#define SYNTH_BLOOD_COLOUR "#030303" +#define SYNTH_FLESH_COLOUR "#575757" \ No newline at end of file diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 96b50fc6c5f..5bb4c93bbcf 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -30,7 +30,7 @@ proc/random_hair_style(gender, species = "Human") for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] - if(gender != NEUTER) + if(gender != NEUTER && gender != PLURAL) if(gender == MALE && S.gender == FEMALE) continue if(gender == FEMALE && S.gender == MALE) @@ -52,7 +52,7 @@ proc/random_facial_hair_style(gender, species = "Human") for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - if(gender != NEUTER) + if(gender != NEUTER && gender != PLURAL) if(gender == MALE && S.gender == FEMALE) continue if(gender == FEMALE && S.gender == MALE) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index d0904aa4664..b066e431ce9 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -98,7 +98,7 @@ name = "damage zone" icon_state = "zone_sel" screen_loc = ui_zonesel - var/selecting = "chest" + var/selecting = BP_TORSO /obj/screen/zone_sel/Click(location, control,params) var/list/PL = params2list(params) @@ -110,52 +110,52 @@ if(1 to 3) //Feet switch(icon_x) if(10 to 15) - selecting = "r_foot" + selecting = BP_R_FOOT if(17 to 22) - selecting = "l_foot" + selecting = BP_L_FOOT else return 1 if(4 to 9) //Legs switch(icon_x) if(10 to 15) - selecting = "r_leg" + selecting = BP_R_LEG if(17 to 22) - selecting = "l_leg" + selecting = BP_L_LEG else return 1 if(10 to 13) //Hands and groin switch(icon_x) if(8 to 11) - selecting = "r_hand" + selecting = BP_R_HAND if(12 to 20) - selecting = "groin" + selecting = BP_GROIN if(21 to 24) - selecting = "l_hand" + selecting = BP_L_HAND else return 1 if(14 to 22) //Chest and arms to shoulders switch(icon_x) if(8 to 11) - selecting = "r_arm" + selecting = BP_R_ARM if(12 to 20) - selecting = "chest" + selecting = BP_TORSO if(21 to 24) - selecting = "l_arm" + selecting = BP_L_ARM else return 1 if(23 to 30) //Head, but we need to check for eye or mouth if(icon_x in 12 to 20) - selecting = "head" + selecting = BP_HEAD switch(icon_y) if(23 to 24) if(icon_x in 15 to 17) - selecting = "mouth" + selecting = O_MOUTH if(26) //Eyeline, eyes are on 15 and 17 if(icon_x in 14 to 18) - selecting = "eyes" + selecting = O_EYES if(25 to 27) if(icon_x in 15 to 17) - selecting = "eyes" + selecting = O_EYES if(old_selecting != selecting) update_icon() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index f748fdd53e7..afe5bd01c36 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -260,7 +260,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role) preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) var/use_eye_icon = "eyes_s" - var/obj/item/organ/external/head/temp_head = H.get_organ("head") + var/obj/item/organ/external/head/temp_head = H.get_organ(BP_HEAD) if(temp_head) use_eye_icon = temp_head.eye_icon var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = use_eye_icon) diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index d6f05d33ef0..5a21e6cb407 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -42,7 +42,7 @@ H << "Your abdomen is a world of pain!" H.Weaken(10) - var/obj/item/organ/external/groin = H.get_organ("groin") + var/obj/item/organ/external/groin = H.get_organ(BP_GROIN) var/datum/wound/W = new /datum/wound/internal_bleeding(20) H.adjustToxLoss(25) groin.wounds += W diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm index c76b5fe1851..d0d1183a0d9 100644 --- a/code/game/antagonist/alien/borer.dm +++ b/code/game/antagonist/alien/borer.dm @@ -37,12 +37,12 @@ var/datum/antagonist/xenos/borer/borers var/mob/living/carbon/human/host for(var/mob/living/carbon/human/H in mob_list) if(H.stat != DEAD && !H.has_brain_worms()) - var/obj/item/organ/external/head = H.get_organ("head") + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) if(head && !(head.status & ORGAN_ROBOT)) host = H break if(istype(host)) - var/obj/item/organ/external/head = host.get_organ("head") + var/obj/item/organ/external/head = host.get_organ(BP_HEAD) borer.host = host head.implants += borer borer.forceMove(head) diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm index b3f5605a91c..60380677d6c 100644 --- a/code/game/antagonist/station/changeling.dm +++ b/code/game/antagonist/station/changeling.dm @@ -54,3 +54,14 @@ survive_objective.owner = changeling changeling.objectives += survive_objective return + +/datum/antagonist/changeling/can_become_antag(var/datum/mind/player, var/ignore_role) + if(..()) + if(player.current && ishuman(player.current)) + var/mob/living/carbon/human/H = player.current + if(H.isSynthetic()) + return 0 + if(H.species.flags & NO_SCAN) + return 0 + return 1 + return 0 \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index f219e1d6c76..9f8fe69202b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -198,7 +198,7 @@ its easier to just keep the beam vertical. f_name = "some " else f_name = "a " - if(blood_color != "#030303") + if(blood_color != SYNTH_BLOOD_COLOUR) f_name += "blood-stained [name][infix]!" else f_name += "oil-stained [name][infix]." @@ -399,8 +399,7 @@ its easier to just keep the beam vertical. M.dna = new /datum/dna(null) M.dna.real_name = M.real_name M.check_dna() - if (M.species) - blood_color = M.species.get_blood_colour(M) + blood_color = M.species.get_blood_colour(M) . = 1 return 1 diff --git a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm index ff45c30d0a3..694e22e8dd2 100644 --- a/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm +++ b/code/game/gamemodes/changeling/powers/bioelectrogenesis.dm @@ -30,10 +30,10 @@ if(istype(held_item,/obj/item/weapon/grab)) var/obj/item/weapon/grab/G = held_item if(G.affecting) - G.affecting.electrocute_act(5,src,1.0,"chest") + G.affecting.electrocute_act(5,src,1.0,BP_TORSO) var/agony = 60 //The same as a stunbaton. var/stun = 0 - G.affecting.stun_effect_act(stun, agony, "chest", src) + G.affecting.stun_effect_act(stun, agony, BP_TORSO, src) msg_admin_attack("[key_name(src)] stunned [key_name(G.affecting)] with the [src].") @@ -112,10 +112,10 @@ src << "We require more chemicals to electrocute [C]!" return 0 - C.electrocute_act(5,src,1.0,"chest") + C.electrocute_act(5,src,1.0,BP_TORSO) var/agony = 60 //The same as a stunbaton. var/stun = 0 - C.stun_effect_act(stun, agony, "chest", src) + C.stun_effect_act(stun, agony, BP_TORSO, src) msg_admin_attack("[key_name(user)] stunned [key_name(C)] with the [src].") diff --git a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm index d273cc9c336..9b0d1e149a1 100644 --- a/code/game/gamemodes/changeling/powers/extract_dna_sting.dm +++ b/code/game/gamemodes/changeling/powers/extract_dna_sting.dm @@ -18,7 +18,18 @@ return 0 var/mob/living/carbon/human/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting) - if(!T) return 0 + + if(!istype(T) || T.isSynthetic()) + src << "\The [T] is not compatible with our biology." + return 0 + + if(T.species.flags & NO_SCAN) + src << "We do not know how to parse this creature's DNA!" + return 0 + + if(HUSK in T.mutations) + src << "This creature's DNA is ruined beyond useability!" + return 0 T.dna.real_name = T.real_name changeling.absorbed_dna |= T.dna diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 760a2d4833b..c5ea0bf9a93 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -631,8 +631,8 @@ var/list/sacrificed = list() if(!(iscultist(V))) victims += V//Checks for cult status and mob type for(var/obj/item/I in src.loc)//Checks for MMIs/brains/Intellicards - if(istype(I,/obj/item/organ/brain)) - var/obj/item/organ/brain/B = I + if(istype(I,/obj/item/organ/internal/brain)) + var/obj/item/organ/internal/brain/B = I victims += B.brainmob else if(istype(I,/obj/item/device/mmi)) var/obj/item/device/mmi/B = I diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index ed7c6ac8717..6b373953b11 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -406,7 +406,7 @@ datum/objective/harm if(!found) return 1 - var/obj/item/organ/external/head/head = H.get_organ("head") + var/obj/item/organ/external/head/head = H.get_organ(BP_HEAD) if(head.disfigured) return 1 return 0 diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index 251a6286974..7e40ee83183 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -107,6 +107,11 @@ path = /obj/item/device/radio/off category = "General" +/datum/autolathe/recipe/suit_cooler + name = "suit cooling unit" + path = /obj/item/device/suit_cooling_unit + category = "General" + /datum/autolathe/recipe/weldermask name = "welding mask" path = /obj/item/clothing/head/welding diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 0bb7dd19357..aab0560fe1b 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -16,11 +16,11 @@ var/stored_matter = 200 var/loaded_dna //Blood sample for DNA hashing. var/list/products = list( - "heart" = list(/obj/item/organ/heart, 50), - "lungs" = list(/obj/item/organ/lungs, 40), - "kidneys" = list(/obj/item/organ/kidneys,20), - "eyes" = list(/obj/item/organ/eyes, 30), - "liver" = list(/obj/item/organ/liver, 50) + O_HEART = list(/obj/item/organ/internal/heart, 50), + O_LUNGS = list(/obj/item/organ/internal/lungs, 40), + O_KIDNEYS = list(/obj/item/organ/internal/kidneys,20), + O_EYES = list(/obj/item/organ/internal/eyes, 30), + O_LIVER = list(/obj/item/organ/internal/liver, 50) ) /obj/machinery/bioprinter/prosthetics diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 9e9571b1778..27e6cb1a9da 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -722,12 +722,12 @@ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) var/damage = rand(5,15) - H.apply_damage(2*damage, BRUTE, "head") - H.apply_damage(2*damage, BRUTE, "chest") - H.apply_damage(0.5*damage, BRUTE, "l_leg") - H.apply_damage(0.5*damage, BRUTE, "r_leg") - H.apply_damage(0.5*damage, BRUTE, "l_arm") - H.apply_damage(0.5*damage, BRUTE, "r_arm") + H.apply_damage(2*damage, BRUTE, BP_HEAD) + H.apply_damage(2*damage, BRUTE, BP_TORSO) + H.apply_damage(0.5*damage, BRUTE, BP_L_LEG) + H.apply_damage(0.5*damage, BRUTE, BP_R_LEG) + H.apply_damage(0.5*damage, BRUTE, BP_L_ARM) + H.apply_damage(0.5*damage, BRUTE, BP_R_ARM) blood_splatter(src,H,1) bloodiness += 4 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c2758a7ffd9..cb8b9f5e692 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -645,24 +645,6 @@ About the new airlock wires panel: if(src.shock(user, 100)) return - // No. -- cib - /** - if(ishuman(user) && prob(40) && src.density) - var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= 60) - playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) - if(!istype(H.head, /obj/item/clothing/head/helmet)) - visible_message("[user] headbutts the airlock.") - var/obj/item/organ/external/affecting = H.get_organ("head") - H.Stun(8) - H.Weaken(5) - if(affecting.take_damage(10, 0)) - H.UpdateDamageIcon() - else - visible_message("[user] headbutts the airlock. Good thing they're wearing a helmet.") - return - **/ - if(src.p_open) user.set_machine(src) wires.Interact(user) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index e6fb41193cb..c7c1d59a083 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -73,7 +73,7 @@ if(!H.eyecheck() <= 0) continue flash_time *= H.species.flash_mod - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] if(!E) return if(E.is_bruised() && prob(E.damage + 50)) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 0fec7a9c1b2..d694fd5d4ca 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -106,7 +106,7 @@ if(NOCLONE in T.mutations) return - if(!T.should_have_organ("heart")) + if(!T.should_have_organ(O_HEART)) return // If the human is losing too much blood, beep. diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 9a950cc023c..f3d4e69611d 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -172,8 +172,9 @@ if(!src.occupant) visible_message("You hear a loud metallic grinding sound.") return + use_power(1000) - visible_message("You hear a loud squelchy grinding sound.") + visible_message("You hear a loud [occupant.isSynthetic() ? "metallic" : "squelchy"] grinding sound.") src.operating = 1 update_icon() @@ -192,7 +193,7 @@ else if(istype(src.occupant,/mob/living/carbon/human)) var/mob/living/carbon/human/H = occupant slab_name = src.occupant.real_name - slab_type = H.species.meat_type + slab_type = H.isSynthetic() ? /obj/item/stack/material/steel : H.species.meat_type // Small mobs don't give as much nutrition. if(issmall(src.occupant)) @@ -200,12 +201,12 @@ slab_nutrition /= slab_count for(var/i=1 to slab_count) - var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src) - new_meat.name = "[slab_name] [new_meat.name]" - new_meat.reagents.add_reagent("nutriment",slab_nutrition) - - if(src.occupant.reagents) - src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) + var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(src, rand(3,8)) + if(istype(new_meat)) + new_meat.name = "[slab_name] [new_meat.name]" + new_meat.reagents.add_reagent("nutriment",slab_nutrition) + if(src.occupant.reagents) + src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 553cf612d5e..355ee4b02d9 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -627,9 +627,9 @@ var/list/turret_icons var/def_zone var/obj/item/weapon/grab/G = locate() in target if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people. - def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg") + def_zone = pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) else - def_zone = pick("chest", "groin") + def_zone = pick(BP_TORSO, BP_GROIN) //Shooting Code: A.launch(target, def_zone) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 01d3d72dac5..bdc6b5ca446 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -103,10 +103,21 @@ R.adjustBruteLoss(-weld_rate) if(wire_rate && R.getFireLoss() && cell.checked_use(wire_power_use * wire_rate * CELLRATE)) R.adjustFireLoss(-wire_rate) + else if(istype(occupant, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = occupant - if(!isnull(H.internal_organs_by_name["cell"] && H.nutrition < 450)) + + // In case they somehow end up with positive values for otherwise unobtainable damage... + if(H.getToxLoss()>0) H.adjustToxLoss(-(rand(1,3))) + if(H.getOxyLoss()>0) H.adjustOxyLoss(-(rand(1,3))) + if(H.getCloneLoss()>0) H.adjustCloneLoss(-(rand(1,3))) + if(H.getBrainLoss()>0) H.adjustBrainLoss(-(rand(1,3))) + + // Also recharge their internal battery. + if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450) H.nutrition = min(H.nutrition+10, 450) + cell.use(7000/450*10) /obj/machinery/recharge_station/examine(mob/user) @@ -206,14 +217,14 @@ /obj/machinery/recharge_station/proc/go_in(var/mob/living/silicon/robot/R) + if(occupant) + return + if(istype(R, /mob/living/silicon/robot)) - if(!istype(R)) - return - if(occupant) - return if(R.incapacitated()) return + if(!R.cell) return diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index d3fe17a0689..83b8614a0e7 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -331,7 +331,7 @@ sleep(50) if(src.OCCUPANT) OCCUPANT.apply_effect(50, IRRADIATE) - var/obj/item/organ/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs + var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs if (!rad_organ) if (OCCUPANT.can_feel_pain()) OCCUPANT.emote("scream") diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index db548443cab..6254e2bb9df 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -266,15 +266,15 @@ else A = new /obj/item/projectile/energy/electrode( loc ) use_power(200) - + //Turrets aim for the center of mass by default. //If the target is grabbing someone then the turret smartly aims for extremities var/obj/item/weapon/grab/G = locate() in target if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people. - A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg") + A.def_zone = pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) else - A.def_zone = pick("chest", "groin") - + A.def_zone = pick(BP_TORSO, BP_GROIN) + A.current = T A.starting = T A.yo = U.y - T.y diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index c9c5c326236..5424882adc7 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -41,7 +41,7 @@ var/mob/living/carbon/human/H = target // if (M.health <= 0) return - var/obj/item/organ/external/temp = H.get_organ(pick("chest", "chest", "chest", "head")) + var/obj/item/organ/external/temp = H.get_organ(pick(BP_TORSO, BP_TORSO, BP_TORSO, BP_HEAD)) if(temp) var/update = 0 switch(damtype) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index aa9f9394932..598b8ad5d37 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -104,7 +104,7 @@ // Aliens can get straight through these. if(istype(usr,/mob/living/carbon)) var/mob/living/carbon/M = usr - if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) + if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) for(var/mob/O in oviewers(src)) O.show_message("[usr] strokes the [name] and it melts away!", 1) health = 0 @@ -349,7 +349,7 @@ Alien plants should do something if theres a lot of poison /obj/effect/alien/egg/attack_hand(user as mob) var/mob/living/carbon/M = user - if(!istype(M) || !(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)) + if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)) return attack_hand(user) switch(status) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 3a0395636e4..fcd53aab448 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -64,6 +64,12 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/update_icon() if(basecolor == "rainbow") basecolor = "#[get_random_colour(1)]" color = basecolor + if(basecolor == SYNTH_BLOOD_COLOUR) + name = "oil" + desc = "It's black and greasy." + else + name = initial(name) + desc = initial(desc) /obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp) if (!istype(perp)) diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 150197347de..1f49fc9f666 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -3,7 +3,7 @@ desc = "It's a useless heap of junk... or is it?" icon = 'icons/mob/robots.dmi' icon_state = "gib1" - basecolor="#030303" + basecolor = SYNTH_BLOOD_COLOUR random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") /obj/effect/decal/cleanable/blood/gibs/robot/update_icon() @@ -38,9 +38,7 @@ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4 /obj/effect/decal/cleanable/blood/oil - name = "motor oil" - desc = "It's black and greasy. Looks like Beepsky made another mess." - basecolor="#030303" + basecolor = SYNTH_BLOOD_COLOUR /obj/effect/decal/cleanable/blood/oil/dry() return diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 3b566fee6e3..4b6b437900b 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -220,9 +220,9 @@ src.loc = O.owner ? O.owner.loc : O.loc src.visible_message("\A [src] makes its way out of [O.owner ? "[O.owner]'s [O.name]" : "\the [O]"]!") if(O.owner) - O.owner.apply_damage(1, BRUTE, O.limb_name) + O.owner.apply_damage(1, BRUTE, O.organ_tag) else if(prob(1)) - O.owner.apply_damage(1, TOX, O.limb_name) + O.owner.apply_damage(1, TOX, O.organ_tag) if(world.time > last_itch + 30 SECONDS) last_itch = world.time O.owner << "Your [O.name] itches..." diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index eeed37b9e72..240aa6783e3 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -449,7 +449,7 @@ var/list/global/slot_flags_enumeration = list( if(istype(H)) - var/obj/item/organ/eyes/eyes = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = H.internal_organs_by_name[O_EYES] if(H != user) for(var/mob/O in (viewers(M) - user - M)) @@ -477,7 +477,7 @@ var/list/global/slot_flags_enumeration = list( if (eyes.damage >= eyes.min_broken_damage) if(M.stat != 2) M << "You go blind!" - var/obj/item/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) if(affecting.take_damage(7)) M:UpdateDamageIcon() else diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 21b6a0e7208..21e55e65ce4 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -38,7 +38,7 @@ /obj/item/device/flashlight/attack(mob/living/M as mob, mob/living/user as mob) add_fingerprint(user) - if(on && user.zone_sel.selecting == "eyes") + if(on && user.zone_sel.selecting == O_EYES) if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 7f9f7e2b988..37ceba94459 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -12,21 +12,25 @@ throwforce = 10.0 throw_speed = 1 throw_range = 4 + action_button_name = "Toggle Heatsink" + matter = list("steel" = 15000, "glass" = 3500) origin_tech = list(TECH_MAGNET = 2, TECH_MATERIAL = 2) var/on = 0 //is it turned on? var/cover_open = 0 //is the cover open? var/obj/item/weapon/cell/cell - var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here - var/charge_consumption = 16.6 //charge per second at max_cooling + var/max_cooling = 12 // in degrees per second - probably don't need to mess with heat capacity here + var/charge_consumption = 3 // charge per second at max_cooling var/thermostat = T20C //TODO: make it heat up the surroundings when not in space +/obj/item/device/suit_cooling_unit/ui_action_click() + toggle(usr) + /obj/item/device/suit_cooling_unit/New() processing_objects |= src - cell = new/obj/item/weapon/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find cell.loc = src @@ -56,7 +60,7 @@ cell.use(charge_usage) if(cell.charge <= 0) - turn_off() + turn_off(1) /obj/item/device/suit_cooling_unit/proc/get_environment_temperature() if (ishuman(loc)) @@ -97,14 +101,12 @@ on = 1 updateicon() -/obj/item/device/suit_cooling_unit/proc/turn_off() - if (ismob(src.loc)) - var/mob/M = src.loc - M.show_message("\The [src] clicks and whines as it powers down.", 2) //let them know in case it's run out of power. +/obj/item/device/suit_cooling_unit/proc/turn_off(var/failed) + if(failed) visible_message("\The [src] clicks and whines as it powers down.") on = 0 updateicon() -/obj/item/device/suit_cooling_unit/attack_self(mob/user as mob) +/obj/item/device/suit_cooling_unit/attack_self(var/mob/user) if(cover_open && cell) if(ishuman(user)) user.put_in_hands(cell) @@ -114,18 +116,19 @@ cell.add_fingerprint(user) cell.update_icon() - user << "You remove the [src.cell]." + user << "You remove \the [src.cell]." src.cell = null updateicon() return - //TODO use a UI like the air tanks + toggle(user) + +/obj/item/device/suit_cooling_unit/proc/toggle(var/mob/user) if(on) turn_off() else turn_on() - if (on) - user << "You switch on the [src]." + user << "You switch \the [src] [on ? "on" : "off"]." /obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/screwdriver)) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 1ccd2f88172..7cccb0eb106 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -30,35 +30,35 @@ name = "left arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_arm" - part = list("l_arm","l_hand") + part = list(BP_L_ARM, BP_L_HAND) model_info = 1 /obj/item/robot_parts/r_arm name = "right arm" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_arm" - part = list("r_arm","r_hand") + part = list(BP_R_ARM, BP_R_HAND) model_info = 1 /obj/item/robot_parts/l_leg name = "left leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "l_leg" - part = list("l_leg","l_foot") + part = list(BP_L_LEG, BP_L_FOOT) model_info = 1 /obj/item/robot_parts/r_leg name = "right leg" desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case." icon_state = "r_leg" - part = list("r_leg","r_foot") + part = list(BP_R_LEG, BP_R_FOOT) model_info = 1 /obj/item/robot_parts/chest - name = "torso" + name = "chest" desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" - part = list("groin","chest") + part = list(BP_GROIN,BP_TORSO) var/wires = 0.0 var/obj/item/weapon/cell/cell = null @@ -66,7 +66,7 @@ name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." icon_state = "head" - part = list("head") + part = list(BP_HEAD) var/obj/item/device/flash/flash1 = null var/obj/item/device/flash/flash2 = null diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index d3ba0a96a81..b8b79a5ca16 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -24,7 +24,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) - if(affecting.name == "head") + if(affecting.organ_tag == BP_HEAD) if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space)) user << "You can't apply [src] through [H.head]!" return 1 @@ -217,7 +217,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) var/limb = affecting.name - if(!(affecting.limb_name in list("l_arm","r_arm","l_leg","r_leg"))) + if(!(affecting.organ_tag in list("l_arm","r_arm","l_leg","r_leg"))) user << "You can't apply a splint there!" return if(affecting.status & ORGAN_SPLINTED) @@ -226,7 +226,7 @@ if (M != user) user.visible_message("[user] starts to apply \the [src] to [M]'s [limb].", "You start to apply \the [src] to [M]'s [limb].", "You hear something being wrapped.") else - if((!user.hand && affecting.limb_name == "r_arm") || (user.hand && affecting.limb_name == "l_arm")) + if((!user.hand && affecting.organ_tag == "r_arm") || (user.hand && affecting.organ_tag == "l_arm")) user << "You can't apply a splint to the arm you're using!" return user.visible_message("[user] starts to apply \the [src] to their [limb].", "You start to apply \the [src] to your [limb].", "You hear something being wrapped.") diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index a85ed010f91..0578c9ab6a6 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -478,7 +478,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM return M.IgniteMob() - if(istype(M.wear_mask, /obj/item/clothing/mask/smokable/cigarette) && user.zone_sel.selecting == "mouth" && lit) + if(istype(M.wear_mask, /obj/item/clothing/mask/smokable/cigarette) && user.zone_sel.selecting == O_MOUTH && lit) var/obj/item/clothing/mask/smokable/cigarette/cig = M.wear_mask if(M == user) cig.attackby(src, user) diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index e32b58e098f..92814eea6ca 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -39,7 +39,7 @@ return /obj/item/weapon/soap/attack(mob/target as mob, mob/user as mob) - if(target && user && ishuman(target) && ishuman(user) && !target.stat && !user.stat && user.zone_sel &&user.zone_sel.selecting == "mouth" ) + if(target && user && ishuman(target) && ishuman(user) && !target.stat && !user.stat && user.zone_sel &&user.zone_sel.selecting == O_MOUTH) user.visible_message("\The [user] washes \the [target]'s mouth out with soap!") return ..() diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index d01b380925f..fe215be2d87 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -84,7 +84,7 @@ //This really should be in mob not every check if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] if (E && E.damage >= E.min_bruised_damage) M << "Your eyes start to burn badly!" if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang))) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 09629e1aded..1ab42d80e24 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -94,11 +94,11 @@ var/last_chew = 0 var/mob/living/carbon/human/H = A if (!H.handcuffed) return if (H.a_intent != I_HURT) return - if (H.zone_sel.selecting != "mouth") return + if (H.zone_sel.selecting != O_MOUTH) return if (H.wear_mask) return if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return - var/obj/item/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] + var/obj/item/organ/external/O = H.organs_by_name[(H.hand ? BP_L_HAND : BP_R_HAND)] if (!O) return var/s = "[H.name] chews on \his [O.name]!" diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 6b2d0abf41c..f256e382233 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -27,7 +27,7 @@ return ..() if(user.a_intent != I_HELP) - if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes") + if(user.zone_sel.selecting == BP_HEAD || user.zone_sel.selecting == O_EYES) if((CLUMSY in user.mutations) && prob(50)) M = user return eyestab(M,user) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index dd33c7a6f28..1af88c9fa86 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -159,7 +159,7 @@ if(!istype(M, /mob)) return - if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask) + if(M == user && user.zone_sel.selecting == O_MOUTH && contents.len > 0 && !user.wear_mask) var/obj/item/clothing/mask/smokable/cigarette/W = new /obj/item/clothing/mask/smokable/cigarette(user) reagents.trans_to_obj(W, (reagents.total_volume/contents.len)) user.equip_to_slot_if_possible(W, slot_wear_mask) @@ -252,7 +252,7 @@ if(!istype(M, /mob)) return - if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask) + if(M == user && user.zone_sel.selecting == O_MOUTH && contents.len > 0 && !user.wear_mask) var/obj/item/clothing/mask/smokable/cigarette/cigar/W = new /obj/item/clothing/mask/smokable/cigarette/cigar(user) reagents.trans_to_obj(W, (reagents.total_volume/contents.len)) user.equip_to_slot_if_possible(W, slot_wear_mask) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 15eb430a3f0..c773f3da383 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -30,7 +30,7 @@ user.Weaken(3 * force) if(ishuman(user)) var/mob/living/carbon/human/H = user - H.apply_damage(2*force, BRUTE, "head") + H.apply_damage(2*force, BRUTE, BP_HEAD) else user.take_organ_damage(2*force) return @@ -123,7 +123,7 @@ user.Weaken(3 * force) if(ishuman(user)) var/mob/living/carbon/human/H = user - H.apply_damage(2*force, BRUTE, "head") + H.apply_damage(2*force, BRUTE, BP_HEAD) else user.take_organ_damage(2*force) return diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 04c0a5fbfea..f87000dd87e 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -7,9 +7,9 @@ /obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user) if(istype(H)) - if(user.zone_sel.selecting == "eyes") + if(user.zone_sel.selecting == O_EYES) - if(!H.organs_by_name["head"]) + if(!H.organs_by_name[BP_HEAD]) user << "\The [H] doesn't have a head." return if(!H.has_eyes()) @@ -27,14 +27,14 @@ return // Repeat failure checks. - if(!H || !src || !H.organs_by_name["head"] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE))) + if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE))) return user.visible_message("\The [user] has taped up \the [H]'s eyes!") H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/blindfold/tape(H), slot_glasses) - else if(user.zone_sel.selecting == "mouth" || user.zone_sel.selecting == "head") - if(!H.organs_by_name["head"]) + else if(user.zone_sel.selecting == O_MOUTH || user.zone_sel.selecting == BP_HEAD) + if(!H.organs_by_name[BP_HEAD]) user << "\The [H] doesn't have a head." return if(!H.check_has_mouth()) @@ -52,7 +52,7 @@ return // Repeat failure checks. - if(!H || !src || !H.organs_by_name["head"] || !H.check_has_mouth() || H.wear_mask || (H.head && (H.head.body_parts_covered & FACE))) + if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.check_has_mouth() || H.wear_mask || (H.head && (H.head.body_parts_covered & FACE))) return user.visible_message("\The [user] has taped up \the [H]'s mouth!") diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 0e1f0dadc3e..2788905eeb1 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -83,7 +83,7 @@ /obj/item/weapon/screwdriver/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!istype(M) || user.a_intent == "help") return ..() - if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head") + if(user.zone_sel.selecting != O_EYES && user.zone_sel.selecting != BP_HEAD) return ..() if((CLUMSY in user.mutations) && prob(50)) M = user @@ -333,7 +333,7 @@ var/safety = user:eyecheck() if(istype(user, /mob/living/carbon/human)) var/mob/living/carbon/human/H = user - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] if(!E) return switch(safety) diff --git a/code/game/objects/items/weapons/trays.dm b/code/game/objects/items/weapons/trays.dm index aca5196cfdb..d4a7117bbb4 100644 --- a/code/game/objects/items/weapons/trays.dm +++ b/code/game/objects/items/weapons/trays.dm @@ -45,7 +45,7 @@ var/mob/living/carbon/human/H = M ///////////////////////////////////// /Let's have this ready for later. - if(!(user.zone_sel.selecting == ("eyes" || "head"))) //////////////hitting anything else other than the eyes + if(!(user.zone_sel.selecting == (O_EYES || BP_HEAD))) //////////////hitting anything else other than the eyes if(prob(33)) src.add_blood(H) var/turf/location = H.loc @@ -79,7 +79,7 @@ if(istype(protection) && (protection.body_parts_covered & FACE)) protected = 1 break - + if(protected) M << "You get slammed in the face with the tray, against your mask!" if(prob(33)) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 5b84455ac77..886ccc2caea 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -140,15 +140,15 @@ switch(pick(list("ankle","wrist","head","knee","elbow"))) if("ankle") - affecting = H.get_organ(pick("l_foot", "r_foot")) + affecting = H.get_organ(pick(BP_L_FOOT, BP_R_FOOT)) if("knee") - affecting = H.get_organ(pick("l_leg", "r_leg")) + affecting = H.get_organ(pick(BP_L_LEG, BP_R_LEG)) if("wrist") - affecting = H.get_organ(pick("l_hand", "r_hand")) + affecting = H.get_organ(pick(BP_L_HAND, BP_R_HAND)) if("elbow") - affecting = H.get_organ(pick("l_arm", "r_arm")) + affecting = H.get_organ(pick(BP_L_ARM, BP_R_ARM)) if("head") - affecting = H.get_organ("head") + affecting = H.get_organ(BP_HEAD) if(affecting) M << "You land heavily on your [affecting.name]!" diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 977a3939d96..cbe89ec86f0 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -48,10 +48,10 @@ var/mob/living/carbon/xenos = user var/mob/living/carbon/victim = M - if(istype(victim) && locate(/obj/item/organ/xenos/hivenode) in victim.internal_organs) + if(istype(victim) && locate(/obj/item/organ/internal/xenos/hivenode) in victim.internal_organs) return - if(istype(xenos) && !(locate(/obj/item/organ/xenos/hivenode) in xenos.internal_organs)) + if(istype(xenos) && !(locate(/obj/item/organ/internal/xenos/hivenode) in xenos.internal_organs)) return if(M == usr) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 720a3d3c075..71b607be180 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -97,33 +97,33 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/organ_name = null switch(name) - if("torso") + if(BP_TORSO) organ_name = "torso" - if("groin") + if(BP_GROIN) organ_name = "groin" - if("head") + if(BP_HEAD) organ_name = "head" - if("l_arm") + if(BP_L_ARM) organ_name = "left arm" - if("r_arm") + if(BP_R_ARM) organ_name = "right arm" - if("l_leg") + if(BP_L_LEG) organ_name = "left leg" - if("r_leg") + if(BP_R_LEG) organ_name = "right leg" - if("l_foot") + if(BP_L_FOOT) organ_name = "left foot" - if("r_foot") + if(BP_R_FOOT) organ_name = "right foot" - if("l_hand") + if(BP_L_HAND) organ_name = "left hand" - if("r_hand") + if(BP_R_HAND) organ_name = "right hand" - if("heart") + if(O_HEART) organ_name = "heart" - if("eyes") + if(O_EYES) organ_name = "eyes" - if("brain") + if(O_BRAIN) organ_name = "brain" if(status == "cyborg") @@ -351,56 +351,73 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return TOPIC_REFRESH else if(href_list["limbs"]) - var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand","Full Body") - if(!limb_name && !CanUseTopic(user)) return TOPIC_NOACTION + + var/list/limb_selection_list = list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand","Full Body") + + // Full prosthetic bodies without a brain are borderline unkillable so make sure they have a brain to remove/destroy. + var/datum/species/current_species = all_species[pref.species] + if(!current_species.has_organ["brain"]) + limb_selection_list -= "Full Body" + + var/organ_tag = input(user, "Which limb do you want to change?") as null|anything in limb_selection_list + + if(!organ_tag && !CanUseTopic(user)) return TOPIC_NOACTION var/limb = null var/second_limb = null // if you try to change the arm, the hand should also change var/third_limb = null // if you try to unchange the hand, the arm should also change - switch(limb_name) + + // Do not let them amputate their entire body, ty. + var/list/choice_options = list("Normal","Amputated","Prothesis") + switch(organ_tag) if("Left Leg") - limb = "l_leg" - second_limb = "l_foot" + limb = BP_L_LEG + second_limb = BP_L_FOOT if("Right Leg") - limb = "r_leg" - second_limb = "r_foot" + limb = BP_R_LEG + second_limb = BP_R_FOOT if("Left Arm") - limb = "l_arm" - second_limb = "l_hand" + limb = BP_L_ARM + second_limb = BP_L_HAND if("Right Arm") - limb = "r_arm" - second_limb = "r_hand" + limb = BP_R_ARM + second_limb = BP_R_HAND if("Left Foot") - limb = "l_foot" - third_limb = "l_leg" + limb = BP_L_FOOT + third_limb = BP_L_LEG if("Right Foot") - limb = "r_foot" - third_limb = "r_leg" + limb = BP_R_FOOT + third_limb = BP_R_LEG if("Left Hand") - limb = "l_hand" - third_limb = "l_arm" + limb = BP_L_HAND + third_limb = BP_L_ARM if("Right Hand") - limb = "r_hand" - third_limb = "r_arm" + limb = BP_R_HAND + third_limb = BP_R_ARM if("Full Body") - limb = "torso" - + limb = BP_TORSO + third_limb = BP_GROIN + choice_options = list("Normal","Prothesis") - var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis") + var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in choice_options if(!new_state && !CanUseTopic(user)) return TOPIC_NOACTION switch(new_state) if("Normal") + + if(limb == BP_TORSO) + for(var/other_limb in BP_ALL - BP_TORSO) + pref.organ_data[other_limb] = null + pref.rlimb_data[other_limb] = null pref.organ_data[limb] = null pref.rlimb_data[limb] = null if(third_limb) pref.organ_data[third_limb] = null pref.rlimb_data[third_limb] = null - if("Amputated") - if(limb == "torso") + if("Amputated") + if(limb == BP_TORSO) return - pref.organ_data[limb] = "amputated" pref.rlimb_data[limb] = null if(second_limb) @@ -430,43 +447,45 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O if(third_limb && pref.organ_data[third_limb] == "amputated") pref.organ_data[third_limb] = null - if(limb == "torso") - for(var/other_limb in list("l_foot","r_foot","l_hand","r_hand","l_leg","r_leg","l_arm","r_arm","groin","head")) + if(limb == BP_TORSO) + for(var/other_limb in BP_ALL - BP_TORSO) if(pref.organ_data[other_limb]) continue pref.organ_data[other_limb] = "cyborg" pref.rlimb_data[other_limb] = choice - if(!pref.organ_data["brain"]) - pref.organ_data["brain"] = "assisted" - for(var/internal_organ in list("heart","eyes")) + if(!pref.organ_data[O_BRAIN]) + pref.organ_data[O_BRAIN] = "assisted" + for(var/internal_organ in list(O_HEART,O_EYES)) pref.organ_data[internal_organ] = "mechanical" return TOPIC_REFRESH else if(href_list["organs"]) + var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes", "Brain") if(!organ_name) return var/organ = null switch(organ_name) if("Heart") - organ = "heart" + organ = O_HEART if("Eyes") - organ = "eyes" + organ = O_EYES if("Brain") - if(pref.organ_data["head"] != "cyborg") + if(pref.organ_data[BP_HEAD] != "cyborg") user << "You may only select an assisted or synthetic brain if you have a full prosthetic body." return organ = "brain" - var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical") + var/list/organ_choices = list("Normal","Assisted","Mechanical") + if(pref.organ_data[BP_TORSO] == "cyborg") + organ_choices -= "Normal" + + var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in organ_choices if(!new_state) return switch(new_state) if("Normal") - if(pref.organ_data["torso"] == "cyborg") - user << "A character with a synthetic body may only use synthetic organs." - return pref.organ_data[organ] = null if("Assisted") pref.organ_data[organ] = "assisted" @@ -512,9 +531,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "
Often present on human stations." if(current_species.spawn_flags & IS_WHITELISTED) dat += "
Whitelist restricted." - if(!current_species.has_organ["heart"]) + if(!current_species.has_organ[O_HEART]) dat += "
Does not have a circulatory system." - if(!current_species.has_organ["lungs"]) + if(!current_species.has_organ[O_LUNGS]) dat += "
Does not have a respiratory system." if(current_species.flags & NO_SCAN) dat += "
Does not have DNA." diff --git a/code/modules/client/preference_setup/global/03_pai.dm b/code/modules/client/preference_setup/global/03_pai.dm index 7944c7b6e7d..8e0b4ea8a5c 100644 --- a/code/modules/client/preference_setup/global/03_pai.dm +++ b/code/modules/client/preference_setup/global/03_pai.dm @@ -24,6 +24,9 @@ /datum/category_item/player_setup_item/player_global/pai/content(var/mob/user) . += "pAI:
" + if(!candidate) + log_debug("[user] pAI prefs have a null candidate var.") + return . . += "Name: [candidate.name ? candidate.name : "None Set"]
" . += "Description: [candidate.description ? TextPreview(candidate.description, 40) : "None Set"]
" . += "Role: [candidate.role ? TextPreview(candidate.role, 40) : "None Set"]
" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index b4060b221fb..971d73ed6d3 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -304,36 +304,29 @@ datum/preferences character.skills = skills character.used_skillpoints = used_skillpoints - // Destroy/cyborgize organs - - for(var/name in organ_data) - + // Destroy/cyborgize organs and limbs. + for(var/name in BP_ALL) var/status = organ_data[name] var/obj/item/organ/external/O = character.organs_by_name[name] - if(name == "torso" && !O) - O = character.organs_by_name["chest"] if(O) - O.status = 0 if(status == "amputated") - character.organs_by_name[O.limb_name] = null - character.organs -= O - if(O.children) // This might need to become recursive. - for(var/obj/item/organ/external/child in O.children) - character.organs_by_name[child.limb_name] = null - character.organs -= child - + O.remove_rejuv() else if(status == "cyborg") if(rlimb_data[name]) O.robotize(rlimb_data[name]) else O.robotize() - else - var/obj/item/organ/I = character.internal_organs_by_name[name] - if(I) - if(status == "assisted") - I.mechassist() - else if(status == "mechanical") - I.robotize() + + for(var/name in list(O_HEART,O_EYES,O_BRAIN)) + var/status = organ_data[name] + if(!status) + continue + var/obj/item/organ/I = character.internal_organs_by_name[name] + if(I) + if(status == "assisted") + I.mechassist() + else if(status == "mechanical") + I.robotize() character.underwear = underwear character.undershirt = undershirt diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index e7ba59a5eff..2b6cf436302 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -93,7 +93,7 @@ var/obj/item/projectile/P = damage_source var/reflectchance = 40 - round(damage/3) - if(!(def_zone in list("chest", "groin"))) + if(!(def_zone in list(BP_TORSO, BP_GROIN))) reflectchance /= 2 if(P.starting && prob(reflectchance)) visible_message("\The [user]'s [src.name] reflects [attack_text]!") diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index f57b9c9be29..51cbe7baa4b 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -99,7 +99,7 @@ var/sound = "heartbeat" var/sound_strength = "cannot hear" var/heartbeat = 0 - var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"] + var/obj/item/organ/internal/heart/heart = M.internal_organs_by_name[O_HEART] if(heart && !(heart.status & ORGAN_ROBOT)) heartbeat = 1 if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) @@ -107,7 +107,7 @@ sound = "anything" else switch(body_part) - if("chest") + if(BP_TORSO) sound_strength = "hear" sound = "no heartbeat" if(heartbeat) @@ -116,14 +116,14 @@ else sound = "healthy heartbeat" - var/obj/item/organ/heart/L = M.internal_organs_by_name["lungs"] + var/obj/item/organ/internal/heart/L = M.internal_organs_by_name[O_LUNGS] if(!L || M.losebreath) sound += " and no respiration" else if(M.is_lung_ruptured() || M.getOxyLoss() > 50) sound += " and [pick("wheezing","gurgling")] sounds" else sound += " and healthy respiration" - if("eyes","mouth") + if(O_EYES,O_MOUTH) sound_strength = "cannot hear" sound = "anything" else diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 105b8d9c804..061f7bf9e91 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -600,4 +600,11 @@ desc = "A red shirt that has had the top cut low." icon_state = "cuttop_red" item_state = "r_suit" - worn_state = "cuttop_red" \ No newline at end of file + worn_state = "cuttop_red" + +/obj/item/clothing/under/harness + name = "gear harness" + desc = "How... minimalist." + icon_state = "gear_harness" + worn_state = "gear_harness" + body_parts_covered = 0 \ No newline at end of file diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 816a228a9c5..300c48ee4c3 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -111,7 +111,7 @@ user.do_attack_animation(src) M.IgniteMob() else if(reagents.total_volume) - if(user.zone_sel.selecting == "mouth") + if(user.zone_sel.selecting == O_MOUTH) user.do_attack_animation(src) user.visible_message( "\The [user] smothers [target] with [src]!", diff --git a/code/modules/detectivework/tools/swabs.dm b/code/modules/detectivework/tools/swabs.dm index 847c0280125..b0b0bb78700 100644 --- a/code/modules/detectivework/tools/swabs.dm +++ b/code/modules/detectivework/tools/swabs.dm @@ -32,8 +32,8 @@ user.visible_message("\The [user] tries to take a swab sample from \the [H], but they move away.") return - if(user.zone_sel.selecting == "mouth") - if(!H.organs_by_name["head"]) + if(user.zone_sel.selecting == O_MOUTH) + if(!H.organs_by_name[BP_HEAD]) user << "They don't have a head." return if(!H.check_has_mouth()) @@ -43,13 +43,13 @@ dna = list(H.dna.unique_enzymes) sample_type = "DNA" - else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand") + else if(user.zone_sel.selecting == BP_R_HAND || user.zone_sel.selecting == BP_L_HAND) var/has_hand - var/obj/item/organ/external/O = H.organs_by_name["r_hand"] + var/obj/item/organ/external/O = H.organs_by_name[BP_R_HAND] if(istype(O) && !O.is_stump()) has_hand = 1 else - O = H.organs_by_name["l_hand"] + O = H.organs_by_name[BP_L_HAND] if(istype(O) && !O.is_stump()) has_hand = 1 if(!has_hand) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 9c696c975e3..4eb60cc7064 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -91,7 +91,7 @@ I said no! /datum/recipe/brainburger items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/organ/brain + /obj/item/organ/internal/brain ) result = /obj/item/weapon/reagent_containers/food/snacks/brainburger @@ -1020,5 +1020,5 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake /datum/recipe/cake/brain - items = list(/obj/item/organ/brain) + items = list(/obj/item/organ/internal/brain) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake \ No newline at end of file diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index d0768a34400..dcb5b4e4990 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -25,7 +25,7 @@ finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("dexalin")) - for(var/organ_name in list("chest","l_arm","r_arm","r_leg","l_leg","head","groin")) + for(var/organ_name in BP_ALL) var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(0, 5, 0) @@ -41,7 +41,7 @@ finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("bicaridine")) - var/organ_name = pick("chest","l_arm","r_arm","r_leg","l_leg","head","groin") + var/organ_name = pick(BP_ALL) var/obj/item/organ/external/E = H.get_organ(organ_name) E.take_damage(20, 0, 0) E.fracture() diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index b1d17a6a699..e9be2bf9938 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -110,7 +110,7 @@ return - if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin") + if(!target_limb) target_limb = pick(BP_ALL) var/obj/item/organ/external/affecting = target.get_organ(target_limb) var/damage = 0 diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 44cde40ced2..13caccfba02 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -252,7 +252,7 @@ ..() /obj/item/weapon/book/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(user.zone_sel.selecting == "eyes") + if(user.zone_sel.selecting == O_EYES) user.visible_message("You open up the book and show it to [M]. ", \ " [user] opens up a book and shows it to [M]. ") M << browse("Penned by [author].
" + "[dat]", "window=book") diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 158c9ef8760..d4a6b85f5db 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -651,7 +651,7 @@ var/list/name_to_material /material/resin/can_open_material_door(var/mob/living/user) var/mob/living/carbon/M = user - if(istype(M) && locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) + if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) return 1 return 0 diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 038591b735e..1f6a663620d 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -104,9 +104,9 @@ if(88) new/obj/item/xenos_claw(src) if(89) - new/obj/item/organ/xenos/plasmavessel(src) + new/obj/item/organ/internal/xenos/plasmavessel(src) if(90) - new/obj/item/organ/heart(src) + new/obj/item/organ/internal/heart(src) if(91) new/obj/item/device/soulstone(src) if(92) @@ -168,8 +168,8 @@ var/turf/T = get_turf(src.loc) explosion(T, 0, 0, 1, 2) qdel(src) - -/obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user) + +/obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user) if (locked) user << "The crate unlocks!" locked = 0 @@ -177,7 +177,7 @@ /obj/structure/closet/crate/secure/loot/proc/check_input(var/input) if(length(input) != codelen) return 0 - + . = 1 lastattempt.Cut() for(var/i in 1 to codelen) @@ -197,7 +197,7 @@ if(lastattempt.len) var/bulls = 0 var/cows = 0 - + var/list/code_contents = code.Copy() for(var/i in 1 to codelen) if(lastattempt[i] == code[i]) diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index c42f76623c4..f496c82e67f 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -131,6 +131,9 @@ return ask_verb return speech_verb +/datum/language/proc/can_speak_special(var/mob/speaker) + return 1 + // Language handling. /mob/proc/add_language(var/language) @@ -155,7 +158,7 @@ // Can we speak this language, as opposed to just understanding it? /mob/proc/can_speak(datum/language/speaking) - return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) + return (speaking.can_speak_special(src) && (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages)) /mob/proc/get_language_prefix() if(client && client.prefs.language_prefixes && client.prefs.language_prefixes.len) diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index 7295a6ae205..308bf0a7c8c 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -24,7 +24,7 @@ var/mob/living/carbon/M = other if(!istype(M)) return 1 - if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs) + if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) return 1 return 0 diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index d237f36b090..53d42c47690 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -106,13 +106,14 @@ syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz") space_chance = 10 +/datum/language/machine/can_speak_special(var/mob/speaker) + return speaker.isSynthetic() + /datum/language/machine/get_random_name() - var/new_name if(prob(70)) - new_name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" + return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" else - new_name = pick(ai_names) - return new_name + return pick(ai_names) //Syllable Lists /* diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 548eee230b9..4ebf7986b6c 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -11,4 +11,4 @@ /mob/living/carbon/alien/larva/New() ..() add_language("Xenomorph") //Bonus language. - internal_organs |= new /obj/item/organ/xenos/hivenode(src) \ No newline at end of file + internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 03de410f5ee..5fe22558038 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -31,25 +31,24 @@ var/locked = 0 var/mob/living/carbon/brain/brainmob = null//The current occupant. - var/obj/item/organ/brain/brainobj = null //The current brain organ. + var/obj/item/organ/internal/brain/brainobj = null //The current brain organ. var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm. attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO + if(istype(O,/obj/item/organ/internal/brain) && !brainmob) //Time to stick a brain in it --NEO - var/obj/item/organ/brain/B = O + var/obj/item/organ/internal/brain/B = O if(B.health <= 0) - user << "\red That brain is well and truly dead." + user << "That brain is well and truly dead." return else if(!B.brainmob) - user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain." + user << "You aren't sure where this brain came from, but you're pretty sure it's useless." return - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] sticks \a [O] into \the [src].")) + user.visible_message("\The [user] sticks \a [O] into \the [src].") - brainmob = O:brainmob - O:brainmob = null + brainmob = B.brainmob + B.brainmob = null brainmob.loc = src brainmob.container = src brainmob.stat = 0 @@ -72,9 +71,9 @@ if((istype(O,/obj/item/weapon/card/id)||istype(O,/obj/item/device/pda)) && brainmob) if(allowed(user)) locked = !locked - user << "\blue You [locked ? "lock" : "unlock"] the brain holder." + user << "You [locked ? "lock" : "unlock"] the brain holder." else - user << "\red Access denied." + user << "Access denied." return if(brainmob) O.attack(brainmob, user)//Oh noooeeeee @@ -84,12 +83,12 @@ //TODO: ORGAN REMOVAL UPDATE. Make the brain remain in the MMI so it doesn't lose organ data. attack_self(mob/user as mob) if(!brainmob) - user << "\red You upend the MMI, but there's nothing in it." + user << "You upend the MMI, but there's nothing in it." else if(locked) - user << "\red You upend the MMI, but the brain is clamped into place." + user << "You upend the MMI, but the brain is clamped into place." else - user << "\blue You upend the MMI, spilling the brain onto the floor." - var/obj/item/organ/brain/brain + user << "You upend the MMI, spilling the brain onto the floor." + var/obj/item/organ/internal/brain/brain if (brainobj) //Pull brain organ out of MMI. brainobj.loc = user.loc brain = brainobj @@ -158,7 +157,7 @@ brainmob << "Can't do that while incapacitated or dead." radio.broadcasting = radio.broadcasting==1 ? 0 : 1 - brainmob << "\blue Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting." + brainmob << "Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting." Toggle_Listening() set name = "Toggle Listening" @@ -171,7 +170,7 @@ brainmob << "Can't do that while incapacitated or dead." radio.listening = radio.listening==1 ? 0 : 1 - brainmob << "\blue Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast." + brainmob << "Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast." /obj/item/device/mmi/emp_act(severity) if(!brainmob) diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index fc1e7778adb..6e1d4bce9c2 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,9 +1,9 @@ -/obj/item/organ/brain +/obj/item/organ/internal/brain name = "brain" health = 400 //They need to live awhile longer than other organs. Is this even used by organ code anymore? desc = "A piece of juicy meat found in a person's head." organ_tag = "brain" - parent_organ = "head" + parent_organ = BP_HEAD vital = 1 icon_state = "brain2" force = 1.0 @@ -15,89 +15,86 @@ attack_verb = list("attacked", "slapped", "whacked") var/mob/living/carbon/brain/brainmob = null +/obj/item/organ/internal/brain/robotize() + replace_self_with(/obj/item/organ/internal/mmi_holder/posibrain) -/obj/item/organ/brain/robotize() - replace_self_with(/obj/item/organ/mmi_holder/posibrain) +/obj/item/organ/internal/brain/mechassist() + replace_self_with(/obj/item/organ/internal/mmi_holder) -/obj/item/organ/brain/mechassist() - replace_self_with(/obj/item/organ/mmi_holder) +/obj/item/organ/internal/brain/proc/replace_self_with(replace_path) + var/mob/living/carbon/human/tmp_owner = owner + qdel(src) + if(tmp_owner) + tmp_owner.internal_organs_by_name[organ_tag] = new replace_path(tmp_owner, 1) + tmp_owner = null -/obj/item/organ/brain/proc/replace_self_with(replace_path) - if(!owner) - new replace_path(src.loc) - qdel(src) - return - owner.internal_organs_by_name[organ_tag] = new replace_path(owner, 1) - owner.internal_organs -= src - while(null in owner.internal_organs_by_name) - owner.internal_organs_by_name -= null - while(null in owner.internal_organs) - owner.internal_organs -= null - -/obj/item/organ/pariah_brain +/obj/item/organ/internal/pariah_brain name = "brain remnants" desc = "Did someone tread on this? It looks useless for cloning or cyborgification." organ_tag = "brain" - parent_organ = "head" + parent_organ = BP_HEAD icon = 'icons/mob/alien.dmi' icon_state = "chitin" vital = 1 -/obj/item/organ/brain/xeno +/obj/item/organ/internal/brain/xeno name = "thinkpan" desc = "It looks kind of like an enormous wad of purple bubblegum." icon = 'icons/mob/alien.dmi' icon_state = "chitin" -/obj/item/organ/brain/New() +/obj/item/organ/internal/brain/New() ..() health = config.default_brain_health spawn(5) if(brainmob && brainmob.client) brainmob.client.screen.len = null //clear the hud -/obj/item/organ/brain/Destroy() +/obj/item/organ/internal/brain/Destroy() if(brainmob) qdel(brainmob) brainmob = null ..() -/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H) - name = "\the [H]'s [initial(src.name)]" - brainmob = new(src) - brainmob.name = H.real_name - brainmob.real_name = H.real_name - brainmob.dna = H.dna.Clone() - brainmob.timeofhostdeath = H.timeofdeath +/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H) + + if(!brainmob) + brainmob = new(src) + brainmob.name = H.real_name + brainmob.real_name = H.real_name + brainmob.dna = H.dna.Clone() + brainmob.timeofhostdeath = H.timeofdeath + if(H.mind) H.mind.transfer_to(brainmob) - brainmob << "You feel slightly disoriented. That's normal when you're just a [initial(src.name)]." + brainmob << "You feel slightly disoriented. That's normal when you're just \a [initial(src.name)]." callHook("debrain", list(brainmob)) -/obj/item/organ/brain/examine(mob/user) // -- TLE +/obj/item/organ/internal/brain/examine(mob/user) // -- TLE ..(user) if(brainmob && brainmob.client)//if thar be a brain inside... the brain. user << "You can feel the small spark of life still left in this one." else user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.." -/obj/item/organ/brain/removed(var/mob/living/user) +/obj/item/organ/internal/brain/removed(var/mob/living/user) - name = "[owner.real_name]'s brain" + if(name == initial(name)) + name = "\the [owner.real_name]'s [initial(name)]" var/mob/living/simple_animal/borer/borer = owner.has_brain_worms() if(borer) borer.detatch() //Should remove borer if the brain is removed - RR - var/obj/item/organ/brain/B = src + var/obj/item/organ/internal/brain/B = src if(istype(B) && istype(owner)) B.transfer_identity(owner) ..() -/obj/item/organ/brain/replaced(var/mob/living/target) +/obj/item/organ/internal/brain/replaced(var/mob/living/target) if(target.key) target.ghostize() @@ -109,13 +106,13 @@ target.key = brainmob.key ..() -/obj/item/organ/brain/slime +/obj/item/organ/internal/brain/slime name = "slime core" desc = "A complex, organic knot of jelly and crystalline particles." icon = 'icons/mob/slimes.dmi' icon_state = "green slime extract" -/obj/item/organ/brain/golem +/obj/item/organ/internal/brain/golem name = "chem" desc = "A tightly furled roll of paper, covered with indecipherable runes." icon = 'icons/obj/wizard.dmi' diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index 43918f5288f..8b6e7f71756 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -9,6 +9,6 @@ if(istype(container, /obj/item/device/mmi)) qdel(container)//Gets rid of the MMI if there is one if(loc) - if(istype(loc,/obj/item/organ/brain)) + if(istype(loc,/obj/item/organ/internal/brain)) qdel(loc)//Gets rid of the brain item ..(null,1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm index fa87736f26c..476e1c11176 100644 --- a/code/modules/mob/living/carbon/breathe.dm +++ b/code/modules/mob/living/carbon/breathe.dm @@ -7,7 +7,7 @@ /mob/living/carbon/proc/breathe() //if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return - if(!should_have_organ("lungs") || does_not_breathe) return + if(!should_have_organ(O_LUNGS) || does_not_breathe) return var/datum/gas_mixture/breath = null diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f0b09f88d62..a45f378ab46 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -56,7 +56,7 @@ var/d = rand(round(I.force / 4), I.force) if(istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src - var/obj/item/organ/external/organ = H.get_organ("chest") + var/obj/item/organ/external/organ = H.get_organ(BP_TORSO) if (istype(organ)) if(organ.take_damage(d, 0)) H.UpdateDamageIcon() diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index cf404df6ffe..823ac808ec2 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -159,7 +159,7 @@ /mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1) var/use_species = species.get_bodytype() - var/obj/item/organ/external/head/H = get_organ("head") + var/obj/item/organ/external/head/H = get_organ(BP_HEAD) if(H) use_species = H.species.get_bodytype() var/list/valid_hairstyles = new() @@ -181,7 +181,7 @@ /mob/living/carbon/human/proc/generate_valid_facial_hairstyles() var/use_species = species.get_bodytype() - var/obj/item/organ/external/head/H = get_organ("head") + var/obj/item/organ/external/head/H = get_organ(BP_HEAD) if(H) use_species = H.species.get_bodytype() var/list/valid_facial_hairstyles = new() diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index a01a8f4ee86..359d60c3e1d 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -38,7 +38,7 @@ animate_tail_stop() //Handle brain slugs. - var/obj/item/organ/external/head = get_organ("head") + var/obj/item/organ/external/head = get_organ(BP_HEAD) var/mob/living/simple_animal/borer/B for(var/I in head.implants) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 65099437548..94c7f4600a6 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -19,11 +19,43 @@ if(src.stat == 2.0 && (act != "deathgasp")) return switch(act) + if ("airguitar") if (!src.restrained()) message = "is strumming the air and headbanging like a safari chimp." m_type = 1 + if("ping", "beep", "buzz") + + if(!isSynthetic()) + src << "You are not a synthetic." + return + + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + var/display_msg = "beeps" + var/use_sound = 'sound/machines/twobeep.ogg' + if(act == "buzz") + display_msg = "buzzes" + use_sound = 'sound/machines/buzz-sigh.ogg' + else if(act == "ping") + display_msg = "pings" + use_sound = 'sound/machines/ping.ogg' + + if (param) + message = "[display_msg] at [param]." + else + message = "[display_msg]." + playsound(src.loc, use_sound, 50, 0) + m_type = 1 + if ("blink") message = "blinks." m_type = 1 diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 650a72014e2..c6501aae7c8 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -39,19 +39,19 @@ msg += "[src.name]" - var/is_synth = isSynthetic() - if(is_synth) - var/use_gender = "a synthetic" - if(gender == MALE) - use_gender = "an android" - else if(gender == FEMALE) - use_gender = "a gynoid" - - msg += ", [use_gender]!" - - else if(species.name != "Human") - msg += ", \a [species.name]!" + if(!(skipjumpsuit && skipface)) + if(is_synth) + var/use_gender = "a synthetic" + if(gender == MALE) + use_gender = "an android" + else if(gender == FEMALE) + use_gender = "a gynoid" + + msg += ", [use_gender]!" + + else if(species.name != "Human") + msg += ", \a [species.name]!" msg += "
" //uniform @@ -64,60 +64,60 @@ tie_msg += ". Attached to it is [lowertext(english_list(U.accessories))]" if(w_uniform.blood_DNA) - msg += "[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!\n" + msg += "[T.He] [T.is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!\n" else msg += "[T.He] [T.is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n" //head if(head) if(head.blood_DNA) - msg += "[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != "#030303") ? "blood" : "oil"]-stained [head.name] on [T.his] head!\n" + msg += "[T.He] [T.is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [(head.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [head.name] on [T.his] head!\n" else msg += "[T.He] [T.is] wearing \icon[head] \a [head] on [T.his] head.\n" //suit/armour if(wear_suit) if(wear_suit.blood_DNA) - msg += "[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_suit.name]!\n" + msg += "[T.He] [T.is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [(wear_suit.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_suit.name]!\n" else msg += "[T.He] [T.is] wearing \icon[wear_suit] \a [wear_suit].\n" //suit/armour storage if(s_store && !skipsuitstorage) if(s_store.blood_DNA) - msg += "[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != "#030303") ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!\n" + msg += "[T.He] [T.is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [(s_store.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [s_store.name] on [T.his] [wear_suit.name]!\n" else msg += "[T.He] [T.is] carrying \icon[s_store] \a [s_store] on [T.his] [wear_suit.name].\n" //back if(back) if(back.blood_DNA) - msg += "[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != "#030303") ? "blood" : "oil"]-stained [back] on [T.his] back.\n" + msg += "[T.He] [T.has] \icon[back] [back.gender==PLURAL?"some":"a"] [(back.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [back] on [T.his] back.\n" else msg += "[T.He] [T.has] \icon[back] \a [back] on [T.his] back.\n" //left hand if(l_hand) if(l_hand.blood_DNA) - msg += "[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!\n" + msg += "[T.He] [T.is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [(l_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [l_hand.name] in [T.his] left hand!\n" else msg += "[T.He] [T.is] holding \icon[l_hand] \a [l_hand] in [T.his] left hand.\n" //right hand if(r_hand) if(r_hand.blood_DNA) - msg += "[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != "#030303") ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!\n" + msg += "[T.He] [T.is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [(r_hand.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [r_hand.name] in [T.his] right hand!\n" else msg += "[T.He] [T.is] holding \icon[r_hand] \a [r_hand] in [T.his] right hand.\n" //gloves if(gloves && !skipgloves) if(gloves.blood_DNA) - msg += "[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!\n" + msg += "[T.He] [T.has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [gloves.name] on [T.his] hands!\n" else msg += "[T.He] [T.has] \icon[gloves] \a [gloves] on [T.his] hands.\n" else if(blood_DNA) - msg += "[T.He] [T.has] [(hand_blood_color != "#030303") ? "blood" : "oil"]-stained hands!\n" + msg += "[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!\n" //handcuffed? @@ -135,30 +135,30 @@ //belt if(belt) if(belt.blood_DNA) - msg += "[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != "#030303") ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!\n" + msg += "[T.He] [T.has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [(belt.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [belt.name] about [T.his] waist!\n" else msg += "[T.He] [T.has] \icon[belt] \a [belt] about [T.his] waist.\n" //shoes if(shoes && !skipshoes) if(shoes.blood_DNA) - msg += "[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != "#030303") ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!\n" + msg += "[T.He] [T.is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [(shoes.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [shoes.name] on [T.his] feet!\n" else msg += "[T.He] [T.is] wearing \icon[shoes] \a [shoes] on [T.his] feet.\n" else if(feet_blood_DNA) - msg += "[T.He] [T.has] [(feet_blood_color != "#030303") ? "blood" : "oil"]-stained feet!\n" + msg += "[T.He] [T.has] [(feet_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained feet!\n" //mask if(wear_mask && !skipmask) if(wear_mask.blood_DNA) - msg += "[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != "#030303") ? "blood" : "oil"]-stained [wear_mask.name] on [T.his] face!\n" + msg += "[T.He] [T.has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [(wear_mask.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [wear_mask.name] on [T.his] face!\n" else msg += "[T.He] [T.has] \icon[wear_mask] \a [wear_mask] on [T.his] face.\n" //eyes if(glasses && !skipeyes) if(glasses.blood_DNA) - msg += "[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != "#030303") ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!\n" + msg += "[T.He] [T.has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [(glasses.blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained [glasses] covering [T.his] eyes!\n" else msg += "[T.He] [T.has] \icon[glasses] \a [glasses] covering [T.his] eyes.\n" @@ -194,7 +194,7 @@ msg += "[T.He] [T.is] twitching ever so slightly.\n" //splints - for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) + for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)) var/obj/item/organ/external/o = get_organ(organ) if(o && o.status & ORGAN_SPLINTED) msg += "[T.He] [T.has] a splint on [T.his] [o.name]!\n" @@ -295,79 +295,6 @@ if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED)) wound_flavor_text["[temp.name]"] += "[T.His] [temp.name] is dented and swollen!
" - //Handles the text strings being added to the actual description. - //If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext. - - // *********************************************************************************** - // THIS NEEDS TO BE ENTIRELY REWRITTEN. Commenting out for now, BADLY NEEDS REWRITING. - // *********************************************************************************** - - /* - var/display_chest = 0 - var/display_shoes = 0 - var/display_gloves = 0 - - if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas))))) - msg += wound_flavor_text["head"] - else if(is_bleeding["head"]) - msg += "[src] [T.has] blood running down [T.his] face!\n" - - if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you. - msg += wound_flavor_text["upper body"] - else if(is_bleeding["upper body"]) - display_chest = 1 - - if(wound_flavor_text["left arm"] && (is_destroyed["left arm"] || (!w_uniform && !skipjumpsuit))) - msg += wound_flavor_text["left arm"] - else if(is_bleeding["left arm"]) - display_chest = 1 - - if(wound_flavor_text["left hand"] && (is_destroyed["left hand"] || (!gloves && !skipgloves))) - msg += wound_flavor_text["left hand"] - else if(is_bleeding["left hand"]) - display_gloves = 1 - - if(wound_flavor_text["right arm"] && (is_destroyed["right arm"] || (!w_uniform && !skipjumpsuit))) - msg += wound_flavor_text["right arm"] - else if(is_bleeding["right arm"]) - display_chest = 1 - - if(wound_flavor_text["right hand"] && (is_destroyed["right hand"] || (!gloves && !skipgloves))) - msg += wound_flavor_text["right hand"] - else if(is_bleeding["right hand"]) - display_gloves = 1 - - if(wound_flavor_text["lower body"] && (is_destroyed["lower body"] || (!w_uniform && !skipjumpsuit))) - msg += wound_flavor_text["lower body"] - else if(is_bleeding["lower body"]) - display_chest = 1 - - if(wound_flavor_text["left leg"] && (is_destroyed["left leg"] || (!w_uniform && !skipjumpsuit))) - msg += wound_flavor_text["left leg"] - else if(is_bleeding["left leg"]) - display_chest = 1 - - if(wound_flavor_text["left foot"]&& (is_destroyed["left foot"] || (!shoes && !skipshoes))) - msg += wound_flavor_text["left foot"] - else if(is_bleeding["left foot"]) - display_shoes = 1 - if(wound_flavor_text["right leg"] && (is_destroyed["right leg"] || (!w_uniform && !skipjumpsuit))) - msg += wound_flavor_text["right leg"] - else if(is_bleeding["right leg"]) - display_chest = 1 - if(wound_flavor_text["right foot"]&& (is_destroyed["right foot"] || (!shoes && !skipshoes))) - msg += wound_flavor_text["right foot"] - else if(is_bleeding["right foot"]) - display_shoes = 1 - - if(display_chest) - msg += "[src] [T.has] blood soaking through from under [T.his] clothing!\n" - if(display_shoes) - msg += "[src] [T.has] blood running from [T.his] shoes!\n" - if(display_gloves) - msg += "[src] [T.has] blood running from under [T.his] gloves!\n" - */ - for(var/limb in wound_flavor_text) msg += wound_flavor_text[limb] is_bleeding[limb] = null diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 68662204a31..303e4a565e7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -71,7 +71,7 @@ stat("Tank Pressure", internal.air_contents.return_pressure()) stat("Distribution Pressure", internal.distribute_pressure) - var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] if(P) stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]") @@ -145,26 +145,12 @@ var/weapon_message = "Explosive Blast" for(var/obj/item/organ/external/temp in organs) - switch(temp.name) - if("head") + switch(temp.organ_tag) + if(BP_HEAD) update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message) - if("chest") + if(BP_TORSO) update |= temp.take_damage(b_loss * 0.4, f_loss * 0.4, used_weapon = weapon_message) - if("l_arm") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("r_arm") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("l_leg") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("r_leg") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("r_foot") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("l_foot") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("r_arm") - update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) - if("l_arm") + else update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) if(update) UpdateDamageIcon() @@ -174,7 +160,7 @@ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M) L.imp_in = M L.implanted = 1 - var/obj/item/organ/external/affected = M.organs_by_name["head"] + var/obj/item/organ/external/affected = M.organs_by_name[BP_HEAD] affected.implants += L L.part = affected L.implanted(src) @@ -318,7 +304,7 @@ //Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable /mob/living/carbon/human/proc/get_face_name() - var/obj/item/organ/external/head = get_organ("head") + var/obj/item/organ/external/head = get_organ(BP_HEAD) if(!head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible return "Unknown" return real_name @@ -655,7 +641,7 @@ ///Returns a number between -1 to 2 /mob/living/carbon/human/eyecheck() - var/obj/item/organ/I = internal_organs_by_name["eyes"] + var/obj/item/organ/I = internal_organs_by_name[O_EYES] if(!I || I.status & (ORGAN_CUT_AWAY|ORGAN_DESTROYED)) return 2 @@ -742,7 +728,7 @@ /mob/living/carbon/human/check_has_mouth() // Todo, check stomach organ when implemented. - var/obj/item/organ/external/head/H = get_organ("head") + var/obj/item/organ/external/head/H = get_organ(BP_HEAD) if(!H || !H.can_intake_reagents) return 0 return 1 @@ -908,7 +894,7 @@ /mob/living/carbon/human/revive() - if(should_have_organ("heart")) + if(should_have_organ(O_HEART)) vessel.add_reagent("blood",560-vessel.total_volume) fixblood() @@ -916,7 +902,7 @@ restore_all_organs() // Reapply robotics/amputated status from preferences. if(!client || !key) //Don't boot out anyone already in the mob. - for (var/obj/item/organ/brain/H in world) + for (var/obj/item/organ/internal/brain/H in world) if(H.brainmob) if(H.brainmob.real_name == src.real_name) if(H.brainmob.mind) @@ -935,11 +921,11 @@ ..() /mob/living/carbon/human/proc/is_lung_ruptured() - var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS] return L && L.is_bruised() /mob/living/carbon/human/proc/rupture_lung() - var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] + var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS] if(L && !L.is_bruised()) src.custom_pain("You feel a stabbing pain in your chest!", 1) @@ -1028,7 +1014,7 @@ for(var/obj/item/O in organ.implants) if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad. // All kinds of embedded objects cause bleeding. - if(!can_feel_pain(organ.limb_name)) + if(!can_feel_pain(organ.organ_tag)) src << "You feel [O] moving inside your [organ.name]." else var/msg = pick( \ @@ -1038,7 +1024,7 @@ src << msg organ.take_damage(rand(1,3), 0, 0) - if(!(organ.status & ORGAN_ROBOT) && !should_have_organ("heart")) //There is no blood in protheses. + if(!(organ.status & ORGAN_ROBOT) && !should_have_organ(O_HEART)) //There is no blood in protheses. organ.status |= ORGAN_BLEEDING src.adjustToxLoss(rand(1,3)) @@ -1140,6 +1126,8 @@ qdel(hud_used) hud_used = new /datum/hud(src) + full_prosthetic = null + if(species) return 1 else @@ -1205,7 +1193,7 @@ if(!target_zone) if(!user) - target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head") + target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) else target_zone = user.zone_sel.selecting @@ -1219,7 +1207,7 @@ fail_msg = "That limb is robotic." else switch(target_zone) - if("head") + if(BP_HEAD) if(head && head.item_flags & THICKMATERIAL) . = 0 else @@ -1227,7 +1215,7 @@ . = 0 if(!. && error_msg && user) if(!fail_msg) - fail_msg = "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into." + fail_msg = "There is no exposed flesh or thin material [target_zone == BP_HEAD ? "on their head" : "on their body"] to inject into." user << "[fail_msg]" /mob/living/carbon/human/print_flavor_text(var/shrink = 1) @@ -1285,15 +1273,15 @@ ..() /mob/living/carbon/human/has_brain() - if(internal_organs_by_name["brain"]) - var/obj/item/organ/brain = internal_organs_by_name["brain"] + if(internal_organs_by_name[O_BRAIN]) + var/obj/item/organ/brain = internal_organs_by_name[O_BRAIN] if(brain && istype(brain)) return 1 return 0 /mob/living/carbon/human/has_eyes() - if(internal_organs_by_name["eyes"]) - var/obj/item/organ/eyes = internal_organs_by_name["eyes"] + if(internal_organs_by_name[O_EYES]) + var/obj/item/organ/eyes = internal_organs_by_name[O_EYES] if(eyes && istype(eyes) && !(eyes.status & ORGAN_CUT_AWAY)) return 1 return 0 @@ -1402,10 +1390,10 @@ /mob/living/carbon/human/should_have_organ(var/organ_check) var/obj/item/organ/external/affecting - if(organ_check in list("heart","lungs")) - affecting = organs_by_name["chest"] - else if(organ_check in list("liver","kidneys")) - affecting = organs_by_name["groin"] + if(organ_check in list(O_HEART, O_LUNGS)) + affecting = organs_by_name[BP_TORSO] + else if(organ_check in list(O_LIVER, O_KIDNEYS)) + affecting = organs_by_name[BP_GROIN] if(affecting && (affecting.status & ORGAN_ROBOT)) return 0 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index a0af1f2fcff..ae262677c84 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -180,7 +180,7 @@ */ if(prob(80)) hit_zone = ran_zone(hit_zone) - if(prob(15) && hit_zone != "chest") // Missed! + if(prob(15) && hit_zone != BP_TORSO) // Missed! if(!src.lying) attack_message = "[H] attempted to strike [src], but missed!" else diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 517bc79a414..1c3f070b963 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -29,7 +29,7 @@ if(status_flags & GODMODE) return 0 //godmode if(should_have_organ("brain")) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.take_damage(amount) brainloss = sponge.damage @@ -43,7 +43,7 @@ if(status_flags & GODMODE) return 0 //godmode if(should_have_organ("brain")) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.damage = min(max(amount, 0),(maxHealth*2)) brainloss = sponge.damage @@ -57,7 +57,7 @@ if(status_flags & GODMODE) return 0 //godmode if(should_have_organ("brain")) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) brainloss = min(sponge.damage,maxHealth*2) else @@ -189,19 +189,19 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/getOxyLoss() - if(!should_have_organ("lungs")) + if(!should_have_organ(O_LUNGS)) oxyloss = 0 return ..() /mob/living/carbon/human/adjustOxyLoss(var/amount) - if(!should_have_organ("lungs")) + if(!should_have_organ(O_LUNGS)) oxyloss = 0 else amount = amount*species.oxy_mod ..(amount) /mob/living/carbon/human/setOxyLoss(var/amount) - if(!should_have_organ("lungs")) + if(!should_have_organ(O_LUNGS)) oxyloss = 0 else ..() @@ -321,7 +321,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t This function restores the subjects blood to max. */ /mob/living/carbon/human/proc/restore_blood() - if(should_have_organ("heart")) + if(should_have_organ(O_HEART)) var/blood_volume = vessel.get_reagent_amount("blood") vessel.add_reagent("blood",560.0-blood_volume) @@ -345,9 +345,10 @@ This function restores all organs. /mob/living/carbon/human/proc/get_organ(var/zone) - if(!zone) zone = "chest" - if (zone in list( "eyes", "mouth" )) - zone = "head" + if(!zone) + zone = BP_TORSO + else if (zone in list( O_EYES, O_MOUTH )) + zone = BP_HEAD return organs_by_name[zone] /mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b516852074d..2e69c9bdb64 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -44,11 +44,11 @@ emp_act agony_amount *= siemens_coeff switch (def_zone) - if("head") + if(BP_HEAD) agony_amount *= 1.50 - if("l_hand", "r_hand") + if(BP_L_HAND, BP_R_HAND) var/c_hand - if (def_zone == "l_hand") + if (def_zone == BP_L_HAND) c_hand = l_hand else c_hand = r_hand @@ -233,7 +233,7 @@ emp_act //Apply blood if(bloody) switch(hit_area) - if("head") + if(BP_HEAD) if(wear_mask) wear_mask.add_blood(src) update_inv_wear_mask(0) @@ -243,7 +243,7 @@ emp_act if(glasses && prob(33)) glasses.add_blood(src) update_inv_glasses(0) - if("chest") + if(BP_TORSO) bloody_body(src) if(Iforce > 10 || Iforce >= 5 && prob(33)) @@ -285,7 +285,7 @@ emp_act var/mob/living/L = O.thrower zone = check_zone(L.zone_sel.selecting) else - zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest + zone = ran_zone(BP_TORSO,75) //Hits a random part of the body, geared towards the chest //check if we hit var/miss_chance = 15 diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index f116ae17f03..78dbee05521 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -82,8 +82,9 @@ var/list/flavor_texts = list() var/gunshot_residue - var/pulling_punches // Are you trying not to hurt your opponent? - var/full_prosthetic // We are a robutt. + var/pulling_punches // Are you trying not to hurt your opponent? + var/full_prosthetic // We are a robutt. + var/robolimb_count = 0 // Number of robot limbs. mob_bump_flag = HUMAN mob_push_flags = ~HEAVY diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index c8011cb059b..ca052edb859 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -26,7 +26,7 @@ tally += wear_suit.slowdown if(istype(buckled, /obj/structure/bed/chair/wheelchair)) - for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm")) + for(var/organ_name in list(BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM)) var/obj/item/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) tally += 4 @@ -38,7 +38,7 @@ if(shoes) tally += shoes.slowdown - for(var/organ_name in list("l_foot","r_foot","l_leg","r_leg")) + for(var/organ_name in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) var/obj/item/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) tally += 4 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index cab9b5a1c2a..45a0a50364e 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -1,5 +1,5 @@ /mob/living/carbon/human/proc/update_eyes() - var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = internal_organs_by_name[O_EYES] if(eyes) eyes.update_colour() regenerate_icons() @@ -113,7 +113,7 @@ // You should not be able to pick anything up, but stranger things have happened. if(l_hand) - for(var/limb_tag in list("l_hand","l_arm")) + for(var/limb_tag in list(BP_L_HAND, BP_L_ARM)) var/obj/item/organ/external/E = get_organ(limb_tag) if(!E) visible_message("Lacking a functioning left hand, \the [src] drops \the [l_hand].") @@ -121,7 +121,7 @@ break if(r_hand) - for(var/limb_tag in list("r_hand","r_arm")) + for(var/limb_tag in list(BP_R_HAND, BP_R_ARM)) var/obj/item/organ/external/E = get_organ(limb_tag) if(!E) visible_message("Lacking a functioning right hand, \the [src] drops \the [r_hand].") diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index c3d0568b808..2f0160f35e6 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -45,44 +45,44 @@ This saves us from having to call add_fingerprint() any time something is put in /mob/living/carbon/human/proc/has_organ_for_slot(slot) switch(slot) if(slot_back) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_wear_mask) - return has_organ("head") + return has_organ(BP_HEAD) if(slot_handcuffed) - return has_organ("l_hand") && has_organ("r_hand") + return has_organ(BP_L_HAND) && has_organ(BP_R_HAND) if(slot_legcuffed) - return has_organ("l_leg") && has_organ("r_leg") + return has_organ(BP_L_FOOT) && has_organ(BP_R_FOOT) if(slot_l_hand) - return has_organ("l_hand") + return has_organ(BP_L_HAND) if(slot_r_hand) - return has_organ("r_hand") + return has_organ(BP_R_HAND) if(slot_belt) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_wear_id) // the only relevant check for this is the uniform check return 1 if(slot_l_ear) - return has_organ("head") + return has_organ(BP_HEAD) if(slot_r_ear) - return has_organ("head") + return has_organ(BP_HEAD) if(slot_glasses) - return has_organ("head") + return has_organ(BP_HEAD) if(slot_gloves) - return has_organ("l_hand") || has_organ("r_hand") + return has_organ(BP_L_HAND) || has_organ(BP_R_HAND) if(slot_head) - return has_organ("head") + return has_organ(BP_HEAD) if(slot_shoes) - return has_organ("r_foot") || has_organ("l_foot") + return has_organ(BP_L_FOOT) || has_organ(BP_R_FOOT) if(slot_wear_suit) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_w_uniform) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_l_store) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_r_store) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_s_store) - return has_organ("chest") + return has_organ(BP_TORSO) if(slot_in_backpack) return 1 if(slot_tie) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8e77023fe7a..971e8c4a6fa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -255,12 +255,7 @@ if (radiation) - // TODO. - if(isSynthetic()) - radiation = 0 - return - - var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs + var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs if(rad_organ && !rad_organ.is_broken()) var/rads = radiation/25 radiation -= rads @@ -280,34 +275,36 @@ if (radiation > 50) damage = 1 radiation -= 1 * RADIATION_SPEED_COEFFICIENT - if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT)) - radiation -= 5 * RADIATION_SPEED_COEFFICIENT - src << "You feel weak." - Weaken(3) - if(!lying) - emote("collapse") - if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == "Human") //apes go bald - if((h_style != "Bald" || f_style != "Shaved" )) - src << "Your hair falls out." - h_style = "Bald" - f_style = "Shaved" - update_hair() + if(!isSynthetic()) + if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT)) + radiation -= 5 * RADIATION_SPEED_COEFFICIENT + src << "You feel weak." + Weaken(3) + if(!lying) + emote("collapse") + if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == "Human") //apes go bald + if((h_style != "Bald" || f_style != "Shaved" )) + src << "Your hair falls out." + h_style = "Bald" + f_style = "Shaved" + update_hair() if (radiation > 75) - radiation -= 1 * RADIATION_SPEED_COEFFICIENT damage = 3 - if(prob(5)) - take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") - if(prob(1)) - src << "You feel strange!" - adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT) - emote("gasp") + radiation -= 1 * RADIATION_SPEED_COEFFICIENT + if(!isSynthetic()) + if(prob(5)) + take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") + if(prob(1)) + src << "You feel strange!" + adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT) + emote("gasp") if(damage) - damage *= species.radiation_mod + damage *= isSynthetic() ? 0.5 : species.radiation_mod adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT) updatehealth() - if(organs.len) + if(!isSynthetic() && organs.len) var/obj/item/organ/external/O = pick(organs) if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) @@ -371,8 +368,8 @@ var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa // Lung damage increases the minimum safe pressure. - if(should_have_organ("lungs")) - var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"] + if(should_have_organ(O_LUNGS)) + var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS] if(isnull(L)) safe_pressure_min = INFINITY //No lungs, how are you breathing? else if(L.is_broken()) @@ -525,24 +522,24 @@ if(breath.temperature >= species.heat_level_1) if(breath.temperature < species.heat_level_2) - apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Heat") + apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Heat") fire_alert = max(fire_alert, 2) else if(breath.temperature < species.heat_level_3) - apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat") + apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, BP_HEAD, used_weapon = "Excessive Heat") fire_alert = max(fire_alert, 2) else - apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") + apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, BP_HEAD, used_weapon = "Excessive Heat") fire_alert = max(fire_alert, 2) else if(breath.temperature <= species.cold_level_1) if(breath.temperature > species.cold_level_2) - apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold") + apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Cold") fire_alert = max(fire_alert, 1) else if(breath.temperature > species.cold_level_3) - apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold") + apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, BP_HEAD, used_weapon = "Excessive Cold") fire_alert = max(fire_alert, 1) else - apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold") + apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, BP_HEAD, used_weapon = "Excessive Cold") fire_alert = max(fire_alert, 1) @@ -691,13 +688,19 @@ */ /mob/living/carbon/human/proc/stabilize_body_temperature() - if (species.passive_temp_gain) // We produce heat naturally. + // We produce heat naturally. + if (species.passive_temp_gain) bodytemperature += species.passive_temp_gain + // Robolimbs cause overheating too. + if(robolimb_count) + bodytemperature += round(robolimb_count/2) + var/body_temperature_difference = species.body_temperature - bodytemperature if (abs(body_temperature_difference) < 0.5) return //fuck this precision + if (on_fire) return //too busy for pesky convection @@ -862,7 +865,7 @@ if(status_flags & GODMODE) return 0 //godmode - var/obj/item/organ/diona/node/light_organ = locate() in internal_organs + var/obj/item/organ/internal/diona/node/light_organ = locate() in internal_organs if(!isSynthetic()) if(light_organ && !light_organ.is_broken()) @@ -1548,7 +1551,7 @@ /mob/living/carbon/human/proc/handle_pulse() if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) - if(!internal_organs_by_name["heart"]) + if(!internal_organs_by_name[O_HEART]) return PULSE_NONE //No blood, no pulse. if(stat == DEAD) @@ -1582,7 +1585,7 @@ if(pulse == PULSE_NONE) return - var/obj/item/organ/heart/H = internal_organs_by_name["heart"] + var/obj/item/organ/internal/heart/H = internal_organs_by_name[O_HEART] if(!H || (H.status & ORGAN_ROBOT)) return diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index c1c335a22d7..94da4151016 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -45,28 +45,28 @@ ) has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest), - "groin" = list("path" = /obj/item/organ/external/groin), - "head" = list("path" = /obj/item/organ/external/head/vox), - "l_arm" = list("path" = /obj/item/organ/external/arm), - "r_arm" = list("path" = /obj/item/organ/external/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/leg), - "r_leg" = list("path" = /obj/item/organ/external/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/hand), - "r_hand" = list("path" = /obj/item/organ/external/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/vox), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) has_organ = list( - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/brain, - "eyes" = /obj/item/organ/eyes, - "stack" = /obj/item/organ/stack/vox + O_HEART = /obj/item/organ/internal/heart, + O_LUNGS = /obj/item/organ/internal/lungs, + O_LIVER = /obj/item/organ/internal/liver, + O_KIDNEYS = /obj/item/organ/internal/kidneys, + O_BRAIN = /obj/item/organ/internal/brain, + O_EYES = /obj/item/organ/internal/eyes, + "stack" = /obj/item/organ/internal/stack/vox ) /datum/species/vox/get_random_name(var/gender) @@ -108,12 +108,12 @@ // Pariahs have no stack. has_organ = list( - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/pariah_brain, - "eyes" = /obj/item/organ/eyes + O_HEART = /obj/item/organ/internal/heart, + O_LUNGS = /obj/item/organ/internal/lungs, + O_LIVER = /obj/item/organ/internal/liver, + O_KIDNEYS = /obj/item/organ/internal/kidneys, + O_BRAIN = /obj/item/organ/internal/pariah_brain, + O_EYES = /obj/item/organ/internal/eyes ) flags = IS_RESTRICTED | NO_SCAN | HAS_EYE_COLOR diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index c0722fbca9d..e19795b6413 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -58,8 +58,6 @@ // Death vars. var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human - var/gibber_type = /obj/effect/gibspawner/human - var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs var/remains_type = /obj/effect/decal/remains/xeno var/gibbed_anim = "gibbed-h" var/dusted_anim = "dust-h" @@ -120,28 +118,28 @@ var/rarity_value = 1 // Relative rarity/collector value for this species. // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/brain, - "appendix" = /obj/item/organ/appendix, - "eyes" = /obj/item/organ/eyes + O_HEART = /obj/item/organ/internal/heart, + O_LUNGS = /obj/item/organ/internal/lungs, + O_LIVER = /obj/item/organ/internal/liver, + O_KIDNEYS = /obj/item/organ/internal/kidneys, + O_BRAIN = /obj/item/organ/internal/brain, + O_APPENDIX = /obj/item/organ/internal/appendix, + O_EYES = /obj/item/organ/internal/eyes ) var/vision_organ // If set, this organ is required for vision. Defaults to "eyes" if the species has them. var/list/has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest), - "groin" = list("path" = /obj/item/organ/external/groin), - "head" = list("path" = /obj/item/organ/external/head), - "l_arm" = list("path" = /obj/item/organ/external/arm), - "r_arm" = list("path" = /obj/item/organ/external/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/leg), - "r_leg" = list("path" = /obj/item/organ/external/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/hand), - "r_hand" = list("path" = /obj/item/organ/external/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) // Bump vars @@ -158,8 +156,8 @@ hud = new() //If the species has eyes, they are the default vision organ - if(!vision_organ && has_organ["eyes"]) - vision_organ = "eyes" + if(!vision_organ && has_organ[O_EYES]) + vision_organ = O_EYES unarmed_attacks = list() for(var/u_type in unarmed_types) @@ -186,13 +184,13 @@ return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd) /datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H) - return ((H && H.isSynthetic()) ? "#1F181F" : blood_color) + return ((H && H.isSynthetic()) ? SYNTH_BLOOD_COLOUR : blood_color) /datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H) return ((H && H.isSynthetic()) ? 1 : virus_immune) /datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H) - return ((H && H.isSynthetic()) ? "#575757" : flesh_color) + return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color) /datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type) @@ -269,7 +267,10 @@ for(var/name in H.organs_by_name) H.organs |= H.organs_by_name[name] - for(var/obj/item/organ/external/O in H.organs) + for(var/name in H.internal_organs_by_name) + H.internal_organs |= H.internal_organs_by_name[name] + + for(var/obj/item/organ/O in (H.organs|H.internal_organs)) O.owner = H /datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target) diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm index 365109d7cf0..cd4ca21e001 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -33,7 +33,7 @@ return 0 switch(zone) - if("head", "mouth", "eyes") + if(BP_HEAD, O_MOUTH, O_EYES) // ----- HEAD ----- // switch(attack_damage) if(1 to 2) diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index 7faf868ac29..23970c61b27 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -18,7 +18,7 @@ flesh_color = "#137E8F" has_organ = list( - "brain" = /obj/item/organ/brain/golem + "brain" = /obj/item/organ/internal/brain/golem ) death_message = "becomes completely motionless..." diff --git a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm index b33d4e8ef71..89b1fc1bd7d 100644 --- a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm @@ -38,12 +38,12 @@ toxins_mod = 1.1 has_organ = list( - "heart" = /obj/item/organ/heart, - "lungs" = /obj/item/organ/lungs, - "liver" = /obj/item/organ/liver, - "kidneys" = /obj/item/organ/kidneys, - "brain" = /obj/item/organ/brain, - "eyes" = /obj/item/organ/eyes + O_HEART = /obj/item/organ/heart, + O_LUNGS = /obj/item/organ/lungs, + O_LIVER = /obj/item/organ/liver, + O_KIDNEYS = /obj/item/organ/kidneys, + O_BRAIN = /obj/item/organ/brain, + O_EYES = /obj/item/organ/eyes ) /* diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index 77a5f942f0a..85890f4de6d 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -39,17 +39,17 @@ pass_flags = PASSTABLE has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest), - "groin" = list("path" = /obj/item/organ/external/groin), - "head" = list("path" = /obj/item/organ/external/head/no_eyes), - "l_arm" = list("path" = /obj/item/organ/external/arm), - "r_arm" = list("path" = /obj/item/organ/external/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/leg), - "r_leg" = list("path" = /obj/item/organ/external/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/hand), - "r_hand" = list("path" = /obj/item/organ/external/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm index 96a926b14ea..f2277f99211 100644 --- a/code/modules/mob/living/carbon/human/species/station/slime.dm +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -20,7 +20,7 @@ death_message = "rapidly loses cohesion, splattering across the ground..." has_organ = list( - "brain" = /obj/item/organ/brain/slime + "brain" = /obj/item/organ/internal/brain/slime ) breath_type = null @@ -31,17 +31,17 @@ push_flags = MONKEY|SLIME|SIMPLE_ANIMAL has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest/unbreakable), - "groin" = list("path" = /obj/item/organ/external/groin/unbreakable), - "head" = list("path" = /obj/item/organ/external/head/unbreakable), - "l_arm" = list("path" = /obj/item/organ/external/arm/unbreakable), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/unbreakable), - "l_leg" = list("path" = /obj/item/organ/external/leg/unbreakable), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/unbreakable), - "l_hand" = list("path" = /obj/item/organ/external/hand/unbreakable), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/unbreakable), - "l_foot" = list("path" = /obj/item/organ/external/foot/unbreakable), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/unbreakable) + BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable), + BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable), + BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable), + BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable), + BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable), + BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable) ) /datum/species/slime/handle_death(var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index 5fecc7c79bf..a0365f7cd04 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -152,17 +152,17 @@ reagent_tag = IS_SKRELL has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest), - "groin" = list("path" = /obj/item/organ/external/groin), - "head" = list("path" = /obj/item/organ/external/head/skrell), - "l_arm" = list("path" = /obj/item/organ/external/arm), - "r_arm" = list("path" = /obj/item/organ/external/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/leg), - "r_leg" = list("path" = /obj/item/organ/external/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/hand), - "r_hand" = list("path" = /obj/item/organ/external/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/skrell), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) /datum/species/diona @@ -190,26 +190,26 @@ water and other radiation." has_organ = list( - "nutrient channel" = /obj/item/organ/diona/nutrients, - "neural strata" = /obj/item/organ/diona/strata, - "response node" = /obj/item/organ/diona/node, - "gas bladder" = /obj/item/organ/diona/bladder, - "polyp segment" = /obj/item/organ/diona/polyp, - "anchoring ligament" = /obj/item/organ/diona/ligament + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients, + O_STRATA = /obj/item/organ/internal/diona/strata, + O_RESPONSE = /obj/item/organ/internal/diona/node, + O_GBLADDER = /obj/item/organ/internal/diona/bladder, + O_POLYP = /obj/item/organ/internal/diona/polyp, + O_ANCHOR = /obj/item/organ/internal/diona/ligament ) has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/diona/chest), - "groin" = list("path" = /obj/item/organ/external/diona/groin), - "head" = list("path" = /obj/item/organ/external/head/no_eyes/diona), - "l_arm" = list("path" = /obj/item/organ/external/diona/arm), - "r_arm" = list("path" = /obj/item/organ/external/diona/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/diona/leg), - "r_leg" = list("path" = /obj/item/organ/external/diona/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/diona/hand), - "r_hand" = list("path" = /obj/item/organ/external/diona/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/diona/foot), - "r_foot" = list("path" = /obj/item/organ/external/diona/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/diona/chest), + BP_GROIN = list("path" = /obj/item/organ/external/diona/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes/diona), + BP_L_ARM = list("path" = /obj/item/organ/external/diona/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/diona/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/diona/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/diona/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/diona/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/diona/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/diona/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/diona/foot/right) ) inherent_verbs = list( @@ -260,9 +260,13 @@ if(H.mind) H.mind.transfer_to(S) + if(H.isSynthetic()) + H.visible_message("\The [H] collapses into parts, revealing a solitary diona nymph at the core.") + return + for(var/mob/living/carbon/alien/diona/D in H.contents) if(D.client) - D.loc = H.loc + D.forceMove(get_turf(H)) else qdel(D) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm index c60d8bca1d7..de601b25924 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm @@ -108,7 +108,7 @@ Des: Removes all infection images from aliens and places an infection image on a for(var/mob/living/carbon/alien in player_list) - if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) continue if(alien.client) @@ -130,7 +130,7 @@ Des: Checks if the passed mob (C) is infected with the alien egg, then gives eac for(var/mob/living/carbon/alien in player_list) - if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) continue if(alien.client) @@ -149,7 +149,7 @@ Des: Removes the alien infection image from all aliens in the world located in p for(var/mob/living/carbon/alien in player_list) - if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs) + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) continue if(alien.client) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm index 335b5660924..af8b93e6206 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm @@ -110,7 +110,7 @@ var/const/MAX_ACTIVE_TIME = 400 return var/mob/living/carbon/C = M - if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs) + if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs) return @@ -221,7 +221,7 @@ var/const/MAX_ACTIVE_TIME = 400 return 0 var/mob/living/carbon/C = M - if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs) + if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs) return 0 if(ishuman(C)) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index a73e3639046..c046c0d8574 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -11,7 +11,7 @@ /mob/living/carbon/human/proc/gain_plasma(var/amount) - var/obj/item/organ/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/internal/xenos/plasmavessel/I = internal_organs_by_name[O_PLASMA] if(!istype(I)) return if(amount) @@ -20,13 +20,13 @@ /mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ) - var/obj/item/organ/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"] + var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] if(!istype(P)) src << "Your plasma vessel has been removed!" return if(needs_organ) - var/obj/item/organ/I = internal_organs_by_name[needs_organ] + var/obj/item/organ/internal/I = internal_organs_by_name[needs_organ] if(!I) src << "Your [needs_organ] has been removed!" return @@ -62,7 +62,7 @@ src << "You need to be closer." return - var/obj/item/organ/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"] + var/obj/item/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name[O_PLASMA] if(!istype(I)) src << "Their plasma vessel is missing." return @@ -70,7 +70,7 @@ var/amount = input("Amount:", "Transfer Plasma to [M]") as num if (amount) amount = abs(round(amount)) - if(check_alien_ability(amount,0,"plasma vessel")) + if(check_alien_ability(amount,0,O_PLASMA)) M.gain_plasma(amount) M << "[src] has transfered [amount] plasma to you." src << "You have transferred [amount] plasma to [M]." @@ -92,7 +92,7 @@ src << "There's already an egg here." return - if(check_alien_ability(75,1,"egg sac")) + if(check_alien_ability(75,1,O_EGG)) visible_message("[src] has laid an egg!") new /obj/effect/alien/egg(loc) @@ -119,7 +119,7 @@ set desc = "Plants some alien weeds" set category = "Abilities" - if(check_alien_ability(50,1,"resin spinner")) + if(check_alien_ability(50,1,O_RESIN)) visible_message("[src] has planted some alien weeds!") new /obj/effect/alien/weeds/node(loc) return @@ -153,7 +153,7 @@ src << "You cannot dissolve this object." return - if(check_alien_ability(200,0,"acid gland")) + if(check_alien_ability(200,0,O_ACID)) new /obj/effect/alien/acid(get_turf(O), O) visible_message("[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!") @@ -164,7 +164,7 @@ set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear." set category = "Abilities" - if(!check_alien_ability(50,0,"acid gland")) + if(!check_alien_ability(50,0,O_ACID)) return if(stat || paralysis || stunned || weakened || lying || restrained() || buckled) @@ -206,7 +206,7 @@ if(!choice) return - if(!check_alien_ability(75,1,"resin spinner")) + if(!check_alien_ability(75,1,O_RESIN)) return visible_message("[src] vomits up a thick purple substance and begins to shape it!", "You shape a [choice].") diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index 5f6ab38fad5..4425d23b7bc 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -44,11 +44,11 @@ vision_flags = SEE_SELF|SEE_MOBS has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain/xeno, - "plasma vessel" = /obj/item/organ/xenos/plasmavessel, - "hive node" = /obj/item/organ/xenos/hivenode, - "nutrient vessel" = /obj/item/organ/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients ) bump_flag = ALIEN @@ -61,17 +61,17 @@ var/weeds_plasma_rate = 5 // Plasma regen on weeds. has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest), - "groin" = list("path" = /obj/item/organ/external/groin), - "head" = list("path" = /obj/item/organ/external/head/no_eyes), - "l_arm" = list("path" = /obj/item/organ/external/arm), - "r_arm" = list("path" = /obj/item/organ/external/arm/right), - "l_leg" = list("path" = /obj/item/organ/external/leg), - "r_leg" = list("path" = /obj/item/organ/external/leg/right), - "l_hand" = list("path" = /obj/item/organ/external/hand), - "r_hand" = list("path" = /obj/item/organ/external/hand/right), - "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) /datum/species/xenos/get_bodytype() @@ -112,7 +112,7 @@ if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T) if(!regenerate(H)) - var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"] + var/obj/item/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name[O_PLASMA] P.stored_plasma += weeds_plasma_rate P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma) ..() @@ -172,13 +172,13 @@ deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi' has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain/xeno, - "plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen, - "acid gland" = /obj/item/organ/xenos/acidgland, - "hive node" = /obj/item/organ/xenos/hivenode, - "resin spinner" = /obj/item/organ/xenos/resinspinner, - "nutrient vessel" = /obj/item/organ/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_RESIN = /obj/item/organ/internal/xenos/resinspinner, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients ) inherent_verbs = list( @@ -211,11 +211,11 @@ deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi' has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain/xeno, - "plasma vessel" = /obj/item/organ/xenos/plasmavessel/hunter, - "hive node" = /obj/item/organ/xenos/hivenode, - "nutrient vessel" = /obj/item/organ/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/hunter, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients ) inherent_verbs = list( @@ -239,12 +239,12 @@ deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi' has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain/xeno, - "plasma vessel" = /obj/item/organ/xenos/plasmavessel/sentinel, - "acid gland" = /obj/item/organ/xenos/acidgland, - "hive node" = /obj/item/organ/xenos/hivenode, - "nutrient vessel" = /obj/item/organ/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/sentinel, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients ) inherent_verbs = list( @@ -271,14 +271,14 @@ deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi' has_organ = list( - "heart" = /obj/item/organ/heart, - "brain" = /obj/item/organ/brain/xeno, - "egg sac" = /obj/item/organ/xenos/eggsac, - "plasma vessel" = /obj/item/organ/xenos/plasmavessel/queen, - "acid gland" = /obj/item/organ/xenos/acidgland, - "hive node" = /obj/item/organ/xenos/hivenode, - "resin spinner" = /obj/item/organ/xenos/resinspinner, - "nutrient vessel" = /obj/item/organ/diona/nutrients + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_EGG = /obj/item/organ/internal/xenos/eggsac, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_RESIN = /obj/item/organ/internal/xenos/resinspinner, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients ) inherent_verbs = list( diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm index a6b566b0c9d..3ebef9e127d 100644 --- a/code/modules/mob/living/carbon/human/stripping.dm +++ b/code/modules/mob/living/carbon/human/stripping.dm @@ -121,7 +121,7 @@ if(can_reach_splints) var/removed_splint - for(var/organ in list("l_leg","r_leg","l_arm","r_arm")) + for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)) var/obj/item/organ/external/o = get_organ(organ) if (o && o.status & ORGAN_SPLINTED) var/obj/item/W = new /obj/item/stack/medical/splint(get_turf(src), 1) diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index f6ecb54ce5b..b5a78b642cf 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -47,22 +47,22 @@ var/global/list/sparring_attack_cache = list() if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance switch(zone) // strong punches can have effects depending on where they hit - if("head", "mouth", "eyes") + if(BP_HEAD, O_EYES, O_MOUTH) // Induce blurriness target.visible_message("[target] looks momentarily disoriented.", "You see stars.") target.apply_effect(attack_damage*2, EYE_BLUR, armour) - if("l_arm", "l_hand") + if(BP_L_ARM, BP_L_HAND) if (target.l_hand) // Disarm left hand //Urist McAssistant dropped the macguffin with a scream just sounds odd. target.visible_message("\The [target.l_hand] was knocked right out of [target]'s grasp!") target.drop_l_hand() - if("r_arm", "r_hand") + if(BP_R_ARM, BP_R_HAND) if (target.r_hand) // Disarm right hand target.visible_message("\The [target.r_hand] was knocked right out of [target]'s grasp!") target.drop_r_hand() - if("chest") + if(BP_TORSO) if(!target.lying) var/turf/T = get_step(get_turf(target), get_dir(get_turf(user), get_turf(target))) if(!T.density) @@ -73,7 +73,7 @@ var/global/list/sparring_attack_cache = list() if(prob(50)) target.set_dir(reverse_dir[target.dir]) target.apply_effect(attack_damage * 0.4, WEAKEN, armour) - if("groin") + if(BP_GROIN) target.visible_message("[target] looks like \he is in pain!", "[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]") target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour) if("l_leg", "l_foot", "r_leg", "r_foot") @@ -93,7 +93,7 @@ var/global/list/sparring_attack_cache = list() playsound(user.loc, attack_sound, 25, 1, -1) /datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target) - var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = target.internal_organs_by_name[O_EYES] if(eyes) eyes.take_damage(rand(3,4), 1) user.visible_message("[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!") @@ -114,7 +114,7 @@ var/global/list/sparring_attack_cache = list() if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) return 0 - if (user == target && (zone == "head" || zone == "eyes" || zone == "mouth")) + if (user == target && (zone == BP_HEAD || zone == O_EYES || zone == O_MOUTH)) return 0 return 1 @@ -137,7 +137,7 @@ var/global/list/sparring_attack_cache = list() if(!target.lying) switch(zone) - if("head", "mouth", "eyes") + if(BP_HEAD, O_MOUTH, O_EYES) // ----- HEAD ----- // switch(attack_damage) if(1 to 2) @@ -177,7 +177,7 @@ var/global/list/sparring_attack_cache = list() if (user.legcuffed) return 0 - if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin"))) + if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", BP_GROIN))) return 0 var/obj/item/organ/external/E = user.organs_by_name["l_foot"] diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index cc112b18d93..8d7b0aeeaed 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -208,12 +208,13 @@ var/global/list/damage_icon_parts = list() if(!(O.status & ORGAN_DESTROYED)) O.update_icon() if(O.damage_state == "00") continue + var/use_colour = ((O.status & ORGAN_ROBOT) ? SYNTH_BLOOD_COLOUR : O.species.get_blood_colour(src)) var/icon/DI - var/cache_index = "[O.damage_state]/[O.icon_name]/[O.species.get_blood_colour()]/[species.get_bodytype()]" + var/cache_index = "[O.damage_state]/[O.icon_name]/[use_colour]/[species.get_bodytype()]" if(damage_icon_parts[cache_index] == null) DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels - DI.Blend(O.species.get_blood_colour(), ICON_MULTIPLY) + DI.Blend(use_colour, ICON_MULTIPLY) damage_icon_parts[cache_index] = DI else DI = damage_icon_parts[cache_index] @@ -252,7 +253,7 @@ var/global/list/damage_icon_parts = list() icon_key += "[lip_style]" else icon_key += "nolips" - var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = internal_organs_by_name[O_EYES] if(eyes) icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" else @@ -286,7 +287,7 @@ var/global/list/damage_icon_parts = list() base_icon = human_icon_cache[icon_key] else //BEGIN CACHED ICON GENERATION. - var/obj/item/organ/external/chest = get_organ("chest") + var/obj/item/organ/external/chest = get_organ(BP_TORSO) base_icon = chest.get_icon() for(var/obj/item/organ/external/part in organs) @@ -351,7 +352,7 @@ var/global/list/damage_icon_parts = list() //Reset our hair overlays_standing[HAIR_LAYER] = null - var/obj/item/organ/external/head/head_organ = get_organ("head") + var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD) if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) ) if(update_icons) update_icons() return @@ -763,9 +764,10 @@ var/global/list/damage_icon_parts = list() if(wear_suit.blood_DNA) var/obj/item/clothing/suit/S = wear_suit - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") - bloodsies.color = wear_suit.blood_color - standing.overlays += bloodsies + if(istype(S)) //You can put non-suits in your suit slot (diona nymphs etc). + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") + bloodsies.color = wear_suit.blood_color + standing.overlays += bloodsies overlays_standing[SUIT_LAYER] = standing update_tail_showing(0) diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 7e487269aa2..352b7d955a9 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -33,15 +33,9 @@ else loc_temp = environment.temperature - if(loc_temp < 310.15) // a cold place - bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) - else // a hot place - bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) - - //Account for massive pressure differences + bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1) if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc - if(bodytemperature <= (T0C - 50)) // hurt temperature if(bodytemperature <= 50) // sqrting negative numbers is bad adjustToxLoss(200) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f575c6303d1..b6cf19b8496 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -344,8 +344,8 @@ default behaviour is: /mob/living/proc/get_organ_target() var/mob/shooter = src var/t = shooter:zone_sel.selecting - if ((t in list( "eyes", "mouth" ))) - t = "head" + if ((t in list( O_EYES, O_MOUTH ))) + t = BP_HEAD var/obj/item/organ/external/def_zone = ran_zone(t) return def_zone diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4c108c69aae..e2535da5ea8 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -404,7 +404,7 @@ var/total_damage = 0 for(var/i in 1 to 3) var/damage = min(W.force*1.5, 20)*damage_mod - apply_damage(damage, W.damtype, "head", 0, sharp=W.sharp, edge=W.edge) + apply_damage(damage, W.damtype, BP_HEAD, 0, sharp=W.sharp, edge=W.edge) total_damage += damage var/oxyloss = total_damage diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index 536d5bcc768..1f4024459e0 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -65,10 +65,12 @@ user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) if("prosthetics") + var/mob/living/carbon/human/H = M user << "Analyzing Results for \the [H]:" + if(H.isSynthetic()) + user << "System instability: [H.getToxLoss()]" user << "Key: Electronics/Brute" - user << "External prosthetics:" var/organ_found if(H.internal_organs.len) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index bb106f8bcd7..88f989f15ef 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -64,7 +64,7 @@ /obj/item/robot_parts, /obj/item/borg/upgrade, /obj/item/device/flash, //to build borgs - /obj/item/organ/brain, //to insert into MMIs. + /obj/item/organ/internal/brain, //to insert into MMIs. /obj/item/stack/cable_coil, //again, for borg building /obj/item/weapon/circuitboard, /obj/item/slime_extract, diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm index d8606524e21..d4b5977a6e6 100644 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ b/code/modules/mob/living/simple_animal/borer/borer.dm @@ -106,7 +106,7 @@ if(istype(host,/mob/living/carbon/human)) var/mob/living/carbon/human/H = host - var/obj/item/organ/external/head = H.get_organ("head") + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) head.implants -= src controlling = 0 diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index 05bf7e8eefb..12c4099623e 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -73,7 +73,7 @@ if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/E = H.organs_by_name["head"] + var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD] if(!E || (E.status & ORGAN_DESTROYED)) src << "\The [H] does not have a head!" @@ -118,7 +118,7 @@ replace_brain() else // If they're in normally, implant removal can get them out. - var/obj/item/organ/external/head = H.get_organ("head") + var/obj/item/organ/external/head = H.get_organ(BP_HEAD) head.implants += src return @@ -181,11 +181,11 @@ H.ChangeToHusk() - var/obj/item/organ/borer/B = new(H) + var/obj/item/organ/internal/borer/B = new(H) H.internal_organs_by_name["brain"] = B H.internal_organs |= B - var/obj/item/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) affecting.implants -= src var/s2h_id = src.computer_id diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 73de95acee7..91f8aa958c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -133,7 +133,7 @@ if(ishuman(target_mob)) var/mob/living/carbon/human/H = target_mob - var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") + var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG) var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1) return H diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 658f0f6d4e8..5340ee39fb3 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -53,7 +53,7 @@ var/parrot_state = PARROT_WANDER //Hunt for a perch when created var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick. var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down - var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack + var/parrot_dam_zone = list(BP_TORSO, BP_HEAD, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) //For humans, select a bodypart to attack var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower. var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0f41b859e59..ff45cb71d02 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1128,3 +1128,6 @@ mob/proc/yank_out_object() src.in_throw_mode = 1 if(src.throw_icon) src.throw_icon.icon_state = "act_throw_on" + +/mob/proc/isSynthetic() + return 0 diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index a9d5456a93c..c85b8d96a23 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -124,7 +124,7 @@ if(iscarbon(affecting)) handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting) - + if(force_down) if(affecting.loc != assailant.loc) force_down = 0 @@ -148,14 +148,14 @@ /obj/item/weapon/grab/proc/handle_eye_mouth_covering(mob/living/carbon/target, mob/user, var/target_zone) var/announce = (target_zone != last_hit_zone) //only display messages when switching between different target zones last_hit_zone = target_zone - + switch(target_zone) - if("mouth") + if(O_MOUTH) if(announce) user.visible_message("\The [user] covers [target]'s mouth!") if(target.silent < 3) target.silent = 3 - if("eyes") + if(O_EYES) if(announce) assailant.visible_message("[assailant] covers [affecting]'s eyes!") if(affecting.eye_blind < 3) @@ -232,7 +232,7 @@ else assailant.visible_message("[assailant] pins [affecting] down to the ground (now hands)!") apply_pinning(affecting, assailant) - + state = GRAB_AGGRESSIVE icon_state = "grabbed1" hud.icon_state = "reinforce1" @@ -252,7 +252,7 @@ hud.name = "kill" affecting.Stun(10) //10 ticks of ensured grab else if(state < GRAB_UPGRADING) - assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") + assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") hud.icon_state = "kill1" state = GRAB_KILL @@ -264,7 +264,7 @@ affecting.setClickCooldown(10) affecting.losebreath += 1 affecting.set_dir(WEST) - adjust_position() + adjust_position() //This is used to make sure the victim hasn't managed to yackety sax away before using the grab. /obj/item/weapon/grab/proc/confirm() @@ -284,10 +284,10 @@ return if(world.time < (last_action + 20)) return - + last_action = world.time reset_kill_state() //using special grab moves will interrupt choking them - + //clicking on the victim while grabbing them if(M == affecting) if(ishuman(affecting)) @@ -300,21 +300,21 @@ force_down = 0 return inspect_organ(affecting, assailant, hit_zone) - + if(I_GRAB) jointlock(affecting, assailant, hit_zone) - + if(I_HURT) - if(hit_zone == "eyes") + if(hit_zone == O_EYES) attack_eye(affecting, assailant) - else if(hit_zone == "head") + else if(hit_zone == BP_HEAD) headbut(affecting, assailant) else dislocate(affecting, assailant, hit_zone) - + if(I_DISARM) pin_down(affecting, assailant) - + //clicking on yourself while grabbing them if(M == assailant && state >= GRAB_AGGRESSIVE) devour(affecting, assailant) @@ -325,7 +325,7 @@ qdel(src) /obj/item/weapon/grab/proc/reset_kill_state() - if(state == GRAB_KILL) + if(state == GRAB_KILL) assailant.visible_message("[assailant] lost \his tight grip on [affecting]'s neck!") hud.icon_state = "kill" state = GRAB_NECK diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index fb51bc15722..76de1cdc33a 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -60,7 +60,7 @@ if(!istype(attacker)) return - var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, "eyes") + var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, O_EYES) if(!attack) return @@ -93,11 +93,11 @@ if(istype(hat)) damage += hat.force * 3 - var/armor = target.run_armor_check("head", "melee") - target.apply_damage(damage, BRUTE, "head", armor) - attacker.apply_damage(10, BRUTE, "head", attacker.run_armor_check("head", "melee")) + var/armor = target.run_armor_check(BP_HEAD, "melee") + target.apply_damage(damage, BRUTE, BP_HEAD, armor) + attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD, "melee")) - if(!armor && target.headcheck("head") && prob(damage)) + if(!armor && target.headcheck(BP_HEAD) && prob(damage)) target.apply_effect(20, PARALYZE) target.visible_message("[target] [target.species.get_knockout_message(target)]") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index bcb48f0bb04..b613fc0df25 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -11,15 +11,16 @@ return L.mob_size <= MOB_SMALL return 0 -/mob/living/proc/isSynthetic() - return 0 - +// If they are 100% robotic, they count as synthetic. /mob/living/carbon/human/isSynthetic() - // If they are 100% robotic, they count as synthetic. - for(var/obj/item/organ/external/E in organs) - if(!(E.status & ORGAN_ROBOT)) - return 0 - return 1 + if(isnull(full_prosthetic)) + robolimb_count = 0 + for(var/obj/item/organ/external/E in organs) + if(E.status & ORGAN_ROBOT) + robolimb_count++ + if(robolimb_count == organs.len) + full_prosthetic = 1 + return full_prosthetic /mob/living/silicon/isSynthetic() return 1 @@ -72,46 +73,13 @@ proc/getsensorlevel(A) Miss Chance */ -//TODO: Integrate defence zones and targeting body parts with the actual organ system, move these into organ definitions. - -//The base miss chance for the different defence zones -var/list/global/base_miss_chance = list( - "head" = 40, - "chest" = 10, - "groin" = 20, - "l_leg" = 20, - "r_leg" = 20, - "l_arm" = 20, - "r_arm" = 20, - "l_hand" = 50, - "r_hand" = 50, - "l_foot" = 50, - "r_foot" = 50, -) - -//Used to weight organs when an organ is hit randomly (i.e. not a directed, aimed attack). -//Also used to weight the protection value that armour provides for covering that body part when calculating protection from full-body effects. -var/list/global/organ_rel_size = list( - "head" = 25, - "chest" = 70, - "groin" = 30, - "l_leg" = 25, - "r_leg" = 25, - "l_arm" = 25, - "r_arm" = 25, - "l_hand" = 10, - "r_hand" = 10, - "l_foot" = 10, - "r_foot" = 10, -) - /proc/check_zone(zone) - if(!zone) return "chest" + if(!zone) return BP_TORSO switch(zone) - if("eyes") - zone = "head" - if("mouth") - zone = "head" + if(O_EYES) + zone = BP_HEAD + if(O_MOUTH) + zone = BP_HEAD return zone // Returns zone with a certain probability. If the probability fails, or no zone is specified, then a random body part is chosen. @@ -126,17 +94,17 @@ var/list/global/organ_rel_size = list( var/ran_zone = zone while (ran_zone == zone) ran_zone = pick ( - organ_rel_size["head"]; "head", - organ_rel_size["chest"]; "chest", - organ_rel_size["groin"]; "groin", - organ_rel_size["l_arm"]; "l_arm", - organ_rel_size["r_arm"]; "r_arm", - organ_rel_size["l_leg"]; "l_leg", - organ_rel_size["r_leg"]; "r_leg", - organ_rel_size["l_hand"]; "l_hand", - organ_rel_size["r_hand"]; "r_hand", - organ_rel_size["l_foot"]; "l_foot", - organ_rel_size["r_foot"]; "r_foot", + organ_rel_size[BP_HEAD]; BP_HEAD, + organ_rel_size[BP_TORSO]; BP_TORSO, + organ_rel_size[BP_GROIN]; BP_GROIN, + organ_rel_size[BP_L_ARM]; BP_L_ARM, + organ_rel_size[BP_R_ARM]; BP_R_ARM, + organ_rel_size[BP_L_LEG]; BP_L_LEG, + organ_rel_size[BP_R_LEG]; BP_R_LEG, + organ_rel_size[BP_L_HAND]; BP_L_HAND, + organ_rel_size[BP_R_HAND]; BP_R_HAND, + organ_rel_size[BP_L_FOOT]; BP_L_FOOT, + organ_rel_size[BP_R_FOOT]; BP_R_FOOT, ) return ran_zone @@ -564,3 +532,37 @@ proc/is_blind(A) return threatcount #undef SAFE_PERP + + +//TODO: Integrate defence zones and targeting body parts with the actual organ system, move these into organ definitions. + +//The base miss chance for the different defence zones +var/list/global/base_miss_chance = list( + "head" = 40, + "chest" = 10, + "groin" = 20, + "l_leg" = 20, + "r_leg" = 20, + "l_arm" = 20, + "r_arm" = 20, + "l_hand" = 50, + "r_hand" = 50, + "l_foot" = 50, + "r_foot" = 50, +) + +//Used to weight organs when an organ is hit randomly (i.e. not a directed, aimed attack). +//Also used to weight the protection value that armour provides for covering that body part when calculating protection from full-body effects. +var/list/global/organ_rel_size = list( + "head" = 25, + "chest" = 70, + "groin" = 30, + "l_leg" = 25, + "r_leg" = 25, + "l_arm" = 25, + "r_arm" = 25, + "l_hand" = 10, + "r_hand" = 10, + "l_foot" = 10, + "r_foot" = 10, +) \ No newline at end of file diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index d20fe8bee22..5a2076aba44 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -5,7 +5,7 @@ datum/preferences s_tone = random_skin_tone() var/use_head_species - var/obj/item/organ/external/head/temp_head = H.get_organ("head") + var/obj/item/organ/external/head/temp_head = H.get_organ(BP_HEAD) if(temp_head) use_head_species = temp_head.species.get_bodytype() else @@ -202,20 +202,20 @@ datum/preferences icobase = 'icons/mob/human_races/r_human.dmi' preview_icon = new /icon(icobase, "") - for(var/name in list("torso", "groin", "head", "r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand")) + for(var/name in BP_ALL) if(organ_data[name] == "amputated") continue if(organ_data[name] == "cyborg") var/datum/robolimb/R if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]] if(!R) R = basic_robolimb - if(name in list("torso", "groin", "head")) + if(name in list(BP_TORSO, BP_GROIN, BP_HEAD)) preview_icon.Blend(icon(R.icon, "[name]_[g]"), ICON_OVERLAY) else preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) continue var/icon/limb_icon - if(name in list("torso", "groin", "head")) + if(name in list(BP_TORSO, BP_GROIN, BP_HEAD)) limb_icon = new /icon(icobase, "[name]_[g]") else limb_icon = new /icon(icobase, "[name]") @@ -244,7 +244,7 @@ datum/preferences // This is absolute garbage but whatever. It will do until this entire file can be rewritten without crashes. var/use_eye_icon = "eyes_s" - var/list/use_eye_data = current_species.has_limbs["head"] + var/list/use_eye_data = current_species.has_limbs[BP_HEAD] if(islist(use_eye_data)) var/use_eye_path = use_eye_data["path"] var/obj/item/organ/external/head/temp_head = new use_eye_path () diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index b358cd0fbbd..d85a464af2b 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -68,12 +68,12 @@ if (istype(mover, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mover var/damage = 5 - H.apply_damage(rand(0, damage), BRUTE, "head") - H.apply_damage(rand(0, damage), BRUTE, "chest") - H.apply_damage(rand(0, damage), BRUTE, "l_leg") - H.apply_damage(rand(0, damage), BRUTE, "r_leg") - H.apply_damage(rand(0, damage), BRUTE, "l_arm") - H.apply_damage(rand(0, damage), BRUTE, "r_arm") + H.apply_damage(rand(0, damage), BRUTE, BP_HEAD) + H.apply_damage(rand(0, damage), BRUTE, BP_TORSO) + H.apply_damage(rand(0, damage), BRUTE, BP_L_LEG) + H.apply_damage(rand(0, damage), BRUTE, BP_R_LEG) + H.apply_damage(rand(0, damage), BRUTE, BP_L_ARM) + H.apply_damage(rand(0, damage), BRUTE, BP_R_ARM) H.weakened = max(H.weakened,2) H.updatehealth() diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 74d2cebce00..6621e0f102b 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -19,7 +19,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 vessel = new/datum/reagents(600) vessel.my_atom = src - if(!should_have_organ("heart")) //We want the var for safety but we can do without the actual blood. + if(!should_have_organ(O_HEART)) //We want the var for safety but we can do without the actual blood. return vessel.add_reagent("blood",560) @@ -39,7 +39,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 if(in_stasis) return - if(!should_have_organ("heart")) + if(!should_have_organ(O_HEART)) return if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood. @@ -62,8 +62,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 // Damaged heart virtually reduces the blood volume, as the blood isn't // being pumped properly anymore. - if(species && should_have_organ("heart")) - var/obj/item/organ/heart/heart = internal_organs_by_name["heart"] + if(species && should_have_organ(O_HEART)) + var/obj/item/organ/internal/heart/heart = internal_organs_by_name[O_HEART] if(!heart) blood_volume = 0 @@ -137,7 +137,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Makes a blood drop, leaking amt units of blood from the mob /mob/living/carbon/human/proc/drip(var/amt as num) - if(!should_have_organ("heart")) //TODO: Make drips come from the reagents instead. + if(!should_have_organ(O_HEART)) //TODO: Make drips come from the reagents instead. return if(!amt) @@ -188,7 +188,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //For humans, blood does not appear from blue, it comes from vessels. /mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount) - if(!should_have_organ("heart")) + if(!should_have_organ(O_HEART)) return null if(vessel.get_reagent_amount("blood") < amount) @@ -216,7 +216,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 //Transfers blood from reagents to vessel, respecting blood types compatability. /mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount) - if(should_have_organ("heart")) + if(should_have_organ(O_HEART)) reagents.add_reagent("blood", amount, injected.data) reagents.update_total() return diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm index 0ba128c1a6b..1f4fc2c1fe6 100644 --- a/code/modules/organs/misc.dm +++ b/code/modules/organs/misc.dm @@ -1,5 +1,14 @@ //CORTICAL BORER ORGANS. -/obj/item/organ/borer/process() +/obj/item/organ/internal/borer + name = "cortical borer" + icon = 'icons/obj/objects.dmi' + icon_state = "borer" + organ_tag = "brain" + desc = "A disgusting space slug." + parent_organ = BP_HEAD + vital = 1 + +/obj/item/organ/internal/borer/process() // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss. for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine")) @@ -21,16 +30,7 @@ goo.basecolor = "#412464" goo.update_icon() -/obj/item/organ/borer - name = "cortical borer" - icon = 'icons/obj/objects.dmi' - icon_state = "borer" - organ_tag = "brain" - desc = "A disgusting space slug." - parent_organ = "head" - vital = 1 - -/obj/item/organ/borer/removed(var/mob/living/user) +/obj/item/organ/internal/borer/removed(var/mob/living/user) ..() @@ -43,19 +43,19 @@ qdel(src) //VOX ORGANS. -/obj/item/organ/stack +/obj/item/organ/internal/stack name = "cortical stack" - parent_organ = "head" + parent_organ = BP_HEAD icon_state = "brain-prosthetic" organ_tag = "stack" vital = 1 var/backup_time = 0 var/datum/mind/backup -/obj/item/organ/stack/process() +/obj/item/organ/internal/stack/process() if(owner && owner.stat != DEAD && !is_broken()) backup_time = world.time if(owner.mind) backup = owner.mind -/obj/item/organ/stack/vox/stack +/obj/item/organ/internal/stack/vox/stack name = "vox cortical stack" diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 63c57acb215..e0851716780 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -6,47 +6,37 @@ var/list/organ_cache = list() germ_level = 0 // Strings. - var/organ_tag = "organ" - var/parent_organ = "chest" - - // Appearance. - var/dead_icon + var/organ_tag = "organ" // Unique identifier. + var/parent_organ = BP_TORSO // Organ holding this object. // Status tracking. - var/status = 0 - var/vital //Lose a vital limb, die immediately. - var/damage = 0 // amount of damage to the organ + var/status = 0 // Various status flags (such as robotic) + var/vital // Lose a vital limb, die immediately. + var/damage = 0 // Current damage to the organ // Reference data. - var/mob/living/carbon/human/owner = null - var/list/transplant_data - var/list/datum/autopsy_data/autopsy_data = list() - var/list/trace_chemicals = list() // traces of chemicals in the organ, - var/datum/dna/dna - var/datum/species/species + var/mob/living/carbon/human/owner // Current mob owning the organ. + var/list/transplant_data // Transplant match data. + var/list/autopsy_data = list() // Trauma data for forensics. + var/list/trace_chemicals = list() // Traces of chemicals in the organ. + var/datum/dna/dna // Original DNA. + var/datum/species/species // Original species. // Damage vars. - var/min_bruised_damage = 10 - var/min_broken_damage = 30 - var/max_damage - var/rejecting // Is this organ already being rejected? + var/min_bruised_damage = 10 // Damage before considered bruised + var/min_broken_damage = 30 // Damage before becoming broken + var/max_damage // Damage cap + var/rejecting // Is this organ already being rejected? /obj/item/organ/Destroy() - if(!owner) - return ..() - if(istype(owner, /mob/living/carbon)) - if((owner.internal_organs) && (src in owner.internal_organs)) - owner.internal_organs -= src - if(istype(owner, /mob/living/carbon/human)) - if((owner.internal_organs_by_name) && (src in owner.internal_organs_by_name)) - owner.internal_organs_by_name -= src - if((owner.organs) && (src in owner.organs)) - owner.organs -= src - if((owner.organs_by_name) && (src in owner.organs_by_name)) - owner.organs_by_name -= src - if(src in owner.contents) - owner.contents -= src - owner = null + + if(owner) owner = null + if(transplant_data) transplant_data.Cut() + if(autopsy_data) autopsy_data.Cut() + if(trace_chemicals) trace_chemicals.Cut() + dna = null + species = null + return ..() /obj/item/organ/proc/update_health() @@ -92,8 +82,6 @@ var/list/organ_cache = list() damage = max_damage status |= ORGAN_DEAD processing_objects -= src - if(dead_icon) - icon_state = dead_icon if(owner && vital) owner.death() @@ -115,7 +103,7 @@ var/list/organ_cache = list() germ_level = 0 return - if(!owner) + if(!owner && reagents) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list if(B && prob(40)) reagents.remove_reagent("blood",0.1) @@ -193,6 +181,9 @@ var/list/organ_cache = list() /obj/item/organ/proc/receive_chem(chemical as obj) return 0 +/obj/item/organ/proc/remove_rejuv() + qdel(src) + /obj/item/organ/proc/rejuvenate(var/ignore_prosthetic_prefs) damage = 0 status = 0 @@ -203,16 +194,6 @@ var/list/organ_cache = list() else if(status == "mechanical") robotize() -/obj/item/organ/proc/remove_rejuv() - if(owner) - owner.internal_organs -= src - owner.internal_organs_by_name[organ_tag] = null - while(null in owner.internal_organs) - owner.internal_organs -= null - while(null in owner.internal_organs_by_name) - owner.internal_organs_by_name -= null - qdel(src) - /obj/item/organ/proc/is_damaged() return damage > 0 @@ -336,16 +317,6 @@ var/list/organ_cache = list() affected.internal_organs |= src target.internal_organs_by_name[organ_tag] = src -/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target) - - // Apply our eye colour to the target. - if(istype(target) && eye_colour) - target.r_eyes = eye_colour[1] - target.g_eyes = eye_colour[2] - target.b_eyes = eye_colour[3] - target.update_eyes() - ..() - /obj/item/organ/proc/bitten(mob/user) if(status & ORGAN_ROBOT) @@ -374,7 +345,7 @@ var/list/organ_cache = list() /obj/item/organ/attack_self(mob/user as mob) // Convert it to an edible form, yum yum. - if((status & ORGAN_ROBOT) && user.a_intent == "help" && user.zone_sel.selecting == "mouth") + if((status & ORGAN_ROBOT) && user.a_intent == I_HELP && user.zone_sel.selecting == O_MOUTH) bitten(user) return diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index ed9d32f122e..a8d61416300 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -15,50 +15,51 @@ organ_tag = "limb" // Strings - var/limb_name + var/broken_description // fracture string if any. + var/damage_state = "00" // Modifier used for generating the on-mob damage overlay for this limb. // Damage vars. - var/brute_mod = 1 // Multiplier for incoming brute damage. - var/burn_mod = 1 // As above for burn. - var/damage_state = "00" // Modifier used for generating the on-mob damage overlay for this limb. - var/brute_dam = 0 // Actual current brute damage. - var/burn_dam = 0 // Actual current burn damage. - var/last_dam = -1 + var/brute_mod = 1 // Multiplier for incoming brute damage. + var/burn_mod = 1 // As above for burn. + var/brute_dam = 0 // Actual current brute damage. + var/burn_dam = 0 // Actual current burn damage. + var/last_dam = -1 // used in healing/processing calculations. // Appearance vars. - var/icon_name = null - var/body_part = null - var/icon_position = 0 - var/model - var/force_icon - var/icon/mob_icon - var/gendered_icon = 0 - var/s_tone - var/list/s_col - var/list/h_col - var/body_hair + var/icon_name = null // Icon state base. + var/body_part = null // Part flag + var/icon_position = 0 // Used in mob overlay layering calculations. + var/model // Used when caching robolimb icons. + var/force_icon // Used to force override of species-specific limb icons (for prosthetics). + var/icon/mob_icon // Cached icon for use in mob overlays. + var/gendered_icon = 0 // Whether or not the icon state appends a gender. + var/s_tone // Skin tone. + var/list/s_col // skin colour + var/list/h_col // hair colour + var/body_hair // Icon blend for body hair if any. // Wound and structural data. - var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often - var/list/wounds = list() - var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len! - var/obj/item/organ/external/parent - var/list/obj/item/organ/external/children - var/list/internal_organs = list() // Internal organs of this body part - var/broken_description - var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails. - var/list/implants = list() + var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often + var/list/wounds = list() // wound datum list. + var/number_wounds = 0 // number of wounds, which is NOT wounds.len! + var/obj/item/organ/external/parent // Master-limb. + var/list/children // Sub-limbs. + var/list/internal_organs = list() // Internal organs of this body part + var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails. + var/list/implants = list() // Currently implanted objects. + var/organ_rel_size = 25 // Relative size of the organ. + var/base_miss_chance = 20 // Chance of missing. // Joint/state stuff. - var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point - var/can_stand - var/disfigured = 0 - var/cannot_amputate - var/cannot_break - var/joint = "joint" // Descriptive string used in dislocation. - var/amputation_point // Descriptive string used in amputation. - var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. - var/encased // Needs to be opened with a saw to access the organs. + var/can_grasp // It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point + var/can_stand // Modifies stance tally/ability to stand. + var/disfigured = 0 // Scarred/burned beyond recognition. + var/cannot_amputate // Impossible to amputate. + var/cannot_break // Impossible to fracture. + var/joint = "joint" // Descriptive string used in dislocation. + var/amputation_point // Descriptive string used in amputation. + var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. + var/encased // Needs to be opened with a saw to access the organs. // Surgery vars. var/open = 0 @@ -67,6 +68,7 @@ /obj/item/organ/external/Destroy() + if(parent && parent.children) parent.children -= src @@ -78,6 +80,13 @@ for(var/obj/item/organ/O in internal_organs) qdel(O) + if(owner) + owner.organs -= src + owner.organs_by_name[organ_tag] = null + owner.organs_by_name -= organ_tag + while(null in owner.organs) + owner.organs -= null + return ..() /obj/item/organ/external/attack_self(var/mob/user) @@ -183,7 +192,7 @@ /obj/item/organ/external/replaced(var/mob/living/carbon/human/target) owner = target if(istype(owner)) - owner.organs_by_name[limb_name] = src + owner.organs_by_name[organ_tag] = src owner.organs |= src for(var/obj/item/organ/organ in src) organ.loc = owner @@ -319,11 +328,6 @@ if(internal) status &= ~ORGAN_BROKEN - /*if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS)) - var/obj/item/organ/external/stump/S = locate() in children - if(S) - world << "Extra healing to go around ([brute+burn]) and [owner] needs a replacement limb."*/ - //Sync the organ's damage with its wounds src.update_damages() owner.updatehealth() @@ -356,11 +360,11 @@ This function completely restores a damaged organ to perfect condition. if(owner && !ignore_prosthetic_prefs) if(owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name) - var/status = owner.client.prefs.organ_data[limb_name] + var/status = owner.client.prefs.organ_data[organ_tag] if(status == "amputated") remove_rejuv() else if(status == "cyborg") - var/robodata = owner.client.prefs.rlimb_data[limb_name] + var/robodata = owner.client.prefs.rlimb_data[organ_tag] if(robodata) robotize(robodata) else @@ -370,20 +374,16 @@ This function completely restores a damaged organ to perfect condition. /obj/item/organ/external/remove_rejuv() if(owner) owner.organs -= src - owner.organs_by_name[limb_name] = null - while(null in owner.organs) - owner.organs -= null - while(null in owner.organs_by_name) - owner.organs_by_name -= null + owner.organs_by_name[organ_tag] = null + owner.organs_by_name -= organ_tag + while(null in owner.organs) owner.organs -= null if(children && children.len) for(var/obj/item/organ/external/E in children) E.remove_rejuv() children.Cut() - - for(var/obj/item/organ/O in contents) - O.remove_rejuv() - - qdel(src) + for(var/obj/item/organ/internal/I in internal_organs) + I.remove_rejuv() + ..() /obj/item/organ/external/proc/createwound(var/type = CUT, var/damage) if(damage == 0) return @@ -652,7 +652,7 @@ Note that amputating the affected organ does in fact remove the infection from t else if(W.damage_type == BURN) burn_dam += W.damage - if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ("heart"))) + if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ(O_HEART))) W.bleed_timer-- status |= ORGAN_BLEEDING @@ -661,7 +661,7 @@ Note that amputating the affected organ does in fact remove the infection from t number_wounds += W.amount //things tend to bleed if they are CUT OPEN - if (open && !clamped && (H && H.should_have_organ("heart"))) + if (open && !clamped && (H && H.should_have_organ(O_HEART))) status |= ORGAN_BLEEDING //Bone fractures @@ -789,7 +789,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(status & ORGAN_ROBOT) gore = new /obj/effect/decal/cleanable/blood/gibs/robot(get_turf(victim)) else - gore = new victim.species.single_gib_type(get_turf(victim)) + gore = new /obj/effect/decal/cleanable/blood/gibs(get_turf(victim)) if(species) if(species.get_flesh_colour()) gore.fleshcolor = species.get_flesh_colour() @@ -905,7 +905,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(isnull(suit.supporting_limbs)) return - owner << "You feel \the [suit] constrict about your [name], supporting it." + owner << "You feel \the [suit] constrict about your [name], supporting it." status |= ORGAN_SPLINTED suit.supporting_limbs |= src return @@ -919,14 +919,20 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 -/obj/item/organ/external/robotize(var/company, var/ski) +/obj/item/organ/external/robotize(var/company, var/skip_prosthetics = 0, var/keep_organs = 0) + + if(status & ORGAN_ROBOT) + return + if(status & ORGAN_ROBOT) return ..() - brute_mod = 0.8 - burn_mod = 0.8 + + brute_mod = 0.8 // More resistant to brute. + burn_mod = 0.8 // More resistant to burn. + max_damage = initial(max_damage)*0.65 // Significantly easier to remove with trauma. brute_mod = 0.8 burn_mod = 0.8 @@ -949,23 +955,25 @@ Note that amputating the affected organ does in fact remove the infection from t for(var/obj/item/organ/external/T in children) T.robotize(company, 1) + if(owner) if(!skip_prosthetics) owner.full_prosthetic = null // Will be rechecked next isSynthetic() call. - for(var/obj/item/organ/thing in src.contents) - if(istype(thing)) - if(thing.vital) - continue - owner.internal_organs_by_name[thing.organ_tag] = null - owner.internal_organs.Remove(thing) - qdel(thing) + if(!keep_organs) + for(var/obj/item/organ/thing in internal_organs) + if(istype(thing)) + if(thing.vital) + continue + internal_organs -= thing + owner.internal_organs_by_name[thing.organ_tag] = null + owner.internal_organs_by_name -= thing.organ_tag + owner.internal_organs.Remove(thing) + qdel(thing) while(null in owner.internal_organs) owner.internal_organs -= null - while(null in owner.internal_organs_by_name) - owner.internal_organs -= null return 1 @@ -1047,7 +1055,7 @@ Note that amputating the affected organ does in fact remove the infection from t release_restraints(victim) victim.organs -= src - victim.organs_by_name[limb_name] = null // Remove from owner's vars. + victim.organs_by_name[organ_tag] = null // Remove from owner's vars. //Robotic limbs explode if sabotaged. if(is_robotic && sabotaged) @@ -1140,7 +1148,7 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/chest name = "upper body" - limb_name = "chest" + organ_tag = BP_TORSO icon_name = "torso" max_damage = 100 min_broken_damage = 35 @@ -1154,43 +1162,46 @@ Note that amputating the affected organ does in fact remove the infection from t cannot_amputate = 1 parent_organ = null encased = "ribcage" + organ_rel_size = 70 + base_miss_chance = 10 /obj/item/organ/external/chest/robotize() if(..()) // Give them a new cell. - owner.internal_organs_by_name["cell"] = new /obj/item/organ/cell(owner,1) + owner.internal_organs_by_name["cell"] = new /obj/item/organ/internal/cell(owner,1) /obj/item/organ/external/groin name = "lower body" - limb_name = "groin" + organ_tag = BP_GROIN icon_name = "groin" max_damage = 100 min_broken_damage = 35 w_class = 5 body_part = LOWER_TORSO vital = 1 - parent_organ = "chest" + parent_organ = BP_TORSO amputation_point = "lumbar" joint = "hip" dislocated = -1 gendered_icon = 1 + organ_rel_size = 30 /obj/item/organ/external/arm - limb_name = "l_arm" + organ_tag = "l_arm" name = "left arm" icon_name = "l_arm" max_damage = 50 min_broken_damage = 30 w_class = 3 body_part = ARM_LEFT - parent_organ = "chest" + parent_organ = BP_TORSO joint = "left elbow" amputation_point = "left shoulder" can_grasp = 1 /obj/item/organ/external/arm/right - limb_name = "r_arm" + organ_tag = "r_arm" name = "right arm" icon_name = "r_arm" body_part = ARM_RIGHT @@ -1198,7 +1209,7 @@ Note that amputating the affected organ does in fact remove the infection from t amputation_point = "right shoulder" /obj/item/organ/external/leg - limb_name = "l_leg" + organ_tag = "l_leg" name = "left leg" icon_name = "l_leg" max_damage = 50 @@ -1206,13 +1217,13 @@ Note that amputating the affected organ does in fact remove the infection from t w_class = 3 body_part = LEG_LEFT icon_position = LEFT - parent_organ = "groin" + parent_organ = BP_GROIN joint = "left knee" amputation_point = "left hip" can_stand = 1 /obj/item/organ/external/leg/right - limb_name = "r_leg" + organ_tag = "r_leg" name = "right leg" icon_name = "r_leg" body_part = LEG_RIGHT @@ -1221,7 +1232,7 @@ Note that amputating the affected organ does in fact remove the infection from t amputation_point = "right hip" /obj/item/organ/external/foot - limb_name = "l_foot" + organ_tag = "l_foot" name = "left foot" icon_name = "l_foot" min_broken_damage = 15 @@ -1232,13 +1243,15 @@ Note that amputating the affected organ does in fact remove the infection from t joint = "left ankle" amputation_point = "left ankle" can_stand = 1 + organ_rel_size = 10 + base_miss_chance = 50 /obj/item/organ/external/foot/removed() if(owner) owner.u_equip(owner.shoes) ..() /obj/item/organ/external/foot/right - limb_name = "r_foot" + organ_tag = "r_foot" name = "right foot" icon_name = "r_foot" body_part = FOOT_RIGHT @@ -1248,7 +1261,7 @@ Note that amputating the affected organ does in fact remove the infection from t amputation_point = "right ankle" /obj/item/organ/external/hand - limb_name = "l_hand" + organ_tag = "l_hand" name = "left hand" icon_name = "l_hand" min_broken_damage = 15 @@ -1258,13 +1271,15 @@ Note that amputating the affected organ does in fact remove the infection from t joint = "left wrist" amputation_point = "left wrist" can_grasp = 1 + organ_rel_size = 10 + base_miss_chance = 50 /obj/item/organ/external/hand/removed() owner.u_equip(owner.gloves) ..() /obj/item/organ/external/hand/right - limb_name = "r_hand" + organ_tag = "r_hand" name = "right hand" icon_name = "r_hand" body_part = HAND_RIGHT @@ -1273,7 +1288,7 @@ Note that amputating the affected organ does in fact remove the infection from t amputation_point = "right wrist" /obj/item/organ/external/head - limb_name = "head" + organ_tag = BP_HEAD icon_name = "head" name = "head" max_damage = 75 @@ -1281,14 +1296,19 @@ Note that amputating the affected organ does in fact remove the infection from t w_class = 3 body_part = HEAD vital = 1 - parent_organ = "chest" + parent_organ = BP_TORSO joint = "jaw" amputation_point = "neck" gendered_icon = 1 encased = "skull" + base_miss_chance = 40 var/eye_icon = "eyes_s" +// These organs are important for robotizing at chargen. +/obj/item/organ/external/head/robotize(var/company, var/skip_prosthetics, var/keep_organs) + return ..(company, skip_prosthetics, 1) + /obj/item/organ/external/head/removed() if(owner) name = "[owner.real_name]'s head" diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 4faa7961076..3b55dc1dda3 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -40,7 +40,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) ..() - var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/eyes = owner.internal_organs_by_name[O_EYES] if(eyes) eyes.update_colour() /obj/item/organ/external/head/removed() @@ -53,8 +53,8 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner || !owner.species) return - if(owner.should_have_organ("eyes")) - var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] + if(owner.should_have_organ(O_EYES)) + var/obj/item/organ/internal/eyes/eyes = owner.internal_organs_by_name[O_EYES] if(eye_icon) var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', eye_icon) if(eyes) diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm index cfd7ec78f71..175873e78b6 100644 --- a/code/modules/organs/organ_internal.dm +++ b/code/modules/organs/organ_internal.dm @@ -3,24 +3,52 @@ /**************************************************** INTERNAL ORGANS DEFINES ****************************************************/ +/obj/item/organ/internal + var/dead_icon // Icon to use when the organ has died. +/obj/item/organ/internal/die() + ..() + if((status & ORGAN_DEAD) && dead_icon) + icon_state = dead_icon + +/obj/item/organ/internal/Destroy() + if(owner) + owner.internal_organs.Remove(src) + owner.internal_organs_by_name[organ_tag] = null + owner.internal_organs_by_name -= organ_tag + while(null in owner.internal_organs) + owner.internal_organs -= null + var/obj/item/organ/external/E = owner.organs_by_name[parent_organ] + if(istype(E)) E.internal_organs -= src + return ..() + +/obj/item/organ/internal/remove_rejuv() + if(owner) + owner.internal_organs -= src + owner.internal_organs_by_name[organ_tag] = null + owner.internal_organs_by_name -= organ_tag + while(null in owner.internal_organs) + owner.internal_organs -= null + var/obj/item/organ/external/E = owner.organs_by_name[parent_organ] + if(istype(E)) E.internal_organs -= src + ..() // Brain is defined in brain_item.dm. -/obj/item/organ/heart +/obj/item/organ/internal/heart name = "heart" icon_state = "heart-on" - organ_tag = "heart" - parent_organ = "chest" + organ_tag = O_HEART + parent_organ = BP_TORSO dead_icon = "heart-off" -/obj/item/organ/lungs +/obj/item/organ/internal/lungs name = "lungs" icon_state = "lungs" gender = PLURAL - organ_tag = "lungs" - parent_organ = "chest" + organ_tag = O_LUNGS + parent_organ = BP_TORSO -/obj/item/organ/lungs/process() +/obj/item/organ/internal/lungs/process() ..() if(!owner) @@ -38,14 +66,14 @@ spawn owner.emote("me", 1, "gasps for air!") owner.losebreath += 15 -/obj/item/organ/kidneys +/obj/item/organ/internal/kidneys name = "kidneys" icon_state = "kidneys" gender = PLURAL - organ_tag = "kidneys" - parent_organ = "groin" + organ_tag = O_KIDNEYS + parent_organ = BP_GROIN -/obj/item/organ/kidneys/process() +/obj/item/organ/internal/kidneys/process() ..() @@ -62,22 +90,39 @@ else if(is_broken()) owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) -/obj/item/organ/eyes +/obj/item/organ/internal/eyes name = "eyeballs" icon_state = "eyes" gender = PLURAL - organ_tag = "eyes" - parent_organ = "head" + organ_tag = O_EYES + parent_organ = BP_HEAD var/list/eye_colour = list(0,0,0) -/obj/item/organ/eyes/robotize() +/obj/item/organ/internal/eyes/robotize() ..() name = "optical sensor" icon = 'icons/obj/robot_component.dmi' icon_state = "camera" dead_icon = "camera_broken" -/obj/item/organ/eyes/proc/update_colour() +/obj/item/organ/internal/eyes/robot + name = "optical sensor" + +/obj/item/organ/internal/eyes/robot/New() + ..() + robotize() + +/obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target) + + // Apply our eye colour to the target. + if(istype(target) && eye_colour) + target.r_eyes = eye_colour[1] + target.g_eyes = eye_colour[2] + target.b_eyes = eye_colour[3] + target.update_eyes() + ..() + +/obj/item/organ/internal/eyes/proc/update_colour() if(!owner) return eye_colour = list( @@ -86,13 +131,13 @@ owner.b_eyes ? owner.b_eyes : 0 ) -/obj/item/organ/eyes/take_damage(amount, var/silent=0) +/obj/item/organ/internal/eyes/take_damage(amount, var/silent=0) var/oldbroken = is_broken() ..() if(is_broken() && !oldbroken && owner && !owner.stat) owner << "You go blind!" -/obj/item/organ/eyes/process() //Eye damage replaces the old eye_stat var. +/obj/item/organ/internal/eyes/process() //Eye damage replaces the old eye_stat var. ..() if(!owner) return @@ -101,13 +146,13 @@ if(is_broken()) owner.eye_blind = 20 -/obj/item/organ/liver +/obj/item/organ/internal/liver name = "liver" icon_state = "liver" organ_tag = "liver" - parent_organ = "groin" + parent_organ = BP_GROIN -/obj/item/organ/liver/process() +/obj/item/organ/internal/liver/process() ..() @@ -130,7 +175,7 @@ src.damage += 0.2 * PROCESS_ACCURACY //Damaged one shares the fun else - var/obj/item/organ/O = pick(owner.internal_organs) + var/obj/item/organ/internal/O = pick(owner.internal_organs) if(O) O.damage += 0.2 * PROCESS_ACCURACY @@ -155,13 +200,13 @@ else take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them -/obj/item/organ/appendix +/obj/item/organ/internal/appendix name = "appendix" icon_state = "appendix" - parent_organ = "groin" + parent_organ = BP_GROIN organ_tag = "appendix" -/obj/item/organ/appendix/removed() +/obj/item/organ/internal/appendix/removed() if(owner) var/inflamed = 0 for(var/datum/disease/appendicitis/appendicitis in owner.viruses) diff --git a/code/modules/organs/organ_stump.dm b/code/modules/organs/organ_stump.dm index d59e7470337..ef1fffd01bd 100644 --- a/code/modules/organs/organ_stump.dm +++ b/code/modules/organs/organ_stump.dm @@ -5,7 +5,7 @@ /obj/item/organ/external/stump/New(var/mob/living/carbon/holder, var/internal, var/obj/item/organ/external/limb) if(istype(limb)) - limb_name = limb.limb_name + organ_tag = limb.organ_tag body_part = limb.body_part amputation_point = limb.amputation_point joint = limb.joint diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 47ae4757350..3c717847ccd 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -1,6 +1,6 @@ -var/global/list/all_robolimbs = list() -var/global/list/chargen_robolimbs = list() -var/global/datum/robolimb/basic_robolimb +var/list/all_robolimbs = list() +var/list/chargen_robolimbs = list() +var/datum/robolimb/basic_robolimb /proc/populate_robolimb_list() basic_robolimb = new() @@ -18,26 +18,26 @@ var/global/datum/robolimb/basic_robolimb var/list/species_cannot_use = list() /datum/robolimb/bishop - company = "Bishop Cybernetics" + company = "Bishop" desc = "This limb has a white polymer casing with blue holo-displays." icon = 'icons/mob/human_races/cyberlimbs/bishop.dmi' /datum/robolimb/hesphaistos - company = "Hesphiastos Industries" + company = "Hesphiastos" desc = "This limb has a militaristic black and green casing with gold stripes." icon = 'icons/mob/human_races/cyberlimbs/hesphaistos.dmi' /datum/robolimb/zenghu - company = "Zeng-Hu Pharmaceuticals" + company = "Zeng-Hu" desc = "This limb has a rubbery fleshtone covering with visible seams." icon = 'icons/mob/human_races/cyberlimbs/zenghu.dmi' /datum/robolimb/xion - company = "Xion Manufacturing Group" + company = "Xion" desc = "This limb has a minimalist black and red casing." icon = 'icons/mob/human_races/cyberlimbs/xion.dmi' /datum/robolimb/ipc - company = "Morpheus Cyberkinetics" + company = "Morpheus" desc = "This limb is simple and functional; no effort has been made to make it look human." icon = 'icons/mob/human_races/cyberlimbs/ipc.dmi' diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm index 5d77383d2aa..3630719d94d 100644 --- a/code/modules/organs/subtypes/diona.dm +++ b/code/modules/organs/subtypes/diona.dm @@ -26,7 +26,7 @@ /obj/item/organ/external/diona/chest name = "core trunk" - limb_name = "chest" + organ_tag = BP_TORSO icon_name = "torso" max_damage = 200 min_broken_damage = 50 @@ -35,56 +35,58 @@ vital = 1 cannot_amputate = 1 parent_organ = null + gendered_icon = 1 /obj/item/organ/external/diona/groin name = "fork" - limb_name = "groin" + organ_tag = BP_GROIN icon_name = "groin" max_damage = 100 min_broken_damage = 50 w_class = 4 body_part = LOWER_TORSO - parent_organ = "chest" + parent_organ = BP_TORSO + gendered_icon = 1 /obj/item/organ/external/diona/arm name = "left upper tendril" - limb_name = "l_arm" + organ_tag = "l_arm" icon_name = "l_arm" max_damage = 35 min_broken_damage = 20 w_class = 3 body_part = ARM_LEFT - parent_organ = "chest" + parent_organ = BP_TORSO can_grasp = 1 /obj/item/organ/external/diona/arm/right name = "right upper tendril" - limb_name = "r_arm" + organ_tag = "r_arm" icon_name = "r_arm" body_part = ARM_RIGHT /obj/item/organ/external/diona/leg name = "left lower tendril" - limb_name = "l_leg" + organ_tag = "l_leg" icon_name = "l_leg" max_damage = 35 min_broken_damage = 20 w_class = 3 body_part = LEG_LEFT icon_position = LEFT - parent_organ = "groin" + parent_organ = BP_GROIN can_stand = 1 /obj/item/organ/external/diona/leg/right name = "right lower tendril" - limb_name = "r_leg" + organ_tag = "r_leg" icon_name = "r_leg" body_part = LEG_RIGHT icon_position = RIGHT /obj/item/organ/external/diona/foot name = "left foot" - limb_name = "l_foot" + organ_tag = "l_foot" icon_name = "l_foot" max_damage = 20 min_broken_damage = 10 @@ -96,7 +98,7 @@ /obj/item/organ/external/diona/foot/right name = "right foot" - limb_name = "r_foot" + organ_tag = "r_foot" icon_name = "r_foot" body_part = FOOT_RIGHT icon_position = RIGHT @@ -106,7 +108,7 @@ /obj/item/organ/external/diona/hand name = "left grasper" - limb_name = "l_hand" + organ_tag = "l_hand" icon_name = "l_hand" max_damage = 30 min_broken_damage = 15 @@ -117,13 +119,15 @@ /obj/item/organ/external/diona/hand/right name = "right grasper" - limb_name = "r_hand" + organ_tag = "r_hand" icon_name = "r_hand" body_part = HAND_RIGHT parent_organ = "r_arm" //DIONA ORGANS. /obj/item/organ/external/diona/removed() + if(status & ORGAN_ROBOT) + return ..() var/mob/living/carbon/human/H = owner ..() if(!istype(H) || !H.organs || !H.organs.len) @@ -131,63 +135,65 @@ if(prob(50) && spawn_diona_nymph(get_turf(src))) qdel(src) -/obj/item/organ/diona/process() +/obj/item/organ/internal/diona + name = "diona nymph" + icon = 'icons/obj/objects.dmi' + icon_state = "nymph" + organ_tag = "special" // Turns into a nymph instantly, no transplanting possible. + +/obj/item/organ/internal/diona/removed(var/mob/living/user, var/skip_nymph) + if(status & ORGAN_ROBOT) + return ..() + var/mob/living/carbon/human/H = owner + ..() + if(!istype(H) || !H.organs || !H.organs.len) + H.death() + if(prob(50) && !skip_nymph && spawn_diona_nymph(get_turf(src))) + qdel(src) + +/obj/item/organ/internal/diona/process() return -/obj/item/organ/diona/strata +/obj/item/organ/internal/diona/strata name = "neural strata" - parent_organ = "chest" + parent_organ = BP_TORSO -/obj/item/organ/diona/bladder +/obj/item/organ/internal/diona/bladder name = "gas bladder" - parent_organ = "head" + parent_organ = BP_HEAD -/obj/item/organ/diona/polyp +/obj/item/organ/internal/diona/polyp name = "polyp segment" - parent_organ = "groin" + parent_organ = BP_GROIN -/obj/item/organ/diona/ligament +/obj/item/organ/internal/diona/ligament name = "anchoring ligament" - parent_organ = "groin" + parent_organ = BP_GROIN -/obj/item/organ/diona/node +/obj/item/organ/internal/diona/node name = "receptor node" - parent_organ = "head" - -/obj/item/organ/diona/nutrients - name = "nutrient vessel" - parent_organ = "chest" + parent_organ = BP_HEAD -/obj/item/organ/diona - name = "diona nymph" - icon = 'icons/obj/objects.dmi' - icon_state = "nymph" - organ_tag = "special" // Turns into a nymph instantly, no transplanting possible. - -/obj/item/organ/diona/removed(var/mob/living/user) - var/mob/living/carbon/human/H = owner - ..() - if(!istype(H) || !H.organs || !H.organs.len) - H.death() - if(prob(50) && spawn_diona_nymph(get_turf(src))) - qdel(src) +/obj/item/organ/internal/diona/nutrients + name = O_NUTRIENT + parent_organ = BP_TORSO // These are different to the standard diona organs as they have a purpose in other // species (absorbing radiation and light respectively) -/obj/item/organ/diona/nutrients - name = "nutrient vessel" - organ_tag = "nutrient vessel" +/obj/item/organ/internal/diona/nutrients + name = O_NUTRIENT + organ_tag = O_NUTRIENT icon = 'icons/mob/alien.dmi' icon_state = "claw" -/obj/item/organ/diona/nutrients/removed() - return +/obj/item/organ/internal/diona/nutrients/removed(var/mob/user) + return ..(user, 1) -/obj/item/organ/diona/node +/obj/item/organ/internal/diona/node name = "receptor node" organ_tag = "receptor node" icon = 'icons/mob/alien.dmi' icon_state = "claw" -/obj/item/organ/diona/node/removed() +/obj/item/organ/internal/diona/node/removed() return diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 3d551a37601..db34e58891a 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -1,17 +1,17 @@ -/obj/item/organ/cell +/obj/item/organ/internal/cell name = "microbattery" desc = "A small, powerful cell for use in fully prosthetic bodies." icon = 'icons/obj/power.dmi' icon_state = "scell" organ_tag = "cell" - parent_organ = "chest" + parent_organ = BP_TORSO vital = 1 -/obj/item/organ/cell/New() +/obj/item/organ/internal/cell/New() robotize() ..() -/obj/item/organ/cell/replaced() +/obj/item/organ/internal/cell/replaced() ..() // This is very ghetto way of rebooting an IPC. TODO better way. if(owner && owner.stat == DEAD) @@ -19,59 +19,50 @@ owner.visible_message("\The [owner] twitches visibly!") // Used for an MMI or posibrain being installed into a human. -/obj/item/organ/mmi_holder - name = "brain" +/obj/item/organ/internal/mmi_holder + name = "brain interface" organ_tag = "brain" - parent_organ = "head" + parent_organ = BP_HEAD vital = 1 var/obj/item/device/mmi/stored_mmi -/obj/item/organ/mmi_holder/Destroy() +/obj/item/organ/internal/mmi_holder/Destroy() stored_mmi = null return ..() -/obj/item/organ/mmi_holder/New() - ..() +/obj/item/organ/internal/mmi_holder/New(var/mob/living/carbon/human/new_owner, var/internal) + ..(new_owner, internal) if(!stored_mmi) stored_mmi = new(src) + sleep(-1) + update_from_mmi() - spawn(1) - - if(!owner) - if(stored_mmi) - stored_mmi.loc = get_turf(src) - qdel(src) - return - - update_from_mmi() - if(stored_mmi.brainmob && owner && owner.stat == DEAD) - owner.stat = 0 - owner.visible_message("\The [owner] twitches visibly!") - -/obj/item/organ/mmi_holder/proc/update_from_mmi() - - if(!stored_mmi) - return +/obj/item/organ/internal/mmi_holder/proc/update_from_mmi() if(!stored_mmi.brainmob) - stored_mmi.brainmob = new(src) - - stored_mmi.brainmob.real_name = owner.name - stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.brainmob = new(stored_mmi) + stored_mmi.brainobj = new(stored_mmi) + stored_mmi.brainmob.container = stored_mmi + stored_mmi.brainmob.real_name = owner.real_name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.name = "[initial(stored_mmi.name)] ([owner.real_name])" - if(owner) - stored_mmi.name = "[initial(stored_mmi.name)] ([owner.name])" + if(!owner) return name = stored_mmi.name desc = stored_mmi.desc icon = stored_mmi.icon + + stored_mmi.icon_state = "mmi_full" icon_state = stored_mmi.icon_state -/obj/item/organ/mmi_holder/removed() - update_from_mmi() - return ..() + if(owner && owner.stat == DEAD) + owner.stat = 0 + dead_mob_list -= owner + living_mob_list |= owner + owner.visible_message("\The [owner] twitches visibly!") -/obj/item/organ/mmi_holder/removed(var/mob/living/user) +/obj/item/organ/internal/mmi_holder/removed(var/mob/living/user) if(stored_mmi) stored_mmi.loc = get_turf(src) @@ -84,9 +75,14 @@ holder_mob.drop_from_inventory(src) qdel(src) -/obj/item/organ/mmi_holder/posibrain - name = "positronic brain" +/obj/item/organ/internal/mmi_holder/posibrain + name = "positronic brain interface" -/obj/item/organ/mmi_holder/posibrain/New() +/obj/item/organ/internal/mmi_holder/posibrain/New() stored_mmi = new /obj/item/device/mmi/digital/posibrain(src) ..() + +/obj/item/organ/internal/mmi_holder/posibrain/update_from_mmi() + ..() + stored_mmi.icon_state = "posibrain-occupied" + icon_state = stored_mmi.icon_state \ No newline at end of file diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index 54ec34ae70c..5d195f3b0cf 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -4,7 +4,7 @@ /obj/item/organ/external/chest name = "upper body" - limb_name = "chest" + organ_tag = BP_TORSO icon_name = "torso" max_damage = 100 min_broken_damage = 35 @@ -21,34 +21,34 @@ /obj/item/organ/external/groin name = "lower body" - limb_name = "groin" + organ_tag = BP_GROIN icon_name = "groin" max_damage = 100 min_broken_damage = 35 w_class = 4 body_part = LOWER_TORSO vital = 1 - parent_organ = "chest" + parent_organ = BP_TORSO amputation_point = "lumbar" joint = "hip" dislocated = -1 gendered_icon = 1 /obj/item/organ/external/arm - limb_name = "l_arm" + organ_tag = "l_arm" name = "left arm" icon_name = "l_arm" max_damage = 50 min_broken_damage = 30 w_class = 3 body_part = ARM_LEFT - parent_organ = "chest" + parent_organ = BP_TORSO joint = "left elbow" amputation_point = "left shoulder" can_grasp = 1 /obj/item/organ/external/arm/right - limb_name = "r_arm" + organ_tag = "r_arm" name = "right arm" icon_name = "r_arm" body_part = ARM_RIGHT @@ -56,7 +56,7 @@ amputation_point = "right shoulder" /obj/item/organ/external/leg - limb_name = "l_leg" + organ_tag = "l_leg" name = "left leg" icon_name = "l_leg" max_damage = 50 @@ -64,13 +64,13 @@ w_class = 3 body_part = LEG_LEFT icon_position = LEFT - parent_organ = "groin" + parent_organ = BP_GROIN joint = "left knee" amputation_point = "left hip" can_stand = 1 /obj/item/organ/external/leg/right - limb_name = "r_leg" + organ_tag = "r_leg" name = "right leg" icon_name = "r_leg" body_part = LEG_RIGHT @@ -79,7 +79,7 @@ amputation_point = "right hip" /obj/item/organ/external/foot - limb_name = "l_foot" + organ_tag = "l_foot" name = "left foot" icon_name = "l_foot" max_damage = 30 @@ -97,7 +97,7 @@ ..() /obj/item/organ/external/foot/right - limb_name = "r_foot" + organ_tag = "r_foot" name = "right foot" icon_name = "r_foot" body_part = FOOT_RIGHT @@ -107,7 +107,7 @@ amputation_point = "right ankle" /obj/item/organ/external/hand - limb_name = "l_hand" + organ_tag = "l_hand" name = "left hand" icon_name = "l_hand" max_damage = 30 @@ -124,7 +124,7 @@ ..() /obj/item/organ/external/hand/right - limb_name = "r_hand" + organ_tag = "r_hand" name = "right hand" icon_name = "r_hand" body_part = HAND_RIGHT @@ -133,7 +133,7 @@ amputation_point = "right wrist" /obj/item/organ/external/head - limb_name = "head" + organ_tag = BP_HEAD icon_name = "head" name = "head" max_damage = 75 @@ -141,7 +141,7 @@ w_class = 3 body_part = HEAD vital = 1 - parent_organ = "chest" + parent_organ = BP_TORSO joint = "jaw" amputation_point = "neck" gendered_icon = 1 diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm index 0b1233085fd..e734d745f7c 100644 --- a/code/modules/organs/subtypes/xenos.dm +++ b/code/modules/organs/subtypes/xenos.dm @@ -1,52 +1,52 @@ //XENOMORPH ORGANS -/obj/item/organ/xenos +/obj/item/organ/internal/xenos name = "xeno organ" icon = 'icons/effects/blood.dmi' desc = "It smells like an accident in a chemical factory." -/obj/item/organ/xenos/eggsac +/obj/item/organ/internal/xenos/eggsac name = "egg sac" - parent_organ = "groin" + parent_organ = BP_GROIN icon_state = "xgibmid1" - organ_tag = "egg sac" + organ_tag = O_EGG -/obj/item/organ/xenos/plasmavessel +/obj/item/organ/internal/xenos/plasmavessel name = "plasma vessel" - parent_organ = "chest" + parent_organ = BP_TORSO icon_state = "xgibdown1" - organ_tag = "plasma vessel" + organ_tag = O_PLASMA var/stored_plasma = 0 var/max_plasma = 500 -/obj/item/organ/xenos/plasmavessel/queen +/obj/item/organ/internal/xenos/plasmavessel/queen name = "bloated plasma vessel" stored_plasma = 200 max_plasma = 500 -/obj/item/organ/xenos/plasmavessel/sentinel +/obj/item/organ/internal/xenos/plasmavessel/sentinel stored_plasma = 100 max_plasma = 250 -/obj/item/organ/xenos/plasmavessel/hunter +/obj/item/organ/internal/xenos/plasmavessel/hunter name = "tiny plasma vessel" stored_plasma = 100 max_plasma = 150 -/obj/item/organ/xenos/acidgland +/obj/item/organ/internal/xenos/acidgland name = "acid gland" - parent_organ = "head" + parent_organ = BP_HEAD icon_state = "xgibtorso" - organ_tag = "acid gland" + organ_tag = O_ACID -/obj/item/organ/xenos/hivenode +/obj/item/organ/internal/xenos/hivenode name = "hive node" - parent_organ = "chest" + parent_organ = BP_TORSO icon_state = "xgibmid2" - organ_tag = "hive node" + organ_tag = O_HIVE -/obj/item/organ/xenos/resinspinner +/obj/item/organ/internal/xenos/resinspinner name = "resin spinner" - parent_organ = "head" + parent_organ = BP_HEAD icon_state = "xgibmid2" - organ_tag = "resin spinner" + organ_tag = O_RESIN diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 66ee2b39dc5..9cb37d98a91 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -140,12 +140,12 @@ return /obj/item/weapon/paper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - if(user.zone_sel.selecting == "eyes") + if(user.zone_sel.selecting == O_EYES) user.visible_message("You show the paper to [M]. ", \ " [user] holds up a paper and shows it to [M]. ") M.examinate(src) - else if(user.zone_sel.selecting == "mouth") // lipstick wiping + else if(user.zone_sel.selecting == O_MOUTH) // lipstick wiping if(ishuman(M)) var/mob/living/carbon/human/H = M if(H == user) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index ee40394c78c..7ed01b02fe2 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -136,7 +136,7 @@ Fire(A,user,params) //Otherwise, fire normally. /obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) - if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot) + if (A == user && user.zone_sel.selecting == O_MOUTH && !mouthshoot) handle_suicide(user) else if(user.a_intent == I_HURT) //point blank shooting Fire(A, user, pointblank=1) @@ -344,7 +344,7 @@ in_chamber.on_hit(M) if (in_chamber.damage_type != HALLOSS) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) + user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, BP_HEAD, used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) user.death() else user << "Ow..." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index f13c2169453..3209560007c 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -72,7 +72,7 @@ /datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.check_is_prosthetic()) + if(H.isSynthetic()) return if(data && data["viruses"]) for(var/datum/disease/D in data["viruses"]) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 88f314c99d0..e77b86a30a4 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -246,7 +246,7 @@ if(prob(50)) M.apply_effect(50, IRRADIATE, check_protection = 0) // curing it that way may kill you instead var/absorbed = 0 - var/obj/item/organ/diona/nutrients/rad_organ = locate() in M.internal_organs + var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in M.internal_organs if(rad_organ && !rad_organ.is_broken()) absorbed = 1 if(!absorbed) @@ -323,7 +323,7 @@ if(!M.unacidable && removed > 0) if(istype(M, /mob/living/carbon/human) && volume >= meltdose) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/affecting = H.get_organ("head") + var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD) if(affecting) if(affecting.take_damage(0, removed * power * 0.1)) H.UpdateDamageIcon() diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 6c169852b94..6c899d831aa 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -1763,7 +1763,7 @@ M.adjustToxLoss(2 * removed) if(dose > 60 && ishuman(M) && prob(5)) var/mob/living/carbon/human/H = M - var/obj/item/organ/heart/L = H.internal_organs_by_name["heart"] + var/obj/item/organ/internal/heart/L = H.internal_organs_by_name[O_HEART] if (L && istype(L)) if(dose < 120) L.take_damage(10 * removed, 0) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index b392e789e08..e947e9ea154 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -255,7 +255,7 @@ M.eye_blind = max(M.eye_blind - 5, 0) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"] + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] if(E && istype(E)) if(E.damage > 0) E.damage = max(E.damage - 5 * removed, 0) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index e4e4ed4c31c..48a0b9eb7c7 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -1540,42 +1540,6 @@ if(wrapped) Unwrap(user) - /* - On_Consume(var/mob/M) - M << "Something inside of you suddently expands!" - - if (istype(M, /mob/living/carbon/human)) - //Do not try to understand. - var/obj/item/weapon/surprise = new/obj/item/weapon(M) - var/mob/ook = monkey_type - surprise.icon = initial(ook.icon) - surprise.icon_state = initial(ook.icon_state) - surprise.name = "malformed [initial(ook.name)]" - surprise.desc = "Looks like \a very deformed [initial(ook.name)], a little small for its kind. It shows no signs of life." - surprise.transform *= 0.6 - surprise.add_blood(M) - var/mob/living/carbon/human/H = M - var/obj/item/organ/external/E = H.get_organ("chest") - E.fracture() - for (var/obj/item/organ/I in E.internal_organs) - I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1)) - - if (!E.hidden && prob(60)) //set it snuggly - E.hidden = surprise - E.cavity = 0 - else //someone is having a bad day - E.createwound(CUT, 30) - E.embed(surprise) - else if (issmall(M)) - M.visible_message("[M] suddenly tears in half!") - var/mob/living/carbon/monkey/ook = new monkey_type(M.loc) - ook.name = "malformed [ook.name]" - ook.transform *= 0.6 - ook.add_blood(M) - M.gib() - ..() - */ - proc/Expand() src.visible_message("\The [src] expands!") var/mob/living/carbon/human/H = new(src.loc) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 75ef62894dd..e14bd53cc17 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -96,7 +96,7 @@ var/datum/reagent/B if(istype(T, /mob/living/carbon/human)) var/mob/living/carbon/human/H = T - if(H.species && !H.should_have_organ("heart")) + if(H.species && !H.should_have_organ(O_HEART)) H.reagents.trans_to_obj(src, amount) else B = T.take_blood(src, amount) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 823561b5d87..ff0ea126359 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -52,7 +52,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.name != "head" && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1 + return affected && affected.organ_tag != BP_HEAD && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -91,7 +91,7 @@ if (!hasorgans(target)) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.name == "head" && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1 + return affected && affected.organ_tag == BP_HEAD && !(affected.status & ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 1 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \ diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 7272ecf49e0..f4e723d0c6d 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -12,7 +12,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if (!affected || (affected.status & ORGAN_ROBOT)) return 0 - return target_zone == "mouth" + return target_zone == O_MOUTH /datum/surgery_step/generic/cut_face allowed_tools = list( @@ -25,7 +25,7 @@ max_duration = 110 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target_zone == "mouth" && target.op_stage.face == 0 + return ..() && target_zone == O_MOUTH && target.op_stage.face == 0 begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \ diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 0fef3de54c2..2dd0390c619 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -8,7 +8,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (isslime(target)) return 0 - if (target_zone == "eyes") //there are specific steps for eye surgery + if (target_zone == O_EYES) //there are specific steps for eye surgery return 0 if (!hasorgans(target)) return 0 @@ -35,7 +35,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 0 && target_zone != "mouth" + return affected && affected.open == 0 && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -73,7 +73,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 0 && target_zone != "mouth" + return affected && affected.open == 0 && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -88,7 +88,7 @@ "\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",) affected.open = 1 - if(istype(target) && target.should_have_organ("heart")) + if(istype(target) && target.should_have_organ(O_HEART)) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) @@ -115,7 +115,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 0 && target_zone != "mouth" + return affected && affected.open == 0 && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -130,7 +130,7 @@ "\blue You have made an incision on [target]'s [affected.name] with \the [tool].",) affected.open = 1 - if(istype(target) && target.should_have_organ("heart")) + if(istype(target) && target.should_have_organ(O_HEART)) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) @@ -195,10 +195,10 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "[user] starts to pry open the incision on [target]'s [affected.name] with \the [tool]." var/self_msg = "You start to pry open the incision on [target]'s [affected.name] with \the [tool]." - if (target_zone == "chest") + if (target_zone == BP_TORSO) msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]." - if (target_zone == "groin") + if (target_zone == BP_GROIN) msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]." user.visible_message(msg, self_msg) @@ -209,10 +209,10 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\blue [user] keeps the incision open on [target]'s [affected.name] with \the [tool]." var/self_msg = "\blue You keep the incision open on [target]'s [affected.name] with \the [tool]." - if (target_zone == "chest") + if (target_zone == BP_TORSO) msg = "\blue [user] keeps the ribcage open on [target]'s torso with \the [tool]." self_msg = "\blue You keep the ribcage open on [target]'s torso with \the [tool]." - if (target_zone == "groin") + if (target_zone == BP_GROIN) msg = "\blue [user] keeps the incision open on [target]'s lower abdomen with \the [tool]." self_msg = "\blue You keep the incision open on [target]'s lower abdomen with \the [tool]." user.visible_message(msg, self_msg) @@ -222,10 +222,10 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) var/msg = "\red [user]'s hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" var/self_msg = "\red Your hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!" - if (target_zone == "chest") + if (target_zone == BP_TORSO) msg = "\red [user]'s hand slips, damaging several organs in [target]'s torso with \the [tool]!" self_msg = "\red Your hand slips, damaging several organs in [target]'s torso with \the [tool]!" - if (target_zone == "groin") + if (target_zone == BP_GROIN) msg = "\red [user]'s hand slips, damaging several organs in [target]'s lower abdomen with \the [tool]" self_msg = "\red Your hand slips, damaging several organs in [target]'s lower abdomen with \the [tool]!" user.visible_message(msg, self_msg) @@ -245,7 +245,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open && target_zone != "mouth" + return affected && affected.open && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -278,7 +278,7 @@ max_duration = 160 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (target_zone == "eyes") //there are specific steps for eye surgery + if (target_zone == O_EYES) //there are specific steps for eye surgery return 0 if (!hasorgans(target)) return 0 diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 213391fd620..f178a6a45b1 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -153,7 +153,7 @@ max_duration = 100 can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/sponge = target.internal_organs_by_name["brain"] return ..() && (!sponge || !sponge.damage) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index e074cbcca58..41b6ad8cd41 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -35,7 +35,7 @@ if (!hasorgans(target)) return var/obj/item/organ/external/affected = target.get_organ(target_zone) - return ..() && affected && embryo && affected.open == 3 && target_zone == "chest" + return ..() && affected && embryo && affected.open == 3 && target_zone == BP_TORSO begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." @@ -218,8 +218,8 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/I = target.internal_organs_by_name[organ] - if((I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && (I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) removable_organs |= organ var/organ_to_remove = input(user, "Which organ do you want to remove?") as null|anything in removable_organs @@ -262,7 +262,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/O = tool + var/obj/item/organ/internal/O = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!affected) return var/organ_compatible @@ -275,35 +275,24 @@ user << "You cannot install a naked organ into a robotic body." return SURGERY_FAILURE - if(!target.species) - user << "You have no idea what species this person is. Report this on the bug tracker." - return SURGERY_FAILURE - var/o_is = (O.gender == PLURAL) ? "are" : "is" var/o_a = (O.gender == PLURAL) ? "" : "a " var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't" - if(O.organ_tag == "limb") - return 0 - else if(target.should_have_organ(O.organ_tag)) - - if(O.damage > (O.max_damage * 0.75)) - user << "\The [O.organ_tag] [o_is] in no state to be transplanted." - return SURGERY_FAILURE - - if(!target.internal_organs_by_name[O.organ_tag]) - organ_missing = 1 - else - user << "\The [target] already has [o_a][O.organ_tag]." - return SURGERY_FAILURE - - if(O && affected.limb_name == O.parent_organ) - organ_compatible = 1 - else - user << "\The [O.organ_tag] [o_do] normally go in \the [affected.name]." - return SURGERY_FAILURE + if(O.damage > (O.max_damage * 0.75)) + user << "\The [O.organ_tag] [o_is] in no state to be transplanted." + return SURGERY_FAILURE + + if(!target.internal_organs_by_name[O.organ_tag]) + organ_missing = 1 + else + user << "\The [target] already has [o_a][O.organ_tag]." + return SURGERY_FAILURE + + if(O && affected.organ_tag == O.parent_organ) + organ_compatible = 1 else - user << "You're pretty sure [target.species.name_plural] don't normally have [o_a][O.organ_tag]." + user << "\The [O.organ_tag] [o_do] normally go in \the [affected.name]." return SURGERY_FAILURE return ..() && organ_missing && organ_compatible @@ -350,7 +339,7 @@ var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] - if(I && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) + if(istype(I) && (I.status & ORGAN_CUT_AWAY) && !(I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) removable_organs |= organ var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index ba9334d933a..721f124e4ef 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -70,7 +70,7 @@ if(!hasorgans(target)) return 0 - if (target_zone == "mouth" || target_zone == "eyes") + if (target_zone == O_MOUTH || target_zone == O_EYES) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -123,7 +123,7 @@ if(!hasorgans(target)) return 0 - if (target_zone == "mouth" || target_zone == "eyes") + if (target_zone == O_MOUTH || target_zone == O_EYES) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -188,7 +188,7 @@ var/obj/item/weapon/weldingtool/welder = tool if(!welder.isOn() || !welder.remove_fuel(1,user)) return 0 - return (target_zone == "chest") && istype(target.back, /obj/item/weapon/rig) && !(target.back.canremove) + return (target_zone == BP_TORSO) && istype(target.back, /obj/item/weapon/rig) && !(target.back.canremove) begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts cutting through the support systems of [target]'s [target.back] with \the [tool]." , \ diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 1ad2aec24f0..bc971478c1e 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -8,7 +8,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (isslime(target)) return 0 - if (target_zone == "eyes") //there are specific steps for eye surgery + if (target_zone == O_EYES) //there are specific steps for eye surgery return 0 if (!hasorgans(target)) return 0 @@ -34,7 +34,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open == 0 && target_zone != "mouth" + return affected && affected.open == 0 && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -78,7 +78,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ "You open the maintenance hatch on [target]'s [affected.name] with \the [tool].") - affected.open = 2 + affected.open = 3 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -98,7 +98,7 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open && target_zone != "mouth" + return affected && affected.open && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -134,7 +134,7 @@ var/obj/item/weapon/weldingtool/welder = tool if(!welder.isOn() || !welder.remove_fuel(1,user)) return 0 - return affected && affected.open == 2 && affected.brute_dam > 0 && target_zone != "mouth" + return affected && affected.open == 3 && (affected.disfigured || affected.brute_dam > 0) && target_zone != O_MOUTH begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -147,7 +147,7 @@ user.visible_message("[user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ "You finish patching damage to [target]'s [affected.name] with \the [tool].") affected.heal_damage(rand(30,50),0,1,1) - + affected.disfigured = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", @@ -166,7 +166,7 @@ if(..()) var/obj/item/stack/cable_coil/C = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth") + var/limb_can_operate = (affected && affected.open == 2 && (affected.disfigured || affected.burn_dam > 0) && target_zone != O_MOUTH) if(limb_can_operate) if(istype(C)) if(!C.get_amount() >= 3) @@ -193,6 +193,7 @@ user.visible_message("[user] causes a short circuit in [target]'s [affected.name]!", "You cause a short circuit in [target]'s [affected.name]!") target.apply_damage(rand(5,10), BURN, affected) + affected.disfigured = 0 /datum/surgery_step/robotics/fix_organ_robotic //For artificial organs allowed_tools = list( @@ -215,7 +216,7 @@ if(I.damage > 0 && (I.status & ORGAN_ROBOT)) is_organ_damaged = 1 break - return affected.open == 2 && is_organ_damaged + return affected.open == 3 && is_organ_damaged begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -276,7 +277,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!(affected && (affected.status & ORGAN_ROBOT))) return 0 - if(affected.open != 2) + if(affected.open < 3) return 0 target.op_stage.current_organ = null @@ -304,7 +305,7 @@ user.visible_message("[user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \ "You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].") - var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] + var/obj/item/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status |= ORGAN_CUT_AWAY @@ -325,7 +326,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!(affected && (affected.status & ORGAN_ROBOT))) return 0 - if(affected.open != 2) + if(affected.open < 3) return 0 target.op_stage.current_organ = null @@ -370,12 +371,12 @@ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(target_zone != "head") + if(target_zone != BP_HEAD) return var/obj/item/device/mmi/M = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && affected.open == 2)) + if(!(affected && affected.open == 3)) return 0 if(!istype(M)) @@ -389,10 +390,6 @@ user << "You cannot install a computer brain into a meat skull." return SURGERY_FAILURE - if(!target.species) - user << "You have no idea what species this person is. Report this on the bug tracker." - return SURGERY_FAILURE - if(!target.should_have_organ("brain")) user << "You're pretty sure [target.species.name_plural] don't normally have a brain." return SURGERY_FAILURE @@ -415,7 +412,7 @@ "You have installed \the [tool] into [target]'s [affected.name].") var/obj/item/device/mmi/M = tool - var/obj/item/organ/mmi_holder/holder = new(target, 1) + var/obj/item/organ/internal/mmi_holder/holder = new(target, 1) target.internal_organs_by_name["brain"] = holder user.drop_from_inventory(tool) tool.loc = holder diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 53c8c4ad40b..05cc2eac20a 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -85,7 +85,7 @@ if (G.state < 2) if(user.a_intent == I_HURT) if (prob(15)) M.Weaken(5) - M.apply_damage(8,def_zone = "head") + M.apply_damage(8,def_zone = BP_HEAD) visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") if(material) playsound(loc, material.tableslam_noise, 50, 1) @@ -97,9 +97,9 @@ if(prob(50)) M.visible_message("\The [S] slices [M]'s face messily!", "\The [S] slices your face messily!") - M.apply_damage(10, def_zone = "head") + M.apply_damage(10, def_zone = BP_HEAD) if(prob(2)) - M.embed(S, def_zone = "head") + M.embed(S, def_zone = BP_HEAD) else user << "You need a better grip to do that!" return diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index c6ff8709881..5b1fc876b31 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -55,7 +55,7 @@ if(is_train_head() && !on) return 0 - + //space check ~no flying space trains sorry if(on && istype(destination, /turf/space)) return 0 @@ -146,7 +146,7 @@ verbs += /obj/vehicle/train/cargo/engine/verb/stop_engine /obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H) - var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm") + var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) H.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index c111bf6657b..bcb70768b3c 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -237,7 +237,7 @@ activate(var/mob/living/carbon/mob,var/multiplier) if(istype(mob, /mob/living/carbon/human)) var/mob/living/carbon/human/H = mob - var/obj/item/organ/brain/B = H.internal_organs_by_name["brain"] + var/obj/item/organ/internal/brain/B = H.internal_organs_by_name["brain"] if (B && B.damage < B.min_broken_damage) B.take_damage(5) else diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm index 69ede1d4946..59e208f0342 100644 --- a/code/modules/virus2/items_devices.dm +++ b/code/modules/virus2/items_devices.dm @@ -16,7 +16,7 @@ var/mob/living/carbon/C = M if (istype(C,/mob/living/carbon/human/)) var/mob/living/carbon/human/H = C - if(!H.should_have_organ("heart")) + if(!H.should_have_organ(O_HEART)) report("Scan aborted: The target does not have blood.", user) return diff --git a/html/changelogs/Zuhayr-robolimbs.yml b/html/changelogs/Zuhayr-robolimbs.yml new file mode 100644 index 00000000000..c63ca3f97b2 --- /dev/null +++ b/html/changelogs/Zuhayr-robolimbs.yml @@ -0,0 +1,9 @@ +author: Zuhayr +delete-after: True +changes: + - rscadd: "Removed the species restrictions on transplanted internal organs. Have fun." + - rscadd: "Added 'full body' prosthetic options to character generation." + - rscadd: "Removed IPC. No tears were shed." + - rscadd: "RE: borgs, Renamed 'robot' type to 'drone' and 'android' type to 'robot' for clarity with new 'android' human mobs." + - rscadd: "Rejuvenate will now reapply robolimb/autopsy data." + - rscadd: "Lots of backend work relating to the above. If you're a coder go look at the PR or ask Zuhayr for details." diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 8600c9c26adef16db1a980ffdcfc29ecb3c95b44..f7a49811cea3568771f891da8dfeb1d58b0e3cd2 100644 GIT binary patch literal 50492 zcmc$`2UL^a*CrZ3ML|TQcSXTM6A^+)lV+i-^bXQ{?*yeu7g0Kdru5!xP?|{ZozPq8 z5PFh1`Tf8D_sy&|bJv}_X5C@QI>}4kobv9o_p_h<97B{9Uy_k9kU$_1ve&Pq-$EdS zY2erI>J@NB>dW5)@aC)Mdktr46DMOw3wvh^J6j0EJvk+|$9C%R^^U&1cUQLrn7=-i zQL4TEFo@9V`05qzfmjC3C-+ub>=06$?QN6M551r44(Z=(E7nFItdAY!Pd16r63b7t zr3qSMj8(cLd%vhMx*#5z(&!qmU&LIyIwCuh_EO=YYnoeFl98#-U(3wVwgSa|BQ?g# zhGyzDU1HCUPkX~qx&RH$uwSiT?Ow5w5^wYP8ZPI>(;xQdM`-oj-}~g3!1Z-#lltY$ zNxhuq)o(#J#DiJHNU#j9iugJT(8Xscpp&sQ(vNNlxotfq5GOIy06)ETvqk<+J^Axq@=m~MEl757cKQq z{k;DW+qW@V-WBj_lCgSdo;63&_{&*g>?_A=^NgW+t96*S6P>0_DRs-&Q)n5LlF`xJ zNdwD7_{BF*w;RHIj7GPJGb%(`=b3L_nqzlSisj`DZ9ggg3meqfS

g7O7F}=kFbN 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

0e|kw#ejH<(BZIS2xQ30m~kOTZEvu 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 H?B)LgV}78N literal 47377 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 VNq#aPJobOBs;qgpMCsAX{{t=GBK`mX diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi index ebc132f554fa1f0118f3e25323a07e59c1191e90..ce332e9bc4c6a613d1715558ca28be72f661f00c 100644 GIT binary patch literal 4210 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 delta 1435 zcmYjPdpOez7~a&OT(TpVaB`_;E_IMDNLG%W!^(XfqerV`$0Bn}bK6fsC%KP!+-Brb zXu?p8p^M`-w-|e}BXo{j7GpBD-=Y5KeE)pk^FH7AKHvL(--=GLT$(zt3j%>~sdm@5 z6T$f+2E}5r($mxZ{rx!{4x7#H?d@%DZjOtKL!;3UpPFM6ph`aI;o$+|%^+qV*lR|i zP?D3AiA3V|AcMi^?(S}HZ}05vY-wqs)9F|&R!>iFn;V0{xVyVMIXU6+cpDoVLqkJo z;&1mL5C8%Vb#-)uocqYZZ?`>(z+gjdeL}p034x&mVgLj}%1<78A=_ypA2T&hmZdC| zj!l#viIeX$I&g1xSH_+jgRSHc`2uvk{pUIDBtLq;WYs&s!6;@zxPF?uVzZbbp_J3xVuDZf|=YL&{$) z@N(mtz))^3h=idGXOV%$^DiK>wpK9UIJku7sF$w(lwe)6!pzRfpf$kq6t?w302bKa z{Q592>q3hS01q-PZ8mt+6cpRB8AW?kMMhbxtXpgIZga0E-$K||4aek@9jsLlrM#^B zYH!Mn>E8e^EBZ`;C{cQ~<52ZL#R$&fvMdnkUcz4r5NPdDNH-L}dtACe)q0B2vaZ%~Eom#PPdm7?;P;Toyj*OJ zlIakWxjt>r9x7|zSe;*)n;2gaOPsF-a`;ztT_=~_h&=!*+&Z_&X!jZKVJUC59?pLMlbLk;U@`FT*J#F^+jQ=@sens%84Sb zk;1>0(d11+9L?CUiJ3*Dfs0=41P6n7tFGv|x^iVPVHvd^SQ|SGM6@LUgXis*K3^iR z8n+BkfM=AMhK^AaU8WM+vo$Qz_dQqsIFPpp|MK29W<|*yyP+yV@H143n7bQ(RiwlR z%@k5pMkeXAir2JdLb{)o0P(y z!v(Qm-XnM&5>=^d3<2=7fZ)quh}3K3+UdTS(T+@=?)~O{K`nUD;_e4zHOls?gv!P-z#PjedHZ)2?7NLrw$WbCP2yJCstla9Y+>b>M~eDO5bn{&0PztGTA9#c z)x)>*(o=1fU*P~&^w#_!vkkt(rmIaud0zBy;DK{8!2dE6A3chNTS zqKogWYHXc^)>&_)t{hZAia(TO{4KlXErK2Fm!M-USUSeXkqFqXdZCko#&r?w3@M;! zbV{IKdY^IW?S4XB(t0jv(GDke iGlXBS`PGW1Ffvp*I4v=GsDw4YgV>`SZJ*g(jr|Y6r?nRV diff --git a/icons/mob/human_races/cyberlimbs/hesphaistos.dmi b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi index 225b18f5b9cf32ed5839d49c3ae5c441281d1383..7e075269a42fd5f7e3f3aaa18f8e83b4db892bf7 100644 GIT binary patch literal 4054 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 F{s|TOg_8gP literal 1431 zcmYjQc~H^`6vk^kveCq3HAk}0RoA>|OEZrp$ukf|$r_>YKvD5Xb2Jsy4ocHJ%P|ef zlrArlO7Wo7O>LDdJXu4#yv-yjap1R5GfnT0cYJT&``&vq@3KG2bGw$276=5|?(O9f z00Jq=UC@k%id+lmUSV>B^!LLexm>Qfxp_oHgrm2Oqobo6+&ubRh+m9zDCS7t9n3r* z4G`hLzi<#7Ff}zbHa3>mVX;^o4u?jgi9{j-fv~c&G9U%+ktdW=0#Jb<_m2}qd2shE z_IQd%WODdvQep}zAsz%ut15WarqyGoojp5A(JEc88=tC!o!1`v^Y?QfR7x}=M!G1; z+SNX--fIicE3u+D4#jTh{&+%7NzwtGWVdRzB!Wi@iN`hQy{||kXgObue9(WW(yAe| zo@GMX*?+8g_&VJPnHP8ZA*9#i%CZJVx732ARIFydBm8#m0gdU;9OSdZ+s<;FSIrXf zMS=<83Gx(UvWpK9yuH_J8ocxz1XA_&_V^o{R<%+kxOT%)7a3{*IdaIb83O>!Lc5#k zEm$+dj`y&PuRbOgNy9Dv58D|hm|*#?Ag-`**~D^F&vqUPyXj{+7k4>%45!h3IV^i9bmp~Pm{<3*7hYXgwq5s>ay(18we$6vtm~4JCR-= zn+$O}To$dr2>I}^m)1Yah~8+oskcvEy;FpiL~dfq;|0Y%;n2`gO^GWb$$v0P%E~md z+3`kdp}RR7X2fiw6PhltHeRfgUyL&i3`YKw7)L* z>0AvZyxhz8ykTu!9Cz*#C8Wz?WvIq7dL2x{?--zGD>x#j1fLl-&(W2phbDA?VpkC( zF1ttL()lhkA#)ZB@6P|E_~B4|9Zu@P+8Dg{bC-I>*Ei`XlOFuYLD9-a!ar4=d1aV* zGIya|HMCnSnFkk*DH7N1YcmkfEX;C(vyRWx37BTl$`>fFvlEOJ&})w!Jqcn@bln1p$=?l&TOvb*8GB7Z>f$qO3tMgJ-0V zRr9D7!bG)JOKr_eiE`uk1eFE2l@eLkJ<|85sw?{-NSeP7S>J2 z>B;vPF#Zx{#@)z}j8&$==A@Y?x*q|gtjDgFDq{wF*+X6(QVKrg9a~DSFHM3z+R{lq zW5E}zE2y*Gb}s3F;foTmItM>a4dHv56Q`F{#zbs_r`uBk*ly`QP(rz7x&(E#(sbnt zX-&6#J~qLgs8_ts_gmF0QHt53X;x-^^BJBwkTa#7;A>ZIr@tyAN!w*#Reh)2YF9r& zNT|_IQ1^86AOSUKZE-K06HnEluz+}v{lLDb&d|ZpAESJ~#J3cg+JD*}1^(DKnF_!g LiSlSfoXY(l*;b($ diff --git a/icons/mob/human_races/cyberlimbs/ipc.dmi b/icons/mob/human_races/cyberlimbs/ipc.dmi index 7af14de51fa18a189e0881911fd01ea69f9b1cf0..e1e948f5b5cb37f021123d25116338aeb7655638 100644 GIT binary patch literal 4379 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 delta 1712 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 Ve)0;Qp&tHEB22AJ@J4PA{{@i;!esye delta 1389 zcmYjRc{tPw82&kmP)aJ~NUp+S@eGSKLo<%DLz&09#gai7XSwGmY$+*&n2M&^a^))5 zR-+-r7-~(9Va8dGWZZK&nwh2T>Dl+6_x;{K-tT+fKfWbpj#RcHC}+o15F(+BTg5Kog+s6abhAg+qY0wziLtkAZ;!5{b01 zu!u1LR8>{){R&jTw}Su_3gzzZ?(FQ0Mx%9gb@z(dF}Gcjm~%*105&s(-X6*mP#!Vx z05IA=DmWr0I2;22afMkQUP`qY$)rpUW2JIg#dJooX1dHfJ%zMsu^h>ZG%_|?rs#CN zW;L-Z?PoL?$13@3yR=&{d~axNh(BgbcKXywUSOCSuSctT*zh) zjeCVLh{NRmBg~Ia+tuCXI{`pk$q{aYiYr_wqFrHF$ir2hX*?RZ{GbtHE)){nA<4md z?{F}E8hWX6>Z%6%n#Nnr#*Z;7JC(H9&rS<)BwZW1&5aGy@@!IaW4m?r3iv^`#!Q^r zZ%EOJSJ@2GJJTwWHPn_EtAKF|n5SRDm?{5We^+ZV&5kuGh`R|X!Q-)2GgtU?3THg! zt%)=ajhuIoRx>!#OD*elkssr%%#~d(+;nZ$Cukn1)lc+`DgK0VYIY0HRqw9tvzXBsb^}?h6Ny_tFYkf_*(!Vw)dO!#!QcQCpDQx%UUucKP^+-f$pdwdV5P z6J4||1dm+vo6^TQnX8H?|MJo?lMl^N8kyUT3r)+wdXkM7=0A0|HxfQi2ozL8Gp5WY zocXm$0Su_L7OD4KS|*&z4soO(6#bqLe&=<|E|T+guy*u`-UZ)PsJE6 z25MwpUFoJXInk@hd}HdXesk@`{hW%{<%FiH7psF{pU7Rf9eKrDs4d};C5WK}wb+c% z91gp8EI})GKhZK?&4QAT>cK9tJ47L!L!ytL!;9g&;!kPJD?~&`f^F8jt=ukLN@5>c zp1dQ{Nwgg?-`X8QvCMeh>f5rch#?QwsPP^8nKcQx>;;A-@(Mh|8l;-POMZz+{#}M#tAd zM}BE=&UF04X}}d$;JuXyk_!=cO5;5b-}8-{Mf8_Wv*0fqgfS}x3nu)pMq<=s;x979 z-w2P3)^nFi*4T?;a^J8zN^-n4p8WNq9HYmU$ZA2{2Y!K8EDOJDb|T7^5^vk zyhSIQtBHu}mI1%0xu*|MODKZbk0?l%L`fXTpRN1|~3}{b_ zzP@eK#&eTx?cpJ!`dXB+Sp)4ZJA6HyCLuh*WT^eW6@gNvUZ5H9L(iC@^taa)^BphGXCc`dq^fJj-}Vpl^})(hv? zg874j(S)#MIkCZ??4lmvV!537=N;Z#OsAqq&1N7VKuN5939)Fe|sLV?6 z76#x-oqAsNi4D$H_}CNP`0T-R20%vwZFyeJ`lh(^#8RvMhsiI7a-kwK?Bi?RsTWhw zg94&WowQolz6(doERxQrmZuY+ZIp7Do8f!%>p{EGuw2v9FHGtEvroLXYNU`4jqB#Q tya|)7@hl!ycz*(?Gwrpt^F#lGm8DS34(*jZB#>&`aU2myc(tu>>c9W%pke?3 diff --git a/icons/mob/human_races/cyberlimbs/zenghu.dmi b/icons/mob/human_races/cyberlimbs/zenghu.dmi index 7ee24241b9faccd0a2ee27b65a245ddce179e596..bf5087827706a73ac1bc16432b71db9de3a2cf61 100644 GIT binary patch delta 1267 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 diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 6ed423e2bff8c080ceefff97635e292189e475c3..7bf3f386950307415e7b5f64a2c8fbe09f4bd2b7 100644 GIT binary patch delta 16838 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 delta 16311 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 Qm?s%LUHx3vIVCg!05kZM*8l(j literal 1413 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRStExgGN?cNllZ!G7N;32F7#J$% z^j`4gI;!Zz&25jmF!E1flF*M4{FZm@#T0X|3GDrh2Ryk9GTv_A zAbLV!JL`_qx#8avdW)z0{xR$GiC6~J6AI7YJ$P95L}P6z|A%`H1#&yN6(lhN3}WpS zJ57sZQ2q9&`peAY zA`6(RV-Hlz3e95+OVZzV=jZ(^D%N=D^zTa$rZk^`VSO;^V4IlasCL?tFojtqI_MXbk zWFO}Pnu!lKaD(Fi@*hUQ%O+d-6nncmc9zOreR?$}XsvhG_NUKuPwqcRyd(Rne%*e%tvRy~#BkNunp*!1x_{8as$S{XGu;Nu z|3zh;Iq|M8Tb88#$edj1`%k?+=$V(Ks^a~7+cujE#)s-2So_XbId`Sd0r`f^(qX9V%D+;EuUiFGFbmupLM@oOAEJ3{W+iO zrxyE)xoK%V8I;mn)eIcqyD)K=V&P@266}r6jQop8t_s+Eq^UEgd+oYel_UgehlMOmDe*U@+Eyv$AA6|PyEq+JRkKUe- z;cRB|KNdXGJ#hHT!Lq92MEROHeWfIq(A1g#YUWwKyYlR8rnk<7l!oxk+1nY??wY!> zy>EW2>6$42W@+TVqU8>&<7az6Tljvv+ga9#lQU+-2LHFvF<@cZcUHP+~gCTUyxm2@jz;czr)78&qol`;+0PS&dKmY&$ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 882a692877335a843b24ca97f90423fb0a68d992..09828580c6220792d93de9172188201ff7dfcd5f 100644 GIT binary patch delta 3462 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 delta 3141 zcmZuzX*`rs7k?y689QT*M$}7EL`j)pNVHg5D2%c1Yu0QJS)#>KBqmKml5He3%vh>P zlvI?1TOk@81?@JE18S{3X#5vCdnaGxbC57ve4;=|-Li##N^ zzojT1yfj|nubN}xfAxsLnA<`cOUe;_#yZHLX`vJe5fjVhg9fy_@erF-aXhJz#-8`Mq2o2 zTG?R#$5XmlvBa~YsDOk3Nrn%#Tz*48C|yNnSo@S8|fCpWk~bRpwJ?C(dW}XrT}7ZBPltE%|agB-32E%SX59 zt6zHyM)9fqgL2pU!5mBVh+79KDOwW38J>E3B004*s@U^^KM)z!d!tdLTub$aD|*{1 zQj`ViRgtdT1Lr2^sZFIMZV7rlNEu|zwl z_FW;OvU{EUta5O*%c6xmCo$^ zVY?hPY%%;8o8eD?*e=iQsV19(;;M5*WPy!}JVdmx{|E_d= zd%5M*p4bZ2cGl@{VV;gzdj98Tvph0mI!iZ6g3>}I-6uNZ-~1AHU6l2W+gR*FTH4r% zlVOraUcFr8N1B_P_bvY&&&D{yolG(^GP*(``*~-cprN3InwpxPGQY5-q@+R?Un)-t z=>+~6qt=s zDZj09oMkAShJ^86VL13C5|=a0WFBR2@9ZQ>?oCUjEu?FAzlsvJBMSk}Jrkoj>PLKe zh*QlTh8lnc`~V8swTaikSxU9oAO02{nOP-^1q~!5rbxupe*ZKzE1qdZHF(zU%PiVX z1~rGaiI?9eNs+pCYiZ9N@<7Y2`V-aG>`6?>=<25J)^C0xvEfze%)TW%G+O))nXjsE zFCed^WM)*HJ`&t{SN1RfY{skf_Vzw0Dnjaj1!O#mwAj4;WobF+V2X9QbT4w$0-oJx ze^~ipYHx+ikgPx%6XmenFiFCtXItD8=&rFJ@b2UuEg+lYl6bOs&*MUYW6!>Ol-QbB z2%m{s`D0vwKy!Tb6h4lJ>Fev8*yWM%V7;ovA&jGuq-4+ByJY^$$K++;SaC+EJP60y zU|y;O0w%>`08j4B+DDp7!B*4!{&$2z2+)K6uJ?`#NO^P+DWz?+=a5LVq>dyHfQ9J%F_gVTp zRN^1E6eS>nXL;o#bN2mdW=l!|IvmOglCAn4F{|4n?xsZBcMTF>QIR#|tN-3heLJqlV=d zU#VK~^eJ!3{T_hhPlCdO|ExM5&UDe@QG4JB)KGoTU3J`>aQ{Yu6jRCU&c+{nCL*fK zG0p)R6&itjFttj__pY`)QUJhkFyU9fnhKb$^mEItUY6umnP7UeS=rm$8vq6a?KkXm z9u*gt+y+D{}BD%yFD?24l;i zvL-|j9+ee=3MDzyid8k58C0Tu(3!~fBPV-77vm}#7JaZ4R>u#|L05tYz|99 z5WxCb?hl+sK-AyNjL`Gkre%H|MB!~Ft+CqFxs7=WFH{o zGv5P@87iXokc_jAFOMx1Xr6TWS+{+uMkUafm3QB29QSqtND{44*$zGO(qrb`?7oqK zfyvGdnoBaNCmZ`vvwC}kek|TgSc$g%E-M(-eUh|;`L!bz&~NN`0^d9{xzyJ!7jc9> zKQXn=bq(P*$Etn;HN-t*bQSqs5L@Ch(Tsp&IyZ8w`U$3N!~uaOMdRxe%iju5NZnIA zg$v`-?`VB7$5a}Q5SQb9d|aRH%IT}+fByn?=C`Mh(nTRWnhd42Hn3>faFwJ zxZ5o-ofah4Uduej(zq$DoZ6Kb-TZH`{H8%EM#M?C{LZR4z_wdxGLd^<8`~Z7d&PlP zg1?=4uGa1E&l?SaL%07-M@Arebu`Y^mU{I6KE^*5|r=jR^Tz;k&V&*||N z)pRIZj0Zu|)U}F;>mhWs!iQ!NIm+@hS(vMzj$d!Q{I^^;;>^~uZ>XjWW-VmKap!Uc z$m*_5WSox{jIDIuiCI(pI=tg`BfXFY2A;WgqMGn!0aTYtE~K?9un@eY<;$PFsrHg{ zLBm3nE%s^^kmqu)bdRlINZWl4ub?@EjWgH4n~8oJz;kxt`dHJUXO+L5d&Wz%;YHzz zbN1tFZ0aSLALp{SRGO%)M`A7&N!+p|q~@tw=%x_W_*Y zzc##sxN0@?ermzk#;P5$WrNF7ZHxHzdK0)y+v&AI1br!su3MH_Z(V=6R)A2E0iR8L zYDfb9BcjT4pSuM|9HuT$={Qqc7J0`Ci|AS{Ls1lpVI&(*`N{H$Y7Dc}4+@V%yCB%^Cl9%-8^nq-|aFs$B7n P0B>2HwKm5iU2p#v33DTR diff --git a/maps/polaris-1.dmm b/maps/polaris-1.dmm index 577a86287d9..d99aa801ea1 100644 --- a/maps/polaris-1.dmm +++ b/maps/polaris-1.dmm @@ -5374,7 +5374,7 @@ "bZr" = (/obj/structure/table/woodentable,/obj/machinery/computer/skills,/obj/item/weapon/hand_tele,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bZs" = (/obj/machinery/door/window/southright{name = "Captain's Desk Door"; req_access = list(20)},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bZt" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/folder/blue,/obj/item/weapon/pen,/obj/item/device/megaphone,/obj/machinery/requests_console{announcementConsole = 1; department = "Captain's Desk"; departmentType = 5; name = "Captain RC"; pixel_x = 30; pixel_y = 0},/obj/structure/window/reinforced,/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bZu" = (/obj/structure/bed/chair,/obj/effect/landmark/start{name = "Assistant"},/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) +"bZu" = (/obj/machinery/recharge_station,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/recreation_area_restroom) "bZv" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) "bZw" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) "bZx" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/space) @@ -5432,8 +5432,8 @@ "cax" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) "cay" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "caz" = (/obj/structure/filingcabinet,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) -"caA" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor,/area/maintenance/central) -"caB" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/machinery/camera/network/civilian{c_tag = "CIV - Cafeteria Port"; dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) +"caA" = (/obj/machinery/recharge_station,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) +"caB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/light/small{dir = 4},/turf/simulated/floor,/area/maintenance/central) "caC" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) "caD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) "caE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) @@ -5472,6 +5472,7 @@ "cbl" = (/turf/simulated/floor/tiled/hydro,/area/rnd/xenobiology/xenoflora_storage) "cbm" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/tiled/hydro,/area/rnd/xenobiology/xenoflora_storage) "cbn" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/obj/machinery/light,/turf/simulated/floor/tiled/hydro,/area/rnd/xenobiology/xenoflora_storage) +"cbo" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/command{c_tag = "EVA - Fore"},/obj/structure/table/rack,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) "cbp" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/effect/floor_decal/industrial/warning{dir = 9},/obj/item/device/radio/intercom{layer = 4; name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/tiled/white,/area/rnd/xenobiology/xenoflora) "cbq" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/effect/floor_decal/industrial/warning{dir = 5},/obj/machinery/light,/turf/simulated/floor/tiled/white,/area/rnd/xenobiology/xenoflora) "cbr" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/tiled/white,/area/rnd/xenobiology/xenoflora) @@ -5513,7 +5514,7 @@ "ccb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) "ccc" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) "ccd" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/central_two) -"cce" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) +"cce" = (/obj/machinery/recharge_station,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled/neutral,/area/crew_quarters/cafeteria) "ccf" = (/obj/effect/floor_decal/corner/pink{dir = 9},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) "ccg" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/corner/pink{dir = 6},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) "cch" = (/obj/effect/floor_decal/corner/pink/full,/obj/machinery/computer/med_data/laptop,/obj/structure/table/glass,/obj/machinery/light,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/white,/area/medical/patient_e) @@ -6710,7 +6711,7 @@ "czc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/maintenance/engineering) "czd" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/requests_console{department = "EVA"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/tiled,/area/ai_monitored/storage/eva) "cze" = (/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) -"czf" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/command{c_tag = "EVA - Fore"},/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) +"czf" = (/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable,/obj/structure/table/steel_reinforced,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/turf/simulated/floor/tiled,/area/engineering/engine_eva) "czg" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/dark,/area/ai_monitored/storage/eva) "czh" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/tiled,/area/ai_monitored/storage/eva) "czi" = (/turf/simulated/wall,/area/maintenance/evahallway) @@ -6931,6 +6932,7 @@ "cDp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "cDq" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar) "cDr" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"cDs" = (/obj/machinery/recharge_station,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled,/area/crew_quarters/cafeteria) "cDt" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3) "cDu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3) "cDv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3) @@ -8249,7 +8251,6 @@ "dcI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/engineering/engine_eva) "dcJ" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/obj/machinery/meter,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; dir = 1; icon_state = "pdoor0"; id = "atmoslockdown"; name = "Atmospherics Lockdown"; opacity = 0},/turf/simulated/floor,/area/engineering/workshop) "dcK" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/tank/jetpack/carbondioxide,/obj/machinery/door/window/southright{name = "Jetpack Storage"; req_one_access = list(11,24)},/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/engineering/engine_eva) -"dcL" = (/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable,/obj/structure/table/steel_reinforced,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/tiled,/area/engineering/engine_eva) "dcM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access = null; req_one_access = list(12,47)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/maintenance/engineering) "dcN" = (/obj/structure/closet,/obj/item/weapon/lipstick/purple,/turf/simulated/floor/plating,/area/maintenance/engineering) "dcO" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/engineering) @@ -9653,7 +9654,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaMWaMWaOpaOqaOraOsaOtaOuaMWaJJaLUaOvaOwaOwaOxaOyaOzaOAaOBaOCaODaOEaOFaMdaOGaOHaKSaOIaOJaOKaOLaOMaFaaONaOOaOPaLmaLmaOQaLmaORaFhaOSaOTaOTaOUaFaaFaaOVaFaaFaaahaahaahatNatNaNIatNaahaNJaOWaOXaOYaOZaOXaPaaxlaxmawnaJjaJkaPbaPcaJkaKuaFoahyaCjaPdaPeaGDaPfaPgaLGaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaHZaPhaLIaIcaPiaPjaPkaPlaPlaPmaPnaPoaPlaPpaPqaPraPsaJAaKBaKCaKCaKCaKCaKCaKCaKCaKDaGRaJEaDtaPtaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaMWaMWaMWaPuaPvaPwaPuaPuaMWaJJaKIaPxaKIaKIaKIaPyaPzaPAaPBaPCaPDaJQaKVaPEaPFaPFaPFaPGaPHaPIaPJaPKaPLaPMaPNaPOaPNaPPaPQaPNaPRaPSaPTaPUaPVaPWaFaaPXaPYaPZaFaaahaahaahaahatNaHNatNaahaNJaQaaOXaQbaQcaQdaQeaQfaQgaQhaKraJkaQiaJmaJnaQjaFoahyaCjaPdaCjaGDaGDaGDaGDaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaJqaKvaLIaIcaQkaQlaQmaQnaQnaQoaQnaQnaQpaQqaQraLQaQsaJAaKBaKCaKCaKCaKCaKCaKCaKCaKDaGRaKEaDtaOoaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaMWaMWaMWaMWaMWaMWaMWaMWaJJaJJaPxaKIaQtaQuaQvaLXaQwaQxaQyaQzaJQaQAaQBaQCaKSaQCaQDaQEaFhaFhaFhaFhaQFaLgaQGaQHaQHaMtaLmaQIaQJaPNaPPaQKaQLaFaaQMaPYaQNaFaaahaahaahaahatNaHNatNaahaNJaNJaQOaOXaQPaQQaNPawnaxmaQRaFoaJkaJkaHVaQSaFoaFoahyaCjaPdaCjaahaahaGDaQTaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaJqaQUaQVaDraQWaClaQnaQnaQXaQYaQZaQnaQnaRaaQnaQnaRbaJAaRcaRdaRdaRdaRdaRdaRdaRdaReaGRaJEaDtaFJaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahahyaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaahaahaahaahaahaMWaMWaMWaMWaMWaMWaMWaJJaRgaRhaRgaRgaJJaJJaJJaJJaJJaJJaJJaRiaRiaRiaRjaRkaRjaRiaRiaRiaahaahaFhaFhaRlaRmaRnaRoaRpaRqaRraPSaPTaRsaRtaRuaFhaFaaFaaRvaFaaahaahaahatNatNaHNatNaahaahaNJaNJaRwaRxaRyaPaawnaxmaRzaFoaRAaRBaGCaFoaFoahyahyaCjaPdaCjaahaahaGDaHXaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaLHaIaaLIaIcaRCaClaRDaREaRFaRGaQZaQnaRHaRGaRIaQnaRbaRJaRKaRKaRKaRKaRKaRKaRKaRKaRKaRLaGRaRMaRNaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahahyaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaRfaahaahaahaahaahaMWaMWaMWaMWaMWaMWaMWaJJaRgaRhaRgaRgaJJaJJaJJaJJaJJaJJaJJaRiaRiaRiaRjaRkaRjaRiaRiaRiaahaahaFhaFhaRlaRmaRnaRoaRpaRqaRraPSaPTaRsaRtaRuaFhaFaaFaaRvaFaaahaahaahatNatNaHNatNaahaahaNJaNJaRwaRxaRyaPaawnaxmaRzaFoaRAaRBaGCaFoaFoahyahyaCjaPdaCjaahaahaGDaHXaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaLHaIaaLIaIcaRCaClbZuaREaRFaRGaQZaQnaRHaRGaRIaQnaRbaRJaRKaRKaRKaRKaRKaRKaRKaRKaRKaRLaGRaRMaRNaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaROaRPaRPaRPaRPaRPaRPaRPaRPaRPaRQaRfaahaahaahaahaahaahaahaahaahaahaahaahaahaRgaRRaRSaRTahyahyahyahyahyahyahyahyahyaRUaRVaRVaRVaRUahyahyaahaahaahaFhaFhaRWaRXaRXaRYaFhaFhaFhaFhaFhaFhaFhaFhaahaFaaRZaFaaahaahaahatNaSaaSbatNaahaahahyaNJaNJaNJaNJaNJaScaSdawnaFoaFoaFoaFoaFoahyahyahyaCjaPdaCjaCjaahaGDaGDaGEaGFaGFaGFaSeaGFaGFaGFaGFaGHaGDaGIaSfaGKaGLaClaQnaQnaSgaShaSiaSjaSkaSlaSmaSjaRbaSnaGRaGRaGRaGRaGRaGRaGRaGRaGRaGRaGRaDtaFJaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaROaRPaSoaSpaSqaSraSsaStaSoaSuaSvaSwaRfaahaahaahaahaahaahaahaahaahaSxaSxaSxaSxaSxaSyaSzaRTahyahyahyahyahyahyahyahyahyaSAaSBaSCaSDaSAahyahyaahaahaahaahahyahyahyahyahyahyahyahyahyahyahyaahaahaahaFaaFaaFaaahaahaahatNaSEaSFatNaahaahahyahyahyahyahyaSGawnaxmawnaSGahyahyahyahyahyahyahyaCjaSHaSIaCjaahaahahyahyahyahyahyahyahyahyahyahyahyaDoaFqaSJaFsaFtaClaRDaSKaSLaSMaSNaQnaRHaSOaRIaQnaSPaGRaFCaSQaSRaFFaSSaFFaSTaSQaFCaSUaEvaDtaOoaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGazGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSVaSWaSXaSXaSXaSXaSXaSXaSXaSYaSvaSwaRfaahaahaahaahaahaahaahaahaahaSxaSZaTaaTbaTcaTdaTeaRTahyahyahyaTfaTgaThaTiaTfahyaTjaTkaTlaTkaTjahyahyaahaahaahaahaahahyahyahyahyahyahyahyahyahyahyahyaahaahaahaahaahaahaahaahatNaHNaTmatNaahaahahyahyahyahyahyaTnawnaxmawnaTnahyaToaTpaTqaTraToahyaCjaPdaDnaCjaahaahahyahyahyahyahyahyahyahyahyahyahyaEpaTsaLIaIcaKwaClaQnaQnaQnaQnaQnaQnaQnaQnaQnaQnaEvaEvaEvaEvaEvaEvaEvaEvaEvaEvaEvaEvaEvaTtaOoaDtaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9701,9 +9702,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahbLkbNebNfbNgbUhbNgbNfbNebLkahyahyaahaahbtHbtHbIibtHbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbUibUjbUkbUlbSEbUmbUnbUnbUobUpbUqbUrbUsbUtbUubUvbUwbUxbSLbUybUzbUAbUBbUBbUybUzbUybUCbUDbUEahyahybKdbecbcnaZzbUFahybUGbUHbUIbUJbUKbULbULbUMbUGbUNbUObUPbNCbNCbUQbNCbNCbNCbNCbNCbNCaahaZdaZHbURbUSbUTbUUbUVbUWbUWbUWbUWbUWbUXbUYbTkbTlbUZbVabVbbVcbTkbTlbVdbVeaUvaUvbVfbVgbdvaUvbVhaToahybMkbVibVjbVkbVlbVmbVnbVobVpbVqbVrbVsbMpbKNbKNbKSbKSbKSbKSbKSbTJbVtbVubVvbVwbVxbVybVzbVAbVBbVCbSpbVDbVEbVFbVGbVGbVHbSqbVIbVJbSubVKbVLbVMbSuaahaahbSxbVNbVObSxaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahbLkbLlbVPbVQbVRbVSbVTbLmbLkahyaahaahaahaahbtHbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbVUbVVbVWbVXbVYbVZbWabWbbWcbWdbWebWfbWgbWhbWibWibWjbWkbSLbWlbWmbWlbWnbUBbWlbWmbWlbUCbUDbUEahyahybKdbWobcnaZzbamahybWpbWqbULbWrbWsbWsbWtbWubUGbWvbWwbUPbWxbWybWzbWAbWBbWCbWDbWEbNCaahaZdbWFbWGbWHbWIbWJbWKbWLbWKbWKbWKbWLbWMbWJbTlbTkbWNbWObVabWPbTlbTkbWQbURbPObPPaTobHCblDbHCaToaToahybMkbWRbWSbMkbWRbWSbMkbMkbMkbWTbWUbWVbWWbKNaahaahaahaahaahaahbTJbWXbWYbWZbTNbXabXbbTQbXcbXdbXebSpbXfbXgbXhbXibXjbXkbSqbXlbXmbXnbXobXpbSubSuaahaahbSxbXqbXrbSxbSxaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahahyahybXsbXtbXubXvbXsahyahyahyaahaahaahaahbtHbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbXwbXxbXybXzbXAbXBbXCbXDbXEbXFbXGbXHbXIbXJbXKbXLbXMbXNbSLbXObUBbUBbXPbXQbXRbXRbXRbXSbXTbUEahyahybXUbXVbhqbXWbamahybXXbXYbXZbYabYbbYcbYdbYebYfbYgbYhbYibYjbYjbYkbYlbYmbYnbYnbYobNCaahaZdbYpbURbYqbTkbTlbWJbYrbWJbYrbWJbYrbWJbYsbTkbTlbUZbYtbVbbVcbTkbTlbYubURahyahyaTobYvbetbYwaToahyahyahyahyahyahyahyahyahyahybKNbKNbYxbYybKNbKNaahaahaahaahaahaahbTJbTJbTJbTJbTJbYzbYAbSpbSpbSpbSpbSpbSqbSqbSqbSqbSqbSqbSqbYBbYCbSubSubSubSuaahaahaahbSxbYDbVObYEbSxaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahybYFbYGbYHbYIbYFahyahyahyaahaahaahaahbtHbYJbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbYKbYLbYMbYNbYObYPbXMbYQbYRbYSbYTbYUbYRbYQbXMbXMbXMbYVbSLbWlbWmbWlbYWbUBbWlbWmbWlbYXbYYbUEbYZbZabeebecbDMbZbbamahybZcbZdbZebZfbZgbZhbZibZjbUGbWvbZkbZlbZmbZnbZobZpbZqbZrbZsbZtbNCaahaZdbYpbURbURbZubTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbZvbTjbZwbTlbTkbTjbZybZxahybJeaUvbetaUvbJeahyahyahyahyahyahyahyahyahyahyahybZzbZAbZBbZzaahaahaahaahaahaahaahbZCbZDbZEbZFbZGbTObTPbZHbZIbZJbZKbZLaahaahaahaahaahaahbZMbZNbZObZPbZQbZMaahaahaahaahbSxbZRbZSbZTbSxaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahybZUbZVbZWbZUbZUahyahyaahaahaahaahaahbZXbZYbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbZZcaacabcacbSEcadcaecaecaecafcagcahcaicaecaecaecajcakbSLbUybUybUybUBbUBbUybUybUybYXcalcamcanbecbecbecbcnaZzbamahycaocapbZecaqcarcarcasbULbUGbWvcatcaucavcavcawcaxcaybYnbYncazbNCaahaZdbYpcaAbURcaBbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkcaCcaDcaEcaFcaGcaHcaIahyahybrGaUvbetcaJbrGahyahyahyahyahyahyahyahyahyahyahycaKcaLcaMcaNaahaahaahaahaahaahaahbZCcaOcaPcaQcaRcaScaTcaUcaVcaWcaXbZLaahaahaahaahaahaahbZMcaYcaZcbacbbbZMaahaahaahaahcbccbdcbecbfcbcaahahyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahycbgcbhcbicbjcbgahyahyaahaahaahaahaahbZXbZYbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEcbkcblcbmcbnbSEbNZcbpcbqcbrcbscbtcbucbvcbwcbxcbycbzcbAbSLcbBcbCbUBbUBbUBbUBcbDbUBcbEcbFcamcancbGcbHbecbcnaZzcbIahybUGcbJcbKcbLcbMbULcbNbUGcbOcbPcbQcbObNCcbRcbScbTcbUcbVcbWcbXbNCaahaZdbYpaZGbURccebTkbYsbTmbTnbTkbTlbTkcbZbTmbTlbTkbTlccabTnccbbTlbTkccccaIahyahybrGccdbgJaUvbrGahyahyahyahyahyahyahyahyahyahyahyccBccfccgcaNaahaahaahaahaahaahaahbZCcchcciccjbZGcckcclbZHccmccnccobZLaahaahaahaahaahaahbZMbZNbZMbZMbZMbZMaahaahaahaahcbcccpccqccrccscctccuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahybYFbYGbYHbYIbYFahyahyahyaahaahaahaahbtHbYJbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbYKbYLbYMbYNbYObYPbXMbYQbYRbYSbYTbYUbYRbYQbXMbXMbXMbYVbSLbWlbWmbWlbYWbUBbWlbWmbWlbYXbYYbUEbYZbZabeebecbDMbZbbamahybZcbZdbZebZfbZgbZhbZibZjbUGbWvbZkbZlbZmbZnbZobZpbZqbZrbZsbZtbNCaahaZdbYpbURcaAbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbZvbTjbZwbTlbTkbTjbZybZxahybJeaUvbetaUvbJeahyahyahyahyahyahyahyahyahyahyahybZzbZAbZBbZzaahaahaahaahaahaahaahbZCbZDbZEbZFbZGbTObTPbZHbZIbZJbZKbZLaahaahaahaahaahaahbZMbZNbZObZPbZQbZMaahaahaahaahbSxbZRbZSbZTbSxaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahybZUbZVbZWbZUbZUahyahyaahaahaahaahaahbZXbZYbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbZZcaacabcacbSEcadcaecaecaecafcagcahcaicaecaecaecajcakbSLbUybUybUybUBbUBbUybUybUybYXcalcamcanbecbecbecbcnaZzbamahycaocapbZecaqcarcarcasbULbUGbWvcatcaucavcavcawcaxcaybYnbYncazbNCaahaZdcaBaZdccebTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkbTlbTkcaCcaDcaEcaFcaGcaHcaIahyahybrGaUvbetcaJbrGahyahyahyahyahyahyahyahyahyahyahycaKcaLcaMcaNaahaahaahaahaahaahaahbZCcaOcaPcaQcaRcaScaTcaUcaVcaWcaXbZLaahaahaahaahaahaahbZMcaYcaZcbacbbbZMaahaahaahaahcbccbdcbecbfcbcaahahyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahahycbgcbhcbicbjcbgahyahyaahaahaahaahaahbZXbZYbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEcbkcblcbmcbnbSEbNZcbpcbqcbrcbscbtcbucbvcbwcbxcbycbzcbAbSLcbBcbCbUBbUBbUBbUBcbDbUBcbEcbFcamcancbGcbHbecbcnaZzcbIahybUGcbJcbKcbLcbMbULcbNbUGcbOcbPcbQcbObNCcbRcbScbTcbUcbVcbWcbXbNCaahaZdbYpaZdcDsbTlbTkbYsbTmbTnbTkbTlbTkcbZbTmbTlbTkbTlccabTnccbbTlbTkccccaIahyahybrGccdbgJaUvbrGahyahyahyahyahyahyahyahyahyahyahyccBccfccgcaNaahaahaahaahaahaahaahbZCcchcciccjbZGcckcclbZHccmccnccobZLaahaahaahaahaahaahbZMbZNbZMbZMbZMbZMaahaahaahaahcbcccpccqccrccscctccuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahahyahybXsccvccwccxbXsahyahyaahaahaahbZXbZXbZXbZYbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbSEccycczbSEbSEbSLbSLbSLbSLbSLccAbSLbSLbSLccEccCccDbSLbSLbUEbUEcdPccFccFccGbUEbUEbUEbUEbUEbYZbZabeeccHblnblmbeeahybUGbUGbUGbUGbUGbUGbUGbUGccIccJccKccLbNCbNCccMbNCbNCbNCccNccObNCccPaZdccQaZdbURccRbTlbUZccSbVbbVcccTccUbVbbVaccVccWbUZbVabWOccXbTkbTlcbYcaIahyahybrGaUvbetaUvbvNahyahyahyahyahyahyahyahyahyahyahyccBccYccZcaNaahaahaahaahaahaahaahbZCbZCbZCbZCbZCcdacdbbZLbZLbZLbZLbZLaahaahaahaahaahaahbZMbZNbZMaahaahaahaahaahaahaahcbccdccddcdecdfcdgcdhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahahyahybYFcdiccwcdjbYFahyahyaahaahaahbZXcdkcdlcdmbZXbZXbZXbZXaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbSEbSEbSEaahaahaahaahbZXcdncdobZXahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyaZybecbcnaZzcbOcbOcbOcbOcdpcdqcdrcdscdtcducdvcdwcdxcdycdzcdAcdBcdCcdDcbOcbOcbOcbOcbOcdEcdFcdGbURbURbTkccUbVbbYtccVcdHbUZbYtbWObVccdIccUcdJcdKcdLcdMcdNcdOcdSahyahybrGcdQbetcdRaTocaNahyahyahyahyahyahyahyahyahyahycelcdTcdUcaNaahaahaahaahaahaahaahaahaahaahaahbZMcdVcdWbZMaahaahaahaahaahaahaahaahaahaahbZMbZNbZMaahaahcbccbccbccbccbccbccdXcdXcbccbccbccbcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahbZUbVSbVQbZUcdYccwcdZbZUbVSbVQbZUbZUbZXbZXceacebceccedceecefbZXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbZXcegcehceiceiceiceiceiahyahyahyahyahyahyahyahyahyahyahyahyahyahyahyahybaicejbjSaZzcekceLcemcbOcenceocepceocencencenccJccKcencencencdBceqcercescbOcetceLceucevcewcexceycezceAceBceCceDceAceEceAceFceCceBceGceBceCceHceIbTkbTlceJbURahyahybvNaUvbetaUvceKcaNcgqceMceMceMceMceMceMceMceMceNcaNceOcePcaNbZMbZMbZMbZMaahaahaahaahaahbZMbZMbZMceQceRbZMaahaahaahaahaahaahaahaahaahbZMbZMbZNbZMaahaahcbcceSceTceTceTceTceUceUceVceTceTceWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9725,7 +9726,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadcuScuScvgcuUcuScuVcuWcuScuScuScuXcvocuZcuXcvrcvbcuXcvccvdcvecvfcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpjcvNcvhcrFcvicvjcpjcrIcqfcqfcqfcqfcqfcqfcqfcqgcpjcvkcvlcqdcpjcrIcqfcqgcpjcrIcqfcqgcpjcvmcrucrucrGcvncpjcpjahyahyahyahyahycwjcvpcuocrLcrLcrLcrLcrLcuqcvqcwjahyahyahycqvcwqcrOcrPcqycvscqvahyahyahyahyahyahyahyahyahyahyahyahycrQcvtcsYcsYcsYcvucvucvucvucvucsYcsYctbcsYcsYcsYcvvcrQaahaahcrXcvwcvxcvwcrXcrXcvycrXcrXcvzcvAcrZcrZcvBcrZcrZcvCcvDcvCcrZcvEcvFcvEcsacsacvGcsacsacvHcvIcsccsccvJcsccsccvKcvLcvKcscaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMaadaaacxfcvOcvPcvQcvRcvScvTcvUcvVcvWcvXcvYcvZcwacwbcwccuXcpXcpXcpXcpXcpXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahcpjcwdcwecwfcwgcwdcpjahyahyahyahyahyahyahyahyahycpjcwhcwicwhcpjahyahyahyahyahyahyahycxAcqicqicqicwkcqicxAahyahyahyahyahyahycovcuncwlcwmcwncwocuncuncuqcwpcovahyahyahycsKcqycrOcrPcqycqycsKahyahyahyahyahyahyahyahyahyahyahyahycxCcvucvucwrcwscwtcwtcwucwvcwtcwscwwcwxcwycwzcsYcwAcrQaahaahcrXcwBcwCcwDcwDcwDcwEcwFcwGcwHcwIcwJcwKcwLcwMcwNcwMcwOcwPcrZcwQcwRcwScwScwScwTcwUcwVcwWcwXcwYcwZcxacxbcxccxbcxdcxecscaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMaadaaacxNcxgcxgcxgcxgcvScvTcxhcxhcxicuXcxjcxkcxlcxmcxncuXcxocxpcxqcxraahaahaahaahaahcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxscxtcxucxvcxwcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcxxcxycwhahyahyahyahyahyahyahyahycxzcyBcxBczkcxDcyBcxzahyahyahyahyahyahycovcovcxEcxFcxGcxHcxIcxJcxKcovcovahyahyahycumcsScxLcxMcqyctucsOahyahyahyahyahyahyahyahyahyahyahyahyczAcxOcxPcsYcsYcxQcxQcxQcxQcxQcsYcxRcxScxTcxTcxTcxUcrQaahaahcrXcxVcxWcxXcxYcxZcyacybcrXcyccydcrZcyecyfcygcyhcyicyjcykcrZcylcymcyncyocypcyqcyrcsacyscytcsccyucyvcywcyxcyycyzcyAcscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczTcyCcyDcyEcyFcxgcxgcvScyGcyHcyIcyJcyKcyLcyMcyNcyOcyPcuXcxqcxqcxqcxrcxrcxrcxrcxrcxrcxrcyQcyRcyScyScyScyScyScyScyScyScyScyScyScyTcyScyUcyVcyWcyXcyYcyVcyZczaczbczaczaczaczaczaczaczaczaczaczccwhahyahyahyahyahycxzcxzcxzcxzczdczeczfczgczhcxzcxzcxzcxzahyahyahyahycovcovcovcziczjczicovcovcovahyahyahyahyahycvacrOcrPcqycvaahyahyahyahyahyahyahyahyahyahyahyahyahyczZczlcxQcsYcsYcsYcsYczmcsYcsYcsYcxRczncvucvucvuczocrQaahaahcrXcrXcrXcrXcrXcrXcrXcrXcrXczpcuAcrZcrZcrZcrZcrZcrZcrZcrZcrZcsacsacsacsacsacsacsacsacuLczqcsccsccsccsccsccsccsccsccscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczTcyCcyDcyEcyFcxgcxgcvScyGcyHcyIcyJcyKcyLcyMcyNcyOcyPcuXcxqcxqcxqcxrcxrcxrcxrcxrcxrcxrcyQcyRcyScyScyScyScyScyScyScyScyScyScyScyTcyScyUcyVcyWcyXcyYcyVcyZczaczbczaczaczaczaczaczaczaczaczaczccwhahyahyahyahyahycxzcxzcxzcxzczdczecboczgczhcxzcxzcxzcxzahyahyahyahycovcovcovcziczjczicovcovcovahyahyahyahyahycvacrOcrPcqycvaahyahyahyahyahyahyahyahyahyahyahyahyahyczZczlcxQcsYcsYcsYcsYczmcsYcsYcsYcxRczncvucvucvuczocrQaahaahcrXcrXcrXcrXcrXcrXcrXcrXcrXczpcuAcrZcrZcrZcrZcrZcrZcrZcrZcrZcsacsacsacsacsacsacsacsacuLczqcsccsccsccsccsccsccsccsccscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczrczsczrczscztczuczvczwczxczyczzcxgcArczBczCczDczEcuXcuXczFczGczGczGczGczGczGczGczGczGczGczHcxqcxrcxrcxrcxrcxrczIczIczJcxrcxqczKcxqcxrczLczMczNczOczPcwhcwhcwhcwhcwhczQczQczQcwhcwhcwhcwhczRcwhahyahyahyahyahycxzczSczScABczUczVczWczXczYcAIcAacAacxzaahahyahyahyahyaahaahczicAbcziaahaahaahahyahyahyahyahycqvcAccAdcAecqvahyahyahyahyahyahyahyahyahyahyahyahyaahcrQcAfcsYcsYcsYcvucvucsYcvucvucsYcxRczncxOcxPcAgcAhcrQaahaahaahaahaahaahcAicAjcAkcAlcAicAmcAncAocApcAqcBbcAoaahaahaahaahaahaahaahcAscAtcAucAvcAscAwcAxcAycAzcAAcBAcAyaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcACcADcACcAEcAFcxgcxgcvScvTcAGczzcAHcBTcAJcAKcALcAMcuXcxqcANcxqcxqcxrcxrcxrcxrcxrcxrcxrcxrcAOcxrcxraahaahaahcxrcAPcAPcAPcxrcxrcxrcxrcwdcwdcAQcARcAScwdcwdaahaahaahcwhcwhczQcwhcwhaahaahcwhczRcwhaahahyahyahyahycxzcATczecAUcAVczeczeczgcAWcAXczecAYcxzaahahyahyaahaahaahaahczicAZcziaahaahaahcBacCScBccBacqvcqvcBdcBecBfcqvcBgcBgcBgcBgcBgahyahyahyahyahyahyaahaahcrQcBhcvucsYcsYcBicxPcsYcxPcBjcsYcxRczncxOcBkcxOcBlcrQaahaahcAicAicAicAicAicBmcBncBocAiczpcBpcAocBqcBrcBscAocAocAocAocAocAscAscAscAscBtcBucBvcAscBwczqcAycBxcBycBzcAycAycAycAycAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcEBcyCcBBcBCcxgcxgcxgcBDcvTcAGczzcBEcuXcvrcvbcuXcuXcuXcxrcANcBFcxrcxraahaahaahaahaahaahcxrcBGcBHcxraahaahaahcBIcBIcBJcBIcBIaahaahaahaahcwdcBKcxucxvcwdaahaahaahaahaahcwhczQcwhaahaahaahcwhczRcwhaahaahaahahyahycxzcxzcxzcxzcBLcBMcBNcBOcBPcxzcxzcxzcxzaahaahaahaahaahaahaahczicAbczicziczicBacBacBQcBRcBacBScEIcrOcrPcqycBUcBgcBVcBWcBXcBgcBgahyahyahyahyahyaahaahcrQcBYcxPcsYcsYcxQcxQcsYcxQcxQcsYcxRczncxQcxQcxQcwAcrQaahaahcAicBZcCacCbcAicAicCccAicAicCdcvAcAocAocCecAocAocCfcCgcChcAocCicCjcCkcAscAscClcAscAscvHcCmcAycAycCncAycAycCocCpcCqcAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9749,7 +9750,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahbkQcIccIccIccIccIcbkQcZocXIcXJcVDcXKcXLcUMcUNcXMcXMcXNcUOcVEcXOcXPcWFcXQcXRcXScXTcXUcXVcXWcXXcXYcXZcYacYbcYacYccYdcNecYecWacNcdaTcYgcYhcYicYjcYkcVmcRQczQcYlczQczQcYmcYncYocYpcYqcYncYrcYpcYscYtcYucYvcYwcYxcYycYxcYxcYzcYxcYAcYBcYxcYxcYCcYDcYEcYFcYGcYHcYCcYxcYIcYxcYycYJcYKcYxcYxcYxcYLcYxcYMcYNcYycYxcYxcYxcYCcYxcYGcYOcYPcYPcYQcYRcYScYRcYTcYRcYUcYVcYRcYRcYRcYWcYScYRcYXcYScYYcYRcYZcYRcYXcYRcZacYRcYRcZbcYRcYRcZccYUcYRcYRcYRcZdcYRcYRcYScYRcYXcZecZfcXFcZgcXGcZhcZicZjcXGaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahbkQcIccZkcZkcZlcZmdbDdbdcZpcZqcVMcZrcPMcUMcUNcZscZtcZucVGcVHcZvcZqcZwcZxcZycZqcZzcZAcZBcZCcZDcZEcZFcZGcZHcZGcZIcZJcZKcZLcZMcZNcZOcZPcZQcZRcZScZTcVmcRQcwhcwhcZUcwhcZVcZWcZXcWhcZVcZWcZYcWhcZVcZZdaadabdacdaddaddaddaedaddaddafdaddaddaddagdaedahdaidajdakdagdaddajdaddaddaddaedaddaddaddaddaddafdaddaddaddaddaddagdakdajdaldaddaedagdamdamdamdandamdamdaodamdamdamdapdamdamdaqdaodardasdatdaudaqdamdandamdamdaodamdamdamdamdamdamdamdavdamdamdaudamdaqdawdaxdaydazdaAdaBdaCdaDcXGaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahahycIcdaEdaFdaGcNZahycTZdaHdaIdaJdaKcTSdaLcUNdaMdaNdaOcUNcPMdaPcPMdaQcPMcPMdaRdaSdaSdbIdaUdaVdaWdbIdaUdaSdaXdaYdaZdbadbbdbcdbNdbedbfdbgdbNdbedbcdbccRQcwhdbhdbidbjcZVdbkdbldbmcWhdbndbldbocZVcWhdbpcXhdbqdbrdbrdbrdbsdbtdbrdbrdbudbrdbrdbvdbwdbxdbydbzdbAdbBdbCdcedbCdbCdbEdbFdbCdbCdbGdbCdbCdbCdbHdbCdbCdcfdbCdbBdbJdbzdbydbKdbLdbvdbMdbMdcrdbMdbMdbMdbOdbMdbMdbMdbPdbMdbMcWwdbQdbRdbScXEdbTcWwdbMdcrdbMdbMdbUdbMdbVdbMdbMdbMdbVdbMdbMdbMdbMdbWdbMcWwdbWdbXcXFdbYcXGdbZdcadcbcXGaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahbkQcIccZkcZkdccdcddcDdczdcgdchdcidaPcPMcUMdcjdckdcldcmdcndcodcpcTQdcpdcmdcodcqdcJdcsdctdcudcvdcwdcxdcydcxddbdcAdcBdcCddndcEdcFdcGdcHdcIddtdcKdcLdbcdcMcwhdcNdbidcOcZVdcPdcQdcRcWhdcSdcTdcUcZVcWhcWhcWhcWhcXHcXocXocXocXocXocXpdcVcXHcXpdcWdcXdcYdcZddadcXdcWddDdcVcXHcXocXocXocXocXpdcVcXHcXocXocXocXocXpdcVddDddcdddddeddfddgddddddcZncXAddhcZncXzcXAddhcZncXzcXAddhcZncXAddiddjddkddlddmddjddiddPddhcZncXzcXzcXzcXzcXAddhcZncXzcXzcXzcXzcXAddhddPddoddpddqddrddscXGcXGcXGcXGcXGaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahbkQcIccZkcZkdccdcddcDdczdcgdchdcidaPcPMcUMdcjdckdcldcmdcndcodcpcTQdcpdcmdcodcqdcJdcsdctdcudcvdcwdcxdcydcxddbdcAdcBdcCddndcEdcFdcGdcHdcIddtdcKczfdbcdcMcwhdcNdbidcOcZVdcPdcQdcRcWhdcSdcTdcUcZVcWhcWhcWhcWhcXHcXocXocXocXocXocXpdcVcXHcXpdcWdcXdcYdcZddadcXdcWddDdcVcXHcXocXocXocXocXpdcVcXHcXocXocXocXocXpdcVddDddcdddddeddfddgddddddcZncXAddhcZncXzcXAddhcZncXzcXAddhcZncXAddiddjddkddlddmddjddiddPddhcZncXzcXzcXzcXzcXAddhcZncXzcXzcXzcXzcXAddhddPddoddpddqddrddscXGcXGcXGcXGcXGaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahaahbkQcIccIccIccIccIcbkQddWdducXJddvddwcTSddxcPMcUOcVFcVEcPMcPMddyddzcWLddAddBddCdeedcsdcudcudcvdcwddEddEddFddGddHddIdcCddJddKddKddKddLddMddNddNddOdbccRQcwhdekddQddRcZVddSddTddScWhddUddVddUcZVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadeqddXddYddZdeadebdeqdecdecdecdecdecdeddeddeddeddeddeddeddecdecdecdecdecdeWdefdegdehdeidejdeWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfbdeldemdendeodepdfbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfcderdesdetdeuddsaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahbkQcIcdevdevdewcZmdbDdbddexcZqdeydezcVNcUMcPMdcjdclcVHcSHcPMcWLcWLcVIcVJdeAdeBdeCdeDdcudeEdeFdeGdeHdeIdeJdeKdeLdeMdeNddJddKddKdeOdePdeQdeRddKdeSdbccRQcwhahyahyahycZVddSdeTddScWhddUdeUddUcZVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVaaaaaadfhdeXdeYdeZdeadfadfmdecdecdecdecdeddeddeddeddeddeddeddeddeddecdecdecdecdfBdfddegdfedffdfgdfBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfIdfidfjdfkdeodfldfIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfLderdesdfndfoddsaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaahaahahycIcdfpdfqdfrcNZahycTZdfscPMcUMcWLcVIdeydftcZqdfucZqdftcZqdfvcWLcPMcPMdfwdfxdfydfzdcudcudfAdfQdfCdfDdfEddbdfFdfGdfHddndfXdfJdfKdfYdfMdfYdfNdbcdbccRQcwhahyahyahyahyddSdfOddScZVddUdfPddUdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdeVdgwdfRdfSdfTdfUdfVdfWdhgdcWdecdecdecdeddeddeddeddeddeddeddeddeddeddeddecdecdecddcdhudfZdgadgbdgcddcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaddidgddemdgedgfdggddiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaddodghdgidgjdgkddsaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/polaris-2.dmm b/maps/polaris-2.dmm index 0d80ccaad5b..75d5b84a09e 100644 --- a/maps/polaris-2.dmm +++ b/maps/polaris-2.dmm @@ -2148,7 +2148,7 @@ "Pp" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pq" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pr" = (/obj/item/clothing/head/xenos,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"Ps" = (/obj/item/organ/xenos/plasmavessel,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ps" = (/obj/item/organ/internal/xenos/plasmavessel,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pt" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror/raider{pixel_x = -28; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pu" = (/obj/item/clothing/mask/gas/swat{desc = "A close-fitting mask clearly not made for a human face."; name = "\improper alien mask"},/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Pv" = (/obj/item/xenos_claw,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) @@ -2165,8 +2165,8 @@ "PG" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/glasses/thermal/plain/monocle,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PH" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PI" = (/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PJ" = (/obj/item/organ/xenos/eggsac,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) -"PK" = (/obj/item/organ/stack,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PJ" = (/obj/item/organ/internal/xenos/eggsac,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"PK" = (/obj/item/organ/internal/stack,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PL" = (/obj/structure/bed/chair,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "PN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) diff --git a/maps/polaris-5.dmm b/maps/polaris-5.dmm index 93f38d8b153..044e7b33f33 100644 --- a/maps/polaris-5.dmm +++ b/maps/polaris-5.dmm @@ -869,7 +869,7 @@ "qK" = (/obj/machinery/portable_atmospherics/canister/air,/obj/effect/floor_decal/corner/purple{dir = 5},/obj/machinery/atmospherics/unary/vent_pump/on,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway/mid) "qL" = (/turf/simulated/floor/tiled,/area/outpost/research/eva) "qM" = (/obj/effect/floor_decal/corner/purple{dir = 6},/turf/simulated/floor/tiled,/area/outpost/research/eva) -"qN" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/window/westright,/turf/simulated/floor/tiled/dark,/area/outpost/research/eva) +"qN" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/window/westright,/obj/item/device/suit_cooling_unit,/turf/simulated/floor/tiled/dark,/area/outpost/research/eva) "qO" = (/obj/structure/sign/science{desc = "A warning sign which reads 'SCIENCE!'. It has fine print below it reading 'May or may not contain spiders'."},/turf/simulated/wall/r_wall,/area/outpost/research/eva) "qP" = (/obj/machinery/chem_master,/obj/effect/floor_decal/corner/beige/full,/obj/machinery/firealarm{dir = 8; pixel_x = -24; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/outpost/research/analysis) "qQ" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/tiled/white,/area/outpost/research/analysis) @@ -1468,7 +1468,7 @@ "Cl" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/mining_main/eva) "Cm" = (/obj/structure/dispenser/oxygen,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) "Cn" = (/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) -"Co" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/mineral/floor/ignore_mapgen,/area/mine/explored) +"Co" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) "Cp" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/machinery/access_button/airlock_interior{frequency = 1377; master_tag = "mcontrol"; pixel_x = 26; pixel_y = -26; req_access = list(48)},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) "Cq" = (/obj/machinery/door/airlock/external{frequency = 1377; icon_state = "door_locked"; id_tag = "mint"; locked = 1},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) "Cr" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) @@ -1532,14 +1532,14 @@ "Dx" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/outpost/mining_main/south_hall) "Dy" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidplating2"},/area/mine/explored) "Dz" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/turf/simulated/floor/airless{icon_state = "asteroidplating2"},/area/mine/explored) -"DA" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"DA" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/mineral/floor/ignore_mapgen,/area/mine/explored) "DB" = (/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap,/turf/simulated/floor/airless{icon_state = "asteroidplating2"},/area/mine/explored) "DC" = (/turf/space,/area/skipjack_station/mining) "DD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/airless,/area/outpost/research/test_area) "DE" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/outpost/engineering/mining/power) "DF" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/outpost/engineering/mining/power) "DG" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor/tiled,/area/outpost/research/anomaly) -"DH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"DH" = (/obj/machinery/light/small{dir = 4},/turf/simulated/mineral/floor/ignore_mapgen,/area/mine/explored) "DI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor/tiled,/area/outpost/mining_main/north_hall) "DJ" = (/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) "DK" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/effect/landmark{name = "bluespacerift"},/turf/simulated/floor/tiled,/area/outpost/mining_main/south_hall) @@ -1562,11 +1562,11 @@ "Eb" = (/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/outpost/research/toxins_misc_lab) "Ec" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/outpost/research/toxins_misc_lab) "Ed" = (/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/effect/floor_decal/industrial/outline/yellow,/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled,/area/outpost/research/hallway/starboard) -"Ee" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) -"Ef" = (/obj/machinery/atmospherics/binary/pump/on{dir = 4},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) -"Eg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) -"Eh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) -"Ei" = (/obj/machinery/light/small{dir = 4},/turf/simulated/mineral/floor/ignore_mapgen,/area/mine/explored) +"Ee" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"Ef" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"Eg" = (/obj/machinery/atmospherics/binary/pump/on{dir = 4},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"Eh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) +"Ei" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/tiled,/area/outpost/mining_main/eva) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1718,11 +1718,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlumumvIvJvKvLvMAt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlumwbwbwbwcwdwewfwgwhvbvbvbwiununvSvTwjwkwkwkwldldluedloVoVdldldldldlvVvXwmwnwmvXwowpwowqwrmbdlwsdldlxGacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadldlvtwtwuugwvwwwxwxwyvbwzwAwBwCwCwDwEwFwGwkwHwIwldldluedloVoVdldldldlvWvWvWwJwKwLwMwMwMwMwMwMwMwMwMwMwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadldlugwNwOwPwQwRwSwSwTwSwUvtwVwSwWwXwYwZxaxbxcxdxeuououldloVoVdldldlvWvWxfvWvXxgvXwMxhxixjxkxlxmxnxoxowMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlvtxpxqugxrxsxtxtxuvbxvxwxxvbxyxzxAxAxBxCxDxEwlxFktktDLoVoVdlCovWvWxHxIxJxKxLxMwMxNxOxPxQxRxRxRxSxTwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlvtxpxqugxrxsxtxtxuvbxvxwxxvbxyxzxAxAxBxCxDxEwlxFktktDLoVoVdlDAvWvWxHxIxJxKxLxMwMxNxOxPxQxRxRxRxSxTwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlxUxVxVxVxVxVxUxUxUBvxXDIxZyaybybybycycybycycybycqiqiqjoVoVdldlvWydyeyfyfyfygyhyiyjykylymynyoypyqxTwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlxUyrysxVytCgxVyvxUxUywyxyyybybyzyAyByCyDyEyFyGyHyIyIyIoVoVdlyJyJyJyJyKyfyLyMCUwMyOyPDeyRySyTyRyUyUwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlxVyVDixVyXyYxVyZzazbzczdDMybDNzgycycyczhziybybycktktkvoVoVdlyJzjzkyJzlyfyfwnzmwMwMwMwMwMwMwMwMwMwMwMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadldlxVxVznxVxVzoxVzpzqzrzsztzuzvzwzwzxzyzzzAziybzCzBzCzDmboVoVCoyJzEzFzGzHzIzJzKDOzMzNzOzPzQzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadldlxVxVznxVxVzoxVzpzqzrzsztzuzvzwzwzxzyzzzAziybzCzBzCzDmboVoVDAyJzEzFzGzHzIzJzKDOzMzNzOzPzQzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadldlacxVzRzSzTzUzVzWzXzYzZAaAbAcAdAdAeAdAfAgAhybzCkZkZkZmboVoVdlyJDPAjyJzMzMAkAlAkzMAmAnAozQzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlacacxVApAqArAsDQAuAvAwAxAsAyAzAAABACADAEAFAGybzCkZwowpAHoVoVdlyJyJyJyJDRAJAKALAMANAOAPAQzMzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadlacxVxVARxVxVASxVATyZzbAUAVAWzvAXAXAYAZBazhBbybBckZkZkZmboVoVdlaczMBdBdAoAoAoBeBfBfBfBgBhzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1730,16 +1730,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacxVBiBjxVBiBkxVyZ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacxUytDSxVytDSxVBwxUxUBxzUByybybBzBABBBCBDBEycBFBGqiqiqjoVoVdlacaczMzMBHAoBKDFDEAoBLzMzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacxUxVxVxVxVxVxUxUxUBMzczdzeBNBOBOBOBPBPBPBPBPBOBPtWdloVoVoVdldlacaczMzMzMBQBRBQzMzMzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaadmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBSBSBTBTBTBUBVBUBSBSBWBXBYBOBOBZCaBZCbCbCcCdCeCckvoVoVoVdldldlacacacaczMzMzMzMzMacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSCfCfCfCfCfCfDTChCiCjCkClCmDHDAEfEeCpCqCrCsCtCuoVoVdldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSBSCvCfCfCwCfCxCyCzCACBCCCDEgCEDJCnCnCcCFCGCcqjoVoVdldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSCvCfCHCICJCJCKCLDKCNCOCPEhCQCnCnCRBOCSCTBPdloVoVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSCfCfCfCfCfCfDTChCiCjCkClCmEeCoEgEfCpCqCrCsCtCuoVoVdldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSBSCvCfCfCwCfCxCyCzCACBCCCDEhCEDJCnCnCcCFCGCcqjoVoVdldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSCvCfCHCICJCJCKCLDKCNCOCPEiCQCnCnCRBOCSCTBPdloVoVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSBSDUCVCWCVCVCXCYCZDaDbDcDcDdDcDVBOBOdldldloVoVoVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacBSBSDfDgCfCfDhDWDjDkBPCnCnDlDmBOBOdldldloVoVoVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacBSBSBSDnDoDhDpDpCkBPDqDrBOBOBOdldldloVoVoVacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacBSBSBSDhDsDtDuBPBOBOBOdldldldldloVoVdlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacBSBSDvDwDxBOBOacdldldldldldloVoVdlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacoVoVDyoVacacdldldldldldloVoVdldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacoVoVDzoVacacdldldldldldloVoVdlEijWacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacoVoVDzoVacacdldldldldldloVoVdlDHjWacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacoVDBacacacacdldldldldloVoVoVdldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacoVacacacacacdldldldldloVoVdldldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacjWdldldldldldldldldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacdldloVoVoVoVdldldldldldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacdloidldldldldldldldldldldldldlacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa