Files
Batrachophreno 1c8c0c2221 Bugfix pile (#22823)
Fixes several runtimes from the past few weeks, some additional material
repath regressions, and the fact that if I shoot you with a stream of
ionized deuterium particles, it doesn't riddle you with cancer.

changes:
- bugfix: "Fixes emergency shields runtiming when hit by thrown
objects."
  - bugfix: "Fixes several stale global list runtimes."
- bugfix: "Fixes several health percentage checks that could use unset
initial health values."
  - bugfix: "Fixes additional materials regressions in INDRA code."
  - bugfix: "Fixes invalid fuel injector depletion math."
- bugfix: "Makes accelerated particles apply radiation damage to living
mobs they pass through."
2026-07-12 18:06:28 +00:00

151 lines
5.1 KiB
Plaintext

SUBSYSTEM_DEF(materials)
name = "Materials"
init_order = INIT_ORDER_MISC_FIRST
flags = SS_NO_FIRE
var/list/materials_by_name
/datum/controller/subsystem/materials/Initialize()
create_material_names_list()
return SS_INIT_SUCCESS
/**
* Initialize the lists of materials, if they are not initialized already
*/
/datum/controller/subsystem/materials/proc/create_material_names_list()
if(LAZYLEN(materials_by_name))
return
materials_by_name = list()
for(var/M in subtypesof(/singleton/material))
var/singleton/material/material = new M
if(material.name)
materials_by_name[lowertext(material.name)] = material
/**
* Returns a `/material` based on its name, or null if the material does not exists
*
* * material_name - A string, lowercase, representing the name of the material
* * log_missing - Whether to stack trace if the material was not found
*/
/datum/controller/subsystem/materials/proc/get_material_by_name(var/material_name, var/log_missing = TRUE)
if(!istext(material_name))
return
if(!materials_by_name)
create_material_names_list()
material_name = lowertext(material_name)
if(material_name == "metal")
material_name = "steel" // old DEFAULT_WALL_MATERIAL_NAME
. = materials_by_name[material_name]
if(!. && log_missing)
stack_trace("SSmaterials received a request for a material that was not found: [material_name].")
/**
* Returns a `/material` based on either its singleton path or name.
*
* * material_id - A `/singleton/material` path, a material datum, a material name, or href text containing a material path
* * log_missing - Whether to stack trace if the material was not found
*/
/datum/controller/subsystem/materials/proc/get_material_by_id(var/material_id, var/log_missing = TRUE)
if(ispath(material_id, /singleton/material))
return GET_SINGLETON(material_id)
if(istype(material_id, /singleton/material))
var/singleton/material/material = material_id
return material
if(istext(material_id))
var/material_path = text2path(material_id)
if(ispath(material_path, /singleton/material))
return GET_SINGLETON(material_path)
return get_material_by_name(material_id, log_missing)
if(log_missing)
stack_trace("SSmaterials received a request for an invalid material id: [material_id].")
/**
* Returns the canonical `/singleton/material` path for any supported material id.
*/
/datum/controller/subsystem/materials/proc/material_to_path(var/material_id, var/log_missing = TRUE)
var/singleton/material/material = get_material_by_id(material_id, log_missing)
if(material)
return material.type
/**
* Normalizes a material amount list in-place to singleton material path keys.
*/
/datum/controller/subsystem/materials/proc/normalize_material_amounts(var/list/materials)
if(!islist(materials))
return
var/list/normalized = list()
for(var/material_id in materials)
var/material_path = material_to_path(material_id, FALSE)
if(!material_path)
material_path = material_id
normalized[material_path] = (normalized[material_path] || 0) + materials[material_id]
materials.Cut()
for(var/material_id in normalized)
materials[material_id] = normalized[material_id]
/**
* Returns the amount of a material in a list, accepting either old names or singleton paths.
*/
/datum/controller/subsystem/materials/proc/get_material_amount(var/list/materials, var/material_id)
if(!islist(materials))
return 0
var/material_path = material_to_path(material_id, FALSE)
if(!material_path)
return materials[material_id] || 0
var/amount = materials[material_path] || 0
var/singleton/material/material = get_material_by_id(material_path, FALSE)
if(material?.name)
amount += materials[material.name] || 0
return amount
/**
* Adds a material amount to a list under its canonical singleton path key.
*/
/datum/controller/subsystem/materials/proc/add_material_amount(var/list/materials, var/material_id, var/amount)
if(!islist(materials) || !amount)
return
var/material_path = material_to_path(material_id, FALSE)
if(!material_path)
material_path = material_id
materials[material_path] = (materials[material_path] || 0) + amount
/**
* Removes a material amount from a list under its canonical singleton path key.
*/
/datum/controller/subsystem/materials/proc/remove_material_amount(var/list/materials, var/material_id, var/amount)
if(!islist(materials) || !amount)
return
var/material_path = material_to_path(material_id, FALSE)
if(!material_path)
material_path = material_id
materials[material_path] = max(0, (materials[material_path] || 0) - amount)
/**
* Returns the stack type associated with a material id.
*/
/datum/controller/subsystem/materials/proc/material_stack_type(var/material_id)
var/singleton/material/material = get_material_by_id(material_id, FALSE)
return material?.stack_type
/**
* Returns a material display name.
*
* * material_name - Any material id accepted by `get_material_by_id`.
*/
/datum/controller/subsystem/materials/proc/material_display_name(var/material_name)
var/singleton/material/material = get_material_by_id(material_name, FALSE)
if(material)
return capitalize(material.display_name)
return "[material_name]"