mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-12 16:44:43 +01:00
e49e13b795
## About The Pull Request Phobias have been refactored to use the new fear system instead of handling their effects via simple triggers on themselves. The overall idea is still the same, triggering upon seeing/hearing/saying a scary word or thing, but instead of instantly sending you into a panic it adds some fear and has a chance of triggering a new startle fear effect, which mirrors some of the previous phobia effects that weren't already included in other handlers. To complete the phobic trio, I've added monophobia as a quirk - its quite interesting compared to nycto- and claustrophobia, as it forces you to stick to other people, thus indirectly incentivizing social interactions, and could make for actually interesting moments. Additionally, I've cleaned up some of the related code and added message CDs to all other handlers that were missing them as to avoid chat spam which could sometimes occur when the effect triggered far too frequently. ## Why It's Good For The Game Using the new system makes phobias much more immersive and interesting to play around, as they no longer absolutely cripple you to the point of making the game unplayable in case of some of them due to random stuns or knockouts. It also makes them natively interact with other phobias and quirks, which is a neat thing for character building. Currently getting a phobia basically forces you to go to medbay as to not risk randomly falling unconscious every once in a while if you roll a common one (like cyborgs, blood, doctors or authority), and picking one as a quirk is basically not an option. ## Changelog 🆑 add: Monophobia is now availible as a negative (-3) quirk. balance: Phobias now have accumulating, and less debilitating effects due to conversion to the new fear system. qol: Fear effects now have a cooldown between messages as to avoid chat spam. code: Cleaned up some of fear code. refactor: Refactored phobias to use the fear system /🆑
210 lines
8.2 KiB
Plaintext
210 lines
8.2 KiB
Plaintext
/// Fearful component: provides optional handling of fears and phobias for mob's mood
|
|
/// Can be applied from multiple sources, and essentially serves as a central controller for fear datums described below
|
|
|
|
/datum/component/fearful
|
|
dupe_mode = COMPONENT_DUPE_SOURCES
|
|
|
|
/// How terrified is the source?
|
|
var/terror_buildup = 0
|
|
/// List of terror handlers we currently have -> sources they're added by
|
|
var/list/terror_handlers = list()
|
|
/// List of overriden handler types, for ease of access
|
|
var/list/list/overriden_handlers = list()
|
|
/// How much buildup we had last tick? Used for non-ticking terror source tracking
|
|
var/last_tick_buildup = 0
|
|
|
|
/*
|
|
* handler_types - terror_handler(s) to add to the mob
|
|
* initial_buildup - amount of fear to add to mob from getting scared shitless by whatever added the component
|
|
* add_defaults - should terror handlers marked as "default" be added to the mob?
|
|
*/
|
|
/datum/component/fearful/Initialize(list/handler_types, initial_buildup, add_defaults = TRUE)
|
|
. = ..()
|
|
if (!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
START_PROCESSING(SSdcs, src)
|
|
terror_buildup = initial_buildup
|
|
|
|
if (!add_defaults)
|
|
return
|
|
|
|
for (var/datum/terror_handler/handler as anything in subtypesof(/datum/terror_handler))
|
|
if (!initial(handler.default))
|
|
continue
|
|
add_handler(handler, "default")
|
|
|
|
/datum/component/fearful/Destroy(force)
|
|
STOP_PROCESSING(SSdcs, src)
|
|
QDEL_LIST(terror_handlers)
|
|
return ..()
|
|
|
|
/datum/component/fearful/RegisterWithParent()
|
|
. = ..()
|
|
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
|
RegisterSignal(parent, COMSIG_CARBON_PRE_MISC_HELP, PROC_REF(comfort_owner))
|
|
RegisterSignal(parent, SIGNAL_ADDTRAIT(TRAIT_FEARLESS), PROC_REF(fearless_added))
|
|
RegisterSignal(parent, COMSIG_CARBON_MOOD_CHECK, PROC_REF(on_mood_check))
|
|
|
|
/datum/component/fearful/UnregisterFromParent()
|
|
. = ..()
|
|
UnregisterSignal(parent, list(COMSIG_ATOM_EXAMINE, COMSIG_CARBON_PRE_MISC_HELP, SIGNAL_ADDTRAIT(TRAIT_FEARLESS), COMSIG_CARBON_MOOD_CHECK))
|
|
|
|
/datum/component/fearful/on_source_add(source, list/handler_types, initial_buildup, add_defaults = TRUE)
|
|
. = ..()
|
|
terror_buildup = clamp(terror_buildup + initial_buildup, 0, TERROR_BUILDUP_MAXIMUM)
|
|
for (var/handler_type in handler_types)
|
|
add_handler(handler_type, source)
|
|
|
|
/datum/component/fearful/on_source_remove(source)
|
|
for (var/datum/terror_handler/handler as anything in terror_handlers)
|
|
terror_handlers[handler] -= source
|
|
if (length(terror_handlers[handler]))
|
|
continue
|
|
terror_handlers -= handler
|
|
for (var/override_type in handler.overrides)
|
|
if (!overriden_handlers[override_type])
|
|
continue
|
|
overriden_handlers[override_type] -= handler.type
|
|
if (!length(overriden_handlers[override_type]))
|
|
overriden_handlers -= override_type
|
|
qdel(handler)
|
|
return ..()
|
|
|
|
/datum/component/fearful/proc/add_handler(handler_type, source)
|
|
for (var/datum/terror_handler/existing as anything in terror_handlers)
|
|
if (existing.type == handler_type && !existing.bespoke)
|
|
terror_handlers[existing] += source
|
|
return
|
|
|
|
var/datum/terror_handler/handler = new handler_type(parent, src)
|
|
terror_handlers[handler] = list(source)
|
|
for (var/override_type in handler.overrides)
|
|
if (!overriden_handlers[override_type])
|
|
overriden_handlers[override_type] = list()
|
|
overriden_handlers[override_type][handler_type] = TRUE
|
|
return handler
|
|
|
|
/datum/component/fearful/proc/get_fear_multiplier()
|
|
var/multiplier = 1
|
|
var/mob/living/parent_mob = parent
|
|
if(HAS_PERSONALITY(parent_mob, /datum/personality/cowardly))
|
|
multiplier *= 1.25
|
|
if(HAS_PERSONALITY(parent_mob, /datum/personality/paranoid))
|
|
multiplier *= 1.10
|
|
if(HAS_PERSONALITY(parent_mob, /datum/personality/brave))
|
|
multiplier *= 0.75
|
|
return multiplier
|
|
|
|
/datum/component/fearful/process(seconds_per_tick)
|
|
var/fear_modifier = get_fear_multiplier()
|
|
var/terror_adjustment = 0
|
|
var/list/tick_later = list()
|
|
for (var/datum/terror_handler/handler as anything in terror_handlers)
|
|
if (overriden_handlers[handler.type])
|
|
continue
|
|
if (handler.handler_type == TERROR_HANDLER_EFFECT)
|
|
tick_later += handler
|
|
continue
|
|
var/adjustment = handler.tick(seconds_per_tick, terror_buildup)
|
|
terror_buildup = clamp(terror_buildup + (adjustment * fear_modifier), 0, TERROR_BUILDUP_MAXIMUM)
|
|
terror_adjustment += adjustment
|
|
|
|
for (var/datum/terror_handler/handler as anything in tick_later)
|
|
var/adjustment = handler.tick(seconds_per_tick, terror_buildup)
|
|
terror_buildup = clamp(terror_buildup + (adjustment * fear_modifier), 0, TERROR_BUILDUP_MAXIMUM)
|
|
terror_adjustment += adjustment
|
|
|
|
// If we gained terror in any way, don't tick it down
|
|
if (terror_adjustment > 0 || terror_buildup > last_tick_buildup)
|
|
last_tick_buildup = terror_buildup
|
|
return
|
|
|
|
// Tick terror down while we're not being actively spooked
|
|
if (terror_buildup > 0)
|
|
terror_buildup = max(terror_buildup - (TERROR_BUILDUP_PASSIVE_DECREASE * (1 / fear_modifier)) * seconds_per_tick, 0)
|
|
last_tick_buildup = terror_buildup
|
|
|
|
/datum/component/fearful/proc/on_examine(mob/living/source, mob/user, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
|
|
if (source.stat >= UNCONSCIOUS)
|
|
return
|
|
|
|
if(terror_buildup >= TERROR_BUILDUP_HEART_ATTACK)
|
|
examine_list += span_danger("[source.p_They()] [source.p_are()] seizing up, about to collapse in fear!")
|
|
else if(terror_buildup > TERROR_BUILDUP_PANIC)
|
|
examine_list += span_boldwarning("[source.p_They()] [source.p_are()] trembling and shaking, barely standing upright!")
|
|
else if(terror_buildup >= TERROR_BUILDUP_TERROR)
|
|
examine_list += span_boldwarning("[source] is visibly trembling and twitching. [source.p_They()] [source.p_are()] clearly in distress!")
|
|
else if(terror_buildup >= TERROR_BUILDUP_FEAR)
|
|
examine_list += span_warning("[source] looks very worried about something. [capitalize(source.p_are())] [source.p_they()] alright?")
|
|
else if (terror_buildup)
|
|
examine_list += span_smallnotice("[source] looks rather anxious. [source.p_They()] could probably use a hug...")
|
|
|
|
/datum/component/fearful/proc/comfort_owner(mob/living/carbon/source, mob/living/hugger)
|
|
SIGNAL_HANDLER
|
|
|
|
if(hugger == parent)
|
|
return
|
|
|
|
if(isnightmare(hugger))
|
|
var/lit_tiles = 0
|
|
var/unlit_tiles = 0
|
|
|
|
for(var/turf/open/turf_to_check in range(1, source))
|
|
var/light_amount = turf_to_check.get_lumcount()
|
|
if(light_amount > LIGHTING_TILE_IS_DARK)
|
|
lit_tiles++
|
|
else
|
|
unlit_tiles++
|
|
|
|
if(lit_tiles < unlit_tiles)
|
|
source.Knockdown(0.5 SECONDS)
|
|
terror_buildup += HUG_TERROR_AMOUNT
|
|
source.visible_message(
|
|
span_warning("[source] recoils in fear as [hugger] waves [hugger.p_their()] arms and shrieks at [source.p_them()]!"),
|
|
span_boldwarning("The shadows lash out at you, and you drop to the ground in fear!"),
|
|
span_hear("You hear someone shriek in fear. How embarassing!"),
|
|
)
|
|
return COMPONENT_BLOCK_MISC_HELP
|
|
|
|
var/hug_buildup = 0
|
|
for (var/datum/terror_handler/handler as anything in terror_handlers)
|
|
hug_buildup += handler.on_hug(hugger)
|
|
|
|
if (hug_buildup > 0)
|
|
terror_buildup += hug_buildup
|
|
source.visible_message(
|
|
span_warning("[source] recoils in fear as [hugger] attempts to hug [source.p_them()]!"),
|
|
span_boldwarning("You recoil in terror as [hugger] attempts to hug you!"),
|
|
span_hear("You hear someone shriek in fear. How embarassing!"),
|
|
)
|
|
return COMPONENT_BLOCK_MISC_HELP
|
|
|
|
terror_buildup -= HUG_TERROR_AMOUNT
|
|
source.visible_message(
|
|
span_notice("[source] seems to relax as [hugger] gives [source.p_them()] a comforting hug."),
|
|
span_nicegreen("You feel yourself calm down as [hugger] gives you a reassuring hug."),
|
|
span_hear("You hear shuffling and a sigh of relief."),
|
|
)
|
|
|
|
/// Remove all terror buildup when we become fearless
|
|
/datum/component/fearful/proc/fearless_added(datum/source)
|
|
SIGNAL_HANDLER
|
|
terror_buildup = 0
|
|
|
|
/datum/component/fearful/proc/on_mood_check(mob/living/source, list/mood_list)
|
|
SIGNAL_HANDLER
|
|
|
|
if(terror_buildup >= TERROR_BUILDUP_HEART_ATTACK)
|
|
mood_list += span_boldwarning("You are about to collapse in fear!")
|
|
else if(terror_buildup > TERROR_BUILDUP_PANIC)
|
|
mood_list += span_boldwarning("You are shaking in fear!")
|
|
else if(terror_buildup >= TERROR_BUILDUP_TERROR)
|
|
mood_list += span_warning("You are trembling in fear.")
|
|
else if(terror_buildup >= TERROR_BUILDUP_FEAR)
|
|
mood_list += span_warning("You feel scared.")
|
|
else if (terror_buildup)
|
|
mood_list += span_notice("You feel on the edge.")
|