mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-18 13:43:27 +00:00
* Fixes for mat container & ORM (#80573) ## About The Pull Request - Fixes #80559 1) The ORM now hooks onto the local container only if off station. The ui act if statement was also messed up but that's fixed now too. 2) Creates a dedicated signal for items inserted into the silo for clarity & uses the helper proc defined inside remote materials for inserting items so we don't have to specify the `context` manually. 3) Properly updates the auto Doc for the container signal defines ## Changelog 🆑 fix: Off station ORM's can redeem points again. /🆑 * Fixes for mat container & ORM --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
419 lines
14 KiB
Plaintext
419 lines
14 KiB
Plaintext
/**********************Ore Redemption Unit**************************/
|
|
//Turns all the various mining machines into a single unit to speed up mining and establish a point system
|
|
|
|
/obj/machinery/mineral/ore_redemption
|
|
name = "ore redemption machine"
|
|
desc = "A machine that accepts ore and instantly transforms it into workable material sheets. Points for ore are generated based on type and can be redeemed at a mining equipment vendor."
|
|
icon = 'icons/obj/machines/mining_machines.dmi'
|
|
icon_state = "ore_redemption"
|
|
density = TRUE
|
|
input_dir = NORTH
|
|
output_dir = SOUTH
|
|
req_access = list(ACCESS_MINERAL_STOREROOM)
|
|
layer = BELOW_OBJ_LAYER
|
|
circuit = /obj/item/circuitboard/machine/ore_redemption
|
|
needs_item_input = TRUE
|
|
processing_flags = START_PROCESSING_MANUALLY
|
|
|
|
///Boolean on whether the ORM can claim points without being connected to an ore silo.
|
|
var/requires_silo = TRUE
|
|
/// The current amount of unclaimed points in the machine
|
|
var/points = 0
|
|
/// Smelted ore's amount is multiplied by this
|
|
var/ore_multiplier = 1
|
|
/// Increases the amount of points the miners gain
|
|
var/point_upgrade = 1
|
|
/// Details how many credits each smelted ore is worth
|
|
var/static/list/ore_values = list(
|
|
/datum/material/iron = 1,
|
|
/datum/material/glass = 1,
|
|
/datum/material/plasma = 15,
|
|
/datum/material/silver = 16,
|
|
/datum/material/gold = 18,
|
|
/datum/material/titanium = 30,
|
|
/datum/material/uranium = 30,
|
|
/datum/material/diamond = 50,
|
|
/datum/material/bluespace = 50,
|
|
/datum/material/bananium = 60,
|
|
)
|
|
/// Variable that holds a timer which is used for callbacks to `send_console_message()`. Used for preventing multiple calls to this proc while the ORM is eating a stack of ores.
|
|
var/console_notify_timer
|
|
/// References the alloys the smelter can create
|
|
var/datum/techweb/stored_research
|
|
/// Linkage to the ORM silo
|
|
var/datum/component/remote_materials/materials
|
|
|
|
/obj/machinery/mineral/ore_redemption/offstation
|
|
circuit = /obj/item/circuitboard/machine/ore_redemption/offstation
|
|
requires_silo = FALSE
|
|
|
|
/obj/machinery/mineral/ore_redemption/Initialize(mapload)
|
|
. = ..()
|
|
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter])
|
|
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter] = new /datum/techweb/autounlocking/smelter
|
|
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter]
|
|
|
|
//mat_container_signals is for reedeming points from local storage if silo is not required
|
|
var/list/local_signals = null
|
|
if(!requires_silo)
|
|
local_signals = list(
|
|
COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/mineral/ore_redemption, local_redeem_points)
|
|
)
|
|
materials = AddComponent( \
|
|
/datum/component/remote_materials, \
|
|
mapload, \
|
|
mat_container_signals = local_signals \
|
|
)
|
|
|
|
//for reedeming points from items inserted into ore silo
|
|
RegisterSignal(src, COMSIG_SILO_ITEM_CONSUMED, TYPE_PROC_REF(/obj/machinery/mineral/ore_redemption, silo_redeem_points))
|
|
|
|
/obj/machinery/mineral/ore_redemption/Destroy()
|
|
stored_research = null
|
|
materials = null
|
|
return ..()
|
|
|
|
/obj/machinery/mineral/ore_redemption/examine(mob/user)
|
|
. = ..()
|
|
if(panel_open)
|
|
. += span_notice("Alt-click to rotate the input and output direction.")
|
|
|
|
|
|
/obj/machinery/mineral/ore_redemption/proc/silo_redeem_points(obj/machinery/mineral/ore_redemption/machine, container, obj/item/stack/ore/gathered_ore)
|
|
SIGNAL_HANDLER
|
|
|
|
local_redeem_points(container, gathered_ore)
|
|
|
|
/obj/machinery/mineral/ore_redemption/proc/local_redeem_points(container, obj/item/stack/ore/gathered_ore)
|
|
SIGNAL_HANDLER
|
|
|
|
if(istype(gathered_ore) && gathered_ore.refined_type)
|
|
points += gathered_ore.points * point_upgrade * gathered_ore.amount
|
|
|
|
/// Returns the amount of a specific alloy design, based on the accessible materials
|
|
/obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D)
|
|
var/datum/component/material_container/mat_container = materials.mat_container
|
|
if(!mat_container || D.make_reagent)
|
|
return FALSE
|
|
|
|
var/build_amount = 0
|
|
|
|
for(var/mat in D.materials)
|
|
var/amount = D.materials[mat]
|
|
var/datum/material/redemption_mat_amount = mat_container.materials[mat]
|
|
|
|
if(!amount || !redemption_mat_amount)
|
|
return FALSE
|
|
|
|
var/smeltable_sheets = FLOOR(redemption_mat_amount / amount, 1)
|
|
|
|
if(!smeltable_sheets)
|
|
return FALSE
|
|
|
|
if(!build_amount)
|
|
build_amount = smeltable_sheets
|
|
|
|
build_amount = min(build_amount, smeltable_sheets)
|
|
|
|
return build_amount
|
|
|
|
/// Sends a message to the request consoles that signed up for ore updates
|
|
/obj/machinery/mineral/ore_redemption/proc/send_console_message()
|
|
var/datum/component/material_container/mat_container = materials.mat_container
|
|
if(!mat_container || !is_station_level(z))
|
|
return
|
|
|
|
console_notify_timer = null
|
|
|
|
var/area/our_area = get_area(src)
|
|
var/message = "Now available in [our_area]:"
|
|
|
|
var/has_minerals = FALSE
|
|
var/list/appended_list = list()
|
|
|
|
for(var/current_material in mat_container.materials)
|
|
var/datum/material/material_datum = current_material
|
|
var/mineral_amount = mat_container.materials[current_material] / SHEET_MATERIAL_AMOUNT
|
|
if(mineral_amount)
|
|
has_minerals = TRUE
|
|
appended_list["[capitalize(material_datum.name)]"] = "[mineral_amount] sheets"
|
|
|
|
if(!has_minerals)
|
|
return
|
|
|
|
var/datum/signal/subspace/messaging/rc/signal = new(src, list(
|
|
"ore_update" = TRUE,
|
|
"sender_department" = "Ore Redemption Machine",
|
|
"message" = message,
|
|
"verified" = "Ore Redemption Machine",
|
|
"priority" = REQ_NORMAL_MESSAGE_PRIORITY,
|
|
"appended_list" = appended_list,
|
|
))
|
|
signal.send_to_receivers()
|
|
|
|
/obj/machinery/mineral/ore_redemption/pickup_item(datum/source, atom/movable/target, direction)
|
|
if(QDELETED(target))
|
|
return
|
|
if(!materials.mat_container || panel_open || !powered())
|
|
return
|
|
|
|
//gethering the ore
|
|
var/list/obj/item/stack/ore/ore_list = list()
|
|
if(istype(target, /obj/structure/ore_box))
|
|
var/obj/structure/ore_box/box = target
|
|
for(var/obj/item/stack/ore/ore_item in box.contents)
|
|
ore_list += ore_item
|
|
else if(istype(target, /obj/item/stack/ore))
|
|
ore_list += target
|
|
else
|
|
return
|
|
|
|
//smelting the ore
|
|
for(var/obj/item/stack/ore/gathered_ore as anything in ore_list)
|
|
if(isnull(gathered_ore.refined_type))
|
|
continue
|
|
|
|
if(materials.insert_item(gathered_ore, ore_multiplier) <= 0)
|
|
unload_mineral(gathered_ore) //if rejected unload
|
|
|
|
SEND_SIGNAL(src, COMSIG_ORM_COLLECTED_ORE)
|
|
|
|
if(!console_notify_timer)
|
|
// gives 5 seconds for a load of ores to be sucked up by the ORM before it sends out request console notifications. This should be enough time for most deposits that people make
|
|
console_notify_timer = addtimer(CALLBACK(src, PROC_REF(send_console_message)), 5 SECONDS)
|
|
|
|
/obj/machinery/mineral/ore_redemption/default_unfasten_wrench(mob/user, obj/item/I)
|
|
. = ..()
|
|
if(. != SUCCESSFUL_UNFASTEN)
|
|
return
|
|
if(anchored)
|
|
register_input_turf() // someone just wrenched us down, re-register the turf
|
|
else
|
|
unregister_input_turf() // someone just un-wrenched us, unregister the turf
|
|
|
|
/obj/machinery/mineral/ore_redemption/screwdriver_act(mob/living/user, obj/item/tool)
|
|
default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", tool)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/mineral/ore_redemption/crowbar_act(mob/living/user, obj/item/tool)
|
|
default_deconstruction_crowbar(tool)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/mineral/ore_redemption/wrench_act(mob/living/user, obj/item/tool)
|
|
default_unfasten_wrench(user, tool)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/mineral/ore_redemption/AltClick(mob/living/user)
|
|
. = ..()
|
|
if(!user.can_perform_action(src))
|
|
return
|
|
if(panel_open)
|
|
input_dir = turn(input_dir, -90)
|
|
output_dir = turn(output_dir, -90)
|
|
to_chat(user, span_notice("You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)]."))
|
|
unregister_input_turf() // someone just rotated the input and output directions, unregister the old turf
|
|
register_input_turf() // register the new one
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
return TRUE
|
|
|
|
/obj/machinery/mineral/ore_redemption/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "OreRedemptionMachine")
|
|
ui.open()
|
|
|
|
/obj/machinery/mineral/ore_redemption/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["unclaimedPoints"] = points
|
|
data["materials"] = list()
|
|
var/datum/component/material_container/mat_container = materials.mat_container
|
|
if (mat_container)
|
|
for(var/datum/material/material as anything in mat_container.materials)
|
|
var/amount = mat_container.materials[material]
|
|
var/sheet_amount = amount / SHEET_MATERIAL_AMOUNT
|
|
data["materials"] += list(list(
|
|
"name" = material.name,
|
|
"id" = REF(material),
|
|
"amount" = sheet_amount,
|
|
"category" = "material",
|
|
"value" = ore_values[material.type],
|
|
))
|
|
|
|
for(var/research in stored_research.researched_designs)
|
|
var/datum/design/alloy = SSresearch.techweb_design_by_id(research)
|
|
data["materials"] += list(list(
|
|
"name" = alloy.name,
|
|
"id" = alloy.id,
|
|
"category" = "alloy",
|
|
"amount" = can_smelt_alloy(alloy),
|
|
))
|
|
|
|
data["disconnected"] = null
|
|
if (!mat_container)
|
|
data["disconnected"] = "Local mineral storage is unavailable"
|
|
else if (!materials.silo && requires_silo)
|
|
data["disconnected"] = "No ore silo connection is available; storing locally"
|
|
else if (!materials.check_z_level() && requires_silo)
|
|
data["disconnected"] = "Unable to connect to ore silo, too far away"
|
|
else if (materials.on_hold())
|
|
data["disconnected"] = "Mineral withdrawal is on hold"
|
|
|
|
var/obj/item/card/id/card
|
|
if(isliving(user))
|
|
var/mob/living/customer = user
|
|
card = customer.get_idcard(hand_first = TRUE)
|
|
if(card?.registered_account)
|
|
data["user"] = list(
|
|
"name" = card.registered_account.account_holder,
|
|
"cash" = card.registered_account.account_balance,
|
|
)
|
|
|
|
else if(issilicon(user))
|
|
var/mob/living/silicon/silicon_player = user
|
|
data["user"] = list(
|
|
"name" = silicon_player.name,
|
|
"cash" = "No valid account",
|
|
)
|
|
return data
|
|
|
|
/obj/machinery/mineral/ore_redemption/ui_static_data(mob/user)
|
|
var/list/data = list()
|
|
|
|
var/datum/component/material_container/mat_container = materials.mat_container
|
|
if (mat_container)
|
|
for(var/datum/material/material as anything in mat_container.materials)
|
|
var/obj/material_display = initial(material.sheet_type)
|
|
data["material_icons"] += list(list(
|
|
"id" = REF(material),
|
|
"product_icon" = icon2base64(getFlatIcon(image(icon = initial(material_display.icon), icon_state = initial(material_display.icon_state)), no_anim=TRUE)),
|
|
))
|
|
|
|
for(var/research in stored_research.researched_designs)
|
|
var/datum/design/alloy = SSresearch.techweb_design_by_id(research)
|
|
var/obj/alloy_display = initial(alloy.build_path)
|
|
data["material_icons"] += list(list(
|
|
"id" = alloy.id,
|
|
"product_icon" = icon2base64(getFlatIcon(image(icon = initial(alloy_display.icon), icon_state = initial(alloy_display.icon_state)), no_anim=TRUE)),
|
|
))
|
|
|
|
return data
|
|
|
|
|
|
/obj/machinery/mineral/ore_redemption/ui_act(action, params)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
var/datum/component/material_container/mat_container = materials.mat_container
|
|
switch(action)
|
|
if("Claim")
|
|
//requires silo but silo not in range
|
|
if(requires_silo && !materials.check_z_level())
|
|
return FALSE
|
|
|
|
//no ID
|
|
var/obj/item/card/id/user_id_card
|
|
if(isliving(usr))
|
|
var/mob/living/user = usr
|
|
user_id_card = user.get_idcard(TRUE)
|
|
if(isnull(user_id_card))
|
|
to_chat(usr, span_warning("No valid ID detected."))
|
|
return FALSE
|
|
|
|
//we have points
|
|
if(points)
|
|
user_id_card.registered_account.mining_points += points
|
|
points = 0
|
|
return TRUE
|
|
|
|
return FALSE
|
|
if("Release")
|
|
if(!mat_container)
|
|
return
|
|
if(materials.on_hold())
|
|
to_chat(usr, span_warning("Mineral access is on hold, please contact the quartermaster."))
|
|
else if(!allowed(usr)) //Check the ID inside, otherwise check the user
|
|
to_chat(usr, span_warning("Required access not found."))
|
|
else
|
|
var/datum/material/mat = locate(params["id"])
|
|
|
|
var/amount = mat_container.materials[mat]
|
|
if(!amount)
|
|
return
|
|
|
|
var/stored_amount = CEILING(amount / SHEET_MATERIAL_AMOUNT, 0.1)
|
|
if(!stored_amount)
|
|
return
|
|
|
|
var/desired = text2num(params["sheets"])
|
|
var/sheets_to_remove = round(min(desired, 50, stored_amount))
|
|
materials.eject_sheets(mat, sheets_to_remove, get_step(src, output_dir))
|
|
return TRUE
|
|
if("Smelt")
|
|
if(!mat_container)
|
|
return
|
|
if(materials.on_hold())
|
|
to_chat(usr, span_warning("Mineral access is on hold, please contact the quartermaster."))
|
|
return
|
|
var/alloy_id = params["id"]
|
|
var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id)
|
|
var/obj/item/card/id/user_id_card
|
|
if(isliving(usr))
|
|
var/mob/living/user = usr
|
|
user_id_card = user.get_idcard(TRUE)
|
|
if((check_access(user_id_card) || allowed(usr)) && alloy)
|
|
var/amount = round(min(text2num(params["sheets"]), 50, can_smelt_alloy(alloy)))
|
|
if(amount < 1) //no negative mats
|
|
return
|
|
materials.use_materials(alloy.materials, multiplier = amount, action = "released", name = "sheets")
|
|
var/output
|
|
if(ispath(alloy.build_path, /obj/item/stack/sheet))
|
|
output = new alloy.build_path(src, amount)
|
|
else
|
|
output = new alloy.build_path(src)
|
|
unload_mineral(output)
|
|
else
|
|
to_chat(usr, span_warning("Required access not found."))
|
|
return TRUE
|
|
|
|
/obj/machinery/mineral/ore_redemption/ex_act(severity, target)
|
|
do_sparks(5, TRUE, src)
|
|
return ..()
|
|
|
|
/obj/machinery/mineral/ore_redemption/update_icon_state()
|
|
icon_state = "[initial(icon_state)][powered() ? null : "-off"]"
|
|
return ..()
|
|
|
|
/obj/machinery/mineral/ore_redemption/update_overlays()
|
|
. = ..()
|
|
if((machine_stat & NOPOWER))
|
|
return
|
|
var/image/ore_input = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_[input_dir]")
|
|
var/image/ore_output = image(icon='icons/obj/doors/airlocks/station/overlays.dmi', icon_state="unres_[REVERSE_DIR(input_dir)]")
|
|
|
|
switch(input_dir)
|
|
if(NORTH)
|
|
ore_input.pixel_y = 32
|
|
ore_output.pixel_y = -32
|
|
if(SOUTH)
|
|
ore_input.pixel_y = -32
|
|
ore_output.pixel_y = 32
|
|
if(EAST)
|
|
ore_input.pixel_x = 32
|
|
ore_output.pixel_x = -32
|
|
if(WEST)
|
|
ore_input.pixel_x = -32
|
|
ore_output.pixel_x = 32
|
|
|
|
ore_input.color = COLOR_MODERATE_BLUE
|
|
ore_output.color = COLOR_SECURITY_RED
|
|
var/mutable_appearance/light_in = emissive_appearance(ore_input.icon, ore_input.icon_state, offset_spokesman = src, alpha = ore_input.alpha)
|
|
light_in.pixel_y = ore_input.pixel_y
|
|
light_in.pixel_x = ore_input.pixel_x
|
|
var/mutable_appearance/light_out = emissive_appearance(ore_output.icon, ore_output.icon_state, offset_spokesman = src, alpha = ore_output.alpha)
|
|
light_out.pixel_y = ore_output.pixel_y
|
|
light_out.pixel_x = ore_output.pixel_x
|
|
. += ore_input
|
|
. += ore_output
|
|
. += light_in
|
|
. += light_out
|