From dc6ccd3ecc63463e20f3c3698ad40ddfe9877ea9 Mon Sep 17 00:00:00 2001 From: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com> Date: Mon, 8 Nov 2021 04:36:27 -0500 Subject: [PATCH] Adds yawn propagation (#62639) --- code/__DEFINES/cooldowns.dm | 3 ++ code/__DEFINES/mobs.dm | 2 ++ code/modules/mob/living/emote.dm | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index 6bca58aac18..a2210386ad5 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -52,6 +52,9 @@ #define COOLDOWN_CIRCUIT_PATHFIND_DIF "circuit_pathfind_different" #define COOLDOWN_CIRCUIT_TARGET_INTERCEPT "circuit_target_intercept" +// mob cooldowns +#define COOLDOWN_YAWN_PROPAGATION "yawn_propagation_cooldown" + //TIMER COOLDOWN MACROS #define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 79d99c5f655..e58071e5874 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -415,6 +415,8 @@ #define EXAMINE_MORE_WINDOW 1 SECONDS /// If you examine another mob who's successfully examined you during this duration of time, you two try to make eye contact. Cute! #define EYE_CONTACT_WINDOW 2 SECONDS +/// If you yawn while someone nearby has examined you within this time frame, it will force them to yawn as well. Tradecraft! +#define YAWN_PROPAGATION_EXAMINE_WINDOW 2 SECONDS /// How far away you can be to make eye contact with someone while examining #define EYE_CONTACT_RANGE 5 diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 424d509c4a4..ab313f02e18 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -414,11 +414,58 @@ key_third_person = "wsmiles" message = "smiles weakly." +/// The base chance for your yawn to propagate to someone else if they're on the same tile as you +#define YAWN_PROPAGATE_CHANCE_BASE 60 +/// The base chance for your yawn to propagate to someone else if they're on the same tile as you +#define YAWN_PROPAGATE_CHANCE_DECAY 10 + /datum/emote/living/yawn key = "yawn" key_third_person = "yawns" message = "yawns." emote_type = EMOTE_AUDIBLE + cooldown = 3 SECONDS + +/datum/emote/living/yawn/run_emote(mob/user, params, type_override, intentional) + . = ..() + if(!. || !isliving(user)) + return + + if(!TIMER_COOLDOWN_CHECK(user, COOLDOWN_YAWN_PROPAGATION)) + TIMER_COOLDOWN_START(user, COOLDOWN_YAWN_PROPAGATION, cooldown * 3) + + var/mob/living/carbon/carbon_user = user + if(istype(carbon_user) && ((carbon_user.wear_mask?.flags_inv & HIDEFACE) || carbon_user.head?.flags_inv & HIDEFACE)) + return // if your face is obscured, skip propagation + + var/propagation_distance = user.client ? 5 : 2 // mindless mobs are less able to spread yawns + + for(var/mob/living/iter_living in view(user, propagation_distance)) + if(IS_DEAD_OR_INCAP(iter_living) || TIMER_COOLDOWN_CHECK(user, COOLDOWN_YAWN_PROPAGATION)) + continue + + var/dist_between = get_dist(user, iter_living) + var/recently_examined = FALSE // if you yawn just after someone looks at you, it forces them to yawn as well. Tradecraft! + + if(iter_living.client) + var/examine_time = LAZYACCESS(iter_living.client?.recent_examines, user) + if(examine_time && (world.time - examine_time < YAWN_PROPAGATION_EXAMINE_WINDOW)) + recently_examined = TRUE + + if(!recently_examined && !prob(YAWN_PROPAGATE_CHANCE_BASE - (YAWN_PROPAGATE_CHANCE_DECAY * dist_between))) + continue + + var/yawn_delay = rand(0.25 SECONDS, 0.75 SECONDS) * dist_between + addtimer(CALLBACK(src, .proc/propagate_yawn, iter_living), yawn_delay) + +/// This yawn has been triggered by someone else yawning specifically, likely after a delay. Check again if they don't have the yawned recently trait +/datum/emote/living/yawn/proc/propagate_yawn(mob/user) + if(!istype(user) || TIMER_COOLDOWN_CHECK(user, COOLDOWN_YAWN_PROPAGATION)) + return + user.emote("yawn") + +#undef YAWN_PROPAGATE_CHANCE_BASE +#undef YAWN_PROPAGATE_CHANCE_DECAY /datum/emote/living/gurgle key = "gurgle"