mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-07-22 15:23:04 +01:00
935126228a
Co-authored-by: silicons <silicons@silicons.dev>
245 lines
6.3 KiB
Plaintext
245 lines
6.3 KiB
Plaintext
/datum/material_container
|
|
/// solid materials (so usually sheets), keyed by ID
|
|
var/list/stored
|
|
/// space available for materials - list with ids for specific, null for infinite, just a number for combined
|
|
var/list/capacity
|
|
|
|
/datum/material_container/New(list/materials_capacity)
|
|
src.capacity = materials_capacity
|
|
|
|
/datum/material_container/proc/set_capacity(new_capacity)
|
|
capacity = new_capacity
|
|
|
|
/datum/material_container/proc/set_multiplied_capacity(new_capacity, multiplier = 1)
|
|
if(isnull(new_capacity))
|
|
capacity = new_capacity
|
|
else if(isnum(new_capacity))
|
|
capacity = new_capacity * multiplier
|
|
else if(islist(new_capacity))
|
|
var/list/built = new_capacity
|
|
built = built.Copy()
|
|
for(var/key in built)
|
|
built[key] *= multiplier
|
|
capacity = built
|
|
|
|
/**
|
|
* dumps everything out
|
|
*
|
|
* @params
|
|
* * where - where to put everything
|
|
*/
|
|
/datum/material_container/proc/dump_everything(atom/where)
|
|
if(isnull(stored))
|
|
return
|
|
for(var/mat_id in stored)
|
|
var/datum/prototype/material/M = RSmaterials.fetch(mat_id)
|
|
if(isnull(M))
|
|
continue
|
|
var/safety = 50
|
|
var/sheets = round(stored[mat_id] / SHEET_MATERIAL_AMOUNT)
|
|
stored[mat_id] -= sheets * SHEET_MATERIAL_AMOUNT
|
|
var/obj/item/stack/stack_type = M.stack_type
|
|
if(!stack_type)
|
|
continue
|
|
var/stack_size = initial(stack_type.max_amount)
|
|
if(!stack_size)
|
|
continue
|
|
while(sheets > 0)
|
|
var/wanted = min(stack_size, sheets)
|
|
M.place_sheet(where, wanted)
|
|
sheets -= wanted
|
|
if(!--safety)
|
|
break
|
|
// if we somehow have remaining, which we shouldn't
|
|
stored[mat_id] += sheets * SHEET_MATERIAL_AMOUNT
|
|
|
|
/**
|
|
* dumps x sheets of y material
|
|
*
|
|
* @params
|
|
* * where - where to dump
|
|
* * material - material id or instance
|
|
* * amount - sheets to dump; defaults to as many as possible
|
|
*
|
|
* @return sheets dumped
|
|
*/
|
|
/datum/material_container/proc/dump(atom/where, datum/prototype/material/material, amount = INFINITY)
|
|
if(amount < 0)
|
|
CRASH("negative amount?")
|
|
if(!istype(material))
|
|
material = RSmaterials.fetch(material)
|
|
var/can_dump = round(stored[material.id] / SHEET_MATERIAL_AMOUNT)
|
|
var/dumping = min(amount, can_dump)
|
|
stored[material.id] -= dumping * SHEET_MATERIAL_AMOUNT
|
|
var/safety = 50
|
|
. = 0
|
|
var/obj/item/stack/stack_type = material.stack_type
|
|
var/stack_size = initial(stack_type.max_amount)
|
|
if(!stack_type)
|
|
return 0
|
|
while(dumping > 0)
|
|
var/wanted = min(stack_size, dumping)
|
|
material.place_sheet(where, wanted)
|
|
dumping -= wanted
|
|
. += wanted
|
|
if(!--safety)
|
|
break
|
|
|
|
/**
|
|
* Inserts sheets
|
|
*
|
|
* Will use() / delete the sheets as needed
|
|
*
|
|
* If you want to just tick materials up, directly access the lists.
|
|
*
|
|
* @params
|
|
* * inserting - sheets
|
|
* * amount - max to insert
|
|
* * force - ignore capacity
|
|
*
|
|
* @return sheets consumed
|
|
*/
|
|
/datum/material_container/proc/insert_sheets(obj/item/stack/material/inserting, amount = INFINITY, force = FALSE)
|
|
if(!istype(inserting))
|
|
return 0
|
|
LAZYINITLIST(stored)
|
|
var/datum/prototype/material/mat = inserting.material
|
|
var/allowed = capacity_material_sheets(mat)
|
|
var/inserted = min(allowed, inserting.amount)
|
|
inserting.use(inserted)
|
|
stored[mat.id] += inserted * SHEET_MATERIAL_AMOUNT
|
|
return inserted
|
|
|
|
/**
|
|
* has space for sheets
|
|
*
|
|
* @return sheets remaining of capacity
|
|
*/
|
|
/datum/material_container/proc/capacity_sheets(obj/item/stack/material/inserting)
|
|
if(!istype(inserting))
|
|
return 0
|
|
var/datum/prototype/material/mat = inserting.material
|
|
return capacity_material_sheets(mat)
|
|
|
|
/**
|
|
* is this sheet instance allowed
|
|
*/
|
|
/datum/material_container/proc/allowed_sheets(obj/item/stack/material/inserting)
|
|
if(!istype(inserting))
|
|
return 0
|
|
return allowed_material(inserting.material)
|
|
|
|
/**
|
|
* has space for material
|
|
*
|
|
* @params
|
|
* * mat - material instance
|
|
*
|
|
* @return number of sheets allowed
|
|
*/
|
|
/datum/material_container/proc/capacity_material_sheets(datum/prototype/material/mat)
|
|
if(isnull(capacity))
|
|
return INFINITY
|
|
if(isnum(capacity))
|
|
return max(0, round((capacity - total_stored()) / SHEET_MATERIAL_AMOUNT))
|
|
if(islist(capacity))
|
|
var/cap = capacity[mat.id]
|
|
var/cur = stored[mat.id]
|
|
if(isnull(cap))
|
|
return 0
|
|
return max(0, round((cap - cur) / SHEET_MATERIAL_AMOUNT))
|
|
CRASH("what?")
|
|
|
|
/**
|
|
* is this material allowed
|
|
*/
|
|
/datum/material_container/proc/allowed_material(datum/prototype/material/mat)
|
|
return isnull(capacity) || isnum(capacity) || !isnull(capacity[mat.id])
|
|
|
|
/**
|
|
* total utilization in units, not sheets
|
|
*/
|
|
/datum/material_container/proc/total_stored()
|
|
. = 0
|
|
if(isnull(stored))
|
|
return
|
|
for(var/key in stored)
|
|
. += stored[key]
|
|
|
|
/**
|
|
* uses the given resources, failing if not enough
|
|
*
|
|
* @params
|
|
* * sheets - units of sheets to use
|
|
* * multiplier - multiplier for actual amount, for convenience
|
|
*
|
|
* @return TRUE / FALSE based on success / fail
|
|
*/
|
|
/datum/material_container/proc/checked_use(list/using, multiplier = 1)
|
|
if(!has(using, multiplier))
|
|
return FALSE
|
|
use(using, multiplier)
|
|
return TRUE
|
|
|
|
/**
|
|
* uses the given resources
|
|
*
|
|
* @params
|
|
* * sheets - units of sheets to use
|
|
* * multiplier - multiplier to actual amount, for convenience
|
|
*/
|
|
/datum/material_container/proc/use(list/using, multiplier = 1)
|
|
if(isnull(stored))
|
|
return
|
|
for(var/key in using)
|
|
if(isnull(stored[key]))
|
|
continue
|
|
stored[key] = max(0, stored[key] - using[key] * multiplier)
|
|
|
|
/**
|
|
* checks if we have the given resources
|
|
*
|
|
* @params
|
|
* * sheets - units of sheets
|
|
* * multiplier - multiplier to actual amount, for convenience
|
|
*/
|
|
/datum/material_container/proc/has(list/wanted, multiplier = 1)
|
|
if(isnull(stored))
|
|
return FALSE
|
|
for(var/key in wanted)
|
|
if(stored[key] < wanted[key] * multiplier)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/**
|
|
* basically, divides by given resources and takes lowest.
|
|
*/
|
|
/datum/material_container/proc/has_multiple(list/wanted)
|
|
if(isnull(stored))
|
|
return 0
|
|
. = INFINITY
|
|
for(var/key in wanted)
|
|
if(!wanted[key])
|
|
continue
|
|
. = min(., stored[key] / wanted[key])
|
|
if(!.)
|
|
return
|
|
|
|
/datum/material_container/proc/has_space(list/materials, multiplier = 1)
|
|
LAZYINITLIST(stored)
|
|
if(isnull(capacity))
|
|
return TRUE
|
|
if(isnum(capacity))
|
|
var/tally = 0
|
|
for(var/key in materials)
|
|
tally += materials[key]
|
|
return (capacity - (tally * multiplier + total_stored())) > 0
|
|
|
|
/datum/material_container/proc/add(list/materials, multiplier = 1)
|
|
LAZYINITLIST(stored)
|
|
for(var/key in materials)
|
|
stored[key] += materials[key] * multiplier
|
|
|
|
/datum/material_container/proc/ui_storage_data()
|
|
. = isnull(stored)? list() : stored.Copy()
|