diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm index 710e4d9ae20a..61eb757e9c4d 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm @@ -109,6 +109,12 @@ #define COMSIG_MOB_EMOTED(emote_key) "mob_emoted_[emote_key]" +#define COMSIG_MOB_TRY_EMOTE "mob_try_emote" + #define COMPONENT_OVERRIDE_EMOTE (1<<0) + +#define COMSIG_MOB_TRY_POINT "mob_try_point" + #define COMPONENT_OVERRIDE_POINT (1<<0) + //from /mob/living/set_stat() #define COMSIG_MOB_STAT_SET_ALIVE "mob_stat_set_alive" //from /mob/living/set_stat() diff --git a/code/datums/components/temporary_mute.dm b/code/datums/components/temporary_mute.dm index 86d6ba8378d8..bd3f3ba28371 100644 --- a/code/datums/components/temporary_mute.dm +++ b/code/datums/components/temporary_mute.dm @@ -2,17 +2,20 @@ dupe_mode = COMPONENT_DUPE_UNIQUE /// A message to tell the user when they attempt to speak, if any var/on_speak_message = "" + /// A message to tell the user when they attempt to emote, if any + var/on_emote_message = "" /// A message to tell the user when they become no longer mute, if any var/on_unmute_message = "" /// How long after the component's initialization it should be deleted. -1 means it will never delete var/time_until_unmute = 3 MINUTES -/datum/component/temporary_mute/Initialize(on_speak_message = "", on_unmute_message = "", time_until_unmute = 3 MINUTES) +/datum/component/temporary_mute/Initialize(on_speak_message = "", on_emote_message = "", on_unmute_message = "", time_until_unmute = 3 MINUTES) . = ..() if(!ismob(parent)) return COMPONENT_INCOMPATIBLE src.on_speak_message = on_speak_message + src.on_emote_message = on_emote_message src.on_unmute_message = on_unmute_message src.time_until_unmute = time_until_unmute if(time_until_unmute != -1) @@ -22,12 +25,16 @@ ..() RegisterSignal(parent, COMSIG_LIVING_SPEAK, PROC_REF(on_speak)) RegisterSignal(parent, COMSIG_XENO_TRY_HIVEMIND_TALK, PROC_REF(on_hivemind)) + RegisterSignal(parent, COMSIG_MOB_TRY_EMOTE, PROC_REF(on_emote)) + RegisterSignal(parent, COMSIG_MOB_TRY_POINT, PROC_REF(on_point)) /datum/component/temporary_mute/UnregisterFromParent() ..() if(parent) UnregisterSignal(parent, COMSIG_LIVING_SPEAK) UnregisterSignal(parent, COMSIG_XENO_TRY_HIVEMIND_TALK) + UnregisterSignal(parent, COMSIG_MOB_TRY_EMOTE) + UnregisterSignal(parent, COMSIG_MOB_TRY_POINT) if(on_unmute_message) to_chat(parent, SPAN_NOTICE(on_unmute_message)) @@ -59,3 +66,26 @@ if(on_speak_message) to_chat(parent, SPAN_BOLDNOTICE(on_speak_message)) return COMPONENT_OVERRIDE_HIVEMIND_TALK + +/datum/component/temporary_mute/proc/on_emote(mob/user, datum/emote/current_emote, act, m_type, param, intentional) + SIGNAL_HANDLER + + // Allow involuntary emotes or non-custom emotes + if(!intentional) + return + if(!param && !istype(current_emote, /datum/emote/custom)) + return + //message = current_emote.message + + log_say("[user.name != "Unknown" ? user.name : "([user.real_name])"] attempted to emote the following before their spawn mute ended: [param] (CKEY: [user.key]) (JOB: [user.job])") + if(on_emote_message) + to_chat(parent, SPAN_BOLDNOTICE(on_emote_message)) + return COMPONENT_OVERRIDE_EMOTE + +/datum/component/temporary_mute/proc/on_point(mob/user, atom/target) + SIGNAL_HANDLER + + log_say("[user.name != "Unknown" ? user.name : "([user.real_name])"] attempted to point at the following before their spawn mute ended: [target] (CKEY: [user.key]) (JOB: [user.job])") + if(on_emote_message) + to_chat(parent, SPAN_BOLDNOTICE(on_emote_message)) + return COMPONENT_OVERRIDE_POINT diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 31e3b48e997f..fa7c7ec3176e 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -14,12 +14,15 @@ to_chat(src, SPAN_NOTICE("'[act]' emote does not exist. Say *help for a list.")) return FALSE var/silenced = FALSE - for(var/datum/emote/P in key_emotes) - if(!P.check_cooldown(src, intentional)) + for(var/datum/emote/current_emote in key_emotes) + if(!current_emote.check_cooldown(src, intentional)) silenced = TRUE continue - if(P.run_emote(src, param, m_type, intentional)) - SEND_SIGNAL(src, COMSIG_MOB_EMOTE, P, act, m_type, message, intentional) + if(SEND_SIGNAL(src, COMSIG_MOB_TRY_EMOTE, current_emote, act, m_type, param, intentional) & COMPONENT_OVERRIDE_EMOTE) + silenced = TRUE + continue + if(current_emote.run_emote(src, param, m_type, intentional)) + SEND_SIGNAL(src, COMSIG_MOB_EMOTE, current_emote, act, m_type, message, intentional) return TRUE if(intentional && !silenced && !force_silence) to_chat(src, SPAN_NOTICE("Unusable emote '[act]'. Say *help for a list.")) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index 32a10be6dd4c..ab7b22b73d81 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -73,6 +73,7 @@ AddComponent(\ /datum/component/temporary_mute,\ "We aren't old enough to vocalize anything yet.",\ + "We aren't old enough to communicate like this yet.",\ "We feel old enough to be able to vocalize and speak to the hivemind.",\ 3 MINUTES,\ ) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm index 1c1d1b00a51f..5d3f4b38c8f8 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/lesser_drone.dm @@ -92,6 +92,7 @@ AddComponent(\ /datum/component/temporary_mute,\ "We aren't old enough to vocalize anything yet.",\ + "We aren't old enough to communicate like this yet.",\ "We feel old enough to be able to vocalize and speak to the hivemind.",\ 3 MINUTES,\ ) diff --git a/code/modules/mob/mob_verbs.dm b/code/modules/mob/mob_verbs.dm index 1ba8985d56bd..f12d00cc0988 100644 --- a/code/modules/mob/mob_verbs.dm +++ b/code/modules/mob/mob_verbs.dm @@ -50,34 +50,33 @@ to_chat(usr, SPAN_DANGER("This mob type cannot throw items.")) return -/mob/proc/point_to(atom/A in view()) +/mob/proc/point_to(atom/target in view()) //set name = "Point To" //set category = "Object" - if(!isturf(src.loc) || !(A in view(src)))//target is no longer visible to us - return 0 + if(!isturf(src.loc) || !(target in view(src)))//target is no longer visible to us + return FALSE - if(!A.mouse_opacity)//can't click it? can't point at it. - return 0 + if(!target.mouse_opacity)//can't click it? can't point at it. + return FALSE if(is_mob_incapacitated() || (status_flags & FAKEDEATH)) //incapacitated, can't point - return 0 + return FALSE - var/tile = get_turf(A) - if (!tile) - return 0 + var/tile = get_turf(target) + if(!tile) + return FALSE if(recently_pointed_to > world.time) - return 0 - - next_move = world.time + 2 - - point_to_atom(A, tile) - return 1 - + return FALSE + if(SEND_SIGNAL(src, COMSIG_MOB_TRY_POINT, target) & COMPONENT_OVERRIDE_POINT) + return FALSE + next_move = world.time + 2 + point_to_atom(target, tile) + return TRUE /mob/verb/memory() set name = "Notes"