mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
114 lines
3.8 KiB
Plaintext
114 lines
3.8 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,
|
|
/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(datum/source, obj/item/I, mob/user)
|
|
if(I.tool_behaviour == TOOL_MULTITOOL)
|
|
if(!I.multitool_check_buffer(user, I))
|
|
return COMPONENT_NO_AFTERATTACK
|
|
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"
|