diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index ca00bfe90be..d887fbb2fb3 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -27,6 +27,7 @@ #define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) #define COMSIG_GLOB_MOB_CREATED "!mob_created" //mob was created somewhere : (mob) #define COMSIG_GLOB_MOB_DEATH "!mob_death" //mob died somewhere : (mob , gibbed) +#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) ////////////////////////////////////////////////////////////////// diff --git a/code/datums/components/beetlejuice.dm b/code/datums/components/beetlejuice.dm new file mode 100644 index 00000000000..85abbbea21b --- /dev/null +++ b/code/datums/components/beetlejuice.dm @@ -0,0 +1,59 @@ +/datum/component/beetlejuice + var/keyword + var/list/first_heard + var/list/count + var/max_delay = 3 SECONDS //How fast they need to be said + var/min_count = 3 + var/cooldown = 30 SECONDS //Delay between teleports + var/active = TRUE + var/regex/R + +/datum/component/beetlejuice/Initialize() + if(!ismovableatom(parent)) + return COMPONENT_INCOMPATIBLE + + first_heard = list() + count = list() + + var/atom/movable/O = parent + keyword = O.name + if(ismob(O)) + var/mob/M = parent + keyword = M.real_name + update_regex() + + RegisterSignal(SSdcs, COMSIG_GLOB_LIVING_SAY_SPECIAL, .proc/say_react) + +/datum/component/beetlejuice/proc/update_regex() + R = regex("[REGEX_QUOTE(keyword)]","g") + +/datum/component/beetlejuice/vv_edit_var(var_name, var_value) + . = ..() + if (var_name == NAMEOF(src, keyword)) + update_regex() + +/datum/component/beetlejuice/proc/say_react(datum/source, mob/speaker,message) + if(!speaker || !message || !active) + return + var/found = R.Find(message) + if(found) + var/occurences = 1 + while(R.Find(message)) + occurences++ + R.next = 1 + + if(!first_heard[speaker] || (first_heard[speaker] + max_delay < world.time)) + first_heard[speaker] = world.time + count[speaker] = 0 + count[speaker] += occurences + if(count[speaker] >= min_count) + first_heard -= speaker + count -= speaker + apport(speaker) + + +/datum/component/beetlejuice/proc/apport(atom/target) + var/atom/movable/AM = parent + do_teleport(AM,get_turf(target)) + active = FALSE + addtimer(VARSET_CALLBACK(src, active, TRUE), cooldown) \ No newline at end of file diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 248660a7f8c..da137fdfaf9 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -269,6 +269,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mode) else AM.Hear(rendered, src, message_language, message, , spans, message_mode) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message) //speech bubble var/list/speech_bubble_recipients = list() diff --git a/tgstation.dme b/tgstation.dme index c6a99fe0a27..a7b1833ea40 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -334,6 +334,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\armor_plate.dm" +#include "code\datums\components\beetlejuice.dm" #include "code\datums\components\butchering.dm" #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm"