Files
Bubberstation/code/datums/components/speechmod.dm
Andrew 6fbc9a2297 More food effects (#84889)
## About The Pull Request

In #77887 I have introduced a food buff system with placeholder buffs to
not bloat that PR with balance-related things to allow people to add
their own effects and discuss the particular effects in separate PRs.

The goal is to have:

- Some default buffs for all food. Currently there's only Haste that
scales with food complexity.
- Some interesting buffs tied to food categories or specific dishes

This PR is a first part of this change.

- Adding an indicator to Cooking UI that food does something special
- Added **Spaghetti Carbonara** dish that gives Italian speech.

![image](https://github.com/user-attachments/assets/2035a97a-6048-4636-bd49-d1ea3390a50e)

- Added **Jupiter Cup Cake** that gives shock immunity instead of it
being randomly given by high-complexity dishes.

![image](https://github.com/user-attachments/assets/3260339d-0167-4840-9b76-10371959e16c)

- Made **Omelette Du Fromage** give French speech.
- Made **Mime Tart** give Mute trait
- Made **Clown Cake** give Waddle Walk trait
- Made **Stuffed Legion** give Ashstorm Immune trait

## Why It's Good For The Game

Foodening PR was incomplete, this PR is a step towards the completion.

## TODO

- [X] Pick a certain dish to give the French speech
- [X] Pick a certain pasta to give the Italian speech
- [X] Pick a certain dish for the shock immunity buff
- [x] Add an indicator to the cooking UI that a dish has a special
effect
- [x] Add more food effects per suggestions

## Changelog

🆑
qol: Dishes with a special food effect are marked in the Cooking UI
add: New Spaghetti Carbonara dish that makes people Italian temporarily
add: Omelette Du Fromage makes people French temporarily
add: Shock Immunity is no longer a random level 4-5 food buff, but a
buff given by a new Jupiter-Cup-Cake
add: Mime Tart gives Mute trait
add: Clown Cake gives Waddle Walk trait
add: Stuffed Legion gives Ashstorm Immune trait
/🆑
2024-08-14 13:10:21 +02:00

141 lines
4.3 KiB
Plaintext

/// Used to apply certain speech patterns
/// Can be used on organs, wearables, mutations and mobs
/datum/component/speechmod
/// Assoc list for strings/regexes and their replacements. Should be lowercase, as case will be automatically changed
var/list/replacements = list()
/// String added to the end of the message
var/end_string = ""
/// Chance for the end string to be applied
var/end_string_chance = 100
/// Current target for modification
var/mob/targeted
/// Slot tags in which this item works when equipped
var/slots
/// If set to true, turns all text to uppercase
var/uppercase = FALSE
/// Any additional checks that we should do before applying the speech modification
var/datum/callback/should_modify_speech = null
/datum/component/speechmod/Initialize(replacements = list(), end_string = "", end_string_chance = 100, slots, uppercase = FALSE, should_modify_speech)
if (!ismob(parent) && !isitem(parent) && !istype(parent, /datum/mutation/human))
return COMPONENT_INCOMPATIBLE
src.replacements = replacements
src.end_string = end_string
src.end_string_chance = end_string_chance
src.slots = slots
src.uppercase = uppercase
src.should_modify_speech = should_modify_speech
if (istype(parent, /datum/mutation/human))
RegisterSignal(parent, COMSIG_MUTATION_GAINED, PROC_REF(on_mutation_gained))
RegisterSignal(parent, COMSIG_MUTATION_LOST, PROC_REF(on_mutation_lost))
return
var/atom/owner = parent
if (istype(parent, /datum/status_effect))
var/datum/status_effect/effect = parent
targeted = effect.owner
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
return
if (ismob(parent))
targeted = parent
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
return
if (ismob(owner.loc))
targeted = owner.loc
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_unequipped))
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_implanted))
RegisterSignal(parent, COMSIG_ORGAN_REMOVED, PROC_REF(on_removed))
/datum/component/speechmod/proc/handle_speech(datum/source, list/speech_args)
SIGNAL_HANDLER
var/message = speech_args[SPEECH_MESSAGE]
if(message[1] == "*")
return
if(!isnull(should_modify_speech) && !should_modify_speech.Invoke(source, speech_args))
return
for (var/to_replace in replacements)
var/replacement = replacements[to_replace]
// Values can be lists to be picked randomly from
if (islist(replacement))
replacement = pick(replacement)
message = replacetextEx(message, to_replace, replacement)
message = trim(message)
if (prob(end_string_chance))
message += islist(end_string) ? pick(end_string) : end_string
speech_args[SPEECH_MESSAGE] = trim(message)
if (uppercase)
return COMPONENT_UPPERCASE_SPEECH
/datum/component/speechmod/proc/on_equipped(datum/source, mob/living/user, slot)
SIGNAL_HANDLER
if (!isnull(slots) && !(slot & slots))
if (!isnull(targeted))
UnregisterSignal(targeted, COMSIG_MOB_SAY)
targeted = null
return
if (targeted == user)
return
targeted = user
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
/datum/component/speechmod/proc/on_unequipped(datum/source, mob/living/user)
SIGNAL_HANDLER
if (isnull(targeted))
return
UnregisterSignal(targeted, COMSIG_MOB_SAY)
targeted = null
/datum/component/speechmod/proc/on_implanted(datum/source, mob/living/carbon/receiver)
SIGNAL_HANDLER
if (targeted == receiver)
return
targeted = receiver
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
/datum/component/speechmod/proc/on_removed(datum/source, mob/living/carbon/former_owner)
SIGNAL_HANDLER
if (isnull(targeted))
return
UnregisterSignal(targeted, COMSIG_MOB_SAY)
targeted = null
/datum/component/speechmod/proc/on_mutation_gained(datum/source, mob/living/carbon/human/owner)
SIGNAL_HANDLER
if (targeted == owner)
return
targeted = owner
RegisterSignal(targeted, COMSIG_MOB_SAY, PROC_REF(handle_speech))
/datum/component/speechmod/proc/on_mutation_lost(datum/source, mob/living/carbon/human/owner)
SIGNAL_HANDLER
if (isnull(targeted))
return
UnregisterSignal(targeted, COMSIG_MOB_SAY)
targeted = null
/datum/component/speechmod/Destroy()
should_modify_speech = null
return ..()