diff --git a/code/__DEFINES/_globals.dm b/code/__DEFINES/_globals.dm
index e5f5929a9545..8c0c99eefda5 100644
--- a/code/__DEFINES/_globals.dm
+++ b/code/__DEFINES/_globals.dm
@@ -41,6 +41,12 @@
//Create a list global that is initialized as an empty list
#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list())
+// Create a typed list global with an initializer expression
+#define GLOBAL_LIST_INIT_TYPED(X, Typepath, InitValue) GLOBAL_RAW(/list##Typepath/X); GLOBAL_MANAGED(X, InitValue)
+
+// Create a typed list global that is initialized as an empty list
+#define GLOBAL_LIST_EMPTY_TYPED(X, Typepath) GLOBAL_LIST_INIT_TYPED(X, Typepath, list())
+
//Create a typed global with an initializer expression
#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue)
diff --git a/code/__DEFINES/spaceman_dmm.dm b/code/__DEFINES/spaceman_dmm.dm
new file mode 100644
index 000000000000..e590a30ff999
--- /dev/null
+++ b/code/__DEFINES/spaceman_dmm.dm
@@ -0,0 +1,13 @@
+// Interfaces for the SpacemanDMM linter, define'd to nothing when the linter
+// is not in use.
+
+// The SPACEMAN_DMM define is set by the linter and other tooling when it runs.
+#ifdef SPACEMAN_DMM
+ #define RETURN_TYPE(X) set SpacemanDMM_return_type = X
+ #define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X
+ #define UNLINT(X) SpacemanDMM_unlint(X)
+#else
+ #define RETURN_TYPE(X)
+ #define SHOULD_CALL_PARENT(X)
+ #define UNLINT(X) X
+#endif
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 5b95db8073f0..47659a55f969 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -124,6 +124,7 @@
//returns a new list with only atoms that are in typecache L
/proc/typecache_filter_list(list/atoms, list/typecache)
+ RETURN_TYPE(/list)
. = list()
for(var/thing in atoms)
var/atom/A = thing
@@ -131,6 +132,7 @@
. += A
/proc/typecache_filter_list_reverse(list/atoms, list/typecache)
+ RETURN_TYPE(/list)
. = list()
for(var/thing in atoms)
var/atom/A = thing
@@ -257,6 +259,7 @@
//Pick a random element from the list and remove it from the list.
/proc/pick_n_take(list/L)
+ RETURN_TYPE(L[_].type)
if(L.len)
var/picked = rand(1,L.len)
. = L[picked]
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index f76e4322b0cb..d685ef9e46e2 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -7,7 +7,7 @@
#define WRITE_LOG(log, text) rustg_log_write(log, text)
//print a warning message to world.log
-#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
+#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].")
/proc/warning(msg)
msg = "## WARNING: [msg]"
log_world(msg)
diff --git a/code/_globalvars/genetics.dm b/code/_globalvars/genetics.dm
index 4582fe0a9a57..bdf53f3d71c7 100644
--- a/code/_globalvars/genetics.dm
+++ b/code/_globalvars/genetics.dm
@@ -1,9 +1,9 @@
//faster than having to constantly loop for them
-GLOBAL_LIST_EMPTY(all_mutations) //type = initialized mutation
+GLOBAL_LIST_EMPTY_TYPED(all_mutations, /datum/mutation/human) //type = initialized mutation
GLOBAL_LIST_EMPTY(full_sequences) //type = correct sequence
GLOBAL_LIST_EMPTY(bad_mutations) //bad initialized mutations
GLOBAL_LIST_EMPTY(good_mutations) //good initialized mutations
GLOBAL_LIST_EMPTY(not_good_mutations) //neutral initialized mutations
GLOBAL_LIST_EMPTY(alias_mutations) //alias = type
-GLOBAL_LIST_EMPTY(mutation_recipes)
\ No newline at end of file
+GLOBAL_LIST_EMPTY(mutation_recipes)
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index dd89b844030f..24415cdd700f 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -47,6 +47,6 @@ GLOBAL_LIST_EMPTY(vr_spawnpoints)
//used by jump-to-area etc. Updated by area/updateName()
GLOBAL_LIST_EMPTY(sortedAreas)
/// An association from typepath to area instance. Only includes areas with `unique` set.
-GLOBAL_LIST_EMPTY(areas_by_type)
+GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
GLOBAL_LIST_EMPTY(all_abstract_markers)
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 349ba560eb54..f2639e87b6b6 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(job)
flags = SS_NO_FIRE
var/list/occupations = list() //List of all jobs
- var/list/name_occupations = list() //Dict of all jobs, keys are titles
+ var/list/datum/job/name_occupations = list() //Dict of all jobs, keys are titles
var/list/type_occupations = list() //Dict of all jobs, keys are types
var/list/unassigned = list() //Players who need jobs
var/initial_players_to_assign = 0 //used for checking against population caps
@@ -360,7 +360,7 @@ SUBSYSTEM_DEF(job)
if(!GiveRandomJob(player))
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
-
+
return validate_required_jobs(required_jobs)
/datum/controller/subsystem/job/proc/validate_required_jobs(list/required_jobs)
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index fbe94cbb9ee3..f938a7030881 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -184,6 +184,7 @@
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
/datum/proc/GetComponent(datum/component/c_type)
+ RETURN_TYPE(c_type)
if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED)
stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]")
var/list/dc = datum_components
diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm
index 2012d32178ed..8f94da2f4533 100644
--- a/code/datums/components/crafting/crafting.dm
+++ b/code/datums/components/crafting/crafting.dm
@@ -299,7 +299,7 @@
Deletion.Cut(Deletion.len)
qdel(DL)
-/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/crafting/image, location, control, params, user)
+/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user)
if(user == parent)
ui_interact(user)
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index ea1d672fa2ca..c23e84456355 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -657,14 +657,14 @@ Code:
if("botlist")
active_bot = null
if("summon") //Args are in the correct order, they are stated here just as an easy reminder.
- active_bot.bot_control(command= "summon", user_turf= get_turf(usr), user_access= host_pda.GetAccess())
+ active_bot.bot_control("summon", usr, host_pda.GetAccess())
else //Forward all other bot commands to the bot itself!
- active_bot.bot_control(command= href_list["op"], user= usr)
+ active_bot.bot_control(href_list["op"], usr)
if(href_list["mule"]) //MULEbots are special snowflakes, and need different args due to how they work.
var/mob/living/simple_animal/bot/mulebot/mule = active_bot
if (istype(mule))
- mule.bot_control(command=href_list["mule"], user=usr, pda=TRUE)
+ mule.bot_control(href_list["mule"], usr, pda=TRUE)
if(!host_pda)
return
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index 3353cd451732..48f064c47649 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -238,6 +238,7 @@
return ..()
/obj/structure/blob/proc/chemeffectreport(mob/user)
+ RETURN_TYPE(/list)
. = list()
if(overmind)
. += list("Material: [overmind.blobstrain.name].",
@@ -247,11 +248,11 @@
. += "No Material Detected!"
/obj/structure/blob/proc/typereport(mob/user)
+ RETURN_TYPE(/list)
return list("Blob Type: [uppertext(initial(name))]",
"Health: [obj_integrity]/[max_integrity]",
"Effects: [scannerreport()]")
-
/obj/structure/blob/attack_animal(mob/living/simple_animal/M)
if(ROLE_BLOB in M.faction) //sorry, but you can't kill the blob as a blobbernaut
return
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index a2dbedd31c1b..87ed6fdc6de9 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -14,7 +14,7 @@
var/should_equip = TRUE
var/traitor_kind = TRAITOR_HUMAN //Set on initial assignment
var/datum/syndicate_contract/current_contract
- var/list/assigned_contracts = list()
+ var/list/datum/syndicate_contract/assigned_contracts = list()
var/contract_TC_payed_out = 0
var/contract_TC_to_redeem = 0
can_hijack = HIJACK_HIJACKER
@@ -39,7 +39,7 @@
var/total = 0
var/lowest_paying_sum = 0
var/datum/syndicate_contract/lowest_paying_contract
-
+
for (var/i = 1; i <= contract_generation_quantity; i++)
var/datum/syndicate_contract/contract_to_add = new(owner)
var/contract_payout_total = contract_to_add.contract.payout + contract_to_add.contract.payout_bonus
@@ -394,7 +394,7 @@
if (completed_contracts > 0)
var/pluralCheck = "contract"
- if (completed_contracts > 1)
+ if (completed_contracts > 1)
pluralCheck = "contracts"
result += "
Completed [completed_contracts] [pluralCheck] for a total of \
[tc_total] TC!
"
diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
index 05402b59ae2c..f8fd7160dba6 100644
--- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
+++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
@@ -72,11 +72,13 @@
air.copy_from(copy)
/turf/return_air()
+ RETURN_TYPE(/datum/gas_mixture)
var/datum/gas_mixture/GM = new
GM.copy_from_turf(src)
return GM
/turf/open/return_air()
+ RETURN_TYPE(/datum/gas_mixture)
return air
/turf/temperature_expose()
diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm
index ace1cdcd2e40..f7cb0bf10213 100644
--- a/code/modules/holodeck/area_copy.dm
+++ b/code/modules/holodeck/area_copy.dm
@@ -5,6 +5,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list(
))
/proc/DuplicateObject(atom/original, perfectcopy = TRUE, sameloc, atom/newloc = null, nerf, holoitem)
+ RETURN_TYPE(original.type)
if(!original)
return
var/atom/O
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 1e6fb2203c03..72950716bd87 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -152,6 +152,7 @@
return .
/mob/living/carbon/human/proc/get_bank_account()
+ RETURN_TYPE(/datum/bank_account)
var/datum/bank_account/account
var/obj/item/card/id/I = get_idcard()
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 17105d29d07d..36dd65c2ad02 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -833,7 +833,7 @@
/mob/living/silicon/ai/can_buckle()
return 0
-/mob/living/silicon/ai/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE)
+/mob/living/silicon/ai/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE, ignore_stasis = FALSE)
if(aiRestorePowerRoutine)
return TRUE
return ..()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 607926f16681..85dab7a91a05 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -672,11 +672,11 @@ Pass a positive integer as an argument to override a bot's default speed.
destination = nearest_beacon
//PDA control. Some bots, especially MULEs, may have more parameters.
-/mob/living/simple_animal/bot/proc/bot_control(command, mob/user, turf/user_turf, list/user_access = list())
+/mob/living/simple_animal/bot/proc/bot_control(command, mob/user, list/user_access = list())
if(!on || emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
return TRUE //ACCESS DENIED
if(client)
- bot_control_message(command,user,user_turf,user_access)
+ bot_control_message(command, user)
// process control input
switch(command)
if("patroloff")
@@ -688,7 +688,7 @@ Pass a positive integer as an argument to override a bot's default speed.
if("summon")
bot_reset()
- summon_target = user_turf
+ summon_target = get_turf(user)
if(user_access.len != 0)
access_card.access = user_access + prev_access //Adds the user's access, if any.
mode = BOT_SUMMON
@@ -700,15 +700,14 @@ Pass a positive integer as an argument to override a bot's default speed.
return
//
-/mob/living/simple_animal/bot/proc/bot_control_message(command,user,user_turf,user_access)
+/mob/living/simple_animal/bot/proc/bot_control_message(command, user)
switch(command)
if("patroloff")
to_chat(src, "STOP PATROL")
if("patrolon")
to_chat(src, "START PATROL")
if("summon")
- var/area/a = get_area(user_turf)
- to_chat(src, "PRIORITY ALERT:[user] in [a.name]!")
+ to_chat(src, "PRIORITY ALERT:[user] in [get_area_name(user)]!")
if("stop")
to_chat(src, "STOP!")
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index 19b67f155078..259921f43dda 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -15,7 +15,7 @@
var/setting = 1 // displayed range is 3 * setting
var/max_range = 3 // displayed max range is 3 * max range
-/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc)
+/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc, silent=FALSE)
amount = setting
carry.copy_to(chemholder, 20)
carry.remove_any(amount * 16 / efficiency)
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index f03ce15ac3b3..7c90fc26ae0d 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -79,7 +79,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
sell()
/obj/docking_port/mobile/supply/proc/buy()
- var/list/miscboxes = list() //miscboxes are combo boxes that contain all small_item orders grouped
+ var/list/obj/miscboxes = list() //miscboxes are combo boxes that contain all small_item orders grouped
var/list/misc_order_num = list() //list of strings of order numbers, so that the manifest can show all orders in a box
var/list/misc_contents = list() //list of lists of items that each box will contain
if(!SSshuttle.shoppinglist.len)
diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm
index b6eb5011a09a..83e1274f9cf1 100644
--- a/code/modules/vehicles/_vehicle.dm
+++ b/code/modules/vehicles/_vehicle.dm
@@ -61,6 +61,7 @@
.++
/obj/vehicle/proc/return_controllers_with_flag(flag)
+ RETURN_TYPE(/list/mob)
. = list()
for(var/i in occupants)
if(occupants[i] & flag)