mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 13:05:44 +01:00
Adds: - Dosimeter, keeps track of how many rads a person has absorbed as well as showing the dose after armour. - Adds a message to shelter in maint to the supermatter explosion. - Adds a flag that makes damage not apply to robotic limbs, useful for preventing radiation burns to metal parts. Should also be added to chemicals that deal brute damage, such as arithrazine and the the burns from chemical exposure to chlorine, but that's another PR. - Added radiation resistance values to makeshift armour. As it only covers the chest, this isn't very useful, but better than nothing. Balance: - Re-scaled radiation damage. - Radiation now maxes out at 1000, from the previous 100. - Radiation damage when at maximum rads is converted directly into burn damage. - Radiation sources decay slowly, so all the old numbers were maxing people's radiation values instantaneously. - Re-scaled organ damage from radiation. Previously you would take no organ damage till 75% rads, then lose your liver almost immediately. Now organ damage ramps up from 500-1000, with 750-1000 being about 1/3rd the organ damage of 75-100. - Added debilitating, but not lethal, effects to moderate and high radiation levels. Lots of pain events instead of straight damage. - Reduced speed and stamina for high radiation doses. - Hyronalin and Arithrazine both remove much more radiation. The intent: People should now be able to work in low radiation zones, without using the radiation suit for short periods of time. The geiger counter is no longer an 'if this is ticking you are at max rads' detector. With the engineering voidsuit, 75% rads, I could stand next to a charged supermatter ~50rads a second, for about 2 minutes before I hit lethal radiation levels. If people stay in a radiation zone, or are exposed to extreme radiation 100+ rads a second, radiation is much more lethal, but not by just killing your organs. Conventional medicine will help a lot. --------- Signed-off-by: FenodyreeAv <fenodyree.av@gmail.com> Co-authored-by: Batrachophreno <Batrochophreno@gmail.com>
253 lines
6.7 KiB
Plaintext
253 lines
6.7 KiB
Plaintext
/mob/living/Life(seconds_per_tick, times_fired)
|
|
if (QDELETED(src)) // If they're being deleted, why bother?
|
|
return FALSE
|
|
|
|
..()
|
|
|
|
if(transforming)
|
|
return FALSE
|
|
|
|
if(!loc)
|
|
return FALSE
|
|
|
|
var/datum/gas_mixture/environment = loc.return_air()
|
|
//Handle temperature/pressure differences between body and environment
|
|
if(environment)
|
|
handle_environment(environment, seconds_per_tick)
|
|
|
|
blinded = 0 // Placing this here just show how out of place it is.
|
|
|
|
if(handle_regular_status_updates())
|
|
handle_status_effects()
|
|
|
|
if(stat != DEAD)
|
|
if(LAZYLEN(auras))
|
|
aura_check(AURA_TYPE_LIFE)
|
|
if(!InStasis())
|
|
//Mutations and radiation
|
|
handle_mutations_and_radiation(seconds_per_tick)
|
|
|
|
//Check if we're on fire
|
|
handle_fire(seconds_per_tick, environment)
|
|
|
|
update_pulling()
|
|
|
|
for(var/obj/item/grab/G in src)
|
|
INVOKE_ASYNC(G, TYPE_PROC_REF(/datum, process))
|
|
|
|
handle_actions()
|
|
|
|
update_canmove()
|
|
|
|
handle_regular_hud_updates()
|
|
|
|
if(languages.len == 1 && default_language != languages[1])
|
|
default_language = languages[1]
|
|
|
|
//Technonancer instability
|
|
handle_instability()
|
|
|
|
return 1
|
|
|
|
/mob/living/proc/handle_breathing()
|
|
return
|
|
|
|
/mob/living/proc/handle_chemicals_in_body()
|
|
return
|
|
|
|
/mob/living/proc/handle_mutations_and_radiation(seconds_per_tick)
|
|
return
|
|
|
|
/mob/living/proc/handle_random_events()
|
|
return
|
|
|
|
/mob/living/proc/update_pulling()
|
|
if(pulling)
|
|
if(incapacitated())
|
|
stop_pulling()
|
|
|
|
//This updates the health and status of the mob (conscious, unconscious, dead)
|
|
/mob/living/proc/handle_regular_status_updates()
|
|
updatehealth()
|
|
if(stat != DEAD)
|
|
if(paralysis)
|
|
set_stat(UNCONSCIOUS)
|
|
else if (status_flags & FAKEDEATH)
|
|
set_stat(UNCONSCIOUS)
|
|
else
|
|
set_stat(CONSCIOUS)
|
|
return 1
|
|
|
|
/mob/living/proc/handle_status_effects()
|
|
if(paralysis)
|
|
paralysis = max(paralysis-1,0)
|
|
if(stunned)
|
|
stunned = max(stunned-1,0)
|
|
if(!stunned)
|
|
update_icon()
|
|
|
|
if(weakened)
|
|
weakened = max(weakened-1,0)
|
|
if(!weakened)
|
|
update_icon()
|
|
|
|
if(confused)
|
|
confused = max(0, confused - 1)
|
|
|
|
/mob/living/proc/handle_disabilities()
|
|
//Eyes
|
|
if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
|
|
eye_blind = max(eye_blind, 1)
|
|
else if(eye_blind) //blindness, heals slowly over time
|
|
eye_blind = max(eye_blind-1,0)
|
|
else if(eye_blurry) //blurry eyes heal slowly
|
|
eye_blurry = max(eye_blurry-1, 0)
|
|
|
|
//Ears
|
|
handle_hearing()
|
|
|
|
if((is_pacified()) && a_intent == I_HURT && !is_berserk())
|
|
to_chat(src, SPAN_NOTICE("You don't feel like harming anybody."))
|
|
a_intent_change(I_HELP)
|
|
|
|
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
|
/mob/living/proc/handle_regular_hud_updates()
|
|
if(!can_update_hud())
|
|
return FALSE
|
|
|
|
handle_hud_icons()
|
|
handle_vision()
|
|
|
|
return TRUE
|
|
|
|
/mob/living/proc/can_update_hud()
|
|
if(!client || QDELETED(src))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/mob/living/handle_vision()
|
|
update_sight()
|
|
|
|
if(stat == DEAD)
|
|
return
|
|
|
|
if(eye_blind)
|
|
overlay_fullscreen("blind", /atom/movable/screen/fullscreen/blind)
|
|
else
|
|
clear_fullscreen("blind")
|
|
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /atom/movable/screen/fullscreen/impaired, 1)
|
|
set_fullscreen(eye_blurry, "blurry", /atom/movable/screen/fullscreen/blurry)
|
|
|
|
set_fullscreen(stat == UNCONSCIOUS, "blackout", /atom/movable/screen/fullscreen/blackout)
|
|
|
|
if(machine)
|
|
var/viewflags = machine.check_eye(src)
|
|
if(viewflags < 0)
|
|
reset_view(null, 0)
|
|
else if(viewflags)
|
|
set_sight(viewflags)
|
|
else if(eyeobj)
|
|
eyeobj.apply_visual(src)
|
|
if(eyeobj.owner != src)
|
|
reset_view(null)
|
|
else if(!client.adminobs)
|
|
reset_view(null)
|
|
|
|
/mob/living/proc/handle_hearing()
|
|
// deafness heals slowly over time, unless ear_damage is over HEARING_DAMAGE_LIMIT
|
|
if(ear_damage < HEARING_DAMAGE_LIMIT)
|
|
adjustEarDamage(-0.05, -1)
|
|
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
|
|
setEarDamage(-1, max(ear_deaf, 1))
|
|
|
|
/mob/living/proc/update_sight()
|
|
if(stop_sight_update)
|
|
return
|
|
|
|
set_sight(0)
|
|
if(stat == DEAD || (eyeobj && !eyeobj.living_eye))
|
|
update_dead_sight()
|
|
else
|
|
update_living_sight()
|
|
|
|
var/list/vision = get_accumulated_vision_handlers()
|
|
set_sight(sight | vision[1])
|
|
set_see_invisible(max(vision[2], see_invisible))
|
|
sync_lighting_plane_alpha()
|
|
|
|
/mob/living/proc/update_living_sight()
|
|
var/set_sight_flags = is_ventcrawling ? (SEE_TURFS) : sight & ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
|
if(is_ventcrawling)
|
|
set_sight_flags |= BLIND
|
|
else
|
|
set_sight_flags &= ~BLIND
|
|
|
|
set_sight(set_sight_flags)
|
|
set_see_invisible(see_invisible)
|
|
|
|
/mob/living/proc/update_dead_sight()
|
|
set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
|
set_see_invisible(SEE_INVISIBLE_LEVEL_TWO)
|
|
|
|
/mob/living/proc/handle_hud_icons()
|
|
handle_hud_icons_health()
|
|
handle_hud_glasses()
|
|
|
|
/mob/living/proc/handle_hud_icons_health()
|
|
return
|
|
|
|
/mob/living
|
|
var/datum/weakref/last_weather
|
|
|
|
/mob/living/proc/is_outside()
|
|
var/turf/T = loc
|
|
return istype(T) && T.is_outside()
|
|
|
|
/mob/living/proc/get_affecting_weather()
|
|
var/turf/my_turf = get_turf(src)
|
|
if(!istype(my_turf))
|
|
return
|
|
var/turf/actual_loc = loc
|
|
// If we're standing in the rain, use the turf weather.
|
|
. = istype(actual_loc) && actual_loc.weather
|
|
if(!.) // If we're under or inside shelter, use the z-level rain (for ambience)
|
|
. = SSweather.weather_by_z["[my_turf.z]"]
|
|
|
|
/mob/living/proc/handle_environment(var/datum/gas_mixture/environment, seconds_per_tick)
|
|
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
|
|
// Handle physical effects of weather.
|
|
var/singleton/state/weather/weather_state
|
|
var/obj/abstract/weather_system/weather = get_affecting_weather()
|
|
if(weather_cooldown_time <= world.time && weather)
|
|
weather_cooldown_time = world.time + WEATHER_COOLDOWN_TIME
|
|
weather_state = weather.weather_system.current_state
|
|
if(istype(weather_state))
|
|
weather_state.handle_exposure(src, get_weather_exposure(weather), weather)
|
|
|
|
// Refresh weather ambience.
|
|
// Show messages and play ambience.
|
|
if(client)
|
|
|
|
// Work out if we need to change or cancel the current ambience sound.
|
|
var/send_sound
|
|
var/mob_ref = WEAKREF(src)
|
|
if(istype(weather_state))
|
|
var/ambient_sounds = !is_outside() ? weather_state.ambient_indoors_sounds : weather_state.ambient_sounds
|
|
var/ambient_sound = length(ambient_sounds) && pick(ambient_sounds)
|
|
if(GLOB.current_mob_ambience[mob_ref] == ambient_sound)
|
|
return
|
|
send_sound = ambient_sound
|
|
GLOB.current_mob_ambience[mob_ref] = send_sound
|
|
else if(mob_ref in GLOB.current_mob_ambience)
|
|
GLOB.current_mob_ambience -= mob_ref
|
|
else
|
|
return
|
|
|
|
// Push sound to client. Pipe dream TODO: crossfade between the new and old weather ambience.
|
|
sound_to(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = GLOB.sound_channels.weather_channel))
|
|
if(send_sound)
|
|
sound_to(src, sound(send_sound, repeat = TRUE, wait = 0, volume = 30, channel = GLOB.sound_channels.weather_channel))
|
|
|