Skip to content

Commit

Permalink
add: SSD And Unconscious Indicators (#5182)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gottfrei authored Jul 3, 2024
1 parent dea9efe commit 7563ae2
Show file tree
Hide file tree
Showing 21 changed files with 165 additions and 94 deletions.
5 changes: 5 additions & 0 deletions code/__DEFINES/emotes_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,8 @@

/// List of emotes useable by ghosties
#define USABLE_DEAD_EMOTES list("*flip", "*spin")

/// Sentinel for emote stats.
/// If this is set for max stat, then its value will be ignored.
#define DEFAULT_MAX_STAT_ALLOWED_EMOTE "defaultstat"

90 changes: 46 additions & 44 deletions code/__DEFINES/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -164,50 +164,52 @@
#define MFOAM_IRON 2

//Carbon Overlays Indexes/////////
#define MUTANTRACE_LAYER 43
#define WING_UNDERLIMBS_LAYER 42
#define TAIL_UNDERLIMBS_LAYER 41 //Tail split-rendering.
#define LIMBS_LAYER 40
#define INTORGAN_LAYER 39
#define MARKINGS_LAYER 38
#define UNDERWEAR_LAYER 37
#define MUTATIONS_LAYER 36
#define H_DAMAGE_LAYER 35
#define UNIFORM_LAYER 34
#define SHOES_LAYER 33
#define OVER_SHOES_LAYER 32
#define ID_LAYER 31
#define GLOVES_LAYER 30
#define EARS_LAYER 29
#define SUIT_LAYER 28
#define BELT_LAYER 27 //Possible make this an overlay of somethign required to wear a belt?
#define NECK_LAYER 26
#define SUIT_STORE_LAYER 25
#define BACK_LAYER 24
#define HEAD_ACCESSORY_LAYER 23
#define FHAIR_LAYER 22
#define GLASSES_LAYER 21
#define HAIR_LAYER 20 //TODO: make part of head layer?
#define HEAD_ACC_OVER_LAYER 19 //Select-layer rendering.
#define FHAIR_OVER_LAYER 18 //Select-layer rendering.
#define GLASSES_OVER_LAYER 17 //Select-layer rendering.
#define WING_LAYER 16
#define TAIL_LAYER 15 //bs12 specific. this hack is probably gonna come back to haunt me
#define FACEMASK_LAYER 14
#define OVER_MASK_LAYER 13 //Select-layer rendering.
#define HEAD_LAYER 12
#define OVER_HEAD_LAYER 11
#define COLLAR_LAYER 10
#define HANDCUFF_LAYER 9
#define LEGCUFF_LAYER 8
#define L_HAND_LAYER 7
#define R_HAND_LAYER 6
#define TARGETED_LAYER 5 //BS12: Layer for the target overlay from weapon targeting system
#define HALO_LAYER 4 //blood cult ascended halo, because there's currently no better solution for adding/removing
#define FIRE_LAYER 3 //If you're on fire
#define MISC_LAYER 2
#define FROZEN_LAYER 1
#define TOTAL_LAYERS 44
#define MUTANTRACE_LAYER 45
#define WING_UNDERLIMBS_LAYER 44
#define TAIL_UNDERLIMBS_LAYER 43 //Tail split-rendering.
#define LIMBS_LAYER 42
#define INTORGAN_LAYER 41
#define MARKINGS_LAYER 40
#define UNDERWEAR_LAYER 39
#define MUTATIONS_LAYER 38
#define H_DAMAGE_LAYER 37
#define UNIFORM_LAYER 36
#define SHOES_LAYER 35
#define OVER_SHOES_LAYER 34
#define ID_LAYER 33
#define GLOVES_LAYER 32
#define EARS_LAYER 31
#define SUIT_LAYER 30
#define BELT_LAYER 29 //Possible make this an overlay of somethign required to wear a belt?
#define NECK_LAYER 28
#define SUIT_STORE_LAYER 27
#define BACK_LAYER 26
#define HEAD_ACCESSORY_LAYER 25
#define FHAIR_LAYER 24
#define GLASSES_LAYER 23
#define HAIR_LAYER 22 //TODO: make part of head layer?
#define HEAD_ACC_OVER_LAYER 21 //Select-layer rendering.
#define FHAIR_OVER_LAYER 20 //Select-layer rendering.
#define GLASSES_OVER_LAYER 19 //Select-layer rendering.
#define WING_LAYER 18
#define TAIL_LAYER 17 //bs12 specific. this hack is probably gonna come back to haunt me
#define FACEMASK_LAYER 16
#define OVER_MASK_LAYER 15 //Select-layer rendering.
#define HEAD_LAYER 14
#define OVER_HEAD_LAYER 13
#define COLLAR_LAYER 12
#define HANDCUFF_LAYER 11
#define LEGCUFF_LAYER 10
#define L_HAND_LAYER 9
#define R_HAND_LAYER 8
#define TARGETED_LAYER 7 //BS12: Layer for the target overlay from weapon targeting system
#define HALO_LAYER 6 //blood cult ascended halo, because there's currently no better solution for adding/removing
#define FIRE_LAYER 5 //If you're on fire
#define MISC_LAYER 4
#define SLEEP_LAYER 3
#define FROZEN_LAYER 2
#define SSD_LAYER 1
#define TOTAL_LAYERS 46

///Access Region Codes///
#define REGION_ALL 0
Expand Down
15 changes: 4 additions & 11 deletions code/datums/emote/emote.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@

// Defines are in code\__DEFINES\emotes.dm

/// Sentinel for emote stats.
/// If this is set for max stat, then its value will be ignored.
#define DEFAULT_MAX_STAT_ALLOWED "defaultstat"

/**
* # Emote
*
Expand Down Expand Up @@ -81,12 +77,12 @@
var/stat_allowed = CONSCIOUS
/// How unconscious/dead can you be while still being able to use this emote intentionally?
/// If this is set to DEFAULT_STAT_ALLOWED, it'll behave as if it isn't set.
var/max_stat_allowed = DEFAULT_MAX_STAT_ALLOWED
var/max_stat_allowed = DEFAULT_MAX_STAT_ALLOWED_EMOTE
/// How conscious do you need to be to have this emote forced out of you?
var/unintentional_stat_allowed = CONSCIOUS
/// Same as above, how unconscious/dead do you need to be to have this emote forced out of you?
/// If this is set to DEFAULT_STAT_ALLOWED, it'll behave as if it isn't set.
var/max_unintentional_stat_allowed = DEFAULT_MAX_STAT_ALLOWED
var/max_unintentional_stat_allowed = DEFAULT_MAX_STAT_ALLOWED_EMOTE
/// Sound to play when emote is called. Might be a list with different sounds. If you want to adjust this dynamically, see get_sound().
var/sound
/// Whether or not to vary the sound of the emote.
Expand Down Expand Up @@ -492,8 +488,8 @@
return FALSE

if(status_check && !is_type_in_typecache(user, mob_type_ignore_stat_typecache))
var/intentional_stat_check = (intentional && (user.stat <= stat_allowed && (max_stat_allowed == DEFAULT_MAX_STAT_ALLOWED || user.stat >= max_stat_allowed)))
var/unintentional_stat_check = (!intentional && (user.stat <= unintentional_stat_allowed && (max_unintentional_stat_allowed == DEFAULT_MAX_STAT_ALLOWED || user.stat >= max_unintentional_stat_allowed)))
var/intentional_stat_check = (intentional && (user.stat <= stat_allowed && (max_stat_allowed == DEFAULT_MAX_STAT_ALLOWED_EMOTE || user.stat >= max_stat_allowed)))
var/unintentional_stat_check = (!intentional && (user.stat <= unintentional_stat_allowed && (max_unintentional_stat_allowed == DEFAULT_MAX_STAT_ALLOWED_EMOTE || user.stat >= max_unintentional_stat_allowed)))
if(!intentional_stat_check && !unintentional_stat_check)
var/stat = stat_to_text(user.stat)
if(!intentional)
Expand Down Expand Up @@ -629,6 +625,3 @@

visible_message(text)


#undef DEFAULT_MAX_STAT_ALLOWED

4 changes: 1 addition & 3 deletions code/datums/emote/emote_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,10 @@
set category = "Эмоции"
emote("sniff", intentional = TRUE)

/*
/mob/living/carbon/human/verb/emote_snore() // locked to unconscious stat
/mob/living/carbon/human/verb/emote_snore()
set name = "▷ Храпеть "
set category = "Эмоции"
emote("snore", intentional = TRUE)
*/

/mob/living/carbon/human/verb/emote_whistle()
set name = "▷ Свистеть "
Expand Down
4 changes: 4 additions & 0 deletions code/datums/keybindings/emote.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@
linked_emote = /datum/emote/living/swear
name = "Ругаться"

/datum/keybinding/emote/snore
linked_emote = /datum/emote/living/snore
name = "Храпеть"

/**
* Carbon
*/
Expand Down
2 changes: 1 addition & 1 deletion code/datums/mind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3106,7 +3106,7 @@

/mob/proc/sync_mind()
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = 1 //indicates that the mind is currently synced with a client
mind.active = TRUE //indicates that the mind is currently synced with a client

//slime
/mob/living/simple_animal/slime/mind_initialize()
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/poolcontroller.dm
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
if(!drownee)
return

if(drownee && ((drownee.body_position == LYING_DOWN && !drownee.player_logged) || deep_water)) //Mob lying down and not SSD or water is deep (determined by controller)
if(drownee && ((drownee.body_position == LYING_DOWN && isnull(drownee.player_logged)) || deep_water)) //Mob lying down and not SSD or water is deep (determined by controller)
if(drownee.internal)
return //Has internals, no drowning
if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations))
Expand Down
2 changes: 0 additions & 2 deletions code/modules/mob/dead/observer/observer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ Works together with spawning an observer, noted above.

