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 ff03f947e19..a29cbee0465 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -116,11 +116,7 @@ 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"] + 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 @@ -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/damage_organs.dm b/code/__defines/damage_organs.dm index 27a34f10ebe..09931cb622b 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -30,15 +30,15 @@ #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 +#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/__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..5bb4c93bbcf 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 && gender != PLURAL) + 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 && gender != PLURAL) + 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/_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 5c86505da7e..afe5bd01c36 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(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) 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..5a21e6cb407 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -33,20 +33,16 @@ 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 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 1a9d246215e..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.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/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/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..c5ea0bf9a93 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.") @@ -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/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/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 23d00318ea8..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 @@ -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/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/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..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) @@ -943,7 +925,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/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 c1b160c94bd..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.species.flags & NO_BLOOD) + if(!T.should_have_organ(O_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/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 ac5ae8d8c79..bdc6b5ca446 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -104,6 +104,22 @@ 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 + + // 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) ..(user) user << "The charge meter reads: [round(chargepercentage())]%" @@ -200,22 +216,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)) - 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) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 703760ddf0a..83b8614a0e7 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -331,18 +331,16 @@ 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") 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/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/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/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 25320136b92..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)) @@ -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) @@ -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/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/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 282e7bece66..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) @@ -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/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/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/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/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..71b607be180 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,26 +96,35 @@ 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("l_arm") + + if(BP_TORSO) + organ_name = "torso" + if(BP_GROIN) + organ_name = "groin" + if(BP_HEAD) + organ_name = "head" + 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(O_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,50 +346,78 @@ 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") - 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" - - var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis") + limb = BP_R_HAND + third_limb = BP_R_ARM + if("Full Body") + 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 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 == BP_TORSO) + return pref.organ_data[limb] = "amputated" pref.rlimb_data[limb] = null if(second_limb) @@ -397,27 +437,51 @@ 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 == 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[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") + + 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[BP_HEAD] != "cyborg") + user << "You may only select an assisted or synthetic brain if you have a full prosthetic body." + return + organ = "brain" + + 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 list("Normal","Assisted","Mechanical") + 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) @@ -436,6 +500,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 +531,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[O_HEART]) + dat += "
Does not have a circulatory system." + 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." if(current_species.flags & NO_PAIN) 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 6bc9b888459..971d73ed6d3 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -304,50 +304,39 @@ 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(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() - character.underwear = underwear + 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 - 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/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 5610a23f638..51cbe7baa4b 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -99,33 +99,31 @@ 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/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)) sound_strength = "cannot hear" sound = "anything" else switch(body_part) - if("chest") + if(BP_TORSO) 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 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 cc477f0ee7d..53d42c47690 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -96,23 +96,24 @@ /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 +/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 07004f97546..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 @@ -60,7 +59,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 @@ -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 543c3d339f3..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,70 +15,86 @@ attack_verb = list("attacked", "slapped", "whacked") var/mob/living/carbon/brain/brainmob = null -/obj/item/organ/pariah_brain +/obj/item/organ/internal/brain/robotize() + replace_self_with(/obj/item/organ/internal/mmi_holder/posibrain) + +/obj/item/organ/internal/brain/mechassist() + replace_self_with(/obj/item/organ/internal/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/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() @@ -90,16 +106,14 @@ 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." - robotic = 2 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." - robotic = 2 icon = 'icons/obj/wizard.dmi' icon_state = "scroll" 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 20f86d4dde0..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(species && (species.flags & NO_BREATHE) || 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 fd6fd0f6580..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() @@ -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..823ac808ec2 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(BP_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(BP_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..359d60c3e1d 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) @@ -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) @@ -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..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 @@ -207,7 +239,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..c6501aae7c8 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(!(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 if(w_uniform && !skipjumpsuit) @@ -52,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? @@ -123,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" @@ -182,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" @@ -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] @@ -282,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 eef1b952458..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 @@ -654,18 +640,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[O_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 +670,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 +723,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") + var/obj/item/organ/external/head/H = get_organ(BP_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 +802,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,16 +894,15 @@ /mob/living/carbon/human/revive() - if(species && !(species.flags & NO_BLOOD)) + if(should_have_organ(O_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) + 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) @@ -964,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) @@ -1057,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(species.flags & NO_PAIN) + if(!can_feel_pain(organ.organ_tag)) src << "You feel [O] moving inside your [organ.name]." else var/msg = pick( \ @@ -1067,7 +1024,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(O_HEART)) //There is no blood in protheses. organ.status |= ORGAN_BLEEDING src.adjustToxLoss(rand(1,3)) @@ -1169,6 +1126,8 @@ qdel(hud_used) hud_used = new /datum/hud(src) + full_prosthetic = null + if(species) return 1 else @@ -1234,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 @@ -1248,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 @@ -1256,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) @@ -1302,23 +1261,27 @@ /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() - 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 @@ -1423,3 +1386,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(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 + 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_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 377581d09b0..1c3f070b963 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,8 +28,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ("brain")) + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) sponge.take_damage(amount) brainloss = sponge.damage @@ -42,8 +42,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ("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 @@ -56,8 +56,8 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) - var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] + if(should_have_organ("brain")) + var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"] if(sponge) brainloss = min(sponge.damage,maxHealth*2) else @@ -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(O_LUNGS)) oxyloss = 0 return ..() /mob/living/carbon/human/adjustOxyLoss(var/amount) - if(species.flags & NO_BREATHE) + if(!should_have_organ(O_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(O_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(O_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) @@ -345,23 +345,29 @@ 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) 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 +377,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..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 @@ -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)) @@ -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 7ed171a1f1d..78dbee05521 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -82,7 +82,9 @@ var/list/flavor_texts = list() var/gunshot_residue - var/pulling_punches // Are you trying not to hurt your opponent? + 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 ca81defe0f9..ca052edb859 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 @@ -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,11 +38,11 @@ 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 - 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..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() @@ -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. @@ -110,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].") @@ -118,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].") @@ -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..2f0160f35e6 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -40,50 +40,49 @@ 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) 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 97327c4bbdb..971e8c4a6fa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -254,7 +254,8 @@ radiation = Clamp(radiation,0,100) if (radiation) - 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 @@ -274,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) @@ -365,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(species.has_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()) @@ -519,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) @@ -685,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 @@ -831,6 +840,7 @@ return min(1,thermal_protection) /mob/living/carbon/human/handle_chemicals_in_body() + if(in_stasis) return @@ -838,43 +848,48 @@ chem_effects.Cut() analgesic = 0 - if(touching) touching.metabolize() - if(ingested) ingested.metabolize() - if(bloodstr) bloodstr.metabolize() + if(!isSynthetic()) - if(CE_PAINKILLER in chem_effects) - analgesic = chem_effects[CE_PAINKILLER] + if(touching) touching.metabolize() + if(ingested) ingested.metabolize() + if(bloodstr) bloodstr.metabolize() - 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(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) 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. + var/obj/item/organ/internal/diona/node/light_organ = locate() in internal_organs + + 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 +916,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 +936,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 +944,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 +1264,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 +1426,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 +1500,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 +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(species && species.flags & NO_BLOOD) + if(!internal_organs_by_name[O_HEART]) return PULSE_NONE //No blood, no pulse. if(stat == DEAD) @@ -1566,12 +1582,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"] + var/obj/item/organ/internal/heart/H = internal_organs_by_name[O_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 +1750,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..94da4151016 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,14 +44,29 @@ /mob/living/carbon/human/proc/leap ) + has_limbs = list( + 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) @@ -94,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 d6e32722b1d..e19795b6413 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.. @@ -59,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" @@ -85,7 +82,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. @@ -121,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 @@ -159,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) @@ -177,6 +174,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()) ? 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()) ? SYNTH_FLESH_COLOUR : flesh_color) + /datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type) if(!prob(5)) @@ -252,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 fae7d834e5c..23970c61b27 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 @@ -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 d9d8347550c..85890f4de6d 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( + 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) 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..f2277f99211 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 @@ -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 e5b3ae6b0f4..a0365f7cd04 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( + 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 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" @@ -178,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/diona/head), - "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( @@ -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" @@ -248,88 +260,14 @@ 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) - 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_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 1c5e88ce59c..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 @@ -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 @@ -46,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 @@ -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( + 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() return "Xenomorph" @@ -100,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) ..() @@ -160,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( @@ -199,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( @@ -227,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( @@ -259,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 92a6089e9f5..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. 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") + 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,11 +93,14 @@ 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"] - 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)? "." : "!"]" + 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]!") + 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") @@ -111,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 @@ -134,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) @@ -174,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 8fab9318878..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]/[species.blood_color]/[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(species.blood_color, 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/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..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 @@ -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_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/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/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.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/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/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.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 88be25cc245..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,11 +73,11 @@ 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!" - 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 @@ -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_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.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 44303241dbd..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,13 +93,13 @@ 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.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/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 a3f81168b78..5a2076aba44 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(BP_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 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 - 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(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 - preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) + var/icon/limb_icon + if(name in list(BP_TORSO, BP_GROIN, BP_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[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 () + 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/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 ebc490601d3..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(species && species.flags & NO_BLOOD) //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) @@ -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(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 && species.has_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 @@ -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(O_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(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(species.flags & NO_BLOOD) + 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 a330e307a38..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,28 +43,19 @@ qdel(src) //VOX ORGANS. -/obj/item/organ/stack +/obj/item/organ/internal/stack name = "cortical stack" - parent_organ = "head" - robotic = 2 + 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 - -/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 +/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 5165108635e..e0851716780 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -3,45 +3,39 @@ var/list/organ_cache = list() /obj/item/organ name = "organ" icon = 'icons/obj/surgery.dmi' - var/dead_icon - var/mob/living/carbon/human/owner = null - 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? - - 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 + + // Strings. + var/organ_tag = "organ" // Unique identifier. + var/parent_organ = BP_TORSO // Organ holding this object. + + // Status tracking. + 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 // 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 // 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 + + 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 ..() @@ -88,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() @@ -111,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) @@ -189,8 +181,18 @@ 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/remove_rejuv() + qdel(src) + +/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/is_damaged() return damage > 0 @@ -241,19 +243,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,25 +316,13 @@ 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) - - // 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(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 +345,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 == I_HELP && user.zone_sel.selecting == O_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..a8d61416300 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -14,51 +14,61 @@ dir = SOUTH organ_tag = "limb" - var/brute_mod = 1 - var/burn_mod = 1 - - 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/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 + // Strings + 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/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 // 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() // 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 // 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 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 - 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 + /obj/item/organ/external/Destroy() + if(parent && parent.children) parent.children -= src @@ -70,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) @@ -175,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 @@ -188,12 +205,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 +230,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,12 +327,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 - 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() @@ -333,13 +338,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 +350,40 @@ 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[organ_tag] + if(status == "amputated") + remove_rejuv() + else if(status == "cyborg") + var/robodata = owner.client.prefs.rlimb_data[organ_tag] + if(robodata) + robotize(robodata) + else + robotize() + owner.updatehealth() +/obj/item/organ/external/remove_rejuv() + 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 + if(children && children.len) + for(var/obj/item/organ/external/E in children) + E.remove_rejuv() + children.Cut() + 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 @@ -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(O_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(O_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 /obj/effect/decal/cleanable/blood/gibs(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)) @@ -877,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 @@ -891,26 +919,63 @@ 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/skip_prosthetics = 0, var/keep_organs = 0) + + if(status & ORGAN_ROBOT) + return + + + if(status & ORGAN_ROBOT) + return + ..() + 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 + 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. + + 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 + + return 1 /obj/item/organ/external/proc/mutate() if(src.status & ORGAN_ROBOT) @@ -923,7 +988,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) @@ -990,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) @@ -1012,13 +1077,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() @@ -1083,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 @@ -1097,37 +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/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 @@ -1135,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 @@ -1143,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 @@ -1158,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 @@ -1169,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 @@ -1185,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 @@ -1195,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 @@ -1210,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 @@ -1218,11 +1296,18 @@ 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) @@ -1244,3 +1329,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..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,10 +53,10 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner || !owner.species) return - if(owner.species.has_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(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) 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..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,15 +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/proc/update_colour() +/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/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( @@ -79,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 @@ -94,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() ..() @@ -109,7 +161,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() @@ -123,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 @@ -148,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/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..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,27 +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' - unavailable_at_chargen = 1 diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm index edef9801c50..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,29 +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" -/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() + if(status & ORGAN_ROBOT) + return ..() var/mob/living/carbon/human/H = owner ..() if(!istype(H) || !H.organs || !H.organs.len) @@ -147,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" - -/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. + parent_organ = BP_HEAD -/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 fd94c2c7590..db34e58891a 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -1,126 +1,68 @@ -// 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 +/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) 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" +/obj/item/organ/internal/mmi_holder + name = "brain interface" organ_tag = "brain" - parent_organ = "chest" + parent_organ = BP_HEAD vital = 1 var/obj/item/device/mmi/stored_mmi -/obj/item/organ/mmi_holder/proc/update_from_mmi() +/obj/item/organ/internal/mmi_holder/Destroy() + stored_mmi = null + return ..() + +/obj/item/organ/internal/mmi_holder/New(var/mob/living/carbon/human/new_owner, var/internal) + ..(new_owner, internal) if(!stored_mmi) - return + stored_mmi = new(src) + sleep(-1) + update_from_mmi() + +/obj/item/organ/internal/mmi_holder/proc/update_from_mmi() + + if(!stored_mmi.brainmob) + 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) 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(var/mob/living/user) + 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/internal/mmi_holder/removed(var/mob/living/user) if(stored_mmi) stored_mmi.loc = get_turf(src) @@ -133,25 +75,14 @@ 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/internal/mmi_holder/posibrain + name = "positronic brain interface" -/obj/item/organ/mmi_holder/posibrain/New() - robotize() +/obj/item/organ/internal/mmi_holder/posibrain/New() 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 + +/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/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/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/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..3209560007c 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.isSynthetic()) + 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..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,12 +323,12 @@ 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() 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..6c899d831aa 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!" @@ -1762,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 1c4abbdfe83..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) @@ -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/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 19ac8c62fbc..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.species.flags & NO_BLOOD) + 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 25addbd40a4..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]." , \ @@ -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/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 d1becd0cbf9..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) @@ -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) @@ -76,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) @@ -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(O_HEART)) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) @@ -118,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) @@ -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(O_HEART)) affected.status |= ORGAN_BLEEDING affected.createwound(CUT, 1) @@ -198,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) @@ -212,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) @@ -225,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) @@ -248,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) @@ -281,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 f0025b74290..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]." @@ -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 @@ -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.species.has_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 24bc8484722..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( @@ -212,10 +213,10 @@ 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 + return affected.open == 3 && is_organ_damaged begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -225,7 +226,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 +242,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 @@ -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,11 +390,7 @@ 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.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 @@ -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/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/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/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..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.species.flags & NO_BLOOD) + 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 8600c9c26ad..f7a49811cea 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi index 045c3a57249..ce332e9bc4c 100644 Binary files a/icons/mob/human_races/cyberlimbs/bishop.dmi and b/icons/mob/human_races/cyberlimbs/bishop.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/hesphaistos.dmi b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi index 5fbcd158619..7e075269a42 100644 Binary files a/icons/mob/human_races/cyberlimbs/hesphaistos.dmi and b/icons/mob/human_races/cyberlimbs/hesphaistos.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/ipc.dmi b/icons/mob/human_races/cyberlimbs/ipc.dmi index b0ae6739177..e1e948f5b5c 100644 Binary files a/icons/mob/human_races/cyberlimbs/ipc.dmi and b/icons/mob/human_races/cyberlimbs/ipc.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/xion.dmi b/icons/mob/human_races/cyberlimbs/xion.dmi index daf10298c21..e07e66e3e0b 100644 Binary files a/icons/mob/human_races/cyberlimbs/xion.dmi and b/icons/mob/human_races/cyberlimbs/xion.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/zenghu.dmi b/icons/mob/human_races/cyberlimbs/zenghu.dmi index a94eacc48a5..bf508782770 100644 Binary files a/icons/mob/human_races/cyberlimbs/zenghu.dmi and b/icons/mob/human_races/cyberlimbs/zenghu.dmi differ diff --git a/icons/mob/human_races/r_diona.dmi b/icons/mob/human_races/r_diona.dmi index 3215ea8908b..91757faf7ca 100644 Binary files a/icons/mob/human_races/r_diona.dmi and b/icons/mob/human_races/r_diona.dmi differ diff --git a/icons/mob/human_races/r_machine.dmi b/icons/mob/human_races/r_machine.dmi deleted file mode 100644 index 65f66c32385..00000000000 Binary files a/icons/mob/human_races/r_machine.dmi and /dev/null differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 6ed423e2bff..7bf3f386950 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/mob/zone_sel.dmi b/icons/mob/zone_sel.dmi index 25ace3720c7..8b367d480f3 100644 Binary files a/icons/mob/zone_sel.dmi and b/icons/mob/zone_sel.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 882a6928773..09828580c62 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ 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