mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-26 09:03:37 +00:00
ELEMENT_DETACH is **not** a requirement to having `Detach` called. Detach is always called when the element itself is destroyed. ELEMENT_DETACH is a flag that when set, makes sure Detach is called when the atom destroys. Sometimes you want this, for instance: ```dm /datum/element/point_of_interest/Detach(datum/target) SSpoints_of_interest.on_poi_element_removed(target) return ..() ``` This Detach cleans up a reference that would have hung if target was destroyed without this being called. However, most uses of Detach are cleaning up signals. Signals are automatically cleaned up when something is destroyed. You do not need ELEMENT_DETACH in this case, and it slows down init. This also includes somewhat more complex stuff, like removing overlays on the source object. It's getting deleted anyway, you don't care! I have removed all uses of ELEMENT_DETACH that seemed superfluous. I have also renamed it to `ELEMENT_DETACH_ON_HOST_DESTROY` to make its purpose more clear, as me and a lot of other maintainers misunderstood what it did, --- An update to this, ELEMENT_DETACH *is* needed for anything that can register to a turf, as turfs do not clear their signals on destroy.
71 lines
2.8 KiB
Plaintext
71 lines
2.8 KiB
Plaintext
/**
|
|
* Adding this element to an atom will have it automatically render an overlay.
|
|
* The overlay can be specified in new as the first paramter; if not set it defaults to rust_overlay's rust_default
|
|
*/
|
|
/datum/element/rust
|
|
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH_ON_HOST_DESTROY // Detach for turfs
|
|
id_arg_index = 2
|
|
/// The rust image itself, since the icon and icon state are only used as an argument
|
|
var/image/rust_overlay
|
|
|
|
/datum/element/rust/Attach(atom/target, rust_icon = 'icons/effects/rust_overlay.dmi', rust_icon_state = "rust_default")
|
|
. = ..()
|
|
if(!isatom(target))
|
|
return COMPONENT_INCOMPATIBLE
|
|
if(!rust_overlay)
|
|
rust_overlay = image(rust_icon, rust_icon_state)
|
|
ADD_TRAIT(target, TRAIT_RUSTY, ELEMENT_TRAIT(type))
|
|
RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_rust_overlay)
|
|
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/handle_examine)
|
|
RegisterSignal(target, list(COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_RUSTSCRAPER)), .proc/secondary_tool_act)
|
|
// Unfortunately registering with parent sometimes doesn't cause an overlay update
|
|
target.update_icon(UPDATE_OVERLAYS)
|
|
|
|
/datum/element/rust/Detach(atom/source)
|
|
. = ..()
|
|
UnregisterSignal(source, COMSIG_ATOM_UPDATE_OVERLAYS)
|
|
UnregisterSignal(source, COMSIG_PARENT_EXAMINE)
|
|
UnregisterSignal(source, list(COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WELDER), COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_RUSTSCRAPER)))
|
|
REMOVE_TRAIT(source, TRAIT_RUSTY, ELEMENT_TRAIT(type))
|
|
source.update_icon(UPDATE_OVERLAYS)
|
|
|
|
/datum/element/rust/proc/handle_examine(datum/source, mob/user, list/examine_text)
|
|
SIGNAL_HANDLER
|
|
examine_text += span_notice("[source] is very rusty, you could probably <i>burn</i> or <i>scrape</i> it off.")
|
|
|
|
/datum/element/rust/proc/apply_rust_overlay(atom/parent_atom, list/overlays)
|
|
SIGNAL_HANDLER
|
|
overlays += rust_overlay
|
|
|
|
/// Because do_after sleeps we register the signal here and defer via an async call
|
|
/datum/element/rust/proc/secondary_tool_act(atom/source, mob/user, obj/item/item)
|
|
SIGNAL_HANDLER
|
|
INVOKE_ASYNC(src, .proc/handle_tool_use, source, user, item)
|
|
return COMPONENT_BLOCK_TOOL_ATTACK
|
|
|
|
/// We call this from secondary_tool_act because we sleep with do_after
|
|
/datum/element/rust/proc/handle_tool_use(atom/source, mob/user, obj/item/item)
|
|
switch(item.tool_behaviour)
|
|
if(TOOL_WELDER)
|
|
if(!item.tool_start_check(user, amount=5))
|
|
return
|
|
|
|
user.balloon_alert(user, "burning off rust...")
|
|
|
|
if(!item.use_tool(source, user, 5 SECONDS))
|
|
return
|
|
user.balloon_alert(user, "burned off rust")
|
|
Detach(source)
|
|
return
|
|
|
|
|
|
if(TOOL_RUSTSCRAPER)
|
|
if(!item.tool_start_check(user))
|
|
return
|
|
user.balloon_alert(user, "scraping off rust...")
|
|
if(!item.use_tool(source, user, 2 SECONDS))
|
|
return
|
|
user.balloon_alert(user, "scraped off rust")
|
|
Detach(source)
|
|
return
|