Files
Yogstation/code/datums/components/remote_materials.dm
Tad Hardesty 5fb15c0c22 [Ready] Communal Resource Storage II (#39118)
add: The vault now contains an ore silo where the station's minerals are stored.
add: The station's ORM, recycling, and the labor camp send materials to the silo via bluespace.
add: Protolathes, techfabs, and circuit imprinters all pull materials from the silo via bluespace.
add: Those with vault access can view mineral logs and pause or remove any machine's access, or add machines with a multitool.
tweak: The ORM's alloy recipes are now available in engineering and science protolathes.
2018-07-28 11:00:49 +02:00

112 lines
3.7 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
var/obj/machinery/ore_silo/silo
var/datum/component/material_container/mat_container
var/category
var/allow_standalone
var/local_size = INFINITY
/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE)
if (!isatom(parent))
return COMPONENT_INCOMPATIBLE
src.category = category
src.allow_standalone = allow_standalone
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
var/turf/T = get_turf(parent)
if (force_connect || (mapload && is_station_level(T.z)))
addtimer(CALLBACK(src, .proc/LateInitialize))
else if (allow_standalone)
_MakeLocal()
/datum/component/remote_materials/proc/LateInitialize()
silo = GLOB.ore_silo_default
if (silo)
silo.connected += src
mat_container = silo.GetComponent(/datum/component/material_container)
else
_MakeLocal()
/datum/component/remote_materials/Destroy()
if (silo)
silo.connected -= src
silo.updateUsrDialog()
silo = null
mat_container = null
else if (mat_container)
// specify explicitly in case the other component is deleted first
var/atom/P = parent
mat_container.retrieve_all(P.drop_location())
return ..()
/datum/component/remote_materials/proc/_MakeLocal()
silo = null
mat_container = parent.AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC),
local_size,
FALSE,
list(/obj/item/stack))
/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 = null
mat_container = null
if (allow_standalone)
_MakeLocal()
/datum/component/remote_materials/proc/OnAttackBy(obj/item/I, mob/user)
if (istype(I, /obj/item/multitool))
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 class='notice'>[parent] is already connected to [silo].</span>")
return COMPONENT_NO_AFTERATTACK
if (silo)
silo.connected -= src
silo.updateUsrDialog()
else if (mat_container)
mat_container.retrieve_all()
qdel(mat_container)
silo = M.buffer
silo.connected += src
silo.updateUsrDialog()
mat_container = silo.GetComponent(/datum/component/material_container)
to_chat(user, "<span class='notice'>You connect [parent] to [silo] from the multitool's buffer.</span>")
return COMPONENT_NO_AFTERATTACK
else if (silo && istype(I, /obj/item/stack))
if (silo.remote_attackby(parent, user, I))
return COMPONENT_NO_AFTERATTACK
/datum/component/remote_materials/proc/on_hold()
return silo && silo.holds["[get_area(parent)]/[category]"]
/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"