/mob/proc/ghostize(flags = GHOST_CAN_REENTER)
if(key)
if(player_logged) //if they have disconnected we want to remove their SSD overlay
cut_overlay(image('icons/effects/effects.dmi', icon_state = "zzz_glow"))
if(GLOB.non_respawnable_keys[ckey])
flags &= ~GHOST_CAN_REENTER
var/mob/dead/observer/ghost = new(src, flags) //Transfer safety to observer spawning proc.
Expand Down
32 changes: 18 additions & 14 deletions code/modules/mob/living/carbon/human/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@

if(player_ghosted > 0 && stat == CONSCIOUS && job && !HAS_TRAIT(src, TRAIT_RESTRAINED))
handle_ghosted()
if(player_logged > 0 && stat != DEAD && job)
handle_ssd()

if(stat != DEAD)
return TRUE
Expand All @@ -67,18 +65,24 @@
if(player_ghosted % 150 == 0)
force_cryo_human(src)

/mob/living/carbon/human/proc/handle_ssd()
player_logged++
if(istype(loc, /obj/machinery/cryopod))
return
if(CONFIG_GET(number/auto_cryo_ssd_mins) && (player_logged >= (CONFIG_GET(number/auto_cryo_ssd_mins) * 30)) && player_logged % 30 == 0)
var/turf/T = get_turf(src)
if(!is_station_level(T.z))
return
var/area/A = get_area(src)
cryo_ssd(src)
if(A.fast_despawn)
force_cryo_human(src)

