From 0d1fcba55d329b2ae3cd1dd82d83fcef111f1726 Mon Sep 17 00:00:00 2001
From: MichiRecRoom <1008889+LikeLakers2@users.noreply.github.com>
Date: Sat, 25 Jan 2025 17:00:03 -0500
Subject: [PATCH 1/3] Refactors Kleptomania brain trauma - it doesn't need to
be a status effect
---
.../code/modules/datums/brain_damage/mild.dm | 123 +++++++++++++-----
1 file changed, 88 insertions(+), 35 deletions(-)
diff --git a/monkestation/code/modules/datums/brain_damage/mild.dm b/monkestation/code/modules/datums/brain_damage/mild.dm
index a0d10cda3a9b..97b8ededd586 100644
--- a/monkestation/code/modules/datums/brain_damage/mild.dm
+++ b/monkestation/code/modules/datums/brain_damage/mild.dm
@@ -2,45 +2,98 @@
name = "Kleptomania"
desc = "Patient has a fixation of small objects and may involuntarily pick them up."
scan_desc = "kleptomania"
- gain_text = "You feel a strong urge to grab things."
- lose_text = "You no longer feel the urge to grab things."
+ gain_text = span_warning("You feel a strong urge to grab things.")
+ lose_text = span_notice("You no longer feel the urge to grab things.")
+ // The percent chance for kleptomania to actually activate every tick
+ var/kleptomania_chance = 2.5
+ // The percent chance to pickpocket from someone, instead of from the ground.
+ var/pickpocket_chance = 25
-/datum/brain_trauma/mild/kleptomania/on_gain()
- owner.apply_status_effect(/datum/status_effect/kleptomania)
- ..()
+/datum/brain_trauma/mild/kleptomania/on_life(seconds_per_tick, times_fired)
+ if(owner.incapacitated())
+ return
+ if(!SPT_PROB(kleptomania_chance, seconds_per_tick))
+ return
+ if(!owner.has_active_hand())
+ return
+ if(owner.get_active_held_item())
+ return
-/datum/brain_trauma/mild/kleptomania/on_lose()
- owner.remove_status_effect(/datum/status_effect/kleptomania)
- ..()
+ if(prob(pickpocket_chance))
+ steal_from_someone()
+ else
+ steal_from_ground()
-/datum/status_effect/kleptomania
- id = "kleptomania"
- status_type = STATUS_EFFECT_UNIQUE
- alert_type = null
- var/kleptomania_chance = 2.5
+/datum/brain_trauma/mild/kleptomania/proc/steal_from_someone()
+ var/list/potential_victims = list()
+ for(var/mob/living/carbon/human/potential_victim in view(1, owner))
+ if(potential_victim == owner)
+ continue
+ var/list/items_in_pockets = potential_victim.get_pockets()
+ if(!length(items_in_pockets))
+ return
+ potential_victims += potential_victim
+
+ if(!length(potential_victims))
+ return
+
+ var/mob/living/carbon/human/victim = pick(potential_victims)
+
+ // `items_in_pockets` should never be empty, given that we excluded them above. If it *is*
+ // empty, something is horribly wrong!
+ var/list/items_in_pockets = victim.get_pockets()
+ var/obj/item/item_to_steal = pick(items_in_pockets)
+ owner.visible_message(
+ span_warning("[owner] attempts to remove [item_to_steal] from [victim]'s pocket!"),
+ span_warning("You attempt to remove [item_to_steal] from [victim]'s pocket."),
+ span_warning("You hear someone rummaging through pockets.")
+ )
+
+ owner.log_message("is pickpocketed [item_to_steal] out of [key_name(victim)]'s pockets (kleptomania).", LOG_ATTACK, color = "red")
+ target.log_message("is having [item_to_steal] pickpocketed by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
+ if(!do_after(owner, item_to_steal.strip_delay, victim) || !victim.temporarilyRemoveItemFromInventory(item_to_steal))
+ owner.visible_message(
+ span_warning("[owner] fails to pickpocket [victim]."),
+ span_warning("You fail to pick [victim]'s pocket."),
+ null
+ )
+ return
+
+ owner.log_message("has pickpocketed [key_name(victim)] of [item_to_steal] (kleptomania).", LOG_ATTACK, color = "red")
+ target.log_message("has been pickpocketed of [item_to_steal] by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
+
+ owner.visible_message(
+ span_warning("[owner] removes [item_to_steal] from [victim]'s pocket!"),
+ span_warning("You remove [item_to_steal] from [victim]'s pocket."),
+ null
+ )
+
+ if(QDELETED(item_to_steal))
+ return
+ if(!owner.putItemFromInventoryInHandIfPossible(item_to_steal, owner.active_hand_index, TRUE))
+ item_to_steal.forceMove(owner.drop_location())
+
+/datum/brain_trauma/mild/kleptomania/proc/steal_from_ground()
+ // Get a list of anything that's not nailed down or already worn by the brain trauma's owner.
+ var/list/stealables = list()
+ var/list/currently_worn_gear = owner.get_all_gear()
+ for(var/obj/item/potential_stealable in oview(1, owner))
+ if(potential_stealable.anchored)
+ continue
+ if(potential_stealable in currently_worn_gear)
+ continue
+ if(!potential_stealable.Adjacent(owner))
+ continue
+ stealables += potential_stealable
+
+ // Shuffle the list of stealables, then loop through it until we find an item to grab.
+ for(var/obj/item/stealable as anything in shuffle(stealables))
+ if(!owner.CanReach(stealable, view_only = TRUE))
+ continue
-/datum/status_effect/kleptomania/tick()
- if(prob(kleptomania_chance) && owner.m_intent == MOVE_INTENT_RUN && !owner.get_active_held_item() && !(owner.incapacitated()) && owner.has_active_hand())
- if(prob(25)) //we pick pockets
- for(var/mob/living/carbon/human/victim in view(1, owner))
- var/pockets = victim.get_pockets()
- if(victim != owner && length(pockets))
- var/obj/item/I = pick(pockets)
- owner.visible_message("[owner] attempts to remove [I] from [victim]'s pocket!","You attempt to remove [I] from [victim]'s pocket.", FALSE, 1)
- if(do_after(owner, I.strip_delay, victim) && victim.temporarilyRemoveItemFromInventory(I))
- owner.visible_message("[owner] removes [I] from [victim]'s pocket!","You remove [I] from [victim]'s pocket.", FALSE, 1)
- log_admin("[key_name(usr)] picked [victim.name]'s pockets with Kleptomania trait.")
- if(!QDELETED(I) && !owner.putItemFromInventoryInHandIfPossible(I, owner.active_hand_index, TRUE, TRUE))
- I.forceMove(owner.drop_location())
- break
- else
- owner.visible_message("[owner] fails to pickpocket [victim].","You fail to pick [victim]'s pocket.", FALSE, 1)
- else //we pick stuff off the ground
- var/mob/living/carbon/C = owner
- for(var/obj/item/I in oview(1, C))
- if(!I.anchored && !(I in C.get_all_gear()) && I.Adjacent(C)) //anything that's not nailed down or worn
- I.attack_hand(C)
- break
+ owner.log_message("attempted to pick up (kleptomania) [stealable]", LOG_ATTACK, color = "orange")
+ stealable.attack_hand(owner)
+ break
/mob/living/carbon/human/proc/get_pockets()
var/list/pockets = list()
From fe23227ecdbffaa7e5a6fe70e596c8b92be5758e Mon Sep 17 00:00:00 2001
From: MichiRecRoom <1008889+LikeLakers2@users.noreply.github.com>
Date: Sat, 25 Jan 2025 23:49:58 -0500
Subject: [PATCH 2/3] SPT_PROB -> prob, turns out I was mistaken about how it
works
---
monkestation/code/modules/datums/brain_damage/mild.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monkestation/code/modules/datums/brain_damage/mild.dm b/monkestation/code/modules/datums/brain_damage/mild.dm
index 97b8ededd586..f7fdff757ec2 100644
--- a/monkestation/code/modules/datums/brain_damage/mild.dm
+++ b/monkestation/code/modules/datums/brain_damage/mild.dm
@@ -12,7 +12,7 @@
/datum/brain_trauma/mild/kleptomania/on_life(seconds_per_tick, times_fired)
if(owner.incapacitated())
return
- if(!SPT_PROB(kleptomania_chance, seconds_per_tick))
+ if(!prob(kleptomania_chance))
return
if(!owner.has_active_hand())
return
From 538863f165ef1202bc13bee9cdf1be6d28ce6106 Mon Sep 17 00:00:00 2001
From: MichiRecRoom <1008889+LikeLakers2@users.noreply.github.com>
Date: Sun, 26 Jan 2025 00:38:14 -0500
Subject: [PATCH 3/3] woops
---
monkestation/code/modules/datums/brain_damage/mild.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/monkestation/code/modules/datums/brain_damage/mild.dm b/monkestation/code/modules/datums/brain_damage/mild.dm
index f7fdff757ec2..95798b549b49 100644
--- a/monkestation/code/modules/datums/brain_damage/mild.dm
+++ b/monkestation/code/modules/datums/brain_damage/mild.dm
@@ -50,7 +50,7 @@
)
owner.log_message("is pickpocketed [item_to_steal] out of [key_name(victim)]'s pockets (kleptomania).", LOG_ATTACK, color = "red")
- target.log_message("is having [item_to_steal] pickpocketed by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
+ victim.log_message("is having [item_to_steal] pickpocketed by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
if(!do_after(owner, item_to_steal.strip_delay, victim) || !victim.temporarilyRemoveItemFromInventory(item_to_steal))
owner.visible_message(
span_warning("[owner] fails to pickpocket [victim]."),
@@ -60,7 +60,7 @@
return
owner.log_message("has pickpocketed [key_name(victim)] of [item_to_steal] (kleptomania).", LOG_ATTACK, color = "red")
- target.log_message("has been pickpocketed of [item_to_steal] by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
+ victim.log_message("has been pickpocketed of [item_to_steal] by [key_name(owner)] (kleptomania).", LOG_VICTIM, color = "orange", log_globally = FALSE)
owner.visible_message(
span_warning("[owner] removes [item_to_steal] from [victim]'s pocket!"),