From 76170e9b1a957b137eba291a7442363cc4d6768c Mon Sep 17 00:00:00 2001 From: NovaBot <154629622+NovaBot13@users.noreply.github.com> Date: Mon, 25 Mar 2024 11:36:45 -0400 Subject: [PATCH] [MIRROR] Adds three brain traumas (feat. returning to monkey) (#1570) * Adds three brain traumas (feat. returning to monkey) * Update mild.dm * Update lewd_quirks.dm * Update lewd_quirks.dm --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- code/datums/brain_damage/brain_trauma.dm | 2 + code/datums/brain_damage/mild.dm | 38 +++++++++++ code/datums/brain_damage/severe.dm | 63 +++++++++++++++++++ code/datums/brain_damage/special.dm | 52 +++++++++++++++ .../religion/honorbound/honorbound_trauma.dm | 3 +- .../lewd_items/code/lewd_quirks.dm | 6 +- 6 files changed, 161 insertions(+), 3 deletions(-) diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm index 2bb26d1b44c..79b2729c5c6 100644 --- a/code/datums/brain_damage/brain_trauma.dm +++ b/code/datums/brain_damage/brain_trauma.dm @@ -36,6 +36,7 @@ //Called when given to a mob /datum/brain_trauma/proc/on_gain() + SHOULD_CALL_PARENT(TRUE) if(gain_text) to_chat(owner, gain_text) RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech)) @@ -43,6 +44,7 @@ //Called when removed from a mob /datum/brain_trauma/proc/on_lose(silent) + SHOULD_CALL_PARENT(TRUE) if(!silent && lose_text) to_chat(owner, lose_text) UnregisterSignal(owner, COMSIG_MOB_SAY) diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index c3d06976ed5..b8f70f8a79f 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -281,3 +281,41 @@ /datum/brain_trauma/mild/color_blindness/on_lose(silent) owner.remove_client_colour(/datum/client_colour/monochrome/colorblind) return ..() + +/datum/brain_trauma/mild/possessive + name = "Possessive" + desc = "Patient is extremely possessive of their belongings." + scan_desc = "possessiveness" + gain_text = span_warning("You start to worry about your belongings.") + lose_text = span_notice("You worry less about your belongings.") + +/datum/brain_trauma/mild/possessive/on_lose(silent) + . = ..() + for(var/obj/item/thing in owner.held_items) + clear_trait(thing) + +/datum/brain_trauma/mild/possessive/on_life(seconds_per_tick, times_fired) + if(!SPT_PROB(5, seconds_per_tick)) + return + + var/obj/item/my_thing = pick(owner.held_items) // can pick null, that's fine + if(isnull(my_thing) || HAS_TRAIT(my_thing, TRAIT_NODROP) || (my_thing.item_flags & (HAND_ITEM|ABSTRACT))) + return + + ADD_TRAIT(my_thing, TRAIT_NODROP, TRAUMA_TRAIT) + RegisterSignals(my_thing, list(COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_MOVED), PROC_REF(clear_trait)) + to_chat(owner, span_warning("You feel a need to keep [my_thing] close...")) + addtimer(CALLBACK(src, PROC_REF(relax), my_thing), rand(30 SECONDS, 3 MINUTES), TIMER_DELETE_ME) + +/datum/brain_trauma/mild/possessive/proc/relax(obj/item/my_thing) + if(QDELETED(my_thing)) + return + if(HAS_TRAIT_FROM_ONLY(my_thing, TRAIT_NODROP, TRAUMA_TRAIT)) // in case something else adds nodrop, somehow? + to_chat(owner, span_notice("You feel more comfortable letting go of [my_thing].")) + clear_trait(my_thing) + +/datum/brain_trauma/mild/possessive/proc/clear_trait(obj/item/my_thing, ...) + SIGNAL_HANDLER + + REMOVE_TRAIT(my_thing, TRAIT_NODROP, TRAUMA_TRAIT) + UnregisterSignal(my_thing, list(COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_MOVED)) diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index d78f2abe9bc..8754c87adc2 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -431,3 +431,66 @@ if(SPT_PROB(50, seconds_per_tick)) to_chat(owner, span_notice("You feel eldritch energies pulse from your body!")) tile.rust_heretic_act() + +/datum/brain_trauma/severe/kleptomaniac + name = "Kleptomania" + desc = "Patient is prone to stealing things." + scan_desc = "kleptomania" + gain_text = span_warning("You feel a sudden urge to take that. Surely no one will notice.") + lose_text = span_notice("You no longer feel the urge to take things.") + /// Cooldown between allowing steal attempts + COOLDOWN_DECLARE(steal_cd) + +/datum/brain_trauma/severe/kleptomaniac/on_gain() + . = ..() + RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(damage_taken)) + +/datum/brain_trauma/severe/kleptomaniac/on_lose() + . = ..() + UnregisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE) + +/datum/brain_trauma/severe/kleptomaniac/proc/damage_taken(datum/source, damage_amount, damage_type, ...) + SIGNAL_HANDLER + // While you're fighting someone (or dying horribly) your mind has more important things to focus on than pocketing stuff + if(damage_amount >= 5 && (damage_type == BRUTE || damage_type == BURN || damage_type == STAMINA)) + COOLDOWN_START(src, steal_cd, 12 SECONDS) + +/datum/brain_trauma/severe/kleptomaniac/on_life(seconds_per_tick, times_fired) + if(owner.usable_hands <= 0) + return + if(!SPT_PROB(5, seconds_per_tick)) + return + if(!COOLDOWN_FINISHED(src, steal_cd)) + return + if(!owner.has_active_hand() || !owner.get_empty_held_indexes()) + return + + // If our main hand is full, that means our offhand is empty, so try stealing with that + var/steal_to_offhand = !!owner.get_active_held_item() + var/curr_index = owner.active_hand_index + var/pre_dir = owner.dir + if(steal_to_offhand) + owner.swap_hand(owner.get_inactive_hand_index()) + + var/list/stealables = list() + for(var/obj/item/potential_stealable in oview(1, owner)) + if(potential_stealable.w_class >= WEIGHT_CLASS_BULKY) + continue + if(potential_stealable.anchored || !(potential_stealable.interaction_flags_item & INTERACT_ITEM_ATTACK_HAND_PICKUP)) + continue + stealables += potential_stealable + + for(var/obj/item/stealable as anything in shuffle(stealables)) + if(!owner.CanReach(stealable, view_only = TRUE) || stealable.IsObscured()) + continue + // Try to do a raw click on the item with one of our empty hands, to pick it up (duh) + owner.log_message("attempted to pick up (kleptomania)", LOG_ATTACK, color = "orange") + owner.ClickOn(stealable) + // No feedback message. Intentional, you may not even realize you picked up something + break + + if(steal_to_offhand) + owner.swap_hand(curr_index) + owner.setDir(pre_dir) + // Gives you a small buffer - not to avoid spam, but to make it more subtle / less predictable + COOLDOWN_START(src, steal_cd, 8 SECONDS) diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index 31f31622130..233713f45be 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -472,3 +472,55 @@ owner.mob_mood?.mood_modifier += 1 owner.mob_mood?.sanity_level = SANITY_GREAT return ..() + +/datum/brain_trauma/special/primal_instincts + name = "Feral Instincts" + desc = "Patient's mind is stuck in a primal state, causing them to act on instinct rather than reason." + scan_desc = "ferality" + gain_text = span_warning("Your pupils dilate, and it becomes harder to think straight.") + lose_text = span_notice("Your mind clears, and you feel more in control.") + resilience = TRAUMA_RESILIENCE_SURGERY + /// Tracks any existing AI controller, so we can restore it when we're cured + var/old_ai_controller_type + +/datum/brain_trauma/special/primal_instincts/on_gain() + . = ..() + if(!isnull(owner.ai_controller)) + old_ai_controller_type = owner.ai_controller.type + QDEL_NULL(owner.ai_controller) + + owner.ai_controller = new /datum/ai_controller/monkey(owner) + owner.ai_controller.continue_processing_when_client = TRUE + owner.ai_controller.set_ai_status(AI_STATUS_OFF) + +/datum/brain_trauma/special/primal_instincts/on_lose(silent) + . = ..() + if(QDELING(owner)) + return + + QDEL_NULL(owner.ai_controller) + if(old_ai_controller_type) + owner.ai_controller = new old_ai_controller_type(owner) + owner.remove_language(/datum/language/monkey, UNDERSTOOD_LANGUAGE, TRAUMA_TRAIT) + +/datum/brain_trauma/special/primal_instincts/on_life(seconds_per_tick, times_fired) + if(isnull(owner.ai_controller)) + qdel(src) + return + + if(!SPT_PROB(3, seconds_per_tick)) + return + + owner.grant_language(/datum/language/monkey, UNDERSTOOD_LANGUAGE, TRAUMA_TRAIT) + owner.ai_controller.set_blackboard_key(BB_MONKEY_AGGRESSIVE, prob(75)) + if(owner.ai_controller.ai_status == AI_STATUS_OFF) + owner.ai_controller.set_ai_status(AI_STATUS_ON) + owner.log_message("became controlled by monkey instincts ([owner.ai_controller.blackboard[BB_MONKEY_AGGRESSIVE] ? "aggressive" : "docile"])", LOG_ATTACK, color = "orange") + to_chat(owner, span_warning("You feel the urge to act on your primal instincts...")) + // extend original timer if we roll the effect while it's already ongoing + addtimer(CALLBACK(src, PROC_REF(primal_instincts_off)), rand(20 SECONDS, 40 SECONDS), TIMER_UNIQUE|TIMER_NO_HASH_WAIT|TIMER_OVERRIDE|TIMER_DELETE_ME) + +/datum/brain_trauma/special/primal_instincts/proc/primal_instincts_off() + owner.ai_controller.set_ai_status(AI_STATUS_OFF) + owner.remove_language(/datum/language/monkey, UNDERSTOOD_LANGUAGE, TRAUMA_TRAIT) + to_chat(owner, span_green("The urge subsides.")) diff --git a/code/modules/religion/honorbound/honorbound_trauma.dm b/code/modules/religion/honorbound/honorbound_trauma.dm index 399bf6765ed..6bc0879b125 100644 --- a/code/modules/religion/honorbound/honorbound_trauma.dm +++ b/code/modules/religion/honorbound/honorbound_trauma.dm @@ -20,7 +20,8 @@ RegisterSignal(owner, COMSIG_MOB_FIRED_GUN, PROC_REF(staff_check)) //adds the relay_attackers element to the owner so whoever attacks him becomes guilty. - owner.AddElement(/datum/element/relay_attackers) + if(!HAS_TRAIT(owner, TRAIT_RELAYING_ATTACKER)) + owner.AddElement(/datum/element/relay_attackers) RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) //signal that checks for dishonorable attacks diff --git a/modular_nova/modules/modular_items/lewd_items/code/lewd_quirks.dm b/modular_nova/modules/modular_items/lewd_items/code/lewd_quirks.dm index 395c4b1230a..f55dd8000bd 100644 --- a/modular_nova/modules/modular_items/lewd_items/code/lewd_quirks.dm +++ b/modular_nova/modules/modular_items/lewd_items/code/lewd_quirks.dm @@ -154,18 +154,18 @@ speech_args[SPEECH_MESSAGE] = message /datum/brain_trauma/very_special/bimbo/on_gain() + . = ..() owner.add_mood_event("bimbo", /datum/mood_event/bimbo) if(!HAS_TRAIT_FROM(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM)) ADD_TRAIT(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM) - RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech)) if(!HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, TRAIT_APHRO)) ADD_TRAIT(owner, TRAIT_MASOCHISM, TRAIT_APHRO) /datum/brain_trauma/very_special/bimbo/on_lose() + . = ..() owner.clear_mood_event("bimbo") if(HAS_TRAIT_FROM(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM)) REMOVE_TRAIT(owner, TRAIT_BIMBO, TRAIT_LEWDCHEM) - UnregisterSignal(owner, COMSIG_MOB_SAY) if(HAS_TRAIT_FROM(owner, TRAIT_MASOCHISM, TRAIT_APHRO)) REMOVE_TRAIT(owner, TRAIT_MASOCHISM, TRAIT_APHRO) @@ -218,10 +218,12 @@ resilience = TRAUMA_RESILIENCE_ABSOLUTE /datum/brain_trauma/very_special/neverboner/on_gain() + . = ..() var/mob/living/carbon/human/affected_human = owner ADD_TRAIT(affected_human, TRAIT_NEVERBONER, TRAIT_APHRO) /datum/brain_trauma/very_special/neverboner/on_lose() + . = ..() var/mob/living/carbon/human/affected_human = owner REMOVE_TRAIT(affected_human, TRAIT_NEVERBONER, TRAIT_APHRO)