diff --git a/code/__DEFINES/_helpers.dm b/code/__DEFINES/_helpers.dm
index 574c4da8dc7..08d4b39906e 100644
--- a/code/__DEFINES/_helpers.dm
+++ b/code/__DEFINES/_helpers.dm
@@ -13,3 +13,10 @@
/// subtypesof(), typesof() without the parent path
#define subtypesof(typepath) ( typesof(typepath) - typepath )
+
+/// Takes a datum as input, returns its ref string, or a cached version of it
+/// This allows us to cache \ref creation, which ensures it'll only ever happen once per datum, saving string tree time
+/// It is slightly less optimal then a []'d datum, but the cost is massively outweighed by the potential savings
+/// It will only work for datums mind, for datum reasons
+/// : because of the embedded typecheck
+#define text_ref(datum) (isdatum(datum) ? (datum:cached_ref ||= "\ref[datum]") : ("\ref[datum]"))
diff --git a/code/__DEFINES/typeids.dm b/code/__DEFINES/typeids.dm
index 275f7719f07..7c69dd29de3 100644
--- a/code/__DEFINES/typeids.dm
+++ b/code/__DEFINES/typeids.dm
@@ -3,6 +3,6 @@
#define TYPEID_NORMAL_LIST "f"
//helper macros
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, -7) ) )
-#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
+#define IS_NORMAL_LIST(L) (GET_TYPEID(text_ref(L)) == TYPEID_NORMAL_LIST)
diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm
index 37c7b753c87..b87f82b77fa 100644
--- a/code/__HELPERS/icons.dm
+++ b/code/__HELPERS/icons.dm
@@ -1181,7 +1181,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
if(isicon(icon) && isfile(icon))
//icons compiled in from 'icons/path/to/dmi_file.dmi' at compile time are weird and arent really /icon objects,
///but they pass both isicon() and isfile() checks. theyre the easiest case since stringifying them gives us the path we want
- var/icon_ref = "\ref[icon]"
+ var/icon_ref = text_ref(icon)
var/locate_icon_string = "[locate(icon_ref)]"
icon_path = locate_icon_string
@@ -1192,7 +1192,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
// the rsc reference returned by fcopy_rsc() will be stringifiable to "icons/path/to/dmi_file.dmi"
var/rsc_ref = fcopy_rsc(icon)
- var/icon_ref = "\ref[rsc_ref]"
+ var/icon_ref = text_ref(rsc_ref)
var/icon_path_string = "[locate(icon_ref)]"
@@ -1202,7 +1202,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
var/rsc_ref = fcopy_rsc(icon)
//if its the text path of an existing dmi file, the rsc reference returned by fcopy_rsc() will be stringifiable to a dmi path
- var/rsc_ref_ref = "\ref[rsc_ref]"
+ var/rsc_ref_ref = text_ref(rsc_ref)
var/rsc_ref_string = "[locate(rsc_ref_ref)]"
icon_path = rsc_ref_string
diff --git a/code/__HELPERS/jatum.dm b/code/__HELPERS/jatum.dm
index d00e6a68642..f11e369007f 100644
--- a/code/__HELPERS/jatum.dm
+++ b/code/__HELPERS/jatum.dm
@@ -42,7 +42,7 @@
"path" = value
)
- var/ref = "\ref[value]"
+ var/ref = text_ref(value)
var/existing_ref = seen_references[ref]
if(existing_ref)
return list(
diff --git a/code/__HELPERS/ref.dm b/code/__HELPERS/ref.dm
index de1ba392b43..365df03dc88 100644
--- a/code/__HELPERS/ref.dm
+++ b/code/__HELPERS/ref.dm
@@ -1,7 +1,7 @@
/**
* \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
* If it ever becomes necesary to get a more performant REF(), this lies here in wait
- * #define REF(thing) (thing && isdatum(thing) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
+ * #define REF(thing) (thing && isdatum(thing) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : text_ref(thing))
**/
/proc/REF(input)
if(isdatum(input))
@@ -12,4 +12,4 @@
thing.datum_flags &= ~DF_USE_TAG
else
return "\[[url_encode(thing.tag)]\]"
- return "\ref[input]"
+ return text_ref(input)
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 3d365d9951d..65c1f5d083d 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -207,7 +207,7 @@ SUBSYSTEM_DEF(garbage)
var/type = D.type
var/datum/qdel_item/I = items[type]
- log_world("## TESTING: GC: -- \ref[D] | [type] was unable to be GC'd --")
+ log_world("## TESTING: GC: -- [text_ref(D)] | [type] was unable to be GC'd --")
#ifdef TESTING
for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage
var/client/admin = c
@@ -249,7 +249,7 @@ SUBSYSTEM_DEF(garbage)
HardDelete(D)
return
var/gctime = world.time
- var/refid = "\ref[D]"
+ var/refid = text_ref(D)
D.gc_destroyed = gctime
var/list/queue = queues[level]
@@ -261,7 +261,7 @@ SUBSYSTEM_DEF(garbage)
++delslasttick
++totaldels
var/type = D.type
- var/refID = "\ref[D]"
+ var/refID = text_ref(D)
var/tick_usage = TICK_USAGE
del(D)
@@ -376,7 +376,7 @@ SUBSYSTEM_DEF(garbage)
D.find_references() //This breaks ci. Consider it insurance against somehow pring reftracking on accident
if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object.
SSgarbage.Queue(D)
- SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
+ SSgarbage.reference_find_on_fail[text_ref(D)] = TRUE
#endif
else
#ifdef TESTING
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index c3be6142a1e..fe39a4e0102 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(mapping)
name = "Mapping"
init_order = INIT_ORDER_MAPPING
- flags = SS_NO_FIRE
+ runlevels = ALL
var/list/nuke_tiles = list()
var/list/nuke_threats = list()
@@ -54,6 +54,8 @@ SUBSYSTEM_DEF(mapping)
var/list/turf/unused_turfs = list() //Not actually unused turfs they're unused but reserved for use for whatever requests them. "[zlevel_of_turf]" = list(turfs)
var/list/datum/turf_reservations //list of turf reservations
var/list/used_turfs = list() //list of turf = datum/turf_reservation
+ /// List of lists of turfs to reserve
+ var/list/lists_to_reserve = list()
var/list/reservation_ready = list()
var/clearing_reserved_turfs = FALSE
@@ -149,6 +151,33 @@ SUBSYSTEM_DEF(mapping)
return SS_INIT_SUCCESS
+/datum/controller/subsystem/mapping/fire(resumed)
+ // Cache for sonic speed
+ var/list/unused_turfs = src.unused_turfs
+ var/list/world_contents = GLOB.areas_by_type[world.area].contents
+ var/list/lists_to_reserve = src.lists_to_reserve
+ var/index = 0
+ while(length(lists_to_reserve))
+ var/list/packet = lists_to_reserve[index + 1]
+ var/packetlen = length(packet)
+ while(packetlen)
+ if(MC_TICK_CHECK)
+ lists_to_reserve.Cut(1, index)
+ return
+ var/turf/T = packet[packetlen]
+ T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE)
+ LAZYINITLIST(unused_turfs["[T.z]"])
+ unused_turfs["[T.z]"] |= T
+ T.flags_1 |= UNUSED_RESERVATION_TURF
+ world_contents += T
+ packet.len--
+ packetlen = length(packet)
+
+ index++
+ // If we're here, we're done with that lad
+ lists_to_reserve.len--
+ lists_to_reserve.Cut(1, index)
+
/datum/controller/subsystem/mapping/proc/calculate_default_z_level_gravities()
for(var/z_level in 1 to length(z_list))
calculate_z_level_gravity(z_level)
@@ -646,15 +675,12 @@ GLOBAL_LIST_EMPTY(the_station_areas)
reservation_ready["[z]"] = TRUE
clearing_reserved_turfs = FALSE
-/datum/controller/subsystem/mapping/proc/reserve_turfs(list/turfs)
- for(var/i in turfs)
- var/turf/T = i
- T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE)
- LAZYINITLIST(unused_turfs["[T.z]"])
- unused_turfs["[T.z]"] |= T
- T.flags_1 |= UNUSED_RESERVATION_TURF
- GLOB.areas_by_type[world.area].contents += T
- CHECK_TICK
+/// Schedules a group of turfs to be handed back to the reservation system's control
+/// If await is true, will sleep until the turfs are finished work
+/datum/controller/subsystem/mapping/proc/reserve_turfs(list/turfs, await = FALSE)
+ lists_to_reserve += list(turfs)
+ if(await)
+ UNTIL(!length(turfs))
//DO NOT CALL THIS PROC DIRECTLY, CALL wipe_reservations().
/datum/controller/subsystem/mapping/proc/do_wipe_turf_reservations()
@@ -672,7 +698,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already.
unused_turfs.Cut()
used_turfs.Cut()
- reserve_turfs(clearing)
+ reserve_turfs(clearing, await = TRUE)
///Initialize all biomes, assoc as type || instance
/datum/controller/subsystem/mapping/proc/initialize_biomes()
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index 816c7943e4b..9ebaf85a63d 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -237,16 +237,16 @@ SUBSYSTEM_DEF(statpanels)
list("CPU:", world.cpu),
list("Instances:", "[num2text(world.contents.len, 10)]"),
list("World Time:", "[world.time]"),
- list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"),
- list("[config]:", config.stat_entry(), "\ref[config]"),
+ list("Globals:", GLOB.stat_entry(), text_ref(GLOB)),
+ list("[config]:", config.stat_entry(), text_ref(config)),
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
- list("Master Controller:", Master.stat_entry(), "\ref[Master]"),
- list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"),
+ list("Master Controller:", Master.stat_entry(), text_ref(Master)),
+ list("Failsafe Controller:", Failsafe.stat_entry(), text_ref(Failsafe)),
list("","")
)
for(var/datum/controller/subsystem/sub_system as anything in Master.subsystems)
- mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]")
- mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", "\ref[GLOB.cameranet]")
+ mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), text_ref(sub_system))
+ mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", text_ref(GLOB.cameranet))
///immediately update the active statpanel tab of the target client
/datum/controller/subsystem/statpanels/proc/immediate_send_stat_data(client/target)
diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm
index 451793f5b9e..7efd2680c04 100644
--- a/code/controllers/subsystem/timer.dm
+++ b/code/controllers/subsystem/timer.dm
@@ -505,8 +505,8 @@ SUBSYSTEM_DEF(timer)
/datum/timedevent/proc/bucketJoin()
// Generate debug-friendly name for timer
var/static/list/bitfield_flags = list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")
- name = "Timer: [id] (\ref[src]), TTR: [timeToRun], wait:[wait] Flags: [jointext(bitfield_to_list(flags, bitfield_flags), ", ")], \
- callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), \
+ name = "Timer: [id] ([text_ref(src)]), TTR: [timeToRun], wait:[wait] Flags: [jointext(bitfield_to_list(flags, bitfield_flags), ", ")], \
+ callBack: [text_ref(callBack)], callBack.object: [callBack.object][text_ref(callBack.object)]([getcallingtype()]), \
callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""]), source: [source]"
if (bucket_joined)
diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm
index ddda44bbbbb..1afe1c62100 100644
--- a/code/controllers/subsystem/vis_overlays.dm
+++ b/code/controllers/subsystem/vis_overlays.dm
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(vis_overlays)
else
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
overlay.cache_expiration = -1
- var/cache_id = "\ref[overlay]@{[world.time]}"
+ var/cache_id = "[text_ref(overlay)]@{[world.time]}"
vis_overlay_cache[cache_id] = overlay
. = overlay
thing.vis_contents += overlay
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index 8cc88b9dc53..12b9d3d9655 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -40,6 +40,11 @@
/// Datum level flags
var/datum_flags = NONE
+ /// A cached version of our \ref
+ /// The brunt of \ref costs are in creating entries in the string tree (a tree of immutable strings)
+ /// This avoids doing that more then once per datum by ensuring ref strings always have a reference to them after they're first pulled
+ var/cached_ref
+
/// A weak reference to another datum
var/datum/weakref/weak_reference
diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm
index 0438d514195..f02183eab90 100644
--- a/code/datums/position_point_vector.dm
+++ b/code/datums/position_point_vector.dm
@@ -23,7 +23,7 @@
return ATAN2((b.y - a.y), (b.x - a.x))
/// For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
-/datum/position
+/datum/position
var/x = 0
var/y = 0
var/z = 0
@@ -68,7 +68,7 @@
return new /datum/point(src)
/// A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
-/datum/point
+/datum/point
var/x = 0
var/y = 0
var/z = 0
@@ -83,7 +83,7 @@
return p
/// First argument can also be a /datum/position or /atom.
-/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0)
+/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0)
if(istype(_x, /datum/position))
var/datum/position/P = _x
_x = P.x
@@ -110,7 +110,7 @@
/datum/point/proc/debug_out()
var/turf/T = return_turf()
- return "\ref[src] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]"
+ return "[text_ref(src)] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]"
/datum/point/proc/move_atom_to_src(atom/movable/AM)
AM.forceMove(return_turf())
@@ -134,11 +134,11 @@
/datum/point/vector
/// Pixels per iteration
- var/speed = 32
+ var/speed = 32
var/iteration = 0
var/angle = 0
/// Calculated x movement amounts to prevent having to do trig every step.
- var/mpx = 0
+ var/mpx = 0
/// Calculated y movement amounts to prevent having to do trig every step.
var/mpy = 0
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
@@ -158,7 +158,7 @@
starting_z = z
/// Same effect as initiliaze_location, but without setting the starting_x/y/z
-/datum/point/vector/proc/set_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
+/datum/point/vector/proc/set_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
if(!isnull(tile_x))
x = ((tile_x - 1) * world.icon_size) + world.icon_size * 0.5 + p_x + 1
if(!isnull(tile_y))
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 62fa9f467df..63be0696780 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -191,23 +191,23 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
/datum/game_mode/dynamic/admin_panel()
var/list/dat = list("
Game Mode PanelGame Mode Panel
")
- dat += "Dynamic Mode \[VV\] \[Refresh\]
"
+ dat += "Dynamic Mode \[VV\] \[Refresh\]
"
dat += "Threat Level: [threat_level]
"
dat += "Budgets (Roundstart/Midrounds): [initial_round_start_budget]/[threat_level - initial_round_start_budget]
"
- dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
"
+ dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
"
dat += "
"
dat += "Parameters: centre = [threat_curve_centre] ; width = [threat_curve_width].
"
dat += "Split parameters: centre = [roundstart_split_curve_centre] ; width = [roundstart_split_curve_width].
"
dat += "On average, [peaceful_percentage]% of the rounds are more peaceful.
"
- dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
"
- dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
"
- dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]"
+ dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
"
+ dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
"
+ dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]"
dat += "
"
- dat += "\[Force Next Latejoin Ruleset\]
"
+ dat += "\[Force Next Latejoin Ruleset\]
"
if (forced_latejoin_rule)
- dat += {"-> [forced_latejoin_rule.name] <-
"}
- dat += "\[Execute Midround Ruleset\]
"
+ dat += {"-> [forced_latejoin_rule.name] <-
"}
+ dat += "\[Execute Midround Ruleset\]
"
dat += "
"
dat += "Executed rulesets: "
if (executed_rules.len > 0)
@@ -217,13 +217,13 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
else
dat += "none.
"
dat += "
Injection Timers: ([get_heavy_midround_injection_chance(dry_run = TRUE)]% heavy midround chance)
"
- dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] \[Now!\]
"
+ dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] \[Now!\]
"
var/next_injection = next_midround_injection()
if (next_injection == INFINITY)
dat += "All midrounds have been exhausted."
else
- dat += "Midround: [DisplayTimeText(next_injection - world.time)] \[Now!\]
"
+ dat += "Midround: [DisplayTimeText(next_injection - world.time)] \[Now!\]
"
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm
index 629e72ad9d7..a4cf5dfa465 100644
--- a/code/game/objects/effects/decals/decal.dm
+++ b/code/game/objects/effects/decals/decal.dm
@@ -37,20 +37,29 @@
layer = TURF_DECAL_LAYER
anchored = TRUE
+// This is with the intent of optimizing mapload
+// See spawners for more details since we use the same pattern
+// Basically rather then creating and deleting ourselves, why not just do the bare minimum?
/obj/effect/turf_decal/Initialize(mapload)
- . = ..()
+ SHOULD_CALL_PARENT(FALSE)
+ if(flags_1 & INITIALIZED_1)
+ stack_trace("Warning: [src]([type]) initialized multiple times!")
+ flags_1 |= INITIALIZED_1
+
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
T.AddElement(/datum/element/decal, icon, icon_state, dir, null, null, alpha, color, null, FALSE, null)
return INITIALIZE_HINT_QDEL
+/obj/effect/turf_decal/Destroy(force)
+ SHOULD_CALL_PARENT(FALSE)
#ifdef UNIT_TESTS
// If we don't do this, turf decals will end up stacking up on a tile, and break the overlay limit
// I hate it too bestie
-/obj/effect/turf_decal/Destroy()
if(GLOB.running_create_and_destroy)
var/turf/T = loc
T.RemoveElement(/datum/element/decal, icon, icon_state, dir, null, null, alpha, color, null, FALSE, null)
- return ..()
#endif
+ moveToNullspace()
+ return QDEL_HINT_QUEUE
diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm
index 6be05751ce0..cbd96e74ff9 100644
--- a/code/game/objects/effects/misc.dm
+++ b/code/game/objects/effects/misc.dm
@@ -21,6 +21,23 @@
/obj/effect/spawner
name = "object spawner"
+// Brief explanation:
+// Rather then setting up and then deleting spawners, we block all atomlike setup
+// and do the absolute bare minimum
+// This is with the intent of optimizing mapload
+/obj/effect/spawner/Initialize(mapload)
+ SHOULD_CALL_PARENT(FALSE)
+ if(flags_1 & INITIALIZED_1)
+ stack_trace("Warning: [src]([type]) initialized multiple times!")
+ flags_1 |= INITIALIZED_1
+
+ return INITIALIZE_HINT_QDEL
+
+/obj/effect/spawner/Destroy(force)
+ SHOULD_CALL_PARENT(FALSE)
+ moveToNullspace()
+ return QDEL_HINT_QUEUE
+
/obj/effect/list_container
name = "list container"
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index 64fc60062e6..9d1da48cd29 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -6,16 +6,16 @@
name = "bomb"
icon = 'icons/hud/screen_gen.dmi'
icon_state = "x"
- /* Gasmixes for tank_one and tank_two of the ttv respectively.
+ /* Gasmixes for tank_one and tank_two of the ttv respectively.
* Populated on /obj/effect/spawner/newbomb/Initialize, depopulated right after by the children procs.
*/
var/datum/gas_mixture/first_gasmix
var/datum/gas_mixture/second_gasmix
-/**
+/**
* The part of code that actually spawns the bomb. Always call the parent's initialize first for subtypes of these.
*
- * Arguments:
+ * Arguments:
* * assembly - An assembly typepath to add to the ttv.
*/
/obj/effect/spawner/newbomb/Initialize(mapload, assembly = null)
@@ -33,7 +33,6 @@
newassembly.on_attach()
newassembly.holder = ttv
ttv.update_appearance()
- return INITIALIZE_HINT_QDEL
/obj/effect/spawner/newbomb/proc/calculate_pressure(datum/gas_mixture/gasmix, pressure)
return pressure * gasmix.volume/(R_IDEAL_GAS_EQUATION*gasmix.temperature)
@@ -85,7 +84,7 @@
first_gasmix.assert_gas(/datum/gas/hypernoblium)
first_gasmix.assert_gas(/datum/gas/tritium)
second_gasmix.assert_gas(/datum/gas/oxygen)
-
+
first_gasmix.gases[/datum/gas/hypernoblium][MOLES] = REACTION_OPPRESSION_THRESHOLD - 0.01
first_gasmix.gases[/datum/gas/tritium][MOLES] = 0.5 * calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)
second_gasmix.gases[/datum/gas/oxygen][MOLES] = calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE-1)
diff --git a/code/game/objects/effects/spawners/costume.dm b/code/game/objects/effects/spawners/costume.dm
index 187004aba39..a32a2c33f5b 100644
--- a/code/game/objects/effects/spawners/costume.dm
+++ b/code/game/objects/effects/spawners/costume.dm
@@ -7,11 +7,10 @@
var/list/items
/obj/effect/spawner/costume/Initialize(mapload)
- ..()
+ . = ..()
if(items?.len)
for(var/path in items)
new path(loc)
- return INITIALIZE_HINT_QDEL
/obj/effect/spawner/costume/chicken
name = "chicken costume spawner"
diff --git a/code/game/objects/effects/spawners/random/entertainment.dm b/code/game/objects/effects/spawners/random/entertainment.dm
index 22d5f681edf..d7378314636 100644
--- a/code/game/objects/effects/spawners/random/entertainment.dm
+++ b/code/game/objects/effects/spawners/random/entertainment.dm
@@ -238,8 +238,7 @@
/obj/effect/spawner/random/entertainment/toy/Initialize(mapload)
loot += GLOB.arcade_prize_pool
- . = ..()
- return INITIALIZE_HINT_QDEL
+ return ..()
/obj/effect/spawner/random/entertainment/plushie
name = "plushie spawner"
diff --git a/code/game/objects/effects/spawners/random/maintenance.dm b/code/game/objects/effects/spawners/random/maintenance.dm
index 8652bc3c5d0..5481123bbff 100644
--- a/code/game/objects/effects/spawners/random/maintenance.dm
+++ b/code/game/objects/effects/spawners/random/maintenance.dm
@@ -10,8 +10,7 @@
/obj/effect/spawner/random/maintenance/Initialize(mapload)
loot = GLOB.maintenance_loot
-
- . = ..()
+ return ..()
/obj/effect/spawner/random/maintenance/proc/hide()
invisibility = INVISIBILITY_OBSERVER
diff --git a/code/game/objects/effects/spawners/random/random.dm b/code/game/objects/effects/spawners/random/random.dm
index 5cf8ba0506a..ece6656b4fa 100644
--- a/code/game/objects/effects/spawners/random/random.dm
+++ b/code/game/objects/effects/spawners/random/random.dm
@@ -13,8 +13,6 @@
var/loot_type_path
/// The subtypes (this excludes the provided path) to combine with the loot list
var/loot_subtype_path
- /// Whether the spawner should immediately spawn loot and cleanup on Initialize()
- var/spawn_on_init = TRUE
/// How many items will be spawned
var/spawn_loot_count = 1
/// If the same item can be spawned twice
@@ -32,14 +30,7 @@
/obj/effect/spawner/random/Initialize(mapload)
. = ..()
-
- if(should_spawn_on_init())
- spawn_loot()
- return INITIALIZE_HINT_QDEL
-
-/// Helper proc that returns TRUE if the spawner should spawn loot in Initialise() and FALSE otherwise. Override this to change spawning behaviour.
-/obj/effect/spawner/random/proc/should_spawn_on_init()
- return spawn_on_init
+ spawn_loot()
///If the spawner has any loot defined, randomly picks some and spawns it. Does not cleanup the spawner.
/obj/effect/spawner/random/proc/spawn_loot(lootcount_override)
diff --git a/code/game/objects/effects/spawners/structure.dm b/code/game/objects/effects/spawners/structure.dm
index 86b4a5868ae..a523cd00720 100644
--- a/code/game/objects/effects/spawners/structure.dm
+++ b/code/game/objects/effects/spawners/structure.dm
@@ -10,13 +10,9 @@ again.
/obj/effect/spawner/structure/Initialize(mapload)
. = ..()
-
for(var/spawn_type in spawn_list)
new spawn_type(loc)
- return INITIALIZE_HINT_QDEL
-
-
//normal windows
/obj/effect/spawner/structure/window
diff --git a/code/game/objects/effects/spawners/xeno_egg_delivery.dm b/code/game/objects/effects/spawners/xeno_egg_delivery.dm
index 75d5a26612d..395d1454e0d 100644
--- a/code/game/objects/effects/spawners/xeno_egg_delivery.dm
+++ b/code/game/objects/effects/spawners/xeno_egg_delivery.dm
@@ -5,7 +5,7 @@
var/announcement_time = 1200
/obj/effect/spawner/xeno_egg_delivery/Initialize(mapload)
- ..()
+ . = ..()
var/turf/T = get_turf(src)
new /obj/structure/alien/egg(T)
@@ -16,4 +16,3 @@
log_game("An alien egg has been delivered to [AREACOORD(T)]")
var/message = "Attention [station_name()], we have entrusted you with a research specimen in [get_area_name(T, TRUE)]. Remember to follow all safety precautions when dealing with the specimen."
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/_addtimer, CALLBACK(GLOBAL_PROC, /proc/print_command_report, message), announcement_time))
- return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm
index 346b3c12e45..dccef7514fc 100644
--- a/code/game/objects/items/AI_modules/_AI_modules.dm
+++ b/code/game/objects/items/AI_modules/_AI_modules.dm
@@ -167,17 +167,16 @@
color = "#00FF00"
/obj/effect/spawner/round_default_module/Initialize(mapload)
- ..()
+ . = ..()
var/datum/ai_laws/default_laws = get_round_default_lawset()
//try to spawn a law board, since they may have special functionality (asimov setting subjects)
for(var/obj/item/ai_module/core/full/potential_lawboard as anything in subtypesof(/obj/item/ai_module/core/full))
if(initial(potential_lawboard.law_id) != initial(default_laws.id))
continue
potential_lawboard = new potential_lawboard(loc)
- return INITIALIZE_HINT_QDEL
+ return
//spawn the fallback instead
new /obj/item/ai_module/core/round_default_fallback(loc)
- return INITIALIZE_HINT_QDEL
///When the default lawset spawner cannot find a module object to spawn, it will spawn this, and this sets itself to the round default.
///This is so /datum/lawsets can be picked even if they have no module for themselves.
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 985fbfb19c5..45a7cc5ea0d 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -232,7 +232,7 @@
"res_amount" = R.res_amount,
"max_res_amount" = R.max_res_amount,
"req_amount" = R.req_amount,
- "ref" = "\ref[R]",
+ "ref" = text_ref(R),
)
/**
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2af98275724..fdaaa615a17 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -24,7 +24,7 @@
dat += "(Force Roundstart Rulesets)
"
if (GLOB.dynamic_forced_roundstart_ruleset.len > 0)
for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset)
- dat += {"-> [rule.name] <-
"}
+ dat += {"-> [rule.name] <-
"}
dat += "(Clear Rulesets)
"
dat += "(Dynamic mode options)
"
dat += "
"
diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm
index 20de4bfcf58..c96253381b9 100644
--- a/code/modules/admin/sound_emitter.dm
+++ b/code/modules/admin/sound_emitter.dm
@@ -58,16 +58,16 @@
/obj/effect/sound_emitter/proc/edit_emitter(mob/user)
var/dat = ""
- dat += "Label: [maptext ? maptext : "No label set!"]
"
+ dat += "Label: [maptext ? maptext : "No label set!"]
"
dat += "
"
- dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
"
- dat += "Volume: [sound_volume]%
"
+ dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
"
+ dat += "Volume: [sound_volume]%
"
dat += "
"
- dat += "Mode: [motus_operandi]
"
+ dat += "Mode: [motus_operandi]
"
if(motus_operandi != SOUND_EMITTER_LOCAL)
- dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
"
+ dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
"
dat += "
"
- dat += "Play Sound (interrupts other sound emitter sounds)"
+ dat += "Play Sound (interrupts other sound emitter sounds)"
var/datum/browser/popup = new(user, "emitter", "", 500, 600)
popup.set_content(dat)
popup.open()
diff --git a/code/modules/admin/verbs/lua/lua_editor.dm b/code/modules/admin/verbs/lua/lua_editor.dm
index 0754f10902c..9e0fb17f86a 100644
--- a/code/modules/admin/verbs/lua/lua_editor.dm
+++ b/code/modules/admin/verbs/lua/lua_editor.dm
@@ -20,7 +20,7 @@
. = ..()
if(state)
current_state = state
- LAZYADDASSOCLIST(SSlua.editors, "\ref[current_state]", src)
+ LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
/datum/lua_editor/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -32,7 +32,7 @@
/datum/lua_editor/Destroy(force, ...)
. = ..()
if(current_state)
- LAZYREMOVEASSOC(SSlua.editors, "\ref[current_state]", src)
+ LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
/datum/lua_editor/ui_state(mob/user)
return GLOB.debug_state
@@ -107,16 +107,16 @@
return TRUE
var/datum/lua_state/new_state = new(state_name)
SSlua.states += new_state
- LAZYREMOVEASSOC(SSlua.editors, "\ref[current_state]", src)
+ LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
current_state = new_state
- LAZYADDASSOCLIST(SSlua.editors, "\ref[current_state]", src)
+ LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
page = 0
return TRUE
if("switchState")
var/state_index = params["index"]
- LAZYREMOVEASSOC(SSlua.editors, "\ref[current_state]", src)
+ LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
current_state = SSlua.states[state_index]
- LAZYADDASSOCLIST(SSlua.editors, "\ref[current_state]", src)
+ LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
page = 0
return TRUE
if("runCode")
diff --git a/code/modules/admin/verbs/lua/lua_state.dm b/code/modules/admin/verbs/lua/lua_state.dm
index a647a4ae587..64805917201 100644
--- a/code/modules/admin/verbs/lua/lua_state.dm
+++ b/code/modules/admin/verbs/lua/lua_state.dm
@@ -95,7 +95,7 @@ GLOBAL_PROTECT(lua_usr)
var/datum/weakref/weak_ref = path_element
var/resolved = weak_ref.hard_resolve()
if(!resolved)
- return list("status" = "errored", "param" = "Weakref in function path ([weak_ref] \ref[weak_ref]) resolved to null.", "name" = jointext(function, "."))
+ return list("status" = "errored", "param" = "Weakref in function path ([weak_ref] [text_ref(weak_ref)]) resolved to null.", "name" = jointext(function, "."))
new_function_path += resolved
else
new_function_path += path_element
@@ -163,7 +163,7 @@ GLOBAL_PROTECT(lua_usr)
__lua_kill_task(internal_id, task_info)
/datum/lua_state/proc/update_editors()
- var/list/editor_list = LAZYACCESS(SSlua.editors, "\ref[src]")
+ var/list/editor_list = LAZYACCESS(SSlua.editors, text_ref(src))
if(editor_list)
for(var/datum/lua_editor/editor as anything in editor_list)
SStgui.update_uis(editor)
diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm
index 2339f06b81d..46c073de185 100644
--- a/code/modules/admin/view_variables/reference_tracking.dm
+++ b/code/modules/admin/view_variables/reference_tracking.dm
@@ -104,11 +104,11 @@
found_refs[varname] = TRUE
continue //End early, don't want these logging
#endif
- log_reftracker("Found [type] \ref[src] in [datum_container.type]'s \ref[datum_container] [varname] var. [container_name]")
+ log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [text_ref(datum_container)] [varname] var. [container_name]")
continue
if(islist(variable))
- DoSearchVar(variable, "[container_name] \ref[datum_container] -> [varname] (list)", recursive_limit - 1, search_time)
+ DoSearchVar(variable, "[container_name] [text_ref(datum_container)] -> [varname] (list)", recursive_limit - 1, search_time)
else if(islist(potential_container))
var/normal = IS_NORMAL_LIST(potential_container)
@@ -124,7 +124,7 @@
found_refs[potential_cache] = TRUE
continue //End early, don't want these logging
#endif
- log_reftracker("Found [type] \ref[src] in list [container_name].")
+ log_reftracker("Found [type] [text_ref(src)] in list [container_name].")
continue
var/assoc_val = null
@@ -137,7 +137,7 @@
found_refs[potential_cache] = TRUE
continue //End early, don't want these logging
#endif
- log_reftracker("Found [type] \ref[src] in list [container_name]\[[element_in_list]\]")
+ log_reftracker("Found [type] [text_ref(src)] in list [container_name]\[[element_in_list]\]")
continue
//We need to run both of these checks, since our object could be hiding in either of them
//Check normal sublists
@@ -151,7 +151,7 @@
thing_to_del.qdel_and_find_ref_if_fail(force)
/datum/proc/qdel_and_find_ref_if_fail(force = FALSE)
- SSgarbage.reference_find_on_fail["\ref[src]"] = TRUE
+ SSgarbage.reference_find_on_fail[text_ref(src)] = TRUE
qdel(src, force)
#endif
diff --git a/code/modules/asset_cache/assets/vending.dm b/code/modules/asset_cache/assets/vending.dm
index 01a6afcf524..574836f0c12 100644
--- a/code/modules/asset_cache/assets/vending.dm
+++ b/code/modules/asset_cache/assets/vending.dm
@@ -20,11 +20,11 @@
var/icon_states_string
for (var/an_icon_state in icon_states_list)
if (!icon_states_string)
- icon_states_string = "[json_encode(an_icon_state)](\ref[an_icon_state])"
+ icon_states_string = "[json_encode(an_icon_state)]([text_ref(an_icon_state)])"
else
- icon_states_string += ", [json_encode(an_icon_state)](\ref[an_icon_state])"
+ icon_states_string += ", [json_encode(an_icon_state)]([text_ref(an_icon_state)])"
- stack_trace("[item] does not have a valid icon state, icon=[icon_file], icon_state=[json_encode(icon_state)](\ref[icon_state]), icon_states=[icon_states_string]")
+ stack_trace("[item] does not have a valid icon state, icon=[icon_file], icon_state=[json_encode(icon_state)]([text_ref(icon_state)]), icon_states=[icon_states_string]")
continue
#endif
diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm
index e5c096d8d9e..5fb5feda3f1 100644
--- a/code/modules/events/holiday/xmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -55,14 +55,12 @@
var/christmas_tree = /obj/structure/flora/tree/pine/xmas/presents
/obj/effect/spawner/xmastree/Initialize(mapload)
- ..()
+ . = ..()
if((CHRISTMAS in SSevents.holidays) && christmas_tree)
new christmas_tree(get_turf(src))
else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
new festive_tree(get_turf(src))
- return INITIALIZE_HINT_QDEL
-
/obj/effect/spawner/xmastree/rdrod
name = "festivus pole spawner"
festive_tree = /obj/structure/festivus
diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm
index e426925fb09..4658edd71ec 100644
--- a/code/modules/language/language_holder.dm
+++ b/code/modules/language/language_holder.dm
@@ -55,7 +55,7 @@ Key procs
/// Initializes, and copies in the languages from the current atom if available.
/datum/language_holder/New(atom/_owner)
if(_owner && QDELETED(_owner))
- CRASH("Langauge holder added to a qdeleting thing, what the fuck \ref[_owner]")
+ CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(_owner)]")
owner = _owner
if(istype(owner, /datum/mind))
var/datum/mind/M = owner
diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm
index 4d4c6b34daa..e85d09aa800 100644
--- a/code/modules/mapping/space_management/space_reservation.dm
+++ b/code/modules/mapping/space_management/space_reservation.dm
@@ -14,11 +14,11 @@
turf_type = /turf/open/space/transit
/datum/turf_reservation/proc/Release()
- var/v = reserved_turfs.Copy()
- for(var/i in reserved_turfs)
- reserved_turfs -= i
- SSmapping.used_turfs -= i
- INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/proc/reserve_turfs, v)
+ var/list/reserved_copy = reserved_turfs.Copy()
+ SSmapping.used_turfs -= reserved_turfs
+ reserved_turfs = list()
+ // Makes the linter happy, even tho we don't await this
+ INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/proc/reserve_turfs, reserved_copy)
/datum/turf_reservation/proc/Reserve(width, height, zlevel)
if(width > world.maxx || height > world.maxy || width < 1 || height < 1)