Persistent trash (#21217)

# Summary

This PR adds trash to the persistence system.

- Trash becomes persistent the moment it is dropped unless it is dropped
in a maint or the disposal room.
- It looses persistence when it lands in a maint/disposal room or gets
picked up again.
- Persistent trash can be found up to three days.

Those are the base rules, some trash types have additional rules.

List of trash to be implemented:

- [x] Basic trash (snacks and such)
  - Cigarette buts
  - spitwad
  - Burned matches
- [x] Broken bottles
- [x] Torn inflatable (-doors)

> Littering is a i120 violation and can be punished with 3-7 minutes of
prison time or with a 40-150 credit fine.
> Stop littering and keep the ship clean.

## Follow-up tasks

- [x] Update GitHub Wiki: Add section on how to add persistent trash
types.
- [x] Update GitHub Wiki: Make persistence_get_content nullable/empty.
This commit is contained in:
FabianK3
2025-09-15 12:13:46 +00:00
committed by GitHub
parent e9e1e923f5
commit 1ccfd0a0e7
11 changed files with 98 additions and 25 deletions
+30 -2
View File
@@ -234,6 +234,11 @@
/// Holder var for the item outline filter, null when no outline filter on the item.
var/outline_filter
// Persistency
// Set this to true if you want the item to become persistent trash
// Requires the usual implementation requirements for new persistent types but provides a single implementation for trash logic
var/persistency_considered_trash = FALSE
/obj/item/Initialize(mapload, ...)
. = ..()
if(islist(armor))
@@ -480,18 +485,38 @@
if(item_flags & ITEM_FLAG_HELD_MAP_TEXT)
check_maptext()
if(zoom)
zoom(user) //binoculars, scope, etc
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED, user)
in_inventory = FALSE
if(user && (z_flags & ZMM_MANGLE_PLANES))
addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE)
user?.update_equipment_speed_mods()
try_make_persistent_trash()
/obj/item/pipe_eject(var/direction)
SHOULD_CALL_PARENT(TRUE)
..()
try_make_persistent_trash() // Trash that gets thrown into disposal bins and ends up in the disposal areas shouldn't be persistent after all
/obj/item/proc/try_make_persistent_trash()
SHOULD_NOT_OVERRIDE(TRUE)
PROTECTED_PROC(TRUE)
if(persistency_considered_trash) // Persistent trash - Applicable if considered_persistent_trash is true
// Trash-like items should become only persistent when they are not dropped in a maint or disposals, otherwise they get deregistered
var/turf/T = get_turf(src)
if(T)
var/area/A = get_area(T)
if(A && !(A.area_flags & AREA_FLAG_PREVENT_PERSISTENT_TRASH))
persistance_expiration_time_days = 3 // Ensure expiration date is set to prevent long term trash
SSpersistence.register_track(src, usr == null ? null : ckey(usr.key))
else
SSpersistence.deregister_track(src)
else
SSpersistence.deregister_track(src)
/obj/item/proc/remove_item_verbs(mob/user)
if(ismech(user)) //very snowflake, but necessary due to how mechs work
@@ -603,6 +628,9 @@
user.update_equipment_speed_mods()
if(persistency_considered_trash || persistence_track_active) // The moment trash like items get picked up they are no longer persistent
SSpersistence.deregister_track(src)
/obj/item/proc/check_equipped(var/mob/user, var/slot, var/assisted_equip = FALSE)
return TRUE
+24
View File
@@ -10,10 +10,34 @@
desc = "General waste material, refuse or litter. Dispose responsibly."
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
persistency_considered_trash = TRUE
/obj/item/trash/attack(mob/living/target_mob, mob/living/user, target_zone)
return
/obj/item/trash/persistence_get_content()
var/list/content = list()
content["name"] = name
content["desc"] = desc
content["icon"] = icon
content["icon_state"] = icon_state
content["item_state"] = item_state
content["drop_sound"] = drop_sound
content["pickup_sound"] = pickup_sound
return content
/obj/item/trash/persistence_apply_content(content, x, y, z)
name = content["name"]
desc = content["desc"]
icon = file(content["icon"])
icon_state = content["icon_state"]
item_state = content["item_state"]
drop_sound = file(content["drop_sound"])
pickup_sound = file(content["pickup_sound"])
src.x = x
src.y = y
src.z = z
/obj/item/trash/koisbar
name = "\improper k'ois bar wrapper"
icon_state = "koisbar"
@@ -289,6 +289,12 @@
name = "torn inflatable wall"
desc = "A folded membrane which rapidly expands into a large cubical shape on activation. It is too torn to be usable."
icon_state = "folded_wall-torn"
persistency_considered_trash = TRUE
/obj/item/inflatable/torn/persistence_apply_content(content, x, y, z)
src.x = x
src.y = y
src.z = z
/obj/item/inflatable/torn/attack_self(mob/user)
to_chat(user, SPAN_NOTICE("The inflatable wall is too torn to be inflated!"))
@@ -298,6 +304,12 @@
name = "torn inflatable door"
desc = "A folded membrane which rapidly expands into a simple door on activation. It is too torn to be usable."
icon_state = "folded_door-torn"
persistency_considered_trash = TRUE
/obj/item/inflatable/door/torn/persistence_apply_content(content, x, y, z)
src.x = x
src.y = y
src.z = z
/obj/item/inflatable/door/torn/attack_self(mob/user)
to_chat(user, SPAN_NOTICE("The inflatable door is too torn to be inflated!"))