From ed2a0524096586df5e8e50a92bf1f93c62fad7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Barou=C5=A1?= Date: Fri, 13 Nov 2020 19:33:44 +0100 Subject: [PATCH] Adds announcer mob and uses it for autosay instead of the full-blown AI (#10474) * Adds announcer mob and uses it for autosay instead of AI Also fixes a runtime when we can't get accent icon. * Makes it gib and dust --- aurorastation.dme | 1 + .../machinery/telecomms/telecomunications.dm | 2 + .../game/objects/items/devices/radio/radio.dm | 24 ++-- code/modules/mob/living/announcer.dm | 121 ++++++++++++++++++ code/modules/mob/living/carbon/human/say.dm | 16 ++- code/modules/mob/living/silicon/say.dm | 2 + code/modules/mob/mob_helpers.dm | 9 +- code/modules/mob/say.dm | 20 +-- html/changelogs/amunak-announcer.yml | 4 + 9 files changed, 167 insertions(+), 32 deletions(-) create mode 100755 code/modules/mob/living/announcer.dm create mode 100755 html/changelogs/amunak-announcer.yml diff --git a/aurorastation.dme b/aurorastation.dme index 9838500ebab..3885624f91a 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1898,6 +1898,7 @@ #include "code\modules\mob\language\outsider.dm" #include "code\modules\mob\language\station.dm" #include "code\modules\mob\language\synthetic.dm" +#include "code\modules\mob\living\announcer.dm" #include "code\modules\mob\living\autohiss.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\default_language.dm" diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 039561a75b7..468060cc3ce 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -544,6 +544,8 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() race = "Slime" else if(isanimal(M)) race = "Domestic Animal" + else if(istype(M, /mob/living/announcer)) + race = "Announcer" log.parameters["race"] = race diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 0164544f17e..742d772a902 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -34,6 +34,7 @@ var/global/list/default_medbay_channels = list( var/frequency = PUB_FREQ //common chat var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies var/canhear_range = 3 // the range which mobs can hear this radio from + var/mob/living/announcer/announcer = null // used in autosay, held by the radio for re-use var/datum/wires/radio/wires = null var/b_stat = 0 var/broadcasting = FALSE @@ -52,7 +53,6 @@ var/global/list/default_medbay_channels = list( var/clicksound = /decl/sound_category/button_sound //played sound on usage var/clickvol = 10 //volume - var/obj/item/cell/cell = /obj/item/cell/device var/last_radio_sound = -INFINITY @@ -66,9 +66,9 @@ var/global/list/default_medbay_channels = list( radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT) /obj/item/device/radio/Destroy() - qdel(wires) listening_objects -= src - wires = null + QDEL_NULL(announcer) + QDEL_NULL(wires) if(SSradio) SSradio.remove_object(src, frequency) for (var/ch_name in channels) @@ -268,19 +268,21 @@ var/global/list/default_medbay_channels = list( else connection = radio_connection channel = null + if (!istype(connection)) return + if (!connection) return - var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1) - A.SetName(from) - Broadcast_Message(connection, A, - 0, "*garbled automated announcement*", src, - message, from, "Automated Announcement", from, "synthesized voice", - 4, 0, list(0), connection.frequency, "states") - qdel(A) - return + if(!istype(announcer)) + announcer = new() + announcer.PrepareBroadcast(from) + Broadcast_Message(connection, announcer, + FALSE, "*garbled automated announcement*", src, + message, from, "Automated Announcement", from, announcer.voice_name, + 4, 0, list(0), connection.frequency, "states", announcer.default_language) + announcer.ResetAfterBroadcast() // Interprets the message mode when talking into a radio, possibly returning a connection datum /obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode) diff --git a/code/modules/mob/living/announcer.dm b/code/modules/mob/living/announcer.dm new file mode 100755 index 00000000000..6c09d0022ec --- /dev/null +++ b/code/modules/mob/living/announcer.dm @@ -0,0 +1,121 @@ +// This mob is a lie. Similar to /mob/abstract it's not really supposed to do much. +// It is used as a fake announcer so that we have a lightweight mob to pass to radio broadcasts. +// To use it simply instantiate it, store a reference to it - it can be reused, so no reason +// to delete it immediately. Just before a broadcast call PrepareBroadcast with desired arguments, +// then right after the broadcast call ResetAfterBroadcast so you can re-use the mob without issues next time. + +/mob/living/announcer + name = "Announcer" + voice_name = "synthesized voice" + accent = ACCENT_TTS + + icon = 'icons/mob/AI.dmi' + icon_state = "ai" + gender = NEUTER + + status_flags = GODMODE|NO_ANTAG|NOFALL + invisibility = INVISIBILITY_ABSTRACT + mob_thinks = FALSE + + universal_understand = TRUE + can_have_vision_cone = FALSE + tesla_ignore = TRUE + stop_sight_update = TRUE + density = FALSE + burn_mod = 0 + brute_mod = 0 + +/mob/living/announcer/Initialize() + // we specifically do not call parent Initialize here because this mob should not need it and its point is to be lightweight + SHOULD_CALL_PARENT(FALSE) + if(initialized) + crash_with("Warning: [src]([type]) initialized multiple times!") + initialized = TRUE + + for(var/K in all_languages) + add_language(K) + default_language = all_languages[LANGUAGE_TCB] + +/mob/living/announcer/Destroy() + // again not calling parent because it shouldn't be needed and makes this faster + SHOULD_CALL_PARENT(FALSE) + for(var/C in contents) + qdel(C) + +/mob/living/announcer/proc/PrepareBroadcast(var/name = "", var/datum/language/lang = null, var/voice_name = null, var/accent = null) + src.name = name + if(!isnull(lang)) + src.default_language = lang + if(!isnull(voice_name)) + src.voice_name = voice_name + if(!isnull(accent)) + src.accent = accent + +/mob/living/announcer/proc/ResetAfterBroadcast() + src.name = initial(name) + src.default_language = all_languages[LANGUAGE_TCB] + src.voice_name = initial(voice_name) + src.accent = initial(accent) + +/mob/living/announcer/Life() + return + +/mob/living/announcer/Move() + return + +/mob/living/announcer/zMove() + return + +/mob/living/announcer/getBruteLoss() + return 0 + +/mob/living/announcer/burn_skin() + return FALSE + +/mob/living/announcer/adjustBodyTemp() + return FALSE + +/mob/living/announcer/get_contents() + return list() + +/mob/living/announcer/check_contents_for() + return FALSE + +/mob/living/announcer/can_inject() + return FALSE + +/mob/living/announcer/seizure() + return FALSE + +/mob/living/announcer/InStasis() + return FALSE + +/mob/living/announcer/apply_radiation_effects() + return FALSE + +/mob/living/announcer/flash_eyes() + return FALSE + +/mob/living/announcer/dust() + qdel(src) + +/mob/living/announcer/gib() + qdel(src) + +/mob/living/announcer/can_fall() + return FALSE + +/mob/living/announcer/conveyor_act() + return + +/mob/living/announcer/ex_act() + return + +/mob/living/announcer/singularity_act() + return + +/mob/living/announcer/singularity_pull() + return + +/mob/living/announcer/singuloCanEat() + return FALSE diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 6578d8f7e03..4b415c3df1c 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -30,25 +30,27 @@ say(temp) winset(client, "input", "text=[null]") -/mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null) +/mob/living/carbon/human/say_understands(var/mob/other, var/datum/language/speaking = null) if(has_brain_worms()) //Brain worms translate everything. Even rat and alien speak. - return 1 + return TRUE if(species.can_understand(other)) - return 1 + return TRUE //These only pertain to common. Languages are handled by mob/say_understands() if (!speaking) if (istype(other, /mob/living/carbon/alien/diona)) if(other.languages.len >= 2) //They've sucked down some blood and can speak common now. - return 1 + return TRUE if (istype(other, /mob/living/silicon)) - return 1 + return TRUE + if (istype(other, /mob/living/announcer)) + return TRUE if (istype(other, /mob/living/carbon/brain)) - return 1 + return TRUE if (istype(other, /mob/living/carbon/slime)) - return 1 + return TRUE //This is already covered by mob/say_understands() //if (istype(other, /mob/living/simple_animal)) diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index b1867e0d63b..0b72a411335 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -74,6 +74,8 @@ return TRUE if(istype(other, /mob/living/silicon)) return TRUE + if (istype(other, /mob/living/announcer)) + return TRUE if(istype(other, /mob/living/carbon/brain)) return TRUE return ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index dfc27c2fd53..4659bc1ff32 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -1174,9 +1174,10 @@ proc/is_blind(A) var/used_accent = force_accent ? force_accent : accent if(used_accent && speaking?.allow_accents) var/datum/accent/a = SSrecords.accents[used_accent] - var/final_icon = a.tag_icon - var/datum/asset/spritesheet/S = get_asset_datum(/datum/asset/spritesheet/goonchat) - return S.icon_tag(final_icon) + if(istype(a)) + var/final_icon = a.tag_icon + var/datum/asset/spritesheet/S = get_asset_datum(/datum/asset/spritesheet/goonchat) + return S.icon_tag(final_icon) /mob/proc/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash) for(var/mob/M in contents) @@ -1185,4 +1186,4 @@ proc/is_blind(A) /mob/assign_player(var/mob/user) ckey = user.ckey - return src \ No newline at end of file + return src diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 8d82b1689fd..84a6799e34d 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -73,33 +73,33 @@ /mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null) if (src.stat == 2) //Dead - return 1 + return TRUE //Universal speak makes everything understandable, for obvious reasons. else if(src.universal_speak || src.universal_understand) - return 1 + return TRUE //Languages are handled after. if (!speaking) if(!other) - return 1 + return TRUE if(other.universal_speak) - return 1 + return TRUE if(isAI(src) && ispAI(other)) - return 1 + return TRUE if (istype(other, src.type) || istype(src, other.type)) - return 1 - return 0 + return TRUE + return FALSE if(speaking.flags & INNATE) - return 1 + return TRUE //Language check. for(var/datum/language/L in src.languages) if(speaking.name == L.name) - return 1 + return TRUE - return 0 + return FALSE /* ***Deprecated*** diff --git a/html/changelogs/amunak-announcer.yml b/html/changelogs/amunak-announcer.yml new file mode 100755 index 00000000000..68ce2429474 --- /dev/null +++ b/html/changelogs/amunak-announcer.yml @@ -0,0 +1,4 @@ +author: Amunak +delete-after: True +changes: + - tweak: "Added a new 'announcer' mob and used it instead of AI for 'autosay' as an optimization."