diff --git a/SpacemanDMM.toml b/SpacemanDMM.toml
index ec6f5ef068f..af773c3ab00 100644
--- a/SpacemanDMM.toml
+++ b/SpacemanDMM.toml
@@ -36,3 +36,6 @@ hide_invisible = [
smart-cables = false
# With the multitile component and the removal of the gravity gen parts, the gravity generator will fail the render passes
gravity-gen = false
+
+[diagnostics]
+redefined_proc = "error"
diff --git a/code/__DEFINES/_spacemandmm.dm b/__spacemandmm.dm
similarity index 91%
rename from code/__DEFINES/_spacemandmm.dm
rename to __spacemandmm.dm
index 8112a60eaec..237146b7bf3 100644
--- a/code/__DEFINES/_spacemandmm.dm
+++ b/__spacemandmm.dm
@@ -12,6 +12,8 @@
#define PRIVATE_PROC(X) set SpacemanDMM_private_proc = X
/// Protected procs can only be call by things of the same type or subtypes
#define PROTECTED_PROC(X) set SpacemanDMM_protected_proc = X
+ /// Redefinable procs permit multiple declarations of themselves.
+ #define CAN_BE_REDEFINED(X) set SpacemanDMM_can_be_redefined = X
/// Final vars forbid overriding their value by types that inherit it.
#define VAR_FINAL var/SpacemanDMM_final
/// Private vars can only be called by things of exactly the same type
@@ -27,6 +29,7 @@
#define SHOULD_BE_PURE(X)
#define PRIVATE_PROC(X)
#define PROTECTED_PROC(X)
+ #define CAN_BE_REDEFINED(X)
#define VAR_FINAL var
#define VAR_PRIVATE var
#define VAR_PROTECTED var
diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm
index 641fcc941d3..828192403d9 100644
--- a/code/__DEFINES/MC.dm
+++ b/code/__DEFINES/MC.dm
@@ -93,7 +93,7 @@
PreInit();\
ss_id="timer_[#X]";\
}\
-/datum/controller/subsystem/timer/##X/fire() {..() /*just so it shows up on the profiler*/} \
+/datum/controller/subsystem/timer/##X/fire() {CAN_BE_REDEFINED(TRUE); ..() } \
/datum/controller/subsystem/timer/##X
#define MOVEMENT_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/movement/##X);\
diff --git a/code/__DEFINES/_globals.dm b/code/__DEFINES/_globals.dm
index f8066168814..ec7015a81af 100644
--- a/code/__DEFINES/_globals.dm
+++ b/code/__DEFINES/_globals.dm
@@ -4,11 +4,12 @@
##X = ##InitValue;\
gvars_datum_init_order += #X;\
}
-#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { return; }
+#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { CAN_BE_REDEFINED(TRUE); return; }
#ifndef TESTING
#define GLOBAL_PROTECT(X)\
/datum/controller/global_vars/InitGlobal##X(){\
+ CAN_BE_REDEFINED(TRUE);\
..();\
gvars_datum_protected_varlist[#X] = TRUE;\
}
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 2b233bca7d2..f66596e87d8 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -151,6 +151,7 @@
* * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED].
*/
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -161,6 +162,7 @@
* This function should not be called before ..() in [/world/proc/New].
*/
/world/proc/TgsInitializationComplete()
+ CAN_BE_REDEFINED(TRUE)
return
/// Put this at the start of [/world/proc/Topic].
@@ -170,6 +172,7 @@
* Call this as late as possible in [world/proc/Reboot] (BEFORE ..()).
*/
/world/proc/TgsReboot()
+ CAN_BE_REDEFINED(TRUE)
return
// DATUM DEFINITIONS
@@ -207,6 +210,7 @@
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
*/
/datum/tgs_version/proc/Wildcard()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -215,6 +219,7 @@
* other_version - The [/datum/tgs_version] to compare against.
*/
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
+ CAN_BE_REDEFINED(TRUE)
return
/// Represents a merge of a GitHub pull request.
@@ -401,16 +406,19 @@
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMaximumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMinimumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/**
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
*/
/world/proc/TgsAvailable()
+ CAN_BE_REDEFINED(TRUE)
return
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
@@ -422,6 +430,7 @@
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again.
*/
/world/proc/TgsEndProcess()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -431,6 +440,7 @@
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
*/
/world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -440,6 +450,7 @@
* user: The [/datum/tgs_chat_user] to PM.
*/
/world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -449,42 +460,52 @@
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
*/
/world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null)
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the running engine type
/world/proc/TgsEngine()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsInstanceName()
+ CAN_BE_REDEFINED(TRUE)
return
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsRevision()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsSecurityLevel()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVisibility()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsTestMerges()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsChatChannelInfo()
+ CAN_BE_REDEFINED(TRUE)
return
/*
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 2f8fe74348d..4326981358f 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -237,6 +237,7 @@
/// To be removed on step_ conversion.
/// All this work to prevent a second bump.
/atom/movable/Move(atom/newloc, direction, glide_size_override = 0, update_dir = TRUE, momentum_change = TRUE)
+ CAN_BE_REDEFINED(TRUE)
. = FALSE
if(!newloc || newloc == loc)
return
diff --git a/code/game/objects/items/cigs.dm b/code/game/objects/items/cigs.dm
index 8325f22e9d1..c0d5687d6b0 100644
--- a/code/game/objects/items/cigs.dm
+++ b/code/game/objects/items/cigs.dm
@@ -428,7 +428,7 @@ LIGHTERS ARE IN LIGHTERS.DM
icon_state = "death_cig"
butt_type = /obj/item/cigbutt/death
-/obj/item/clothing/mask/cigarette/random/New()
+/obj/item/clothing/mask/cigarette/carcinoma/New()
list_reagents = list("nicotine" = 40, "dnicotine" = 10, pick("carpotoxin", "toxin", "atrazine") = 1)
..()
diff --git a/code/modules/antagonists/_common/antag_exfiltration.dm b/code/modules/antagonists/_common/antag_exfiltration.dm
index d057c71162c..42722e05b3b 100644
--- a/code/modules/antagonists/_common/antag_exfiltration.dm
+++ b/code/modules/antagonists/_common/antag_exfiltration.dm
@@ -225,7 +225,7 @@
icon_state = "flayer_telepad_base"
setup_type = /obj/effect/temp_visual/exfiltration/mindflayer
-/obj/item/wormhole_jaunter/extraction/changeling/show_activation_message(mob/user)
+/obj/item/wormhole_jaunter/extraction/mindflayer/show_activation_message(mob/user)
user.visible_message("[user] sets a strange telepad on the floor. It begins to unfold.",
"You push a button on [src], and watch as it begins to unfold.")
diff --git a/paradise.dme b/paradise.dme
index 9e95ef103e7..aecfceeae50 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -11,6 +11,7 @@
// END_PREFERENCES
// BEGIN_INCLUDE
#include "__odlint.dm"
+#include "__spacemandmm.dm"
#include "_maps\__MAP_DEFINES.dm"
#include "_maps\base_map.dm"
#include "_maps\map_datums.dm"
@@ -25,7 +26,6 @@
#include "code\__DEFINES\_math.dm"
#include "code\__DEFINES\_protection.dm"
#include "code\__DEFINES\_readme.dm"
-#include "code\__DEFINES\_spacemandmm.dm"
#include "code\__DEFINES\_tgs_defines.dm"
#include "code\__DEFINES\_tick.dm"
#include "code\__DEFINES\_versions.dm"