Add ashtray persistence & fixes (#21925)

# Summary

This PR adds persistency to ash trays. This in turn fixes cigarettes
butts spawning a round later in locations where non-empty ash trays were
found.

## Changes

- Add persistence to ash trays and prevent (fixes) cigarette butt
persistence if in an ash tray.
- Fixed cigarette butts not being persistent if the cigarette was put
out on purpose and landing on the floor.
- Fixed loss of registered persistence track on item pickup.
- Fixed persistent tracks when item is held by player.
- Removed all ash trays on the Horizon as their existence is now
persistent. One-time job for operations after merge.
- Fixed matter configuration on `/obj/item/material` not being set
during `set_material()`.
- Fixed persistent trash on space turfs.
- Minor adjustments in SQL/Readme.md.

---------

Signed-off-by: FabianK3 <21039694+FabianK3@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
This commit is contained in:
FabianK3
2026-03-17 13:12:57 +00:00
committed by GitHub
co-authored by VMSolidus
parent b56522f6e5
commit 6c4e9254b2
12 changed files with 74 additions and 88 deletions
@@ -246,6 +246,7 @@ ABSTRACT_TYPE(/obj/item/clothing/mask/smokable)
to_chat(M, SPAN_NOTICE("Your [name] goes out."))
if(intentionally)
butt.loc = T
butt.try_make_persistent_trash()
else if(M.wear_mask == src)
M.remove_from_mob(src) //un-equip it so the overlays can update
M.update_inv_wear_mask(0)
@@ -11,11 +11,32 @@
/obj/item/material/ashtray/Initialize(newloc, material_key)
. = ..()
if(!material)
return INITIALIZE_HINT_QDEL
persistance_expiration_time_days = rand(7, 180) // Imagine they get stolen, lost or break...
max_butts = round(material.hardness/10) //This is arbitrary but whatever.
randpixel_xy()
update_icon()
SSpersistence.register_track(src, null)
/obj/item/material/ashtray/persistence_get_content()
var/list/content = list()
content["fill_count"] = length(contents)
content["material"] = material.name
return content
/obj/item/material/ashtray/persistence_apply_content(content, x, y, z)
src.x = x
src.y = y
src.z = z
if(content["material"])
set_material(content["material"])
max_butts = round(material.hardness/10)
var/fill_count = content["fill_count"]
if(fill_count)
if(fill_count > max_butts)
fill_count = max_butts
for(var/i = 1; i <= fill_count; i++)
var/obj/item/trash/cigbutt/cigarbutt/cigbutt = new /obj/item/trash/cigbutt(src)
cigbutt.forceMove(src)
/obj/item/material/ashtray/shatter()
..()
@@ -67,6 +88,9 @@
user.remove_from_mob(attacking_item)
attacking_item.forceMove(src)
if(istype(attacking_item, /obj/item/trash/cigbutt))
SSpersistence.deregister_track(attacking_item) // Ashtray will handle the persistent contents in it itself
if (istype(attacking_item,/obj/item/clothing/mask/smokable/cigarette))
var/obj/item/clothing/mask/smokable/cigarette/cig = attacking_item
if (cig.lit == TRUE)
@@ -36,12 +36,6 @@
qdel(src)
return
matter = material.get_matter()
if(matter.len)
for(var/material_type in matter)
if(!isnull(matter[material_type]))
matter[material_type] *= force_divisor // May require a new var instead.
/obj/item/material/should_equip()
return TRUE
@@ -85,6 +79,11 @@
START_PROCESSING(SSprocessing, src)
update_force()
matter = material.get_matter()
for(var/material_type in matter)
if(!isnull(matter[material_type]))
matter[material_type] *= force_divisor // May require a new var instead.
/obj/item/material/Destroy()
STOP_PROCESSING(SSprocessing, src)
return ..()