[MIRROR] Adds three brain traumas (feat. returning to monkey) (#26981)

* Adds colorblindness as a mild brain trauma (#76527)

## About The Pull Request

What the title says. 
The brain trauma makes the whole screen monochrome until cured.

![image](https://github.com/tgstation/tgstation/assets/82850673/442d24a8-6625-454c-bc28-64b786b03f49)

## Why It's Good For The Game

I feel like the current pool for mild brain traumas is quite lame, this
helps spice it up a bit with something that is quite annoying and
distracting but not game breaking (as mild brain traumas should
generally be).

## Changelog

🆑
add: Added colorblindness as a mild brain trauma.
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>

* Adds three brain traumas (feat. returning to monkey)  (#82129)

## About The Pull Request

- Adds "Primal Instincts" brain trama. 
   - Special trauma
   - Randomly, your body will be taken over by monkey AI. 
- You will still be in control of the body, but you will have to fight
against the monkey ai for actions.
- There is a probability the monkey AI that takes control is aggressive,
meaning it will attack anyone nearby.
   - While primal, you can understand monkey language. 

- Adds "Kleptomania" brain trauma
   - Severe trauma
- When you have empty hands, you will passively try to pick up things
near you.
- There is no feedback message associated, so you may not even notice
you did this.
- This effect is temporarily disabled if you have taken damage recently.

- Adds "Possessive" brain trauma
   - Mild trauma
- Randomly, your held items will become undroppable for a short to
medium length of time.

## Why It's Good For The Game

I was looking through AI stuff recently and remembered we support
allowing AI controllers to work in cliented mobs, but we don't use it
anywhere (outside of adminbus)

So I wanted to add a brain trauma themed around that. Simple enough. 

But I didn't want to PR just a single trauma, that's boring so I thought
of some additional ones. Just to spice up the other two trauma pools. I
especially wanted to add some traumas that interact with inventory and
items, because while a lot of our traumas involving how a person
interacts with the world, not many involve how a person interacts with
themself.

## Changelog

🆑 Melbert
add: Adds 3 Traumas: Primal Instincts (special), Kleptomania (severe),
and Possessive (mild)
/🆑

* lewd

* Is this it?

* Hmmm

* Oh, this was unnecessary.

---------

Co-authored-by: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-04-03 21:03:57 +02:00
committed by GitHub
parent 56307c364c
commit ffa5c01b30
7 changed files with 180 additions and 2 deletions

View File

@@ -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)

View File

@@ -266,3 +266,56 @@
speak_dejavu += speech_args[SPEECH_MESSAGE]
else
speak_dejavu += speech_args[SPEECH_MESSAGE]
/datum/brain_trauma/mild/color_blindness
name = "Achromatopsia"
desc = "Patient's occipital lobe is unable to recognize and interpret color, rendering the patient completely colorblind."
scan_desc = "colorblindness"
gain_text = span_warning("The world around you seems to lose its color.")
lose_text = span_notice("The world feels bright and colorful again.")
/datum/brain_trauma/mild/color_blindness/on_gain()
owner.add_client_colour(/datum/client_colour/monochrome/colorblind)
return ..()
/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))

View File

@@ -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)

View File

@@ -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."))

View File

@@ -211,6 +211,9 @@
fade_in = 20
fade_out = 20
/datum/client_colour/monochrome/colorblind
priority = PRIORITY_HIGH
/datum/client_colour/monochrome/trance
priority = PRIORITY_NORMAL

View File

@@ -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

View File

@@ -154,14 +154,16 @@
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))
RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech), override=TRUE)
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)
@@ -218,10 +220,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)