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