diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm
index 83fe9efbe1a..a5e217ae2b4 100644
--- a/code/__DEFINES/crafting.dm
+++ b/code/__DEFINES/crafting.dm
@@ -37,6 +37,14 @@
/// This craft won't change the materials of the resulting item to match that of the combined components
#define CRAFT_NO_MATERIALS (1<<10)
+//Crafting blacklist behaviors
+/// By default, blacklist the result if it's not in reqs
+#define BLACKLIST_RESULT_IF_NOT_IN_REQS null
+/// Always blacklist - override default behavior
+#define ALWAYS_BLACKLIST_RESULT TRUE
+/// Never blacklist - override default behavior
+#define NEVER_BLACKLIST_RESULT FALSE
+
//food/drink crafting defines
//When adding new defines, please make sure to also add them to the encompassing list
#define CAT_FOOD "Foods"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 5ba6af88746..4b34b40ee63 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -11,11 +11,9 @@
init_crafting_recipes_atoms()
/// Inits crafting recipe lists
-/proc/init_crafting_recipes(list/crafting_recipes)
- for(var/path in subtypesof(/datum/crafting_recipe))
- if(ispath(path, /datum/crafting_recipe/stack))
- continue
- var/datum/crafting_recipe/recipe = new path()
+/proc/init_crafting_recipes()
+ for(var/datum/crafting_recipe_path as anything in valid_subtypesof(/datum/crafting_recipe))
+ var/datum/crafting_recipe/recipe = new crafting_recipe_path()
var/is_cooking = (recipe.category in GLOB.crafting_category_food)
recipe.reqs = sort_list(recipe.reqs, GLOBAL_PROC_REF(cmp_crafting_req_priority))
if(recipe.name != "" && recipe.result)
diff --git a/code/datums/actions/mobs/defensive_mode.dm b/code/datums/actions/mobs/defensive_mode.dm
index 6030afea137..e19be70e845 100644
--- a/code/datums/actions/mobs/defensive_mode.dm
+++ b/code/datums/actions/mobs/defensive_mode.dm
@@ -34,7 +34,7 @@
defence(owner_mob)
/datum/action/cooldown/mob_cooldown/defensive_mode/proc/offence(mob/living/basic/owner_mob)
- owner_mob.damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 1, STAMINA = 1, OXY = 1)
+ owner_mob.damage_coeff = string_assoc_list(list(BRUTE = 1, BURN = 1.25, TOX = 1, STAMINA = 1, OXY = 1))
owner_mob.icon_state = initial(owner_mob.icon_state)
owner_mob.icon_living = initial(owner_mob.icon_living)
owner_mob.icon_dead = initial(owner_mob.icon_dead)
@@ -42,7 +42,7 @@
defense_active = FALSE
/datum/action/cooldown/mob_cooldown/defensive_mode/proc/defence(mob/living/basic/owner_mob)
- owner_mob.damage_coeff = list(BRUTE = 0.4, BURN = 0.5, TOX = 1, STAMINA = 1, OXY = 1)
+ owner_mob.damage_coeff = string_assoc_list(list(BRUTE = 0.4, BURN = 0.5, TOX = 1, STAMINA = 1, OXY = 1))
owner_mob.icon_dead = "[owner_mob.icon_state]_d_dead"
owner_mob.icon_state = "[owner_mob.icon_state]_d"
owner_mob.icon_living = "[owner_mob.icon_living]_d"
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
index 7dbce139b57..2a4a0d336e2 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
@@ -2,23 +2,23 @@
//The chance of an emote occurring each second
var/speech_chance = 0
///Hearable emotes
- var/list/emote_hear = list()
+ var/list/emote_hear
///Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
- var/list/emote_see = list()
+ var/list/emote_see
///Possible lines of speech the AI can have
- var/list/speak = list()
+ var/list/speak
///The sound effects associated with this speech, if any
- var/list/sound = list()
+ var/list/sound
/datum/ai_planning_subtree/random_speech/New()
. = ..()
- if(speak)
+ if(LAZYLEN(speak))
speak = string_list(speak)
- if(sound)
+ if(LAZYLEN(sound))
sound = string_list(sound)
- if(emote_hear)
+ if(LAZYLEN(emote_hear))
emote_hear = string_list(emote_hear)
- if(emote_see)
+ if(LAZYLEN(emote_see))
emote_see = string_list(emote_see)
/datum/ai_planning_subtree/random_speech/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
index 71bb1d28c53..69f1ea69cf7 100644
--- a/code/datums/components/chasm.dm
+++ b/code/datums/components/chasm.dm
@@ -6,7 +6,7 @@
var/oblivion_message = "You stumble and stare into the abyss before you. It stares back, and you fall into the enveloping dark."
/// List of refs to falling objects -> how many levels deep we've fallen
- var/static/list/falling_atoms = list()
+ var/static/list/falling_atoms
var/static/list/forbidden_types = typecacheof(list(
/obj/docking_port,
/obj/effect/abstract,
@@ -106,7 +106,8 @@
/datum/component/chasm/proc/droppable(atom/movable/dropped_thing)
var/datum/weakref/falling_ref = WEAKREF(dropped_thing)
// avoid an infinite loop, but allow falling a large distance
- if(falling_atoms[falling_ref] && falling_atoms[falling_ref] > 30)
+ var/falling_atom = LAZYACCESS(falling_atoms, falling_ref)
+ if(falling_atom && falling_atom > 30)
return CHASM_NOT_DROPPING
if(is_type_in_typecache(dropped_thing, forbidden_types) || (!isliving(dropped_thing) && !isobj(dropped_thing)))
return CHASM_NOT_DROPPING
@@ -133,14 +134,14 @@
var/datum/weakref/falling_ref = WEAKREF(dropped_thing)
//Make sure the item is still there after our sleep
if(!dropped_thing || !falling_ref?.resolve())
- falling_atoms -= falling_ref
+ LAZYREMOVE(falling_atoms, falling_ref)
return
- falling_atoms[falling_ref] = (falling_atoms[falling_ref] || 0) + 1
+ LAZYSET(falling_atoms, falling_ref, (falling_atoms[falling_ref] || 0) + 1)
var/turf/below_turf = target_turf
var/atom/parent = src.parent
- if(falling_atoms[falling_ref] > 1)
+ if(LAZYACCESS(falling_atoms, falling_ref) > 1)
return // We're already handling this
if(SEND_SIGNAL(dropped_thing, COMSIG_MOVABLE_CHASM_DROPPED, parent) & COMPONENT_NO_CHASM_DROP)
@@ -164,7 +165,7 @@
var/mob/living/fallen = dropped_thing
fallen.Paralyze(100)
fallen.adjust_brute_loss(30)
- falling_atoms -= falling_ref
+ LAZYREMOVE(falling_atoms, falling_ref)
return
// send to oblivion
@@ -235,7 +236,7 @@
fallen_mob.death(TRUE)
fallen_mob.apply_damage(300)
- falling_atoms -= falling_ref
+ LAZYREMOVE(falling_atoms, falling_ref)
/**
* Called when something has left the chasm depths storage.
diff --git a/code/datums/components/crafting/_recipes.dm b/code/datums/components/crafting/_recipes.dm
index 3989b0c8de3..77c075cfda1 100644
--- a/code/datums/components/crafting/_recipes.dm
+++ b/code/datums/components/crafting/_recipes.dm
@@ -8,7 +8,7 @@
///type paths of items consumed associated with how many are needed
var/list/reqs = list()
///type paths of items explicitly not allowed as an ingredient
- var/list/blacklist = list()
+ var/list/blacklist
///type path of item resulting from this craft
var/result
/// String defines of items needed but not consumed. Lazy list.
@@ -23,13 +23,13 @@
///time in seconds. Remember to use the SECONDS define!
var/time = 3 SECONDS
///type paths of items that will be forceMoved() into the result instead of being deleted
- var/list/parts = list()
+ var/list/parts
///items, structures and machineries of types that are in this list won't transfer their materials to the result
var/list/requirements_mats_blacklist
///if set, the materials in this list and their values will be subtracted from the result.
var/list/removed_mats
///like tool_behaviors but for reagents
- var/list/chem_catalysts = list()
+ var/list/chem_catalysts
///where it shows up in the crafting UI
var/category
///Required machines for the craft, set the assigned value of the typepath to CRAFTING_MACHINERY_CONSUME or CRAFTING_MACHINERY_USE. Lazy associative list: type_path key -> flag value.
@@ -50,19 +50,15 @@
var/delete_contents = TRUE
/// Allows you to craft so that you don't have to click the craft button many times.
var/mass_craftable = FALSE
-
///crafting_flags var to hold bool values
var/crafting_flags = CRAFT_CHECK_DENSITY
-
-/datum/crafting_recipe/New()
- if(!name && result)
- var/atom/atom_result = result
- name = initial(atom_result.name)
-
- if(!(result in reqs))
- blacklist += result
- // These should be excluded from all crafting recipies
- blacklist += list(
+ /**
+ * Should the recipe blacklist its result? Default behavior is to blacklist any result that isn't in reqs.
+ * Can be set to ALWAYS_BLACKLIST_RESULT or NEVER_BLACKLIST_RESULT to override the default behavior.
+ */
+ var/blacklist_result = BLACKLIST_RESULT_IF_NOT_IN_REQS
+ /// Global crafting blacklist. These should be excluded from all crafting recipes no matter what.
+ var/static/list/global_blacklist = typecacheof(list(
/obj/item/cautery/augment,
/obj/item/cautery/cruel/augment,
/obj/item/circular_saw/augment,
@@ -81,15 +77,25 @@
/obj/item/weldingtool/largetank/cyborg,
/obj/item/wirecutters/cyborg,
/obj/item/wrench/cyborg,
- )
+ ))
+
+/datum/crafting_recipe/New()
+ if(!name && result)
+ var/atom/atom_result = result
+ name = initial(atom_result.name)
+ if(result && blacklist_result == BLACKLIST_RESULT_IF_NOT_IN_REQS && !(result in reqs))
+ blacklist_result = ALWAYS_BLACKLIST_RESULT
if(tool_behaviors)
tool_behaviors = string_list(tool_behaviors)
if(tool_paths)
tool_paths = string_list(tool_paths)
- for(var/key in parts)
- if(!parts[key])
+ for(var/key, part in parts)
+ if(!part)
//ensure every single, same-type part used for the recipe will be transferred if the value is otherwise not specified
- parts[key] = INFINITY
+ part = INFINITY
+
+/datum/crafting_recipe/stack
+ abstract_type = /datum/crafting_recipe/stack
/datum/crafting_recipe/stack/New(obj/item/stack/material, datum/stack_recipe/stack_recipe)
if(!material || !stack_recipe || !stack_recipe.result_type)
diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm
index dfe48688cf3..c9e07d0d76a 100644
--- a/code/datums/components/crafting/crafting.dm
+++ b/code/datums/components/crafting/crafting.dm
@@ -68,12 +68,17 @@
var/list/requirements_list = list()
// Process all requirements
- for(var/requirement_path in recipe.reqs)
+ var/recipe_result
+ if(recipe.blacklist_result)
+ recipe_result = recipe.result
+ for(var/requirement_path, needed_amount in recipe.reqs)
// Check we have the appropriate amount available in the contents list
- var/needed_amount = recipe.reqs[requirement_path]
for(var/content_item_path in contents)
// Right path and not blacklisted
- if(!ispath(content_item_path, requirement_path) || recipe.blacklist.Find(content_item_path))
+ if(!ispath(content_item_path, requirement_path) || (content_item_path in recipe.blacklist) || is_type_in_typecache(recipe.global_blacklist, content_item_path))
+ continue
+ // If we are a recipe that is blacklisting its result, make sure we skip that path
+ if(recipe_result && content_item_path == recipe_result)
continue
needed_amount -= contents[content_item_path]
@@ -85,14 +90,14 @@
// Store the instances of what we will use for recipe.check_requirements() for requirement_path
var/list/instances_list = list()
- for(var/instance_path in item_instances)
+ for(var/instance_path, item_instance in item_instances)
if(ispath(instance_path, requirement_path))
- instances_list += item_instances[instance_path]
+ instances_list += item_instance
requirements_list[requirement_path] = instances_list
- for(var/requirement_path in recipe.chem_catalysts)
- if(contents[requirement_path] < recipe.chem_catalysts[requirement_path])
+ for(var/requirement_path, chem_amount in recipe.chem_catalysts)
+ if(contents[requirement_path] < chem_amount)
return FALSE
var/mech_found = FALSE
@@ -245,8 +250,7 @@
var/list/total_materials = list()
var/list/stuff_to_use = get_used_reqs(recipe, crafter, total_materials)
- for(var/mat in recipe.removed_mats)
- var/to_remove = recipe.removed_mats[mat]
+ for(var/mat, to_remove in recipe.removed_mats)
var/datum/material/ref_mat = locate(mat) in total_materials
if(!ref_mat)
continue
@@ -680,11 +684,11 @@
data["reqs"]["[id]"] = recipe.reqs[req_atom]
// Catalysts
- if(recipe.chem_catalysts.len)
+ if(LAZYLEN(recipe.chem_catalysts))
data["chem_catalysts"] = list()
- for(var/req_atom in recipe.chem_catalysts)
+ for(var/req_atom, chem_amount in recipe.chem_catalysts)
var/id = atoms.Find(req_atom)
- data["chem_catalysts"]["[id]"] = recipe.chem_catalysts[req_atom]
+ data["chem_catalysts"]["[id]"] = chem_amount
// Reaction data
if(ispath(recipe.reaction))
diff --git a/code/datums/components/crafting/equipment.dm b/code/datums/components/crafting/equipment.dm
index 16eeeff45e2..3a4744579e6 100644
--- a/code/datums/components/crafting/equipment.dm
+++ b/code/datums/components/crafting/equipment.dm
@@ -10,8 +10,8 @@
category = CAT_EQUIPMENT
/datum/crafting_recipe/strobeshield/New()
- ..()
- blacklist |= subtypesof(/obj/item/shield/riot)
+ LAZYADD(blacklist, typecacheof(/obj/item/shield/riot, ignore_root_path = TRUE))
+ return ..()
/datum/crafting_recipe/improvisedshield
name = "Improvised Shield"
@@ -33,8 +33,19 @@
time = 4 SECONDS
category = CAT_EQUIPMENT
+/datum/crafting_recipe/radio_containing
+ abstract_type = /datum/crafting_recipe/radio_containing
+ /// Shared blacklist of all the radio types for anything that uses a radio in its construction, so we don't repeat it.
+ var/static/list/radio_types_blacklist
-/datum/crafting_recipe/radiogloves
+/datum/crafting_recipe/radio_containing/New()
+ if(isnull(radio_types_blacklist))
+ // because we got shit like /obj/item/radio/off ... WHY!?!
+ radio_types_blacklist = typecacheof(list(/obj/item/radio/headset, /obj/item/radio/intercom))
+ blacklist = radio_types_blacklist
+ return ..()
+
+/datum/crafting_recipe/radio_containing/radiogloves
name = "Radio Gloves"
result = /obj/item/clothing/gloves/radio
time = 1.5 SECONDS
@@ -46,11 +57,6 @@
tool_behaviors = list(TOOL_WIRECUTTER)
category = CAT_EQUIPMENT
-/datum/crafting_recipe/radiogloves/New()
- ..()
- blacklist |= typesof(/obj/item/radio/headset)
- blacklist |= typesof(/obj/item/radio/intercom)
-
/datum/crafting_recipe/wheelchair
name = "Wheelchair"
result = /obj/vehicle/ridden/wheelchair
@@ -163,8 +169,8 @@
category = CAT_EQUIPMENT
/datum/crafting_recipe/flashlight_eyes/New()
- . = ..()
- blacklist += typesof(/obj/item/flashlight/flare)
+ LAZYADD(blacklist, typecacheof(/obj/item/flashlight/flare))
+ return ..()
/datum/crafting_recipe/extendohand_r
name = "Extendo-Hand (Right Arm)"
@@ -308,8 +314,8 @@
tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
/datum/crafting_recipe/morbid_surgical_toolset/New()
- ..()
- blacklist |= subtypesof(/obj/item/organ/cyberimp/arm/toolkit/surgery)
+ LAZYADD(blacklist, typecacheof(/obj/item/organ/cyberimp/arm/toolkit/surgery, ignore_root_path = TRUE))
+ return ..()
/datum/crafting_recipe/surgical_toolset
name = "Surgical Toolset Implant"
diff --git a/code/datums/components/crafting/melee_weapon.dm b/code/datums/components/crafting/melee_weapon.dm
index 28db00ae3f3..9f0fab50964 100644
--- a/code/datums/components/crafting/melee_weapon.dm
+++ b/code/datums/components/crafting/melee_weapon.dm
@@ -89,7 +89,6 @@
time = 4 SECONDS
category = CAT_WEAPON_MELEE
-
/datum/crafting_recipe/balloon_mallet
name = "Balloon Mallet"
result = /obj/item/balloon_mallet
diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm
index df4313cc114..c78bf9ff708 100644
--- a/code/datums/components/crafting/ranged_weapon.dm
+++ b/code/datums/components/crafting/ranged_weapon.dm
@@ -67,8 +67,8 @@
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/advancedegun/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/energy/e_gun)
+ LAZYADD(blacklist, typecacheof(/obj/item/gun/energy/e_gun, ignore_root_path = TRUE))
+ return ..()
/datum/crafting_recipe/tempgun
name = "Temperature Gun"
@@ -81,8 +81,8 @@
category = CAT_WEAPON_RANGED
/datum/crafting_recipe/tempgun/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/energy/e_gun)
+ LAZYADD(blacklist, typecacheof(/obj/item/gun/energy/e_gun, ignore_root_path = TRUE))
+ return ..()
/datum/crafting_recipe/beam_rifle
name = "Event Horizon Anti-Existential Beam Rifle"
@@ -108,7 +108,18 @@
time = 10 SECONDS
category = CAT_WEAPON_RANGED
-/datum/crafting_recipe/xraylaser
+/datum/crafting_recipe/laser
+ abstract_type = /datum/crafting_recipe/laser
+ /// We will use the same blacklist for every type here to avoid repeating lists
+ var/static/list/laser_blacklist
+
+/datum/crafting_recipe/laser/New()
+ if(isnull(laser_blacklist))
+ laser_blacklist = typecacheof(/obj/item/gun/energy/laser, ignore_root_path = TRUE)
+ blacklist = laser_blacklist
+ return ..()
+
+/datum/crafting_recipe/laser/xraylaser
name = "X-ray Laser Gun"
result = /obj/item/gun/energy/laser/xray
reqs = list(
@@ -118,11 +129,7 @@
time = 10 SECONDS
category = CAT_WEAPON_RANGED
-/datum/crafting_recipe/xraylaser/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/energy/laser)
-
-/datum/crafting_recipe/hellgun
+/datum/crafting_recipe/laser/hellgun
name = "Hellfire Laser Gun"
result = /obj/item/gun/energy/laser/hellgun
reqs = list(
@@ -132,11 +139,7 @@
time = 10 SECONDS
category = CAT_WEAPON_RANGED
-/datum/crafting_recipe/hellgun/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/energy/laser)
-
-/datum/crafting_recipe/ioncarbine
+/datum/crafting_recipe/laser/ioncarbine
name = "Ion Carbine"
result = /obj/item/gun/energy/ionrifle/carbine
reqs = list(
@@ -146,10 +149,6 @@
time = 10 SECONDS
category = CAT_WEAPON_RANGED
-/datum/crafting_recipe/ioncarbine/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/energy/laser)
-
/datum/crafting_recipe/teslacannon
name = "Tesla Cannon"
result = /obj/item/gun/energy/tesla_cannon
@@ -241,8 +240,8 @@
/obj/item/gun/ballistic/rifle/rebarxbow = 1,
)
blacklist = list(
- /obj/item/gun/ballistic/rifle/rebarxbow/forced,
- /obj/item/gun/ballistic/rifle/rebarxbow/syndie,
+ /obj/item/gun/ballistic/rifle/rebarxbow/forced,
+ /obj/item/gun/ballistic/rifle/rebarxbow/syndie,
)
tool_behaviors = list(TOOL_CROWBAR)
time = 1 SECONDS
@@ -289,8 +288,8 @@
crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED
/datum/crafting_recipe/deagle_prime/New()
- ..()
- blacklist += subtypesof(/obj/item/gun/ballistic/automatic/pistol)
+ LAZYADD(blacklist, typecacheof(/obj/item/gun/ballistic/automatic/pistol, ignore_root_path = TRUE))
+ return ..()
/datum/crafting_recipe/deagle_prime_mag
name = "Regal Condor Magazine (10mm Reaper)"
diff --git a/code/datums/components/crafting/tailoring.dm b/code/datums/components/crafting/tailoring.dm
index e696dc2b44b..c0e46325c98 100644
--- a/code/datums/components/crafting/tailoring.dm
+++ b/code/datums/components/crafting/tailoring.dm
@@ -421,12 +421,7 @@
)
reqs = list(/obj/item/stack/sheet/cloth = 4)
category = CAT_CLOTHING
-
-/datum/crafting_recipe/chaplain_hood/New()
- . = ..()
- //the resulting hoodie can be used to craft other hoodies.
- //recipe blacklists should be refactored to only affect components and not tools.
- blacklist -= result
+ blacklist_result = NEVER_BLACKLIST_RESULT //the resulting hoodie can be used to craft other hoodies.
/datum/crafting_recipe/flower_garland
name = "Flower Garland"
diff --git a/code/datums/components/ground_sinking.dm b/code/datums/components/ground_sinking.dm
index 4e846b4cf70..971cb15529d 100644
--- a/code/datums/components/ground_sinking.dm
+++ b/code/datums/components/ground_sinking.dm
@@ -36,7 +36,7 @@
heal_when_sinked = TRUE,
health_per_second = 1,
outline_colour = COLOR_PALE_GREEN,
- damage_res_sinked = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1))
+ damage_res_sinked = string_assoc_list(list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1)))
if (!isbasicmob(parent))
return COMPONENT_INCOMPATIBLE
@@ -112,7 +112,7 @@
if(sinked && heal_when_sinked)
stop_regenerating()
living_target.icon_state = target_icon_state
- living_target.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1)
+ living_target.damage_coeff = string_assoc_list(list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1))
living_target.set_density(TRUE)
sinked = FALSE
diff --git a/code/datums/components/soapbox.dm b/code/datums/components/soapbox.dm
index 9d15e5e6929..012229cb2de 100644
--- a/code/datums/components/soapbox.dm
+++ b/code/datums/components/soapbox.dm
@@ -1,6 +1,6 @@
/datum/component/soapbox
/// List of our current soapboxxer(s) who are gaining loud speech
- var/list/soapboxers = list()
+ var/list/soapboxers
/// Gives atoms moving over us the soapbox speech and takes it away when they leave
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_loc_entered),
@@ -21,21 +21,21 @@
if(QDELETED(soapbox_arrive))
return
RegisterSignal(soapbox_arrive, COMSIG_MOB_SAY, PROC_REF(soapbox_speech))
- soapboxers += soapbox_arrive
+ LAZYADD(soapboxers, soapbox_arrive)
///Takes away loud speech from our movable when it leaves the turf our parent is on
/datum/component/soapbox/proc/on_loc_exited(datum/source, mob/living/soapbox_leave)
SIGNAL_HANDLER
if(soapbox_leave in soapboxers)
UnregisterSignal(soapbox_leave, COMSIG_MOB_SAY)
- soapboxers -= soapbox_leave
+ LAZYREMOVE(soapboxers, soapbox_leave)
///We don't want our soapboxxer to keep their loud say if the parent is moved out from under them
/datum/component/soapbox/proc/parent_moved(datum/source)
SIGNAL_HANDLER
for(var/atom/movable/loud as anything in soapboxers)
UnregisterSignal(loud, COMSIG_MOB_SAY)
- soapboxers.Cut()
+ LAZYNULL(soapboxers)
///Gives a mob a unique say span
/datum/component/soapbox/proc/soapbox_speech(datum/source, list/speech_args)
diff --git a/code/datums/dna/dna.dm b/code/datums/dna/dna.dm
index 6b0ef3fc1c8..b0cd64e4bef 100644
--- a/code/datums/dna/dna.dm
+++ b/code/datums/dna/dna.dm
@@ -43,11 +43,11 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
///Stores the real name of the person who originally got this dna datum. Used primarily for changelings
var/real_name
///All mutations are from now on here
- var/list/mutations = list()
+ var/list/mutations
///Temporary changes to the UE
- var/list/temporary_mutations = list()
+ var/list/temporary_mutations
///For temporary name/ui/ue/blood_type modifications
- var/list/previous = list()
+ var/list/previous
var/mob/living/holder
///List of which mutations this carbon has and its assigned block
var/mutation_index[DNA_MUTATION_BLOCKS]
@@ -76,9 +76,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
QDEL_NULL(species)
- mutations.Cut() //This only references mutations, just dereference.
- temporary_mutations.Cut() //^
- previous.Cut() //^
+ LAZYNULL(mutations) //This only references mutations, just dereference.
+ LAZYNULL(temporary_mutations) //^
+ LAZYNULL(previous) //^
return ..()
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
new_dna.unique_features = unique_features
new_dna.features = features.Copy()
new_dna.real_name = real_name
- new_dna.temporary_mutations = temporary_mutations.Copy()
+ new_dna.temporary_mutations = LAZYLISTDUPLICATE(temporary_mutations)
new_dna.mutation_index = mutation_index
new_dna.default_mutation_genes = default_mutation_genes
//if the new DNA has a holder, transform them immediately, otherwise save it
diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm
index 817529ce9d7..1c27df60822 100644
--- a/code/datums/dog_fashion.dm
+++ b/code/datums/dog_fashion.dm
@@ -4,13 +4,13 @@
///Description modifier for the dog that we're dressing up
var/desc = null
///Hearable emotes modifier for the dog that we're dressing up
- var/list/emote_hear = list()
+ var/list/emote_hear
///Visible emotes modifier for the dog that we're dressing up
- var/list/emote_see = list()
+ var/list/emote_see
///Speech modifier for the dog that we're dressing up
- var/list/speak = list()
+ var/list/speak
///Speech verb modifier for the dog that we're dressing up
- var/list/speak_emote = list()
+ var/list/speak_emote
// This isn't applied to the dog, but stores the icon_state of the
// sprite that the associated item uses
@@ -41,16 +41,16 @@
dressup_doggy.name = name
if(desc)
dressup_doggy.desc = desc
- if(length(speak_emote))
+ if(LAZYLEN(speak_emote))
dressup_doggy.speak_emote = string_list(speak_emote)
///Applies random speech modifiers to the dog
/datum/dog_fashion/proc/apply_to_speech(datum/ai_planning_subtree/random_speech/speech)
- if(length(emote_see))
+ if(LAZYLEN(emote_see))
speech.emote_see = string_list(emote_see)
- if(length(emote_hear))
+ if(LAZYLEN(emote_hear))
speech.emote_hear = string_list(emote_hear)
- if(length(speak))
+ if(LAZYLEN(speak))
speech.speak = string_list(speak)
/**
@@ -237,7 +237,7 @@
name = "Butter %REAL_NAME%"
desc = "%NAME%. %CAPITAL_REAL_NAME% with the butter. %NAME%. %CAPITAL_REAL_NAME% with a butter on 'em."
obj_icon_state = "butter"
- speak = list() //they're very patient and focused on holding the butter on 'em
+ speak = null //they're very patient and focused on holding the butter on 'em
emote_see = list("shakes a little.", "looks around.")
emote_hear = list("licks a trickle of the butter up.", "smiles.")
diff --git a/code/datums/embedding.dm b/code/datums/embedding.dm
index 1c876468350..77fec4f8746 100644
--- a/code/datums/embedding.dm
+++ b/code/datums/embedding.dm
@@ -420,7 +420,7 @@
if (user.zone_selected != owner_limb.body_zone || (tool.tool_behaviour != TOOL_HEMOSTAT && tool.tool_behaviour != TOOL_WIRECUTTER))
return
- if (parent != owner_limb.embedded_objects[1]) // Don't pluck everything at the same time
+ if (parent != LAZYACCESS(owner_limb.embedded_objects, 1)) // Don't pluck everything at the same time
return
// Ensure that we can actually
diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm
index a9641a4795e..9055c7b458e 100644
--- a/code/datums/mutations/_mutations.dm
+++ b/code/datums/mutations/_mutations.dm
@@ -129,7 +129,7 @@
return FALSE
owner = acquirer
dna = acquirer.dna
- dna.mutations += src
+ LAZYADD(dna.mutations, src)
SEND_SIGNAL(src, COMSIG_MUTATION_GAINED, acquirer)
if(text_gain_indication)
to_chat(owner, text_gain_indication)
@@ -153,7 +153,7 @@
return
/datum/mutation/proc/on_losing(mob/living/carbon/human/owner)
- if(!istype(owner) || !(owner.dna.mutations.Remove(src)))
+ if(!istype(owner) || !(owner.dna.mutations?.Remove(src)))
return TRUE
. = FALSE
SEND_SIGNAL(src, COMSIG_MUTATION_LOST, owner)
diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm
index 41b7a61949f..cbb36a9662e 100644
--- a/code/datums/storage/storage.dm
+++ b/code/datums/storage/storage.dm
@@ -21,12 +21,12 @@
VAR_FINAL/atom/real_location
/// List of all the mobs currently viewing the contents of this storage.
- VAR_PRIVATE/list/mob/is_using = list()
+ VAR_PRIVATE/list/mob/is_using
///The type of storage interface this datum uses.
var/datum/storage_interface/storage_type = /datum/storage_interface
/// Associated list that keeps track of all storage UI datums per person.
- VAR_PRIVATE/list/datum/storage_interface/storage_interfaces = null
+ VAR_PRIVATE/list/datum/storage_interface/storage_interfaces
/// Typecache of items that can be inserted into this storage.
/// By default, all item types can be inserted (assuming other conditions are met).
@@ -158,7 +158,7 @@
for(var/mob/person as anything in is_using)
hide_contents(person)
- is_using.Cut()
+ LAZYNULL(is_using)
QDEL_LIST_ASSOC_VAL(storage_interfaces)
parent = null
@@ -1084,7 +1084,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
orient_storage()
- is_using |= to_show
+ LAZYOR(is_using, to_show)
to_show.hud_used.open_containers |= storage_interfaces[to_show].list_ui_elements()
to_show.client.screen |= storage_interfaces[to_show].list_ui_elements()
@@ -1103,14 +1103,14 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
if(to_hide.active_storage == src)
to_hide.active_storage = null
- if(!length(is_using) && ismovable(real_location))
+ if(!LAZYLEN(is_using) && ismovable(real_location))
var/atom/movable/movable_loc = real_location
movable_loc.lose_active_storage(src)
- if (!length(storage_interfaces) || isnull(storage_interfaces[to_hide]))
+ if (!LAZYLEN(storage_interfaces) || isnull(storage_interfaces[to_hide]))
return TRUE
- is_using -= to_hide
+ LAZYREMOVE(is_using, to_hide)
if(to_hide.client)
to_hide.client.screen -= storage_interfaces[to_hide].list_ui_elements()
diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm
index 2519189fdec..a015ea68961 100644
--- a/code/game/atom/_atom.dm
+++ b/code/game/atom/_atom.dm
@@ -346,8 +346,8 @@
/atom/proc/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter)
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_ATOM_ON_CRAFT, components, current_recipe)
- var/list/remaining_parts = current_recipe?.parts?.Copy()
- var/list/parts_by_type = remaining_parts?.Copy()
+ var/list/remaining_parts = LAZYLISTDUPLICATE(current_recipe?.parts)
+ var/list/parts_by_type = LAZYLISTDUPLICATE(remaining_parts)
for(var/parttype in parts_by_type) //necessary for our is_type_in_list() call with the zebra arg set to true
parts_by_type[parttype] = parttype
for(var/atom/movable/movable as anything in components) // machinery or structure objects in the list are guaranteed to be used up. We only check items.
diff --git a/code/game/atom/atoms_initializing_EXPENSIVE.dm b/code/game/atom/atoms_initializing_EXPENSIVE.dm
index 7b0965beabb..f39b987990d 100644
--- a/code/game/atom/atoms_initializing_EXPENSIVE.dm
+++ b/code/game/atom/atoms_initializing_EXPENSIVE.dm
@@ -122,6 +122,9 @@
SET_PLANE_IMPLICIT(src, plane)
+ if(LAZYLEN(hud_possible))
+ hud_possible = string_assoc_list(hud_possible)
+
if(greyscale_config && greyscale_colors) //we'll check again at item/init for inhand/belt/worn configs.
update_greyscale()
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index e5a32b706bd..1cfa8977ea8 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -165,7 +165,7 @@
/obj/item/card/id/Destroy()
if (registered_account)
- registered_account.bank_cards -= src
+ LAZYREMOVE(registered_account.bank_cards, src)
if (my_store)
QDEL_NULL(my_store)
if (isitem(loc))
@@ -768,9 +768,9 @@
to_chat(user, span_warning("The account ID number provided is invalid."))
return FALSE
if(old_account)
- old_account.bank_cards -= src
+ LAZYREMOVE(old_account.bank_cards, src)
account.account_balance += old_account.account_balance
- account.bank_cards += src
+ LAZYADD(account.bank_cards, src)
registered_account = account
to_chat(user, span_notice("The provided account has been linked to this ID card. It contains [account.account_balance] [MONEY_NAME]."))
return TRUE
@@ -1095,11 +1095,10 @@
/obj/item/card/id/departmental_budget/Initialize(mapload)
. = ..()
- var/datum/bank_account/B = SSeconomy.get_dep_account(department_ID)
- if(B)
- registered_account = B
- if(!B.bank_cards.Find(src))
- B.bank_cards += src
+ var/datum/bank_account/department_account = SSeconomy.get_dep_account(department_ID)
+ if(department_account)
+ registered_account = department_account
+ LAZYOR(department_account.bank_cards, src)
name = "departmental card ([department_name])"
desc = "Provides access to the [department_name]."
SSeconomy.dep_cards += src
@@ -1972,7 +1971,7 @@
var/datum/bank_account/account = SSeconomy.bank_accounts_by_id["[owner.account_id]"]
if(account)
- account.bank_cards += src
+ LAZYADD(account.bank_cards, src)
registered_account = account
to_chat(user, span_notice("Your account number has been automatically assigned."))
diff --git a/code/game/objects/items/devices/scanners/autopsy_scanner.dm b/code/game/objects/items/devices/scanners/autopsy_scanner.dm
index 40835bc7920..61bc6c4d262 100644
--- a/code/game/objects/items/devices/scanners/autopsy_scanner.dm
+++ b/code/game/objects/items/devices/scanners/autopsy_scanner.dm
@@ -91,7 +91,7 @@
dmgreport += ""
dmgreport += "
| ↳ Physical trauma: Dismembered |
"
continue
- var/has_any_embeds = length(limb.embedded_objects) >= 1
+ var/has_any_embeds = LAZYLEN(limb.embedded_objects) >= 1
var/has_any_wounds = length(limb.wounds) >= 1
dmgreport += ""
dmgreport += "| [capitalize(limb.name)]: | "
diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm
index c70ce933df4..56fab997cf7 100644
--- a/code/game/objects/items/devices/scanners/health_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/health_analyzer.dm
@@ -252,7 +252,7 @@
dmgreport += "
"
dmgreport += "| ↳ Physical trauma: [conditional_tooltip("Dismembered", "Reattach or replace surgically.", tochat)] |
"
continue
- var/has_any_embeds = length(limb.embedded_objects) >= 1
+ var/has_any_embeds = LAZYLEN(limb.embedded_objects) >= 1
var/has_any_wounds = length(limb.wounds) >= 1
var/is_damaged = limb.burn_dam > 0 || limb.brute_dam > 0
if(!is_damaged && (zone != BODY_ZONE_CHEST || (tox_loss <= 0 && oxy_loss <= 0)) && !has_any_embeds && !has_any_wounds)
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 09cc0a9b2cc..baf4bb85e62 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -120,6 +120,7 @@
addtimer(CALLBACK(target.dna, TYPE_PROC_REF(/datum/dna, remove_mutation), mutation, MUTATION_SOURCE_TIMED_INJECTOR), duration)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
+ LAZYINITLIST(target.dna.previous)
if(!target.dna.previous["name"])
target.dna.previous["name"] = target.real_name
if(!target.dna.previous["UE"])
@@ -130,17 +131,19 @@
target.dna.unique_enzymes = fields["UE"]
target.name = target.real_name
target.set_blood_type(fields["blood_type"])
- target.dna.temporary_mutations[UE_CHANGED] = endtime
+ LAZYSET(target.dna.temporary_mutations, UE_CHANGED, endtime)
if(fields["UI"]) //UI+UE
+ LAZYINITLIST(target.dna.previous)
if(!target.dna.previous["UI"])
target.dna.previous["UI"] = target.dna.unique_identity
target.dna.unique_identity = merge_text(target.dna.unique_identity, fields["UI"])
- target.dna.temporary_mutations[UI_CHANGED] = endtime
+ LAZYSET(target.dna.temporary_mutations, UI_CHANGED, endtime)
if(fields["UF"]) //UI+UE
+ LAZYINITLIST(target.dna.previous)
if(!target.dna.previous["UF"])
target.dna.previous["UF"] = target.dna.unique_features
target.dna.unique_features = merge_text(target.dna.unique_features, fields["UF"])
- target.dna.temporary_mutations[UF_CHANGED] = endtime
+ LAZYSET(target.dna.temporary_mutations, UF_CHANGED, endtime)
if(fields["UI"] || fields["UF"])
target.updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE)
return TRUE
diff --git a/code/modules/cargo/markets/market_uplink.dm b/code/modules/cargo/markets/market_uplink.dm
index 5585f434c23..d727453da15 100644
--- a/code/modules/cargo/markets/market_uplink.dm
+++ b/code/modules/cargo/markets/market_uplink.dm
@@ -162,7 +162,7 @@
. = ..()
ADD_TRAIT(src, TRAIT_CONTRABAND, INNATE_TRAIT)
-/datum/crafting_recipe/blackmarket_uplink
+/datum/crafting_recipe/radio_containing/blackmarket_uplink
name = "Black Market Uplink"
result = /obj/item/market_uplink/blackmarket
time = 3 SECONDS
@@ -175,8 +175,3 @@
/obj/item/analyzer = 1
)
category = CAT_EQUIPMENT
-
-/datum/crafting_recipe/blackmarket_uplink/New()
- ..()
- blacklist |= typesof(/obj/item/radio/headset) // because we got shit like /obj/item/radio/off ... WHY!?!
- blacklist |= typesof(/obj/item/radio/intercom)
diff --git a/code/modules/clothing/chameleon/generic_chameleon_clothing.dm b/code/modules/clothing/chameleon/generic_chameleon_clothing.dm
index 2cd2da4ed67..5c9aed76919 100644
--- a/code/modules/clothing/chameleon/generic_chameleon_clothing.dm
+++ b/code/modules/clothing/chameleon/generic_chameleon_clothing.dm
@@ -193,12 +193,13 @@ do { \
clothing_traits = list(TRAIT_VOICE_MATCHES_ID)
/obj/item/clothing/mask/chameleon/attack_self(mob/user)
- var/was_on = (TRAIT_VOICE_MATCHES_ID in clothing_traits)
- if(was_on)
- attach_clothing_traits(TRAIT_VOICE_MATCHES_ID)
- else
+ var/on = (TRAIT_VOICE_MATCHES_ID in clothing_traits)
+ if(on)
detach_clothing_traits(TRAIT_VOICE_MATCHES_ID)
- to_chat(user, span_notice("The voice changer is now [was_on ? "off" : "on"]!"))
+ else
+ attach_clothing_traits(TRAIT_VOICE_MATCHES_ID)
+ on = !on
+ to_chat(user, span_notice("The voice changer is now [on ? "on" : "off"]!"))
/obj/item/clothing/mask/chameleon/broken
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 1f2177a72e6..ccec75931e5 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -64,6 +64,8 @@
/obj/item/clothing/Initialize(mapload)
if(clothing_flags & VOICEBOX_TOGGLABLE)
actions_types += list(/datum/action/item_action/toggle_voice_box)
+ if(LAZYLEN(clothing_traits))
+ clothing_traits = string_list(clothing_traits)
. = ..()
AddElement(/datum/element/venue_price, FOOD_PRICE_CHEAP)
if(can_be_bloody && ((body_parts_covered & FEET) || (flags_inv & HIDESHOES)))
@@ -286,7 +288,11 @@
if(!islist(trait_or_traits))
trait_or_traits = list(trait_or_traits)
+ // Use a temporary list so we don't mutate the cached version
+ clothing_traits = LAZYLISTDUPLICATE(clothing_traits)
LAZYOR(clothing_traits, trait_or_traits)
+ if(clothing_traits) // because we might be null
+ clothing_traits = string_list(clothing_traits)
var/mob/wearer = loc
if(istype(wearer) && (wearer.get_slot_by_item(src) & slot_flags))
for(var/new_trait in trait_or_traits)
@@ -303,7 +309,11 @@
if(!islist(trait_or_traits))
trait_or_traits = list(trait_or_traits)
+ // Use a temporary list so we don't mutate the cached version
+ clothing_traits = LAZYLISTDUPLICATE(clothing_traits)
LAZYREMOVE(clothing_traits, trait_or_traits)
+ if(clothing_traits) // because we might be null
+ clothing_traits = string_list(clothing_traits)
var/mob/wearer = loc
if(istype(wearer))
for(var/new_trait in trait_or_traits)
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 3887807503c..003cbf4850a 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -270,7 +270,7 @@
/obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user)
..()
var/hud_type
- if (!isnull(clothing_traits) && clothing_traits.len)
+ if (LAZYLEN(clothing_traits))
hud_type = clothing_traits[1]
switch (hud_type)
if (TRAIT_MEDICAL_HUD)
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index b9f82135c47..bcaa124e487 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -12,7 +12,7 @@
/obj/item/clothing/gloves/color/black/Initialize(mapload)
. = ..()
- var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/radiogloves)
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/radio_containing/radiogloves)
AddElement(
/datum/element/slapcrafting,\
diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm
index a7bdc7bf93c..60cafe30a1b 100644
--- a/code/modules/economy/account.dm
+++ b/code/modules/economy/account.dm
@@ -16,7 +16,7 @@
///The job datum of the account owner.
var/datum/job/account_job
///List of the physical ID card objects that are associated with this bank_account
- var/list/bank_cards = list()
+ var/list/bank_cards
///Should this ID be added to the global list of accounts? If true, will be subject to station-bound economy effects as well as income.
var/add_to_accounts = TRUE
///The Unique ID number code associated with the owner's bank account, assigned at round start.
@@ -34,7 +34,7 @@
///A special semi-tandom token for tranfering money from NT pay app
var/pay_token
///List with a transaction history for NT pay app
- var/list/transaction_history = list()
+ var/list/transaction_history
///A lazylist of coupons redeemed with the Coupon Master pda app associated with this account.
var/list/redeemed_coupons
/// How many paychecks to skip when payday is called.
@@ -232,7 +232,7 @@
* * force - if TRUE ignore checks on client and client prefernces.
*/
/datum/bank_account/proc/bank_card_talk(message, force)
- if(!message || !bank_cards.len)
+ if(!message || !LAZYLEN(bank_cards))
return
for(var/obj/card in bank_cards)
var/icon_source = card
@@ -344,12 +344,12 @@
* * reason - The reason of interact with balance, for example, "Bought chips" or "Payday".
*/
/datum/bank_account/proc/add_log_to_history(adjusted_money, reason)
- if(transaction_history.len >= 20)
+ if(LAZYLEN(transaction_history) >= 20)
transaction_history.Cut(1,2)
- transaction_history += list(list(
+ LAZYADD(transaction_history, list(list(
"adjusted_money" = adjusted_money,
"reason" = reason,
- ))
+ )))
#undef DUMPTIME
diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm
index 01fa0e88dba..48f0c712c73 100644
--- a/code/modules/experisci/experiment/experiments.dm
+++ b/code/modules/experisci/experiment/experiments.dm
@@ -348,7 +348,7 @@
. = ..()
if (!.)
return
- if(!check.dna.mutations.len)
+ if(!LAZYLEN(check.dna.mutations))
return FALSE
return TRUE
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
index 3482dec940c..62e4add9f62 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_guide.dm
@@ -52,7 +52,7 @@
*/
/datum/crafting_recipe/food/reaction/proc/setup_chemical_reaction_details(datum/chemical_reaction/chemical_reaction)
reqs = chemical_reaction.required_reagents?.Copy()
- chem_catalysts = chemical_reaction.required_catalysts?.Copy()
+ chem_catalysts = LAZYLISTDUPLICATE(chemical_reaction.required_catalysts)
if(isnull(result) && length(chemical_reaction.results))
result = chemical_reaction.results[1]
result_amount = chemical_reaction.results[result]
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 39f2600e29f..721c0671952 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -406,7 +406,7 @@
if(account && account.account_id == equipped.account_id)
card.registered_account = account
- account.bank_cards += card
+ LAZYADD(account.bank_cards, card)
equipped.update_ID_card()
diff --git a/code/modules/jobs/job_types/station_trait/cargo_gorilla.dm b/code/modules/jobs/job_types/station_trait/cargo_gorilla.dm
index 9fe2cccc934..bbc50389381 100644
--- a/code/modules/jobs/job_types/station_trait/cargo_gorilla.dm
+++ b/code/modules/jobs/job_types/station_trait/cargo_gorilla.dm
@@ -41,7 +41,7 @@
gorilla_id.registered_name = spawned.name
gorilla_id.update_label()
gorilla_id.registered_account = bank_account
- bank_account.bank_cards += gorilla_id
+ LAZYADD(bank_account.bank_cards, gorilla_id)
spawned.put_in_hands(gorilla_id, del_on_fail = TRUE)
to_chat(spawned, span_boldnotice("You are Cargorilla, a pacifist friend of the station and carrier of freight."))
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 5050974e122..4a6c6a3585c 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -6,7 +6,6 @@
density = FALSE
stat = DEAD
hud_type = /datum/hud/new_player
- hud_possible = list()
/// String Values tied to Defines that state whether the new_player is ready to play or not.
/// Do try your best to compare this value directly against the defines for certainty but helper procs do exist in bulkier situations.
diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm
index 06eba0ac141..0965a5cc5ab 100644
--- a/code/modules/mob/living/basic/basic.dm
+++ b/code/modules/mob/living/basic/basic.dm
@@ -51,7 +51,7 @@
var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 1, OXY = 1)
///Verbs used for speaking e.g. "Says" or "Chitters". This can be elementized
- var/list/speak_emote = list()
+ var/list/speak_emote
///When someone interacts with the simple animal.
///Help-intent verb in present continuous tense.
@@ -120,8 +120,9 @@
apply_target_randomisation()
make_stamina_slowable()
- if(speak_emote)
+ if(LAZYLEN(speak_emote))
speak_emote = string_list(speak_emote)
+ damage_coeff = string_assoc_list(damage_coeff)
///We need to wait for SSair to be initialized before we can check atmos/temp requirements.
if(PERFORM_ALL_TESTS(focus_only/atmos_and_temp_requirements) && mapload && !SSair.initialized)
diff --git a/code/modules/mob/living/basic/bots/cleanbot/cleanbot.dm b/code/modules/mob/living/basic/bots/cleanbot/cleanbot.dm
index d52b70575c5..64f0b2cfd6a 100644
--- a/code/modules/mob/living/basic/bots/cleanbot/cleanbot.dm
+++ b/code/modules/mob/living/basic/bots/cleanbot/cleanbot.dm
@@ -161,9 +161,9 @@
/mob/living/basic/bot/cleanbot/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
- if(istype(arrived, /obj/item/reagent_containers/cup/bucket) && isnull(build_bucket))
+ if(istype(arrived, /obj/item/reagent_containers/cup/bucket))
+ QDEL_NULL(build_bucket)
build_bucket = arrived
- return
if(istype(arrived, /obj/item/mop) && isnull(our_mop))
our_mop = arrived
@@ -208,7 +208,7 @@
/mob/living/basic/bot/cleanbot/explode()
var/atom/drop_loc = drop_location()
- build_bucket.forceMove(drop_loc)
+ build_bucket?.forceMove(drop_loc)
new /obj/item/assembly/prox_sensor(drop_loc)
if(weapon)
weapon.force = initial(weapon.force)
@@ -256,11 +256,6 @@
GLOB.janitor_devices -= src
return ..()
-/mob/living/basic/bot/cleanbot/proc/apply_custom_bucket(obj/item/custom_bucket)
- if(!isnull(build_bucket))
- QDEL_NULL(build_bucket)
- custom_bucket.forceMove(src)
-
/mob/living/basic/bot/cleanbot/proc/on_attack_by(datum/source, obj/item/used_item, mob/living/user)
SIGNAL_HANDLER
if(!istype(used_item, /obj/item/knife) || user.combat_mode)
diff --git a/code/modules/mob/living/basic/guardian/guardian_types/protector.dm b/code/modules/mob/living/basic/guardian/guardian_types/protector.dm
index 2205eaf10d1..45d746b2335 100644
--- a/code/modules/mob/living/basic/guardian/guardian_types/protector.dm
+++ b/code/modules/mob/living/basic/guardian/guardian_types/protector.dm
@@ -71,7 +71,9 @@
/// Overlay for our protection shield.
var/mutable_appearance/shield_overlay
/// Damage coefficients when shielded
- var/list/shielded_damage = list(BRUTE = 0.05, BURN = 0.05, TOX = 0.05, STAMINA = 0, OXY = 0.05)
+ var/static/list/shielded_damage = list(BRUTE = 0.05, BURN = 0.05, TOX = 0.05, STAMINA = 0, OXY = 0.05)
+ // What the damage coefficients were previously
+ var/list/original_damage_coeff
/datum/status_effect/protector_shield/on_apply()
if (isguardian(owner))
@@ -86,6 +88,7 @@
if (isbasicmob(owner)) // Better hope you are or this status is doing basically nothing useful for you
var/mob/living/basic/basic_owner = owner
+ original_damage_coeff = basic_owner.damage_coeff
basic_owner.damage_coeff = shielded_damage
to_chat(owner, span_bolddanger("You enter protection mode."))
@@ -101,7 +104,7 @@
if (isbasicmob(owner))
var/mob/living/basic/basic_owner = owner
- basic_owner.damage_coeff = initial(basic_owner.damage_coeff)
+ basic_owner.damage_coeff = original_damage_coeff
to_chat(owner, span_bolddanger("You return to your normal mode."))
UnregisterSignal(owner, list(COMSIG_ATOM_UPDATE_OVERLAYS) + COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES)
diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm
index f4f329b1505..e1b664e852a 100644
--- a/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm
+++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm
@@ -50,7 +50,7 @@
/datum/ai_planning_subtree/random_speech/when_has_target/mimic_machine
speech_chance = 7
- emote_hear = list()
+ emote_hear = null
speak = list(
"HUMANS ARE IMPERFECT!",
"YOU SHALL BE ASSIMILATED!",
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 35e96354d99..45b4142ed4b 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -530,24 +530,26 @@
disease.stage_act(seconds_per_tick)
/mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick)
- if(!dna?.temporary_mutations.len)
+ if(!LAZYLEN(dna?.temporary_mutations))
return
- for(var/mut in dna.temporary_mutations)
- if(dna.temporary_mutations[mut] < world.time)
+ for(var/mut, mut_data in dna.temporary_mutations)
+ if(mut_data < world.time)
+ if(!LAZYLEN(dna.previous))
+ continue
if(mut == UI_CHANGED)
if(dna.previous["UI"])
dna.unique_identity = merge_text(dna.unique_identity,dna.previous["UI"])
updateappearance(mutations_overlay_update=1)
dna.previous.Remove("UI")
- dna.temporary_mutations.Remove(mut)
+ LAZYREMOVE(dna.temporary_mutations, mut)
continue
if(mut == UF_CHANGED)
if(dna.previous["UF"])
dna.unique_features = merge_text(dna.unique_features,dna.previous["UF"])
updateappearance(mutcolor_update=1, mutations_overlay_update=1)
dna.previous.Remove("UF")
- dna.temporary_mutations.Remove(mut)
+ LAZYREMOVE(dna.temporary_mutations, mut)
continue
if(mut == UE_CHANGED)
if(dna.previous["name"])
@@ -560,7 +562,7 @@
if(dna.previous["blood_type"])
set_blood_type(dna.previous["blood_type"])
dna.previous.Remove("blood_type")
- dna.temporary_mutations.Remove(mut)
+ LAZYREMOVE(dna.temporary_mutations, mut)
continue
/**
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 11953281a2b..e55c94b73d5 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -74,7 +74,7 @@
if(!can_finish_build(item_attached, user))
return
var/mob/living/basic/bot/cleanbot/bot = new(drop_location())
- bot.apply_custom_bucket(bucket_obj)
+ bucket_obj.forceMove(bot)
bot.name = created_name
bot.robot_arm = item_attached.type
to_chat(user, span_notice("You add [item_attached] to [src]. Beep boop!"))
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index c3d14859d4f..1974c078bac 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -73,8 +73,6 @@
var/search_objects_timer_id
///The delay between being attacked and gaining our old search_objects value back
var/search_objects_regain_time = 3 SECONDS
- ///A typecache of objects types that will be checked against to attack, should we have search_objects enabled
- var/list/wanted_objects = list()
///Mobs ignore mob/living targets with a stat lower than that of stat_attack. If set to DEAD, then they'll include corpses in their targets, if to HARD_CRIT they'll keep attacking until they kill, and so on.
var/stat_attack = CONSCIOUS
///Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses
@@ -86,17 +84,11 @@
//Attempting to call GET_TARGETS_FROM(mob) when this var is null will just return mob as a base
///all range/attack/etc. calculations should be done from the atom this weakrefs, useful for Vehicles and such.
var/datum/weakref/targets_from
- ///if true, equivalent to having a wanted_objects list containing ALL objects.
- var/attack_all_objects = FALSE
///id for a timer to call LoseTarget(), used to stop mobs fixating on a target they can't reach
var/lose_patience_timer_id
///30 seconds by default, so there's no major changes to AI behaviour, beyond actually bailing if stuck forever
var/lose_patience_timeout = 30 SECONDS
-/mob/living/simple_animal/hostile/Initialize(mapload)
- . = ..()
- wanted_objects = typecacheof(wanted_objects)
-
/mob/living/simple_animal/hostile/Destroy()
//We can't use losetarget here because fucking cursed blobs override it to do nothing the motherfuckers
GiveTarget(null)
@@ -295,10 +287,6 @@
return FALSE
return TRUE
- if(isobj(the_target))
- if(attack_all_objects || is_type_in_typecache(the_target, wanted_objects))
- return TRUE
-
return FALSE
/mob/living/simple_animal/hostile/proc/GiveTarget(new_target)//Step 4, give us our selected target
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 684ac23e122..e92563748c2 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -17,14 +17,14 @@
///Flip the sprite upside down on death. Mostly here for things lacking custom dead sprites.
var/flip_on_death = FALSE
- var/list/speak = list()
+ var/list/speak
///Emotes while speaking IE: `Ian [emote], [text]` -- `Ian barks, "WOOF!".` Spoken text is generated from the speak variable.
- var/list/speak_emote = list()
+ var/list/speak_emote
var/speak_chance = 0
///Hearable emotes
- var/list/emote_hear = list()
+ var/list/emote_hear
///Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
- var/list/emote_see = list()
+ var/list/emote_see
///ticks up every time `handle_automated_movement()` is called, which is every 2 seconds at the time of documenting. 1 turns per move is 1 movement every 2 seconds.
var/turns_per_move = 1
@@ -177,16 +177,15 @@
add_traits(weather_immunities, ROUNDSTART_TRAIT)
if (environment_smash >= ENVIRONMENT_SMASH_WALLS)
AddElement(/datum/element/wall_smasher, strength_flag = environment_smash)
- if(speak)
+ if(LAZYLEN(speak))
speak = string_list(speak)
- if(speak_emote)
+ if(LAZYLEN(speak_emote))
speak_emote = string_list(speak_emote)
- if(emote_hear)
+ if(LAZYLEN(emote_hear))
emote_hear = string_list(emote_hear)
- if(emote_see)
- emote_see = string_list(emote_hear)
- if(damage_coeff)
- damage_coeff = string_assoc_list(damage_coeff)
+ if(LAZYLEN(emote_see))
+ emote_see = string_list(emote_see)
+ damage_coeff = string_assoc_list(damage_coeff)
if(footstep_type)
AddElement(/datum/element/footstep, footstep_type)
if(isnull(unsuitable_cold_damage))
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ffa4f5aee50..368241aa844 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -181,7 +181,7 @@
* Goes through hud_possible list and adds the images to the hud_list variable (if not already cached)
*/
/atom/proc/prepare_huds()
- if(hud_list) // I choose to be lienient about people calling this proc more then once
+ if(hud_list) // I choose to be lenient about people calling this proc more then once
return
hud_list = list()
for(var/hud in hud_possible)
diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm
index 87f18a285d4..b77f273378f 100644
--- a/code/modules/modular_computers/computers/item/role_tablet_presets.dm
+++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm
@@ -501,7 +501,7 @@
var/datum/computer_file/program/themeify/theme_app = locate() in stored_files
if(theme_app)
for(var/theme_key in GLOB.pda_name_to_theme - GLOB.default_pda_themes)
- theme_app.imported_themes += theme_key
+ LAZYADD(theme_app.imported_themes, theme_key)
/obj/item/modular_computer/pda/clear/get_messenger_ending()
return "Sent from my crystal PDA"
diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
index eed37d68cde..b7b8685750c 100644
--- a/code/modules/modular_computers/file_system/program.dm
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -14,9 +14,9 @@
var/power_cell_use = PROGRAM_BASIC_CELL_USE
///List of required accesses to *run* the program. Any match will do.
///This also acts as download_access if that is not set, making this more draconic and restrictive.
- var/list/run_access = list()
+ var/list/run_access
///List of required access to download or file host the program. Any match will do.
- var/list/download_access = list()
+ var/list/download_access
/// User-friendly name of this program.
var/filedesc = "Unknown Program"
/// Short description of this program's function.
@@ -51,6 +51,10 @@
/datum/computer_file/program/New()
..()
+ if(LAZYLEN(run_access))
+ run_access = string_list(run_access)
+ if(LAZYLEN(download_access))
+ download_access = string_list(download_access)
///We need to ensure that different programs (subtypes mostly) won't try to load in the same circuit comps into the shell or usb port of the modpc.
if(circuit_comp_type && initial(circuit_comp_type.associated_program) != type)
stack_trace("circuit comp type mismatch: [type] has circuit comp type \[[circuit_comp_type]\], while \[[circuit_comp_type]\] has associated program \[[initial(circuit_comp_type.associated_program)]\].")
diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm
index 70e7f657ae0..c619c9a69ba 100644
--- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm
+++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm
@@ -174,7 +174,7 @@
program_open_overlay = "generic"
extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs."
program_flags = PROGRAM_ON_SYNDINET_STORE
- download_access = list()
+ download_access = null
circuit_comp_type = /obj/item/circuit_component/mod_program/borg_monitor/syndie
/datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R)
diff --git a/code/modules/modular_computers/file_system/programs/dept_order.dm b/code/modules/modular_computers/file_system/programs/dept_order.dm
index eede7b147f1..57a14636947 100644
--- a/code/modules/modular_computers/file_system/programs/dept_order.dm
+++ b/code/modules/modular_computers/file_system/programs/dept_order.dm
@@ -49,7 +49,7 @@ GLOBAL_VAR(department_cd_override)
linked_department = department
var/datum/job_department/linked_department_real = SSjob.get_department_type(linked_department)
// Heads of staff can download
- download_access |= linked_department_real.head_of_staff_access
+ LAZYOR(download_access, linked_department_real.head_of_staff_access)
// Heads of staff + anyone in the dept can run it
use_access |= linked_department_real.head_of_staff_access
use_access |= linked_department_real.department_access
@@ -164,7 +164,7 @@ GLOBAL_VAR(department_cd_override)
if(action == "override_order")
if(isnull(department_order) || !(department_order in SSshuttle.shopping_list))
return TRUE
- if(length(download_access & id_card_access) <= 0)
+ if(LAZYLEN(download_access & id_card_access) <= 0)
computer.physical.balloon_alert(orderer, "requires head of staff access!")
playsound(computer, 'sound/machines/buzz/buzz-sigh.ogg', 30, TRUE)
return TRUE
diff --git a/code/modules/modular_computers/file_system/programs/maintenance/themes.dm b/code/modules/modular_computers/file_system/programs/maintenance/themes.dm
index e3dca731d3a..de52daa335e 100644
--- a/code/modules/modular_computers/file_system/programs/maintenance/themes.dm
+++ b/code/modules/modular_computers/file_system/programs/maintenance/themes.dm
@@ -20,7 +20,7 @@
if(!theme_app)
return FALSE
//don't get the same one twice
- if(theme_app.imported_themes.Find(theme_name))
+ if(LAZYFIND(theme_app.imported_themes, theme_name))
return FALSE
return TRUE
@@ -30,7 +30,7 @@
//add the theme to the computer and increase its size to match
var/datum/computer_file/program/themeify/theme_app = locate() in computer.stored_files
if(theme_app)
- theme_app.imported_themes += theme_name
+ LAZYADD(theme_app.imported_themes, theme_name)
theme_app.size += size
qdel(src)
diff --git a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
index 027782f9f47..0cd3595c437 100644
--- a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
+++ b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm
@@ -34,7 +34,7 @@
var/spam_mode = FALSE
/// An asssociative list of chats we have started, format: chatref -> pda_chat.
- var/list/saved_chats = list()
+ var/list/saved_chats
/// Whose chatlogs we currently have open. If we are in the contacts list, this is null.
var/viewing_messages_of = null
@@ -74,7 +74,7 @@
/datum/computer_file/program/messenger/proc/on_imprint_reset(sender)
SIGNAL_HANDLER
remove_messenger(src)
- saved_chats = list()
+ LAZYNULL(saved_chats)
selected_image = null
viewing_messages_of = null
@@ -117,7 +117,7 @@
data |= photo.picture_name
if(viewing_messages_of in saved_chats)
- var/datum/pda_chat/chat = saved_chats[viewing_messages_of]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, viewing_messages_of)
for(var/datum/pda_message/message as anything in chat.messages)
if(isnull(message.photo_name))
continue
@@ -180,13 +180,13 @@
if("PDA_viewMessages")
if(viewing_messages_of in saved_chats)
- var/datum/pda_chat/chat = saved_chats[viewing_messages_of]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, viewing_messages_of)
chat.unread_messages = 0
viewing_messages_of = params["ref"]
if (viewing_messages_of in saved_chats)
- var/datum/pda_chat/chat = saved_chats[viewing_messages_of]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, viewing_messages_of)
chat.visible_in_recents = TRUE
selected_image = null
@@ -198,7 +198,7 @@
if(!(target in saved_chats))
return FALSE
- var/datum/pda_chat/chat = saved_chats[target]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, target)
chat.visible_in_recents = FALSE
if(viewing_messages_of == target)
viewing_messages_of = null
@@ -208,9 +208,9 @@
var/chat_ref = params["ref"]
if(chat_ref in saved_chats)
- saved_chats.Remove(chat_ref)
+ LAZYREMOVE(saved_chats, chat_ref)
else if(isnull(chat_ref))
- saved_chats = list()
+ LAZYNULL(saved_chats)
viewing_messages_of = null
return TRUE
@@ -240,7 +240,7 @@
if(!(target_chat_ref in saved_chats))
return FALSE
- var/datum/pda_chat/chat = saved_chats[target_chat_ref]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, target_chat_ref)
chat.message_draft = message_draft
@@ -252,7 +252,7 @@
if(!(target_chat_ref in saved_chats))
return FALSE
- var/datum/pda_chat/chat = saved_chats[target_chat_ref]
+ var/datum/pda_chat/chat = LAZYACCESS(saved_chats, target_chat_ref)
chat.unread_messages = 0
return TRUE
@@ -269,7 +269,7 @@
var/target = null
if(target_ref in saved_chats)
- target = saved_chats[target_ref]
+ target = LAZYACCESS(saved_chats, target_ref)
else if(target_ref in GLOB.pda_messengers)
target = GLOB.pda_messengers[target_ref]
else
@@ -357,7 +357,7 @@
"job" = computer.saved_job,
"ref" = REF(src)
) : null)
- data["saved_chats"] = chats_data
+ data["saved_chats"] = chats_data || list()
data["messengers"] = messengers
data["sort_by_job"] = sort_by_job
data["alert_silenced"] = alert_silenced
@@ -412,8 +412,8 @@
for(var/mc in get_messengers())
messenger_targets += mc
- for(var/chatref in saved_chats)
- var/datum/pda_chat/chat = saved_chats[chatref]
+ for(var/chatref, data in saved_chats)
+ var/datum/pda_chat/chat = data
if(!(chat.recipient?.reference in messenger_targets)) // if its in messenger_targets, it's valid
continue
messenger_targets -= chat.recipient.reference
@@ -443,14 +443,14 @@
new_chat.cached_job = job
new_chat.can_reply = FALSE
- saved_chats[REF(new_chat)] = new_chat
+ LAZYSET(saved_chats, REF(new_chat), new_chat)
return new_chat
/// Gets the chat by the recipient, either by their name or messenger ref
/datum/computer_file/program/messenger/proc/find_chat_by_recipient(recipient, fake_user = FALSE)
- for(var/chat_ref in saved_chats)
- var/datum/pda_chat/chat = saved_chats[chat_ref]
+ for(var/chat_ref, data in saved_chats)
+ var/datum/pda_chat/chat = data
if(fake_user && chat.cached_name == recipient)
return chat
else if(chat.recipient?.reference == recipient)
@@ -752,7 +752,7 @@
if("message")
if(!(target_href in saved_chats))
return
- quick_reply_prompt(usr, saved_chats[target_href])
+ quick_reply_prompt(usr, LAZYACCESS(saved_chats, target_href))
if("open")
if(target_href in saved_chats)
diff --git a/code/modules/modular_computers/file_system/programs/notepad.dm b/code/modules/modular_computers/file_system/programs/notepad.dm
index 95def6f8e96..af165952830 100644
--- a/code/modules/modular_computers/file_system/programs/notepad.dm
+++ b/code/modules/modular_computers/file_system/programs/notepad.dm
@@ -9,7 +9,6 @@
program_icon = "book"
can_run_on_flags = PROGRAM_ALL
circuit_comp_type = /obj/item/circuit_component/mod_program/notepad
-
var/written_note = "Congratulations on your station upgrading to the new NtOS and Thinktronic based collaboration effort, \
bringing you the best in electronics and software since 2467!\n\
To help with navigation, we have provided the following definitions:\n\
diff --git a/code/modules/modular_computers/file_system/programs/nt_pay.dm b/code/modules/modular_computers/file_system/programs/nt_pay.dm
index 19f3c7bb198..4be567a3c86 100644
--- a/code/modules/modular_computers/file_system/programs/nt_pay.dm
+++ b/code/modules/modular_computers/file_system/programs/nt_pay.dm
@@ -50,7 +50,7 @@
data["owner_token"] = current_user.pay_token
data["money"] = current_user.account_balance
data["wanted_token"] = wanted_token
- data["transaction_list"] = current_user.transaction_history
+ data["transaction_list"] = current_user.transaction_history || list()
return data
diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm
index 51e3cfed303..6d99a795cf6 100644
--- a/code/modules/modular_computers/file_system/programs/secureye.dm
+++ b/code/modules/modular_computers/file_system/programs/secureye.dm
@@ -38,7 +38,7 @@
filename = "syndeye"
filedesc = "SyndEye"
extended_desc = "This program allows for illegal access to security camera networks."
- download_access = list()
+ download_access = null
can_run_on_flags = PROGRAM_ALL
program_flags = PROGRAM_ON_SYNDINET_STORE | PROGRAM_UNIQUE_COPY
diff --git a/code/modules/modular_computers/file_system/programs/theme_selector.dm b/code/modules/modular_computers/file_system/programs/theme_selector.dm
index 3d3f5a6a3cb..dafa7ddab6a 100644
--- a/code/modules/modular_computers/file_system/programs/theme_selector.dm
+++ b/code/modules/modular_computers/file_system/programs/theme_selector.dm
@@ -10,7 +10,7 @@
program_icon = "paint-roller"
///List of all themes imported from maintenance apps.
- var/list/imported_themes = list()
+ var/list/imported_themes
/datum/computer_file/program/themeify/ui_data(mob/user)
var/list/data = list()
@@ -29,7 +29,7 @@
var/selected_theme = params["selected_theme"]
if( \
!GLOB.default_pda_themes.Find(selected_theme) && \
- !imported_themes.Find(selected_theme) && \
+ !LAZYFIND(imported_themes, selected_theme) && \
!(computer.obj_flags & EMAGGED) \
)
return FALSE
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index f3989e16cad..de7922b8ef8 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -16,7 +16,7 @@
// Only regular lasguns can be slapcrafted
if(type != /obj/item/gun/energy/laser)
return
- var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/xraylaser, /datum/crafting_recipe/hellgun, /datum/crafting_recipe/ioncarbine)
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/laser/xraylaser, /datum/crafting_recipe/laser/hellgun, /datum/crafting_recipe/laser/ioncarbine)
AddElement(
/datum/element/slapcrafting,\
slapcraft_recipes = slapcraft_recipe_list,\
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index c01b06a92ea..eddeafe8371 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -1274,7 +1274,8 @@
. = ..()
affected_mob.remove_status_effect(/datum/status_effect/jitter)
if(affected_mob.has_dna())
- affected_mob.dna.remove_mutation_group(affected_mob.dna.mutations - affected_mob.dna.get_mutation(/datum/mutation/race), GLOB.standard_mutation_sources)
+ var/list/mutations = affected_mob.dna.mutations || list()
+ affected_mob.dna.remove_mutation_group(mutations - affected_mob.dna.get_mutation(/datum/mutation/race), GLOB.standard_mutation_sources)
affected_mob.dna.scrambled = FALSE
/datum/reagent/medicine/antihol
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index 2967b5084e1..512aecdc28b 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -67,7 +67,7 @@
/// bitflag used to check which clothes cover this bodypart
var/body_part
/// List of obj/item's embedded inside us. Managed by embedded components, do not modify directly
- var/list/embedded_objects = list()
+ var/list/embedded_objects
/// are we a hand? if so, which one!
var/held_index = 0
/// A speed modifier we apply to the owner when attached, if any. Positive numbers make it move slower, negative numbers make it move faster.
@@ -1395,14 +1395,14 @@
if(embed in embedded_objects) // go away
return
// We don't need to do anything with projectile embedding, because it will never reach this point
- embedded_objects += embed
+ LAZYADD(embedded_objects, embed)
RegisterSignal(embed, COMSIG_ITEM_EMBEDDING_UPDATE, PROC_REF(embedded_object_changed))
refresh_bleed_rate()
/// INTERNAL PROC, DO NOT USE
/// Cleans up any attachment we have to the embedded object, removes it from our list
/obj/item/bodypart/proc/_unembed_object(obj/item/unembed)
- embedded_objects -= unembed
+ LAZYREMOVE(embedded_objects, unembed)
UnregisterSignal(unembed, COMSIG_ITEM_EMBEDDING_UPDATE)
refresh_bleed_rate()
diff --git a/code/modules/unit_tests/crafting.dm b/code/modules/unit_tests/crafting.dm
index d6da10b732c..2a362dbe182 100644
--- a/code/modules/unit_tests/crafting.dm
+++ b/code/modules/unit_tests/crafting.dm
@@ -48,17 +48,14 @@
//If it doesn't fail, then it was already handled, maybe through `unit_test_spawn_extras`
var/list/uncreatables_found
- for(var/spawn_path in recipe.unit_test_spawn_extras)
- var/amount = recipe.unit_test_spawn_extras[spawn_path]
+ for(var/spawn_path, amount in recipe.unit_test_spawn_extras)
if(ispath(spawn_path, /obj/item/stack))
new spawn_path(turf, /*new_amount =*/ amount, /*merge =*/ FALSE)
continue
for(var/index in 1 to amount)
new spawn_path(turf)
- for(var/req_path in recipe.reqs) //spawn items and reagents
- var/amount = recipe.reqs[req_path]
-
+ for(var/req_path, amount in recipe.reqs) //spawn items and reagents
if(ispath(req_path, /datum/reagent)) //it's a reagent
if(!bottomless_cup.reagents.has_reagent(req_path, amount))
bottomless_cup.reagents.add_reagent(req_path, amount + 1, no_react = TRUE)
@@ -76,8 +73,8 @@
for(var/iteration in 1 to amount)
new req_path(turf)
- for(var/req_path in recipe.chem_catalysts) // spawn catalysts
- var/amount = recipe.chem_catalysts[req_path]
+ for(var/req_path, chem_amount in recipe.chem_catalysts) // spawn catalysts
+ var/amount = chem_amount
if(!bottomless_cup.reagents.has_reagent(req_path, amount))
bottomless_cup.reagents.add_reagent(req_path, amount + 1, no_react = TRUE)