diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 7819a34e1a..963b07df0f 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -296,7 +296,8 @@
"tg_diseases_list" = H.viruses.Copy(),
"lung_ruptured" = H.is_lung_ruptured(),
"external_organs" = H.organs.Copy(),
- "internal_organs" = H.internal_organs.Copy()
+ "internal_organs" = H.internal_organs.Copy(),
+ "species_organs" = H.species.has_organ //Just pass a reference for this, it shouldn't ever be modified outside of the datum.
)
return occupant_data
@@ -413,6 +414,7 @@
dat += ""
for(var/datum/organ/internal/i in occ["internal_organs"])
+
var/mech = ""
if(i.robotic == 1)
mech = "Assisted:"
@@ -439,6 +441,11 @@
dat += ""
dat += ""
+ var/list/species_organs = occ["species_organs"]
+ for(var/organ_name in species_organs)
+ if(!locate(species_organs[organ_name]) in occ["internal_organs"])
+ dat += text("No [organ_name] detected.
")
+
if(occ["sdisabilities"] & BLIND)
dat += text("Cataracts detected.
")
if(occ["sdisabilities"] & NEARSIGHTED)
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 383d20ff18..feae925a86 100755
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -22,12 +22,16 @@
if(istype(player,/mob/dead))
understood = 1
- else if(src in player.languages)
+ else if((src in player.languages) && check_special_condition(player))
understood = 1
if(understood)
if(!speaker_mask) speaker_mask = speaker.name
- player << "[name], [speaker_mask] [speech_verb], \"[message]\""
+ var/msg = "[name], [speaker_mask] [speech_verb], \"[message]\""
+ player << "[msg]"
+
+/datum/language/proc/check_special_condition(var/mob/other)
+ return 1
/datum/language/unathi
name = "Sinta'unathi"
@@ -99,6 +103,16 @@
key = "a"
flags = RESTRICTED | HIVEMIND
+/datum/language/xenos/check_special_condition(var/mob/other)
+
+ var/mob/living/carbon/M = other
+ if(!istype(M))
+ return 1
+ if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs)
+ return 1
+
+ return 0
+
/datum/language/ling
name = "Changeling"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
@@ -116,7 +130,7 @@
/datum/language/corticalborer
name = "Cortical Link"
- desc = "Cortical borers possess a strange between their tiny minds."
+ desc = "Cortical borers possess a strange link between their tiny minds."
speech_verb = "sings"
colour = "alien"
key = "x"
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index f822078885..e58e193a6e 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -12,6 +12,9 @@
if(stat == 2)
return say_dead(message)
+ if(copytext(message,1,2) == "*")
+ return emote(copytext(message,2))
+
var/datum/language/speaking = null
if(length(message) >= 2)
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index ae2ed01192..5daa904bf6 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -23,9 +23,15 @@
attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO
- if(!O:brainmob)
+
+ var/obj/item/organ/brain/B = O
+ if(B.health <= 0)
+ user << "\red That brain is well and truly dead."
+ return
+ else if(!B:brainmob)
user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain."
return
+
for(var/mob/V in viewers(src, null))
V.show_message(text("\blue [user] sticks \a [O] into \the [src]."))
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index d2ba4fbb94..382af96282 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -17,6 +17,12 @@
var/mob/living/carbon/brain/brainmob = null
+/obj/item/organ/brain/xeno
+ name = "thinkpan"
+ desc = "It looks kind of like an enormous wad of purple bubblegum."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "chitin"
+
/obj/item/organ/brain/New()
..()
spawn(5)
diff --git a/code/modules/mob/living/carbon/human/alien/alien.dm b/code/modules/mob/living/carbon/human/alien/alien.dm
index 4c5c9e739b..e1caf89324 100644
--- a/code/modules/mob/living/carbon/human/alien/alien.dm
+++ b/code/modules/mob/living/carbon/human/alien/alien.dm
@@ -23,10 +23,6 @@ proc/create_new_xenomorph(var/alien_caste,var/target)
h_style = "Bald"
..(new_loc, "Xenomorph Queen")
-/mob/living/carbon/human/Stat()
-
- ..()
-
// I feel like we should generalize/condense down all the various icon-rendering antag procs.
/*----------------------------------------
Proc: AddInfectionImages()
diff --git a/code/modules/mob/living/carbon/human/alien/alien_species.dm b/code/modules/mob/living/carbon/human/alien/alien_species.dm
index c1c820a17f..09c8a19b13 100644
--- a/code/modules/mob/living/carbon/human/alien/alien_species.dm
+++ b/code/modules/mob/living/carbon/human/alien/alien_species.dm
@@ -6,6 +6,7 @@
secondary_unarmed_type = /datum/unarmed_attack/bite/strong
hud_type = /datum/hud_data/alien
rarity_value = 3
+ speaks_common = 0
has_fine_manipulation = 0
insulated = 1
@@ -40,7 +41,7 @@
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
- "brain" = /datum/organ/internal/brain,
+ "brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel,
"hive node" = /datum/organ/internal/xenos/hivenode,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
@@ -51,6 +52,18 @@
var/weeds_heal_rate = 1 // Health regen on weeds.
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
+/datum/species/xenos/can_understand(var/mob/other)
+
+ if(istype(other,/mob/living/carbon/alien/larva))
+ return 1
+
+ if(istype(other,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = other
+ if(istype(H.species,/datum/species/xenos))
+ return 1
+
+ return 0
+
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
H.visible_message("[H] caresses [target] with its scythe-like arm.", \
"You caress [target] with your scythe-like arm.")
@@ -109,7 +122,7 @@
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
- "brain" = /datum/organ/internal/brain,
+ "brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
"acid gland" = /datum/organ/internal/xenos/acidgland,
"hive node" = /datum/organ/internal/xenos/hivenode,
@@ -148,7 +161,7 @@
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
- "brain" = /datum/organ/internal/brain,
+ "brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/hunter,
"hive node" = /datum/organ/internal/xenos/hivenode,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
@@ -176,7 +189,7 @@
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
- "brain" = /datum/organ/internal/brain,
+ "brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/sentinel,
"acid gland" = /datum/organ/internal/xenos/acidgland,
"hive node" = /datum/organ/internal/xenos/hivenode,
@@ -207,7 +220,7 @@
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
- "brain" = /datum/organ/internal/brain,
+ "brain" = /datum/organ/internal/brain/xeno,
"egg sac" = /datum/organ/internal/xenos/eggsac,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
"acid gland" = /datum/organ/internal/xenos/acidgland,
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 70ba0805f5..3a2e262253 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -435,6 +435,7 @@
proc/handle_breath(datum/gas_mixture/breath)
+
if(status_flags & GODMODE)
return
@@ -456,7 +457,17 @@
return 0
var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa
- //var/safe_pressure_max = 140 // Maximum safe partial pressure of breathable gas in kPa (Not used for now)
+
+ // Lung damage increases the minimum safe pressure.
+ if(species.has_organ["lungs"])
+ var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
+ if(!L)
+ safe_pressure_min = INFINITY //No lungs, how are you breathing?
+ else if(L.is_broken())
+ safe_pressure_min *= 1.5
+ else if(L.is_bruised())
+ safe_pressure_min *= 1.25
+
var/safe_exhaled_max = 10
var/safe_toxins_max = 0.005
var/SA_para_min = 1
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 21b336a650..35c310c5de 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -169,6 +169,9 @@
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
return 1
+ if(species.can_understand(other))
+ return 1
+
//These only pertain to common. Languages are handled by mob/say_understands()
if (!speaking)
if (istype(other, /mob/living/carbon/alien/diona))
@@ -180,6 +183,10 @@
return 1
if (istype(other, /mob/living/carbon/slime))
return 1
+ if(istype(other,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = other
+ if(!species.speaks_common || !H.species.speaks_common)
+ return 0
//This is already covered by mob/say_understands()
//if (istype(other, /mob/living/simple_animal))
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 6b4e3b4586..895e0234d3 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -24,6 +24,7 @@
var/unarmed_type = /datum/unarmed_attack
var/secondary_unarmed_type = /datum/unarmed_attack/bite
+ var/speaks_common = 1 // Speaks the common galactic tongue.
var/secondary_langs = list() // The names of secondary languages that are available to this species.
var/mutantrace // Safeguard due to old code.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
@@ -194,6 +195,10 @@
/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H)
return
+//Used by xenos understanding larvae and dionaea understanding nymphs.
+/datum/species/proc/can_understand(var/mob/other)
+ return
+
/datum/species/human
name = "Human"
language = "Sol Common"
@@ -395,6 +400,12 @@
reagent_tag = IS_DIONA
+/datum/species/diona/can_understand(var/mob/other)
+ var/mob/living/carbon/alien/diona/D = other
+ if(istype(D))
+ return 1
+ return 0
+
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
index 8eb5f12a31..8ca87ef3ba 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/organ_alien.dm
@@ -56,11 +56,13 @@
del(src)
-//These are different to the standard diona organs as they have a purpose in other
+// These are different to the standard diona organs as they have a purpose in other
// species (absorbing radiation and light respectively)
/obj/item/organ/diona/nutrients
name = "nutrient vessel"
organ_tag = "nutrient vessel"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "claw"
/obj/item/organ/diona/nutrients/removed()
return
@@ -68,6 +70,8 @@
/obj/item/organ/diona/node
name = "receptor node"
organ_tag = "receptor node"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "claw"
/obj/item/organ/diona/node/removed()
return
@@ -88,11 +92,14 @@
// They're also super gross and ooze ichor.
if(prob(5))
- var/obj/effect/decal/cleanable/blood/splatter/goo = new(get_turf(owner))
- goo.name = "husk ichor"
- goo.desc = "It's thick and stinks of decay."
- goo.basecolor = "#412464"
- goo.update_icon()
+ var/datum/reagent/blood = owner.reagents.reagent_list["blood"]
+ blood_splatter(owner,blood,1)
+ var/obj/effect/decal/cleanable/blood/splatter/goo = locate() in get_turf(owner)
+ if(goo)
+ goo.name = "husk ichor"
+ goo.desc = "It's thick and stinks of decay."
+ goo.basecolor = "#412464"
+ goo.update_icon()
/obj/item/organ/borer
name = "cortical borer"
@@ -103,7 +110,6 @@
/obj/item/organ/borer/removed(var/mob/living/target,var/mob/living/user)
-
..()
var/mob/living/simple_animal/borer/B = target.has_brain_worms()
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index 39840c88f0..5605f8c40f 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -249,6 +249,9 @@
removed_type = /obj/item/organ/brain
vital = 1
+/datum/organ/internal/brain/xeno
+ removed_type = /obj/item/organ/brain/xeno
+
/datum/organ/internal/eyes
name = "eyes"
parent_organ = "head"
diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm
index c48a9d4b54..ea49f7276a 100644
--- a/code/modules/organs/organ_objects.dm
+++ b/code/modules/organs/organ_objects.dm
@@ -97,6 +97,7 @@
/obj/item/organ/lungs
name = "lungs"
icon_state = "lungs"
+ gender = PLURAL
prosthetic_name = "gas exchange system"
prosthetic_icon = "lungs-prosthetic"
organ_tag = "lungs"
@@ -104,6 +105,7 @@
/obj/item/organ/kidneys
name = "kidneys"
icon_state = "kidneys"
+ gender = PLURAL
prosthetic_name = "prosthetic kidneys"
prosthetic_icon = "kidneys-prosthetic"
organ_tag = "kidneys"
@@ -111,6 +113,7 @@
/obj/item/organ/eyes
name = "eyeballs"
icon_state = "eyes"
+ gender = PLURAL
prosthetic_name = "visual prosthesis"
prosthetic_icon = "eyes-prosthetic"
organ_tag = "eyes"
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 1d8fa06e53..e2ad2be210 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -365,25 +365,33 @@
if(!istype(O))
return 0
- if(target.species && target.species.has_organ[O.organ_tag])
+ if(!target.species)
+ user << "\red You have no idea what species this person is. Report this on the bug tracker."
+ return 0
+
+ var/o_is = (O.gender == PLURAL) ? "are" : "is"
+ var/o_a = (O.gender == PLURAL) ? "" : " a"
+ var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't"
+
+ if(target.species.has_organ[O.organ_tag])
if(!O.health)
- user << "\red \The [O.organ_tag] is dead."
+ user << "\red \The [O.organ_tag] [o_is] in no state to be transplanted."
return 0
if(!target.internal_organs_by_name[O.organ_tag])
organ_missing = 1
else
- user << "\red \The [target] already has a [O.organ_tag]." //TODO: grammar.
+ user << "\red \The [target] already has [o_a][O.organ_tag]."
return 0
if(O.organ_data && affected.name == O.organ_data.parent_organ)
organ_compatible = 1
else
- user << "\red \The [O.organ_tag] doesn't normally go in \the [affected.display_name]."
+ user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.display_name]."
return 0
else
- user << "\red \A [target.species.name] doesn't normally have a [O.organ_tag]." //TODO: grammar.
+ user << "\red \A [target.species.name] doesn't normally have [o_a][O.organ_tag]."
return 0
return ..() && organ_missing && organ_compatible
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 58a7aaf25c..202ec39bc8 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