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!"),