mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 00:29:02 +01:00
General code maintenance for Mat container related stuff (#77671)
1. Removes `/obj/machinery/ore_silo/proc/remote_attackby()`. This proc calls `datum/component/material_container/user_insert()` anyway which performs all the checks necessary for inserting stuff into the ore silo and `/obj/machinery/ore_silo/proc/remote_attackby()` was just repeating its code & checks. So now inserting into the ore silo is directly handled by the mat container without this proxy proc making the operation slightly faster 2. Removed silo `attackby` code. Same operations can be done via `screwdriver_act` & `crowbar_act` procs much cleaner 3. The ore silo now hooks onto signals `COMSIG_MATCONTAINER_ITEM_CONSUMED` and `COMSIG_MATCONTAINER_SHEETS_RETRIVED` and logs into silo when they are triggered. This means when you insert/eject sheets from the silo the connected machine performing the operation no longer has to do the logging manually thus the proc `silo_log` has been removed from a lot of places ,reducing overall code size 4. A lot of stuff that use materials from the ore silo follow this pattern. i.e. They first use the materials from the silo and then log it via `silo_log` proc. This code pattern is repeated in a lot of places so let's just merge these 2 lines with some extra sanity checks into a single proc inside `remote_materials` itself. That's what was done and the number of places where you log manually into the silo has been removed further reducing code size everywhere. 5. Added auto doc & cleaned up some procs Since logging is now done by the ore silo directly, we need a way to pass the machine that is inserting items into the silo to the signal handlers of the ore silo [via the `context` var]. So other code changes elsewhere is because of this var
This commit is contained in:
@@ -131,19 +131,27 @@
|
||||
* - [source][/obj/item]: The source of the materials we are inserting.
|
||||
* - multiplier: The multiplier for the materials extract from this item being inserted.
|
||||
* - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
|
||||
* - context: the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED and is used mostly for silo logging
|
||||
*/
|
||||
/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags)
|
||||
/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags, atom/context = parent)
|
||||
var/primary_mat
|
||||
var/max_mat_value = 0
|
||||
var/material_amount = 0
|
||||
|
||||
var/list/item_materials = source.get_material_composition(breakdown_flags)
|
||||
var/list/mats_consumed = list()
|
||||
for(var/MAT in item_materials)
|
||||
if(!can_hold_material(MAT))
|
||||
continue
|
||||
materials[MAT] += OPTIMAL_COST(item_materials[MAT] * multiplier)
|
||||
var/mat_amount = OPTIMAL_COST(item_materials[MAT] * multiplier)
|
||||
materials[MAT] += mat_amount
|
||||
if(item_materials[MAT] > max_mat_value)
|
||||
max_mat_value = item_materials[MAT]
|
||||
primary_mat = MAT
|
||||
mats_consumed[MAT] = mat_amount
|
||||
material_amount += mat_amount
|
||||
if(length(mats_consumed))
|
||||
SEND_SIGNAL(src, COMSIG_MATCONTAINER_ITEM_CONSUMED, source, primary_mat, mats_consumed, material_amount, context)
|
||||
|
||||
return primary_mat
|
||||
//===================================================================================
|
||||
@@ -188,15 +196,16 @@
|
||||
* - [weapon][obj/item]: the item you are trying to insert
|
||||
* - multiplier: The multiplier for the materials being inserted
|
||||
* - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
|
||||
* - context: the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED and is used mostly for silo logging
|
||||
*/
|
||||
/datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, breakdown_flags = mat_container_flags)
|
||||
/datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, breakdown_flags = mat_container_flags, atom/context = parent)
|
||||
if(QDELETED(weapon))
|
||||
return MATERIAL_INSERT_ITEM_NO_MATS
|
||||
multiplier = CEILING(multiplier, 0.01)
|
||||
|
||||
var/obj/item/target = weapon
|
||||
|
||||
var/material_amount = get_item_material_amount(target, breakdown_flags) * multiplier
|
||||
var/material_amount = OPTIMAL_COST(get_item_material_amount(target, breakdown_flags) * multiplier)
|
||||
if(!material_amount)
|
||||
return MATERIAL_INSERT_ITEM_NO_MATS
|
||||
var/obj/item/stack/item_stack
|
||||
@@ -218,9 +227,8 @@
|
||||
return MATERIAL_INSERT_ITEM_NO_SPACE
|
||||
|
||||
//do the insert
|
||||
var/last_inserted_id = insert_item_materials(target, multiplier, breakdown_flags)
|
||||
var/last_inserted_id = insert_item_materials(target, multiplier, breakdown_flags, context)
|
||||
if(!isnull(last_inserted_id))
|
||||
SEND_SIGNAL(src, COMSIG_MATCONTAINER_ITEM_CONSUMED, target, last_inserted_id, material_amount, src)
|
||||
qdel(target) //item gone
|
||||
return material_amount
|
||||
else if(!isnull(item_stack) && item_stack != target) //insertion failed, merge the split stack back into the original
|
||||
@@ -242,8 +250,9 @@
|
||||
* * held_item - the item to insert
|
||||
* * user - the mob inserting this item
|
||||
* * breakdown_flags - how this item and all it's contents inside are broken down during insertion. This is unique to the machine doing the insertion
|
||||
* * context - the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED and is used mostly for silo logging
|
||||
*/
|
||||
/datum/component/material_container/proc/user_insert(obj/item/held_item, mob/living/user, breakdown_flags = mat_container_flags)
|
||||
/datum/component/material_container/proc/user_insert(obj/item/held_item, mob/living/user, breakdown_flags = mat_container_flags, atom/context = parent)
|
||||
set waitfor = FALSE
|
||||
. = 0
|
||||
|
||||
@@ -327,7 +336,7 @@
|
||||
|
||||
//insert the item
|
||||
var/item_name = target.name
|
||||
var/inserted = insert_item(target, breakdown_flags = mat_container_flags)
|
||||
var/inserted = insert_item(target, 1, mat_container_flags, context)
|
||||
if(inserted > 0)
|
||||
. += inserted
|
||||
inserted /= SHEET_MATERIAL_AMOUNT // display units inserted as sheets for improved readability
|
||||
@@ -564,44 +573,52 @@
|
||||
* sheet_amt: number of sheets to extract
|
||||
* [material][datum/material]: type of sheets present in this container to extract
|
||||
* [target][atom]: drop location
|
||||
* [atom][context]: context - the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_SHEETS_RETRIVED and is used mostly for silo logging
|
||||
*/
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/material, atom/target = null)
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/material, atom/target = null, atom/context = parent)
|
||||
//do we support sheets of this material
|
||||
if(!material.sheet_type)
|
||||
return 0 //Add greyscale sheet handling here later
|
||||
if(sheet_amt <= 0)
|
||||
if(!can_hold_material(material))
|
||||
return 0
|
||||
|
||||
//requested amount greater than available amount or just an invalid value
|
||||
sheet_amt = min(round(materials[material] / SHEET_MATERIAL_AMOUNT), sheet_amt)
|
||||
if(sheet_amt <= 0)
|
||||
return 0
|
||||
//auto drop location
|
||||
if(!target)
|
||||
var/atom/parent_atom = parent
|
||||
target = parent_atom.drop_location()
|
||||
if(materials[material] < (sheet_amt * SHEET_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(materials[material] / SHEET_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, MAX_STACK_SIZE, null, list((material) = SHEET_MATERIAL_AMOUNT))
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIVED, new_sheets)
|
||||
if(sheet_amt >= 1)
|
||||
var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, sheet_amt, null, list((material) = SHEET_MATERIAL_AMOUNT))
|
||||
count += sheet_amt
|
||||
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material)
|
||||
SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIVED, new_sheets)
|
||||
return count
|
||||
if(!target)
|
||||
return 0
|
||||
|
||||
//eject sheets based on available amount after each iteration
|
||||
var/count = 0
|
||||
while(sheet_amt > 0)
|
||||
//create sheets in null space so it doesn't merge & delete itself
|
||||
var/obj/item/stack/sheet/new_sheets = new material.sheet_type(null, min(sheet_amt, MAX_STACK_SIZE), null, list((material) = SHEET_MATERIAL_AMOUNT))
|
||||
count += new_sheets.amount
|
||||
//use material & deduct work needed
|
||||
use_amount_mat(new_sheets.amount * SHEET_MATERIAL_AMOUNT, material)
|
||||
sheet_amt -= new_sheets.amount
|
||||
//send signal
|
||||
SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIVED, new_sheets, context)
|
||||
//now move to target so it gets merged
|
||||
new_sheets.forceMove(target)
|
||||
return count
|
||||
|
||||
/**
|
||||
* Proc to get all the materials and dump them as sheets
|
||||
*
|
||||
* Arguments:
|
||||
* - target: drop location of the sheets
|
||||
* - context: the atom which is ejecting the sheets. Used mostly in silo logging
|
||||
*/
|
||||
/datum/component/material_container/proc/retrieve_all(target = null)
|
||||
/datum/component/material_container/proc/retrieve_all(target = null, atom/context = parent)
|
||||
var/result = 0
|
||||
for(var/MAT in materials)
|
||||
var/amount = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(amount), MAT, target)
|
||||
result += retrieve_sheets(amount2sheet(materials[MAT]), MAT, target, context)
|
||||
return result
|
||||
//============================================================================================
|
||||
|
||||
|
||||
@@ -22,13 +22,6 @@ handles linking back and forth.
|
||||
///Flags used when converting inserted materials into their component materials.
|
||||
var/mat_container_flags = NONE
|
||||
|
||||
//Internal vars
|
||||
|
||||
///Prepare storage when component is registered to parent. This allows local material container(if created) to be first in the component list so it gets GC'd properly
|
||||
var/_prepare_on_register = FALSE
|
||||
///Are we trying to to connect to remote ore silo or not
|
||||
var/_connect_to_silo = FALSE
|
||||
|
||||
/datum/component/remote_materials/Initialize(mapload, allow_standalone = TRUE, force_connect = FALSE, mat_container_flags = NONE)
|
||||
if (!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
@@ -36,23 +29,26 @@ handles linking back and forth.
|
||||
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)
|
||||
_connect_to_silo = FALSE
|
||||
var/connect_to_silo = FALSE
|
||||
if(force_connect || (mapload && is_station_level(T.z)))
|
||||
_connect_to_silo = TRUE
|
||||
connect_to_silo = TRUE
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, TYPE_PROC_REF(/datum/component/remote_materials, SiloAttackBy))
|
||||
|
||||
if(mapload) // wait for silo to initialize during mapload
|
||||
addtimer(CALLBACK(src, PROC_REF(_PrepareStorage), _connect_to_silo))
|
||||
addtimer(CALLBACK(src, PROC_REF(_PrepareStorage), connect_to_silo))
|
||||
else //directly register in round
|
||||
_prepare_on_register = TRUE
|
||||
|
||||
/datum/component/remote_materials/RegisterWithParent()
|
||||
if(_prepare_on_register)
|
||||
_PrepareStorage(_connect_to_silo)
|
||||
_PrepareStorage(connect_to_silo)
|
||||
|
||||
/**
|
||||
* Internal proc. prepares local storage if onnect_to_silo = FALSE
|
||||
*
|
||||
* Arguments
|
||||
* connect_to_silo- if true connect to global silo. If not successfull then go to local storage
|
||||
* only if allow_standalone = TRUE, else you a null mat_container
|
||||
*/
|
||||
/datum/component/remote_materials/proc/_PrepareStorage(connect_to_silo)
|
||||
if (connect_to_silo)
|
||||
silo = GLOB.ore_silo_default
|
||||
@@ -112,7 +108,12 @@ handles linking back and forth.
|
||||
if (!silo && mat_container)
|
||||
mat_container.max_amount = size
|
||||
|
||||
// called if disconnected by ore silo UI or destruction
|
||||
/**
|
||||
* Disconnect this component from the remote silo
|
||||
*
|
||||
* Arguments
|
||||
* old_silo- The silo we are trying to disconnect from
|
||||
*/
|
||||
/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo)
|
||||
if (!old_silo || silo != old_silo)
|
||||
return
|
||||
@@ -122,12 +123,14 @@ handles linking back and forth.
|
||||
if (allow_standalone)
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
///Insert mats into silo
|
||||
/datum/component/remote_materials/proc/SiloAttackBy(datum/source, obj/item/target, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (silo && isstack(I))
|
||||
if (silo.remote_attackby(parent, user, I, mat_container_flags))
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
if(silo)
|
||||
mat_container.user_insert(target, user, mat_container_flags, parent)
|
||||
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I)
|
||||
SIGNAL_HANDLER
|
||||
@@ -152,52 +155,87 @@ handles linking back and forth.
|
||||
silo.ore_connected_machines += src
|
||||
silo.updateUsrDialog()
|
||||
mat_container = silo.GetComponent(/datum/component/material_container)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, TYPE_PROC_REF(/datum/component/remote_materials, SiloAttackBy))
|
||||
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
|
||||
/**
|
||||
* Checks if the param silo is in the same level as this components parent i.e. connected machine, rcd, etc
|
||||
*
|
||||
* Arguments
|
||||
* silo_to_check- Is this components parent in the same Z level as this param silo. If null
|
||||
* then check this components connected silo
|
||||
*
|
||||
* Returns true if both are on the station or same z level
|
||||
*/
|
||||
/datum/component/remote_materials/proc/check_z_level(obj/silo_to_check = silo)
|
||||
if(isnull(silo_to_check))
|
||||
return FALSE
|
||||
|
||||
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 is_valid_z_level(get_turf(silo_to_check), get_turf(parent))
|
||||
|
||||
/// returns TRUE if this connection put on hold by the silo
|
||||
/datum/component/remote_materials/proc/on_hold()
|
||||
return check_z_level() ? silo.holds[src] : FALSE
|
||||
|
||||
/**
|
||||
* Internal proc to check if this connection can use any materials from the silo
|
||||
* Returns true only if
|
||||
* - The parent is of type movable atom
|
||||
* - A mat container is actually present
|
||||
* - The silo in not on hold
|
||||
*/
|
||||
/datum/component/remote_materials/proc/_can_use_resource()
|
||||
var/atom/movable/movable_parent = parent
|
||||
if (!istype(movable_parent))
|
||||
return FALSE
|
||||
if (!mat_container) //no silolink & local storage not supported
|
||||
movable_parent.say("No access to material storage, please contact the quartermaster.")
|
||||
return FALSE
|
||||
if(on_hold()) //silo on hold
|
||||
movable_parent.say("Mineral access is on hold, please contact the quartermaster.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/component/remote_materials/proc/on_hold()
|
||||
if(!check_z_level())
|
||||
return FALSE
|
||||
return silo.holds[src]
|
||||
/**
|
||||
* Use materials from either the silo(if connected) or from the local storage. If silo then this action
|
||||
* is logged else not e.g. action="build" & name="matter bin" means you are trying to build an matter bin
|
||||
*
|
||||
* Arguments
|
||||
* [mats][list]- list of materials to use
|
||||
* coefficient- each mat unit is scaled by this value then rounded. This value if usually your machine efficiency e.g. upgraded protolathe has reduced costs
|
||||
* multiplier- each mat unit is scaled by this value then rounded after it is scaled by coefficient. This value is your print quatity e.g. printing multiple items
|
||||
* action- For logging only. e.g. build, create, i.e. the action you are trying to perform
|
||||
* name- For logging only. the design you are trying to build e.g. matter bin, etc.
|
||||
*/
|
||||
/datum/component/remote_materials/proc/use_materials(list/mats, coefficient = 1, multiplier = 1, action = "build", name = "design")
|
||||
if(!_can_use_resource())
|
||||
return 0
|
||||
|
||||
/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)
|
||||
var/amount_consumed = mat_container.use_materials(mats, coefficient, multiplier)
|
||||
|
||||
if (silo)//log only if silo is linked
|
||||
var/list/scaled_mats = list()
|
||||
for(var/i in mats)
|
||||
scaled_mats[i] = OPTIMAL_COST(OPTIMAL_COST(mats[i] * coefficient) * multiplier)
|
||||
silo.silo_log(parent, action, -multiplier, name, scaled_mats)
|
||||
|
||||
return amount_consumed
|
||||
|
||||
/**
|
||||
* Ejects the given material ref and logs it
|
||||
*
|
||||
* Arguments
|
||||
* [material_ref][datum/material]- The material type you are trying to eject
|
||||
* eject_amount- how many sheets to eject
|
||||
* [drop_target][atom]- optional where to drop the sheets. null means it is dropped at this components parent location
|
||||
*/
|
||||
/datum/component/remote_materials/proc/eject_sheets(datum/material/material_ref, eject_amount, atom/drop_target = null)
|
||||
if(!_can_use_resource())
|
||||
return 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(isnull(drop_target))
|
||||
drop_target = movable_parent.drop_location()
|
||||
|
||||
if (!mat_container) //no silolink & local storage not supported
|
||||
movable_parent.say("No access to material storage, please contact the quartermaster.")
|
||||
return 0
|
||||
if(!mat_container.can_hold_material(material_ref)) //material not supported by container
|
||||
movable_parent.say("Invalid material requested.")
|
||||
return 0
|
||||
if(eject_amount <= 0) //invalid amount
|
||||
movable_parent.say("Invalid amount requested.")
|
||||
return 0
|
||||
if(on_hold()) //silo 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
|
||||
return mat_container.retrieve_sheets(eject_amount, material_ref, target = drop_target, context = parent)
|
||||
|
||||
Reference in New Issue
Block a user