Merge pull request #15430 from DeltaFire15/synth-coolant
Synth stuff : Balancing Nightmare Edition (aka, coolant)
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
return
|
||||
|
||||
var/obj/item/organ/lungs/lungs = owner.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if((!lungs && !HAS_TRAIT(owner, TRAIT_NOBREATH)) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic))))
|
||||
if((!lungs && (HAS_TRAIT_FROM(owner, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) || !HAS_TRAIT(owner, TRAIT_NOBREATH))) || (lungs && (istype(lungs, /obj/item/organ/lungs/cybernetic))))
|
||||
replace_lungs(lungs)
|
||||
return
|
||||
|
||||
|
||||
@@ -65,29 +65,30 @@
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
|
||||
//Effects of bloodloss
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM)) //Synths are immune to direct consequences of bloodloss, instead suffering penalties to heat exchange.
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Unconscious(rand(20,60))
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
|
||||
if(!HAS_TRAIT(src, TRAIT_NODEATH))
|
||||
death()
|
||||
|
||||
var/temp_bleed = 0
|
||||
//Bleeding out
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
var/list/whatmighthappen = list()
|
||||
whatmighthappen += list("avoided" = 3, "dropthing" = 1, "movetile" = 1, "shortdeaf" = 1, "flopover" = 1, "nutriloss" = 1, "selfflash" = 1, "harmies" = 1)
|
||||
if(corruption >= CORRUPTION_THRESHHOLD_MAJOR)
|
||||
whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "halluscinate" = 1)
|
||||
whatmighthappen += list("longdeaf" = 1, "longknockdown" = 1, "shortlimbdisable" = 1, "shortblind" = 1, "shortstun" = 1, "shortmute" = 1, "vomit" = 1, "hallucinate" = 1, "jamcoolanthud" = 1)
|
||||
if(corruption >= CORRUPTION_THRESHHOLD_CRITICAL)
|
||||
whatmighthappen += list("receporgandamage" = 1, "longlimbdisable" = 1, "blindmutedeaf" = 1, "longstun" = 1, "sleep" = 1, "inducetrauma" = 1, "amplifycorrupt" = 1, "changetemp" = 1)
|
||||
var/event = pickweight(whatmighthappen)
|
||||
@@ -97,8 +97,10 @@
|
||||
if("vomit")
|
||||
to_chat(src, "<span class='notice'>Ejecting contaminant.</span>")
|
||||
vomit()
|
||||
if("halluscinate")
|
||||
if("hallucinate")
|
||||
hallucination += 20 //Doesn't give a cue
|
||||
if("jamcoolanthud")
|
||||
hud_used.coolant_display.jam(10)
|
||||
if("receporgandamage")
|
||||
adjustOrganLoss(ORGAN_SLOT_EARS, rand(10, 20))
|
||||
adjustOrganLoss(ORGAN_SLOT_EYES, rand(10, 20))
|
||||
@@ -159,7 +161,7 @@
|
||||
|
||||
/mob/living/carbon/proc/forcesleep(time = 100)
|
||||
to_chat(src, "<span class='notice'>Preparations complete, powering down.</span>")
|
||||
Sleeping(time, 0)
|
||||
Sleeping(time)
|
||||
|
||||
|
||||
#undef CORRUPTION_CHECK_INTERVAL
|
||||
|
||||
@@ -249,16 +249,17 @@
|
||||
if(DISGUST_LEVEL_DISGUSTED to INFINITY)
|
||||
msg += "[t_He] look[p_s()] extremely disgusted.\n"
|
||||
|
||||
var/apparent_blood_volume = blood_volume
|
||||
if(dna.species.use_skintones && skin_tone == "albino")
|
||||
apparent_blood_volume -= 150 // enough to knock you down one tier
|
||||
switch(apparent_blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
msg += "<b>[t_He] look[p_s()] like pale death.</b>\n"
|
||||
if(-INFINITY to BLOOD_VOLUME_BAD)
|
||||
msg += "<span class='deadsay'><b>[t_He] resemble[p_s()] a crushed, empty juice pouch.</b></span>\n"
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
var/apparent_blood_volume = blood_volume
|
||||
if(dna.species.use_skintones && skin_tone == "albino")
|
||||
apparent_blood_volume -= 150 // enough to knock you down one tier
|
||||
switch(apparent_blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
msg += "<b>[t_He] look[p_s()] like pale death.</b>\n"
|
||||
if(-INFINITY to BLOOD_VOLUME_BAD)
|
||||
msg += "<span class='deadsay'><b>[t_He] resemble[p_s()] a crushed, empty juice pouch.</b></span>\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever
|
||||
|
||||
@@ -416,6 +416,7 @@
|
||||
severity *= 0.5
|
||||
var/do_not_stun = FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
hud_used?.coolant_display.jam(round(severity / 10, 1)) //Messes up the cooling system readout.
|
||||
severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act)
|
||||
do_not_stun = TRUE
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
/mob/living/carbon/human/PhysicalLife(seconds, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM) && hud_used)
|
||||
hud_used.coolant_display.update_counter(src)
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
|
||||
@@ -76,9 +78,23 @@
|
||||
|
||||
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
|
||||
|
||||
var/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(breath && HAS_TRAIT(src, TRAIT_NOBREATH) && HAS_TRAIT(src, TRAIT_AUXILIARY_LUNGS)) //Something something bz and synth cooling systems interacting (in reality, this only exists to not make robot lings too strong)
|
||||
var/total_moles = breath.total_moles()
|
||||
var/pressure = breath.return_pressure()
|
||||
#define PP_MOLES(X) ((X / total_moles) * pressure)
|
||||
#define PP(air, gas) PP_MOLES(air.get_moles(gas))
|
||||
var/bz_pp = PP(breath, GAS_BZ)
|
||||
if(bz_pp > 1)
|
||||
reagents.add_reagent(/datum/reagent/bz_metabolites,5)
|
||||
else if(bz_pp > 0.1)
|
||||
reagents.add_reagent(/datum/reagent/bz_metabolites,1)
|
||||
#undef PP_MOLES
|
||||
#undef PP
|
||||
|
||||
var/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(!L)
|
||||
if(HAS_TRAIT(src, TRAIT_NOBREATH))
|
||||
return
|
||||
if(health >= crit_threshold)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
|
||||
else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
|
||||
|
||||
@@ -108,6 +108,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/burnmod = 1
|
||||
///multiplier for damage from cold temperature
|
||||
var/coldmod = 1
|
||||
///moves their safe minimum temp by this value.
|
||||
var/cold_offset = 0
|
||||
///moves their safe maximum temp by this value.
|
||||
var/hot_offset = 0
|
||||
///multiplier for damage from hot temperature
|
||||
var/heatmod = 1
|
||||
///multiplier for stun durations
|
||||
@@ -147,6 +151,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/list/blacklisted_quirks = list() // Quirks that will be removed upon gaining this species, to be defined by species
|
||||
var/list/removed_quirks = list() // Quirks that got removed due to being blacklisted, and will be restored when on_species_loss() is called
|
||||
var/balance_point_values = FALSE //If true, will balance point values on species gain after removing blacklisted quirks. Use this for roundstart species with blacklisted quirks that people may attempt to use to powergame trait points.
|
||||
|
||||
///Punch-specific attack verb.
|
||||
var/attack_verb = "punch"
|
||||
@@ -331,7 +336,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/should_have_brain = TRUE
|
||||
var/should_have_heart = !(NOBLOOD in species_traits)
|
||||
var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits)
|
||||
var/should_have_lungs = ((TRAIT_AUXILIARY_LUNGS in inherent_traits) || !(TRAIT_NOBREATH in inherent_traits))
|
||||
var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
|
||||
var/should_have_eyes = TRUE
|
||||
var/should_have_ears = TRUE
|
||||
@@ -569,17 +574,39 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
for(var/obj/item/bodypart/B in C.bodyparts)
|
||||
B.change_bodypart_status(initial(B.status), FALSE, TRUE)
|
||||
|
||||
if((TRAIT_ROBOTIC_ORGANISM in inherent_traits) && C.hud_used)
|
||||
C.hud_used.coolant_display.clear()
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
|
||||
|
||||
// shamelessly inspired by antag_datum.remove_blacklisted_quirks()
|
||||
/datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C)
|
||||
var/mob/living/L = C.mind?.current
|
||||
if(istype(L))
|
||||
for(var/q in L.roundstart_quirks)
|
||||
var/datum/quirk/Q = q
|
||||
if(Q.type in blacklisted_quirks)
|
||||
qdel(Q)
|
||||
removed_quirks += Q.type
|
||||
. = 0
|
||||
if(istype(C))
|
||||
if(!balance_point_values)
|
||||
for(var/q in C.roundstart_quirks)
|
||||
var/datum/quirk/Q = q
|
||||
if(Q.type in blacklisted_quirks)
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
else
|
||||
var/point_overhead = 0
|
||||
for(var/datum/quirk/Q as anything in C.roundstart_quirks)
|
||||
if(Q.type in blacklisted_quirks)
|
||||
point_overhead -= Q.value
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
if(point_overhead)
|
||||
for(var/datum/quirk/Q as anything in C.roundstart_quirks)
|
||||
if(Q.value > 0)
|
||||
point_overhead -= Q.value
|
||||
removed_quirks += Q.type
|
||||
. += 1
|
||||
qdel(Q)
|
||||
if(!point_overhead)
|
||||
break
|
||||
|
||||
// restore any quirks that we removed
|
||||
/datum/species/proc/restore_quirks(mob/living/carbon/C)
|
||||
@@ -1165,7 +1192,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)
|
||||
if((H.health < H.crit_threshold) && takes_crit_damage)
|
||||
H.adjustBruteLoss(1)
|
||||
if(!HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM))
|
||||
H.adjustBruteLoss(1)
|
||||
else
|
||||
H.adjustFireLoss(1) //Robots melt instead of taking brute.
|
||||
|
||||
/datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -1874,7 +1904,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(!I.get_sharpness() && armor_block < 50)
|
||||
if(prob(I.force))
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM))
|
||||
H.adjustToxLoss(5, toxins_type = TOX_SYSCORRUPT) //Bonk! - Effectively 5 bonus damage
|
||||
else
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
@@ -2171,15 +2201,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
//Thermal protection (insulation) has mixed benefits in two situations (hot in hot places, cold in hot places)
|
||||
if(!H.on_fire) //If you're on fire, you do not heat up or cool down based on surrounding gases
|
||||
var/natural = 0
|
||||
var/cooling_efficiency = 1
|
||||
if(H.stat != DEAD)
|
||||
natural = H.natural_bodytemperature_stabilization()
|
||||
cooling_efficiency = H.get_cooling_efficiency()
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_ROBOTIC_ORGANISM)) //Synths by default slowly heat up and need to lose said heat to the environment or active cooling. If you have very high cooling efficiency, you instead passively cool.
|
||||
H.adjust_bodytemperature(SYNTH_PASSIVE_HEAT_GAIN * (1 - cooling_efficiency), (T0C + SYNTH_MIN_PASSIVE_COOLING_TEMP), (T0C + SYNTH_MAX_PASSIVE_GAIN_TEMP))
|
||||
var/thermal_protection = 1
|
||||
if(loc_temp < H.bodytemperature) //Place is colder than we are
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + max((thermal_protection * (loc_temp - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max(((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) * cooling_efficiency) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
|
||||
else //Place is hotter than we are
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment
|
||||
@@ -2203,7 +2238,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 3)
|
||||
|
||||
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
|
||||
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
|
||||
if(H.bodytemperature > (BODYTEMP_HEAT_DAMAGE_LIMIT + hot_offset) && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
|
||||
//Body temperature is too hot.
|
||||
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
@@ -2231,11 +2266,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.emote("scream")
|
||||
H.apply_damage(burn_damage, BURN)
|
||||
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
else if(H.bodytemperature < (BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//Apply cold slowdown
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = (((BODYTEMP_COLD_DAMAGE_LIMIT + cold_offset) - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/shiver, 1)
|
||||
|
||||
@@ -24,11 +24,18 @@
|
||||
id = SPECIES_MAMMAL_SYNTHETIC
|
||||
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE,WINGCOLOR,HORNCOLOR)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID|MOB_BEAST
|
||||
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
@@ -47,5 +54,7 @@
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
exotic_bloodtype = "S"
|
||||
exotic_blood_color = BLOOD_COLOR_OIL
|
||||
allowed_limb_ids = list("mammal","aquatic","avian", "human")
|
||||
species_category = "robot"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
default_color = "00FF00"
|
||||
blacklisted = 0
|
||||
sexes = 0
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING,HAS_FLESH,HAS_BONE,HAIR,ROBOTIC_LIMBS)
|
||||
hair_alpha = 210
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
@@ -13,6 +13,12 @@
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
@@ -26,7 +32,7 @@
|
||||
//special cybernetic organ for getting power from apcs
|
||||
mutant_organs = list(/obj/item/organ/cyberimp/arm/power_cord)
|
||||
|
||||
exotic_bloodtype = "HF"
|
||||
exotic_bloodtype = "S"
|
||||
exotic_blood_color = BLOOD_COLOR_OIL
|
||||
species_category = SPECIES_CATEGORY_ROBOT
|
||||
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
say_mod = "beeps"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM)
|
||||
inherent_traits = list(TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NO_PROCESS_FOOD, TRAIT_ROBOTIC_ORGANISM, TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_AUXILIARY_LUNGS)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
|
||||
coldmod = 0.5
|
||||
heatmod = 1.2
|
||||
cold_offset = -125 //Can handle pretty cold environments, but it's still a slightly bad idea if you enter a room thats full of near-absolute-zero gas
|
||||
blacklisted_quirks = list(/datum/quirk/coldblooded)
|
||||
balance_point_values = TRUE
|
||||
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
|
||||
@@ -659,7 +659,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
|
||||
//used in human and monkey handle_environment()
|
||||
/mob/living/carbon/proc/natural_bodytemperature_stabilization()
|
||||
if (HAS_TRAIT(src, TRAIT_COLDBLOODED))
|
||||
if(HAS_TRAIT(src, TRAIT_COLDBLOODED) || HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 0 //Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this.
|
||||
|
||||
var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature
|
||||
@@ -672,6 +672,49 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
return min(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, max(body_temperature_difference, -BODYTEMP_AUTORECOVERY_MINIMUM/4))
|
||||
if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY)
|
||||
return min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
|
||||
|
||||
/mob/living/carbon/proc/get_cooling_efficiency()
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 1
|
||||
|
||||
var/integration_bonus = min(blood_volume * SYNTH_INTEGRATION_COOLANT_CAP, integrating_blood * SYNTH_INTEGRATION_COOLANT_PENALTY) //Integration blood somewhat helps, though only at 40% impact and to a cap of 25% of current blood level.
|
||||
var/blood_effective_volume = blood_volume + integration_bonus
|
||||
var/coolant_efficiency = min(blood_effective_volume / BLOOD_VOLUME_SAFE, 1) //Low coolant is only a negative, adding more than needed will not help you.
|
||||
var/environment_efficiency = get_environment_cooling_efficiency()
|
||||
|
||||
return min(coolant_efficiency * environment_efficiency, SYNTH_MAX_COOLING_EFFICIENCY)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/get_environment_cooling_efficiency()
|
||||
var/suitlink = check_suitlinking()
|
||||
if(suitlink)
|
||||
return suitlink //If you are wearing full EVA or lavaland hazard gear (on lavaland), assume it has been made to accomodate your cooling needs.
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if(!environment)
|
||||
return 0
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/heat = environment.return_temperature()
|
||||
|
||||
var/heat_efficiency = clamp(1 + ((bodytemperature - heat) * SYNTH_HEAT_EFFICIENCY_COEFF), 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
var/pressure_efficiency = clamp(pressure / ONE_ATMOSPHERE, 0, SYNTH_SINGLE_INFLUENCE_COOLING_EFFECT_CAP)
|
||||
|
||||
var/total_environment_efficiency = min(heat_efficiency * pressure_efficiency, SYNTH_TOTAL_ENVIRONMENT_EFFECT_CAP) //At best, you can get 200% total
|
||||
return total_environment_efficiency
|
||||
|
||||
/mob/living/carbon/proc/check_suitlinking()
|
||||
var/suit_item = get_item_by_slot(SLOT_WEAR_SUIT)
|
||||
var/head_item = get_item_by_slot(SLOT_HEAD)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space))
|
||||
return 1
|
||||
|
||||
if(T && is_mining_level(T.z) && istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/////////
|
||||
//LIVER//
|
||||
/////////
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
/datum/reagent/medicine/leporazine
|
||||
name = "Leporazine"
|
||||
description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 8.4
|
||||
color = "#82b8aa"
|
||||
value = REAGENT_VALUE_COMMON
|
||||
@@ -693,7 +692,6 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#00FFFF"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 2
|
||||
|
||||
/datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M)
|
||||
@@ -710,7 +708,6 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FF6464"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 11
|
||||
|
||||
/datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M)
|
||||
@@ -920,7 +917,6 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#000000"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 35
|
||||
pH = 12
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
@@ -951,7 +947,6 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#D2FFFA"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
pH = 10.2
|
||||
|
||||
@@ -1203,7 +1198,6 @@
|
||||
description = "Restores oxygen loss. Overdose causes it instead."
|
||||
reagent_state = LIQUID
|
||||
color = "#13d2f0"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
pH = 9.7
|
||||
|
||||
@@ -1267,7 +1261,6 @@
|
||||
reagent_state = LIQUID
|
||||
pH = 8.5
|
||||
color = "#5dc1f0"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M)
|
||||
if(M.losebreath >= 5)
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
category = list("Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/hypospray/mkii
|
||||
/datum/design/hypospray_mkii
|
||||
name = "Hypospray Mk. II"
|
||||
id = "hypospray_mkii"
|
||||
build_type = PROTOLATHE
|
||||
@@ -222,6 +222,15 @@
|
||||
category = list("Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/nanogel
|
||||
name = "Nanogel paste"
|
||||
id = "nanogel"
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
materials = list(/datum/material/iron = 800, /datum/material/titanium = 500, /datum/material/gold = 100, /datum/material/diamond = 20)
|
||||
build_path = /obj/item/stack/medical/nanogel/one
|
||||
category = list("Medical Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/blood_bag
|
||||
name = "Empty Blood Bag"
|
||||
desc = "A small sterilized plastic bag for blood."
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
display_name = "Advanced Robotics Research"
|
||||
description = "It can even do the dishes!"
|
||||
prereq_ids = list("robotics")
|
||||
design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter")
|
||||
design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter", "nanogel")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000)
|
||||
|
||||
/datum/techweb_node/neural_programming
|
||||
|
||||
@@ -148,14 +148,14 @@
|
||||
return
|
||||
to_chat(owner, "<span class='warning'>Alert: Auditory systems corrupted!.</span>")
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.Jitter(30)
|
||||
owner.Dizzy(30)
|
||||
owner.DefaultCombatKnockdown(80)
|
||||
deaf = 30
|
||||
|
||||
if(2)
|
||||
if(1 to 50)
|
||||
owner.Jitter(15)
|
||||
owner.Dizzy(15)
|
||||
owner.DefaultCombatKnockdown(40)
|
||||
|
||||
if(50 to INFINITY)
|
||||
owner.Jitter(30)
|
||||
owner.Dizzy(30)
|
||||
owner.DefaultCombatKnockdown(80)
|
||||
deaf = max(deaf, 30)
|
||||
damage += 0.15 * severity
|
||||
|
||||
@@ -415,7 +415,7 @@
|
||||
if(!.)
|
||||
return
|
||||
if(!failed && organ_flags & ORGAN_FAILING)
|
||||
if(owner && owner.stat == CONSCIOUS)
|
||||
if(owner && owner.stat == CONSCIOUS && !HAS_TRAIT(owner, TRAIT_NOBREATH))
|
||||
owner.visible_message("<span class='danger'>[owner] grabs [owner.p_their()] throat, struggling for breath!</span>", \
|
||||
"<span class='userdanger'>You suddenly feel like you can't breathe!</span>")
|
||||
failed = TRUE
|
||||
@@ -425,6 +425,10 @@
|
||||
/obj/item/organ/lungs/ipc
|
||||
name = "ipc cooling system"
|
||||
icon_state = "lungs-c"
|
||||
var/is_cooling = 0
|
||||
var/cooling_coolant_drain = 5 //Coolant (blood) use per tick of active cooling.
|
||||
var/next_warn = BLOOD_VOLUME_NORMAL
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
|
||||
/obj/item/organ/lungs/ipc/emp_act(severity) //Should probably put it somewhere else later
|
||||
. = ..()
|
||||
@@ -432,11 +436,65 @@
|
||||
return
|
||||
to_chat(owner, "<span class='warning'>Alert: Critical cooling system failure!</span>")
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
if(2)
|
||||
if(1 to 50)
|
||||
owner.adjust_bodytemperature(30*TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
if(50 to INFINITY)
|
||||
owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
|
||||
/obj/item/organ/lungs/ipc/ui_action_click(mob/user, actiontype)
|
||||
if(!owner)
|
||||
return
|
||||
if(!HAS_TRAIT(user, TRAIT_ROBOTIC_ORGANISM))
|
||||
to_chat(user, "<span class='notice'>Biotype incompatible with cooling system. Activation signal suppressed.</span>")
|
||||
return
|
||||
if(!is_cooling && owner.blood_volume < cooling_coolant_drain)
|
||||
to_chat(user, "<span class='warning'>Coolant levels insufficient to enable active cooling - Replenish immediately.</span>")
|
||||
return
|
||||
|
||||
is_cooling = !is_cooling
|
||||
to_chat(user, "<span class='notice'>Active cooling [is_cooling ? "enabled" : "disabled"] - current coolant level: [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.</span>")
|
||||
var/possible_next_warn = owner.blood_volume - (BLOOD_VOLUME_NORMAL * 0.1)
|
||||
if(possible_next_warn > next_warn)
|
||||
next_warn = possible_next_warn //If we recovered blood inbetween activations, update warning
|
||||
|
||||
/obj/item/organ/lungs/ipc/on_life(seconds, times_fired)
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(is_cooling)
|
||||
to_chat(owner, "<span class='warning'>Cooling system safeguards triggered - active cooling aborted.</span>")
|
||||
is_cooling = 0
|
||||
return
|
||||
if(!is_cooling)
|
||||
return
|
||||
if(!HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM))
|
||||
to_chat(owner, "<span class='warning'>Biotype incompatible with cooling system. Commencing emergency shutdown.</span>")
|
||||
is_cooling = 0
|
||||
return
|
||||
if(owner.stat >= SOFT_CRIT)
|
||||
to_chat(owner, "<span class='warning'>Operating system ping returned null response - Shutting down active cooling to avoid component damage.</span>")
|
||||
is_cooling = 0
|
||||
return
|
||||
if(owner.blood_volume < cooling_coolant_drain)
|
||||
to_chat(owner, "<span class='warning'>Coolant levels insufficient to maintain active cooling - Replenish immediately.</span>")
|
||||
is_cooling = 0
|
||||
return
|
||||
if(abs(owner.bodytemperature - T20C) < SYNTH_ACTIVE_COOLING_TEMP_BOUNDARY)
|
||||
return //Does not drain coolant (blood) nor do anything if we are close enough to room temp.
|
||||
var/cooling_efficiency = owner.get_cooling_efficiency()
|
||||
var/actual_drain = cooling_coolant_drain * max(1 - cooling_efficiency, 0.2) //Being in a suitable environment reduces drain by up to 80%
|
||||
var/temp_diff = owner.bodytemperature - T20C
|
||||
if(temp_diff > 0)
|
||||
owner.adjust_bodytemperature(clamp(((T0C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX, -SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT))
|
||||
else
|
||||
owner.adjust_bodytemperature(clamp(((T20C - owner.bodytemperature) * max(cooling_efficiency, 0.5) / BODYTEMP_HEAT_DIVISOR), SYNTH_ACTIVE_COOLING_MIN_ADJUSTMENT, BODYTEMP_HEATING_MAX))
|
||||
var/datum/gas_mixture/air = owner.loc.return_air()
|
||||
if(!air || air.return_pressure() < ONE_ATMOSPHERE * SYNTH_ACTIVE_COOLING_LOW_PRESSURE_THRESHOLD)
|
||||
actual_drain *= SYNTH_ACTIVE_COOLING_LOW_PRESSURE_PENALTY //Our cooling system can handle hot places okayish, but starts to cry at low pressures (reads: Effectively vents hot coolant thats been warmed up via internal heat-exchange as emergency measure and with very low efficiency)
|
||||
owner.blood_volume = max(owner.blood_volume - actual_drain, 0)
|
||||
if(owner.blood_volume <= next_warn)
|
||||
to_chat(owner, "[owner.blood_volume > BLOOD_VOLUME_BAD ? "<span class='notice'>" : "<span class='warning'>"]Coolant level passed threshold - now [round(owner.blood_volume / BLOOD_VOLUME_NORMAL * 100, 0.1)] percent.</span>")
|
||||
next_warn -= (BLOOD_VOLUME_NORMAL * 0.1)
|
||||
|
||||
/obj/item/organ/lungs/plasmaman
|
||||
name = "plasma filter"
|
||||
desc = "A spongy rib-shaped mass for filtering plasma from the air."
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
var/breathes = TRUE
|
||||
var/blooded = TRUE
|
||||
if(dna && dna.species)
|
||||
if(HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT))
|
||||
if(!HAS_TRAIT_FROM(src, TRAIT_AUXILIARY_LUNGS, SPECIES_TRAIT) && HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT))
|
||||
breathes = FALSE
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
blooded = FALSE
|
||||
|
||||
@@ -136,11 +136,11 @@
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.nutrition = min(owner.nutrition - 50, 0)
|
||||
if(1 to 50)
|
||||
owner.nutrition = max(owner.nutrition - 50, 0)
|
||||
to_chat(owner, "<span class='warning'>Alert: Detected severe battery discharge!</span>")
|
||||
if(2)
|
||||
owner.nutrition = min(owner.nutrition - 100, 0)
|
||||
if(50 to INFINITY)
|
||||
owner.nutrition = max(owner.nutrition - 100, 0)
|
||||
to_chat(owner, "<span class='warning'>Alert: Minor battery discharge!</span>")
|
||||
|
||||
/obj/item/organ/stomach/ethereal
|
||||
|
||||
Reference in New Issue
Block a user