/mob/living/carbon/human/handle_SSD(seconds_per_tick)
. = ..()
if(!. || !job || istype(loc, /obj/machinery/cryopod) || !CONFIG_GET(number/auto_cryo_ssd_mins))
return .

if(player_logged < (CONFIG_GET(number/auto_cryo_ssd_mins) MINUTES))
return .

var/turf/our_turf = get_turf(src)
if(!our_turf || !is_station_level(our_turf.z))
return .

cryo_ssd(src)
var/area/our_area = get_area(src)
if(our_area.fast_despawn)
force_cryo_human(src)


/mob/living/carbon/human/calculate_affecting_pressure(pressure)
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
Expand Down
4 changes: 1 addition & 3 deletions code/modules/mob/living/carbon/human/login.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/mob/living/carbon/human/Login()
if(player_logged)
cut_overlay(image('icons/effects/effects.dmi', icon_state = "zzz_glow"))
..()
regenerate_icons()
return

4 changes: 2 additions & 2 deletions code/modules/mob/living/carbon/human/logout.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/mob/living/carbon/human/Logout()
..()
if(mind && mind.active && stat != DEAD)
add_overlay(image('icons/effects/effects.dmi', icon_state = "zzz_glow"))
// nothing for now

20 changes: 20 additions & 0 deletions code/modules/mob/living/carbon/human/update_icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
add_overlay(get_emissive_block())
update_halo_layer()
update_fire()
update_ssd_overlay()
update_unconscious_overlay()
SEND_SIGNAL(src, COMSIG_HUMAN_REGENERATE_ICONS)


Expand Down Expand Up @@ -1319,3 +1321,21 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)

. = "[.][!!husk][!!hulk][!!skeleton]"


