diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm
index ff03f947e1..cffa28a1fc 100644
--- a/code/ZAS/Phoron.dm
+++ b/code/ZAS/Phoron.dm
@@ -116,10 +116,6 @@ obj/var/contaminated = 0
/mob/living/carbon/human/proc/burn_eyes()
- //The proc that handles eye burning.
- if(!species.has_organ["eyes"])
- return
-
var/obj/item/organ/eyes/E = internal_organs_by_name["eyes"]
if(E)
if(prob(20)) src << "Your eyes burn!"
@@ -143,15 +139,15 @@ obj/var/contaminated = 0
//Checks if the suit is adequately sealed.
var/coverage = 0
for(var/obj/item/protection in list(wear_suit, gloves, shoes))
- if(!protection)
+ if(!protection)
continue
if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD))
return 0
coverage |= protection.body_parts_covered
-
+
if(vsc.plc.PHORONGUARD_ONLY)
return 1
-
+
return BIT_TEST_ALL(coverage, UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS)
/mob/living/carbon/human/proc/suit_contamination()
diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 31bdcc9469..3c1be97566 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -23,7 +23,6 @@
#define IS_UNATHI 4
#define IS_TAJARA 5
#define IS_XENOS 6
-#define IS_MACHINE 7
#define CE_STABLE "stable" // Inaprovaline
#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index e204cdb977..9dc9ecd0fd 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 6e2a7fae36..96b50fc6c5 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -29,10 +29,13 @@ proc/random_hair_style(gender, species = "Human")
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
+
+ if(gender != NEUTER)
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+
if( !(species in S.species_allowed))
continue
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
@@ -48,10 +51,13 @@ proc/random_facial_hair_style(gender, species = "Human")
var/list/valid_facialhairstyles = list()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
+
+ if(gender != NEUTER)
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+
if( !(species in S.species_allowed))
continue
@@ -61,12 +67,12 @@ proc/random_facial_hair_style(gender, species = "Human")
f_style = pick(valid_facialhairstyles)
return f_style
-
+
proc/sanitize_name(name, species = "Human")
var/datum/species/current_species
if(species)
current_species = all_species[species]
-
+
return current_species ? current_species.sanitize_name(name) : sanitizeName(name)
proc/random_name(gender, species = "Human")
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 5c86505da7..f748fdd53e 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -222,6 +222,7 @@
locked += L
return
+// TODO.
proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role)
var/icon/preview_icon = null
@@ -258,7 +259,10 @@ proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role)
if(!H.species || H.species.flags & HAS_SKIN_COLOR)
preview_icon.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD)
- var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s")
+ var/use_eye_icon = "eyes_s"
+ var/obj/item/organ/external/head/temp_head = H.get_organ("head")
+ if(temp_head) use_eye_icon = temp_head.eye_icon
+ var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = use_eye_icon)
if (H.species.flags & HAS_EYE_COLOR)
eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD)
diff --git a/code/datums/disease.dm b/code/datums/disease.dm
index 606acdef99..453cd0d8bd 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 1f62065ef9..ecfd2deb81 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 b4f2b1a38a..d6f05d33ef 100644
--- a/code/datums/diseases/appendicitis.dm
+++ b/code/datums/diseases/appendicitis.dm
@@ -33,13 +33,9 @@
affected_mob.adjustToxLoss(1)
if(stage > 2)
if(prob(1))
- if (affected_mob.nutrition > 100)
- var/mob/living/carbon/human/H = affected_mob
- H.vomit()
- else
- affected_mob << "You gag as you want to throw up, but there's nothing in your stomach!"
- affected_mob.Weaken(10)
- affected_mob.adjustToxLoss(3)
+ var/mob/living/carbon/human/H = affected_mob
+ spawn H.vomit()
+
if(stage > 3)
if(prob(1) && ishuman(affected_mob))
var/mob/living/carbon/human/H = affected_mob
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 1a9d246215..f219e1d6c7 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -400,7 +400,7 @@ its easier to just keep the beam vertical.
M.dna.real_name = M.real_name
M.check_dna()
if (M.species)
- blood_color = M.species.blood_color
+ blood_color = M.species.get_blood_colour(M)
. = 1
return 1
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index ce6320cd88..98acc1d335 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 7d5a42e7e8..0c13276f12 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -19,8 +19,8 @@
return
var/mob/living/carbon/human/T = G.affecting
- if(!istype(T))
- src << "[T] is not compatible with our biology."
+ if(!istype(T) || T.isSynthetic())
+ src << "\The [T] is not compatible with our biology."
return
if(T.species.flags & NO_SCAN)
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 465088a06a..f67df60f2a 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 aafcd791e5..760a2d4833 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -162,8 +162,8 @@ var/list/sacrificed = list()
target.adjustBrainLoss(rand(1,5))
initial_message = 1
- if (target.species && (target.species.flags & NO_PAIN))
- target.visible_message("The markings below [target] glow a bloody red.")
+ if (!target.can_feel_pain())
+ target.visible_message("The markings below \the [target] glow a bloody red.")
else
target.visible_message("[target] writhes in pain as the markings below \him glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.")
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index 6cec7149e9..b64508499c 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 af922271d9..64393c2bc4 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -399,9 +399,9 @@
for(var/obj/item/organ/i in occ["internal_organs"])
var/mech = ""
- if(i.robotic == 1)
+ if(i.status & ORGAN_ASSISTED)
mech = "Assisted:"
- if(i.robotic == 2)
+ if(i.status & ORGAN_ROBOT)
mech = "Mechanical:"
var/infection = "None"
diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm
index 23d00318ea..0bb7dd1935 100644
--- a/code/game/machinery/bioprinter.dm
+++ b/code/game/machinery/bioprinter.dm
@@ -41,7 +41,7 @@
var/obj/item/organ/O = new new_organ(get_turf(src))
if(prints_prosthetics)
- O.robotic = 2
+ O.robotize()
else if(loaded_dna)
visible_message("The printer injects the stored DNA into the biomass..")
O.transplant_data = list()
@@ -80,5 +80,5 @@
user << "\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]"
qdel(W)
return
-
+
return..()
\ No newline at end of file
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index a2b2b63325..d3c152fa25 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 857832d2f5..83b6f2ce86 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 d32c7e45ee..c2758a7ffd 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -943,7 +943,7 @@ About the new airlock wires panel:
/mob/living/carbon/airlock_crush(var/crush_damage)
. = ..()
- if (!(species && (species.flags & NO_PAIN)))
+ if(can_feel_pain())
emote("scream")
/mob/living/silicon/robot/airlock_crush(var/crush_damage)
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index c1b160c94b..0fec7a9c1b 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -106,7 +106,7 @@
if(NOCLONE in T.mutations)
return
- if(T.species.flags & NO_BLOOD)
+ if(!T.should_have_organ("heart"))
return
// If the human is losing too much blood, beep.
@@ -165,4 +165,4 @@
/obj/machinery/iv_drip/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(height && istype(mover) && mover.checkpass(PASSTABLE)) //allow bullets, beams, thrown objects, mice, drones, and the like through.
return 1
- return ..()
+ return ..()
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 703760ddf0..d3fe17a068 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -333,16 +333,14 @@
OCCUPANT.apply_effect(50, IRRADIATE)
var/obj/item/organ/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs
if (!rad_organ)
+ if (OCCUPANT.can_feel_pain())
+ OCCUPANT.emote("scream")
if(src.issuperUV)
var/burndamage = rand(28,35)
OCCUPANT.take_organ_damage(0,burndamage)
- if (!(OCCUPANT.species && (OCCUPANT.species.flags & NO_PAIN)))
- OCCUPANT.emote("scream")
else
var/burndamage = rand(6,10)
OCCUPANT.take_organ_damage(0,burndamage)
- if (!(OCCUPANT.species && (OCCUPANT.species.flags & NO_PAIN)))
- OCCUPANT.emote("scream")
if(i==3) //End of the cycle
if(!src.issuperUV)
if(src.HELMET)
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index c70a5ab9fc..250e8f350e 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -102,10 +102,10 @@
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/viruses = list()
- Destroy()
- for(var/datum/disease/D in viruses)
- D.cure(0)
- ..()
+/obj/effect/decal/cleanable/vomit/Destroy()
+ for(var/datum/disease/D in viruses)
+ D.cure(0)
+ return ..()
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 25320136b9..eeed37b9e7 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -465,7 +465,7 @@ var/list/global/slot_flags_enumeration = list(
eyes.damage += rand(3,4)
if(eyes.damage >= eyes.min_bruised_damage)
if(M.stat != 2)
- if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly
+ if(!(eyes.status & ORGAN_ROBOT)) //robot eyes bleeding might be a bit silly
M << "Your eyes start to bleed profusely!"
if(prob(50))
if(M.stat != 2)
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index 65bb1d4ebc..bb4b80c1b8 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -64,10 +64,10 @@
..()
if(isliving(AM))
var/mob/M = AM
-
+
if(M.buckled) //wheelchairs, office chairs, rollerbeds
return
-
+
M << "You step on \the [src]!"
playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
if(ishuman(M))
@@ -78,7 +78,7 @@
if( H.shoes || ( H.wear_suit && (H.wear_suit.body_parts_covered & FEET) ) )
return
-
+
var/list/check = list("l_foot", "r_foot")
while(check.len)
var/picked = pick(check)
@@ -89,7 +89,7 @@
if(affecting.take_damage(5, 0))
H.UpdateDamageIcon()
H.updatehealth()
- if(!(H.species.flags & NO_PAIN))
+ if(affecting.can_feel_pain())
H.Weaken(3)
return
check -= picked
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 282e7bece6..0e1f0dadc3 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -422,14 +422,18 @@
icon_state = "red_crowbar"
item_state = "crowbar_red"
+/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone)
+ if(ishuman(A) && user.a_intent == I_HELP)
+ return
+ return ..()
+
/obj/item/weapon/weldingtool/afterattack(var/mob/M, var/mob/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting]
- if (!S) return
- if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
+ if(!S || !(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
return ..()
if(S.brute_dam)
@@ -438,10 +442,9 @@
user.visible_message("\The [user] patches some dents on \the [M]'s [S.name] with \the [src].")
else if(S.open != 2)
user << "The damage is far too severe to patch over externally."
- return 1
else if(S.open != 2)
user << "Nothing to fix!"
-
+ return
else
return ..()
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 9f8eed2eb5..949cbc1ff6 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -324,7 +324,7 @@
M.emote("scream")
else
var/mob/living/carbon/C = M
- if (!(C.species && (C.species.flags & NO_PAIN)))
+ if (C.can_feel_pain())
C.emote("scream")
//Logging for this causes runtimes resulting in the cremator locking up. Commenting it out until that's figured out.
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index e959c1991b..19302f8d30 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 440cf90e59..0f993b0fca 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 07530881fe..720a3d3c07 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -75,8 +75,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
pref.update_preview_icon()
if(pref.preview_icon_front && pref.preview_icon_side)
- user << browse_rsc(pref.preview_icon_front, "previewicon.png")
- user << browse_rsc(pref.preview_icon_side, "previewicon2.png")
+ user << browse_rsc(pref.preview_icon_front, "preview_icon.png")
+ user << browse_rsc(pref.preview_icon_side, "preview_icon2.png")
var/mob_species = all_species[pref.species]
. += "
Body "
@@ -87,7 +87,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(has_flag(mob_species, HAS_SKIN_TONE))
. += "Skin Tone: [-pref.s_tone + 35]/220 "
. += "Needs Glasses: [pref.disabilities & NEARSIGHTED ? "Yes" : "No"] "
- . += "Limbs: Adjust "
+ . += "Limbs: Adjust Reset "
. += "Internal Organs: Adjust "
//display limbs below
@@ -96,6 +96,13 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/status = pref.organ_data[name]
var/organ_name = null
switch(name)
+
+ if("torso")
+ organ_name = "torso"
+ if("groin")
+ organ_name = "groin"
+ if("head")
+ organ_name = "head"
if("l_arm")
organ_name = "left arm"
if("r_arm")
@@ -116,6 +123,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
organ_name = "heart"
if("eyes")
organ_name = "eyes"
+ if("brain")
+ organ_name = "brain"
if(status == "cyborg")
++ind
@@ -136,7 +145,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
++ind
if(ind > 1)
. += ", "
- . += "\tMechanical [organ_name]"
+ . += "\tSynthetic [organ_name]"
else if(status == "assisted")
++ind
if(ind > 1)
@@ -148,6 +157,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "\tSurgically altered [organ_name]"
if("eyes")
. += "\tRetinal overlayed [organ_name]"
+ if("brain")
+ . += "\tAssisted-interface [organ_name]"
else
. += "\tMechanically assisted [organ_name]"
if(!ind)
@@ -155,7 +166,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
else
. += "
"
- . += " | Preview
 "
+ . += " | Preview
 "
. += " |
"
. += "Hair
"
@@ -252,6 +263,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.b_hair = 0//hex2num(copytext(new_hair, 6, 8))
pref.s_tone = 0
+ reset_limbs() // Safety for species with incompatible manufacturers; easier than trying to do it case by case.
return TOPIC_REFRESH
else if(href_list["hair_color"])
@@ -334,8 +346,12 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.f_style = new_f_style
return TOPIC_REFRESH
+ else if(href_list["reset_limbs"])
+ reset_limbs()
+ return TOPIC_REFRESH
+
else if(href_list["limbs"])
- var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand")
+ var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand","Full Body")
if(!limb_name && !CanUseTopic(user)) return TOPIC_NOACTION
var/limb = null
@@ -366,6 +382,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if("Right Hand")
limb = "r_hand"
third_limb = "r_arm"
+ if("Full Body")
+ limb = "torso"
+
var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis")
if(!new_state && !CanUseTopic(user)) return TOPIC_NOACTION
@@ -378,6 +397,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.organ_data[third_limb] = null
pref.rlimb_data[third_limb] = null
if("Amputated")
+
+ if(limb == "torso")
+ return
+
pref.organ_data[limb] = "amputated"
pref.rlimb_data[limb] = null
if(second_limb)
@@ -397,17 +420,31 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/choice = input(user, "Which manufacturer do you wish to use for this limb?") as null|anything in usable_manufacturers
if(!choice)
return
+
pref.rlimb_data[limb] = choice
pref.organ_data[limb] = "cyborg"
+
if(second_limb)
pref.rlimb_data[second_limb] = choice
pref.organ_data[second_limb] = "cyborg"
if(third_limb && pref.organ_data[third_limb] == "amputated")
pref.organ_data[third_limb] = null
+
+ if(limb == "torso")
+ for(var/other_limb in list("l_foot","r_foot","l_hand","r_hand","l_leg","r_leg","l_arm","r_arm","groin","head"))
+ if(pref.organ_data[other_limb])
+ continue
+ pref.organ_data[other_limb] = "cyborg"
+ pref.rlimb_data[other_limb] = choice
+ if(!pref.organ_data["brain"])
+ pref.organ_data["brain"] = "assisted"
+ for(var/internal_organ in list("heart","eyes"))
+ pref.organ_data[internal_organ] = "mechanical"
+
return TOPIC_REFRESH
else if(href_list["organs"])
- var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
+ var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes", "Brain")
if(!organ_name) return
var/organ = null
@@ -416,12 +453,20 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
organ = "heart"
if("Eyes")
organ = "eyes"
+ if("Brain")
+ if(pref.organ_data["head"] != "cyborg")
+ user << "You may only select an assisted or synthetic brain if you have a full prosthetic body."
+ return
+ organ = "brain"
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical")
if(!new_state) return
switch(new_state)
if("Normal")
+ if(pref.organ_data["torso"] == "cyborg")
+ user << "A character with a synthetic body may only use synthetic organs."
+ return
pref.organ_data[organ] = null
if("Assisted")
pref.organ_data[organ] = "assisted"
@@ -436,6 +481,18 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
return ..()
+/datum/category_item/player_setup_item/general/body/proc/reset_limbs()
+
+ for(var/organ in pref.organ_data)
+ pref.organ_data[organ] = null
+ while(null in pref.organ_data)
+ pref.organ_data -= null
+
+ for(var/organ in pref.rlimb_data)
+ pref.rlimb_data[organ] = null
+ while(null in pref.rlimb_data)
+ pref.rlimb_data -= null
+
/datum/category_item/player_setup_item/general/body/proc/SetSpecies(mob/user)
if(!pref.species_preview || !(pref.species_preview in all_species))
pref.species_preview = "Human"
@@ -455,10 +512,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
dat += "Often present on human stations."
if(current_species.spawn_flags & IS_WHITELISTED)
dat += "Whitelist restricted."
- if(current_species.flags & NO_BLOOD)
- dat += "Does not have blood."
- if(current_species.flags & NO_BREATHE)
- dat += "Does not breathe."
+ if(!current_species.has_organ["heart"])
+ dat += "Does not have a circulatory system."
+ if(!current_species.has_organ["lungs"])
+ dat += "Does not have a respiratory system."
if(current_species.flags & NO_SCAN)
dat += "Does not have DNA."
if(current_species.flags & NO_PAIN)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 6bc9b88845..b4060b221f 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -310,6 +310,8 @@ datum/preferences
var/status = organ_data[name]
var/obj/item/organ/external/O = character.organs_by_name[name]
+ if(name == "torso" && !O)
+ O = character.organs_by_name["chest"]
if(O)
O.status = 0
if(status == "amputated")
@@ -334,20 +336,14 @@ datum/preferences
I.robotize()
character.underwear = underwear
-
character.undershirt = undershirt
-
character.socks = socks
if(backbag > 4 || backbag < 1)
backbag = 1 //Same as above
character.backbag = backbag
- //Debugging report to track down a bug, which randomly assigned the plural gender to people.
- if(character.gender in list(PLURAL, NEUTER))
- if(isliving(src)) //Ghosts get neuter by default
- message_admins("[character] ([character.ckey]) has spawned with their gender as plural or neuter. Please notify coders.")
- character.gender = MALE
+ character.update_body()
/datum/preferences/proc/open_load_dialog(mob/user)
var/dat = ""
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index 5610a23f63..f57b9c9be2 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -99,10 +99,9 @@
var/sound = "heartbeat"
var/sound_strength = "cannot hear"
var/heartbeat = 0
- if(M.species && M.species.has_organ["heart"])
- var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"]
- if(heart && !heart.robotic)
- heartbeat = 1
+ var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"]
+ if(heart && !(heart.status & ORGAN_ROBOT))
+ heartbeat = 1
if(M.stat == DEAD || (M.status_flags&FAKEDEATH))
sound_strength = "cannot hear"
sound = "anything"
@@ -112,7 +111,6 @@
sound_strength = "hear"
sound = "no heartbeat"
if(heartbeat)
- var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"]
if(heart.is_bruised() || M.getOxyLoss() > 50)
sound = "[pick("odd noises in","weak")] heartbeat"
else
diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm
index cc477f0ee7..d237f36b09 100644
--- a/code/modules/mob/language/station.dm
+++ b/code/modules/mob/language/station.dm
@@ -96,13 +96,13 @@
/datum/language/machine
name = "Encoded Audio Language"
- desc = "A language of encoded tones that allow for IPCs to communicate auditorily between each other in a manner that allows for easier transfer of information."
- speech_verb = "beeps"
- ask_verb = "beeps"
- exclaim_verb = "loudly beeps"
+ desc = "A efficient language of encoded tones developed by synthetics and cyborgs."
+ speech_verb = "whistles"
+ ask_verb = "chirps"
+ exclaim_verb = "whistles loudly"
colour = "changeling"
key = "6"
- flags = RESTRICTED | NO_STUTTER
+ flags = NO_STUTTER
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz")
space_chance = 10
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 07004f9754..03de410f5e 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -60,7 +60,7 @@
brainobj = O
brainobj.loc = src
- name = "Man-Machine Interface: [brainmob.real_name]"
+ name = "man-machine interface ([brainmob.real_name])"
icon_state = "mmi_full"
locked = 1
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 543c3d339f..fc1e7778ad 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -15,6 +15,25 @@
attack_verb = list("attacked", "slapped", "whacked")
var/mob/living/carbon/brain/brainmob = null
+
+/obj/item/organ/brain/robotize()
+ replace_self_with(/obj/item/organ/mmi_holder/posibrain)
+
+/obj/item/organ/brain/mechassist()
+ replace_self_with(/obj/item/organ/mmi_holder)
+
+/obj/item/organ/brain/proc/replace_self_with(replace_path)
+ if(!owner)
+ new replace_path(src.loc)
+ qdel(src)
+ return
+ owner.internal_organs_by_name[organ_tag] = new replace_path(owner, 1)
+ owner.internal_organs -= src
+ while(null in owner.internal_organs_by_name)
+ owner.internal_organs_by_name -= null
+ while(null in owner.internal_organs)
+ owner.internal_organs -= null
+
/obj/item/organ/pariah_brain
name = "brain remnants"
desc = "Did someone tread on this? It looks useless for cloning or cyborgification."
@@ -93,13 +112,11 @@
/obj/item/organ/brain/slime
name = "slime core"
desc = "A complex, organic knot of jelly and crystalline particles."
- robotic = 2
icon = 'icons/mob/slimes.dmi'
icon_state = "green slime extract"
/obj/item/organ/brain/golem
name = "chem"
desc = "A tightly furled roll of paper, covered with indecipherable runes."
- robotic = 2
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll"
diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm
index 20f86d4dde..fa87736f26 100644
--- a/code/modules/mob/living/carbon/breathe.dm
+++ b/code/modules/mob/living/carbon/breathe.dm
@@ -7,7 +7,7 @@
/mob/living/carbon/proc/breathe()
//if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
- if(species && (species.flags & NO_BREATHE) || does_not_breathe) return
+ if(!should_have_organ("lungs") || does_not_breathe) return
var/datum/gas_mixture/breath = null
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fd6fd0f658..f0b09f88d6 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -472,3 +472,11 @@
if(!species)
return null
return species.default_language ? all_languages[species.default_language] : null
+
+/mob/living/carbon/proc/should_have_organ(var/organ_check)
+ return 0
+
+/mob/living/carbon/proc/can_feel_pain(var/check_organ)
+ if(isSynthetic())
+ return 0
+ return !(species.flags & NO_PAIN)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/carbon_powers.dm b/code/modules/mob/living/carbon/carbon_powers.dm
index 65fcbc7b17..f1360504ef 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 5f9d7e827c..cf404df6ff 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -157,30 +157,44 @@
return valid_species
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
+
+ var/use_species = species.get_bodytype()
+ var/obj/item/organ/external/head/H = get_organ("head")
+ if(H) use_species = H.species.get_bodytype()
+
var/list/valid_hairstyles = new()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if(check_gender && gender == MALE && S.gender == FEMALE)
- continue
- if(check_gender && gender == FEMALE && S.gender == MALE)
- continue
- if(!(species.get_bodytype() in S.species_allowed))
+ if(check_gender && gender != NEUTER)
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ else if(gender == FEMALE && S.gender == MALE)
+ continue
+
+ if(!(use_species in S.species_allowed))
continue
valid_hairstyles += hairstyle
return valid_hairstyles
/mob/living/carbon/human/proc/generate_valid_facial_hairstyles()
+
+ var/use_species = species.get_bodytype()
+ var/obj/item/organ/external/head/H = get_organ("head")
+ if(H) use_species = H.species.get_bodytype()
+
var/list/valid_facial_hairstyles = new()
for(var/facialhairstyle in facial_hair_styles_list)
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if(!(species.get_bodytype() in S.species_allowed))
+ if(gender != NEUTER)
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ else if(gender == FEMALE && S.gender == MALE)
+ continue
+
+ if(!(use_species in S.species_allowed))
continue
valid_facial_hairstyles += facialhairstyle
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index ff7255523d..a01a8f4ee8 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -15,7 +15,7 @@
I.throw_at(get_edge_target_turf(src,pick(alldirs)), rand(1,3), round(30/I.w_class))
..(species.gibbed_anim)
- gibs(loc, viruses, dna, null, species.flesh_color, species.blood_color)
+ gibs(loc, viruses, dna, null, species.get_flesh_colour(src), species.get_blood_colour(src))
/mob/living/carbon/human/dust()
if(species)
@@ -68,7 +68,7 @@
if(wearing_rig)
wearing_rig.notify_ai("Warning: user death event. Mobility control passed to integrated intelligence system.")
- return ..(gibbed,species.death_message)
+ return ..(gibbed,species.get_death_message(src))
/mob/living/carbon/human/proc/ChangeToHusk()
if(HUSK in mutations) return
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index c1abe448f3..6509943754 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -207,7 +207,7 @@
m_type = 2
if ("deathgasp")
- message = "[species.death_message]"
+ message = "[species.get_death_message()]"
m_type = 1
if ("giggle")
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 07619bff1f..650a72014e 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -38,9 +38,21 @@
CRASH("Gender datum was null; key was '[(skipjumpsuit && skipface) ? PLURAL : gender]'")
msg += "[src.name]"
- if(species.name != "Human")
- msg += ", a [species.name]"
- msg += "!\n"
+
+
+ var/is_synth = isSynthetic()
+ if(is_synth)
+ var/use_gender = "a synthetic"
+ if(gender == MALE)
+ use_gender = "an android"
+ else if(gender == FEMALE)
+ use_gender = "a gynoid"
+
+ msg += ", [use_gender]!"
+
+ else if(species.name != "Human")
+ msg += ", \a [species.name]!"
+ msg += "
"
//uniform
if(w_uniform && !skipjumpsuit)
@@ -230,11 +242,12 @@
if(getBrainLoss() >= 60)
msg += "[T.He] [T.has] a stupid expression on [T.his] face.\n"
- if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD)
+ var/ssd_msg = species.get_ssd(src)
+ if(ssd_msg && (!should_have_organ("brain") || has_brain()) && stat != DEAD)
if(!key)
- msg += "[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.\n"
+ msg += "[T.He] [T.is] [ssd_msg]. It doesn't look like [T.he] [T.is] waking up anytime soon.\n"
else if(!client)
- msg += "[T.He] [T.is] [species.show_ssd].\n"
+ msg += "[T.He] [T.is] [ssd_msg].\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
@@ -261,12 +274,12 @@
is_destroyed["[temp.name]"] = 1
wound_flavor_text["[temp.name]"] = "[T.He] [T.is] missing [T.his] [temp.name].\n"
continue
- if(temp.status & ORGAN_ROBOT)
+ if(!is_synth && temp.status & ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
- wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a robot [temp.name]!\n"
+ wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name]!\n"
continue
else
- wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a robot [temp.name]. It has[temp.get_wounds_desc()]!\n"
+ wound_flavor_text["[temp.name]"] = "[T.He] [T.has] a [temp.name]. It has[temp.get_wounds_desc()]!\n"
else if(temp.wounds.len > 0 || temp.open)
if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ])
var/obj/item/organ/external/parent = organs_by_name[temp.parent_organ]
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index eef1b95245..68662204a3 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -654,18 +654,12 @@
///eyecheck()
///Returns a number between -1 to 2
/mob/living/carbon/human/eyecheck()
+
+ var/obj/item/organ/I = internal_organs_by_name["eyes"]
+ if(!I || I.status & (ORGAN_CUT_AWAY|ORGAN_DESTROYED))
+ return 2
+
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
- return 2
-
if(istype(src.head, /obj/item/clothing/head/welding))
if(!src.head:up)
number += 2
@@ -690,8 +684,6 @@
//Used by various things that knock people out by applying blunt trauma to the head.
//Checks that the species has a "head" (brain containing organ) and that hit_zone refers to it.
/mob/living/carbon/human/proc/headcheck(var/target_zone, var/brain_tag = "brain")
- if(!species.has_organ[brain_tag])
- return 0
var/obj/item/organ/affecting = internal_organs_by_name[brain_tag]
@@ -745,38 +737,16 @@
xylophone=0
return
-/mob/living/carbon/human/proc/check_has_mouth()
+/mob/living/proc/check_has_mouth()
+ return 1
+
+/mob/living/carbon/human/check_has_mouth()
// Todo, check stomach organ when implemented.
var/obj/item/organ/external/head/H = get_organ("head")
if(!H || !H.can_intake_reagents)
return 0
return 1
-/mob/living/carbon/human/proc/vomit()
-
- if(!check_has_mouth())
- return
-
- if(!lastpuke)
- lastpuke = 1
- src << "You feel nauseous..."
- spawn(150) //15 seconds until second warning
- src << "You feel like you are about to throw up!"
- spawn(100) //and you have 10 more for mad dash to the bucket
- Stun(5)
-
- src.visible_message("[src] throws up!","You throw up!")
- playsound(loc, 'sound/effects/splat.ogg', 50, 1)
-
- var/turf/location = loc
- if (istype(location, /turf/simulated))
- location.add_vomit_floor(src, 1)
-
- nutrition -= 40
- adjustToxLoss(-3)
- spawn(350) //wait 35 seconds before next volley
- lastpuke = 0
-
/mob/living/carbon/human/proc/morph()
set name = "Morph"
set category = "Superpower"
@@ -846,12 +816,14 @@
if(new_style)
f_style = new_style
- var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female")
+ var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neutral")
if (new_gender)
if(new_gender == "Male")
gender = MALE
- else
+ else if(new_gender == "Female")
gender = FEMALE
+ else
+ gender = NEUTER
regenerate_icons()
check_dna()
@@ -936,13 +908,12 @@
/mob/living/carbon/human/revive()
- if(species && !(species.flags & NO_BLOOD))
+ if(should_have_organ("heart"))
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
- // Fix up all organs.
- // This will ignore any prosthetics in the prefs currently.
- species.create_organs(src)
+ species.create_organs(src) // Reset our organs/limbs.
+ restore_all_organs() // Reapply robotics/amputated status from preferences.
if(!client || !key) //Don't boot out anyone already in the mob.
for (var/obj/item/organ/brain/H in world)
@@ -1057,7 +1028,7 @@
for(var/obj/item/O in organ.implants)
if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad.
// All kinds of embedded objects cause bleeding.
- if(species.flags & NO_PAIN)
+ if(!can_feel_pain(organ.limb_name))
src << "You feel [O] moving inside your [organ.name]."
else
var/msg = pick( \
@@ -1067,7 +1038,7 @@
src << msg
organ.take_damage(rand(1,3), 0, 0)
- if(!(organ.status & ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //There is no blood in protheses.
+ if(!(organ.status & ORGAN_ROBOT) && !should_have_organ("heart")) //There is no blood in protheses.
organ.status |= ORGAN_BLEEDING
src.adjustToxLoss(rand(1,3))
@@ -1302,11 +1273,15 @@
/mob/living/carbon/human/getDNA()
if(species.flags & NO_SCAN)
return null
+ if(isSynthetic())
+ return
..()
/mob/living/carbon/human/setDNA()
if(species.flags & NO_SCAN)
return
+ if(isSynthetic())
+ return
..()
/mob/living/carbon/human/has_brain()
@@ -1423,3 +1398,24 @@
pulling_punches = !pulling_punches
src << "You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"]."
return
+
+/mob/living/carbon/human/should_have_organ(var/organ_check)
+
+ var/obj/item/organ/external/affecting
+ if(organ_check in list("heart","lungs"))
+ affecting = organs_by_name["chest"]
+ else if(organ_check in list("liver","kidneys"))
+ affecting = organs_by_name["groin"]
+
+ if(affecting && (affecting.status & ORGAN_ROBOT))
+ return 0
+ return (species && species.has_organ[organ_check])
+
+/mob/living/carbon/human/can_feel_pain(var/obj/item/organ/check_organ)
+ if(isSynthetic())
+ return 0
+ if(check_organ)
+ if(!istype(check_organ))
+ return 0
+ return check_organ.can_feel_pain()
+ return !(species.flags & NO_PAIN)
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 377581d09b..517bc79a41 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -13,7 +13,7 @@
total_brute += O.brute_dam
total_burn += O.burn_dam
- var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss())
+ var/oxy_l = getOxyLoss()
var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss())
var/clone_l = getCloneLoss()
@@ -28,7 +28,7 @@
if(status_flags & GODMODE) return 0 //godmode
- if(species && species.has_organ["brain"])
+ if(should_have_organ("brain"))
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.take_damage(amount)
@@ -42,7 +42,7 @@
if(status_flags & GODMODE) return 0 //godmode
- if(species && species.has_organ["brain"])
+ if(should_have_organ("brain"))
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.damage = min(max(amount, 0),(maxHealth*2))
@@ -56,7 +56,7 @@
if(status_flags & GODMODE) return 0 //godmode
- if(species && species.has_organ["brain"])
+ if(should_have_organ("brain"))
var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
brainloss = min(sponge.damage,maxHealth*2)
@@ -142,12 +142,12 @@
..()
/mob/living/carbon/human/getCloneLoss()
- if(species.flags & (NO_SCAN))
+ if((species.flags & NO_SCAN) || isSynthetic())
cloneloss = 0
return ..()
/mob/living/carbon/human/setCloneLoss(var/amount)
- if(species.flags & (NO_SCAN))
+ if((species.flags & NO_SCAN) || isSynthetic())
cloneloss = 0
else
..()
@@ -155,7 +155,7 @@
/mob/living/carbon/human/adjustCloneLoss(var/amount)
..()
- if(species.flags & (NO_SCAN))
+ if((species.flags & NO_SCAN) || isSynthetic())
cloneloss = 0
return
@@ -189,37 +189,37 @@
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/getOxyLoss()
- if(species.flags & NO_BREATHE)
+ if(!should_have_organ("lungs"))
oxyloss = 0
return ..()
/mob/living/carbon/human/adjustOxyLoss(var/amount)
- if(species.flags & NO_BREATHE)
+ if(!should_have_organ("lungs"))
oxyloss = 0
else
amount = amount*species.oxy_mod
..(amount)
/mob/living/carbon/human/setOxyLoss(var/amount)
- if(species.flags & NO_BREATHE)
+ if(!should_have_organ("lungs"))
oxyloss = 0
else
..()
/mob/living/carbon/human/getToxLoss()
- if(species.flags & NO_POISON)
+ if((species.flags & NO_POISON) || isSynthetic())
toxloss = 0
return ..()
/mob/living/carbon/human/adjustToxLoss(var/amount)
- if(species.flags & NO_POISON)
+ if((species.flags & NO_POISON) || isSynthetic())
toxloss = 0
else
amount = amount*species.toxins_mod
..(amount)
/mob/living/carbon/human/setToxLoss(var/amount)
- if(species.flags & NO_POISON)
+ if((species.flags & NO_POISON) || isSynthetic())
toxloss = 0
else
..()
@@ -321,7 +321,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
This function restores the subjects blood to max.
*/
/mob/living/carbon/human/proc/restore_blood()
- if(!(species.flags & NO_BLOOD))
+ if(should_have_organ("heart"))
var/blood_volume = vessel.get_reagent_amount("blood")
vessel.add_reagent("blood",560.0-blood_volume)
@@ -329,9 +329,9 @@ This function restores the subjects blood to max.
/*
This function restores all organs.
*/
-/mob/living/carbon/human/restore_all_organs()
+/mob/living/carbon/human/restore_all_organs(var/ignore_prosthetic_prefs)
for(var/obj/item/organ/external/current_organ in organs)
- current_organ.rejuvenate()
+ current_organ.rejuvenate(ignore_prosthetic_prefs)
/mob/living/carbon/human/proc/HealDamage(zone, brute, burn)
var/obj/item/organ/external/E = get_organ(zone)
@@ -354,14 +354,19 @@ This function restores all organs.
if(Debug2)
world.log << "## DEBUG: human/apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]."
- //visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
+ var/obj/item/organ/external/organ = null
+ if(isorgan(def_zone))
+ organ = def_zone
+ else
+ if(!def_zone) def_zone = ran_zone(def_zone)
+ organ = get_organ(check_zone(def_zone))
//Handle other types of damage
if((damagetype != BRUTE) && (damagetype != BURN))
- if(damagetype == HALLOSS && !(species && (species.flags & NO_PAIN)))
- if ((damage > 25 && prob(20)) || (damage > 50 && prob(60)))
- emote("scream")
-
+ if(damagetype == HALLOSS)
+ if((damage > 25 && prob(20)) || (damage > 50 && prob(60)))
+ if(organ && organ.can_feel_pain())
+ emote("scream")
..(damage, damagetype, def_zone, blocked)
return 1
@@ -371,12 +376,7 @@ This function restores all organs.
if(blocked >= 100)
return 0
- var/obj/item/organ/external/organ = null
- if(isorgan(def_zone))
- organ = def_zone
- else
- if(!def_zone) def_zone = ran_zone(def_zone)
- organ = get_organ(check_zone(def_zone))
+
if(!organ) return 0
if(blocked)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index e34a4de79e..b516852074 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -61,7 +61,7 @@ emp_act
emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!")
else
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
- emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [affected.name]!")
+ emote("me", 1, "[affected.can_feel_pain() ? "" : emote_scream]drops what they were holding in their [affected.name]!")
..(stun_amount, agony_amount, def_zone)
@@ -223,7 +223,7 @@ emp_act
//Harder to score a stun but if you do it lasts a bit longer
if(prob(effective_force))
apply_effect(20, PARALYZE, armor)
- visible_message("[src] [species.knockout_message]")
+ visible_message("[src] [species.get_knockout_message(src)]")
else
//Easier to score a stun but lasts less time
if(prob(effective_force + 10))
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 7ed171a1f1..f116ae17f0 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -83,6 +83,7 @@
var/list/flavor_texts = list()
var/gunshot_residue
var/pulling_punches // Are you trying not to hurt your opponent?
+ var/full_prosthetic // We are a robutt.
mob_bump_flag = HUMAN
mob_push_flags = ~HEAVY
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index ca81defe0f..c8011cb059 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -16,7 +16,7 @@
var/health_deficiency = (100 - health)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
- if (!(species && (species.flags & NO_PAIN)))
+ if(can_feel_pain())
if(halloss >= 10) tally += (halloss / 10) //halloss shouldn't slow you down if you can't even feel it
var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
@@ -42,7 +42,7 @@
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || (E.status & ORGAN_DESTROYED))
tally += 4
- if(E.status & ORGAN_SPLINTED)
+ else if(E.status & ORGAN_SPLINTED)
tally += 0.5
else if(E.status & ORGAN_BROKEN)
tally += 1.5
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index d69f6e57cc..cab9b5a1c2 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -68,6 +68,7 @@
if (istype(buckled, /obj/structure/bed))
return
+ var/limb_pain
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
var/obj/item/organ/external/E = organs_by_name[limb_tag]
if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD)))
@@ -88,6 +89,8 @@
else if (E.is_dislocated())
stance_damage += 0.5
+ if(E) limb_pain = E.can_feel_pain()
+
// Canes and crutches help you stand (if the latter is ever added)
// One cane mitigates a broken leg+foot, or a missing foot.
// Two canes are needed for a lost leg. If you are missing both legs, canes aren't gonna help you.
@@ -99,7 +102,7 @@
// standing is poor
if(stance_damage >= 4 || (stance_damage >= 2 && prob(5)))
if(!(lying || resting))
- if(species && !(species.flags & NO_PAIN))
+ if(limb_pain)
emote("scream")
custom_emote(1, "collapses!")
Weaken(5) //can't emote while weakened, apparently.
@@ -145,7 +148,7 @@
drop_from_inventory(r_hand)
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
- emote("me", 1, "[(species.flags & NO_PAIN) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
+ emote("me", 1, "[(E.can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
else if(E.is_malfunctioning())
switch(E.body_part)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index ae66cf3fe0..c3d0568b80 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -40,7 +40,6 @@ This saves us from having to call add_fingerprint() any time something is put in
/mob/living/carbon/human/proc/has_organ(name)
var/obj/item/organ/external/O = organs_by_name[name]
-
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 97327c4bbd..8e77023fe7 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -254,6 +254,12 @@
radiation = Clamp(radiation,0,100)
if (radiation)
+
+ // TODO.
+ if(isSynthetic())
+ radiation = 0
+ return
+
var/obj/item/organ/diona/nutrients/rad_organ = locate() in internal_organs
if(rad_organ && !rad_organ.is_broken())
var/rads = radiation/25
@@ -365,7 +371,7 @@
var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa
// Lung damage increases the minimum safe pressure.
- if(species.has_organ["lungs"])
+ if(should_have_organ("lungs"))
var/obj/item/organ/lungs/L = internal_organs_by_name["lungs"]
if(isnull(L))
safe_pressure_min = INFINITY //No lungs, how are you breathing?
@@ -831,6 +837,7 @@
return min(1,thermal_protection)
/mob/living/carbon/human/handle_chemicals_in_body()
+
if(in_stasis)
return
@@ -838,43 +845,48 @@
chem_effects.Cut()
analgesic = 0
- if(touching) touching.metabolize()
- if(ingested) ingested.metabolize()
- if(bloodstr) bloodstr.metabolize()
+ if(!isSynthetic())
- if(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.
+ if(!isSynthetic())
+ if(light_organ && !light_organ.is_broken())
+ var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
+ if(isturf(loc)) //else, there's considered to be no light
+ var/turf/T = loc
+ var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
+ if(L)
+ light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
+ else
+ light_amount = 5
+ nutrition += light_amount
+ traumatic_shock -= light_amount
+
+ if(species.flags & IS_PLANT)
+ if(nutrition > 450)
+ nutrition = 450
+
+ if(light_amount >= 3) //if there's enough light, heal
+ adjustBruteLoss(-(round(light_amount/2)))
+ adjustFireLoss(-(round(light_amount/2)))
+ adjustToxLoss(-(light_amount))
+ adjustOxyLoss(-(light_amount))
+ //TODO: heal wounds, heal broken limbs.
if(species.light_dam)
var/light_amount = 0
@@ -901,13 +913,14 @@
if(overeatduration > 1)
overeatduration -= 2 //doubled the unfat rate
- if(species.flags & IS_PLANT && (!light_organ || light_organ.is_broken()))
+ if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken()))
if(nutrition < 200)
take_overall_damage(2,0)
traumatic_shock++
// TODO: stomach and bloodstream organ.
- handle_trace_chems()
+ if(!isSynthetic())
+ handle_trace_chems()
updatehealth()
@@ -920,7 +933,7 @@
if(status_flags & GODMODE) return 0
//SSD check, if a logged player is awake put them back to sleep!
- if(species.show_ssd && !client && !teleop)
+ if(species.get_ssd(src) && !client && !teleop)
Sleeping(2)
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
@@ -928,7 +941,7 @@
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
- if(health <= config.health_threshold_dead || (species.has_organ["brain"] && !has_brain()))
+ if(health <= config.health_threshold_dead || (should_have_organ("brain") && !has_brain()))
death()
blinded = 1
silent = 0
@@ -1248,7 +1261,7 @@
if(2) healths.icon_state = "health7"
else
//switch(health - halloss)
- switch(100 - ((species.flags & NO_PAIN) ? 0 : traumatic_shock))
+ switch(100 - (!can_feel_pain() ? 0 : traumatic_shock))
if(100 to INFINITY) healths.icon_state = "health0"
if(80 to 100) healths.icon_state = "health1"
if(60 to 80) healths.icon_state = "health2"
@@ -1410,7 +1423,7 @@
// Puke if toxloss is too high
if(!stat)
if (getToxLoss() >= 45 && nutrition > 20)
- vomit()
+ spawn vomit()
//0.1% chance of playing a scary sound to someone who's in complete darkness
if(isturf(loc) && rand(1,1000) == 1)
@@ -1484,7 +1497,7 @@
/mob/living/carbon/human/handle_shock()
..()
if(status_flags & GODMODE) return 0 //godmode
- if(species && species.flags & NO_PAIN) return
+ if(!can_feel_pain()) return
if(health < config.health_threshold_softcrit)// health 0 makes you immediately collapse
shock_stage = max(shock_stage, 61)
@@ -1535,7 +1548,7 @@
/mob/living/carbon/human/proc/handle_pulse()
if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load)
- if(species && species.flags & NO_BLOOD)
+ if(!internal_organs_by_name["heart"])
return PULSE_NONE //No blood, no pulse.
if(stat == DEAD)
@@ -1566,12 +1579,12 @@
return temp
/mob/living/carbon/human/proc/handle_heartbeat()
- if(pulse == PULSE_NONE || !species.has_organ["heart"])
+ if(pulse == PULSE_NONE)
return
var/obj/item/organ/heart/H = internal_organs_by_name["heart"]
- if(!H || H.robotic >=2 )
+ if(!H || (H.status & ORGAN_ROBOT))
return
if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space))
@@ -1734,7 +1747,7 @@
return slurring
/mob/living/carbon/human/handle_stunned()
- if(species.flags & NO_PAIN)
+ if(!can_feel_pain())
stunned = 0
return 0
if(..())
diff --git a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm
index 87fe13fb1d..8820ffaf5b 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 fa7dda8f57..c1c335a22d 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -25,7 +25,6 @@
cold_level_2 = 50
cold_level_3 = 0
- eyes = "vox_eyes_s"
gluttonous = 2
breath_type = "nitrogen"
@@ -45,6 +44,21 @@
/mob/living/carbon/human/proc/leap
)
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest),
+ "groin" = list("path" = /obj/item/organ/external/groin),
+ "head" = list("path" = /obj/item/organ/external/head/vox),
+ "l_arm" = list("path" = /obj/item/organ/external/arm),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right),
+ "l_leg" = list("path" = /obj/item/organ/external/leg),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right),
+ "l_hand" = list("path" = /obj/item/organ/external/hand),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right),
+ "l_foot" = list("path" = /obj/item/organ/external/foot),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right)
+ )
+
+
has_organ = list(
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index d6e32722b1..c0722fbca9 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -19,7 +19,6 @@
var/blood_mask = 'icons/mob/human_races/masks/blood_human.dmi'
var/prone_icon // If set, draws this from icobase when mob is prone.
- var/eyes = "eyes_s" // Icon for eyes.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previes..
@@ -85,7 +84,7 @@
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative.
- var/body_temperature = 310.15 // Non-IS_SYNTHETIC species will try to stabilize at this temperature.
+ var/body_temperature = 310.15 // Species will try to stabilize at this temperature.
// (also affects temperature processing)
var/heat_discomfort_level = 315 // Aesthetic messages about feeling warm.
@@ -177,6 +176,24 @@
/datum/species/proc/get_bodytype()
return name
+/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message)
+
+/datum/species/proc/get_death_message(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message)
+
+/datum/species/proc/get_ssd(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd)
+
+/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "#1F181F" : blood_color)
+
+/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? 1 : virus_immune)
+
+/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "#575757" : flesh_color)
+
/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type)
if(!prob(5))
diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm
index fae7d834e5..7faf868ac2 100644
--- a/code/modules/mob/living/carbon/human/species/station/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/station/golem.dm
@@ -7,7 +7,7 @@
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch)
- flags = NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN | NO_POISON | NO_MINOR_CUT
+ flags = NO_PAIN | NO_SCAN | NO_POISON | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
siemens_coefficient = 0
diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm
index d9d8347550..77a5f942f0 100644
--- a/code/modules/mob/living/carbon/human/species/station/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm
@@ -15,8 +15,6 @@
has_fine_manipulation = 0
show_ssd = null
- eyes = "blank_eyes"
-
gibbed_anim = "gibbed-m"
dusted_anim = "dust-m"
death_message = "lets out a faint chimper as it collapses and stops moving..."
@@ -40,6 +38,20 @@
pass_flags = PASSTABLE
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest),
+ "groin" = list("path" = /obj/item/organ/external/groin),
+ "head" = list("path" = /obj/item/organ/external/head/no_eyes),
+ "l_arm" = list("path" = /obj/item/organ/external/arm),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right),
+ "l_leg" = list("path" = /obj/item/organ/external/leg),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right),
+ "l_hand" = list("path" = /obj/item/organ/external/hand),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right),
+ "l_foot" = list("path" = /obj/item/organ/external/foot),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right)
+ )
+
/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm
index 38db954932..96a926b14e 100644
--- a/code/modules/mob/living/carbon/human/species/station/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/station/slime.dm
@@ -8,7 +8,7 @@
language = null //todo?
unarmed_types = list(/datum/unarmed_attack/slime_glomp)
- flags = NO_SCAN | NO_SLIP | NO_BREATHE | NO_MINOR_CUT
+ flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
siemens_coefficient = 3 //conductive
darksight = 3
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index e5b3ae6b0f..5fecc7c79b 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -131,7 +131,6 @@
name_plural = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
- eyes = "skrell_eyes_s"
primitive_form = "Neaera"
unarmed_types = list(/datum/unarmed_attack/punch)
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
@@ -152,6 +151,20 @@
reagent_tag = IS_SKRELL
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest),
+ "groin" = list("path" = /obj/item/organ/external/groin),
+ "head" = list("path" = /obj/item/organ/external/head/skrell),
+ "l_arm" = list("path" = /obj/item/organ/external/arm),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right),
+ "l_leg" = list("path" = /obj/item/organ/external/leg),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right),
+ "l_hand" = list("path" = /obj/item/organ/external/hand),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right),
+ "l_foot" = list("path" = /obj/item/organ/external/foot),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right)
+ )
+
/datum/species/diona
name = "Diona"
name_plural = "Dionaea"
@@ -164,7 +177,6 @@
rarity_value = 3
hud_type = /datum/hud_data/diona
siemens_coefficient = 0.3
- eyes = "blank_eyes"
show_ssd = "completely quiescent"
num_alternate_languages = 1
name_language = "Rootspeak"
@@ -189,7 +201,7 @@
has_limbs = list(
"chest" = list("path" = /obj/item/organ/external/diona/chest),
"groin" = list("path" = /obj/item/organ/external/diona/groin),
- "head" = list("path" = /obj/item/organ/external/diona/head),
+ "head" = list("path" = /obj/item/organ/external/head/no_eyes/diona),
"l_arm" = list("path" = /obj/item/organ/external/diona/arm),
"r_arm" = list("path" = /obj/item/organ/external/diona/arm/right),
"l_leg" = list("path" = /obj/item/organ/external/diona/leg),
@@ -217,7 +229,7 @@
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
- flags = NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | NO_MINOR_CUT
+ flags = NO_SCAN | IS_PLANT | NO_PAIN | NO_SLIP | NO_MINOR_CUT
spawn_flags = CAN_JOIN | IS_WHITELISTED
blood_color = "#004400"
@@ -254,82 +266,4 @@
else
qdel(D)
- H.visible_message("[H] splits apart with a wet slithering noise!")
-
-/datum/species/machine
- name = "Machine"
- name_plural = "machines"
-
- blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \
- robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \
- to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \
- generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \
- inhuman in outlook and perspective."
-
- icobase = 'icons/mob/human_races/r_machine.dmi'
- deform = 'icons/mob/human_races/r_machine.dmi'
-
- language = "Encoded Audio Language"
- unarmed_types = list(/datum/unarmed_attack/punch)
- rarity_value = 2
- num_alternate_languages = 1 // potentially could be 2?
- name_language = "Encoded Audio Language"
-
- eyes = "blank_eyes"
- brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150%
- burn_mod = 1.875 // So they take 50% extra damage from brute/burn overall.
- show_ssd = "flashing a 'system offline' glyph on their monitor"
- death_message = "gives one shrill beep before falling lifeless."
- knockout_message = "encounters a hardware fault and suddenly reboots!"
-
- warning_low_pressure = 50
- hazard_low_pressure = 0
-
- cold_level_1 = 50
- cold_level_2 = -1
- cold_level_3 = -1
-
- heat_level_1 = 500 // Gives them about 25 seconds in space before taking damage
- heat_level_2 = 1000
- heat_level_3 = 2000
-
- passive_temp_gain = 10 // This should cause IPCs to stabilize at ~80 C in a 20 C environment.
-
- flags = NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_POISON
- spawn_flags = CAN_JOIN | IS_WHITELISTED
-
- blood_color = "#1F181F"
- flesh_color = "#575757"
- virus_immune = 1
- reagent_tag = IS_MACHINE
-
- has_organ = list(
- "brain" = /obj/item/organ/mmi_holder/posibrain,
- "cell" = /obj/item/organ/cell,
- "optics" = /obj/item/organ/optical_sensor
- )
-
- vision_organ = "optics"
-
- has_limbs = list(
- "chest" = list("path" = /obj/item/organ/external/chest/ipc),
- "groin" = list("path" = /obj/item/organ/external/groin/ipc),
- "head" = list("path" = /obj/item/organ/external/head/ipc),
- "l_arm" = list("path" = /obj/item/organ/external/arm/ipc),
- "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc),
- "l_leg" = list("path" = /obj/item/organ/external/leg/ipc),
- "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc),
- "l_hand" = list("path" = /obj/item/organ/external/hand/ipc),
- "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc),
- "l_foot" = list("path" = /obj/item/organ/external/foot/ipc),
- "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc)
- )
-
-/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
- ..()
- H.h_style = ""
- spawn(100)
- if(H) H.update_hair()
-
-/datum/species/machine/sanitize_name(var/name)
- return sanitizeName(name, allow_numbers = 1)
+ H.visible_message("\The [H] splits apart with a wet slithering noise!")
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
index 1c5e88ce59..5f6ab38fad 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
@@ -13,8 +13,6 @@
siemens_coefficient = 0
gluttonous = 3
- eyes = "blank_eyes"
-
brute_mod = 0.5 // Hardened carapace.
burn_mod = 2 // Weak to fire.
@@ -25,7 +23,7 @@
cold_level_2 = -1
cold_level_3 = -1
- flags = NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT
+ flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT
spawn_flags = IS_RESTRICTED
reagent_tag = IS_XENOS
@@ -62,6 +60,20 @@
var/weeds_heal_rate = 1 // Health regen on weeds.
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest),
+ "groin" = list("path" = /obj/item/organ/external/groin),
+ "head" = list("path" = /obj/item/organ/external/head/no_eyes),
+ "l_arm" = list("path" = /obj/item/organ/external/arm),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right),
+ "l_leg" = list("path" = /obj/item/organ/external/leg),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right),
+ "l_hand" = list("path" = /obj/item/organ/external/hand),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right),
+ "l_foot" = list("path" = /obj/item/organ/external/foot),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right)
+ )
+
/datum/species/xenos/get_bodytype()
return "Xenomorph"
diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm
index 92a6089e9f..f6ecb54ce5 100644
--- a/code/modules/mob/living/carbon/human/unarmed_attack.dm
+++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm
@@ -54,7 +54,7 @@ var/global/list/sparring_attack_cache = list()
if("l_arm", "l_hand")
if (target.l_hand)
// Disarm left hand
- //Urist McAssistant dropped the macguffin with a scream just sounds odd. Plus it doesn't work with NO_PAIN
+ //Urist McAssistant dropped the macguffin with a scream just sounds odd.
target.visible_message("\The [target.l_hand] was knocked right out of [target]'s grasp!")
target.drop_l_hand()
if("r_arm", "r_hand")
@@ -94,10 +94,13 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
var/obj/item/organ/eyes/eyes = target.internal_organs_by_name["eyes"]
- eyes.take_damage(rand(3,4), 1)
-
- user.visible_message("[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!")
- target << "You experience[(target.species.flags & NO_PAIN)? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(target.species.flags & NO_PAIN)? "." : "!"]"
+ if(eyes)
+ eyes.take_damage(rand(3,4), 1)
+ user.visible_message("[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!")
+ var/eye_pain = eyes.can_feel_pain()
+ target << "You experience[(eye_pain) ? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(eye_pain)? "." : "!"]"
+ return
+ user.visible_message("[user] attempts to press \his [eye_attack_text] into [target]'s eyes, but they don't have any!")
/datum/unarmed_attack/bite
attack_verb = list("bit")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 8fab931887..cc112b18d9 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -209,11 +209,11 @@ var/global/list/damage_icon_parts = list()
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
- var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
+ var/cache_index = "[O.damage_state]/[O.icon_name]/[O.species.get_blood_colour()]/[species.get_bodytype()]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
- DI.Blend(species.blood_color, ICON_MULTIPLY)
+ DI.Blend(O.species.get_blood_colour(), ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm
index 8b8e875aec..2e1cc29595 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 be31d28034..92eccc66df 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 ef7a33fd40..f575c6303d 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -813,3 +813,51 @@ default behaviour is:
ear_damage = damage
if(deaf >= 0)
ear_deaf = deaf
+
+/mob/living/proc/vomit(var/skip_wait, var/blood_vomit)
+
+ if(isSynthetic())
+ src << "A sudden, dizzying wave of internal feedback rushes over you!"
+ src.Weaken(5)
+ return
+
+ if(!check_has_mouth())
+ return
+
+ if(!lastpuke)
+
+ if (nutrition <= 100)
+ src << "You gag as you want to throw up, but there's nothing in your stomach!"
+ src.Weaken(10)
+ src.adjustToxLoss(3)
+ return
+
+ lastpuke = 1
+ src << "You feel nauseous..."
+
+ if(!skip_wait)
+ sleep(150) //15 seconds until second warning
+ src << "You feel like you are about to throw up!"
+ sleep(100) //and you have 10 more for mad dash to the bucket
+
+ Stun(5)
+ src.visible_message("[src] throws up!","You throw up!")
+ playsound(loc, 'sound/effects/splat.ogg', 50, 1)
+
+ var/turf/simulated/T = get_turf(src)
+ if(istype(T))
+ if(blood_vomit)
+ T.add_blood_floor(src)
+ else
+ T.add_vomit_floor(src, 1)
+
+ if(blood_vomit)
+ if(getBruteLoss() < 50)
+ adjustBruteLoss(3)
+ else
+ nutrition -= 40
+ adjustToxLoss(-3)
+
+ sleep(350)
+ lastpuke = 0
+
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 5a671afe99..c547211ecf 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -43,3 +43,4 @@
var/fire_stacks
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
+ var/lastpuke = 0
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 6b38a7c465..14434bfe6e 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -30,7 +30,7 @@ var/list/mob_hat_cache = list()
universal_understand = 1
gender = NEUTER
pass_flags = PASSTABLE
- braintype = "Robot"
+ braintype = "Drone"
lawupdate = 0
density = 1
req_access = list(access_engine, access_robotics)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 8507053e23..293a55b222 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -247,7 +247,7 @@
if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately.
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
- modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
+ modtype = input("Please, select a module!", "Robot module", null, null) as null|anything in modules
if(module)
return
@@ -267,9 +267,9 @@
modtype = prefix
if(istype(mmi, /obj/item/device/mmi/digital/posibrain))
- braintype = "Android"
- else if(istype(mmi, /obj/item/device/mmi/digital/robot))
braintype = "Robot"
+ else if(istype(mmi, /obj/item/device/mmi/digital/robot))
+ braintype = "Drone"
else
braintype = "Cyborg"
@@ -911,7 +911,7 @@
if(!(icontype in module_sprites))
icontype = module_sprites[1]
else
- icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot", icontype, null) in module_sprites
+ icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot Icon", icontype, null) in module_sprites
icon_state = module_sprites[icontype]
updateicon()
diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm
index 88be25cc24..05bf7e8eef 100644
--- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm
+++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm
@@ -77,7 +77,7 @@
if(!E || (E.status & ORGAN_DESTROYED))
src << "\The [H] does not have a head!"
- if(!H.species.has_organ["brain"])
+ if(!H.should_have_organ("brain"))
src << "\The [H] does not seem to have an ear canal to breach."
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 7885d3e8f7..9503800189 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -87,7 +87,6 @@
var/canmove = 1
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
- var/lastpuke = 0
var/unacidable = 0
var/list/pinned = list() // List of things pinning this creature to walls (see living_defense.dm)
var/list/embedded = list() // Embedded items, since simple mobs don't have organs.
diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm
index 44303241db..fb51bc1572 100644
--- a/code/modules/mob/mob_grab_specials.dm
+++ b/code/modules/mob/mob_grab_specials.dm
@@ -99,7 +99,7 @@
if(!armor && target.headcheck("head") && prob(damage))
target.apply_effect(20, PARALYZE)
- target.visible_message("[target] [target.species.knockout_message]")
+ target.visible_message("[target] [target.species.get_knockout_message(target)]")
playsound(attacker.loc, "swing_hit", 25, 1, -1)
attacker.attack_log += text("\[[time_stamp()]\] Headbutted [target.name] ([target.ckey])")
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index a3f81168b7..d20fe8bee2 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -3,8 +3,18 @@ datum/preferences
proc/randomize_appearance_for(var/mob/living/carbon/human/H)
gender = pick(MALE, FEMALE)
s_tone = random_skin_tone()
- h_style = random_hair_style(gender, species)
- f_style = random_facial_hair_style(gender, species)
+
+ var/use_head_species
+ var/obj/item/organ/external/head/temp_head = H.get_organ("head")
+ if(temp_head)
+ use_head_species = temp_head.species.get_bodytype()
+ else
+ use_head_species = H.species.get_bodytype()
+
+ if(use_head_species)
+ h_style = random_hair_style(gender, species)
+ f_style = random_facial_hair_style(gender, species)
+
randomize_hair_color("hair")
randomize_hair_color("facial")
randomize_eyes_color()
@@ -191,37 +201,58 @@ datum/preferences
else
icobase = 'icons/mob/human_races/r_human.dmi'
- preview_icon = new /icon(icobase, "torso_[g]")
- preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
- preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
-
- for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
- if(organ_data[name] == "amputated") continue
+ preview_icon = new /icon(icobase, "")
+ for(var/name in list("torso", "groin", "head", "r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
+ if(organ_data[name] == "amputated")
+ continue
if(organ_data[name] == "cyborg")
var/datum/robolimb/R
if(rlimb_data[name]) R = all_robolimbs[rlimb_data[name]]
if(!R) R = basic_robolimb
- preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic.
+ if(name in list("torso", "groin", "head"))
+ preview_icon.Blend(icon(R.icon, "[name]_[g]"), ICON_OVERLAY)
+ else
+ preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY)
continue
- preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY)
+ var/icon/limb_icon
+ if(name in list("torso", "groin", "head"))
+ limb_icon = new /icon(icobase, "[name]_[g]")
+ else
+ limb_icon = new /icon(icobase, "[name]")
+ // Skin color
+ if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR))
+ limb_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
+ // Skin tone
+ if(current_species && (current_species.appearance_flags & HAS_SKIN_TONE))
+ if (s_tone >= 0)
+ limb_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
+ else
+ limb_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
+ preview_icon.Blend(limb_icon, ICON_OVERLAY)
//Tail
if(current_species && (current_species.tail))
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
+ if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR))
+ temp.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
+ if(current_species && (current_species.appearance_flags & HAS_SKIN_TONE))
+ if (s_tone >= 0)
+ temp.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
+ else
+ temp.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
preview_icon.Blend(temp, ICON_OVERLAY)
- // Skin color
- if(current_species && (current_species.appearance_flags & HAS_SKIN_COLOR))
- preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
+ // This is absolute garbage but whatever. It will do until this entire file can be rewritten without crashes.
+ var/use_eye_icon = "eyes_s"
+ var/list/use_eye_data = current_species.has_limbs["head"]
+ if(islist(use_eye_data))
+ var/use_eye_path = use_eye_data["path"]
+ var/obj/item/organ/external/head/temp_head = new use_eye_path ()
+ if(istype(temp_head))
+ use_eye_icon = temp_head.eye_icon
+ qdel(temp_head)
- // 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")
+ 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 10b9d0ebbf..f200766179 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -145,9 +145,9 @@
O.loc = loc
O.job = "Cyborg"
if(O.mind.assigned_role == "Cyborg")
- if(O.mind.role_alt_title == "Android")
+ if(O.mind.role_alt_title == "Robot")
O.mmi = new /obj/item/device/mmi/digital/posibrain(O)
- else if(O.mind.role_alt_title == "Robot")
+ else if(O.mind.role_alt_title == "Drone")
O.mmi = new /obj/item/device/mmi/digital/robot(O)
else
O.mmi = new /obj/item/device/mmi(O)
diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm
index ebc490601d..74d2cebce0 100644
--- a/code/modules/organs/blood.dm
+++ b/code/modules/organs/blood.dm
@@ -19,7 +19,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
vessel = new/datum/reagents(600)
vessel.my_atom = src
- if(species && species.flags & NO_BLOOD) //We want the var for safety but we can do without the actual blood.
+ if(!should_have_organ("heart")) //We want the var for safety but we can do without the actual blood.
return
vessel.add_reagent("blood",560)
@@ -30,7 +30,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
- B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.blood_color,"blood_type"=dna.b_type, \
+ B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.get_blood_colour(src),"blood_type"=dna.b_type, \
"resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = list())
B.color = B.data["blood_colour"]
@@ -39,7 +39,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(in_stasis)
return
- if(species && species.flags & NO_BLOOD)
+ if(!should_have_organ("heart"))
return
if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood.
@@ -62,7 +62,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
- if(species && species.has_organ["heart"])
+ if(species && should_have_organ("heart"))
var/obj/item/organ/heart/heart = internal_organs_by_name["heart"]
if(!heart)
@@ -126,7 +126,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//Bleeding out
var/blood_max = 0
for(var/obj/item/organ/external/temp in organs)
- if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
+ if(!(temp.status & ORGAN_BLEEDING) || (temp.status & ORGAN_ROBOT))
continue
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
blood_max += W.damage / 40
@@ -137,7 +137,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/human/proc/drip(var/amt as num)
- if(species && species.flags & NO_BLOOD) //TODO: Make drips come from the reagents instead.
+ if(!should_have_organ("heart")) //TODO: Make drips come from the reagents instead.
return
if(!amt)
@@ -175,7 +175,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
// Putting this here due to return shenanigans.
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src
- B.data["blood_colour"] = H.species.blood_color
+ B.data["blood_colour"] = H.species.get_blood_colour(H)
B.color = B.data["blood_colour"]
var/list/temp_chem = list()
@@ -188,7 +188,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//For humans, blood does not appear from blue, it comes from vessels.
/mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
- if(species && species.flags & NO_BLOOD)
+ if(!should_have_organ("heart"))
return null
if(vessel.get_reagent_amount("blood") < amount)
@@ -216,7 +216,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
//Transfers blood from reagents to vessel, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount)
- if(species.flags & NO_BLOOD)
+ if(should_have_organ("heart"))
reagents.add_reagent("blood", amount, injected.data)
reagents.update_total()
return
diff --git a/code/modules/organs/misc.dm b/code/modules/organs/misc.dm
index a330e307a3..0ba128c1a6 100644
--- a/code/modules/organs/misc.dm
+++ b/code/modules/organs/misc.dm
@@ -46,7 +46,8 @@
/obj/item/organ/stack
name = "cortical stack"
parent_organ = "head"
- robotic = 2
+ icon_state = "brain-prosthetic"
+ organ_tag = "stack"
vital = 1
var/backup_time = 0
var/datum/mind/backup
@@ -56,15 +57,5 @@
backup_time = world.time
if(owner.mind) backup = owner.mind
-/obj/item/organ/stack/vox
-
/obj/item/organ/stack/vox/stack
-
-/obj/item/organ/stack
- name = "cortical stack"
- icon_state = "brain-prosthetic"
- organ_tag = "stack"
- robotic = 2
-
-/obj/item/organ/stack/vox
name = "vox cortical stack"
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 5165108635..63c57acb21 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -3,33 +3,37 @@ var/list/organ_cache = list()
/obj/item/organ
name = "organ"
icon = 'icons/obj/surgery.dmi'
+ germ_level = 0
+
+ // Strings.
+ var/organ_tag = "organ"
+ var/parent_organ = "chest"
+
+ // Appearance.
var/dead_icon
- var/mob/living/carbon/human/owner = null
+
+ // Status tracking.
var/status = 0
var/vital //Lose a vital limb, die immediately.
var/damage = 0 // amount of damage to the organ
- var/min_bruised_damage = 10
- var/min_broken_damage = 30
- var/max_damage
- var/organ_tag = "organ"
-
- var/parent_organ = "chest"
- var/robotic = 0 //For being a robot
- var/rejecting // Is this organ already being rejected?
-
+ // Reference data.
+ var/mob/living/carbon/human/owner = null
var/list/transplant_data
var/list/datum/autopsy_data/autopsy_data = list()
var/list/trace_chemicals = list() // traces of chemicals in the organ,
- // links chemical IDs to number of ticks for which they'll stay in the blood
- germ_level = 0
var/datum/dna/dna
var/datum/species/species
+ // Damage vars.
+ var/min_bruised_damage = 10
+ var/min_broken_damage = 30
+ var/max_damage
+ var/rejecting // Is this organ already being rejected?
+
/obj/item/organ/Destroy()
if(!owner)
return ..()
-
if(istype(owner, /mob/living/carbon))
if((owner.internal_organs) && (src in owner.internal_organs))
owner.internal_organs -= src
@@ -42,7 +46,7 @@ var/list/organ_cache = list()
owner.organs_by_name -= src
if(src in owner.contents)
owner.contents -= src
-
+ owner = null
return ..()
/obj/item/organ/proc/update_health()
@@ -189,8 +193,25 @@ var/list/organ_cache = list()
/obj/item/organ/proc/receive_chem(chemical as obj)
return 0
-/obj/item/organ/proc/rejuvenate()
+/obj/item/organ/proc/rejuvenate(var/ignore_prosthetic_prefs)
damage = 0
+ status = 0
+ if(!ignore_prosthetic_prefs && owner && owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name)
+ var/status = owner.client.prefs.organ_data[organ_tag]
+ if(status == "assisted")
+ mechassist()
+ else if(status == "mechanical")
+ robotize()
+
+/obj/item/organ/proc/remove_rejuv()
+ if(owner)
+ owner.internal_organs -= src
+ owner.internal_organs_by_name[organ_tag] = null
+ while(null in owner.internal_organs)
+ owner.internal_organs -= null
+ while(null in owner.internal_organs_by_name)
+ owner.internal_organs_by_name -= null
+ qdel(src)
/obj/item/organ/proc/is_damaged()
return damage > 0
@@ -241,19 +262,13 @@ var/list/organ_cache = list()
owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
/obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc
- robotic = 2
- src.status &= ~ORGAN_BROKEN
- src.status &= ~ORGAN_BLEEDING
- src.status &= ~ORGAN_SPLINTED
- src.status &= ~ORGAN_CUT_AWAY
- src.status &= ~ORGAN_DESTROYED
- src.status |= ORGAN_ROBOT
- src.status |= ORGAN_ASSISTED
+ status = 0
+ status |= ORGAN_ASSISTED
+ status |= ORGAN_ROBOT
/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc
- robotize()
- src.status &= ~ORGAN_ROBOT
- robotic = 1
+ status = 0
+ status |= ORGAN_ASSISTED
min_bruised_damage = 15
min_broken_damage = 35
@@ -320,8 +335,6 @@ var/list/organ_cache = list()
target.internal_organs |= src
affected.internal_organs |= src
target.internal_organs_by_name[organ_tag] = src
- if(robotic)
- status |= ORGAN_ROBOT
/obj/item/organ/eyes/replaced(var/mob/living/carbon/human/target)
@@ -335,10 +348,10 @@ var/list/organ_cache = list()
/obj/item/organ/proc/bitten(mob/user)
- if(robotic)
+ if(status & ORGAN_ROBOT)
return
- user << "\blue You take an experimental bite out of \the [src]."
+ user << "You take an experimental bite out of \the [src]."
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
blood_splatter(src,B,1)
@@ -361,6 +374,9 @@ var/list/organ_cache = list()
/obj/item/organ/attack_self(mob/user as mob)
// Convert it to an edible form, yum yum.
- if(!robotic && user.a_intent == "help" && user.zone_sel.selecting == "mouth")
+ if((status & ORGAN_ROBOT) && user.a_intent == "help" && user.zone_sel.selecting == "mouth")
bitten(user)
return
+
+/obj/item/organ/proc/can_feel_pain()
+ return !(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) && !(species.flags & NO_PAIN)
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 1e2f7d1e52..ed9d32f122 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -14,49 +14,57 @@
dir = SOUTH
organ_tag = "limb"
- var/brute_mod = 1
- var/burn_mod = 1
+ // Strings
+ var/limb_name
+ // Damage vars.
+ var/brute_mod = 1 // Multiplier for incoming brute damage.
+ var/burn_mod = 1 // As above for burn.
+ var/damage_state = "00" // Modifier used for generating the on-mob damage overlay for this limb.
+ var/brute_dam = 0 // Actual current brute damage.
+ var/burn_dam = 0 // Actual current burn damage.
+ var/last_dam = -1
+
+ // Appearance vars.
var/icon_name = null
var/body_part = null
var/icon_position = 0
var/model
var/force_icon
- var/damage_state = "00"
- var/brute_dam = 0
- var/burn_dam = 0
- var/max_size = 0
- var/last_dam = -1
var/icon/mob_icon
var/gendered_icon = 0
- var/limb_name
- var/disfigured = 0
- var/cannot_amputate
- var/cannot_break
var/s_tone
var/list/s_col
var/list/h_col
+ var/body_hair
+
+ // Wound and structural data.
+ var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often
var/list/wounds = list()
var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len!
- var/perma_injury = 0
var/obj/item/organ/external/parent
var/list/obj/item/organ/external/children
var/list/internal_organs = list() // Internal organs of this body part
- var/damage_msg = "\red You feel an intense pain"
var/broken_description
- var/open = 0
- var/stage = 0
- var/cavity = 0
var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails.
- var/encased // Needs to be opened with a saw to access the organs.
var/list/implants = list()
- var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often
+
+ // Joint/state stuff.
+ var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point
+ var/can_stand
+ var/disfigured = 0
+ var/cannot_amputate
+ var/cannot_break
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
- var/can_grasp //It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point
- var/can_stand
- var/body_hair
+ var/encased // Needs to be opened with a saw to access the organs.
+
+ // Surgery vars.
+ var/open = 0
+ var/stage = 0
+ var/cavity = 0
+
/obj/item/organ/external/Destroy()
if(parent && parent.children)
@@ -188,12 +196,6 @@
parent.children = list()
parent.children.Add(src)
-/obj/item/organ/external/robotize()
- ..()
- //robit limbs take reduced damage
- brute_mod = 0.8
- burn_mod = 0.8
-
/****************************************************
DAMAGE PROCS
****************************************************/
@@ -219,7 +221,7 @@
brute -= brute / 2
if(status & ORGAN_BROKEN && prob(40) && brute)
- if (!(owner.species && (owner.species.flags & NO_PAIN)))
+ if(!((species.flags & NO_PAIN) || (status & ORGAN_ROBOT)))
owner.emote("scream") //getting hit on broken hand hurts
if(used_weapon)
add_autopsy_data("[used_weapon]", brute + burn)
@@ -316,7 +318,6 @@
if(internal)
status &= ~ORGAN_BROKEN
- perma_injury = 0
/*if((brute || burn) && children && children.len && (owner.species.flags & REGENERATES_LIMBS))
var/obj/item/organ/external/stump/S = locate() in children
@@ -333,13 +334,10 @@
/*
This function completely restores a damaged organ to perfect condition.
*/
-/obj/item/organ/external/rejuvenate()
+/obj/item/organ/external/rejuvenate(var/ignore_prosthetic_prefs)
damage_state = "00"
- if(status & 128) //Robotic organs stay robotic. Fix because right click rejuvinate makes IPC's organs organic.
- status = 128
- else
- status = 0
- perma_injury = 0
+
+ status = 0
brute_dam = 0
burn_dam = 0
germ_level = 0
@@ -348,16 +346,44 @@ This function completely restores a damaged organ to perfect condition.
// handle internal organs
for(var/obj/item/organ/current_organ in internal_organs)
- current_organ.rejuvenate()
+ current_organ.rejuvenate(ignore_prosthetic_prefs)
// remove embedded objects and drop them on the floor
for(var/obj/implanted_object in implants)
if(!istype(implanted_object,/obj/item/weapon/implant)) // We don't want to remove REAL implants. Just shrapnel etc.
- implanted_object.loc = owner.loc
+ implanted_object.loc = get_turf(src)
implants -= implanted_object
- owner.updatehealth()
+ if(owner && !ignore_prosthetic_prefs)
+ if(owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name)
+ var/status = owner.client.prefs.organ_data[limb_name]
+ if(status == "amputated")
+ remove_rejuv()
+ else if(status == "cyborg")
+ var/robodata = owner.client.prefs.rlimb_data[limb_name]
+ if(robodata)
+ robotize(robodata)
+ else
+ robotize()
+ owner.updatehealth()
+/obj/item/organ/external/remove_rejuv()
+ if(owner)
+ owner.organs -= src
+ owner.organs_by_name[limb_name] = null
+ while(null in owner.organs)
+ owner.organs -= null
+ while(null in owner.organs_by_name)
+ owner.organs_by_name -= null
+ if(children && children.len)
+ for(var/obj/item/organ/external/E in children)
+ E.remove_rejuv()
+ children.Cut()
+
+ for(var/obj/item/organ/O in contents)
+ O.remove_rejuv()
+
+ qdel(src)
/obj/item/organ/external/proc/createwound(var/type = CUT, var/damage)
if(damage == 0) return
@@ -384,13 +410,13 @@ This function completely restores a damaged organ to perfect condition.
W.open_wound(damage)
if(prob(25))
if(status & ORGAN_ROBOT)
- owner.visible_message("\red The damage to [owner.name]'s [name] worsens.",\
- "\red The damage to your [name] worsens.",\
- "You hear the screech of abused metal.")
+ owner.visible_message("The damage to [owner.name]'s [name] worsens.",\
+ "The damage to your [name] worsens.",\
+ "You hear the screech of abused metal.")
else
- owner.visible_message("\red The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\
- "\red The wound on your [name] widens with a nasty ripping noise.",\
- "You hear a nasty ripping noise, as if flesh is being torn apart.")
+ owner.visible_message("The wound on [owner.name]'s [name] widens with a nasty ripping noise.",\
+ "The wound on your [name] widens with a nasty ripping noise.",\
+ "You hear a nasty ripping noise, as if flesh is being torn apart.")
return
//Creating wound
@@ -451,9 +477,6 @@ This function completely restores a damaged organ to perfect condition.
if(trace_chemicals[chemID] <= 0)
trace_chemicals.Remove(chemID)
- if(!(status & ORGAN_BROKEN))
- perma_injury = 0
-
//Infections
update_germs()
else
@@ -629,7 +652,7 @@ Note that amputating the affected organ does in fact remove the infection from t
else if(W.damage_type == BURN)
burn_dam += W.damage
- if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && !(H.species.flags & NO_BLOOD)))
+ if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ("heart")))
W.bleed_timer--
status |= ORGAN_BLEEDING
@@ -638,7 +661,7 @@ Note that amputating the affected organ does in fact remove the infection from t
number_wounds += W.amount
//things tend to bleed if they are CUT OPEN
- if (open && !clamped && (H && !(H.species.flags & NO_BLOOD)))
+ if (open && !clamped && (H && H.should_have_organ("heart")))
status |= ORGAN_BLEEDING
//Bone fractures
@@ -687,7 +710,7 @@ Note that amputating the affected organ does in fact remove the infection from t
****************************************************/
//Handles dismemberment
-/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children)
+/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children, var/silent)
if(cannot_amputate || !owner)
return
@@ -762,12 +785,18 @@ Note that amputating the affected organ does in fact remove the infection from t
I.loc = get_turf(src)
qdel(src)
if(DROPLIMB_BLUNT)
- var/obj/effect/decal/cleanable/blood/gibs/gore = new victim.species.single_gib_type(get_turf(victim))
- if(victim.species.flesh_color)
- gore.fleshcolor = victim.species.flesh_color
- if(victim.species.blood_color)
- gore.basecolor = victim.species.blood_color
- gore.update_icon()
+ var/obj/effect/decal/cleanable/blood/gibs/gore
+ if(status & ORGAN_ROBOT)
+ gore = new /obj/effect/decal/cleanable/blood/gibs/robot(get_turf(victim))
+ else
+ gore = new victim.species.single_gib_type(get_turf(victim))
+ if(species)
+ if(species.get_flesh_colour())
+ gore.fleshcolor = species.get_flesh_colour()
+ if(species.get_blood_colour())
+ gore.basecolor = species.get_blood_colour()
+ gore.update_icon()
+
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
for(var/obj/item/organ/I in internal_organs)
@@ -849,15 +878,14 @@ Note that amputating the affected organ does in fact remove the infection from t
if(owner)
owner.visible_message(\
- "\red You hear a loud cracking sound coming from \the [owner].",\
- "\red Something feels like it shattered in your [name]!",\
- "You hear a sickening crack.")
- if(owner.species && !(owner.species.flags & NO_PAIN))
+ "You hear a loud cracking sound coming from \the [owner].",\
+ "Something feels like it shattered in your [name]!",\
+ "You hear a sickening crack.")
+ if(!(species.flags & NO_PAIN))
owner.emote("scream")
status |= ORGAN_BROKEN
broken_description = pick("broken","fracture","hairline fracture")
- perma_injury = brute_dam
// Fractures have a chance of getting you out of restraints
if (prob(25))
@@ -891,26 +919,55 @@ Note that amputating the affected organ does in fact remove the infection from t
status &= ~ORGAN_BROKEN
return 1
-/obj/item/organ/external/robotize(var/company)
+/obj/item/organ/external/robotize(var/company, var/ski)
+
+ if(status & ORGAN_ROBOT)
+ return
+
..()
+ brute_mod = 0.8
+ burn_mod = 0.8
+
+ brute_mod = 0.8
+ burn_mod = 0.8
if(company)
model = company
var/datum/robolimb/R = all_robolimbs[company]
- if(species && (species.name in R.species_cannot_use))
+ if(!R || (species && (species.name in R.species_cannot_use)))
R = basic_robolimb
if(R)
force_icon = R.icon
- name = "[R.company] [initial(name)]"
- desc = "[R.desc]"
+ name = "robotic [initial(name)]"
+ desc = "[R.desc] It looks like it was produced by [R.company]."
- dislocated = -1 //TODO, make robotic limbs a separate type, remove snowflake
+ dislocated = -1
cannot_break = 1
get_icon()
unmutate()
- for (var/obj/item/organ/external/T in children)
- if(T)
- T.robotize()
+
+ for(var/obj/item/organ/external/T in children)
+ T.robotize(company, 1)
+
+ if(owner)
+
+ if(!skip_prosthetics)
+ owner.full_prosthetic = null // Will be rechecked next isSynthetic() call.
+
+ for(var/obj/item/organ/thing in src.contents)
+ if(istype(thing))
+ if(thing.vital)
+ continue
+ owner.internal_organs_by_name[thing.organ_tag] = null
+ owner.internal_organs.Remove(thing)
+ qdel(thing)
+
+ while(null in owner.internal_organs)
+ owner.internal_organs -= null
+ while(null in owner.internal_organs_by_name)
+ owner.internal_organs -= null
+
+ return 1
/obj/item/organ/external/proc/mutate()
if(src.status & ORGAN_ROBOT)
@@ -923,7 +980,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(owner) owner.update_body()
/obj/item/organ/external/proc/get_damage() //returns total damage
- return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use max_damage?
+ return (brute_dam+burn_dam) //could use max_damage?
/obj/item/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds)
@@ -1012,13 +1069,13 @@ Note that amputating the affected organ does in fact remove the infection from t
return
if(owner)
if(type == "brute")
- owner.visible_message("\red You hear a sickening cracking sound coming from \the [owner]'s [name].", \
- "\red Your [name] becomes a mangled mess!", \
- "\red You hear a sickening crack.")
+ owner.visible_message("You hear a sickening cracking sound coming from \the [owner]'s [name].", \
+ "Your [name] becomes a mangled mess!", \
+ "You hear a sickening crack.")
else
- owner.visible_message("\red \The [owner]'s [name] melts away, turning into mangled mess!", \
- "\red Your [name] melts away!", \
- "\red You hear a sickening sizzle.")
+ owner.visible_message("\The [owner]'s [name] melts away, turning into mangled mess!", \
+ "Your [name] melts away!", \
+ "You hear a sickening sizzle.")
disfigured = 1
/obj/item/organ/external/proc/get_wounds_desc()
@@ -1098,6 +1155,12 @@ Note that amputating the affected organ does in fact remove the infection from t
parent_organ = null
encased = "ribcage"
+/obj/item/organ/external/chest/robotize()
+ if(..())
+ // Give them a new cell.
+ owner.internal_organs_by_name["cell"] = new /obj/item/organ/cell(owner,1)
+
+
/obj/item/organ/external/groin
name = "lower body"
limb_name = "groin"
@@ -1224,6 +1287,8 @@ Note that amputating the affected organ does in fact remove the infection from t
gendered_icon = 1
encased = "skull"
+ var/eye_icon = "eyes_s"
+
/obj/item/organ/external/head/removed()
if(owner)
name = "[owner.real_name]'s head"
@@ -1244,3 +1309,32 @@ Note that amputating the affected organ does in fact remove the infection from t
disfigure("brute")
if (burn_dam > 40)
disfigure("burn")
+
+/obj/item/organ/external/head/skrell
+ eye_icon = "skrell_eyes_s"
+
+/obj/item/organ/external/head/resomi
+ eye_icon = "eyes_resomi"
+
+/obj/item/organ/external/head/vox
+ eye_icon = "vox_eyes_s"
+
+/obj/item/organ/external/head/no_eyes
+ eye_icon = "blank_eyes"
+
+/obj/item/organ/external/head/no_eyes/diona
+ max_damage = 50
+ min_broken_damage = 25
+ cannot_break = 1
+ amputation_point = "branch"
+ joint = "structural ligament"
+ dislocated = -1
+ vital = 0
+
+/obj/item/organ/external/head/no_eyes/diona/removed()
+ var/mob/living/carbon/human/H = owner
+ ..()
+ if(!istype(H) || !H.organs || !H.organs.len)
+ H.death()
+ if(prob(50) && spawn_diona_nymph(get_turf(src)))
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index bcc8de7694..4faa796107 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -53,10 +53,10 @@ var/global/list/limb_icon_cache = list()
overlays.Cut()
if(!owner || !owner.species)
return
- if(owner.species.has_organ["eyes"])
+ if(owner.should_have_organ("eyes"))
var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"]
- if(species.eyes)
- var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes)
+ if(eye_icon)
+ var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', eye_icon)
if(eyes)
eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD)
else
@@ -91,7 +91,7 @@ var/global/list/limb_icon_cache = list()
var/gender
if(force_icon)
- mob_icon = new /icon(force_icon, "[icon_name]")
+ mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_f" : ""]")
else
if(!dna)
mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]")
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index 39a8a142cf..cfd7ec78f7 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -70,6 +70,13 @@
parent_organ = "head"
var/list/eye_colour = list(0,0,0)
+/obj/item/organ/eyes/robotize()
+ ..()
+ name = "optical sensor"
+ icon = 'icons/obj/robot_component.dmi'
+ icon_state = "camera"
+ dead_icon = "camera_broken"
+
/obj/item/organ/eyes/proc/update_colour()
if(!owner)
return
@@ -109,7 +116,7 @@
if (germ_level > INFECTION_LEVEL_ONE)
if(prob(1))
- owner << "\red Your skin itches."
+ owner << "Your skin itches."
if (germ_level > INFECTION_LEVEL_TWO)
if(prob(1))
spawn owner.vomit()
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index e4e024be10..280ea53f49 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 774f7a5261..47ae475735 100644
--- a/code/modules/organs/robolimbs.dm
+++ b/code/modules/organs/robolimbs.dm
@@ -41,4 +41,3 @@ var/global/datum/robolimb/basic_robolimb
company = "Morpheus Cyberkinetics"
desc = "This limb is simple and functional; no effort has been made to make it look human."
icon = 'icons/mob/human_races/cyberlimbs/ipc.dmi'
- unavailable_at_chargen = 1
diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm
index edef9801c5..5d77383d2a 100644
--- a/code/modules/organs/subtypes/diona.dm
+++ b/code/modules/organs/subtypes/diona.dm
@@ -122,22 +122,6 @@
body_part = HAND_RIGHT
parent_organ = "r_arm"
-/obj/item/organ/external/diona/head
- limb_name = "head"
- icon_name = "head"
- name = "head"
- max_damage = 50
- min_broken_damage = 25
- w_class = 3
- body_part = HEAD
- parent_organ = "chest"
-
-/obj/item/organ/external/diona/head/removed()
- if(owner)
- owner.u_equip(owner.head)
- owner.u_equip(owner.l_ear)
- ..()
-
//DIONA ORGANS.
/obj/item/organ/external/diona/removed()
var/mob/living/carbon/human/H = owner
diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm
index fd94c2c759..3d551a3760 100644
--- a/code/modules/organs/subtypes/machine.dm
+++ b/code/modules/organs/subtypes/machine.dm
@@ -1,77 +1,3 @@
-// IPC limbs.
-/obj/item/organ/external/head/ipc
- dislocated = -1
- can_intake_reagents = 0
- vital = 0
- max_damage = 50 //made same as arm, since it is not vital
- min_broken_damage = 30
- encased = null
-
-/obj/item/organ/external/head/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/chest/ipc
- dislocated = -1
- encased = null
-/obj/item/organ/external/chest/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/groin/ipc
- dislocated = -1
-/obj/item/organ/external/groin/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/arm/ipc
- dislocated = -1
-/obj/item/organ/external/arm/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/arm/right/ipc
- dislocated = -1
-/obj/item/organ/external/arm/right/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/leg/ipc
- dislocated = -1
-/obj/item/organ/external/leg/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/leg/right/ipc
- dislocated = -1
-/obj/item/organ/external/leg/right/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/foot/ipc
- dislocated = -1
-/obj/item/organ/external/foot/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/foot/right/ipc
- dislocated = -1
-/obj/item/organ/external/foot/right/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/hand/ipc
- dislocated = -1
-/obj/item/organ/external/hand/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
-/obj/item/organ/external/hand/right/ipc
- dislocated = -1
-/obj/item/organ/external/hand/right/ipc/New()
- robotize("Morpheus Cyberkinetics")
- ..()
-
/obj/item/organ/cell
name = "microbattery"
desc = "A small, powerful cell for use in fully prosthetic bodies."
@@ -92,34 +18,59 @@
owner.stat = 0
owner.visible_message("\The [owner] twitches visibly!")
-/obj/item/organ/optical_sensor
- name = "optical sensor"
- organ_tag = "eyes"
- parent_organ = "head"
- icon = 'icons/obj/robot_component.dmi'
- icon_state = "camera"
- dead_icon = "camera_broken"
-
-/obj/item/organ/optical_sensor/New()
- robotize()
- ..()
-
// Used for an MMI or posibrain being installed into a human.
/obj/item/organ/mmi_holder
name = "brain"
organ_tag = "brain"
- parent_organ = "chest"
+ parent_organ = "head"
vital = 1
var/obj/item/device/mmi/stored_mmi
+/obj/item/organ/mmi_holder/Destroy()
+ stored_mmi = null
+ return ..()
+
+/obj/item/organ/mmi_holder/New()
+ ..()
+ if(!stored_mmi)
+ stored_mmi = new(src)
+
+ spawn(1)
+
+ if(!owner)
+ if(stored_mmi)
+ stored_mmi.loc = get_turf(src)
+ qdel(src)
+ return
+
+ update_from_mmi()
+ if(stored_mmi.brainmob && owner && owner.stat == DEAD)
+ owner.stat = 0
+ owner.visible_message("\The [owner] twitches visibly!")
+
/obj/item/organ/mmi_holder/proc/update_from_mmi()
+
if(!stored_mmi)
return
+
+ if(!stored_mmi.brainmob)
+ stored_mmi.brainmob = new(src)
+
+ stored_mmi.brainmob.real_name = owner.name
+ stored_mmi.brainmob.name = stored_mmi.brainmob.real_name
+
+ if(owner)
+ stored_mmi.name = "[initial(stored_mmi.name)] ([owner.name])"
+
name = stored_mmi.name
desc = stored_mmi.desc
icon = stored_mmi.icon
icon_state = stored_mmi.icon_state
+/obj/item/organ/mmi_holder/removed()
+ update_from_mmi()
+ return ..()
+
/obj/item/organ/mmi_holder/removed(var/mob/living/user)
if(stored_mmi)
@@ -133,25 +84,9 @@
holder_mob.drop_from_inventory(src)
qdel(src)
-/obj/item/organ/mmi_holder/New()
- ..()
- // This is very ghetto way of rebooting an IPC. TODO better way.
- spawn(1)
- if(owner && owner.stat == DEAD)
- owner.stat = 0
- owner.visible_message("\The [owner] twitches visibly!")
+/obj/item/organ/mmi_holder/posibrain
+ name = "positronic brain"
/obj/item/organ/mmi_holder/posibrain/New()
- robotize()
stored_mmi = new /obj/item/device/mmi/digital/posibrain(src)
..()
- spawn(1)
- if(owner)
- stored_mmi.name = "positronic brain ([owner.name])"
- stored_mmi.brainmob.real_name = owner.name
- stored_mmi.brainmob.name = stored_mmi.brainmob.real_name
- stored_mmi.icon_state = "posibrain-occupied"
- update_from_mmi()
- else
- stored_mmi.loc = get_turf(src)
- qdel(src)
\ No newline at end of file
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 25c8c4827f..12c48a7826 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -119,6 +119,7 @@ By design, d1 is the smallest direction and d2 is the highest
// - Cable coil : merge cables
// - Multitool : get the power currently passing through the cable
//
+
/obj/structure/cable/attackby(obj/item/W, mob/user)
var/turf/T = src.loc
@@ -512,14 +513,18 @@ obj/structure/cable/proc/cableColor(var/colorC)
///////////////////////////////////
//you can use wires to heal robotics
+/obj/item/stack/cable_coil/attack(var/atom/A, var/mob/living/user, var/def_zone)
+ if(ishuman(A) && user.a_intent == I_HELP)
+ return
+ return ..()
+
/obj/item/stack/cable_coil/afterattack(var/mob/M, var/mob/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting]
- if (!S) return
- if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
+ if(!S || !(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP)
return ..()
if(S.burn_dam)
@@ -528,10 +533,9 @@ obj/structure/cable/proc/cableColor(var/colorC)
user.visible_message("\The [user] repairs some burn damage on \the [M]'s [S.name] with \the [src].")
else if(S.open != 2)
user << "The damage is far too severe to patch over externally."
- return 1
else if(S.open != 2)
user << "Nothing to fix!"
-
+ return
else
return ..()
diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm
index c643e94dcc..45e8910b38 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 4ed12a2846..f13c216945 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -70,8 +70,10 @@
infect_virus2(M, V.getcopy())
/datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
- if(alien == IS_MACHINE)
- return
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.check_is_prosthetic())
+ return
if(data && data["viruses"])
for(var/datum/disease/D in data["viruses"])
if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS)
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index 87897fd9a8..88f314c99d 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -328,7 +328,7 @@
if(affecting.take_damage(0, removed * power * 0.1))
H.UpdateDamageIcon()
if(prob(100 * removed / meltdose)) // Applies disfigurement
- if (!(H.species && (H.species.flags & NO_PAIN)))
+ if (affecting.can_feel_pain())
H.emote("scream")
H.status_flags |= DISFIGURED
else
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
index 0bfa1b4006..6c169852b9 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
@@ -233,12 +233,13 @@
M.adjustToxLoss(0.5 * removed)
/datum/reagent/capsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
- if(alien == IS_DIONA || alien == IS_MACHINE)
+ if(alien == IS_DIONA)
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species && (H.species.flags & (NO_PAIN)))
+ if(!H.can_feel_pain())
return
+
if(dose < 5 && (dose == metabolism || prob(5)))
M << "Your insides feel uncomfortably hot!"
if(dose >= 5)
@@ -268,7 +269,7 @@
var/obj/item/safe_thing = null
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species && (H.species.flags & NO_PAIN))
+ if(!H.can_feel_pain())
return
if(H.head)
if(H.head.body_parts_covered & EYES)
@@ -314,7 +315,7 @@
/datum/reagent/condensedcapsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species && (H.species.flags & (NO_PAIN)))
+ if(!H.can_feel_pain())
return
if(dose == metabolism)
M << "You feel like your insides are burning!"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 1c4abbdfe8..b392e789e0 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -274,7 +274,7 @@
var/mob/living/carbon/human/H = M
for(var/obj/item/organ/I in H.internal_organs)
- if((I.damage > 0) && (I.robotic != 2)) //Peridaxon heals only non-robotic organs
+ if((I.damage > 0) && !(I.status & ORGAN_ROBOT)) //Peridaxon heals only non-robotic organs
I.damage = max(I.damage - removed, 0)
/datum/reagent/ryetalyn
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index d981734ec9..3de830f644 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -234,9 +234,14 @@
affect_blood(M, alien, removed)
/datum/reagent/mutagen/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+
+ if(M.isSynthetic())
+ return
+
var/mob/living/carbon/human/H = M
if(istype(H) && (H.species.flags & NO_SCAN))
return
+
if(M.dna)
if(prob(removed * 0.1)) // Approx. one mutation per 10 injected/20 ingested/30 touching units
randmuti(M)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 19ac8c62fb..75ef62894d 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -96,7 +96,7 @@
var/datum/reagent/B
if(istype(T, /mob/living/carbon/human))
var/mob/living/carbon/human/H = T
- if(H.species && H.species.flags & NO_BLOOD)
+ if(H.species && !H.should_have_organ("heart"))
H.reagents.trans_to_obj(src, amount)
else
B = T.take_blood(src, amount)
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index 25addbd40a..823561b5d8 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -142,7 +142,6 @@
affected.status &= ~ORGAN_BROKEN
affected.status &= ~ORGAN_SPLINTED
affected.stage = 0
- affected.perma_injury = 0
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index d1becd0cbf..0fef3de54c 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -51,9 +51,6 @@
//Could be cleaner ...
affected.open = 1
- if(istype(target) && !(target.species.flags & NO_BLOOD))
- affected.status |= ORGAN_BLEEDING
-
affected.createwound(CUT, 1)
affected.clamp()
spread_germs_to_organ(affected, user)
@@ -91,7 +88,7 @@
"\blue You have constructed a prepared incision on and within [target]'s [affected.name] with \the [tool].",)
affected.open = 1
- if(istype(target) && !(target.species.flags & NO_BLOOD))
+ if(istype(target) && target.should_have_organ("heart"))
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1)
@@ -133,7 +130,7 @@
"\blue You have made an incision on [target]'s [affected.name] with \the [tool].",)
affected.open = 1
- if(istype(target) && !(target.species.flags & NO_BLOOD))
+ if(istype(target) && target.should_have_organ("heart"))
affected.status |= ORGAN_BLEEDING
affected.createwound(CUT, 1)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index f0025b7429..e074cbcca5 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -91,7 +91,7 @@
for(var/obj/item/organ/I in affected.internal_organs)
if(I && I.damage > 0)
- if(I.robotic < 2)
+ if(!(I.status & ORGAN_ROBOT))
user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \
"You start treating damage to [target]'s [I.name] with [tool_name]." )
@@ -111,7 +111,7 @@
for(var/obj/item/organ/I in affected.internal_organs)
if(I && I.damage > 0)
- if(I.robotic < 2)
+ if(!(I.status & ORGAN_ROBOT))
user.visible_message("[user] treats damage to [target]'s [I.name] with [tool_name].", \
"You treat damage to [target]'s [I.name] with [tool_name]." )
I.damage = 0
@@ -285,7 +285,7 @@
if(O.organ_tag == "limb")
return 0
- else if(target.species.has_organ[O.organ_tag])
+ else if(target.should_have_organ(O.organ_tag))
if(O.damage > (O.max_damage * 0.75))
user << "\The [O.organ_tag] [o_is] in no state to be transplanted."
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 24bc848472..1ad2aec24f 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -212,7 +212,7 @@
if(!affected) return
var/is_organ_damaged = 0
for(var/obj/item/organ/I in affected.internal_organs)
- if(I.damage > 0 && I.robotic >= 2)
+ if(I.damage > 0 && (I.status & ORGAN_ROBOT))
is_organ_damaged = 1
break
return affected.open == 2 && is_organ_damaged
@@ -225,7 +225,7 @@
for(var/obj/item/organ/I in affected.internal_organs)
if(I && I.damage > 0)
- if(I.robotic >= 2)
+ if(I.status & ORGAN_ROBOT)
user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
"You start mending the damage to [target]'s [I.name]'s mechanisms." )
@@ -241,7 +241,7 @@
for(var/obj/item/organ/I in affected.internal_organs)
if(I && I.damage > 0)
- if(I.robotic >= 2)
+ if(I.status & ORGAN_ROBOT)
user.visible_message("[user] repairs [target]'s [I.name] with [tool].", \
"You repair [target]'s [I.name] with [tool]." )
I.damage = 0
@@ -393,7 +393,7 @@
user << "You have no idea what species this person is. Report this on the bug tracker."
return SURGERY_FAILURE
- if(!target.species.has_organ["brain"])
+ if(!target.should_have_organ("brain"))
user << "You're pretty sure [target.species.name_plural] don't normally have a brain."
return SURGERY_FAILURE
diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm
index dad0a30925..b36da37d6f 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 81a57dd300..b6e56d231b 100644
--- a/code/modules/virus2/disease2.dm
+++ b/code/modules/virus2/disease2.dm
@@ -45,7 +45,7 @@
var/list/res = list()
for (var/specie in all_species)
var/datum/species/S = all_species[specie]
- if(!S.virus_immune)
+ if(!S.get_virus_immune())
meat += S
if(meat.len)
var/num = rand(1,meat.len)
@@ -71,7 +71,7 @@
// Some species are flat out immune to organic viruses.
var/mob/living/carbon/human/H = mob
- if(istype(H) && H.species.virus_immune)
+ if(istype(H) && H.species.get_virus_immune(H))
cure(mob)
return
diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm
index 1cd185a32b..4daae5c5e2 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 d318ca9f8a..69ede1d494 100644
--- a/code/modules/virus2/items_devices.dm
+++ b/code/modules/virus2/items_devices.dm
@@ -16,7 +16,7 @@
var/mob/living/carbon/C = M
if (istype(C,/mob/living/carbon/human/))
var/mob/living/carbon/human/H = C
- if(H.species.flags & NO_BLOOD)
+ if(!H.should_have_organ("heart"))
report("Scan aborted: The target does not have blood.", user)
return
diff --git a/icons/mob/human_races/cyberlimbs/bishop.dmi b/icons/mob/human_races/cyberlimbs/bishop.dmi
index 045c3a5724..ebc132f554 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 5fbcd15861..225b18f5b9 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 b0ae673917..7af14de51f 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 daf10298c2..6c230675c3 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 a94eacc48a..7ee24241b9 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_machine.dmi b/icons/mob/human_races/r_machine.dmi
deleted file mode 100644
index 65f66c3238..0000000000
Binary files a/icons/mob/human_races/r_machine.dmi and /dev/null differ