#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_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.8 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) msg = "[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(msg) if(emote_type == EMOTE_AUDIBLE) user.audible_message(msg) else user.visible_message(msg) /// For handling emote cooldown, return true to allow the emote to happen /datum/emote/proc/check_cooldown(mob/user, intentional) if(!intentional) return TRUE if(user.emotes_used && user.emotes_used[src] + cooldown > world.time) return FALSE 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(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, "You cannot [key] while in a critical condition!") if(UNCONSCIOUS) to_chat(user, "You cannot [key] while unconscious!") if(DEAD) to_chat(user, "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, "You cannot [key] while stunned!") return FALSE if(restraint_check && user.restrained()) if(!intentional) return FALSE to_chat(user, "You cannot [key] while restrained!") return FALSE if(isliving(user)) var/mob/living/L = user if(HAS_TRAIT(L, TRAIT_EMOTEMUTE)) return FALSE