/mob/living/carbon/human/update_ssd_overlay()
if(!isnull(player_logged))
overlays_standing[SSD_LAYER] = mutable_appearance('icons/effects/effects.dmi', "SSD", -SSD_LAYER, appearance_flags = KEEP_APART|RESET_TRANSFORM|RESET_COLOR)
apply_overlay(SSD_LAYER)
else
remove_overlay(SSD_LAYER)


/mob/living/carbon/human/update_unconscious_overlay()
if(stat == UNCONSCIOUS)
var/mutable_appearance/sleep_effect = mutable_appearance('icons/effects/effects.dmi', "sleep", -SLEEP_LAYER, appearance_flags = KEEP_APART|RESET_TRANSFORM|RESET_COLOR)
sleep_effect.pixel_z = 8
overlays_standing[SLEEP_LAYER] = sleep_effect
apply_overlay(SLEEP_LAYER)
else
remove_overlay(SLEEP_LAYER)

13 changes: 13 additions & 0 deletions code/modules/mob/living/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@

handle_gravity(seconds, times_fired)

handle_SSD(seconds)

if(stat != DEAD)
return TRUE

Expand Down Expand Up @@ -282,3 +284,14 @@
if(!breathing_tube)
AdjustLoseBreath(3 SECONDS, bound_upper = 6 SECONDS)


/// Handles mob SSD status.
/mob/living/proc/handle_SSD(seconds_per_tick)
if(isnull(player_logged))
return FALSE
if(stat == DEAD)
set_SSD(FALSE)
return FALSE
player_logged += seconds_per_tick SECONDS // called every 2s. on life
return TRUE

35 changes: 35 additions & 0 deletions code/modules/mob/living/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2177,14 +2177,17 @@
update_sight()
update_blind_effects()
update_blurry_effects()
update_unconscious_overlay()
if(UNCONSCIOUS)
update_sight()
update_blind_effects()
update_blurry_effects()
update_unconscious_overlay()
if(DEAD)
update_sight()
update_blind_effects()
update_blurry_effects()
update_unconscious_overlay()
GLOB.alive_mob_list += src
GLOB.dead_mob_list -= src

Expand Down Expand Up @@ -2240,3 +2243,35 @@
return
layer = (body_position == LYING_DOWN) ? LYING_MOB_LAYER : initial(layer)


/**
* Updates mob's SSD status with all the necessaey checks.
*
* Arguments:
* * enable (boolean) - `TRUE` to set SSD status, `FALSE` to remove.
*
* Returns `TRUE` on success, `FALSE` otherwise.
*/
/mob/living/proc/set_SSD(enable)
if(!mind || !last_known_ckey) // mindless / non player mobs are skipped
return FALSE

if(enable)
if(stat == DEAD) // dead mobs are skipped, unless we are removing SSD status
return FALSE
if(!mind.active || (ckey && ckey[1] == "@")) // aghosting will do this, we want to avoid SSDing admemes
return FALSE
if(!isnull(player_logged)) // already in SSD, return TRUE and we are done
return TRUE
// this causes instant sleep and tags a player as SSD. See [/proc/handle_SSD()] for furthering SSD
player_logged = 0
Sleeping(4 SECONDS)
. = TRUE
else
if(isnull(player_logged)) // SSD status is removed already, return TRUE and we are done
return TRUE
player_logged = null
. = TRUE

update_ssd_overlay() // special SSD overlay handling

5 changes: 0 additions & 5 deletions code/modules/mob/living/living_emote.dm
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,6 @@
emote_type = EMOTE_AUDIBLE|EMOTE_MOUTH
volume = 70
age_based = TRUE
// lock it so these emotes can only be used while unconscious
stat_allowed = UNCONSCIOUS
max_stat_allowed = UNCONSCIOUS
unintentional_stat_allowed = UNCONSCIOUS
max_unintentional_stat_allowed = UNCONSCIOUS


/datum/emote/living/snore/get_sound(mob/living/carbon/human/user)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/login.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
update_z(T.z)

//If they're SSD, remove it so they can wake back up.
player_logged = 0
set_SSD(FALSE)
//Vents
if(is_ventcrawler(src))
to_chat(src, span_notice("You can ventcrawl! Use <b>Alt+Click</b> on vents to quickly travel about the station."))
Expand Down
Loading

0 comments on commit 7563ae2

Please sign in to comment.