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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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--
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user