mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-28 01:51:46 +00:00
* Material container & related stuff ui refactors & clean-up (#76220) ## About The Pull Request **1. Material container clean-up & refactor** - Replaced `total_amount` var with `total_amount()` proc, this var can be easily computed by summing up all material amounts rather than storing it as a var which is tedious to update & keep track of when materials are added/removed - Removed unused procs `transer_amt_to()`, `can_insert_amount_mat()`, and `get_categories()`. These procs are not used anywhere in the codebase so let's remove them & make some space. - Callbacks are replaced with signals, the callbacks don't need to be explicitly garbage collected & having macros & procs marked with `SIGNAL_HANDLER` makes your intentions more readable & explicit. - Fixes #76151 All material adding, removal, checking operations are "Integer" operations, i.e. the final value is rounded & them made 1 if the final value is 0 using the macro `OPTIMIZE_COST`[coudn't come up with a better name]. No more dealing with decimal value materials The problem was after the protolathe was upgraded with better parts all the design costs were multiplied with a decimal `efficiency_coeff` value, this means even though in the UI the cost was displayed as 60 bluespace crystals its actual cost was `60.0001` something in the backend causing this check for materials to fail & print the error message. - Replaced `GetComponent(/datum/component_material_container)` with just a simple ref to the material container when adding the component, so we can save some overhead from calling this proc - Gave all procs a ton of documentation with documentation having documentation - Fixes #76506 RCD and other devices that uses the silo link upgrade now have the correct material usages - Fixes #72096. It wasn't just a problem with ancient protolathe but with all machines that used `datum/component/remote_materials` the problem was remote materials would add an instance of `datum/remote/material_container` if it wanted to use local storage but this component would get added before `datum/component/remote_materials` could be registered i.e. it comes before remote_materials in the component list. So when the machine is destroyed it will first destroy `material_container` & then `remote_materials` therefore destroying the materials before they could get ejected - Silo link is established when parent is registered with remote materials raher than adding an external timer which is faster - Everything that uses a material container will auto eject their sheets when destroyed - Moved this & remote materials into its own folder for better organization **2. Material UI Changes** - Removed the x25 & x50 print buttons from the autolathe, now they just have x5 & x10 buttons like the protolathe, These buttons were of no use since you could just type the exact amount you want to print in the `[Max: <some amount>]` side bar. The code to compute these buttons was just plain right nasty & some of it unused in the UI. - The material eject button in the material bar does not gray out when you can eject exactly one sheet - All material cost are integer values rounded - Fixes #76253 Exosuit Fabricator sends the material container static data to the UI so its material bar is not greyed out when there are sufficient materials to eject - Component printer material bar sends the material container static data to the UI so its material bar is not greyed out when there are sufficient materials to eject - Autolathe Material bars now display number of sheets available - Max printable amount of items are now computed & updated correctly in the UI. They were displaying wrong values & now get updated when items are printed, materials are removed - Silo hold actually works now. When a machine is put on hold it calls this proce929cf39cd/code/datums/components/remote_materials.dm (L78-L87)Notice how the key is `src` so we should be consistent during checking if a machine is on hold using the same `src` var. But for some reason we did dumb shit like thise929cf39cd/code/datums/components/remote_materials.dm (L150-L153)What is category? Why do we care for the area the machine is in? None of it made sense so i removed all that junk and just made it check for `src` like it should - Removed redundant `removable` & `sheets` var from the material container ui_data. These vars are unused in the UI - If an item does not have the required materials then upon clicking that item you will not get any error message but instead nothing happens ## Changelog 🆑 fix: items can be printed from autolathe & protolathe when the exact material amounts are present in them after upgrading fix: max printable amount now shows the correct value & updates when items are printed, materials are removed in the autolathe & protolathe fix: component printer material bar is not greyed out when there are sufficient materials to eject fix: rcd and other devices that uses the silo link upgrade now have the correct material usages fix: silo hold actually works fix: machines using local storage to hold materials will eject it's materials as sheets when deconstructed/destroyed refactor: Autolathe Material bars now display number of sheets available refactor: printing an item that does not have enough materials will fail silently with no error messages refactor: Drone dispenser will eject sheets upon deconstruction refactor: all things that store materials will auto ejects its sheets(if there is sufficient material) when destroyed refactor: inserting an item into the material container will display the units consumed as sheets not absolute units refactor: removed x25 & x50 print buttons from the autolathe * Material container & related stuff ui refactors & clean-up * Update ammo_workbench.dm --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
189 lines
6.0 KiB
Plaintext
189 lines
6.0 KiB
Plaintext
/*
|
|
This component allows machines to connect remotely to a material container
|
|
(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful
|
|
fallback to a local material storage in case remote storage is unavailable, and
|
|
handles linking back and forth.
|
|
*/
|
|
|
|
/datum/component/remote_materials
|
|
// Three possible states:
|
|
// 1. silo exists, materials is parented to silo
|
|
// 2. silo is null, materials is parented to parent
|
|
// 3. silo is null, materials is null
|
|
|
|
/// The silo machine this container is connected to
|
|
var/obj/machinery/ore_silo/silo
|
|
//material container. the value is either the silo or local
|
|
var/datum/component/material_container/mat_container
|
|
//should we create a local storage if we can't connect to silo
|
|
var/allow_standalone
|
|
//are we trying to connect to the silo
|
|
var/connecting
|
|
//local size of container when silo = null
|
|
var/local_size = INFINITY
|
|
///Flags used when converting inserted materials into their component materials.
|
|
var/mat_container_flags = NONE
|
|
|
|
/datum/component/remote_materials/Initialize(mapload, allow_standalone = TRUE, force_connect = FALSE, mat_container_flags = NONE)
|
|
if (!isatom(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.allow_standalone = allow_standalone
|
|
src.mat_container_flags = mat_container_flags
|
|
|
|
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(OnAttackBy))
|
|
RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(OnMultitool))
|
|
|
|
var/turf/T = get_turf(parent)
|
|
if(force_connect || (mapload && is_station_level(T.z)))
|
|
connecting = TRUE
|
|
|
|
/datum/component/remote_materials/RegisterWithParent()
|
|
if (connecting)
|
|
silo = GLOB.ore_silo_default
|
|
if (silo)
|
|
silo.ore_connected_machines += src
|
|
mat_container = silo.GetComponent(/datum/component/material_container)
|
|
connecting = FALSE
|
|
if (!mat_container && allow_standalone)
|
|
_MakeLocal()
|
|
|
|
/datum/component/remote_materials/Destroy()
|
|
if (silo)
|
|
silo.ore_connected_machines -= src
|
|
silo.holds -= src
|
|
silo.updateUsrDialog()
|
|
silo = null
|
|
mat_container = null
|
|
return ..()
|
|
|
|
/datum/component/remote_materials/proc/_MakeLocal()
|
|
silo = null
|
|
|
|
var/static/list/allowed_mats = list(
|
|
/datum/material/iron,
|
|
/datum/material/glass,
|
|
/datum/material/silver,
|
|
/datum/material/gold,
|
|
/datum/material/diamond,
|
|
/datum/material/plasma,
|
|
/datum/material/uranium,
|
|
/datum/material/bananium,
|
|
/datum/material/titanium,
|
|
/datum/material/bluespace,
|
|
/datum/material/plastic,
|
|
)
|
|
|
|
mat_container = parent.AddComponent( \
|
|
/datum/component/material_container, \
|
|
allowed_mats, \
|
|
local_size, \
|
|
mat_container_flags, \
|
|
allowed_items = /obj/item/stack \
|
|
)
|
|
|
|
/datum/component/remote_materials/proc/toggle_holding(force_hold = FALSE)
|
|
if(isnull(silo))
|
|
return
|
|
|
|
if(force_hold)
|
|
silo.holds[src] = TRUE
|
|
else if(!silo.holds[src])
|
|
silo.holds[src] = TRUE
|
|
else
|
|
silo.holds -= src
|
|
|
|
/datum/component/remote_materials/proc/set_local_size(size)
|
|
local_size = size
|
|
if (!silo && mat_container)
|
|
mat_container.max_amount = size
|
|
|
|
// called if disconnected by ore silo UI or destruction
|
|
/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo)
|
|
if (!old_silo || silo != old_silo)
|
|
return
|
|
silo.ore_connected_machines -= src
|
|
silo = null
|
|
mat_container = null
|
|
if (allow_standalone)
|
|
_MakeLocal()
|
|
|
|
/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if (silo && isstack(I))
|
|
if (silo.remote_attackby(parent, user, I, mat_container_flags))
|
|
return COMPONENT_NO_AFTERATTACK
|
|
|
|
/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!I.multitool_check_buffer(user, I))
|
|
return COMPONENT_BLOCK_TOOL_ATTACK
|
|
var/obj/item/multitool/M = I
|
|
if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
|
|
if (silo == M.buffer)
|
|
to_chat(user, span_warning("[parent] is already connected to [silo]!"))
|
|
return COMPONENT_BLOCK_TOOL_ATTACK
|
|
if(!check_z_level(M.buffer))
|
|
to_chat(user, span_warning("[parent] is too far away to get a connection signal!"))
|
|
return COMPONENT_BLOCK_TOOL_ATTACK
|
|
if (silo)
|
|
silo.ore_connected_machines -= src
|
|
silo.holds -= src
|
|
silo.updateUsrDialog()
|
|
else if (mat_container)
|
|
qdel(mat_container)
|
|
silo = M.buffer
|
|
silo.ore_connected_machines += src
|
|
silo.updateUsrDialog()
|
|
mat_container = silo.GetComponent(/datum/component/material_container)
|
|
to_chat(user, span_notice("You connect [parent] to [silo] from the multitool's buffer."))
|
|
return COMPONENT_BLOCK_TOOL_ATTACK
|
|
|
|
/datum/component/remote_materials/proc/check_z_level(obj/silo_to_check)
|
|
SIGNAL_HANDLER
|
|
if(!silo_to_check)
|
|
if(isnull(silo))
|
|
return FALSE
|
|
silo_to_check = silo
|
|
|
|
var/turf/current_turf = get_turf(parent)
|
|
var/turf/silo_turf = get_turf(silo_to_check)
|
|
if(!is_valid_z_level(silo_turf, current_turf))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/component/remote_materials/proc/on_hold()
|
|
if(!check_z_level())
|
|
return FALSE
|
|
return silo.holds[src]
|
|
|
|
/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
|
|
if (silo)
|
|
silo.silo_log(M || parent, action, amount, noun, mats)
|
|
|
|
/datum/component/remote_materials/proc/format_amount()
|
|
if (mat_container)
|
|
return "[mat_container.total_amount()] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
|
|
else
|
|
return "0 / 0"
|
|
|
|
/// Ejects the given material ref and logs it, or says out loud the problem.
|
|
/datum/component/remote_materials/proc/eject_sheets(datum/material/material_ref, eject_amount)
|
|
var/atom/movable/movable_parent = parent
|
|
if (!istype(movable_parent))
|
|
return 0
|
|
|
|
if (!mat_container)
|
|
movable_parent.say("No access to material storage, please contact the quartermaster.")
|
|
return 0
|
|
if (on_hold())
|
|
movable_parent.say("Mineral access is on hold, please contact the quartermaster.")
|
|
return 0
|
|
var/count = mat_container.retrieve_sheets(eject_amount, material_ref, movable_parent.drop_location())
|
|
var/list/matlist = list()
|
|
matlist[material_ref] = eject_amount
|
|
silo_log(parent, "ejected", -count, "sheets", matlist)
|
|
return count
|