mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
Let's you talk through action figures, plushies, and toy mechs with .l and .r. Also a big clean up of say because its support for non-mobs was lackluster. (#81848)
This commit is contained in:
@@ -155,9 +155,9 @@
|
||||
#define ZIMPACT_NO_SPIN (1<<2)
|
||||
|
||||
/// From mob/living/try_speak(): (message, ignore_spam, forced)
|
||||
#define COMSIG_LIVING_TRY_SPEECH "living_vocal_speech"
|
||||
/// Return if the mob can speak the message, regardless of any other signal returns or checks.
|
||||
#define COMPONENT_CAN_ALWAYS_SPEAK (1<<0)
|
||||
#define COMSIG_MOB_TRY_SPEECH "living_vocal_speech"
|
||||
/// Return to skip can_speak check, IE, forcing success. Overrides below.
|
||||
#define COMPONENT_IGNORE_CAN_SPEAK (1<<0)
|
||||
/// Return if the mob cannot speak.
|
||||
#define COMPONENT_CANNOT_SPEAK (1<<1)
|
||||
|
||||
|
||||
@@ -311,9 +311,11 @@
|
||||
|
||||
// /obj/item/radio signals
|
||||
|
||||
///called from base of /obj/item/proc/talk_into(): (atom/movable/speaker, message, channel, list/spans, language, list/message_mods)
|
||||
#define COMSIG_ITEM_TALK_INTO "item_talk_into"
|
||||
///called from base of /obj/item/radio/proc/set_frequency(): (list/args)
|
||||
#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency"
|
||||
///called from base of /obj/item/radio/proc/talk_into(): (atom/movable/M, message, channel)
|
||||
///called from base of /obj/item/radio/talk_into(): (atom/movable/M, message, channel)
|
||||
#define COMSIG_RADIO_NEW_MESSAGE "radio_new_message"
|
||||
///called from base of /obj/item/radio/proc/on_receive_messgae(): (list/data)
|
||||
#define COMSIG_RADIO_RECEIVE_MESSAGE "radio_receive_message"
|
||||
|
||||
@@ -55,11 +55,14 @@
|
||||
|
||||
#define MODE_MAFIA "mafia"
|
||||
|
||||
/// Applies singing characters to the message
|
||||
#define MODE_SING "sing"
|
||||
|
||||
/// A custom say emote is being supplied [value = the emote]
|
||||
#define MODE_CUSTOM_SAY_EMOTE "custom_say"
|
||||
|
||||
/// No message is following, just emote
|
||||
#define MODE_CUSTOM_SAY_ERASE_INPUT "erase_input"
|
||||
/// Message is being relayed through another object
|
||||
#define MODE_RELAY "relayed"
|
||||
|
||||
//Spans. Robot speech, italics, etc. Applied in compose_message().
|
||||
#define SPAN_ROBOT "robot"
|
||||
@@ -75,8 +78,11 @@
|
||||
#define SPAN_HELIUM "small"
|
||||
|
||||
//bitflag #defines for return value of the radio() proc.
|
||||
/// Makes the message use italics
|
||||
#define ITALICS (1<<0)
|
||||
/// Reduces the range of the message to 1
|
||||
#define REDUCE_RANGE (1<<1)
|
||||
/// Stops any actual message from being sent
|
||||
#define NOPASS (1<<2)
|
||||
|
||||
/// Range to hear normal messages
|
||||
|
||||
@@ -171,7 +171,8 @@
|
||||
to_chat(src, span_notice("As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality."))
|
||||
to_chat(src, span_warning("<b>Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.</b>"))
|
||||
|
||||
/mob/living/split_personality/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/living/split_personality/try_speak(message, ignore_spam, forced, filterproof)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
to_chat(src, span_warning("You cannot speak, your other self is controlling your body!"))
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, PROC_REF(on_burned))
|
||||
RegisterSignal(parent, COMSIG_ATOM_TRIED_PASS, PROC_REF(on_attempted_pass))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_SPACEMOVE, PROC_REF(on_space_move))
|
||||
RegisterSignal(parent, COMSIG_LIVING_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(parent, COMSIG_MOB_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(parent, COMSIG_MOB_CHANGED_TYPE, PROC_REF(on_transformed))
|
||||
living_parent.update_appearance(UPDATE_ICON)
|
||||
GLOB.blob_telepathy_mobs |= parent
|
||||
@@ -73,7 +73,7 @@
|
||||
COMSIG_ATOM_FIRE_ACT,
|
||||
COMSIG_ATOM_TRIED_PASS,
|
||||
COMSIG_ATOM_UPDATE_ICON,
|
||||
COMSIG_LIVING_TRY_SPEECH,
|
||||
COMSIG_MOB_TRY_SPEECH,
|
||||
COMSIG_MOB_CHANGED_TYPE,
|
||||
COMSIG_MOB_GET_STATUS_TAB_ITEMS,
|
||||
COMSIG_MOB_MIND_INITIALIZED,
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_MOB_SPELL_PROJECTILE, PROC_REF(on_spell_projectile))
|
||||
RegisterSignal(parent, COMSIG_MOB_PRE_INVOCATION, PROC_REF(on_pre_invocation))
|
||||
RegisterSignal(parent, COMSIG_LIVING_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(parent, COMSIG_MOB_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(parent, COMSIG_MOB_AFTER_SPELL_CAST, PROC_REF(on_after_spell_cast))
|
||||
|
||||
/datum/component/chuunibyou/UnregisterFromParent()
|
||||
@@ -53,7 +53,7 @@
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_MOB_SPELL_PROJECTILE,
|
||||
COMSIG_MOB_PRE_INVOCATION,
|
||||
COMSIG_LIVING_TRY_SPEECH,
|
||||
COMSIG_MOB_TRY_SPEECH,
|
||||
COMSIG_MOB_AFTER_SPELL_CAST,
|
||||
))
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(casting_spell)
|
||||
return COMPONENT_CAN_ALWAYS_SPEAK
|
||||
return COMPONENT_IGNORE_CAN_SPEAK
|
||||
|
||||
///signal sent when the parent casts a spell that has a projectile
|
||||
/datum/component/chuunibyou/proc/on_spell_projectile(mob/living/source, datum/action/cooldown/spell/spell, atom/cast_on, obj/projectile/to_fire)
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
language = language,
|
||||
forced = "[source]'s marionette",
|
||||
saymode = saymode,
|
||||
message_mods = list(MODE_RELAY = TRUE),
|
||||
)
|
||||
speech_args[SPEECH_RANGE] = WHISPER_RANGE
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
carbon_parent.verb_yell = "emphatically signs"
|
||||
carbon_parent.bubble_icon = "signlang"
|
||||
RegisterSignal(carbon_parent, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_added_organ))
|
||||
RegisterSignal(carbon_parent, COMSIG_LIVING_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(carbon_parent, COMSIG_MOB_TRY_SPEECH, PROC_REF(on_try_speech))
|
||||
RegisterSignal(carbon_parent, COMSIG_LIVING_TREAT_MESSAGE, PROC_REF(on_treat_living_message))
|
||||
RegisterSignal(carbon_parent, COMSIG_MOVABLE_USING_RADIO, PROC_REF(on_using_radio))
|
||||
RegisterSignal(carbon_parent, COMSIG_MOVABLE_SAY_QUOTE, PROC_REF(on_say_quote))
|
||||
@@ -106,7 +106,7 @@
|
||||
carbon_parent.bubble_icon = initial(carbon_parent.bubble_icon)
|
||||
UnregisterSignal(carbon_parent, list(
|
||||
COMSIG_CARBON_GAIN_ORGAN,
|
||||
COMSIG_LIVING_TRY_SPEECH,
|
||||
COMSIG_MOB_TRY_SPEECH,
|
||||
COMSIG_LIVING_TREAT_MESSAGE,
|
||||
COMSIG_MOVABLE_USING_RADIO,
|
||||
COMSIG_MOVABLE_SAY_QUOTE,
|
||||
@@ -125,7 +125,7 @@
|
||||
var/obj/item/organ/internal/tongue/new_tongue = new_organ
|
||||
new_tongue.temp_say_mod = "signs"
|
||||
|
||||
/// Signal proc for [COMSIG_LIVING_TRY_SPEECH]
|
||||
/// Signal proc for [COMSIG_MOB_TRY_SPEECH]
|
||||
/// Sign languagers can always speak regardless of they're mute (as long as they're not mimes)
|
||||
/datum/component/sign_language/proc/on_try_speech(mob/living/source, message, ignore_spam, forced)
|
||||
SIGNAL_HANDLER
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
// Assuming none of the above fail, sign language users can speak
|
||||
// regardless of being muzzled or mute toxin'd or whatever.
|
||||
return COMPONENT_CAN_ALWAYS_SPEAK
|
||||
return COMPONENT_IGNORE_CAN_SPEAK
|
||||
|
||||
/// Checks to see what state this person is in and if they are able to sign or not.
|
||||
/datum/component/sign_language/proc/check_signables_state()
|
||||
|
||||
28
code/datums/elements/toy_talk.dm
Normal file
28
code/datums/elements/toy_talk.dm
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Allows people to talk via the item with .l or .r
|
||||
*
|
||||
* Be sure to override [/atom/movable/proc/GetVoice] if you want the item's "voice" to not default to itself
|
||||
*/
|
||||
/datum/element/toy_talk
|
||||
|
||||
/datum/element/toy_talk/Attach(datum/target)
|
||||
. = ..()
|
||||
if(!isitem(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
RegisterSignal(target, COMSIG_ITEM_TALK_INTO, PROC_REF(do_talk))
|
||||
|
||||
/datum/element/toy_talk/Detach(datum/source, ...)
|
||||
. = ..()
|
||||
UnregisterSignal(source, COMSIG_ITEM_TALK_INTO)
|
||||
|
||||
/datum/element/toy_talk/proc/do_talk(obj/item/source, mob/speaker, message, channel, list/spans, language, list/message_mods)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!ismob(speaker) || message_mods[MODE_HEADSET] || message_mods[MODE_RELAY])
|
||||
return NONE
|
||||
|
||||
message_mods[MODE_RELAY] = TRUE // Redundant (given NOPASS) but covers our bases
|
||||
speaker.log_talk(message, LOG_SAY, tag = "toy talk ([source])")
|
||||
source.say(message, language = language, sanitize = FALSE, message_mods = list(MODE_RELAY = TRUE))
|
||||
return NOPASS
|
||||
@@ -606,8 +606,23 @@
|
||||
playsound(src, block_sound, BLOCK_SOUND_VOLUME, vary = TRUE)
|
||||
return TRUE
|
||||
|
||||
/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language, list/message_mods)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
/**
|
||||
* Handles someone talking INTO an item
|
||||
*
|
||||
* Commonly used by someone holding it and using .r or .l
|
||||
* Also used by radios
|
||||
*
|
||||
* * speaker - the atom that is doing the talking
|
||||
* * message - the message being spoken
|
||||
* * channel - the channel the message is being spoken on, only really used for radios
|
||||
* * spans - the spans of the message
|
||||
* * language - the language the message is in
|
||||
* * message_mods - any message mods that should be applied to the message
|
||||
*
|
||||
* Return a flag that modifies the original message
|
||||
*/
|
||||
/obj/item/proc/talk_into(atom/movable/speaker, message, channel, list/spans, datum/language/language, list/message_mods)
|
||||
return SEND_SIGNAL(src, COMSIG_ITEM_TALK_INTO, speaker, message, channel, spans, language, message_mods) || (ITALICS|REDUCE_RANGE)
|
||||
|
||||
/// Called when a mob drops an item.
|
||||
/obj/item/proc/dropped(mob/user, silent = FALSE)
|
||||
|
||||
@@ -262,17 +262,29 @@
|
||||
|
||||
/obj/item/radio/talk_into(atom/movable/talking_movable, message, channel, list/spans, datum/language/language, list/message_mods)
|
||||
if(SEND_SIGNAL(talking_movable, COMSIG_MOVABLE_USING_RADIO, src) & COMPONENT_CANNOT_USE_RADIO)
|
||||
return
|
||||
return NONE
|
||||
if(SEND_SIGNAL(src, COMSIG_RADIO_NEW_MESSAGE, talking_movable, message, channel) & COMPONENT_CANNOT_USE_RADIO)
|
||||
return
|
||||
return NONE
|
||||
|
||||
if(!spans)
|
||||
spans = list(talking_movable.speech_span)
|
||||
if(!language)
|
||||
language = talking_movable.get_selected_language()
|
||||
INVOKE_ASYNC(src, PROC_REF(talk_into_impl), talking_movable, message, channel, spans.Copy(), language, message_mods)
|
||||
INVOKE_ASYNC(src, PROC_REF(talk_into_impl), talking_movable, message, channel, LAZYLISTDUPLICATE(spans), language, LAZYLISTDUPLICATE(message_mods))
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/**
|
||||
* Handles talking into the radio
|
||||
*
|
||||
* Unlike most speech related procs, spans and message_mods are not guaranteed to be lists
|
||||
*
|
||||
* * talking_movable - the atom that is talking
|
||||
* * message - the message to be spoken
|
||||
* * channel - the channel to be spoken on
|
||||
* * spans - the spans to be used, lazylist
|
||||
* * language - the language to be spoken in. (Should) never be null
|
||||
* * message_mods - the message mods to be used, lazylist
|
||||
*/
|
||||
/obj/item/radio/proc/talk_into_impl(atom/movable/talking_movable, message, channel, list/spans, datum/language/language, list/message_mods)
|
||||
if(!on)
|
||||
return // the device has to be on
|
||||
@@ -358,9 +370,9 @@
|
||||
|
||||
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range)
|
||||
. = ..()
|
||||
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range)
|
||||
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range || message_mods[MODE_RELAY])
|
||||
return
|
||||
var/filtered_mods = list()
|
||||
var/list/filtered_mods = list()
|
||||
|
||||
if (message_mods[MODE_SING])
|
||||
filtered_mods[MODE_SING] = message_mods[MODE_SING]
|
||||
|
||||
@@ -159,6 +159,9 @@
|
||||
|
||||
/obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list(), message_range)
|
||||
. = ..()
|
||||
if(message_mods[MODE_RELAY])
|
||||
return
|
||||
|
||||
if(mytape && recording)
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss")]\] [raw_message]"
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, squeak_override)
|
||||
AddElement(/datum/element/bed_tuckable, mapload, 6, -5, 90)
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
//have we decided if Pinocchio goes in the blue or pink aisle yet?
|
||||
if(gender == NEUTER)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
/obj/item/toy/mecha/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/series, /obj/item/toy/mecha, "Mini-Mecha action figures")
|
||||
AddElement(/datum/element/toy_talk)
|
||||
combat_health = max_combat_health
|
||||
switch(special_attack_type)
|
||||
if(SPECIAL_ATTACK_DAMAGE)
|
||||
@@ -263,12 +264,8 @@
|
||||
if(wins || losses)
|
||||
. += span_notice("This toy has [wins] wins, and [losses] losses.")
|
||||
|
||||
/**
|
||||
* Override the say proc if they're mute
|
||||
*/
|
||||
/obj/item/toy/mecha/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
if(!quiet)
|
||||
. = ..()
|
||||
/obj/item/toy/mecha/can_speak(allow_mimes)
|
||||
return !quiet && ..()
|
||||
|
||||
/**
|
||||
* The 'master' proc of the mech battle. Processes the entire battle's events and makes sure it start and finishes correctly.
|
||||
|
||||
@@ -1013,6 +1013,7 @@
|
||||
/obj/item/toy/figure/Initialize(mapload)
|
||||
. = ..()
|
||||
desc = "A \"Space Life\" brand [src]."
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
/obj/item/toy/figure/attack_self(mob/user as mob)
|
||||
if(cooldown <= world.time)
|
||||
@@ -1245,13 +1246,9 @@
|
||||
to_chat(user, span_notice("You name the dummy as \"[doll_name]\"."))
|
||||
name = "[initial(name)] - [doll_name]"
|
||||
|
||||
/obj/item/toy/dummy/talk_into(atom/movable/A, message, channel, list/spans, datum/language/language, list/message_mods)
|
||||
var/mob/M = A
|
||||
if (istype(M))
|
||||
M.log_talk(message, LOG_SAY, tag="dummy toy")
|
||||
|
||||
say(message, language, sanitize = FALSE)
|
||||
return NOPASS
|
||||
/obj/item/toy/dummy/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
/obj/item/toy/dummy/GetVoice()
|
||||
return doll_name
|
||||
|
||||
@@ -21,7 +21,36 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
"[FREQ_CTF_YELLOW]" = "yellowteamradio"
|
||||
))
|
||||
|
||||
/atom/movable/proc/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = FALSE, message_range = 7, datum/saymode/saymode = null)
|
||||
/**
|
||||
* What makes things... talk.
|
||||
*
|
||||
* * message - The message to say.
|
||||
* * bubble_type - The type of speech bubble to use when talking
|
||||
* * spans - A list of spans to attach to the message. Includes the atom's speech span by default
|
||||
* * sanitize - Should we sanitize the message? Only set to FALSE if you have ALREADY sanitized it
|
||||
* * language - The language to speak in. Defaults to the atom's selected language
|
||||
* * ignore_spam - Should we ignore spam checks?
|
||||
* * forced - What was it forced by? null if voluntary. (NOT a boolean!)
|
||||
* * filterproof - Do we bypass the filter when checking the message?
|
||||
* * message_range - The range of the message. Defaults to 7
|
||||
* * saymode - Saymode passed to the speech
|
||||
* This is usually set automatically and is only relevant for living mobs.
|
||||
* * message_mods - A list of message modifiers, i.e. whispering/singing.
|
||||
* Most of these are set automatically but you can pass in your own pre-say.
|
||||
*/
|
||||
/atom/movable/proc/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(!try_speak(message, ignore_spam, forced, filterproof))
|
||||
return
|
||||
if(sanitize)
|
||||
@@ -31,7 +60,6 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
spans |= speech_span
|
||||
if(!language)
|
||||
language = get_selected_language()
|
||||
var/list/message_mods = list()
|
||||
message_mods[SAY_MOD_VERB] = say_mod(message, message_mods)
|
||||
send_speech(message, message_range, src, bubble_type, spans, language, message_mods, forced = forced)
|
||||
|
||||
@@ -60,7 +88,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
* TRUE of FASE depending on if our movable can speak
|
||||
*/
|
||||
/atom/movable/proc/try_speak(message, ignore_spam = FALSE, forced = null, filterproof = FALSE)
|
||||
return TRUE
|
||||
return can_speak()
|
||||
|
||||
/**
|
||||
* Checks if our movable can currently speak, vocally, in general.
|
||||
@@ -77,7 +105,8 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
* if TRUE, we will check if the movable can speak REGARDLESS of if they have an active mime vow.
|
||||
*/
|
||||
/atom/movable/proc/can_speak(allow_mimes = FALSE)
|
||||
return TRUE
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return !HAS_TRAIT(src, TRAIT_MUTE)
|
||||
|
||||
/atom/movable/proc/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans, datum/language/message_language, list/message_mods = list(), forced = FALSE, tts_message, list/tts_filter)
|
||||
var/found_client = FALSE
|
||||
@@ -174,7 +203,15 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
/atom/movable/proc/get_default_say_verb()
|
||||
return verb_say
|
||||
|
||||
/atom/movable/proc/say_quote(input, list/spans=list(speech_span), list/message_mods = list())
|
||||
/**
|
||||
* This prock is used to generate a message for chat
|
||||
* Generates the `says, "<span class='red'>meme</span>"` part of the `Grey Tider says, "meme"`.
|
||||
*
|
||||
* input - The message to be said
|
||||
* spans - A list of spans to attach to the message. Includes the atom's speech span by default
|
||||
* message_mods - A list of message modifiers, i.e. whispering/singing
|
||||
*/
|
||||
/atom/movable/proc/say_quote(input, list/spans = list(speech_span), list/message_mods = list())
|
||||
if(!input)
|
||||
input = "..."
|
||||
|
||||
|
||||
@@ -286,7 +286,19 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
blob_points = clamp(blob_points + points, 0, max_blob_points)
|
||||
hud_used.blobpwrdisplay.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_points)]</font></div>")
|
||||
|
||||
/mob/camera/blob/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/camera/blob/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if (!message)
|
||||
return
|
||||
|
||||
|
||||
@@ -113,7 +113,19 @@ the new instance inside the host to be updated to the template's stats.
|
||||
for(var/datum/disease_ability/ability in purchased_abilities)
|
||||
. += span_notice("[ability.name]")
|
||||
|
||||
/mob/camera/disease/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/camera/disease/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(!message)
|
||||
return
|
||||
if(sanitize)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/obj/item/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range)
|
||||
. = ..()
|
||||
if(message_mods[WHISPER_MODE]) //Too quiet lad
|
||||
if(message_mods[WHISPER_MODE] || message_mods[MODE_RELAY]) //Too quiet lad
|
||||
return FALSE
|
||||
if(speaker == src)
|
||||
return FALSE
|
||||
|
||||
@@ -9,7 +9,19 @@
|
||||
mods[RADIO_EXTENSION] = GLOB.department_radio_keys[mods[RADIO_KEY]]
|
||||
return message
|
||||
|
||||
/mob/dead/observer/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/dead/observer/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
message = trim(message) //trim now and sanitize after checking for special admin radio keys
|
||||
|
||||
var/list/filter_result = CAN_BYPASS_FILTER(src) ? null : is_ooc_filtered(message)
|
||||
@@ -27,7 +39,6 @@
|
||||
|
||||
if(!message)
|
||||
return
|
||||
var/list/message_mods = list()
|
||||
message = get_message_mods(message, message_mods)
|
||||
if(client?.holder && (message_mods[RADIO_EXTENSION] == MODE_ADMIN || message_mods[RADIO_EXTENSION] == MODE_DEADMIN || (message_mods[RADIO_EXTENSION] == MODE_PUPPET && mind?.current)))
|
||||
message = trim_left(copytext_char(message, length(message_mods[RADIO_KEY]) + 2))
|
||||
|
||||
@@ -47,12 +47,11 @@
|
||||
/mob/living/basic/migo/proc/update_dodge_chance(health_ratio)
|
||||
dodge_prob = LERP(50, 10, health_ratio)
|
||||
|
||||
/mob/living/basic/migo/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
..()
|
||||
if(stat)
|
||||
/mob/living/basic/migo/send_speech(message_raw, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter)
|
||||
. = ..()
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
var/chosen_sound = pick(migo_sounds)
|
||||
playsound(src, chosen_sound, 50, TRUE)
|
||||
playsound(src, pick(migo_sounds), 50, TRUE)
|
||||
|
||||
/mob/living/basic/migo/Life(seconds_per_tick = SSMOBS_DT, times_fired)
|
||||
..()
|
||||
|
||||
@@ -168,7 +168,19 @@
|
||||
essencecolor = "#1D2953" //oh jeez you're dying
|
||||
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[essencecolor]'>[essence]E</font></div>")
|
||||
|
||||
/mob/living/basic/revenant/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/living/basic/revenant/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
/mob/living/basic/statue/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_UNOBSERVANT, INNATE_TRAIT)
|
||||
add_traits(list(TRAIT_MUTE, TRAIT_UNOBSERVANT), INNATE_TRAIT)
|
||||
AddComponent(/datum/component/unobserved_actor, unobserved_flags = NO_OBSERVED_MOVEMENT | NO_OBSERVED_ATTACKS)
|
||||
|
||||
var/static/list/innate_actions = list(
|
||||
@@ -69,14 +69,8 @@
|
||||
/mob/living/basic/statue/med_hud_set_status()
|
||||
return //we're a statue we're invincible
|
||||
|
||||
/mob/living/basic/statue/can_speak(allow_mimes = FALSE)
|
||||
return FALSE // We're a statue, of course we can't talk.
|
||||
|
||||
// Cannot talk
|
||||
|
||||
/mob/living/basic/statue/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
return
|
||||
|
||||
// Turn to dust when gibbed
|
||||
|
||||
/mob/living/basic/statue/gib()
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
/mob/living/brain/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterpoof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
if(!(container && istype(container, /obj/item/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
if(prob(emp_damage*4))
|
||||
if(prob(10))//10% chane to drop the message entirely
|
||||
return
|
||||
else
|
||||
message = Gibberish(message, emp_damage >= 12)//scrambles the message, gets worse when emp_damage is higher
|
||||
/mob/living/brain/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(prob(emp_damage * 4))
|
||||
if(prob(10)) //10% chance to drop the message entirely
|
||||
return
|
||||
message = Gibberish(message, emp_damage >= 12)//scrambles the message, gets worse when emp_damage is higher
|
||||
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/can_speak(allow_mimes)
|
||||
return istype(container, /obj/item/mmi) && ..()
|
||||
|
||||
/mob/living/brain/radio(message, list/message_mods = list(), list/spans, language)
|
||||
if(message_mods[MODE_HEADSET] && istype(container, /obj/item/mmi))
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/say(message, bubble_type, list/spans, sanitize, datum/language/language, ignore_spam, forced, filterproof, message_range, datum/saymode/saymode)
|
||||
/mob/living/carbon/human/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(!HAS_TRAIT(src, TRAIT_SPEAKS_CLEARLY))
|
||||
var/static/regex/tongueless_lower = new("\[gdntke]+", "g")
|
||||
var/static/regex/tongueless_upper = new("\[GDNTKE]+", "g")
|
||||
|
||||
@@ -94,13 +94,24 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
|
||||
return new_msg
|
||||
|
||||
/mob/living/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/living/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(sanitize)
|
||||
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
if(!message || message == "")
|
||||
return
|
||||
|
||||
var/list/message_mods = list()
|
||||
var/original_message = message
|
||||
message = get_message_mods(message, message_mods)
|
||||
saymode = SSradio.saymodes[message_mods[RADIO_KEY]]
|
||||
@@ -206,7 +217,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
message = "[randomnote] [message] [randomnote]"
|
||||
spans |= SPAN_SINGING
|
||||
|
||||
if(LAZYACCESS(message_mods,WHISPER_MODE)) // whisper away
|
||||
if(message_mods[WHISPER_MODE]) // whisper away
|
||||
spans |= SPAN_ITALICS
|
||||
|
||||
if(!message)
|
||||
@@ -222,6 +233,9 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
return
|
||||
|
||||
var/radio_return = radio(message, message_mods, spans, language)//roughly 27% of living/say()'s total cost
|
||||
if(radio_return & NOPASS)
|
||||
return TRUE
|
||||
|
||||
if(radio_return & ITALICS)
|
||||
spans |= SPAN_ITALICS
|
||||
if(radio_return & REDUCE_RANGE)
|
||||
@@ -229,8 +243,6 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
if(!message_mods[WHISPER_MODE])
|
||||
message_mods[WHISPER_MODE] = MODE_WHISPER
|
||||
message_mods[SAY_MOD_VERB] = say_mod(message, message_mods)
|
||||
if(radio_return & NOPASS)
|
||||
return TRUE
|
||||
|
||||
//No screams in space, unless you're next to someone.
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -426,38 +438,6 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
/mob/proc/binarycheck()
|
||||
return FALSE
|
||||
|
||||
/mob/living/try_speak(message, ignore_spam = FALSE, forced = null, filterproof = FALSE)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/sigreturn = SEND_SIGNAL(src, COMSIG_LIVING_TRY_SPEECH, message, ignore_spam, forced)
|
||||
if(sigreturn & COMPONENT_CAN_ALWAYS_SPEAK)
|
||||
return TRUE
|
||||
|
||||
if(sigreturn & COMPONENT_CANNOT_SPEAK)
|
||||
return FALSE
|
||||
|
||||
if(!can_speak())
|
||||
if(HAS_MIND_TRAIT(src, TRAIT_MIMING))
|
||||
to_chat(src, span_green("Your vow of silence prevents you from speaking!"))
|
||||
else
|
||||
to_chat(src, span_warning("You find yourself unable to speak!"))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/can_speak(allow_mimes = FALSE)
|
||||
if(!allow_mimes && HAS_MIND_TRAIT(src, TRAIT_MIMING))
|
||||
return FALSE
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE))
|
||||
return FALSE
|
||||
|
||||
if(is_muzzled())
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/**
|
||||
* Treats the passed message with things that may modify speech (stuttering, slurring etc).
|
||||
*
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
/mob/living/silicon/ai/say(message, bubble_type,list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
if(parent && istype(parent) && parent.stat != DEAD) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
/mob/living/silicon/ai/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if(istype(parent) && parent.stat != DEAD) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
return parent.say(arglist(args))
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -56,11 +56,8 @@
|
||||
M.take_damage(50, BRUTE, MELEE, 1)
|
||||
|
||||
//Elites can't talk (normally)!
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
if(can_talk)
|
||||
. = ..()
|
||||
return TRUE
|
||||
return FALSE
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/can_speak(allow_mimes)
|
||||
return can_talk && ..()
|
||||
|
||||
/*Basic setup for elite attacks, based on Whoneedspace's megafauna attack setup.
|
||||
While using this makes the system rely on OnFire, it still gives options for timers not tied to OnFire, and it makes using attacks consistent accross the board for player-controlled elites.*/
|
||||
|
||||
@@ -63,9 +63,11 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/herald/proc/become_ghost()
|
||||
icon_state = "herald_ghost"
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/herald/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/herald/send_speech(message_raw, message_range, obj/source, bubble_type, list/spans, datum/language/message_language, list/message_mods, forced, tts_message, list/tts_filter)
|
||||
. = ..()
|
||||
playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE)
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE)
|
||||
|
||||
/datum/action/innate/elite_attack/herald_trishot
|
||||
name = "Triple Shot"
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
QUEUE_OR_CALL_VERB_FOR(VERB_CALLBACK(src, TYPE_PROC_REF(/mob, emote), "me", 1, message, TRUE), SSspeech_controller)
|
||||
|
||||
/mob/try_speak(message, ignore_spam = FALSE, forced = null, filterproof = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/list/filter_result
|
||||
var/list/soft_filter_result
|
||||
if(client && !forced && !filterproof)
|
||||
@@ -88,9 +85,31 @@
|
||||
return FALSE
|
||||
if(client.handle_spam_prevention(message, MUTE_IC))
|
||||
return FALSE
|
||||
// Including can_speak() here would ignore COMPONENT_CAN_ALWAYS_SPEAK in /mob/living/try_speak()
|
||||
|
||||
var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_TRY_SPEECH, message, ignore_spam, forced)
|
||||
if(sigreturn & COMPONENT_IGNORE_CAN_SPEAK)
|
||||
return TRUE
|
||||
if(sigreturn & COMPONENT_CANNOT_SPEAK)
|
||||
return FALSE
|
||||
|
||||
if(!..()) // the can_speak check
|
||||
if(HAS_MIND_TRAIT(src, TRAIT_MIMING))
|
||||
to_chat(src, span_green("Your vow of silence prevents you from speaking!"))
|
||||
else
|
||||
to_chat(src, span_warning("You find yourself unable to speak!"))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/can_speak(allow_mimes = FALSE)
|
||||
if(!allow_mimes && HAS_MIND_TRAIT(src, TRAIT_MIMING))
|
||||
return FALSE
|
||||
|
||||
if(is_muzzled())
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
///Speak as a dead person (ghost etc)
|
||||
/mob/proc/say_dead(message)
|
||||
var/name = real_name
|
||||
|
||||
@@ -194,13 +194,9 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/item/bodypart/head/talk_into(mob/holder, message, channel, spans, datum/language/language, list/message_mods)
|
||||
var/mob/headholder = holder
|
||||
if(istype(headholder))
|
||||
headholder.log_talk(message, LOG_SAY, tag = "beheaded talk")
|
||||
|
||||
say(message, language, sanitize = FALSE)
|
||||
return NOPASS
|
||||
/obj/item/bodypart/head/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/toy_talk)
|
||||
|
||||
/obj/item/bodypart/head/GetVoice()
|
||||
return "The head of [real_name]"
|
||||
|
||||
@@ -289,8 +289,8 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
|
||||
GLOB.vending_machines_to_restock -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/vending/can_speak()
|
||||
return !shut_up
|
||||
/obj/machinery/vending/can_speak(allow_mimes)
|
||||
return is_operational && !shut_up && ..()
|
||||
|
||||
/obj/machinery/vending/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
@@ -20,16 +20,29 @@
|
||||
new /obj/item/circuit_component/bci_core,
|
||||
), SHELL_CAPACITY_SMALL, starting_circuit = circuit)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/bci/say(message, bubble_type, list/spans, sanitize, datum/language/language, ignore_spam, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
||||
/obj/item/organ/internal/cyberimp/bci/say(
|
||||
message,
|
||||
bubble_type,
|
||||
list/spans = list(),
|
||||
sanitize = TRUE,
|
||||
datum/language/language,
|
||||
ignore_spam = FALSE,
|
||||
forced,
|
||||
filterproof = FALSE,
|
||||
message_range = 7,
|
||||
datum/saymode/saymode,
|
||||
list/message_mods = list(),
|
||||
)
|
||||
if (owner)
|
||||
// Otherwise say_dead will be called.
|
||||
// It's intentional that a circuit for a dead person does not speak from the shell.
|
||||
if (owner.stat == DEAD)
|
||||
return
|
||||
|
||||
owner.say(message, forced = "circuit speech")
|
||||
else
|
||||
return ..()
|
||||
forced = "circuit speech"
|
||||
return owner.say(arglist(args))
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/bci/proc/action_comp_registered(datum/source, obj/item/circuit_component/equipment_action/action_comp)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -1479,6 +1479,7 @@
|
||||
#include "code\datums\elements\tenacious.dm"
|
||||
#include "code\datums\elements\tiny_mob_hunter.dm"
|
||||
#include "code\datums\elements\tool_flash.dm"
|
||||
#include "code\datums\elements\toy_talk.dm"
|
||||
#include "code\datums\elements\turf_transparency.dm"
|
||||
#include "code\datums\elements\undertile.dm"
|
||||
#include "code\datums\elements\unfriend_attacker.dm"
|
||||
|
||||
Reference in New Issue
Block a user