#define EMOTE_VISIBLE 1 #define EMOTE_AUDIBLE 2 /datum/emote var/key = "" //What calls the emote var/key_third_person = "" //This will also call the emote var/message = "" //Message displayed when emote is used var/message_mime = "" //Message displayed if the user is a mime var/message_alien = "" //Message displayed if the user is a grown alien var/message_larva = "" //Message displayed if the user is an alien larva var/message_robot = "" //Message displayed if the user is a robot var/message_AI = "" //Message displayed if the user is an AI var/message_monkey = "" //Message displayed if the user is a monkey var/message_ipc = "" // Message to display if the user is an IPC var/message_simple = "" //Message to display if the user is a simple_animal var/message_param = "" //Message to display if a param was given var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote var/muzzle_ignore = FALSE //Will only work if the emote is EMOTE_AUDIBLE var/list/mob_type_allowed_typecache = /mob //Types that are allowed to use that emote var/list/mob_type_blacklist_typecache //Types that are NOT allowed to use that emote var/list/mob_type_ignore_stat_typecache var/stat_allowed = CONSCIOUS var/sound //Sound to play when emote is called var/vary = FALSE //used for the honk borg emote var/only_forced_audio = FALSE //can only code call this event instead of the player. var/cooldown = 0.4 SECONDS /datum/emote/New() if (ispath(mob_type_allowed_typecache)) switch (mob_type_allowed_typecache) if (/mob) mob_type_allowed_typecache = GLOB.typecache_mob if (/mob/living) mob_type_allowed_typecache = GLOB.typecache_living else mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache) else mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache) mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache) mob_type_ignore_stat_typecache = typecacheof(mob_type_ignore_stat_typecache) /datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE) . = TRUE if(!can_run_emote(user, TRUE, intentional)) return FALSE var/msg = select_message_type(user, intentional) if(params && message_param) msg = select_param(user, params) msg = replace_pronoun(user, msg) if(isliving(user)) var/mob/living/L = user for(var/obj/item/implant/I in L.implants) I.trigger(key, L) if(!msg) return user.log_message(msg, LOG_EMOTE) var/dchatmsg = "[user] [msg]" var/tmp_sound = get_sound(user) if(tmp_sound && (!only_forced_audio || !intentional)) playsound(user, tmp_sound, 50, vary) for(var/mob/M in GLOB.dead_mob_list) if(!M.client || isnewplayer(M)) continue var/T = get_turf(user) if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null))) M.show_message("[FOLLOW_LINK(M, user)] [dchatmsg]") if(emote_type == EMOTE_AUDIBLE) user.audible_message(msg, audible_message_flags = EMOTE_MESSAGE) else user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE) /// For handling emote cooldown, return true to allow the emote to happen /datum/emote/proc/check_cooldown(mob/user, intentional, update=TRUE) if(!intentional) return TRUE if(user.emotes_used && user.emotes_used[src] + cooldown > world.time) return FALSE if(!update) return TRUE if(!user.emotes_used) user.emotes_used = list() user.emotes_used[src] = world.time return TRUE /datum/emote/proc/get_sound(mob/living/user) return sound //by default just return this var. /datum/emote/proc/replace_pronoun(mob/user, message) if(findtext(message, "their")) message = replacetext(message, "their", user.p_their()) if(findtext(message, "them")) message = replacetext(message, "them", user.p_them()) if(findtext(message, "%s")) message = replacetext(message, "%s", user.p_s()) return message /datum/emote/proc/select_message_type(mob/user, intentional) . = message if(!muzzle_ignore && user.is_muzzled() && emote_type == EMOTE_AUDIBLE) return "makes a [pick("strong ", "weak ", "")]noise." if(user.mind && user.mind.miming && message_mime) . = message_mime if(isalienadult(user) && message_alien) . = message_alien else if(islarva(user) && message_larva) . = message_larva else if(iscyborg(user) && message_robot) . = message_robot else if(isAI(user) && message_AI) . = message_AI else if(ismonkey(user) && message_monkey) . = message_monkey else if(isipc(user) && message_ipc) . = message_ipc else if(isanimal(user) && message_simple) . = message_simple /datum/emote/proc/select_param(mob/user, params) return replacetext(message_param, "%t", params) /datum/emote/proc/can_run_emote(mob/user, status_check = TRUE, intentional = FALSE) . = TRUE if(!is_type_in_typecache(user, mob_type_allowed_typecache)) return FALSE if(is_type_in_typecache(user, mob_type_blacklist_typecache)) return FALSE if(status_check && !is_type_in_typecache(user, mob_type_ignore_stat_typecache)) if(user.stat > stat_allowed) if(!intentional) return FALSE switch(user.stat) if(SOFT_CRIT) to_chat(user, span_notice("You cannot [key] while in a critical condition.")) if(UNCONSCIOUS) to_chat(user, span_notice("You cannot [key] while unconscious.")) if(DEAD) to_chat(user, span_notice("You cannot [key] while dead.")) return FALSE if(restraint_check) if(isliving(user)) var/mob/living/L = user if(L.IsParalyzed() || L.IsStun()) if(!intentional) return FALSE to_chat(user, span_notice("You cannot [key] while stunned.")) return FALSE if(restraint_check && user.restrained()) if(!intentional) return FALSE to_chat(user, span_notice("You cannot [key] while restrained.")) return FALSE if(isliving(user)) var/mob/living/L = user if(HAS_TRAIT(L, TRAIT_EMOTEMUTE)) return FALSE /** * Allows the intrepid coder to send a basic emote * Takes text as input, sends it out to those who need to know after some light parsing * If you need something more complex, make it into a datum emote * Arguments: * * text - The text to send out */ /mob/proc/manual_emote(text) //Just override the song and dance . = TRUE if(findtext(text, "their")) text = replacetext(text, "their", p_their()) if(findtext(text, "them")) text = replacetext(text, "them", p_them()) if(findtext(text, "%s")) text = replacetext(text, "%s", p_s()) if(stat != CONSCIOUS) return if(!text) CRASH("Someone passed nothing to manual_emote(), fix it") log_message(text, LOG_EMOTE) var/ghost_text = "[src] " + text //Sin I know for(var/mob/M in GLOB.dead_mob_list) if(!M.client || isnewplayer(M)) continue var/T = get_turf(src) if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null))) M.show_message("[FOLLOW_LINK(M, src)] [ghost_text]") visible_message(text, visible_message_flags = EMOTE_MESSAGE)