diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 398f106ce9..0be1b3b44e 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -396,10 +396,6 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else pref.body_descriptors[entry] = CLAMP(last_descriptors[entry], 1, LAZYLEN(descriptor.standalone_value_descriptors)) - character.update_emotes() - - return - /datum/category_item/player_setup_item/general/body/content(var/mob/user) . = list() if(!pref.preview_icon) diff --git a/code/modules/emotes/definitions/_mob.dm b/code/modules/emotes/definitions/_mob.dm index 8c10b4cde2..8651c933b1 100644 --- a/code/modules/emotes/definitions/_mob.dm +++ b/code/modules/emotes/definitions/_mob.dm @@ -24,18 +24,3 @@ var/list/_default_mob_emotes = list( /decl/emote/audible/moan, /decl/emote/audible/gnarl, ) - -/mob - var/list/usable_emotes - -/mob/proc/update_emotes(var/skip_sort) - usable_emotes = list() - for(var/emote in get_default_emotes()) - var/decl/emote/emote_datum = decls_repository.get_decl(emote) - if(emote_datum.check_user(src)) - usable_emotes[emote_datum.key] = emote_datum - if(!skip_sort) - usable_emotes = sortAssoc(usable_emotes) - -/mob/proc/get_default_emotes() - return global._default_mob_emotes diff --git a/code/modules/emotes/definitions/_species.dm b/code/modules/emotes/definitions/_species.dm index ff15df2fae..3fb1ccd65d 100644 --- a/code/modules/emotes/definitions/_species.dm +++ b/code/modules/emotes/definitions/_species.dm @@ -1,11 +1,7 @@ /datum/species var/list/default_emotes = list() -/mob/living/carbon/update_emotes(var/skip_sort) - . = ..(skip_sort = TRUE) - if(species) - for(var/emote in species.default_emotes) - var/decl/emote/emote_datum = decls_repository.get_decl(emote) - if(emote_datum.check_user(src)) - usable_emotes[emote_datum.key] = emote_datum - usable_emotes = sortAssoc(usable_emotes) +/mob/living/carbon/get_available_emotes() + . = ..() + if(length(species?.default_emotes)) + . |= species.default_emotes diff --git a/code/modules/emotes/definitions/exertion.dm b/code/modules/emotes/definitions/exertion.dm index ac0061cca3..97404cef64 100644 --- a/code/modules/emotes/definitions/exertion.dm +++ b/code/modules/emotes/definitions/exertion.dm @@ -4,7 +4,7 @@ emote_message_1p = "You are sweating heavily." emote_message_3p = "is sweating heavily." -/decl/emote/exertion/biological/check_user(mob/living/user) +/decl/emote/exertion/biological/mob_can_use(mob/living/user) if(istype(user) && !user.isSynthetic()) return ..() return FALSE @@ -29,7 +29,7 @@ emote_message_1p = "You overstress your actuators." emote_message_3p = "USER's actuators whine with strain." -/decl/emote/exertion/synthetic/check_user(mob/living/user) +/decl/emote/exertion/synthetic/mob_can_use(mob/living/user) if(istype(user) && user.isSynthetic()) return ..() return FALSE diff --git a/code/modules/emotes/definitions/human.dm b/code/modules/emotes/definitions/human.dm index 1da9220623..ff97908622 100644 --- a/code/modules/emotes/definitions/human.dm +++ b/code/modules/emotes/definitions/human.dm @@ -1,11 +1,5 @@ -/decl/emote/human - key = "vomit" - -/decl/emote/human/check_user(var/mob/living/carbon/human/user) - return (istype(user) && user.check_has_mouth() && !user.isSynthetic()) - -/decl/emote/human/do_emote(var/mob/living/carbon/human/user) - user.vomit() +/decl/emote/human/mob_can_use(var/mob/living/carbon/human/user) + return ..() && istype(user) && user.check_has_mouth() && !user.isSynthetic() /decl/emote/human/deathgasp key = "deathgasp" diff --git a/code/modules/emotes/definitions/slimes.dm b/code/modules/emotes/definitions/slimes.dm index 877422825b..bde5b580aa 100644 --- a/code/modules/emotes/definitions/slimes.dm +++ b/code/modules/emotes/definitions/slimes.dm @@ -8,8 +8,8 @@ user.mood = mood user.update_icon() -/decl/emote/slime/check_user(var/atom/user) - return isslime(user) +/decl/emote/slime/mob_can_use(var/atom/user) + return ..() && isslime(user) /decl/emote/slime/pout key = "pout" diff --git a/code/modules/emotes/definitions/synthetics.dm b/code/modules/emotes/definitions/synthetics.dm index ae87d38a27..e0de1060b7 100644 --- a/code/modules/emotes/definitions/synthetics.dm +++ b/code/modules/emotes/definitions/synthetics.dm @@ -3,7 +3,7 @@ emote_message_3p = "beeps." emote_sound = 'sound/machines/twobeep.ogg' -/decl/emote/audible/synth/check_user(var/mob/living/user) +/decl/emote/audible/synth/mob_can_use(var/mob/living/user) if(istype(user) && user.isSynthetic()) return ..() return FALSE @@ -34,8 +34,8 @@ emote_message_3p_target = "shows TARGET USER_THEIR legal authorization barcode." emote_sound = 'sound/voice/biamthelaw.ogg' -/decl/emote/audible/synth/security/check_user(var/mob/living/silicon/robot/user) - return (istype(user) && istype(user.module, /obj/item/weapon/robot_module/robot/security)) +/decl/emote/audible/synth/security/mob_can_use(var/mob/living/silicon/robot/user) + return ..() && istype(user) && istype(user.module, /obj/item/weapon/robot_module/robot/security) /decl/emote/audible/synth/security/halt key = "halt" diff --git a/code/modules/emotes/definitions/visible.dm b/code/modules/emotes/definitions/visible.dm index 986839fff1..fa19ac257a 100644 --- a/code/modules/emotes/definitions/visible.dm +++ b/code/modules/emotes/definitions/visible.dm @@ -237,9 +237,6 @@ emote_message_3p = "signals." check_restraints = TRUE -/decl/emote/visible/signal/check_user(atom/user) - return ismob(user) - /decl/emote/visible/signal/get_emote_message_3p(var/mob/living/user, var/atom/target, var/extra_params) if(istype(user) && (!user.get_active_hand() || !user.get_inactive_hand())) var/t1 = round(text2num(extra_params)) diff --git a/code/modules/emotes/definitions/visible_animated.dm b/code/modules/emotes/definitions/visible_animated.dm index 2e035d289c..5a5d88a66b 100644 --- a/code/modules/emotes/definitions/visible_animated.dm +++ b/code/modules/emotes/definitions/visible_animated.dm @@ -2,6 +2,7 @@ key = "spin" check_restraints = TRUE emote_message_3p = "spins!" + emote_delay = 2 SECONDS /decl/emote/visible/spin/do_extra(mob/user) if(istype(user)) @@ -11,6 +12,7 @@ key = "sidestep" check_restraints = TRUE emote_message_3p = "steps rhythmically and moves side to side." + emote_delay = 1.2 SECONDS /decl/emote/visible/sidestep/do_extra(mob/user) if(istype(user)) @@ -24,6 +26,7 @@ emote_message_1p = "You do a flip!" emote_message_3p = "does a flip!" emote_sound = 'sound/effects/bodyfall4.ogg' + emote_delay = 1.2 SECONDS /decl/emote/visible/flip/do_extra(mob/user) . = ..() @@ -34,6 +37,7 @@ key = "floorspin" emote_message_1p = "You spin around on the floor!" emote_message_3p = "spins around on the floor!" + emote_delay = 1.2 SECONDS var/static/list/spin_dirs = list( NORTH, SOUTH, diff --git a/code/modules/emotes/emote_define.dm b/code/modules/emotes/emote_define.dm index 21d129c4a3..c0a480346b 100644 --- a/code/modules/emotes/emote_define.dm +++ b/code/modules/emotes/emote_define.dm @@ -4,6 +4,13 @@ // gender-appropriate version of the same. // - Impaired messages do not do any substitutions. +var/global/list/emotes_by_key + +/proc/get_emote_by_key(var/key) + if(!global.emotes_by_key) + decls_repository.get_decls_of_type(/decl/emote) // emotes_by_key will be updated in emote Initialize() + return global.emotes_by_key[key] + /decl/emote var/key // Command to use emote ie. '*[key]' var/emote_message_1p // First person message ('You do a flip!') @@ -28,6 +35,7 @@ var/list/emote_sound_synthetic // As above, but used when check_synthetic() is true. var/emote_volume = 50 // Volume of sound to play. var/emote_volume_synthetic = 50 // As above, but used when check_synthetic() is true. + var/emote_delay = 0 // Time in ds that this emote will block further emote use (spam prevention). var/message_type = VISIBLE_MESSAGE // Audible/visual flag var/check_restraints // Can this emote be used while restrained? @@ -35,6 +43,11 @@ var/conscious = TRUE // Do we need to be awake to emote this? var/emote_range = 0 // If >0, restricts emote visibility to viewers within range. +/decl/emote/Initialize() + . = ..() + if(key) + LAZYSET(global.emotes_by_key, key, src) + /decl/emote/proc/get_emote_message_1p(var/atom/user, var/atom/target, var/extra_params) if(target) if(emote_message_synthetic_1p_target && check_synthetic(user)) @@ -162,8 +175,8 @@ if(sound_to_play) playsound(user.loc, sound_to_play, use_sound["vol"], 0) -/decl/emote/proc/check_user(var/atom/user) - return TRUE +/decl/emote/proc/mob_can_use(var/mob/user) + return istype(user) && user.stat != DEAD && (type in user.get_available_emotes()) /decl/emote/proc/can_target() return (emote_message_1p_target || emote_message_3p_target) diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index bda07cbb11..f315fd69c4 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -1,9 +1,18 @@ +/mob + var/next_emote + var/next_emote_refresh + var/last_emote_summary + +/mob/proc/get_available_emotes() + return global._default_mob_emotes + /mob/proc/can_emote(var/emote_type) return (stat == CONSCIOUS) /mob/living/can_emote(var/emote_type) return (..() && !(silent && emote_type == AUDIBLE_MESSAGE)) +#define EMOTE_REFRESH_SPAM_COOLDOWN (5 SECONDS) /mob/proc/emote(var/act, var/m_type, var/message) set waitfor = FALSE // s-s-snowflake @@ -15,8 +24,20 @@ to_chat(src, "You cannot send IC messages (muted).") return + if(world.time < next_emote) + to_chat(src, SPAN_WARNING("You cannot use another emote yet.")) + return + if(act == "help") - to_chat(src,"Usable emotes: [english_list(usable_emotes)].") + if(world.time >= next_emote_refresh) + var/list/usable_emotes = list() + next_emote_refresh = world.time + EMOTE_REFRESH_SPAM_COOLDOWN + for(var/emote in get_available_emotes()) + var/decl/emote/emote_datum = decls_repository.get_decl(emote) + if(emote_datum.mob_can_use(src)) + usable_emotes[emote_datum.key] = emote_datum + last_emote_summary = english_list(sortAssoc(usable_emotes)) + to_chat(src,"Usable emotes: [last_emote_summary].") return if(!can_emote(m_type)) @@ -44,24 +65,30 @@ act = copytext(tempstr,1,splitpoint) message = copytext(tempstr,splitpoint+1,0) - var/decl/emote/use_emote = usable_emotes[act] - if(!use_emote) + var/decl/emote/use_emote = get_emote_by_key(act) + if(!istype(use_emote)) to_chat(src, SPAN_WARNING("Unknown emote '[act]'. Type say *help for a list of usable emotes.")) return + if(!use_emote.mob_can_use(src)) + to_chat(src, SPAN_WARNING("You cannot use the emote '[act]'. Type say *help for a list of usable emotes.")) + return + if(m_type != use_emote.message_type && use_emote.conscious && stat != CONSCIOUS) return if(use_emote.message_type == AUDIBLE_MESSAGE && is_muzzled()) audible_message("\The [src] [use_emote.emote_message_muffled || "makes a muffled sound."]") return - else - use_emote.do_emote(src, message) + next_emote = world.time + use_emote.emote_delay + use_emote.do_emote(src, message) for (var/obj/item/weapon/implant/I in src) if (I.implanted) I.trigger(act, src) +#undef EMOTE_REFRESH_SPAM_COOLDOWN + /mob/proc/format_emote(var/emoter = null, var/message = null) var/pretext var/subtext diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm index 739c3b09c6..690fdb3325 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona.dm @@ -46,7 +46,7 @@ var/list/_nymph_default_emotes = list( holder_type = /obj/item/weapon/holder/diona var/obj/item/hat -/mob/living/carbon/alien/diona/get_default_emotes() +/mob/living/carbon/alien/diona/get_available_emotes() return global._nymph_default_emotes /mob/living/carbon/alien/diona/Initialize() diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm index b0517e7a95..cb7ab9b7b0 100644 --- a/code/modules/mob/living/carbon/alien/emote.dm +++ b/code/modules/mob/living/carbon/alien/emote.dm @@ -27,5 +27,5 @@ var/list/_alien_default_emotes = list( /decl/emote/audible/chirp ) -/mob/living/carbon/alien/get_default_emotes() +/mob/living/carbon/alien/get_available_emotes() . = global._alien_default_emotes diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm index cb6ed6a1b7..5fb8159b1f 100644 --- a/code/modules/mob/living/carbon/brain/emote.dm +++ b/code/modules/mob/living/carbon/brain/emote.dm @@ -13,5 +13,5 @@ var/list/_brain_default_emotes = list( /mob/living/carbon/brain/can_emote() return (istype(container, /obj/item/device/mmi) && ..()) -/mob/living/carbon/brain/get_default_emotes() +/mob/living/carbon/brain/get_available_emotes() return global._brain_default_emotes diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 73f8ae0188..1ab9df5813 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -33,7 +33,6 @@ var/list/_human_default_emotes = list( /decl/emote/audible/grunt, /decl/emote/audible/slap, /decl/emote/audible/crack, - /decl/emote/human, /decl/emote/human/deathgasp, /decl/emote/audible/giggle, /decl/emote/audible/scream, @@ -94,8 +93,10 @@ var/list/_human_default_emotes = list( /decl/emote/visible/flip ) -/mob/living/carbon/human/get_default_emotes() - return global._human_default_emotes +/mob/living/carbon/human/get_available_emotes() + . = global._human_default_emotes + if(length(species?.default_emotes)) + . |= species.default_emotes /mob/living/carbon/human/verb/pose() set name = "Set Pose" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 02758587bd..48c03d454a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1134,9 +1134,6 @@ //A slew of bits that may be affected by our species change regenerate_icons() - // Update our available emote list. - update_emotes() - if(species) if(mind) apply_traits() diff --git a/code/modules/mob/living/silicon/emote.dm b/code/modules/mob/living/silicon/emote.dm index 6aa6ae2150..220458c522 100644 --- a/code/modules/mob/living/silicon/emote.dm +++ b/code/modules/mob/living/silicon/emote.dm @@ -9,5 +9,5 @@ var/list/_silicon_default_emotes = list( /decl/emote/audible/synth/security/halt ) -/mob/living/silicon/get_default_emotes() +/mob/living/silicon/get_available_emotes() return global._silicon_default_emotes diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index e54b036a29..54b06ff35a 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -25,5 +25,5 @@ var/list/_robot_default_emotes = list( /decl/emote/audible/synth/security/halt ) -/mob/living/silicon/robot/get_default_emotes() +/mob/living/silicon/robot/get_available_emotes() return global._robot_default_emotes diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm index 242c48ca52..34068ccf39 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm @@ -56,7 +56,7 @@ var/list/_cat_default_emotes = list( update_icon() return ..() -/mob/living/simple_mob/animal/passive/cat/get_default_emotes() +/mob/living/simple_mob/animal/passive/cat/get_available_emotes() return global._cat_default_emotes /mob/living/simple_mob/animal/passive/cat/handle_special() diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm index 85a260e622..cf213ca8c2 100644 --- a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm +++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm @@ -80,7 +80,7 @@ var/list/_slime_default_emotes = list( can_enter_vent_with = list(/obj/item/clothing/head) -/mob/living/simple_mob/slime/get_default_emotes() +/mob/living/simple_mob/slime/get_available_emotes() return global._slime_default_emotes /datum/say_list/slime diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 73ad8b193c..fe6d09df70 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -41,7 +41,6 @@ living_mob_list += src lastarea = get_area(src) update_transform() // Some mobs may start bigger or smaller than normal. - update_emotes() return ..() /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index b910f697fc..3493b65acb 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -37,7 +37,6 @@ if(!R) log_error("A torso was robotize() but has no model that can be found: [model]. May affect FBPs.") owner.synthetic = R - owner.update_emotes() return FALSE /obj/item/organ/external/chest/handle_germ_effects()