diff --git a/aurorastation.dme b/aurorastation.dme
index 297599441b0..f9e05008aa6 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -100,6 +100,7 @@
#include "code\__DEFINES\ruin_tags.dm"
#include "code\__DEFINES\rust_g.dm"
#include "code\__DEFINES\rust_g_debug.dm"
+#include "code\__DEFINES\rust_g_overrides.dm"
#include "code\__DEFINES\ship_weapons.dm"
#include "code\__DEFINES\shuttle.dm"
#include "code\__DEFINES\singletons.dm"
@@ -165,6 +166,7 @@
#include "code\__HELPERS\overlay.dm"
#include "code\__HELPERS\overmap.dm"
#include "code\__HELPERS\qdel.dm"
+#include "code\__HELPERS\ref.dm"
#include "code\__HELPERS\sanitize_values.dm"
#include "code\__HELPERS\shell.dm"
#include "code\__HELPERS\smart_token_bucket.dm"
diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm
index 66b392d7753..cdcaaf21c3d 100644
--- a/code/__DEFINES/_flags.dm
+++ b/code/__DEFINES/_flags.dm
@@ -3,5 +3,8 @@
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
+// for /datum/var/datum_flags
+#define DF_USE_TAG (1<<0)
+
///Whether /atom/Initialize() has already run for the object
#define INITIALIZED_1 (1<<5)
diff --git a/code/__DEFINES/rust_g_overrides.dm b/code/__DEFINES/rust_g_overrides.dm
new file mode 100644
index 00000000000..57de7d96acd
--- /dev/null
+++ b/code/__DEFINES/rust_g_overrides.dm
@@ -0,0 +1,3 @@
+// RUSTG_OVERRIDE_BUILTINS is not used since the file APIs don't work well over Linux.
+#define url_encode(text) rustg_url_encode("[text]")
+#define url_decode(text) rustg_url_decode("[text]")
diff --git a/code/__HELPERS/ref.dm b/code/__HELPERS/ref.dm
new file mode 100644
index 00000000000..365df03dc88
--- /dev/null
+++ b/code/__HELPERS/ref.dm
@@ -0,0 +1,15 @@
+/**
+ * \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]" : text_ref(thing))
+**/
+/proc/REF(input)
+ if(isdatum(input))
+ var/datum/thing = input
+ if(thing.datum_flags & DF_USE_TAG)
+ if(!thing.tag)
+ stack_trace("A ref was requested of an object with DF_USE_TAG set but no tag: [thing]")
+ thing.datum_flags &= ~DF_USE_TAG
+ else
+ return "\[[url_encode(thing.tag)]\]"
+ return text_ref(input)
diff --git a/code/controllers/subsystems/processing/dcs.dm b/code/controllers/subsystems/processing/dcs.dm
index 0b4f2ef4d12..51cb8b0c4ae 100644
--- a/code/controllers/subsystems/processing/dcs.dm
+++ b/code/controllers/subsystems/processing/dcs.dm
@@ -22,8 +22,6 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
return
. = elements_by_type[element_id] = new eletype
-///Temporary compatibility to not rewrite the proc, it is being ported already in another PR
-#define REF(k) ref(##k)
/****
* Generates an id for bespoke elements when given the argument list
* Generating the id here is a bit complex because we need to support named arguments
@@ -66,4 +64,3 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
named_arguments = sortList(named_arguments)
fullid += named_arguments
return list2params(fullid)
-#undef REF
diff --git a/code/controllers/subsystems/statpanel.dm b/code/controllers/subsystems/statpanel.dm
index 5dfe51087fb..49d9827488c 100644
--- a/code/controllers/subsystems/statpanel.dm
+++ b/code/controllers/subsystems/statpanel.dm
@@ -125,7 +125,7 @@ SUBSYSTEM_DEF(statpanels)
/datum/controller/subsystem/statpanels/proc/set_SDQL2_tab(client/target)
var/list/sdql2A = list()
- sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", ref(GLOB.sdql2_vv_statobj))
+ sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
var/list/sdql2B = list()
for(var/datum/sdql2_query/query as anything in GLOB.sdql2_queries)
sdql2B = query.generate_stat()
@@ -219,7 +219,7 @@ SUBSYSTEM_DEF(statpanels)
continue
// We already have it. Success!
if(existing_image)
- turf_items[++turf_items.len] = list("[turf_item.name]", ref(turf_item), existing_image)
+ turf_items[++turf_items.len] = list("[turf_item.name]", REF(turf_item), existing_image)
continue
// Now, we're gonna queue image generation out of those refs
to_make += turf_item
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index eb0e9e9a28e..9b63cd80c89 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -24,6 +24,9 @@
/// Set to true when a signal has been registered
var/signal_enabled = FALSE
+ /// Datum level flags
+ var/datum_flags = NONE
+
/// A weak reference to another datum
var/datum/weakref/weak_reference
@@ -48,6 +51,7 @@
//SHOULD_NOT_SLEEP(TRUE) //Soon my friend, soon...
tag = null
+ datum_flags &= ~DF_USE_TAG //In case something tries to REF us
weak_reference = null //ensure prompt GCing of weakref.
if(active_timers)
@@ -138,6 +142,12 @@
vars[var_name] = var_value
return TRUE
+///Generate a tag for this /datum, if it implements one
+///Should be called as early as possible, best would be in New, to avoid weakref mistargets
+///Really just don't use this, you don't need it, global lists will do just fine MOST of the time
+///We really only use it for mobs to make id'ing people easier
+/datum/proc/GenerateTag()
+ datum_flags |= DF_USE_TAG
/// Return text from this proc to provide extra context to hard deletes that happen to it
/// Optional, you should use this for cases where replication is difficult and extra context is required
diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm
index 911623ff4c2..490d3bfbfeb 100644
--- a/code/datums/weakrefs.dm
+++ b/code/datums/weakrefs.dm
@@ -56,7 +56,7 @@
var/reference
/datum/weakref/New(datum/thing)
- reference = text_ref(thing)
+ reference = REF(thing)
/datum/weakref/Destroy(force)
var/datum/target = resolve()
diff --git a/code/modules/admin/verbs/SDQL_2.dm b/code/modules/admin/verbs/SDQL_2.dm
index 8b82ee6a6ab..cb59138ccf5 100644
--- a/code/modules/admin/verbs/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL_2.dm
@@ -431,8 +431,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null
L[++L.len] = list("[id] ", "[delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
[islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\
[islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\
- [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", ref(delete_click))
- L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", ref(action_click))
+ [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", REF(delete_click))
+ L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
return L
/datum/sdql2_query/proc/delete_click()
@@ -696,7 +696,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null
obj_count_finished = select_refs
for(var/i in found)
SDQL_print(i, text_list, print_nulls)
- select_refs[ref(i)] = TRUE
+ select_refs[REF(i)] = TRUE
SDQL2_TICK_CHECK
SDQL2_HALT_CHECK
select_text = text_list
@@ -717,7 +717,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null
/datum/sdql2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE)
if(isdatum(object))
- text_list += "[ref(object)] : [object]"
+ text_list += "[REF(object)] : [object]"
if(istype(object, /atom))
var/atom/A = object
var/turf/T = A.loc
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index fd513013e21..0ad321e8077 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -45,6 +45,10 @@
return ..()
+/mob/New()
+ // This needs to happen IMMEDIATELY. I'm sorry :(
+ GenerateTag()
+ return ..()
/mob/proc/remove_screen_obj_references()
flash = null
@@ -87,6 +91,15 @@
become_hearing_sensitive()
+/**
+ * Generate the tag for this mob
+ *
+ * This is simply "mob_"+ a global incrementing counter that goes up for every mob
+ */
+/mob/GenerateTag()
+ . = ..()
+ tag = "mob_[next_mob_id++]"
+
/mob/verb/say_wrapper()
set name = ".Say"
set hidden = TRUE
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 871a8a8b743..888091644a8 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -5,6 +5,7 @@
movable_flags = MOVABLE_FLAG_PROXMOVE
sight = DEFAULT_SIGHT
var/datum/mind/mind
+ var/static/next_mob_id = 0
// we never want to hide a turf because it's not lit
// We can rely on the lighting plane to handle that for us
diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm
index 213bbde9e34..a1d234cce5a 100644
--- a/code/modules/tgui/tgui.dm
+++ b/code/modules/tgui/tgui.dm
@@ -60,7 +60,7 @@
src_object = src_object)
src.user = user
src.src_object = src_object
- src.window_key = "[text_ref(src_object)]-main"
+ src.window_key = "[REF(src_object)]-main"
src.interface = interface
if(title)
src.title = title
diff --git a/code/modules/tgui_panel/tgui_panel.dm b/code/modules/tgui_panel/tgui_panel.dm
index 244c59d0192..f5372fb822b 100644
--- a/code/modules/tgui_panel/tgui_panel.dm
+++ b/code/modules/tgui_panel/tgui_panel.dm
@@ -60,7 +60,7 @@
*/
/datum/tgui_panel/proc/on_initialize_timed_out()
// Currently does nothing but sending a message to old chat.
- to_target(client, "Failed to load fancy chat, click HERE to attempt to reload it.")
+ to_target(client, "Failed to load fancy chat, click HERE to attempt to reload it.")
/**
* private
diff --git a/html/changelogs/fluffyghost-datumflagsrefport.yml b/html/changelogs/fluffyghost-datumflagsrefport.yml
new file mode 100644
index 00000000000..2b3263fb4ea
--- /dev/null
+++ b/html/changelogs/fluffyghost-datumflagsrefport.yml
@@ -0,0 +1,43 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: FluffyGhost
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - backend: "Ported TG's REF proc and relative datum_flags infrastructure."
+ - backend: "Mobs now get assigned an unique tag to reference and track them."
+ - backend: "Updated previous workarounds due to the lack of this, to use this - at least, the ones I found."