Files
Bubberstation/code/modules/mining/machine_redemption.dm
SkyratBot 4948dafe7e [MIRROR] Request Console refactor [MDB IGNORE] (#20979)
* Request Console refactor

* wew

* wew

---------

Co-authored-by: Profakos <profakos@gmail.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
2023-05-08 23:09:17 +01:00

430 lines
15 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]
materials = AddComponent(/datum/component/remote_materials, "orm", mapload, mat_container_flags=BREAKDOWN_FLAGS_ORM)
/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.")
/// Turns ore into its refined type, and sends it to its material container
/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/gathered_ore)
if(QDELETED(gathered_ore))
return
var/datum/component/material_container/mat_container = materials.mat_container
if (!mat_container)
return
if(gathered_ore.refined_type == null)
return
if(gathered_ore?.refined_type)
points += gathered_ore.points * point_upgrade * gathered_ore.amount
var/material_amount = mat_container.get_item_material_amount(gathered_ore, BREAKDOWN_FLAGS_ORM)
if(!material_amount)
qdel(gathered_ore) //no materials, incinerate it
else if(!mat_container.has_space(material_amount * gathered_ore.amount)) //if there is no space, eject it
unload_mineral(gathered_ore)
else
var/list/stack_mats = gathered_ore.get_material_composition(BREAKDOWN_FLAGS_ORM)
var/mats = stack_mats & mat_container.materials
var/amount = gathered_ore.amount
mat_container.insert_item(gathered_ore, ore_multiplier, breakdown_flags=BREAKDOWN_FLAGS_ORM) //insert it
materials.silo_log(src, "smelted", amount, gathered_ore.name, mats)
qdel(gathered_ore)
SEND_SIGNAL(src, COMSIG_ORM_COLLECTED_ORE)
/// 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
/// Smelts the passed ores one by one
/obj/machinery/mineral/ore_redemption/proc/process_ores(list/ores_to_process)
for(var/ore in ores_to_process)
smelt_ore(ore)
/// 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
if(istype(target, /obj/structure/ore_box))
var/obj/structure/ore_box/box = target
process_ores(box.contents)
else if(istype(target, /obj/item/stack/ore))
var/obj/item/stack/ore/O = target
smelt_ore(O)
else
return
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/wrench_act(mob/living/user, obj/item/tool)
. = ..()
default_unfasten_wrench(user, tool)
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params)
if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W))
return
if(default_deconstruction_crowbar(W))
return
if(!powered())
return ..()
var/obj/item/stack/ore/O = W
if(istype(O))
if(isnull(O.refined_type))
to_chat(user, span_warning("[O] has already been refined!"))
return
return ..()
/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")
var/obj/item/card/id/user_id_card
if(isliving(usr))
var/mob/living/user = usr
user_id_card = user.get_idcard(TRUE)
if(!materials.check_z_level() && (requires_silo || !user_id_card.registered_account.replaceable))
return TRUE
if(points)
if(user_id_card)
user_id_card.registered_account.mining_points += points
points = 0
else
to_chat(usr, span_warning("No valid ID detected."))
else
to_chat(usr, span_warning("No points to claim."))
return TRUE
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))
var/count = mat_container.retrieve_sheets(sheets_to_remove, mat, get_step(src, output_dir))
var/list/mats = list()
mats[mat] = SHEET_MATERIAL_AMOUNT
materials.silo_log(src, "released", -count, "sheets", mats)
//Logging deleted for quick coding
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
mat_container.use_materials(alloy.materials, amount)
materials.silo_log(src, "released", -amount, "sheets", alloy.materials)
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_[turn(input_dir, 180)]")
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