Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] 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. #2312

Merged
merged 1 commit into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 3 additions & 1 deletion code/__DEFINES/dcs/signals/signals_object.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
10 changes: 8 additions & 2 deletions code/__DEFINES/say.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,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"
Expand All @@ -79,8 +82,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
Expand Down
3 changes: 2 additions & 1 deletion code/datums/brain_damage/split_personality.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions code/datums/components/blob_minion.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions code/datums/components/chuunibyou.dm
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
. = ..()
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()
. = ..()
UnregisterSignal(parent, list(
COMSIG_MOB_SPELL_PROJECTILE,
COMSIG_MOB_PRE_INVOCATION,
COMSIG_LIVING_TRY_SPEECH,
COMSIG_MOB_TRY_SPEECH,
COMSIG_MOB_AFTER_SPELL_CAST,
))

Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions code/datums/components/marionette.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
language = language,
forced = "[source]'s marionette",
saymode = saymode,
message_mods = list(MODE_RELAY = TRUE),
)
speech_args[SPEECH_RANGE] = WHISPER_RANGE

Expand Down
8 changes: 4 additions & 4 deletions code/datums/components/sign_language.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down
28 changes: 28 additions & 0 deletions code/datums/elements/toy_talk.dm
Original file line number Diff line number Diff line change
@@ -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
19 changes: 17 additions & 2 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,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)
Expand Down
22 changes: 17 additions & 5 deletions code/game/objects/items/devices/radio/radio.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
3 changes: 3 additions & 0 deletions code/game/objects/items/devices/taperecorder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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]"
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/items/plushes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 3 additions & 6 deletions code/game/objects/items/toy_mechs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 4 additions & 7 deletions code/game/objects/items/toys.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading