12/21 modernizations from TG live (#103)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes
This commit is contained in:
Poojawa
2016-12-22 03:57:55 -06:00
committed by GitHub
parent f5e143a452
commit cf59ac1c3d
2215 changed files with 707445 additions and 87041 deletions
+74 -17
View File
@@ -4,7 +4,7 @@
zone = "r_arm"
slot = "r_arm_device"
icon_state = "implant-toolkit"
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/organ_action/toggle)
var/list/items_list = list()
@@ -64,12 +64,16 @@
if(!holder || (holder in src))
return
owner.visible_message("<span class='notice'>[owner] retracts [holder] back into \his [zone == "r_arm" ? "right" : "left"] arm.</span>",
owner.visible_message("<span class='notice'>[owner] retracts [holder] back into [owner.p_their()] [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='notice'>[holder] snaps back into your [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='italics'>You hear a short mechanical noise.</span>")
if(istype(holder, /obj/item/device/assembly/flash/armimplant))
var/obj/item/device/assembly/flash/F = holder
F.SetLuminosity(0)
owner.unEquip(holder, 1)
holder.loc = src
holder.forceMove(src)
holder = null
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
@@ -80,13 +84,16 @@
holder = item
holder.flags |= NODROP
holder.unacidable = 1
holder.resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
holder.slot_flags = null
holder.w_class = 5
holder.w_class = WEIGHT_CLASS_HUGE
holder.materials = null
var/arm_slot = (zone == "r_arm" ? slot_r_hand : slot_l_hand)
var/obj/item/arm_item = owner.get_item_by_slot(arm_slot)
if(istype(holder, /obj/item/device/assembly/flash/armimplant))
var/obj/item/device/assembly/flash/F = holder
F.SetLuminosity(7)
var/obj/item/arm_item = owner.get_active_held_item()
if(arm_item)
if(!owner.unEquip(arm_item))
@@ -95,15 +102,15 @@
else
owner << "<span class='notice'>You drop [arm_item] to activate [src]!</span>"
if(zone == "r_arm" ? !owner.put_in_r_hand(holder) : !owner.put_in_l_hand(holder))
var/result = (zone == "r_arm" ? owner.put_in_r_hand(holder) : owner.put_in_l_hand(holder))
if(!result)
owner << "<span class='warning'>Your [src] fails to activate!</span>"
return
// Activate the hand that now holds our item.
if(zone == "r_arm" ? owner.hand : !owner.hand)
owner.swap_hand()
owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow
owner.visible_message("<span class='notice'>[owner] extends [holder] from \his [zone == "r_arm" ? "right" : "left"] arm.</span>",
owner.visible_message("<span class='notice'>[owner] extends [holder] from [owner.p_their()] [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='notice'>You extend [holder] from your [zone == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='italics'>You hear a short mechanical noise.</span>")
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
@@ -114,8 +121,7 @@
return
// You can emag the arm-mounted implant by activating it while holding emag in it's hand.
var/arm_slot = (zone == "r_arm" ? slot_r_hand : slot_l_hand)
if(istype(owner.get_item_by_slot(arm_slot), /obj/item/weapon/card/emag) && emag_act())
if(istype(owner.get_active_held_item(), /obj/item/weapon/card/emag) && emag_act())
return
if(!holder || (holder in src))
@@ -152,7 +158,8 @@
origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
holder = /obj/item/weapon/gun/energy/laser/mounted
/obj/item/organ/cyberimp/arm/gun/laser/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/laser/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/taser
@@ -160,9 +167,10 @@
desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use."
icon_state = "arm_taser"
origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
holder = /obj/item/weapon/gun/energy/gun/advtaser/mounted
holder = /obj/item/weapon/gun/energy/e_gun/advtaser/mounted
/obj/item/organ/cyberimp/arm/gun/taser/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/gun/taser/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset
@@ -172,7 +180,8 @@
contents = newlist(/obj/item/weapon/screwdriver/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/weldingtool/largetank/cyborg,
/obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, /obj/item/device/multitool/cyborg)
/obj/item/organ/cyberimp/arm/toolset/l/zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset/l
zone = "l_arm"
/obj/item/organ/cyberimp/arm/toolset/emag_act()
if(!(locate(/obj/item/weapon/kitchen/knife/combat/cyborg) in items_list))
@@ -180,3 +189,51 @@
items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src)
return 1
return 0
/obj/item/organ/cyberimp/arm/esword
name = "arm-mounted energy blade"
desc = "An illegal, and highly dangerous cybernetic implant that can project a deadly blade of concentrated enregy."
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight)
origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5"
/obj/item/organ/cyberimp/arm/medibeam
name = "integrated medical beamgun"
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
contents = newlist(/obj/item/weapon/gun/medbeam)
origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1"
/obj/item/organ/cyberimp/arm/flash
name = "integrated high-intensity photon projector" //Why not
desc = "An integrated projector mounted onto a user's arm, that is able to be used as a powerful flash."
contents = newlist(/obj/item/device/assembly/flash/armimplant)
origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3"
/obj/item/organ/cyberimp/arm/flash/New()
..()
if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
F.I = src
/obj/item/organ/cyberimp/arm/baton
name = "arm electrification implant"
desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
contents = newlist(/obj/item/borg/stun)
origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3"
/obj/item/organ/cyberimp/arm/combat
name = "combat cybernetics implant"
desc = "A powerful cybernetic implant that contains combat modules built into the user's arm"
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight, /obj/item/weapon/gun/medbeam, /obj/item/borg/stun, /obj/item/device/assembly/flash/armimplant)
origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5"
/obj/item/organ/cyberimp/arm/combat/New()
..()
if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
F.I = src
/obj/item/organ/cyberimp/arm/surgery
name = "surgical toolset implant"
desc = "A set of surgical tools hidden behind a concealed panel on the user's arm"
contents = newlist(/obj/item/weapon/retractor, /obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, /obj/item/weapon/circular_saw, /obj/item/weapon/surgical_drapes)
origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3"
@@ -14,7 +14,7 @@
var/synthesizing = 0
var/poison_amount = 5
slot = "stomach"
origin_tech = "materials=4;powerstorage=5;biotech=4"
origin_tech = "materials=2;powerstorage=2;biotech=2"
/obj/item/organ/cyberimp/chest/nutriment/on_life()
if(synthesizing)
@@ -41,14 +41,14 @@
implant_color = "#006607"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
origin_tech = "materials=4;powerstorage=5;biotech=5"
origin_tech = "materials=4;powerstorage=3;biotech=3"
/obj/item/organ/cyberimp/chest/reviver
name = "Reviver implant"
desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!"
icon_state = "chest_implant"
implant_color = "#AD0000"
origin_tech = "materials=5;programming=4;biotech=6"
origin_tech = "materials=5;programming=4;biotech=4"
slot = "heartdrive"
var/revive_cost = 0
var/reviving = 0
@@ -96,7 +96,7 @@
else
cooldown += 200
if(istype(owner, /mob/living/carbon/human))
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.stat != DEAD && prob(50 / severity))
H.heart_attack = TRUE
@@ -121,7 +121,7 @@
implant_overlay = null
implant_color = null
actions_types = list(/datum/action/item_action/organ_action/toggle)
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
var/on = 0
var/datum/effect_system/trail_follow/ion/ion_trail
@@ -197,3 +197,4 @@
toggle(silent=1)
return 0
+4 -4
View File
@@ -5,7 +5,7 @@
implant_overlay = "eye_implant_overlay"
slot = "eye_sight"
zone = "eyes"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/sight_flags = 0
var/dark_view = 0
@@ -18,7 +18,7 @@
/obj/item/organ/cyberimp/eyes/Insert(var/mob/living/carbon/M, var/special = 0)
..()
if(istype(owner, /mob/living/carbon/human) && eye_color)
if(ishuman(owner) && eye_color)
var/mob/living/carbon/human/HMN = owner
old_eye_color = HMN.eye_color
HMN.eye_color = eye_color
@@ -30,7 +30,7 @@
/obj/item/organ/cyberimp/eyes/Remove(var/mob/living/carbon/M, var/special = 0)
M.sight ^= sight_flags
if(istype(M,/mob/living/carbon/human) && eye_color)
if(ishuman(M) && eye_color)
var/mob/living/carbon/human/HMN = owner
HMN.eye_color = old_eye_color
HMN.regenerate_icons()
@@ -43,7 +43,7 @@
if(prob(10 * severity))
return
owner << "<span class='warning'>Static obfuscates your vision!</span>"
owner.flash_eyes(visual = 1)
owner.flash_act(visual = 1)
/obj/item/organ/cyberimp/eyes/xray
name = "X-ray implant"
@@ -26,7 +26,7 @@
icon_state = "brain_implant"
implant_overlay = "brain_implant_overlay"
zone = "head"
w_class = 1
w_class = WEIGHT_CLASS_TINY
/obj/item/organ/cyberimp/brain/emp_act(severity)
if(!owner)
@@ -41,10 +41,7 @@
name = "anti-drop implant"
desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle."
var/active = 0
var/l_hand_ignore = 0
var/r_hand_ignore = 0
var/obj/item/l_hand_obj = null
var/obj/item/r_hand_obj = null
var/list/stored_items = list()
implant_color = "#DE7E00"
slot = "brain_antidrop"
origin_tech = "materials=4;programming=5;biotech=4"
@@ -53,66 +50,41 @@
/obj/item/organ/cyberimp/brain/anti_drop/ui_action_click()
active = !active
if(active)
l_hand_obj = owner.l_hand
r_hand_obj = owner.r_hand
if(l_hand_obj)
if(owner.l_hand.flags & NODROP)
l_hand_ignore = 1
else
owner.l_hand.flags |= NODROP
l_hand_ignore = 0
for(var/obj/item/I in owner.held_items)
if(!(I.flags & NODROP))
stored_items += I
if(r_hand_obj)
if(owner.r_hand.flags & NODROP)
r_hand_ignore = 1
else
owner.r_hand.flags |= NODROP
r_hand_ignore = 0
if(!l_hand_obj && !r_hand_obj)
var/list/L = owner.get_empty_held_indexes()
if(L && L.len == owner.held_items.len)
owner << "<span class='notice'>You are not holding any items, your hands relax...</span>"
active = 0
stored_items = list()
else
var/msg = 0
msg += !l_hand_ignore && l_hand_obj ? 1 : 0
msg += !r_hand_ignore && r_hand_obj ? 2 : 0
switch(msg)
if(1)
owner << "<span class='notice'>Your left hand's grip tightens.</span>"
if(2)
owner << "<span class='notice'>Your right hand's grip tightens.</span>"
if(3)
owner << "<span class='notice'>Both of your hand's grips tighten.</span>"
for(var/obj/item/I in stored_items)
owner << "<span class='notice'>Your [owner.get_held_index_name(owner.get_held_index_of_item(I))]'s grip tightens.</span>"
else
release_items()
owner << "<span class='notice'>Your hands relax...</span>"
l_hand_obj = null
r_hand_obj = null
/obj/item/organ/cyberimp/brain/anti_drop/emp_act(severity)
if(!owner)
return
var/range = severity ? 10 : 5
var/atom/A
var/obj/item/L_item = owner.l_hand
var/obj/item/R_item = owner.r_hand
release_items()
..()
if(L_item)
for(var/obj/item/I in stored_items)
A = pick(oview(range))
L_item.throw_at(A, range, 2)
owner << "<span class='warning'>Your left arm spasms and throws the [L_item.name]!</span>"
if(R_item)
A = pick(oview(range))
R_item.throw_at(A, range, 2)
owner << "<span class='warning'>Your right arm spasms and throws the [R_item.name]!</span>"
I.throw_at(A, range, 2)
owner << "<span class='warning'>Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!</span>"
stored_items = list()
/obj/item/organ/cyberimp/brain/anti_drop/proc/release_items()
if(!l_hand_ignore && l_hand_obj in owner.contents)
l_hand_obj.flags ^= NODROP
if(!r_hand_ignore && r_hand_obj in owner.contents)
r_hand_obj.flags ^= NODROP
for(var/obj/item/I in stored_items)
I.flags ^= NODROP
/obj/item/organ/cyberimp/brain/anti_drop/Remove(var/mob/living/carbon/M, special = 0)
if(active)
@@ -156,7 +128,7 @@
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
icon_state = "implant_mask"
slot = "breathing_tube"
w_class = 1
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=2;biotech=3"
/obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity)
+2 -2
View File
@@ -5,7 +5,7 @@
desc = "A device that automatically injects a cyber-implant into the user without the hassle of extensive surgery. It has a slot to insert implants and a screwdriver slot for removing accidentally added implants."
icon_state = "autoimplanter"
item_state = "walkietalkie"//left as this so as to intentionally not have inhands
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/obj/item/organ/storedorgan
var/organ_type = /obj/item/organ/cyberimp
var/uses = INFINITE
@@ -51,7 +51,7 @@
var/turf/open/floorloc = get_turf(user)
floorloc.contents += contents
user << "<span class='notice'>You remove the [storedorgan] from [src].</span>"
playsound(get_turf(user), 'sound/items/Screwdriver.ogg', 50, 1)
playsound(get_turf(user), I.usesound, 50, 1)
storedorgan = null
if(uses != INFINITE)
uses--
+8 -11
View File
@@ -1,17 +1,17 @@
mob/proc/getorgan(typepath)
/mob/proc/getorgan(typepath)
return
mob/proc/getorganszone(zone)
/mob/proc/getorganszone(zone)
return
mob/proc/getorganslot(slot)
/mob/proc/getorganslot(slot)
return
mob/living/carbon/getorgan(typepath)
/mob/living/carbon/getorgan(typepath)
return (locate(typepath) in internal_organs)
mob/living/carbon/getorganszone(zone, var/subzones = 0)
/mob/living/carbon/getorganszone(zone, subzones = 0)
var/list/returnorg = list()
if(subzones)
// Include subzones - groin for chest, eyes and mouth for head
@@ -20,14 +20,11 @@ mob/living/carbon/getorganszone(zone, var/subzones = 0)
if(zone == "chest")
returnorg = getorganszone("groin")
for(var/obj/item/organ/O in internal_organs)
for(var/X in internal_organs)
var/obj/item/organ/O = X
if(zone == O.zone)
returnorg += O
return returnorg
mob/living/carbon/getorganslot(slot)
/mob/living/carbon/getorganslot(slot)
return internal_organs_slot[slot]
proc/isorgan(atom/A)
return istype(A, /obj/item/organ)
+269 -19
View File
@@ -4,8 +4,7 @@
var/mob/living/carbon/owner = null
var/status = ORGAN_ORGANIC
origin_tech = "biotech=3"
force = 1
w_class = 2
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
var/zone = "chest"
var/slot
@@ -165,7 +164,7 @@
/obj/item/organ/heart/cursed
name = "cursed heart"
desc = "it needs to be pumped..."
desc = "A heart that, when inserted, will force you to pump it manually."
icon_state = "cursedheart-off"
icon_base = "cursedheart"
origin_tech = "biotech=6"
@@ -193,7 +192,7 @@
if(world.time > (last_pump + pump_delay))
if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects.
var/mob/living/carbon/human/H = owner
if(H.dna && !(NOBLOOD in H.dna.species.specflags))
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
H.blood_volume = max(H.blood_volume - blood_loss, 0)
H << "<span class = 'userdanger'>You have to keep pumping your blood!</span>"
if(add_colour)
@@ -208,7 +207,7 @@
owner << "<span class ='userdanger'>Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!</span>"
/datum/action/item_action/organ_action/cursed_heart
name = "pump your blood"
name = "Pump your blood"
//You are now brea- pumping blood manually
/datum/action/item_action/organ_action/cursed_heart/Trigger()
@@ -226,7 +225,7 @@
var/mob/living/carbon/human/H = owner
if(istype(H))
if(H.dna && !(NOBLOOD in H.dna.species.specflags))
if(H.dna && !(NOBLOOD in H.dna.species.species_traits))
H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_MAXIMUM)
H.remove_client_colour(/datum/client_colour/cursed_heart_blood)
cursed_heart.add_colour = TRUE
@@ -239,7 +238,15 @@
priority = 100 //it's an indicator you're dieing, so it's very high priority
colour = "red"
#define HUMAN_MAX_OXYLOSS 3
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
#define HEAT_GAS_DAMAGE_LEVEL_1 2
#define HEAT_GAS_DAMAGE_LEVEL_2 4
#define HEAT_GAS_DAMAGE_LEVEL_3 8
#define COLD_GAS_DAMAGE_LEVEL_1 0.5
#define COLD_GAS_DAMAGE_LEVEL_2 1.5
#define COLD_GAS_DAMAGE_LEVEL_3 3
/obj/item/organ/lungs
name = "lungs"
@@ -247,13 +254,266 @@
zone = "chest"
slot = "lungs"
gender = PLURAL
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
var/list/breathlevels = list("safe_oxygen_min" = 16,"safe_oxygen_max" = 0,"safe_co2_min" = 0,"safe_co2_max" = 10,
"safe_toxins_min" = 0,"safe_toxins_max" = 0.05,"SA_para_min" = 1,"SA_sleep_min" = 5,"BZ_trip_balls_min" = 1)
//Breath damage
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
var/safe_oxygen_max = 0
var/safe_co2_min = 0
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_min = 0
var/safe_toxins_max = 0.05
var/SA_para_min = 1 //Sleeping agent
var/SA_sleep_min = 5 //Sleeping agent
var/BZ_trip_balls_min = 1 //BZ gas.
var/oxy_breath_dam_min = 1
var/oxy_breath_dam_max = 10
var/co2_breath_dam_min = 1
var/co2_breath_dam_max = 10
var/tox_breath_dam_min = MIN_PLASMA_DAMAGE
var/tox_breath_dam_max = MAX_PLASMA_DAMAGE
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, var/mob/living/carbon/human/H)
if((H.status_flags & GODMODE))
return
var/species_traits = list()
if(H && H.dna && H.dna.species && H.dna.species.species_traits)
species_traits = H.dna.species.species_traits
if(!breath || (breath.total_moles() == 0))
if(H.reagents.has_reagent("epinephrine"))
return
if(H.health >= HEALTH_THRESHOLD_CRIT)
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
else if(!(NOCRITDAMAGE in species_traits))
H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
H.failed_last_breath = 1
if(safe_oxygen_min)
H.throw_alert("oxy", /obj/screen/alert/oxy)
else if(safe_toxins_min)
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(safe_co2_min)
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
return 0
var/gas_breathed = 0
var/list/breath_gases = breath.gases
breath.assert_gases("o2", "plasma", "co2", "n2o", "bz")
//Partial pressures in our breath
var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES])
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES])
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES])
//-- OXY --//
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if(O2_pp > safe_oxygen_max)
var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10
H.adjustOxyLoss(Clamp(ratio,oxy_breath_dam_min,oxy_breath_dam_max))
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
else
H.clear_alert("too_much_oxy")
//Too little oxygen!
if(safe_oxygen_min)
if(O2_pp < safe_oxygen_min)
gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases["o2"][MOLES])
H.throw_alert("oxy", /obj/screen/alert/oxy)
else
H.failed_last_breath = 0
if(H.getOxyLoss())
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["o2"][MOLES]
H.clear_alert("oxy")
//Exhale
breath_gases["o2"][MOLES] -= gas_breathed
breath_gases["co2"][MOLES] += gas_breathed
gas_breathed = 0
//-- CO2 --//
//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
if(safe_co2_max)
if(CO2_pp > safe_co2_max)
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
H.Paralyse(3)
H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.adjustOxyLoss(8)
H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
H.emote("cough")
else
H.co2overloadtime = 0
H.clear_alert("too_much_co2")
//Too little CO2!
if(breathlevels["safe_co2_min"])
if(CO2_pp < safe_co2_min)
gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases["co2"][MOLES])
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["co2"][MOLES]
H.clear_alert("not_enough_co2")
//Exhale
breath_gases["co2"][MOLES] -= gas_breathed
breath_gases["o2"][MOLES] += gas_breathed
gas_breathed = 0
//-- TOX --//
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10
if(H.reagents)
H.reagents.add_reagent("plasma", Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max))
H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
H.clear_alert("tox_in_air")
//Too little toxins!
if(safe_toxins_min)
if(Toxins_pp < safe_toxins_min)
gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES])
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
gas_breathed = breath_gases["plasma"][MOLES]
H.clear_alert("not_enough_tox")
//Exhale
breath_gases["plasma"][MOLES] -= gas_breathed
breath_gases["co2"][MOLES] += gas_breathed
gas_breathed = 0
//-- TRACES --//
if(breath) // If there's some other shit in the air lets deal with it here.
// N2O
var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES])
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
H.Sleeping(max(H.sleeping+2, 10))
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
// BZ
var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES])
if(bz_pp > BZ_trip_balls_min)
H.hallucination += 20
if(prob(33))
H.adjustBrainLoss(3)
else if(bz_pp > 0.01)
H.hallucination += 5//Removed at 2 per tick so this will slowly build up
handle_breath_temperature(breath, H)
breath.garbage_collect()
return 1
/obj/item/organ/lungs/proc/handle_too_little_breath(mob/living/carbon/human/H = null,breath_pp = 0, safe_breath_min = 0, true_pp = 0)
. = 0
if(!H || !safe_breath_min) //the other args are either: Ok being 0 or Specifically handled.
return 0
if(prob(20))
H.emote("gasp")
if(breath_pp > 0)
var/ratio = safe_breath_min/breath_pp
H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!
H.failed_last_breath = 1
. = true_pp*ratio/6
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.failed_last_breath = 1
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
if(abs(310.15 - breath.temperature) > 50)
var/species_traits = list()
if(H && H.dna && H.dna.species && H.dna.species.species_traits)
species_traits = H.dna.species.species_traits
if(!(mutations_list[COLDRES] in H.dna.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE
switch(breath.temperature)
if(-INFINITY to 120)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head")
if(120 to 200)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head")
if(200 to 260)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head")
if(!(RESISTHOT in species_traits)) // HEAT DAMAGE
switch(breath.temperature)
if(360 to 400)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head")
if(400 to 1000)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head")
if(1000 to INFINITY)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head")
/obj/item/organ/lungs/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("salbutamol", 5)
return S
/obj/item/organ/lungs/plasmaman
name = "plasma filter"
safe_oxygen_min = 0 //We don't breath this
safe_toxins_min = 16 //We breath THIS!
safe_toxins_max = 0
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
#undef HEAT_GAS_DAMAGE_LEVEL_1
#undef HEAT_GAS_DAMAGE_LEVEL_2
#undef HEAT_GAS_DAMAGE_LEVEL_3
#undef COLD_GAS_DAMAGE_LEVEL_1
#undef COLD_GAS_DAMAGE_LEVEL_2
#undef COLD_GAS_DAMAGE_LEVEL_3
/obj/item/organ/tongue
name = "tongue"
desc = "A fleshy muscle mostly used for lying."
@@ -358,10 +618,10 @@
name = "alien tongue"
desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"."
icon_state = "tonguexeno"
say_mod = "hisses"
say_mod = "hiss"
/obj/item/organ/tongue/alien/TongueSpeech(var/message)
playsound(owner, "hiss", 15, 1, 1)
playsound(owner, "hiss", 25, 1, 1)
return message
/obj/item/organ/tongue/bone
@@ -433,13 +693,3 @@
if(inflamed)
S.reagents.add_reagent("????", 5)
return S
/obj/item/organ/tongue/yautja
name = "yautja tongue"
desc = "You're having a hard time even deciding if this is a tongue or not."
icon_state = "tongueyautja"
say_mod = "clicks"
/obj/item/organ/tongue/yautja/TongueSpeech(var/message)
playsound(owner, "predsay", 50, 0, 1)
return message