Files
GS13NG/code/modules/mob/living/carbon/human/life.dm
T
CitadelStationBotandPoojawa dad2d44ea2 [MIRROR] [READY] Several fixes/changes to mood, longterm mood effects, beauty component (#5992)
* [READY] Several fixes/changes to mood, longterm mood effects, beauty component (#36344)

cl Floyd / Qustinnus
del: Removes short-term effects of mood
add; Adds long-term effects of mood by implementing sanity which goes up with good mood, down with bad mood, but takes time to change. Your sanity can be seen as your average mood in the recent past. All effects of moods are now covered by this system
add: Beauty component, currently only attached to cleanables, but you could attach it to any atom/movable and make them pretty/ugly, affecting mood of anyone in the room.
refactor: Removes the original way of adding mood events, uses signals properly instead.
fix: Cleanables "giving" area's free beauty during initialization
fix: Fixes some events not clearing properly
/cl

Fixes #36444

From now on mood no longer affects you directly, instead it decides whether your sanity goes up or down, when your sanity gets too low you will get the effects of what mood did before.

This means getting hit with bad moods due to being attacked while not mean you are doomed anymore, and you get a large timeframe to get away and just fix your mood later.

I also added the beauty component, you could add this to any object and it would either make a room prettier or uglier, comparable to DF or Rimworld. You could add traits to make certain people ugly, for example.

* [READY] Several fixes/changes to mood, longterm mood effects, beauty component
2018-03-19 21:33:18 -05:00

473 lines
19 KiB
Plaintext

//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
#define HEAT_DAMAGE_LEVEL_3 10 //Amount of damage applied when your body temperature passes the 460K point and you are on fire
#define COLD_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when your body temperature just passes the 260.15k safety point
#define COLD_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when your body temperature passes the 200K point
#define COLD_DAMAGE_LEVEL_3 3 //Amount of damage applied when your body temperature passes the 120K point
//Note that gas heat damage is only applied once every FOUR ticks.
#define HEAT_GAS_DAMAGE_LEVEL_1 2 //Amount of damage applied when the current breath's temperature just passes the 360.15k safety point
#define HEAT_GAS_DAMAGE_LEVEL_2 4 //Amount of damage applied when the current breath's temperature passes the 400K point
#define HEAT_GAS_DAMAGE_LEVEL_3 8 //Amount of damage applied when the current breath's temperature passes the 1000K point
#define COLD_GAS_DAMAGE_LEVEL_1 0.5 //Amount of damage applied when the current breath's temperature just passes the 260.15k safety point
#define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
// The values here should add up to 1.
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
#define THERMAL_PROTECTION_HEAD 0.3
#define THERMAL_PROTECTION_CHEST 0.15
#define THERMAL_PROTECTION_GROIN 0.15
#define THERMAL_PROTECTION_LEG_LEFT 0.075
#define THERMAL_PROTECTION_LEG_RIGHT 0.075
#define THERMAL_PROTECTION_FOOT_LEFT 0.025
#define THERMAL_PROTECTION_FOOT_RIGHT 0.025
#define THERMAL_PROTECTION_ARM_LEFT 0.075
#define THERMAL_PROTECTION_ARM_RIGHT 0.075
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
/mob/living/carbon/human/Life()
set invisibility = 0
if (notransform)
return
if(..()) //not dead
handle_active_genes()
if(stat != DEAD)
//heart attack stuff
handle_heart()
if(stat != DEAD)
//Stuff jammed in your limbs hurts
handle_embedded_objects()
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
dna.species.spec_life(src) // for mutantraces
if(stat != DEAD)
return 1
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
if((wear_suit && (wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (head && (head.flags_1 & STOPSPRESSUREDMAGE_1)))
return ONE_ATMOSPHERE
if(istype(loc, /obj/belly))
return ONE_ATMOSPHERE
if(istype(loc, /obj/item/device/dogborg/sleeper))
return ONE_ATMOSPHERE
else
return pressure
/mob/living/carbon/human/handle_traits()
if(eye_blind) //blindness, heals slowly over time
if(has_trait(TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster
adjust_blindness(-3)
else
adjust_blindness(-1)
else if(eye_blurry) //blurry eyes heal slowly
adjust_blurriness(-1)
if(has_trait(TRAIT_PACIFISM) && a_intent == INTENT_HARM)
to_chat(src, "<span class='notice'>You don't feel like harming anybody.</span>")
a_intent_change(INTENT_HELP)
if (getBrainLoss() >= 60 && !incapacitated(TRUE))
SendSignal(COMSIG_ADD_MOOD_EVENT, "brain_damage", /datum/mood_event/brain_damage)
if(prob(3))
if(prob(25))
emote("drool")
else
say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage"))
else
SendSignal(COMSIG_CLEAR_MOOD_EVENT, "brain_damage")
/mob/living/carbon/human/handle_mutations_and_radiation()
if(!dna || !dna.species.handle_mutations_and_radiation(src))
..()
/mob/living/carbon/human/breathe()
if(!dna.species.breathe(src))
..()
#define HUMAN_MAX_OXYLOSS 3
#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30)
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
var/L = getorganslot(ORGAN_SLOT_LUNGS)
if(!L)
if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!has_trait(TRAIT_NOCRITDAMAGE))
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
failed_last_breath = 1
var/datum/species/S = dna.species
if(S.breathid == "o2")
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else if(S.breathid == "tox")
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(S.breathid == "co2")
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else if(S.breathid == "n2")
throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
return FALSE
else
if(istype(L, /obj/item/organ/lungs))
var/obj/item/organ/lungs/lun = L
lun.check_breath(breath,src)
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
dna.species.handle_environment(environment, src)
///FIRE CODE
/mob/living/carbon/human/handle_fire()
..()
if(dna)
dna.species.handle_fire(src)
/mob/living/carbon/human/proc/get_thermal_protection()
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
//CITADEL EDIT Vore code required overrides
if(istype(loc, /obj/item/device/dogborg/sleeper))
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
if(ismob(loc))
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
if(istype(loc, /obj/belly))
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
//END EDIT
if(wear_suit)
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
thermal_protection += (wear_suit.max_heat_protection_temperature*0.7)
if(head)
if(head.max_heat_protection_temperature >= FIRE_HELM_MAX_TEMP_PROTECT)
thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD)
thermal_protection = round(thermal_protection)
return thermal_protection
/mob/living/carbon/human/IgniteMob()
//If have no DNA or can be Ignited, call parent handling to light user
//If firestacks are high enough
if(!dna || dna.species.CanIgniteMob(src))
return ..()
. = FALSE //No ignition
/mob/living/carbon/human/ExtinguishMob()
if(!dna || !dna.species.ExtinguishMob(src))
..()
//END FIRE CODE
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
var/thermal_protection_flags = 0
//Handle normal clothing
if(head)
if(head.max_heat_protection_temperature && head.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= head.heat_protection
if(wear_suit)
if(wear_suit.max_heat_protection_temperature && wear_suit.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= wear_suit.heat_protection
if(w_uniform)
if(w_uniform.max_heat_protection_temperature && w_uniform.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= w_uniform.heat_protection
if(shoes)
if(shoes.max_heat_protection_temperature && shoes.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= shoes.heat_protection
if(gloves)
if(gloves.max_heat_protection_temperature && gloves.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= gloves.heat_protection
if(wear_mask)
if(wear_mask.max_heat_protection_temperature && wear_mask.max_heat_protection_temperature >= temperature)
thermal_protection_flags |= wear_mask.heat_protection
return thermal_protection_flags
/mob/living/carbon/human/proc/get_heat_protection(temperature) //Temperature is the temperature you're being exposed to.
var/thermal_protection_flags = get_heat_protection_flags(temperature)
var/thermal_protection = 0
if(thermal_protection_flags)
if(thermal_protection_flags & HEAD)
thermal_protection += THERMAL_PROTECTION_HEAD
if(thermal_protection_flags & CHEST)
thermal_protection += THERMAL_PROTECTION_CHEST
if(thermal_protection_flags & GROIN)
thermal_protection += THERMAL_PROTECTION_GROIN
if(thermal_protection_flags & LEG_LEFT)
thermal_protection += THERMAL_PROTECTION_LEG_LEFT
if(thermal_protection_flags & LEG_RIGHT)
thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
if(thermal_protection_flags & FOOT_LEFT)
thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
if(thermal_protection_flags & FOOT_RIGHT)
thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
if(thermal_protection_flags & ARM_LEFT)
thermal_protection += THERMAL_PROTECTION_ARM_LEFT
if(thermal_protection_flags & ARM_RIGHT)
thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
if(thermal_protection_flags & HAND_LEFT)
thermal_protection += THERMAL_PROTECTION_HAND_LEFT
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
return min(1,thermal_protection)
//See proc/get_heat_protection_flags(temperature) for the description of this proc.
/mob/living/carbon/human/proc/get_cold_protection_flags(temperature)
var/thermal_protection_flags = 0
//Handle normal clothing
if(head)
if(head.min_cold_protection_temperature && head.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= head.cold_protection
if(wear_suit)
if(wear_suit.min_cold_protection_temperature && wear_suit.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= wear_suit.cold_protection
if(w_uniform)
if(w_uniform.min_cold_protection_temperature && w_uniform.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= w_uniform.cold_protection
if(shoes)
if(shoes.min_cold_protection_temperature && shoes.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= shoes.cold_protection
if(gloves)
if(gloves.min_cold_protection_temperature && gloves.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= gloves.cold_protection
if(wear_mask)
if(wear_mask.min_cold_protection_temperature && wear_mask.min_cold_protection_temperature <= temperature)
thermal_protection_flags |= wear_mask.cold_protection
return thermal_protection_flags
/mob/living/carbon/human/proc/get_cold_protection(temperature)
if(has_trait(TRAIT_RESISTCOLD))
return TRUE
//CITADEL EDIT Mandatory for vore code.
if(istype(loc, /obj/item/device/dogborg/sleeper))
return 1 //freezing to death in sleepers ruins fun.
if(istype(loc, /obj/belly))
return 1
if(ismob(loc))
return 1 //because lazy and being inside somemone insulates you from space
//END EDIT
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
var/thermal_protection_flags = get_cold_protection_flags(temperature)
var/thermal_protection = 0
if(thermal_protection_flags)
if(thermal_protection_flags & HEAD)
thermal_protection += THERMAL_PROTECTION_HEAD
if(thermal_protection_flags & CHEST)
thermal_protection += THERMAL_PROTECTION_CHEST
if(thermal_protection_flags & GROIN)
thermal_protection += THERMAL_PROTECTION_GROIN
if(thermal_protection_flags & LEG_LEFT)
thermal_protection += THERMAL_PROTECTION_LEG_LEFT
if(thermal_protection_flags & LEG_RIGHT)
thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
if(thermal_protection_flags & FOOT_LEFT)
thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
if(thermal_protection_flags & FOOT_RIGHT)
thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
if(thermal_protection_flags & ARM_LEFT)
thermal_protection += THERMAL_PROTECTION_ARM_LEFT
if(thermal_protection_flags & ARM_RIGHT)
thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
if(thermal_protection_flags & HAND_LEFT)
thermal_protection += THERMAL_PROTECTION_HAND_LEFT
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
return min(1,thermal_protection)
/mob/living/carbon/human/handle_random_events()
//Puke if toxloss is too high
if(!stat)
if(getToxLoss() >= 45 && nutrition > 20)
lastpuke += prob(50)
if(lastpuke >= 50) // about 25 second delay I guess
vomit(20, toxic = TRUE)
lastpuke = 0
/mob/living/carbon/human/has_smoke_protection()
if(wear_mask)
if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
return TRUE
if(glasses)
if(glasses.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
return TRUE
if(head)
if(head.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
return TRUE
return ..()
/mob/living/carbon/human/proc/handle_embedded_objects()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
for(var/obj/item/I in BP.embedded_objects)
if(prob(I.embedding.embedded_pain_chance))
BP.receive_damage(I.w_class*I.embedding.embedded_pain_multiplier)
to_chat(src, "<span class='userdanger'>[I] embedded in your [BP.name] hurts!</span>")
if(prob(I.embedding.embedded_fall_chance))
BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier)
BP.embedded_objects -= I
I.forceMove(drop_location())
visible_message("<span class='danger'>[I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>[I] falls out of your [BP.name]!</span>")
if(!has_embedded_objects())
clear_alert("embeddedobject")
SendSignal(COMSIG_CLEAR_MOOD_EVENT, "embedded")
/mob/living/carbon/human/proc/handle_active_genes()
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
/mob/living/carbon/human/proc/handle_heart()
if(!can_heartattack())
return
var/we_breath = !has_trait(TRAIT_NOBREATH, SPECIES_TRAIT)
if(!undergoing_cardiac_arrest())
return
// Cardiac arrest, unless heart is stabilized
if(has_trait(TRAIT_STABLEHEART))
return
if(we_breath)
adjustOxyLoss(8)
Unconscious(80)
// Tissues die without blood circulation
adjustBruteLoss(2)
/*
Alcohol Poisoning Chart
Note that all higher effects of alcohol poisoning will inherit effects for smaller amounts (i.e. light poisoning inherts from slight poisoning)
In addition, severe effects won't always trigger unless the drink is poisonously strong
All effects don't start immediately, but rather get worse over time; the rate is affected by the imbiber's alcohol tolerance
0: Non-alcoholic
1-10: Barely classifiable as alcohol - occassional slurring
11-20: Slight alcohol content - slurring
21-30: Below average - imbiber begins to look slightly drunk
31-40: Just below average - no unique effects
41-50: Average - mild disorientation, imbiber begins to look drunk
51-60: Just above average - disorientation, vomiting, imbiber begins to look heavily drunk
61-70: Above average - small chance of blurry vision, imbiber begins to look smashed
71-80: High alcohol content - blurry vision, imbiber completely shitfaced
81-90: Extremely high alcohol content - light brain damage, passing out
91-100: Dangerously toxic - swift death
*/
#define BALLMER_POINTS 5
GLOBAL_LIST_INIT(ballmer_good_msg, list("Hey guys, what if we rolled out a bluespace wiring system so mice can't destroy the powergrid anymore?",
"Hear me out here. What if, and this is just a theory, we made R&D controllable from our PDAs?",
"I'm thinking we should roll out a git repository for our research under the AGPLv3 license so that we can share it among the other stations freely.",
"I dunno about you guys, but IDs and PDAs being separate is clunky as fuck. Maybe we should merge them into a chip in our arms? That way they can't be stolen easily.",
"Why the fuck aren't we just making every pair of shoes into galoshes? We have the technology."))
GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put a webserver that's automatically turned on with default admin passwords into every PDA?",
"So like, you know how we separate our codebase from the master copy that runs on our consumer boxes? What if we merged the two and undid the separation between codebase and server?",
"Dude, radical idea: H.O.N.K mechs but with no bananium required.",
"Best idea ever: Disposal pipes instead of hallways."))
/mob/living/carbon/human/handle_status_effects()
..()
if(drunkenness)
drunkenness = max(drunkenness - (drunkenness * 0.04), 0)
if(drunkenness >= 6)
if(prob(25))
slurring += 2
jitteriness = max(jitteriness - 3, 0)
if(drunkenness >= 11 && slurring < 5)
slurring += 1.2
if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director"))
if(SSresearch.science_tech)
if(drunkenness >= 12.9 && drunkenness <= 13.8)
drunkenness = round(drunkenness, 0.01)
var/ballmer_percent = 0
if(drunkenness == 13.35) // why run math if I dont have to
ballmer_percent = 1
else
ballmer_percent = (-abs(drunkenness - 13.35) / 0.9) + 1
if(prob(5))
say(pick(GLOB.ballmer_good_msg))
SSresearch.science_tech.research_points += (BALLMER_POINTS * ballmer_percent)
if(drunkenness > 26) // by this point you're into windows ME territory
if(prob(5))
SSresearch.science_tech.research_points -= BALLMER_POINTS
say(pick(GLOB.ballmer_windows_me_msg))
if(drunkenness >= 41)
if(prob(25))
confused += 2
Dizzy(10)
if(drunkenness >= 51)
if(prob(5))
confused += 10
vomit()
Dizzy(25)
if(drunkenness >= 61)
if(prob(50))
blur_eyes(5)
if(drunkenness >= 71)
blur_eyes(5)
if(drunkenness >= 81)
adjustToxLoss(0.2)
if(prob(5) && !stat)
to_chat(src, "<span class='warning'>Maybe you should lie down for a bit...</span>")
if(drunkenness >= 91)
adjustBrainLoss(0.4, 60)
if(prob(20) && !stat)
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(z)) //QoL mainly
to_chat(src, "<span class='warning'>You're so tired... but you can't miss that shuttle...</span>")
else
to_chat(src, "<span class='warning'>Just a quick nap...</span>")
Sleeping(900)
if(drunkenness >= 101)
adjustToxLoss(4) //Let's be honest you shouldn't be alive by now
#undef HUMAN_MAX_OXYLOSS
#undef THERMAL_PROTECTION_HEAD
#undef THERMAL_PROTECTION_CHEST
#undef THERMAL_PROTECTION_GROIN
#undef THERMAL_PROTECTION_LEG_LEFT
#undef THERMAL_PROTECTION_LEG_RIGHT
#undef THERMAL_PROTECTION_FOOT_LEFT
#undef THERMAL_PROTECTION_FOOT_RIGHT
#undef THERMAL_PROTECTION_ARM_LEFT
#undef THERMAL_PROTECTION_ARM_RIGHT
#undef THERMAL_PROTECTION_HAND_LEFT
#undef THERMAL_PROTECTION_HAND_RIGHT