From 29547e194a77ef5751b0373d564efc8689bd5e8a Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sun, 2 Mar 2025 10:00:02 -0500 Subject: [PATCH] refactors point redemption vendors (#7005) this is a quick one makes them less code copypaste-y and easier to modify in the future as i'll want to do some experimentation on the system when we start reworking explo --- citadel.dme | 14 +- code/__DEFINES/misc/point_redemption.dm | 10 + code/__DEFINES/procs/clickcode.dm | 2 + code/game/machinery/computer/command/card.dm | 2 +- .../point_redemption_vendor}/construction.dm | 11 +- .../point_redemption_item.dm | 48 ++++ .../point_redemption_vendor.dm | 174 ++++++++++++ .../point_redemption_voucher.dm | 119 +++++++++ .../types/engineering.dm | 58 ++++ .../point_redemption_vendor/types/mining.dm | 90 +++++++ .../point_redemption_vendor/types/survey.dm | 66 +++++ .../unsorted_please_sort_these.dm | 113 ++++++++ .../objects/items/id_cards/station_ids.dm | 36 ++- .../crates_lockers/closets/secure/explorer.dm | 2 +- code/modules/catalogue/cataloguer.dm | 2 +- .../mining/machinery/machine_processing.dm | 4 +- .../engineering_points_vendor.dm | 235 ---------------- .../equipment_vendor.dm | 250 ------------------ .../mine_point_items.dm | 75 ------ .../ore_redemption_machine/survey_vendor.dm | 124 --------- .../file_system/programs/command/card.dm | 2 +- code/modules/power/crypto_miner.dm | 2 +- code/modules/tgui/datum.dm | 3 +- code/modules/tgui/tgui.dm | 7 +- .../point_redemption_vendor/engineering.dmi | Bin 0 -> 595 bytes .../point_redemption_vendor/mining.dmi | Bin 0 -> 1091 bytes .../point_redemption_vendor/survey.dmi | Bin 0 -> 3105 bytes icons/obj/card_new.dmi | Bin 9611 -> 9686 bytes icons/obj/card_new_vr.dmi | Bin 8934 -> 0 bytes icons/obj/machines/mining_machines.dmi | Bin 9397 -> 4123 bytes maps/endeavour/levels/deck1.dmm | 2 +- maps/endeavour/levels/deck3.dmm | 2 +- maps/endeavour/levels/deck4.dmm | 2 +- maps/euthenia/levels/deck2.dmm | 2 +- maps/euthenia/levels/deck4.dmm | 2 +- maps/rift/levels/rift-02-underground2.dmm | 4 +- maps/rift/levels/rift-06-surface3.dmm | 2 +- maps/rift/levels/rift-08-west_deep.dmm | 2 +- maps/rift/levels/rift-09-west_caves.dmm | 2 +- maps/sectors/miaphus/levels/miaphus_beach.dmm | 1 - maps/sectors/surt/levels/surt_west.dmm | 2 +- .../shuttles/overmaps/generic/shelter_6.dmm | 59 ++--- .../shuttles/overmaps/generic/vespa.dmm | 2 +- maps/tether/levels/station1.dmm | 2 +- maps/tether/levels/station2.dmm | 4 +- maps/triumph/levels/deck1.dmm | 2 +- maps/triumph/levels/deck2.dmm | 2 +- maps/triumph/levels/deck4.dmm | 2 +- .../machines/PointRedemptionVendor.tsx | 75 ++++++ tgui/packages/tgui/routes.tsx | 11 +- 50 files changed, 858 insertions(+), 773 deletions(-) create mode 100644 code/__DEFINES/misc/point_redemption.dm rename code/{modules/mining/ore_redemption_machine => game/machinery/point_redemption_vendor}/construction.dm (64%) create mode 100644 code/game/machinery/point_redemption_vendor/point_redemption_item.dm create mode 100644 code/game/machinery/point_redemption_vendor/point_redemption_vendor.dm create mode 100644 code/game/machinery/point_redemption_vendor/point_redemption_voucher.dm create mode 100644 code/game/machinery/point_redemption_vendor/types/engineering.dm create mode 100644 code/game/machinery/point_redemption_vendor/types/mining.dm create mode 100644 code/game/machinery/point_redemption_vendor/types/survey.dm create mode 100644 code/game/machinery/point_redemption_vendor/unsorted_please_sort_these.dm delete mode 100644 code/modules/mining/ore_redemption_machine/engineering_points_vendor.dm delete mode 100644 code/modules/mining/ore_redemption_machine/equipment_vendor.dm delete mode 100644 code/modules/mining/ore_redemption_machine/mine_point_items.dm delete mode 100644 code/modules/mining/ore_redemption_machine/survey_vendor.dm create mode 100644 icons/machinery/point_redemption_vendor/engineering.dmi create mode 100644 icons/machinery/point_redemption_vendor/mining.dmi create mode 100644 icons/machinery/point_redemption_vendor/survey.dmi delete mode 100644 icons/obj/card_new_vr.dmi create mode 100644 tgui/packages/tgui/interfaces/machines/PointRedemptionVendor.tsx diff --git a/citadel.dme b/citadel.dme index 92c188d2167..61be27550de 100644 --- a/citadel.dme +++ b/citadel.dme @@ -283,6 +283,7 @@ #include "code\__DEFINES\misc\attack_animations.dm" #include "code\__DEFINES\misc\message_ranges.dm" #include "code\__DEFINES\misc\nightshift.dm" +#include "code\__DEFINES\misc\point_redemption.dm" #include "code\__DEFINES\misc\posters.dm" #include "code\__DEFINES\mobs\actions.dm" #include "code\__DEFINES\mobs\biology.dm" @@ -1507,6 +1508,14 @@ #include "code\game\machinery\pipe\construction.dm" #include "code\game\machinery\pipe\pipe_dispenser.dm" #include "code\game\machinery\pipe\pipe_recipes.dm" +#include "code\game\machinery\point_redemption_vendor\construction.dm" +#include "code\game\machinery\point_redemption_vendor\point_redemption_item.dm" +#include "code\game\machinery\point_redemption_vendor\point_redemption_vendor.dm" +#include "code\game\machinery\point_redemption_vendor\point_redemption_voucher.dm" +#include "code\game\machinery\point_redemption_vendor\unsorted_please_sort_these.dm" +#include "code\game\machinery\point_redemption_vendor\types\engineering.dm" +#include "code\game\machinery\point_redemption_vendor\types\mining.dm" +#include "code\game\machinery\point_redemption_vendor\types\survey.dm" #include "code\game\machinery\suit_storage\suit_cycler.dm" #include "code\game\machinery\suit_storage\suit_storage_massive.dm" #include "code\game\machinery\suit_storage\suit_storage_prepared.dm" @@ -3609,11 +3618,6 @@ #include "code\modules\mining\machinery\sheet_silo_loader.dm" #include "code\modules\mining\misc\abandonedcrates.dm" #include "code\modules\mining\misc\abandonedcrates_vr.dm" -#include "code\modules\mining\ore_redemption_machine\construction.dm" -#include "code\modules\mining\ore_redemption_machine\engineering_points_vendor.dm" -#include "code\modules\mining\ore_redemption_machine\equipment_vendor.dm" -#include "code\modules\mining\ore_redemption_machine\mine_point_items.dm" -#include "code\modules\mining\ore_redemption_machine\survey_vendor.dm" #include "code\modules\mining\ores\alloys.dm" #include "code\modules\mining\ores\ore.dm" #include "code\modules\mining\ores\ore_datum.dm" diff --git a/code/__DEFINES/misc/point_redemption.dm b/code/__DEFINES/misc/point_redemption.dm new file mode 100644 index 00000000000..b7684199539 --- /dev/null +++ b/code/__DEFINES/misc/point_redemption.dm @@ -0,0 +1,10 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/** + * stupid GBP system for mining / engineering / survey / etc + */ + +#define POINT_REDEMPTION_TYPE_MINING "mining" +#define POINT_REDEMPTION_TYPE_ENGINEERING "engineering" +#define POINT_REDEMPTION_TYPE_SURVEY "survey" diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm index 5eaa74894e1..47c11f429ee 100644 --- a/code/__DEFINES/procs/clickcode.dm +++ b/code/__DEFINES/procs/clickcode.dm @@ -51,6 +51,8 @@ #define CLICKCHAIN_FLAGS_UNCONDITIONAL_ABORT (CLICKCHAIN_DO_NOT_PROPAGATE) /// check these for 'abort attack' #define CLICKCHAIN_FLAGS_ATTACK_ABORT (CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_FULL_BLOCKED) +/// check these for 'abort further interactions' +#define CLICKCHAIN_FLAGS_INTERACT_ABORT (CLICKCHAIN_DO_NOT_PROPAGATE | CLICKCHAIN_DID_SOMETHING) //! Reachability Depths - checked from level of DirectAccess and turf adjacency. /// default reachability depth diff --git a/code/game/machinery/computer/command/card.dm b/code/game/machinery/computer/command/card.dm index d306d3bd22d..44135031e65 100644 --- a/code/game/machinery/computer/command/card.dm +++ b/code/game/machinery/computer/command/card.dm @@ -27,7 +27,7 @@ return switch(id) if("modify") - return tgui_cardmod.ui_act(action, params, ui) + return tgui_cardmod.ui_act(action, params, ui, new /datum/event_args/actor(usr)) /** * for later use: authorized to change slots diff --git a/code/modules/mining/ore_redemption_machine/construction.dm b/code/game/machinery/point_redemption_vendor/construction.dm similarity index 64% rename from code/modules/mining/ore_redemption_machine/construction.dm rename to code/game/machinery/point_redemption_vendor/construction.dm index 77b55ea2e12..014ec78ffb9 100644 --- a/code/modules/mining/ore_redemption_machine/construction.dm +++ b/code/game/machinery/point_redemption_vendor/construction.dm @@ -2,19 +2,22 @@ #error T_BOARD macro is not defined but we need it! #endif -/obj/item/circuitboard/mining_equipment_vendor +/obj/item/circuitboard/point_redemption_vendor + abstract_type = /obj/item/circuitboard/point_redemption_vendor + +/obj/item/circuitboard/point_redemption_vendor/mining name = T_BOARD("Mining Equipment Vendor") board_type = new /datum/frame/frame_types/machine - build_path = /obj/machinery/mineral/equipment_vendor + build_path = /obj/machinery/point_redemption_vendor/mining origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 3) req_components = list( /obj/item/stock_parts/console_screen = 1, /obj/item/stock_parts/matter_bin = 3) -/obj/item/circuitboard/exploration_equipment_vendor +/obj/item/circuitboard/point_redemption_vendor/survey name = T_BOARD("Exploration Equipment Vendor") board_type = new /datum/frame/frame_types/machine - build_path = /obj/machinery/mineral/equipment_vendor/survey + build_path = /obj/machinery/point_redemption_vendor/survey origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2) req_components = list( /obj/item/stock_parts/console_screen = 1, diff --git a/code/game/machinery/point_redemption_vendor/point_redemption_item.dm b/code/game/machinery/point_redemption_vendor/point_redemption_item.dm new file mode 100644 index 00000000000..9888e2e1c1e --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/point_redemption_item.dm @@ -0,0 +1,48 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/** + * Describes stuff you can get for points in a point redemption vendor. + * * Does not store info about the type of points, at time of writing. + * + * todo: category system + */ +/datum/point_redemption_item + var/name = "Unknown Item" + /** + * Description. + * * Inferred from path if unspecified. + */ + var/desc = "Some kind of item." + var/path = /obj/item/bananapeel + var/cost = 1 + +/datum/point_redemption_item/New(name, path, cost, desc) + if(name) + src.name = name + if(path) + src.path = path + if(cost) + src.cost = cost + if(desc) + src.desc = desc + + if(!ispath(src.path, /atom/movable)) + CRASH("invalid path '[src.path]'.") + + if(desc == initial(desc)) + var/atom/movable/casted = src.path + desc = initial(casted.desc) + +/** + * @return list of entities created + */ +/datum/point_redemption_item/proc/instantiate(atom/where, amount = 1) as /list + RETURN_TYPE(/list) + . = list() + var/safety = 50 + for(var/i in 1 to amount) + if(!--safety) + CRASH("safety limit hit") + var/atom/movable/created = new path(where) + . += created diff --git a/code/game/machinery/point_redemption_vendor/point_redemption_vendor.dm b/code/game/machinery/point_redemption_vendor/point_redemption_vendor.dm new file mode 100644 index 00000000000..085bd1c7770 --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/point_redemption_vendor.dm @@ -0,0 +1,174 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/obj/machinery/point_redemption_vendor + name = "point redemption vendor" + desc = "An equipment vendor that trades points for various gear. Usually found in the station's departments \ + and used to incentivize good performance." + density = TRUE + anchored = TRUE + + /// point type we operate with + var/point_type + + /// flick tihs state when denying sometihng + var/icon_state_append_deny + /// set to this state if panel is open + // todo: render at /obj/machinery level + var/icon_state_append_open + /// set to this state if we're depowered + // todo: render at /obj/machinery level + var/icon_state_append_off + /// flick this state when vending something + var/icon_state_append_vend + /// set to this state if we're broken + var/icon_state_append_broken + + /// The inserted ID, if any + var/obj/item/card/id/inserted_id + + /// available items + var/list/datum/point_redemption_item/prize_list = list() + +/obj/machinery/point_redemption_vendor/update_icon_state() + var/icon_base_state = base_icon_state || initial(icon_state) + var/is_broken = atom_flags & ATOM_BROKEN + if(is_broken && icon_state_append_broken) + icon_state = "[icon_base_state][icon_state_append_broken]" + else if((!powered() || is_broken) && icon_state_append_off) + icon_state = "[icon_base_state][icon_state_append_off]" + else if(panel_open) + icon_state = "[icon_base_state][icon_state_append_open]" + else + icon_state = icon_base_state + return ..() + +/obj/machinery/point_redemption_vendor/power_change() + var/old_stat = machine_stat + . = ..() + // todo: machine-level update icon hook? + if(machine_stat != old_stat) + update_icon() + if(!powered() && inserted_id) + visible_message( + SPAN_NOTICE("The ID slot indicator light on [src] flickers as it spits out [inserted_id]."), + ) + inserted_id.forceMove(drop_location()) + +/obj/machinery/point_redemption_vendor/drop_products(method, atom/where) + . = ..() + if(inserted_id) + drop_product(inserted_id, where) + inserted_id = null + +/obj/machinery/point_redemption_vendor/using_item_on(obj/item/using, datum/event_args/actor/clickchain/e_args, clickchain_flags, datum/callback/reachability_check) + . = ..() + if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT) + return + if(handle_id_insertion(using, e_args)) + // in either case they wouldn't do anything because the id is either not on them anymore + // or is not going to touch the machine + return CLICKCHAIN_DID_SOMETHING | CLICKCHAIN_DO_NOT_PROPAGATE + +/** + * @return TRUE if handled + */ +/obj/machinery/point_redemption_vendor/proc/handle_id_insertion(obj/item/maybe_id, datum/event_args/actor/actor) + if(!istype(maybe_id, /obj/item/card/id)) + return FALSE + if(inserted_id) + actor.chat_feedback( + SPAN_WARNING("[src] already has an inserted ID."), + target = src, + ) + return TRUE + if(!actor.performer.attempt_insert_item_for_installation(maybe_id, src)) + return TRUE + actor.chat_feedback( + SPAN_NOTICE("You insert [maybe_id] into [src]'s card slot."), + target = src, + ) + inserted_id = maybe_id + return TRUE + +/obj/machinery/point_redemption_vendor/ui_act(action, list/params, datum/tgui/ui, datum/event_args/actor/e_args) + . = ..() + if(.) + return + + switch(action) + if("idcard") + if(inserted_id) + e_args.visible_feedback( + target = src, + range = MESSAGE_RANGE_INVENTORY_SOFT, + visible = SPAN_NOTICE("[e_args.performer] retrieves [inserted_id] from [src]."), + ) + e_args.performer.put_in_hands_or_drop(inserted_id) + inserted_id = null + else if(!inserted_id) + var/obj/item/active_held = e_args.performer.get_active_held_item() + handle_id_insertion(active_held, e_args) + return TRUE + if("vend") + if(!inserted_id) + return TRUE + // double-verify incase entry changed; we don't give them the refs though so + // no locate() in list! + var/target_index = params["index"] + var/target_name = params["name"] + if(target_index < 1 || target_index > length(prize_list)) + update_static_data(hard_refresh = TRUE) + return TRUE + var/datum/point_redemption_item/resolved = prize_list[target_index] + if(resolved.name != target_name) + update_static_data(hard_refresh = TRUE) + return TRUE + if(inserted_id.get_redemption_points(point_type) < resolved.cost) + return TRUE + inserted_id.adjust_redemption_points(point_type, -resolved.cost) + vend_item(resolved) + return TRUE + +/obj/machinery/point_redemption_vendor/ui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "machines/PointRedemptionVendor") + ui.set_title(name) + ui.open() + +/obj/machinery/point_redemption_vendor/ui_static_data(mob/user, datum/tgui/ui) + . = ..() + .["pointName"] = point_type + var/list/serialized_items = list() + for(var/datum/point_redemption_item/item in prize_list) + serialized_items[++serialized_items.len] = list( + "name" = item.name, + "desc" = item.desc, + "cost" = item.cost, + ) + .["availableItems"] = serialized_items + +/obj/machinery/point_redemption_vendor/ui_data(mob/user, datum/tgui/ui) + . = ..() + .["points"] = inserted_id ? inserted_id.get_redemption_points(point_type) : 0 + .["insertedId"] = inserted_id ? list( + "name" = inserted_id.name, + "rank" = inserted_id.rank, + "owner" = inserted_id.registered_name, + ) : null + +/obj/machinery/point_redemption_vendor/proc/vend_item(datum/point_redemption_item/item) + item.instantiate(drop_location()) + flick_vend() + return TRUE + +/obj/machinery/point_redemption_vendor/proc/flick_deny() + if(!icon_state_append_deny) + return + flick("[base_icon_state || initial(icon_state)][icon_state_append_deny]", src) + +/obj/machinery/point_redemption_vendor/proc/flick_vend() + if(!icon_state_append_vend) + return + flick("[base_icon_state || initial(icon_state)][icon_state_append_vend]", src) diff --git a/code/game/machinery/point_redemption_vendor/point_redemption_voucher.dm b/code/game/machinery/point_redemption_vendor/point_redemption_voucher.dm new file mode 100644 index 00000000000..e2f54a0c229 --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/point_redemption_voucher.dm @@ -0,0 +1,119 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2025 Citadel Station Developers *// + +/** + * Kinda self explanatory; stores points you can apply to a card. + */ +/obj/item/point_redemption_voucher + name = "point redemption voucher" + desc = "A voucher with redemption points that you can apply to an ID card to use at an equipment vendor." + icon = 'icons/obj/card_cit.dmi' + icon_state = "generic" + w_class = WEIGHT_CLASS_TINY + slot_flags = SLOT_ID | SLOT_EARS + pickup_sound = 'sound/items/pickup/card.ogg' + + /// stored points + var/list/stored_redemption_points + +/obj/item/point_redemption_voucher/Initialize(mapload, list/points) + . = ..() + if(points) + src.stored_redemption_points = points.Copy() + +/obj/item/point_redemption_voucher/examine(mob/user, dist) + . = ..() + var/any_found = FALSE + for(var/key in stored_redemption_points) + var/amount = stored_redemption_points[key] + if(!amount) + continue + any_found = TRUE + . += SPAN_NOTICE("There's [amount] [key] equipment redemption point[amount > 1 ? "s" : ""] loaded on this card.") + if(!any_found) + . += SPAN_NOTICE("There's no equipment redemption points loaded on this voucher.") + +/obj/item/point_redemption_voucher/using_as_item(atom/target, datum/event_args/actor/clickchain/e_args, clickchain_flags, datum/callback/reachability_check) + . = ..() + if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT) + return + if(istype(target, /obj/item/card/id)) + transfer_to_card(target, e_args) + return CLICKCHAIN_DID_SOMETHING + +/obj/item/point_redemption_voucher/using_item_on(obj/item/using, datum/event_args/actor/clickchain/e_args, clickchain_flags, datum/callback/reachability_check) + . = ..() + if(. & CLICKCHAIN_FLAGS_INTERACT_ABORT) + return + if(istype(using, /obj/item/card/id)) + transfer_to_card(using, e_args) + return CLICKCHAIN_DID_SOMETHING + +/obj/item/point_redemption_voucher/proc/transfer_to_card(obj/item/card/id/to_id_card, datum/event_args/actor/actor) + if(!length(stored_redemption_points)) + actor?.chat_feedback( + SPAN_NOTICE("[src] has no stored redemption points."), + target = src, + ) + return + for(var/key in stored_redemption_points) + var/amount = stored_redemption_points[key] + to_id_card.adjust_redemption_points(key, amount) + actor?.chat_feedback( + SPAN_NOTICE("You transfer [amount] [key] points to [to_id_card] from [src]."), + ) + stored_redemption_points = null + +//* Presets *// + +/obj/item/point_redemption_voucher/preloaded + +/obj/item/point_redemption_voucher/preloaded/mining/c500 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_MINING = 500, + ) + +/obj/item/point_redemption_voucher/preloaded/mining/c1000 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_MINING = 1000, + ) + +/obj/item/point_redemption_voucher/preloaded/mining/c2000 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_MINING = 2000, + ) + +/obj/item/point_redemption_voucher/preloaded/mining/c3000 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_MINING = 3000, + ) + +/obj/item/point_redemption_voucher/preloaded/mining/c50000 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_MINING = 50000, + ) + +/obj/item/point_redemption_voucher/preloaded/survey/c50 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_SURVEY = 50, + ) + +/obj/item/point_redemption_voucher/preloaded/survey/c100 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_SURVEY = 100, + ) + +/obj/item/point_redemption_voucher/preloaded/survey/c200 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_SURVEY = 200, + ) + +/obj/item/point_redemption_voucher/preloaded/survey/c300 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_SURVEY = 300, + ) + +/obj/item/point_redemption_voucher/preloaded/engineering/c50 + stored_redemption_points = list( + POINT_REDEMPTION_TYPE_ENGINEERING = 50, + ) diff --git a/code/game/machinery/point_redemption_vendor/types/engineering.dm b/code/game/machinery/point_redemption_vendor/types/engineering.dm new file mode 100644 index 00000000000..57e3cc6ba4f --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/types/engineering.dm @@ -0,0 +1,58 @@ +/obj/machinery/point_redemption_vendor/engineering + name = "Engineering Equipment Vendor" + desc = "An equipment vendor for engineers, point generated by the crypto miners can be spend here." + icon = 'icons/machinery/point_redemption_vendor/engineering.dmi' + icon_state = "vendor" + icon_state_append_deny = "-deny" + icon_state_append_open = "-open" + icon_state_append_off = "-off" + point_type = POINT_REDEMPTION_TYPE_ENGINEERING + prize_list = list( + //Mining vendor steals + new /datum/point_redemption_item("Vodka", /obj/item/reagent_containers/food/drinks/bottle/vodka, 3), + new /datum/point_redemption_item("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 5), + new /datum/point_redemption_item("Soap", /obj/item/soap/nanotrasen, 2), + new /datum/point_redemption_item("Laser Pointer", /obj/item/laser_pointer, 9), + new /datum/point_redemption_item("Plush Toy", /obj/random/plushie, 3), + new /datum/point_redemption_item("GPS Device", /obj/item/gps/engineering, 1), + new /datum/point_redemption_item("50 Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/engineering/c50, 50), + new /datum/point_redemption_item("Umbrella", /obj/item/melee/umbrella/random, 20), + new /datum/point_redemption_item("100 Thaler", /obj/item/spacecash/c100, 4), + new /datum/point_redemption_item("1000 Thaler", /obj/item/spacecash/c1000, 40), + new /datum/point_redemption_item("Hardsuit - Control Module", /obj/item/hardsuit/industrial, 50), + new /datum/point_redemption_item("Hardsuit - Plasma Cutter", /obj/item/hardsuit_module/device/plasmacutter, 10), + new /datum/point_redemption_item("Hardsuit - Maneuvering Jets", /obj/item/hardsuit_module/maneuvering_jets, 12), + new /datum/point_redemption_item("Hardsuit - Intelligence Storage", /obj/item/hardsuit_module/ai_container, 25), + new /datum/point_redemption_item("Injector (L) - Panacea", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), + //Mining vendor steals - Ends + //Power tools like the CE gets, if kev comes crying: https://cdn.discordapp.com/attachments/296237931587305472/956517623519141908/unknown.png + new /datum/point_redemption_item("Advanced Hardsuit", /obj/item/hardsuit/ce, 150), + new /datum/point_redemption_item("Power Tool - Hand Drill", /obj/item/tool/screwdriver/power, 80), + new /datum/point_redemption_item("Power Tool - Jaws of life", /obj/item/tool/crowbar/power, 80), + new /datum/point_redemption_item("Power Tool - Experimental Welder", /obj/item/weldingtool/experimental, 80), + new /datum/point_redemption_item("Power Tool - Upgraded T-Ray Scanner", /obj/item/t_scanner/upgraded, 80), + new /datum/point_redemption_item("Power Tool - Advanced T-Ray Scanner", /obj/item/t_scanner/advanced, 80), + new /datum/point_redemption_item("Power Tool - Long Range Atmosphere scanner", /obj/item/atmos_analyzer/longrange, 80), + //new /datum/point_redemption_item("Power Tool - Holofan Projector", /obj/item/holosign_creator/combifan, 80), + new /datum/point_redemption_item("Superior Welding Goggles", /obj/item/clothing/glasses/welding/superior, 50), + + //Level 2 stock parts, to make engineering kinda self sufficent for minor upgrades but the parts are also kinda expansive + new /datum/point_redemption_item("Stock Parts - Advanced Capacitor", /obj/item/stock_parts/capacitor/adv, 20), + new /datum/point_redemption_item("Stock Parts - Advanced Scanning Module", /obj/item/stock_parts/scanning_module/adv, 20), + new /datum/point_redemption_item("Stock Parts - Nano-Manipulator", /obj/item/stock_parts/manipulator/nano, 20), + new /datum/point_redemption_item("Stock Parts - High-Power Micro-Laser", /obj/item/stock_parts/micro_laser/high, 20), + new /datum/point_redemption_item("Stock Parts - Advanced Matter Bin", /obj/item/stock_parts/matter_bin/adv, 20), + + //Special Resources which the vendor is the primary source off: + new /datum/point_redemption_item("Special Parts - Vimur Tank", /obj/item/tank/vimur, 5), + new /datum/point_redemption_item("Special Parts - TEG Voucher", /obj/item/engineering_voucher/teg, 20), + new /datum/point_redemption_item("Special Parts - SM Core Voucher", /obj/item/engineering_voucher/smcore, 40), + new /datum/point_redemption_item("Special Parts - Fusion Core Voucher", /obj/item/engineering_voucher/fusion_core, 20), + new /datum/point_redemption_item("Special Parts - Fuel Injector Voucher", /obj/item/engineering_voucher/fusion_fuel_injector, 10), + new /datum/point_redemption_item("Special Parts - Gyrotrons Voucher", /obj/item/engineering_voucher/gyrotrons, 20), + new /datum/point_redemption_item("Special Parts - Fuel compressor Voucher", /obj/item/engineering_voucher/fuel_compressor, 10), + new /datum/point_redemption_item("Special Parts - Collector Voucher", /obj/item/engineering_voucher/collectors, 10), + new /datum/point_redemption_item("Special Parts - Laser Reflector Voucher", /obj/item/engineering_voucher/reflector, 30), + //voucher: Solar crate, Vimur canister + new /datum/point_redemption_item("???", /obj/item/engineering_mystical_tech, 1000) + ) diff --git a/code/game/machinery/point_redemption_vendor/types/mining.dm b/code/game/machinery/point_redemption_vendor/types/mining.dm new file mode 100644 index 00000000000..90d944b4b3e --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/types/mining.dm @@ -0,0 +1,90 @@ +/obj/machinery/point_redemption_vendor/mining + name = "mining equipment vendor" + desc = "An equipment vendor for miners, points collected at an ore redemption machine can be spent here." + icon = 'icons/machinery/point_redemption_vendor/mining.dmi' + icon_state = "vendor" + icon_state_append_deny = "-deny" + icon_state_append_open = "-open" + icon_state_append_off = "-off" + point_type = POINT_REDEMPTION_TYPE_MINING + circuit = /obj/item/circuitboard/point_redemption_vendor/mining + prize_list = list( + new /datum/point_redemption_item("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), + new /datum/point_redemption_item("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), + new /datum/point_redemption_item("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), + new /datum/point_redemption_item("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 125), + new /datum/point_redemption_item("Absinthe", /obj/item/reagent_containers/food/drinks/bottle/absinthe, 125), + new /datum/point_redemption_item("Hard Root Beer", /obj/item/reagent_containers/food/drinks/bottle/small/alcsassafras, 70), + new /datum/point_redemption_item("Special Blend Whiskey", /obj/item/reagent_containers/food/drinks/bottle/specialwhiskey, 250), + new /datum/point_redemption_item("Random Booze", /obj/random/alcohol, 125), + new /datum/point_redemption_item("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), + new /datum/point_redemption_item("Root Beer", /obj/item/reagent_containers/food/drinks/bottle/small/sassafras, 50), + new /datum/point_redemption_item("Sarsaparilla", /obj/item/reagent_containers/food/drinks/bottle/small/sarsaparilla, 50), + new /datum/point_redemption_item("Soap", /obj/item/soap/nanotrasen, 200), + new /datum/point_redemption_item("Laser Pointer", /obj/item/laser_pointer, 900), + new /datum/point_redemption_item("Geiger Counter", /obj/item/geiger_counter, 750), + new /datum/point_redemption_item("Plush Toy", /obj/random/plushie, 300), + new /datum/point_redemption_item("GPS Device", /obj/item/gps/mining, 100), + new /datum/point_redemption_item("Portable Fuel Can", /obj/item/reagent_containers/portable_fuelcan, 250), + // TODO new /datum/point_redemption_item("Advanced Scanner", /obj/item/t_scanner/adv_mining_scanner, 800), + new /datum/point_redemption_item("Fulton Beacon", /obj/item/fulton_core, 500), + new /datum/point_redemption_item("Shelter Capsule", /obj/item/survivalcapsule, 500), + // TODO new /datum/point_redemption_item("Explorer's Webbing", /obj/item/storage/belt/mining, 500), + new /datum/point_redemption_item("500 Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/mining/c500, 500), + new /datum/point_redemption_item("1000 Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/mining/c1000, 1000), + new /datum/point_redemption_item("2000 Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/mining/c2000, 2000), + new /datum/point_redemption_item("3000 Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/mining/c3000, 3000), + new /datum/point_redemption_item("Umbrella", /obj/item/melee/umbrella/random, 200), + new /datum/point_redemption_item("Survival Medipen", /obj/item/reagent_containers/hypospray/autoinjector/miner, 500), + new /datum/point_redemption_item("Mini-Translocator", /obj/item/perfect_tele/one_beacon, 1200), + // new /datum/point_redemption_item("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), + new /datum/point_redemption_item("Kinetic Accelerator", /obj/item/gun/projectile/energy/kinetic_accelerator, 900), + new /datum/point_redemption_item("Resonator", /obj/item/resonator, 900), + new /datum/point_redemption_item("Fulton Pack", /obj/item/extraction_pack, 1200), + new /datum/point_redemption_item("Wormhole Fulton Pack", /obj/item/extraction_pack/wormhole, 1750), + new /datum/point_redemption_item("Silver Pickaxe", /obj/item/pickaxe/silver, 1200), + new /datum/point_redemption_item("Climbing Pick", /obj/item/pickaxe/icepick, 2200), + //new /datum/point_redemption_item("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), + new /datum/point_redemption_item("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), + new /datum/point_redemption_item("Advanced Ore Scanner", /obj/item/mining_scanner/advanced, 2000), + new /datum/point_redemption_item("100 Thalers", /obj/item/spacecash/c100, 5000), + new /datum/point_redemption_item("1000 Thalers", /obj/item/spacecash/c1000, 50000), + new /datum/point_redemption_item("Hardsuit - Control Module", /obj/item/hardsuit/industrial, 2000), + new /datum/point_redemption_item("Hardsuit - Plasma Cutter", /obj/item/hardsuit_module/device/plasmacutter, 800), + new /datum/point_redemption_item("Hardsuit - Drill", /obj/item/hardsuit_module/device/drill, 5000), + new /datum/point_redemption_item("Hardsuit - Ore Scanner", /obj/item/hardsuit_module/device/orescanner, 1000), + new /datum/point_redemption_item("Hardsuit - Material Scanner", /obj/item/hardsuit_module/vision/material, 500), + new /datum/point_redemption_item("Hardsuit - Maneuvering Jets", /obj/item/hardsuit_module/maneuvering_jets, 1250), + new /datum/point_redemption_item("Hardsuit - Intelligence Storage", /obj/item/hardsuit_module/ai_container, 2500), + new /datum/point_redemption_item("Hardsuit - Smoke Bomb Deployer", /obj/item/hardsuit_module/grenade_launcher/smoke, 2000), + new /datum/point_redemption_item("Industrial Equipment - Phoron Bore", /obj/item/gun/projectile/magnetic/matfed, 3000), + new /datum/point_redemption_item("Industrial Equipment - Sheet-Snatcher",/obj/item/storage/bag/sheetsnatcher, 500), + new /datum/point_redemption_item("Repurposed Equipment - Mining Carbine", /obj/item/gun/projectile/energy/gun/miningcarbine, 5000), + new /datum/point_redemption_item("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), + new /datum/point_redemption_item("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), + new /datum/point_redemption_item("Super Resonator", /obj/item/resonator/upgraded, 2500), + new /datum/point_redemption_item("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), + new /datum/point_redemption_item("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3100), + new /datum/point_redemption_item("KA White Tracer Rounds", /obj/item/ka_modkit/tracer, 125), + new /datum/point_redemption_item("KA Adjustable Tracer Rounds", /obj/item/ka_modkit/tracer/adjustable, 175), + new /datum/point_redemption_item("KA Super Chassis", /obj/item/ka_modkit/chassis_mod, 250), + new /datum/point_redemption_item("KA Hyper Chassis", /obj/item/ka_modkit/chassis_mod/orange, 300), + new /datum/point_redemption_item("KA Range Increase", /obj/item/ka_modkit/range, 1000), + new /datum/point_redemption_item("KA Cooldown Decrease", /obj/item/ka_modkit/cooldown, 1200), + new /datum/point_redemption_item("KA Capacity Increase", /obj/item/ka_modkit/capacity, 1500), + new /datum/point_redemption_item("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), + new /datum/point_redemption_item("Fine Excavation Kit - Chisels",/obj/item/storage/excavation, 500), + new /datum/point_redemption_item("Fine Excavation Kit - Measuring Tape",/obj/item/measuring_tape, 125), + new /datum/point_redemption_item("Fine Excavation Kit - Hand Pick",/obj/item/pickaxe/hand, 375), + new /datum/point_redemption_item("Explosive Excavation Kit - Plastic Charge",/obj/item/plastique/seismic/locked, 1500), + new /datum/point_redemption_item("Injector (L) - Glucose",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), + new /datum/point_redemption_item("Injector (L) - Panacea",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), + new /datum/point_redemption_item("Injector (L) - Trauma",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), + new /datum/point_redemption_item("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), + new /datum/point_redemption_item("Defense Equipment - Smoke Bomb",/obj/item/grenade/smokebomb, 100), + new /datum/point_redemption_item("Defense Equipment - Razor Drone Deployer",/obj/item/grenade/spawnergrenade/manhacks/station/locked, 1000), + new /datum/point_redemption_item("Defense Equipment - Sentry Drone Deployer",/obj/item/grenade/spawnergrenade/ward, 1500), + new /datum/point_redemption_item("Defense Equipment - Plasteel Machete", /obj/item/clothing/accessory/holster/machete/occupied, 500), + new /datum/point_redemption_item("Defense Equipment - Kinetic Dagger", /obj/item/kinetic_crusher/dagger, 1200), + new /datum/point_redemption_item("Bar Shelter Capsule", /obj/item/survivalcapsule/luxurybar, 10000) + ) diff --git a/code/game/machinery/point_redemption_vendor/types/survey.dm b/code/game/machinery/point_redemption_vendor/types/survey.dm new file mode 100644 index 00000000000..0aad3e4616a --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/types/survey.dm @@ -0,0 +1,66 @@ +/obj/machinery/point_redemption_vendor/survey + name = "exploration equipment vendor" + desc = "An equipment vendor for explorers, points collected with a survey scanner can be spent here." + icon = 'icons/machinery/point_redemption_vendor/survey.dmi' + icon_state = "vendor" + icon_state_append_deny = "-deny" + icon_state_append_open = "-open" + icon_state_append_off = "-off" + icon_state_append_broken = "-broken" + icon_state_append_vend = "-vend" + point_type = POINT_REDEMPTION_TYPE_SURVEY + circuit = /obj/item/circuitboard/point_redemption_vendor/survey + prize_list = list( + new /datum/point_redemption_item("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + new /datum/point_redemption_item("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + new /datum/point_redemption_item("GPS Device", /obj/item/gps/explorer, 10), + new /datum/point_redemption_item("Defense Equipment - Smoke Bomb",/obj/item/grenade/smokebomb, 10), + new /datum/point_redemption_item("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 10), + new /datum/point_redemption_item("Absinthe", /obj/item/reagent_containers/food/drinks/bottle/absinthe, 10), + new /datum/point_redemption_item("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), + new /datum/point_redemption_item("Soap", /obj/item/soap/nanotrasen, 20), + new /datum/point_redemption_item("Umbrella", /obj/item/melee/umbrella/random, 20), + new /datum/point_redemption_item("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), + new /datum/point_redemption_item("Plush Toy", /obj/random/plushie, 30), + new /datum/point_redemption_item("Survey Tools - Shovel", /obj/item/shovel, 40), + new /datum/point_redemption_item("Survey Tools - Mechanical Trap", /obj/item/beartrap, 50), + new /datum/point_redemption_item("Shelter Capsule", /obj/item/survivalcapsule, 50), + new /datum/point_redemption_item("Point Transfer Card", /obj/item/point_redemption_voucher/preloaded/survey/c50, 50), + new /datum/point_redemption_item("Regular Firstaid Kit", /obj/item/storage/firstaid/regular, 50), + // new /datum/point_redemption_item("Advanced Firstaid Kit", /obj/item/storage/firstaid/adv, 50), + // new /datum/point_redemption_item("Bone Restoration Medicine", /obj/item/storage/firstaid/bonemed, 50), + // new /datum/point_redemption_item("Clotting Kit", /obj/item/storage/firstaid/clotting, 50), + new /datum/point_redemption_item("Survival Medipen", /obj/item/reagent_containers/hypospray/autoinjector/miner, 50), + new /datum/point_redemption_item("Injector (L) - Glucose", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), + new /datum/point_redemption_item("Injector (L) - Panacea", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), + new /datum/point_redemption_item("Injector (L) - Trauma", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), + new /datum/point_redemption_item("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), + new /datum/point_redemption_item("Geiger Counter", /obj/item/geiger_counter, 75), + new /datum/point_redemption_item("Defense Equipment - Steel Machete", /obj/item/material/knife/machete, 75), + new /datum/point_redemption_item("Defense Equipment - Kinetic Dagger", /obj/item/kinetic_crusher/dagger, 75), + new /datum/point_redemption_item("Laser Pointer", /obj/item/laser_pointer, 90), + new /datum/point_redemption_item("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), + new /datum/point_redemption_item("Nanopaste Tube", /obj/item/stack/nanopaste, 100), + new /datum/point_redemption_item("Binoculars", /obj/item/binoculars, 100), + new /datum/point_redemption_item("100 Thalers", /obj/item/spacecash/c100, 100), + new /datum/point_redemption_item("Defense Equipment - Razor Drone Deployer", /obj/item/grenade/spawnergrenade/manhacks/station/locked, 100), + new /datum/point_redemption_item("Mini-Translocator", /obj/item/perfect_tele/one_beacon, 120), + new /datum/point_redemption_item("Extraction Equipment - Fulton Pack", /obj/item/extraction_pack, 125), + new /datum/point_redemption_item("Defense Equipment - Sentry Drone Deployer", /obj/item/grenade/spawnergrenade/ward, 150), + new /datum/point_redemption_item("Holy Crusade Pack", /obj/item/storage/lockbox/crusade, 200), + new /datum/point_redemption_item("Maniple Pack", /obj/item/storage/lockbox/maniple, 200), + new /datum/point_redemption_item("Jump Boots", /obj/item/clothing/shoes/bhop, 250), + new /datum/point_redemption_item("Defense Equipment - AXHS Gun Case", /obj/item/storage/lockbox/axhs, 250), + new /datum/point_redemption_item("Conscript Pack", /obj/item/storage/lockbox/russian, 250), + new /datum/point_redemption_item("Extraction Equipment - Fulton Beacon", /obj/item/fulton_core, 300), + new /datum/point_redemption_item("Industrial Equipment - Phoron Bore", /obj/item/gun/projectile/magnetic/matfed, 300), + new /datum/point_redemption_item("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 310), + new /datum/point_redemption_item("Colonial Recce Pack", /obj/item/storage/lockbox/colonial, 350), + //uav code is cursed new /datum/point_redemption_item("UAV - Recon Skimmer", /obj/item/uav, 400), + new /datum/point_redemption_item("Away Team Pack", /obj/item/storage/lockbox/away, 550), + new /datum/point_redemption_item("Gateway Guardian Pack", /obj/item/storage/lockbox/gateway, 800), + new /datum/point_redemption_item("Cyan Posse Pack", /obj/item/storage/lockbox/cowboy, 800), + new /datum/point_redemption_item("Bar Shelter Capsule", /obj/item/survivalcapsule/luxurybar, 1000), + new /datum/point_redemption_item("1000 Thalers", /obj/item/spacecash/c1000, 1000), + new /datum/point_redemption_item("Defense Equipment - Marksman Box", /obj/item/gunbox/marksman, 1000), + ) diff --git a/code/game/machinery/point_redemption_vendor/unsorted_please_sort_these.dm b/code/game/machinery/point_redemption_vendor/unsorted_please_sort_these.dm new file mode 100644 index 00000000000..9d27f1903c2 --- /dev/null +++ b/code/game/machinery/point_redemption_vendor/unsorted_please_sort_these.dm @@ -0,0 +1,113 @@ +// stuff i kicked over from old files that i don't want to deal with. someone deal with them. + +/obj/item/tank/vimur + name = "Vimur tank" + desc = "Contains Vimur. A gas with very high thermal capacity. Probably not so smart to breath." + icon = 'icons/obj/tank_vr.dmi' + icon_state = "coolant" + gauge_icon = null + slot_flags = null //they have no straps! + volume = 500//Standard tanks have 70, we up that alot, a cannister has 1000, but we want this to be worth our points. + +/obj/item/tank/vimur/Initialize(mapload) + . = ..() + src.air_contents.adjust_gas(GAS_ID_VIMUR, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + return . + +/obj/item/engineering_mystical_tech + name = "XYE" + desc = "???" + icon = 'icons/obj/abductor.dmi' + icon_state = "circuit" + w_class = WEIGHT_CLASS_SMALL + origin_tech = list(TECH_PRECURSOR = 1) + +// todo: generic supply vouchers +/obj/item/engineering_voucher + name = "equipment voucher" + desc = "An used voucher that could be used to be redeemed for something at the cargo console" + icon = 'icons/obj/vouchers.dmi' + icon_state = "engineering_voucher_used" + w_class = WEIGHT_CLASS_SMALL + var/datum/supply_pack/redeemable_for = null + +/obj/item/engineering_voucher/proc/redeem(var/mob/user) + if(!redeemable_for) + to_chat(user, SPAN_WARNING("[src] has already been used")) + return + var/datum/supply_order/order = new /datum/supply_order + + var/idname = "*None Provided*" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + idname = H.get_authentification_name() + else if(issilicon(user)) + idname = user.real_name + + order.ordernum = ++SSsupply.ordernum // Ordernum is used to track the order between the playerside list of orders and the adminside list + order.index = order.ordernum // Index can be fabricated, or falsified. Ordernum is a permanent marker used to track the order + order.object = redeemable_for + order.name = redeemable_for.name + order.cost = 0 + order.ordered_by = idname + order.comment = "Voucher redemption" + order.ordered_at = stationdate2text() + " - " + stationtime2text() + order.status = SUP_ORDER_APPROVED //auto approved + order.approved_by = "[user]" + order.approved_at = stationdate2text() + " - " + stationtime2text() + + SSsupply.order_history += order//tell supply the order exists. + SSsupply.adm_order_history += order + + name = "used " + name + redeemable_for = null + icon_state = "engineering_voucher_used" + desc = "An used voucher that was used to redeem for something at the cargo console" + +/obj/item/engineering_voucher/teg + name = "Thermo-Electric Generator voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of a Thermo-Electric Generator" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/teg + +/obj/item/engineering_voucher/collectors + name = "Radiation Collector voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of crate of radiation collectors" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/radiation_collector + +/obj/item/engineering_voucher/smcore + name = "Supermatter Core voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of a Supermatter core" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/supermatter_core + +/obj/item/engineering_voucher/fusion_core + name = "Fusion Core voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of a fusion core" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_core + +/obj/item/engineering_voucher/fusion_fuel_injector + name = "Fuel Injector voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of a fusion fuel injector" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_fuel_injector + +/obj/item/engineering_voucher/gyrotrons + name = "Gyrotron voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of Gyrotrons" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/gyrotron + +/obj/item/engineering_voucher/fuel_compressor + name = "Fuel compressor voucher" + desc = "A voucher redeemable, at any NT cargo department, for shipment of a Fuel rod compressor" + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_fuel_compressor + +/obj/item/engineering_voucher/reflector + name = "Laser reflector voucher" + desc = "A voucher redeemable, at any NT cargo department, for a single laser reflector." + icon_state = "engineering_voucher" + redeemable_for = new /datum/supply_pack/nanotrasen/engineering/reflector diff --git a/code/game/objects/items/id_cards/station_ids.dm b/code/game/objects/items/id_cards/station_ids.dm index 8a455e75ccc..20a473b093d 100644 --- a/code/game/objects/items/id_cards/station_ids.dm +++ b/code/game/objects/items/id_cards/station_ids.dm @@ -37,9 +37,11 @@ var/assignment = null //can be alt title or the actual job var/rank = null //actual job - var/mining_points = 0 // For redeeming at mining equipment vendors - var/survey_points = 0 // For redeeming at explorer equipment vendors. - var/engineer_points = 0 // For redeeming at engineering equipment vendors + //* Point Redemption *// + + /// stored POINT_REDEMPTION_TYPE_* points; enum associated to number + /// * lazy list + var/list/stored_redemption_points /obj/item/card/id/Initialize(mapload) . = ..() @@ -76,8 +78,11 @@ . = ..() if(.) . += "
" - if(mining_points) - . += "There's [mining_points] mining equipment redemption point\s loaded onto this card." + for(var/key in stored_redemption_points) + var/amount = stored_redemption_points[key] + if(!amount) + continue + . += "There's [amount] [key] equipment redemption point[amount > 1 ? "s" : ""] loaded on this card." /obj/item/card/id/update_name() name = "[registered_name? "[registered_name]'s " : ""]ID Card [assignment? "([assignment])" : ""]" @@ -216,6 +221,27 @@ var/datum/tgui_module/card_mod/admin/card_vv/mod = new(src) mod.ui_interact(usr) +//* Point Redemption *// + +/obj/item/card/id/proc/get_redemption_points(point_type) + return stored_redemption_points?[point_type] || 0 + +/obj/item/card/id/proc/set_redemption_points(point_type, amount) + LAZYSET(stored_redemption_points, point_type, amount) + +/obj/item/card/id/proc/adjust_redemption_points(point_type, amount) + LAZYINITLIST(stored_redemption_points) + stored_redemption_points[point_type] = max(0, stored_redemption_points[point_type] + amount) + +/** + * @return TRUE / FALSE on success / fail + */ +/obj/item/card/id/proc/use_redemption_points(point_type, amount) + if(stored_redemption_points?[point_type] < amount) + return FALSE + stored_redemption_points[point_type] -= amount + return TRUE + /obj/item/card/id/silver name = "command identification card" desc = "A silver card which shows honour and dedication." diff --git a/code/game/objects/structures/crates_lockers/closets/secure/explorer.dm b/code/game/objects/structures/crates_lockers/closets/secure/explorer.dm index 38c6d00eae8..ce4ce245aa8 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/explorer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/explorer.dm @@ -152,7 +152,7 @@ /obj/item/clothing/accessory/holster/leg, /obj/item/reagent_containers/food/snacks/liquid, /obj/item/reagent_containers/food/snacks/liquid/protein, - /obj/item/card/mining_point_card/survey/gimmick, + /obj/item/point_redemption_voucher/preloaded/survey/c300, /obj/item/cataloguer/compact/pathfinder, /obj/item/binoculars) diff --git a/code/modules/catalogue/cataloguer.dm b/code/modules/catalogue/cataloguer.dm index 452e3296d28..4676f0f844f 100644 --- a/code/modules/catalogue/cataloguer.dm +++ b/code/modules/catalogue/cataloguer.dm @@ -329,7 +329,7 @@ GLOBAL_LIST_EMPTY(all_cataloguers) busy = TRUE var/obj/item/card/id/ID = W if(points_stored) - ID.survey_points += points_stored + ID.adjust_redemption_points(POINT_REDEMPTION_TYPE_SURVEY, points_stored) points_stored = 0 to_chat(user, "You swipe the id over \the [src].") else diff --git a/code/modules/mining/machinery/machine_processing.dm b/code/modules/mining/machinery/machine_processing.dm index 950f9b19713..5adfbb47f14 100644 --- a/code/modules/mining/machinery/machine_processing.dm +++ b/code/modules/mining/machinery/machine_processing.dm @@ -74,7 +74,7 @@ data["unclaimedPoints"] = machine.points if(inserted_id) data["idName"] = inserted_id.registered_name - data["idPoints"] = inserted_id.mining_points + data["idPoints"] = inserted_id.get_redemption_points(POINT_REDEMPTION_TYPE_MINING) else data["idName"] = "" data["idPoints"] = 0 @@ -114,7 +114,7 @@ return TRUE if("claim_points") if(istype(inserted_id)) - inserted_id.mining_points += machine.points + inserted_id.adjust_redemption_points(POINT_REDEMPTION_TYPE_MINING, machine.points) machine.points = 0 playsound(src.loc, 'sound/machines/ping.ogg', clickvol, 0) return TRUE diff --git a/code/modules/mining/ore_redemption_machine/engineering_points_vendor.dm b/code/modules/mining/ore_redemption_machine/engineering_points_vendor.dm deleted file mode 100644 index f2ad1e9bebe..00000000000 --- a/code/modules/mining/ore_redemption_machine/engineering_points_vendor.dm +++ /dev/null @@ -1,235 +0,0 @@ -/***************************** - * Points vendor for engineers - * Points are aquired via crypto miners. - *****************************/ - -/obj/machinery/mineral/equipment_vendor/engineering - name = "Engineering Equipment Vendor" - desc = "An equipment vendor for engineers, point generated by the crypto miners can be spend here." - icon_state = "engineering" - icon_deny = "engineering-deny" - child = TRUE - //circuit = /obj/item/circuitboard/engineering_equip - prize_list = list( - //Mining vendor steals - new /datum/data/mining_equipment("Vodka", /obj/item/reagent_containers/food/drinks/bottle/vodka, 3), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 5), - new /datum/data/mining_equipment("Soap", /obj/item/soap/nanotrasen, 2), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/laser_pointer, 9), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 3), - new /datum/data/mining_equipment("GPS Device", /obj/item/gps/engineering, 1), - new /datum/data/mining_equipment("50 Point Transfer Card", /obj/item/card/mining_point_card/engineering, 50), - new /datum/data/mining_equipment("Umbrella", /obj/item/melee/umbrella/random, 20), - new /datum/data/mining_equipment("100 Thaler", /obj/item/spacecash/c100, 4), - new /datum/data/mining_equipment("1000 Thaler", /obj/item/spacecash/c1000, 40), - new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/hardsuit/industrial, 50), - new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/hardsuit_module/device/plasmacutter, 10), - new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/hardsuit_module/maneuvering_jets, 12), - new /datum/data/mining_equipment("Hardsuit - Intelligence Storage", /obj/item/hardsuit_module/ai_container, 25), - new /datum/data/mining_equipment("Injector (L) - Panacea", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), - //Mining vendor steals - Ends - //Power tools like the CE gets, if kev comes crying: https://cdn.discordapp.com/attachments/296237931587305472/956517623519141908/unknown.png - new /datum/data/mining_equipment("Advanced Hardsuit", /obj/item/hardsuit/ce, 150), - new /datum/data/mining_equipment("Power Tool - Hand Drill", /obj/item/tool/screwdriver/power, 80), - new /datum/data/mining_equipment("Power Tool - Jaws of life", /obj/item/tool/crowbar/power, 80), - new /datum/data/mining_equipment("Power Tool - Experimental Welder", /obj/item/weldingtool/experimental, 80), - new /datum/data/mining_equipment("Power Tool - Upgraded T-Ray Scanner", /obj/item/t_scanner/upgraded, 80), - new /datum/data/mining_equipment("Power Tool - Advanced T-Ray Scanner", /obj/item/t_scanner/advanced, 80), - new /datum/data/mining_equipment("Power Tool - Long Range Atmosphere scanner", /obj/item/atmos_analyzer/longrange, 80), - //new /datum/data/mining_equipment("Power Tool - Holofan Projector", /obj/item/holosign_creator/combifan, 80), - new /datum/data/mining_equipment("Superior Welding Goggles", /obj/item/clothing/glasses/welding/superior, 50), - - //Level 2 stock parts, to make engineering kinda self sufficent for minor upgrades but the parts are also kinda expansive - new /datum/data/mining_equipment("Stock Parts - Advanced Capacitor", /obj/item/stock_parts/capacitor/adv, 20), - new /datum/data/mining_equipment("Stock Parts - Advanced Scanning Module", /obj/item/stock_parts/scanning_module/adv, 20), - new /datum/data/mining_equipment("Stock Parts - Nano-Manipulator", /obj/item/stock_parts/manipulator/nano, 20), - new /datum/data/mining_equipment("Stock Parts - High-Power Micro-Laser", /obj/item/stock_parts/micro_laser/high, 20), - new /datum/data/mining_equipment("Stock Parts - Advanced Matter Bin", /obj/item/stock_parts/matter_bin/adv, 20), - - //Special Resources which the vendor is the primary source off: - new /datum/data/mining_equipment("Special Parts - Vimur Tank", /obj/item/tank/vimur, 5), - new /datum/data/mining_equipment("Special Parts - TEG Voucher", /obj/item/engineering_voucher/teg, 20), - new /datum/data/mining_equipment("Special Parts - SM Core Voucher", /obj/item/engineering_voucher/smcore, 40), - new /datum/data/mining_equipment("Special Parts - Fusion Core Voucher", /obj/item/engineering_voucher/fusion_core, 20), - new /datum/data/mining_equipment("Special Parts - Fuel Injector Voucher", /obj/item/engineering_voucher/fusion_fuel_injector, 10), - new /datum/data/mining_equipment("Special Parts - Gyrotrons Voucher", /obj/item/engineering_voucher/gyrotrons, 20), - new /datum/data/mining_equipment("Special Parts - Fuel compressor Voucher", /obj/item/engineering_voucher/fuel_compressor, 10), - new /datum/data/mining_equipment("Special Parts - Collector Voucher", /obj/item/engineering_voucher/collectors, 10), - new /datum/data/mining_equipment("Special Parts - Laser Reflector Voucher", /obj/item/engineering_voucher/reflector, 30), - //voucher: Solar crate, Vimur canister - new /datum/data/mining_equipment("???", /obj/item/engineering_mystical_tech, 1000) - ) - -/obj/machinery/mineral/equipment_vendor/engineering/interact(mob/user) - user.set_machine(src) - - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.engineer_points] engineering points collected. Eject ID.
" - else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Engineering Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() - -/obj/machinery/mineral/equipment_vendor/engineering/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - if(ishuman(usr)) - usr.put_in_hands_or_drop(inserted_id) - inserted_id = null - else - inserted_id.forceMove(get_turf(src)) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/card/id/I = usr.get_active_held_item() - if(istype(I) && !inserted_id) - if(!usr.attempt_insert_item_for_installation(I, src)) - return - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_id.engineer_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.engineer_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() - -/obj/item/tank/vimur - name = "Vimur tank" - desc = "Contains Vimur. A gas with very high thermal capacity. Probably not so smart to breath." - icon = 'icons/obj/tank_vr.dmi' - icon_state = "coolant" - gauge_icon = null - slot_flags = null //they have no straps! - volume = 500//Standard tanks have 70, we up that alot, a cannister has 1000, but we want this to be worth our points. - -/obj/item/tank/vimur/Initialize(mapload) - . = ..() - src.air_contents.adjust_gas(GAS_ID_VIMUR, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) - return . - -/obj/item/engineering_voucher - name = "equipment voucher" - desc = "An used voucher that could be used to be redeemed for something at the cargo console" - icon = 'icons/obj/vouchers.dmi' - icon_state = "engineering_voucher_used" - w_class = WEIGHT_CLASS_SMALL - var/datum/supply_pack/redeemable_for = null - -/obj/item/engineering_voucher/proc/redeem(var/mob/user) - if(!redeemable_for) - to_chat(user, SPAN_WARNING("[src] has already been used")) - return - var/datum/supply_order/order = new /datum/supply_order - - var/idname = "*None Provided*" - if(ishuman(user)) - var/mob/living/carbon/human/H = user - idname = H.get_authentification_name() - else if(issilicon(user)) - idname = user.real_name - - order.ordernum = ++SSsupply.ordernum // Ordernum is used to track the order between the playerside list of orders and the adminside list - order.index = order.ordernum // Index can be fabricated, or falsified. Ordernum is a permanent marker used to track the order - order.object = redeemable_for - order.name = redeemable_for.name - order.cost = 0 - order.ordered_by = idname - order.comment = "Voucher redemption" - order.ordered_at = stationdate2text() + " - " + stationtime2text() - order.status = SUP_ORDER_APPROVED //auto approved - order.approved_by = "[user]" - order.approved_at = stationdate2text() + " - " + stationtime2text() - - SSsupply.order_history += order//tell supply the order exists. - SSsupply.adm_order_history += order - - name = "used " + name - redeemable_for = null - icon_state = "engineering_voucher_used" - desc = "An used voucher that was used to redeem for something at the cargo console" - -/obj/item/engineering_voucher/teg - name = "Thermo-Electric Generator voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of a Thermo-Electric Generator" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/teg - -/obj/item/engineering_voucher/collectors - name = "Radiation Collector voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of crate of radiation collectors" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/radiation_collector - -/obj/item/engineering_voucher/smcore - name = "Supermatter Core voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of a Supermatter core" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/supermatter_core - -/obj/item/engineering_voucher/fusion_core - name = "Fusion Core voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of a fusion core" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_core - -/obj/item/engineering_voucher/fusion_fuel_injector - name = "Fuel Injector voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of a fusion fuel injector" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_fuel_injector - -/obj/item/engineering_voucher/gyrotrons - name = "Gyrotron voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of Gyrotrons" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/gyrotron - -/obj/item/engineering_voucher/fuel_compressor - name = "Fuel compressor voucher" - desc = "A voucher redeemable, at any NT cargo department, for shipment of a Fuel rod compressor" - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/engine/fusion_fuel_compressor - -/obj/item/engineering_voucher/reflector - name = "Laser reflector voucher" - desc = "A voucher redeemable, at any NT cargo department, for a single laser reflector." - icon_state = "engineering_voucher" - redeemable_for = new /datum/supply_pack/nanotrasen/engineering/reflector - -/obj/item/engineering_mystical_tech - name = "XYE" - desc = "???" - icon = 'icons/obj/abductor.dmi' - icon_state = "circuit" - w_class = WEIGHT_CLASS_SMALL - origin_tech = list(TECH_PRECURSOR = 1) diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm deleted file mode 100644 index c6294d6f77d..00000000000 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ /dev/null @@ -1,250 +0,0 @@ -/**********************Mining Equipment Locker**************************/ - -/obj/machinery/mineral/equipment_vendor - name = "mining equipment vendor" - desc = "An equipment vendor for miners, points collected at an ore redemption machine can be spent here." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "mining" - density = TRUE - anchored = TRUE - circuit = /obj/item/circuitboard/mining_equipment_vendor - var/icon_deny = "mining-deny" - var/obj/item/card/id/inserted_id - var/child = FALSE//To tell topic() to bypass this iteration of it - var/list/prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 125), - new /datum/data/mining_equipment("Absinthe", /obj/item/reagent_containers/food/drinks/bottle/absinthe, 125), - new /datum/data/mining_equipment("Hard Root Beer", /obj/item/reagent_containers/food/drinks/bottle/small/alcsassafras, 70), - new /datum/data/mining_equipment("Special Blend Whiskey", /obj/item/reagent_containers/food/drinks/bottle/specialwhiskey, 250), - new /datum/data/mining_equipment("Random Booze", /obj/random/alcohol, 125), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - new /datum/data/mining_equipment("Root Beer", /obj/item/reagent_containers/food/drinks/bottle/small/sassafras, 50), - new /datum/data/mining_equipment("Sarsaparilla", /obj/item/reagent_containers/food/drinks/bottle/small/sarsaparilla, 50), - new /datum/data/mining_equipment("Soap", /obj/item/soap/nanotrasen, 200), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/laser_pointer, 900), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/geiger_counter, 750), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), - new /datum/data/mining_equipment("GPS Device", /obj/item/gps/mining, 100), - new /datum/data/mining_equipment("Portable Fuel Can", /obj/item/reagent_containers/portable_fuelcan, 250), - // TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/t_scanner/adv_mining_scanner, 800), - new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 500), - // TODO new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), - new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card, 500), - new /datum/data/mining_equipment("1000 Point Transfer Card", /obj/item/card/mining_point_card/onethou, 1000), - new /datum/data/mining_equipment("2000 Point Transfer Card", /obj/item/card/mining_point_card/twothou, 2000), - new /datum/data/mining_equipment("3000 Point Transfer Card", /obj/item/card/mining_point_card/threethou, 3000), - new /datum/data/mining_equipment("Umbrella", /obj/item/melee/umbrella/random, 200), - new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/autoinjector/miner, 500), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/perfect_tele/one_beacon, 1200), - // new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), - new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/projectile/energy/kinetic_accelerator, 900), - new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900), - new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), - new /datum/data/mining_equipment("Wormhole Fulton Pack", /obj/item/extraction_pack/wormhole, 1750), - new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/pickaxe/silver, 1200), - new /datum/data/mining_equipment("Climbing Pick", /obj/item/pickaxe/icepick, 2200), - //new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), - new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000), - new /datum/data/mining_equipment("Advanced Ore Scanner", /obj/item/mining_scanner/advanced, 2000), - new /datum/data/mining_equipment("100 Thalers", /obj/item/spacecash/c100, 20000), - new /datum/data/mining_equipment("1000 Thalers", /obj/item/spacecash/c1000, 200000), - new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/hardsuit/industrial, 2000), - new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/hardsuit_module/device/plasmacutter, 800), - new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/hardsuit_module/device/drill, 5000), - new /datum/data/mining_equipment("Hardsuit - Ore Scanner", /obj/item/hardsuit_module/device/orescanner, 1000), - new /datum/data/mining_equipment("Hardsuit - Material Scanner", /obj/item/hardsuit_module/vision/material, 500), - new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/hardsuit_module/maneuvering_jets, 1250), - new /datum/data/mining_equipment("Hardsuit - Intelligence Storage", /obj/item/hardsuit_module/ai_container, 2500), - new /datum/data/mining_equipment("Hardsuit - Smoke Bomb Deployer", /obj/item/hardsuit_module/grenade_launcher/smoke, 2000), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/gun/projectile/magnetic/matfed, 3000), - new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher",/obj/item/storage/bag/sheetsnatcher, 500), - new /datum/data/mining_equipment("Repurposed Equipment - Mining Carbine", /obj/item/gun/projectile/energy/gun/miningcarbine, 5000), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), - new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3100), - new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/ka_modkit/tracer, 125), - new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/ka_modkit/tracer/adjustable, 175), - new /datum/data/mining_equipment("KA Super Chassis", /obj/item/ka_modkit/chassis_mod, 250), - new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/ka_modkit/chassis_mod/orange, 300), - new /datum/data/mining_equipment("KA Range Increase", /obj/item/ka_modkit/range, 1000), - new /datum/data/mining_equipment("KA Cooldown Decrease", /obj/item/ka_modkit/cooldown, 1200), - new /datum/data/mining_equipment("KA Capacity Increase", /obj/item/ka_modkit/capacity, 1500), - new /datum/data/mining_equipment("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), - new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/storage/excavation, 500), - new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/measuring_tape, 125), - new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/pickaxe/hand, 375), - new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/plastique/seismic/locked, 1500), - new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), - new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), - new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/grenade/smokebomb, 100), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/grenade/spawnergrenade/manhacks/station/locked, 1000), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/grenade/spawnergrenade/ward, 1500), - new /datum/data/mining_equipment("Defense Equipment - Plasteel Machete", /obj/item/clothing/accessory/holster/machete/occupied, 500), - new /datum/data/mining_equipment("Defense Equipment - Kinetic Dagger", /obj/item/kinetic_crusher/dagger, 1200), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/survivalcapsule/luxurybar, 10000) - ) - -/datum/data/mining_equipment - var/equipment_name = "generic" - var/equipment_path = null - var/cost = 0 - -/datum/data/mining_equipment/New(name, path, cost) - src.equipment_name = name - src.equipment_path = path - src.cost = cost - -/obj/machinery/mineral/equipment_vendor/power_change() - var/old_stat = machine_stat - ..() - if(old_stat != machine_stat) - update_icon() - if(inserted_id && !powered()) - visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.") - inserted_id.forceMove(get_turf(src)) - -/obj/machinery/mineral/equipment_vendor/update_icon() - if(panel_open) - icon_state = "[initial(icon_state)]-open" - else if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - -/obj/machinery/mineral/equipment_vendor/attack_hand(mob/user, datum/event_args/actor/clickchain/e_args) - if(..()) - return - interact(user) - -/obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user) - . = ..() - interact(user) - -/obj/machinery/mineral/equipment_vendor/interact(mob/user) - user.set_machine(src) - - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" - else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() - -/obj/machinery/mineral/equipment_vendor/Topic(href, href_list) - if(..()) - return 1 - if(child) - return 0 - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - if(ishuman(usr)) - usr.put_in_hands_or_drop(inserted_id) - inserted_id = null - else - inserted_id.forceMove(get_turf(src)) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/card/id/I = usr.get_active_held_item() - if(istype(I) && !inserted_id) - if(!usr.attempt_insert_item_for_installation(I, src)) - return - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_id.mining_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.mining_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() - -/obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, I)) - updateUsrDialog() - return CLICKCHAIN_DO_NOT_PROPAGATE - if(default_part_replacement(user, I)) - return CLICKCHAIN_DO_NOT_PROPAGATE - if(default_deconstruction_crowbar(user, I)) - return CLICKCHAIN_DO_NOT_PROPAGATE - if(istype(I, /obj/item/mining_voucher)) - if(!powered()) - return - RedeemVoucher(I, user) - return CLICKCHAIN_DO_NOT_PROPAGATE - if(istype(I,/obj/item/card/id)) - if(!powered()) - return CLICKCHAIN_DO_NOT_PROPAGATE - else if(!inserted_id) - if(!user.attempt_insert_item_for_installation(I, src)) - return - inserted_id = I - interact(user) - return CLICKCHAIN_DO_NOT_PROPAGATE - ..() - -/obj/machinery/mineral/equipment_vendor/drop_products(method, atom/where) - . = ..() - inserted_id?.forceMove(where) - inserted_id = null - -/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner", "Crusher") - if(!selection || !Adjacent(redeemer) || voucher.loc != redeemer) - return - var/drop_location = drop_location() - switch(selection) - if("Kinetic Accelerator") - new /obj/item/gun/projectile/energy/kinetic_accelerator(drop_location) - if("Resonator") - new /obj/item/resonator(drop_location) - qdel(voucher) - -/obj/machinery/mineral/equipment_vendor/proc/new_prize(var/name, var/path, var/cost) // Generic proc for adding new entries. Good for abusing for FUN and PROFIT. - if(!cost) - cost = 100 - if(!path) - path = /obj/item/stack/marker_beacon - if(!name) - name = "Generic Entry" - prize_list += new /datum/data/mining_equipment(name, path, cost) - -/obj/machinery/mineral/equipment_vendor/legacy_ex_act(severity, target) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() - if(prob(50 / severity) && severity < 3) - qdel(src) diff --git a/code/modules/mining/ore_redemption_machine/mine_point_items.dm b/code/modules/mining/ore_redemption_machine/mine_point_items.dm deleted file mode 100644 index fe4dd1f39d5..00000000000 --- a/code/modules/mining/ore_redemption_machine/mine_point_items.dm +++ /dev/null @@ -1,75 +0,0 @@ -/**********************Mining Equipment Locker Items**************************/ - -/**********************Mining Equipment Voucher**********************/ - -/obj/item/mining_voucher - name = "mining voucher" - desc = "A token to redeem a piece of equipment. Use it on a mining equipment vendor." - icon = 'icons/obj/mining.dmi' - icon_state = "mining_voucher" - w_class = WEIGHT_CLASS_TINY - -/**********************Mining Point Card**********************/ - -/obj/item/card/mining_point_card - name = "mining point card" - desc = "A small card preloaded with mining points. Swipe your ID card over it to transfer the points, then discard." - icon_state = "data" - var/mine_points = 500 - var/survey_points = 0 - var/engineering_points - -/obj/item/card/mining_point_card/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/card/id)) - var/obj/item/card/id/C = I - if(mine_points) - C.mining_points += mine_points - to_chat(user, "You transfer [mine_points] excavation points to [C].") - mine_points = 0 - else - to_chat(user, "There's no excavation points left on [src].") - - if(survey_points) - C.survey_points += survey_points - to_chat(user, "You transfer [survey_points] survey points to [C].") - survey_points = 0 - else - to_chat(user, "There's no survey points left on [src].") - - if(engineering_points) - C.engineer_points += engineering_points - to_chat(user, "You transfer [engineering_points] engineering points to [C].") - engineering_points = 0 - else - to_chat(user, "There's no engineering points left on [src].") - ..() - -/obj/item/card/mining_point_card/examine(mob/user, dist) - . = ..() - . += "There's [mine_points] excavation points on the card." - . += "There's [survey_points] survey points on the card." - -/obj/item/card/mining_point_card/onethou - name = "deluxe mining point card" - mine_points = 1000 - -/obj/item/card/mining_point_card/twothou - name = "deluxe mining point card" - mine_points = 2000 - -/obj/item/card/mining_point_card/threethou - name = "deluxe mining point card" - mine_points = 3000 - -/obj/item/card/mining_point_card/survey - mine_points = 0 - survey_points = 50 - -/obj/item/card/mining_point_card/survey/gimmick - name = "exploration equipment voucher" - mine_points = 0 - survey_points = 300 - -/obj/item/card/mining_point_card/engineering - mine_points = 0 - engineering_points = 50 diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm deleted file mode 100644 index 1c8e8bc280f..00000000000 --- a/code/modules/mining/ore_redemption_machine/survey_vendor.dm +++ /dev/null @@ -1,124 +0,0 @@ -/obj/machinery/mineral/equipment_vendor/survey - name = "exploration equipment vendor" - desc = "An equipment vendor for explorers, points collected with a survey scanner can be spent here." - icon = 'icons/obj/machines/mining_machines.dmi' - icon_state = "exploration" - density = TRUE - anchored = TRUE - circuit = /obj/item/circuitboard/exploration_equipment_vendor - icon_deny = "exploration-deny" - var/icon_vend = "exploration-vend" - child = TRUE - prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), - new /datum/data/mining_equipment("GPS Device", /obj/item/gps/explorer, 10), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/grenade/smokebomb, 10), - new /datum/data/mining_equipment("Whiskey", /obj/item/reagent_containers/food/drinks/bottle/whiskey, 10), - new /datum/data/mining_equipment("Absinthe", /obj/item/reagent_containers/food/drinks/bottle/absinthe, 10), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), - new /datum/data/mining_equipment("Soap", /obj/item/soap/nanotrasen, 20), - new /datum/data/mining_equipment("Umbrella", /obj/item/melee/umbrella/random, 20), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30), - new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/shovel, 40), - new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/beartrap, 50), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/survivalcapsule, 50), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/card/mining_point_card/survey, 50), - new /datum/data/mining_equipment("Regular Firstaid Kit", /obj/item/storage/firstaid/regular, 50), - // new /datum/data/mining_equipment("Advanced Firstaid Kit", /obj/item/storage/firstaid/adv, 50), - // new /datum/data/mining_equipment("Bone Restoration Medicine", /obj/item/storage/firstaid/bonemed, 50), - // new /datum/data/mining_equipment("Clotting Kit", /obj/item/storage/firstaid/clotting, 50), - new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/autoinjector/miner, 50), - new /datum/data/mining_equipment("Injector (L) - Glucose", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), - new /datum/data/mining_equipment("Injector (L) - Panacea", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), - new /datum/data/mining_equipment("Injector (L) - Trauma", /obj/item/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/geiger_counter, 75), - new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/material/knife/machete, 75), - new /datum/data/mining_equipment("Defense Equipment - Kinetic Dagger", /obj/item/kinetic_crusher/dagger, 75), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/laser_pointer, 90), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100), - new /datum/data/mining_equipment("Binoculars", /obj/item/binoculars, 100), - new /datum/data/mining_equipment("100 Thalers", /obj/item/spacecash/c100, 100), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer", /obj/item/grenade/spawnergrenade/manhacks/station/locked, 100), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/perfect_tele/one_beacon, 120), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack", /obj/item/extraction_pack, 125), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer", /obj/item/grenade/spawnergrenade/ward, 150), - new /datum/data/mining_equipment("Holy Crusade Pack", /obj/item/storage/lockbox/crusade, 200), - new /datum/data/mining_equipment("Maniple Pack", /obj/item/storage/lockbox/maniple, 200), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250), - new /datum/data/mining_equipment("Defense Equipment - AXHS Gun Case", /obj/item/storage/lockbox/axhs, 250), - new /datum/data/mining_equipment("Conscript Pack", /obj/item/storage/lockbox/russian, 250), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon", /obj/item/fulton_core, 300), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/gun/projectile/magnetic/matfed, 300), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 310), - new /datum/data/mining_equipment("Colonial Recce Pack", /obj/item/storage/lockbox/colonial, 350), - //uav code is cursed new /datum/data/mining_equipment("UAV - Recon Skimmer", /obj/item/uav, 400), - new /datum/data/mining_equipment("Away Team Pack", /obj/item/storage/lockbox/away, 550), - new /datum/data/mining_equipment("Gateway Guardian Pack", /obj/item/storage/lockbox/gateway, 800), - new /datum/data/mining_equipment("Cyan Posse Pack", /obj/item/storage/lockbox/cowboy, 800), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/survivalcapsule/luxurybar, 1000), - new /datum/data/mining_equipment("1000 Thalers", /obj/item/spacecash/c1000, 1000), - new /datum/data/mining_equipment("Defense Equipment - Marksman Box", /obj/item/gunbox/marksman, 1000), - ) -/obj/machinery/mineral/equipment_vendor/survey/interact(mob/user) - user.set_machine(src) - - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.survey_points] survey points collected. Eject ID.
" - else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Survey Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() - -/obj/machinery/mineral/equipment_vendor/survey/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands_or_drop(inserted_id) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/card/id/I = usr.get_active_held_item() - if(istype(I) && !inserted_id) - if(!usr.attempt_insert_item_for_installation(I, src)) - return - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_id.survey_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.survey_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - flick(icon_vend, src) - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm index 78f9e82325c..06e19da285d 100644 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -27,7 +27,7 @@ return switch(id) if("modify") - return tgui_cardmod.ui_act(action, params, ui) + return tgui_cardmod.ui_act(action, params, ui, new /datum/event_args/actor(usr)) /datum/computer_file/program/card_mod/ui_pre_open(datum/tgui/ui) ui.register_module(tgui_cardmod, "modify") diff --git a/code/modules/power/crypto_miner.dm b/code/modules/power/crypto_miner.dm index 049f285aee9..119d8c7efad 100644 --- a/code/modules/power/crypto_miner.dm +++ b/code/modules/power/crypto_miner.dm @@ -73,7 +73,7 @@ GLOBAL_VAR_INIT(power_per_point, 1000 KILOWATTS) if(istype(W, /obj/item/card/id)) var/obj/item/card/id/used_id = W - used_id.engineer_points += points_stored + used_id.adjust_redemption_points(POINT_REDEMPTION_TYPE_ENGINEERING, points_stored) to_chat(user, SPAN_NOTICE("You transfer [points_stored] points to your ID")) points_stored = 0 return diff --git a/code/modules/tgui/datum.dm b/code/modules/tgui/datum.dm index 96a04797227..4a134110c82 100644 --- a/code/modules/tgui/datum.dm +++ b/code/modules/tgui/datum.dm @@ -46,6 +46,7 @@ * * action - the string of the TGUI-side act() that was invoked by the user * * params - the list of key-value parameters of the act() invocation. This is always strings for both key and value! * * ui - the TGUI instance invoking this (host window) + * * e_args - actor datum holding data on who's doing it and who's initiating it * * @return bool If the user's input has been handled and the UI should update. */ @@ -152,7 +153,7 @@ // this basically matches the useModule<>() hook used on the UI side, because id is null if // we're a host window, and not an act call from an embedded component. if(!id) - return ui_act(action, params, ui) + return ui_act(action, params, ui, new /datum/event_args/actor(usr)) return FALSE /** diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 4281f386c57..967a08cfab0 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -412,7 +412,7 @@ window = window, src_object = src_object) process_status() - if(src_object.ui_act(action, payload, src)) + if(src_object.ui_act(action, payload, src, new /datum/event_args/actor(usr))) SStgui.update_uis(src_object) return FALSE if("mod/") // module act @@ -559,3 +559,8 @@ */ /datum/tgui/proc/still_interactive() return status == UI_INTERACTIVE + +//* Setters *// + +/datum/tgui/proc/set_title(string) + title = string diff --git a/icons/machinery/point_redemption_vendor/engineering.dmi b/icons/machinery/point_redemption_vendor/engineering.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3e344cc7c601afebcb4d9ccf209b3ec42df09d8d GIT binary patch literal 595 zcmV-Z0<8UsP)WEC1U9X>D$FbaYE@ zQJDY$00DGTPE!Ct=GbNc004t}R9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo` zEh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+H7`9gFEzC&GcR3< zi!&v&s2C_}$igNLXE&vFgNi`<1 zT<`z@0X#`WK~z|U?N-@t#2^d|xlEJpw*CK~t!<7t6ig&|sl;q#iJf5xP9kQSI>40i zjGyOu$pHUe%@bY$32OXg)~$fm8C3YmYOHL8czbSVDa*bIEn@; z?^dvgYXv_NccAcY1q)!W75qrtfx-vDeiQ6}42pcGEi^Z=@iDf(NFRAb1Dz*9`kftA zgu$8Mppr8HUk>U~#sGY|@oa!?<+%(rpch3N;E?As&_MDem~#*YD&M1t&5yBz!KXyV zK;xa@^?n7g0GoX?Q1~E-aDuPYpvXJH`#U0Qpz!%Urdv?>4o^WjI85bWF}0&@sT^$! z8!XE20YCD=$Oj`IjC>%^#-9WS6=9&}2WbGlr1?P24{U&K<+%(rNb-T2A4Wd-$NAuF h%m?Sl2a<2i2fx~iQH!hH`r-fp002ovPDHLkV1nK#1JVEh literal 0 HcmV?d00001 diff --git a/icons/machinery/point_redemption_vendor/mining.dmi b/icons/machinery/point_redemption_vendor/mining.dmi new file mode 100644 index 0000000000000000000000000000000000000000..8f44b349cbed8128c9b0f6749da0c2f1ba5d600a GIT binary patch literal 1091 zcmV-J1ibr+P)*-p*mn; zDxgO-QBpu+WjaDbF-(IyJ!vm>c4QnJ77q^$FE1}UJ3A>WD`{V=-0C=2JR&a84_w-Y6@%7{? zOD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sVp@wCBI0Ci!&v& zs2C_<$imYs6jQ*my5 zzQleHyDFuNBvjx&3s~emZ zh>BEkc09KWK-eWgJnAOUtRg_maRxAK61W-aIBqi-j_yaFux~uZW@5jSi3`y3JYaN> z0b{y|Vq3d`g5y8YJT$2c&~mI{d|JL~y~a9@yTFuSQZ&=qd^WFkiH_4Q7(YG^^XgFn zr}O!2=I;^>$A`q%P|NWl!DoDbLUDa@at~3*x$_)^^FD~vS@P9a!&#%@dBEanQHlca zjfzc7?_4FPHxdRo@dBD>*r&@q%)ltCluoA77b$`EHxfx14D8UjxD^Jwny|FkRlHjZWRD>!4%fm|4 z{1C(Zza+K)msbGmCV9?{<)YAjuQ$(|?>J_=#b#%}yWQHe=PVCPuzAKCZ0VxW*wzv- zTon5IA5HT7Kg&g-zdtSSzWxk&E(-m9IdE4r`@`{Y^!z`|16Ba*?aRwLuPzmMe>@%z z{x0IUC?nKZ;-b|4UrxXu1)~3#r1t+o2`=^juWv`^|0Om1`vvd+Uw{5`{y!+enZIA~ z{{Q#jkMsXQCA!rAzf*!RSMe|Y|NWweto8q50VhtvdkXG>2$w` zhR59xqnr*}qMU-l{bv^~7;n_9Z49V)H|6Dd9v<4Z$4ir6+C^J+)682H6>BzkFc?f) zS{j8y5gB_BfjoE!scU3vX@_z531|q)07UKsDc+}iK$vgL3!+19hHpTM^ZAPr$uanp zm_!^1lvd;8hfn@#XUhk_&Y3gtFgEz`XTQ&*f0=$VpPDi1KcW8ylw4HYhBEgyA24@E z*36Xkl=&ik?in35(Wbjzp_ps8HYw|c_4VHLyHQmw6~FyZt$fovuS zB-!ESe9SkkW+j*sI(A&)f{EqhLG`EN&k73*T}m|ULo-)KXwmv#v`@y#TH#uL@2t^u zY}2Xy*)9i{K@_}S9xd}TJEPBRt{D*9n;LN4j3KOWtW@G~Y?`UrZ|KJz9+hhZ!kWj6 zy}i9G_QuzD;@peYm4@Foq;6{1RT};vmA;!jUpt)_{%JyU1*KhOGDqo6m3F~Mt%3t~ z&7bG_&R(p%k(Hz__&QIyeEBjs5_-FHe(c!Wb!%^fuap;Rvdx+S*X%!3x<^{#nWVYb z%Iky@oLWfz+xz!_yni*$;7t0KWABi8-J!AFpf{!%S*r(wPw&SVG{%IGZPm## zLr33loEZ4x64uIIse8zB2pS&LE^K5^s}@Xm%Q(?M)y2C4MxEb-;=gEmKw*Ek)yaYR z#9OiZneoYD&8n-yhTQGpoy36AnT?GKLp6Yv2N(Xa21h^IYN)7q;BO5c!XkvV(+Fau zO2yz{+_2>guX6wAc+0c21A=FTziO&pBmFd6?s-$FYh~2h{*1tHr(yzImubd4bJMYB z#tAC8mHuq#N8`-Qv0l#p9{SpJ!THtYwzkKytL)Lx<9|a0;@CR=pudwu!mnRO!_pDB zGuwaNW+gs6I>pxU3}dlcp2zbJ2m;=ksZVYGLK!&Mei+9z&REhwsPgYleYjg zu%BE~Ts}91SLgK}Volrxx=L@V1K!^% z6|T0YrDkVOJg=Im1Yd1WX$fiJ;dAtVX{z9 zRRo3cm)c?+n(R$AqAzZ88&w$defZ07jr|v2;Vtp)ziQ{btsGv=>~86MYdbre6t&)@8Z2Jv^Sn!1eGWQ7%@RdWnot*<@@L9+oS{vUUdkINe1s;?4C8PSzeC-6Qcn2GG>|={VufWb}>4};1?E}FGfS%}g-qc(SdDD8Cu+m)-HjC!%(+ucit0W#&n0;aGXDy*BLCPzcfd!}&ilJNN^u`rN6n#^lCL2S*`CV|$;U2<+-YEm{Kq`& zq7FhM|Cct>COuV&swe)zKhuO!oZKg~pE>+y2jtmFs&h8xeiu5IOA5*+f;qqou0U%E z;>JnOO!dznn}3yHs{rS~wFc)C&gPG8zrYiTm>NNDJ-5^Nqi_-UkT*ui+AH2l&lOyU zqLkRH@WKIfNdQ%8L5RYNwH>-bhDmXuWlNiye8jw~1#YagO-Q`^dJ$3eBqx!A--pEg zLq{3fncn@BrU$ts0Pg)WfH#Nl_61tM#A^*j;CblDKSSHQJahQPe-g5%hJDNiIJrK_ zHk+K>fxs4c%>_=b1xpy19VYRAG?sASeJ$`vKIAhC5-4N{&k7mNN&0-qBO)NMdqyu3 z03GMBGySUlv%Gf;h-lanRF0S>Y$hUEh(0d#Hv#aXZI8>aPWqbzWVOjXdb}(BL@wtD zC-?H@N|Vr+{e~H@!LHZnX-6ceMFKdFY)=PwLpp=nFm^JWToKFQ_s38Ll+#uz_|gW< zEb-W_Z zK`&YG<@f`=vR;d_Lrkn;nTrJ10>l=lZZ;dh0usqTmBgmDu7!N3v2J0K#@uA%S$ z*La2t2?sm8nFwYZblTXR?CkmZ4p5`FjxN%ah!Sdo zB3%g5AwWbRNK1eKArO+cIiB~%|NrldJMO)Eut@gWYwxx8T64|$ec#Nh+XmVK`%muY z;o%X0-MV4K!?VkFr|jheYJ%@)>+$gXRvBn)=6%D#%kGhjhqnvTorlLiEk2RtPL@9q zLh8ILylCFYfqRKq98mv2Z@3k%ua}@2YA}GOeDdv1#Z*f+IKB7-`mL{bX?~hHzqQ0( z53G8pT;QO35K2U;U$v5CDV+)dQ3M5#cBry8bFW+xY?)YIUV8my#N!k}>~z;n#j*@! z!>f}aRHb<_XXh9>H|EvL18KC0qr;$ZsN9vwDX~{+iD~q&;u4SMe&A0U_}us716^>o zeJy%T)&jAeWUU--H6(Gp*pnz=t!$jFu&z6GuhIGI_SpdV;^*1q-ivaF0^9i$ie&Rd zG!0G4%(A3%<%&#~lmh#^HFRQbJ1xUphNzA^)Y+vi^JeHQxef-nEDBSqJzlCvMeK*Rl^^z+ObiPw{;~2FnX=Be# zQksMjR!*n*bXB-flD-aB(hRimw)$jsA4d9U(VloKF-`Gdv&+Vz70273bU7WFr(c*C zY}I;yC@EmldBNUx%ns)yg{~MV6y^=Ea`$M49Of;l5<-!c!hHt%nWL*3VGEqBb{C3@ll#PV9gmT;zH zvbfoUm4a<}ew6i%%p;5VW53@dq0;ih)1nj4=9+IhMLNxe{77!@j(f82vtq;_1`YO8 z$<2?y4tq}Ug_j1W?zwoPy*1fBwP`tMG_-NPtLs^9-;47_yI&kP6MBrOv=X02|DIntfy!{3=5%<}asvBq1x4;&-=AY^4en*N?! zp81E$lep8VIm)45nsue4Nt|d@6b0o)pfJ=!=;tYCNG*C)1`9>pV@=7RqgJM0i|+z9 z)_)%I>G1(4a*Qt8Nf%dF2N<8`Nh|5{6f`P`Gq3S32)}Gm=kGbS*cN-9{&Q}wMzIvP z`|)zlXziQ&dbqN(vWW#xL(t8uM{eaBId-L88ThQGrsjWO7f<8O&d0lW?ChTUeOeo| zLCO?oXN!BFrQ#K4y+jT27`Sfx9GL z>rJMDQH;9*<8rWvZf?eQc6Oz7#Mr#952sHnfS8k+x-p^cJH0tRP){%(g!{pF+PS*k zwY0SS)$TZR&Ge^mNPs?J?f!AK=KI#MNVM7gNc2U-zOPHBr@{@PM%n4RT3BM;ZGNF8 zrlzKe{U|5Cg=3awU0q$h?Sc?q-_Vl5S9V*5($IwiUoTc#*ZR>lO4!R9ymox-@nw>| zg3jCC=#O0#^DhU6ELWQYsS8ty0?d-BsKDRFlB4VNTNDewvV{IP8M(D&W?{;aYtP9W}1UH2dx#=W7uvgsq^QLyc(^#4UN9_ zyzAxGrnGnX-w!g$v|F&IGE-37?^04y;tbx3BeH9_4{Uw-x(*Bli^wb5IyPvwP_`pv zLrtV+McxGosSTu=m-Qp|rtRA5R2|*lsgsrdR^_B0k^d}>-Q0ZBm36IYupF=i;0u^2PMZYzX|!ZecJuzH-Tw3W zZ3&HRm$X+~iq$IpCV*{?`c~O;yj;&)ba4C7=lQ850~>c4?k#HnQ`SAkk%5)kgO2=k z?p(zBI`>m8a2fug-GU>%1(Hgl$RnS9WaIYGMdGoMCGyAQ;&qa9brai#vzx+BXpg5~ z4OodREiHv?uYmhaQm5k+AKH4{24j|fw35T19yBp19YRgzj*h%?T>cTOlctvYg?%>~ zU!Z$_e3`<`Sn15b5k{@b=M->^Cy(HPy-m@0hncvsWvVWcMK$fzO=?f=Q1)MeqnGl$ z&LYpVmp?HdsFE;SYE_f1L>(WaxX;o{BF zHj2i_@&UaC`h_7ejdcQ!@JAKxhPZ5pMD9#0`O`jZ^<;x9DXLYDNf!Q+{r7$zkzW^s zloq|Uw$Bxq&d)JV7&$bqru2rtEX^%fU~=fmHGR11Cmqq7uC7H?QU)?tAiJ*O-rE>P z$%p$3baJ-Vaoyq%tfjpVPQm{62pmpiWMo6jq11;(`ajr$W*wyT4X^KZFJ}e}l)~g7 zE;8H`#0=pL;Rn8(j}#YE!iuMf>?*!TavP^@f_N46d5uQq{^odC-5hL>`{U0=T|mq~#q}obl+BAsFM^v^}tb zM6m~+vLGt@6$x0t%k8I@6%>C+;Qs07_lZ3>_t2FUA_$UAA|l8tt}Gkw=Ab6J#uxCN zF@2+>RtZQqa^6U$*Sl)OPyc|HN_D(%R&x3pqXWV-Sg<2 z(r3f(QIi)UHq17IdilTF$Pp~coXFmuSt={*)@{EZpKvlAMY>l_d-aq>>YBoj1#A`D zKMh@q)bIUTA}woN>393p?9sDG$>cX@>+;_BTq?@HUHMk~m5Ac6Ix9FFAtf!{Pob1u zyqkApTu0%WmOr@?;kY>Rac*J3SRpyQF5dq0u?b-7=)|O?rZOTCmev6U5-wiki8?#7 zketSqzG^w{P^Gj9{2WXzCP0}!R0-I=Bn(bzher1NPXEoaiMi%xStaw{7`0Y3nfW6m zbh^5Iop3ZurgU#eJKh*op|0NZ<<)Km;y8uF;oROr7H#MT!ZY zvh@4VF!UaOP~i7S1jN@?-s4p63W^{1K*UEhwgz8AYxD1f8%+T{v#Tuiuw zzkj7kVNOUG352sJ6=Um*70L_XCDySlTl4Or%F6Q?8zH3~ z^!mRzmN-g5Yc~~vG6}9k(6a710;L&PMquma0mco~E{?DM=7kJ=vMfqoUkKgmtdORG zF?M8Mw-m>n!Ul#`P^{!CB^?2n0$@mYfyDtT5#-8FH=t}p+#e2gB6k91r-31+Vi>iO z+PTw*<@UZ_6YS@W2n1y5X9=|-8-J2mj-bw3+ojW#F?RE;J!SIL@5h0rWJP|VBqyOd zrT__2iD-+FbOZ`epDIEH-}F8=WjQo5a#FRjq^?5Q!;Q=#s6VkITazkxN0w~$FMlt0 z7#{!BP`<`aPY2dzdwUzWss@4Zw!Ab57!?KfYtj2EFb|K!#b3_0@RwJL#v7`y#R0~H zb{$V?*QqGZx;~tKTGH|B%et}t!MA&AY746W7c>5^x2(ri?;(}ooB?~hC>F1z8;vJ! zG~GbY5n{y^#vI?uflZ5R^pIjFyMs*)BI~vnHHm}KUyBGkK_qX5`bZ2SpI^X#{>Hd3 zG*Ab=r-HLZ49qsK`XT)gf#_$m7~)95s~o8J)TdfBV@B4(Ay3AYq6OP#lTngrPTY zQXMGl|8M)og4h-AD7FcOEtZ;>Y-wth<3@+*=t03N>ztOT`N~e@#*V*H>X4F(Tb#Y~ zpgFvi3`e5_-_(-9#G0BBV-u4?BGKk)`_@B7Ff1Oqyj~DWdD-mNI zEoZ^b=(uDS$DL?rt9zTUh*(OeT%Y-T6O-fxH5tsHtl4gEbPt()$eS3^ z!~%i$kL|TfcHR1NqNcl<>^pR{Y&x#@VU!ddZ@khRxiy38=ToqBAocj8f3N=sUM0#Y!~0MU9lY*y#mg zRGpJ_x4SH|R7*;mR>A*40oPtwFic>7K|igy%6)IwxY9qZaVC zV!X17A$9`g>?ES)&%Rj00|8eDB}|65tTZ#+V?l|L;6J(VizP=-GS!TTAnwjpWDU{*5fL#P4mFEt2~? za-%0#w|{)R6u{)Imaua_&#ICcMN~<>>CWk3l6}Ex{iHW%<$>o`cr=;zjf@ns7&F?x zVywPHuDQvbOgF=*BZ`i{;;t$HmVb42sjSWz2zrD4cjZEX@C(Fq00O5pg&FE-OLiJf zEqbLmKMnOb)q?Hoca*NHuOCAa+nB1pw%t0SFG_xp0S_)kF^~@xtGI@kYglLeR|LIPq-cByxF1CQhnLL|Bz03^`iIUrOWzy51KP6WeX$r7~lR z_K57Uxne8hL$pZQk6N!R>NV5OGjQwxX2DeCVpZ zT3lEtC1Y8sckkXk@y#Y`LOX6A72$wMva`|ATFznn4w%LCl+vFX?A#_x zQ7x{iQTzDe!?AkAoz_Hk6V|M^MY7(xo&>hydCK9LHABwO6wnn|S$Uc;YWEgIRR*M~ z{GuZ1hvcV~)xt6|GKED&VUomx0@$p#+OOMWO6N1!Qw*{#U)IK~d7!HG zZU_q0yh)Mcdfel;!2+-LhOErJ-8@jX8yy9$_vr}Re24Ae>+)N+LdKQt9d#LW00IChSH|y1A71mJ{PBxo#t$~1 z|LO*^Mf6=u37(Thh`^o=fE*J8E|>;x_UcHR)2qg-uw4P9i$-BnAKHR-V_Cg z_Iyt)77P1p^pjPbbN=AZCd+8xr6`yv+oFxi%E}k*_zYV1iu#$ z&NQy1ef^-05sehkqQdw$oIS?v>iY6>do2kF%y0C=GT zBKvV~$QZZ0j?>PN@eXz9Lzo$qhu8cIlvcSk^WasDOahY>aSv0;#Jyg$y@M$KF~VJr zq06LnRrOVx*_Cs%9UJ}}C4ATxeKN@`0@k{~(v+Orq&a%Z$iu2uFPX(s3NfNG<-LXF=S#-sEqG>*s1Y zq1k)lIA6~Ou}G)7qaUxqK`3)@ZdrK(B|gAh?I)3Aqb6ta`NuLh5!?BD>CT8;wl|3% z6NnBS6Ahvs+xmuc9X4t$7M#YYt0HEPB?=x;ort>pvjl^;+H3U)r^**PY%Ej?=?ID( z%QJ&pwc_gPs{NOSw-V8KGK^ufB;o;wkG(8sh=)q_4-W3gTWf1;TF6tZ<(b6z2-IK~ z&Tl+|ddEO_t9r!t zsV?vJlVb$w6EGLuGPn)DjrQ~?%>C{!m=km=&*lIyG2rHKsfO|EbEiXQPsCH0-}6Nq zg8ry&xxeXTgc+TImZFg5-cdMA(%@7O{BrXT_6(YDfx3M-r=Z{>bF6dhg}L>9;3-Uv zr&WwDh*yQBpQvL1jFk@Bg{{GZ!L=Uv`w1DZcHUWarDE94ojT{vK(p$bYwL_FN!*vS z`T)bf1J!=iVXyGe-Ffg>uI+n^v*`VQRV$Ju1;&{ zB7p>zjg_twIJsGqA)>%@quuhk698I`{pldtx|5uTZ+N1#cSDbhG;DyqsCwcsV(qM7 zOiuPuNwigpavkA5@k7P6y!&r8&ch(NZzqQg!oO(S^Ekb;S8yrC^%da4UNmb%Wji+u zbNB`~a&mZ$8Vy`#meeU{&?Z@jS`fy&tnZq;ENaIC9FSj#4csL|tf=rBodLAjQ~_y9 zoWvMo2>V(hpe0ugwc+uJT^R6<{j5`T7z6A1@FmWQ`?M%T!=s!ze44WOa&9vSW&3B$ zhX*TDR!}{HelIfZepWko=|o6rZ)XQFo47^9zJ0N+*+JZ9YA$vPqK%q`w|nPiBw^f* zdoE7Tl(uJQ=N1;~d6KM5WY`2;>q%6_py$}8gz9s9W z+{58UF2ML1sDe9tl=69Fd>_8WxL_n0Ar3vVusxDuuZ2#lzJbnaZAWP21;=PS>c5UQ zJ}L64Oy_4R2ReOiUTX}m!_;f$C`$9enVyZ9Su!QjmvClr zyR2SQaf+v+H!&4ZdraD?tjkTuCiFk{I|fYWMpIAReGbU|K-$42hlSDd?<04+9jCY% z8pc6Z2|EIl8~x4u`e)TYX2lXmUL4k1#?^Q{<>TYq8T1bS267axwzhxznX=(ADUrn*-wI2$42N< zI0IMG74BUNRrZ2k^lB7Wzxp?Hn`Gkil(Bjr=QA;tJHR?BN9JBoP>=-Tbscx_%(0Gq z%VRB;N;uB~gjvhM12?-3`WhM@cf~8ov-jHCQ8K(2lEM5`?MLgA1}pHMefWtM32)-1KRMSsX0@>{4XO%J>yfw(wACf~bz_b5#Cx!<*LO{q1tecz&MhnMAB?X8-B3`Zw26g zxPNVJZU5L}Pd=voi9-(>Ie9 zoumQ=;SX0zH^!C*--St{Ex`g&DLEo1Hy;Vj#*Bhm=lt4rV$QiZI_B+2MGU5OK&}S; z(nfX;NDvE)87HrId@xR&-4la3Gx#}E4uoVf%5I!M6E3Sz(&n{X{cM+`E_i zE6Cq6Dy8)ID;ILAwwm0c0I=aRKj1RI6g*EQMB@l}bvRATV-thO^kFpzKOb&+5UE+- zB1uCLk+#7E)|C$SbKH|=9P%zf#6uxj2|ViYth8>W{ctd|Cp83PF|z#AWNiHvGqj*~ zNv9|MM5Im(N5Lw{5Wl3xj?6823Lak(qn%Adin2HFZwP${rjTloQ+vp%V%Q2uc})RO z;nj_^t2dRE>zRkL2m}rA4zt0OwG9dub!*fl1`qqa#pX?Ip?UckopQH^oZflPkd1$e zEJe=Xsr$<^084)e%*T42hxgBqauSj-Fb19Qu$>aLWn2(EI6-I`{XCBCsxtPRsRe-d z^jPI}veB*Y(9c(b2h~N_$6INhNf_aA0l)u?5`^!sm&Z+dJ9+oj7+m9qt-4jwmQE|{JS{QX;RZ#F|iWi>??N$U%V9DNNKS@7Ut?@Nv2 z*tg;|l(w#JNB(c8;!O20-^KT819O-;Y(@a=qGon<|5y@DrTF^RPoZ_yI0fEFX<|3H z!bq;_SC9Ksc7fEqZ{g7oaK2YJ$17~WZrF4&$s%K zc8|qkDDtE}6c~9}cJ(M;QC0%EYaB4sQSMQDCT*-5bGf42$kE2ADpi&;zwQ3@f#LNe z^jGF)ek6b|D!-`nMnG&a2iHMaA0HoB&r6Ik)H6!W{0;}?T=s^0RG+gY&22hi6DNUQumg3hHL_)2 z05d4HS_`CggwL~1Shr+qhO9CsHKR^uU8?ID+LnD@p`Jl`!51#xX5Zt_U4|6;DciCq zrglxf^b=aRIf3R*5YO^X-Xi$jxb06NUTA1g-LZOD*3xecX1eEMo2eoHb*{0?kwCQb zzKig&C+;$Bf)>^Eq2*g6MvHXvQJ7^Rkl+ALa((Ve$UI(dV~W4}JAHQyW*NGT4*HP) z0QN62!7}tisnJbhXb!HVCA14VhD_(#-?3#k0gNYBmCG9)Y;VY}&YyX_BSgE(>S!ep znf_jPNKbaM@QO|b_AEeT(Nf=&ULTl!&-m{J{PZ9TEnbf0I@(^#5oQ#~gv$ZvLzgq3>FMhE#7 zB%Po0%)owkJG@cQ3MeXo$Z=O!H%wxB6Ap(1PB13NTTQ(%Bl0IT0>Wh%gc+NZTjbHN z!P?ghPm#+)K*N%-&6UK2h&e1vx8rPES#j~#S}uS~Mu49eNB~@HEqil*uq;Y~a;4Or zHo0ic_r^a{BVio=`zcy#R~ab2iZP}&G$H#QvzmFXB{r&(bd#y zDA}Q7#x^z?^Fb{DBe~-?S=B06WTyUr-CJKDljB;JoDN*sNyWcM(K*odp>Ak#iB+}2 zAT!dm^lCl+eRWikWu_eszUK___U@|OTnFP_9u%|j)Jt=zvNTjLz&L(ekS!g*F6uB5 zzd|S0Rt54e&I(y;cY7XCqaK5wN$Xa$MILs3_;7#PzAKaYUvPAp&(JZlsOpwa^POcH z7Vrmz;icJDFt2Z9In%6mFu(@rstzfjlWTOYeFl}RmzR&f9}&XFa;)#!vof|UOz*IO zyliK`AM({DETwr(t6ty|ZBj5z289d-$inC0bP$vN;AIf^AN2n-GhE)wf4(Wnsrjn9 P!x>;&1~*Et+dln2c8Qn1 literal 9611 zcmbVy2UJtrx-RNQ+=8;V3J8j*fFf0;DOIrs1f&Q8hAM<&2%SKHs0eICKsrc?^d=x( zT7s}CO7A6*&?BJ)5+H=MyV#!d?l|Y{_r`s94dx(guDRyS{Ok9BGvSZ*9vnL=bd-aG z;~41ST|*9z1J?WP$YG!-#3uU@2gku0f8(cKckMmxJe=IToM5gT9PqS+q&`>dRi3cE z9;4H1X00r+r=U5HdKIbp;XB<&i8tQrjn?A7`h4#CXyy9rMv6_RzQVQw15TsuX{ceE z&dI*ebry_jrRt-2c}+nY$2w-QW38=!Ue`khIqCJby2At1)Wph_&W6c_g;fr8uMp0- zWwmGC?D6Lk`mn%_Ro8!~n2*@KyTd)-r_+1G@4-caI6;+iBs{Htw!{G_ zh5PR#Oe{3>Opl2QD24y#G6f4ZJvLJCj(Ngw$NK3`4=vc86Ge0a%jx_2Wd}BOtST#56SgiKFGtMI)4v4*dTcg@& zI1u_4=#t)>sD60NVHH)7XAU&pTb-NL=N zDm%HuQ80P`P6brD0DDgGgez~PL~Rmp%sPrVJ zTDWL-q`T2w!RPwt_3~c%1hkpUlXtJ$oFh|X?BbrPpOPGj6uNq5)In%GrErIIBz&ax zp4)G#wbu?^pdQdQ)Z2b5lX*S@Evh6N9|ZEPl6#qBz5PoXO86Joqspf?cpC@f?{`gnFw#Y|b&})9a zkkbCLd%}J8@VnBGRIV!m-#b&Dr?zb(rrx%$^!5ff42NDW<_z6tceM;{kXdT`CdNA0 zx!xxIQ3e;m!Ev4gboaI~JZ)_n={CIGMA|gH=*SlZ|60{Te0?F}&r@Q#wk1!a>PL3; zEc{!V$>A%Y+-g8Efs{Q?o#Z9BBTmI1FGS&G%01XUEX;+r<$SO0Ov zSH7L%{Puis{HTkQlVBVd2c+0@D){+zr$kw>q}@AyIm@&D2=cS|cj)kK(@Y&jxcv0c9l?@S(ZOn$@$oWdI zO&uVTk|kAn>-_O0B9W+4!ua^tXBGDsY^O!8^jA0Al*ZPl8}y|xQxNO!m-uP+vX^UaYXL?j{!I=-3&Rjz*-6d6KtVA8VIZ_S$@* zulwTf`4ZB79Xdkxd~tpd37RGro3w^^TiaUw@|Yd!k{=d}`u4nn30KPy79e)aZ#D}W zppYRuJUXmcBLW|OH>$;g)dy*9} z3ogT4pJ`$iD}M-)Lg$#`3yqnPwQq2&?Z$7uO{^6pr5n}Yn2=KQJogexL4|$iTR#?b z=OoF$I)6lde>0V`#sNr^6n&{sQn*kEEL&nTQ` zGI@T7N*c&25;vI)_`+#$|DPd&ga>>damLmN92t&cYq-!-P9nFPj&1%WnB2=Hi)?cA z$w1hhZa^`4U_?wcV{GRfwdt6Fx}0k-3IS*%JV|o@xnw1i|sWR8h&m0O0t!ak(~^CW44u(QVYcbrdn*pbpEJ6rgtgseyq8${AcwZ#rTN;x`+Gg^%S91dFjNfCiz|2fP#4%1@_p;r z6^%fxA0=Y*rf1|)~@BUKXcKK#Md=NSr(WY?q>c=Zad2evq*MsiC zu{BVKwaIEABpP0fIntEy{Pn5XT%9EC{qIkXf?AwwxEosqI3}(f8XyRP;g`2xFG zESn%E48o-OzOYyw)dm?-mC4bq3Kx7|mCVtd^VG+M%p}o!J)5^STieLb?DufT`}s}Z z99p!HM5o{^o#y_0O{;lJYHq&uajo`AKtp}~!9^Xz2M@wX<28XDQS_)1RdeeX6KBE> z2X@p5t6p7DJ#J)=4$&*;X*kw>CDEq#!2Xou$N5GM_mbAC2M;fv>iUfRm}V>J!yTUr zq_de9wSn}VqnL82i{&mf1V3K$7WR&X$plnD$G|_gz+PC;=aHW_&H!fjzq#PB4^95r zDL~s4!YcU=NXi3kUa_VG@Z6yruwbCq2T)+0W_2?>5{lT@S_&VpP+2)tRY_NVzggO0 zM*$7#N;@>R*NhAgCj+_xCV=j%18D6oJY6PgLpJ*j7yzbj^LtK@S-cw?uh|Jbnb$P? zW`Bv90c_8!2QXz|vTmcmcC`^mWBVwD*V487YgZ&NG+#jas=geY%4NAeUL&rPm<+Vj zz?X1%Gj@75MjkcDMvaBwSaV7At?I3a3|ikOcz*z+rtcx< zrYzXo;K!Oia-*-FR*qGt_`dky;A-U_b3G6yrNNx)$8w3NmZ~aYmQpa6_~pBbisF~o zo&>bN>&Jqb%sp5AXh@K*Ze)0yt8+X zj!NF_+(xK%cL(6HE+XS|Nic-4M>H(c&PG(Tvs|Q%(zg=uxk-dvVuVJobq5fF*St3x zaP9NENs(FtE%2pDjg1h!Dh~_Z)U0uK+d|}6oq$(h`yJyBn?_1-8a1Rs3i|2kDM{eU zx-skF8F?))D=W*kaZI#`ao$f!?qvWSe?Jkg@(yBoffn^3e&wkv{ql?ahQREjZbn9N z*V>Z-)G7rvG8+2QeK;+`qY+}=8%~lw)3@E3MB0M#Ed==0MMqOPpI&Pb#NycV=}D>S zsRSIsKv#RJ-R}B~clymPXz3lah)+l<_rGlae{}P*!ua>?qZ~IX#o|D54WDvzL(C0d z{|dOnOZl#}o1VsiLkatOc@^a5inl1LcpAJsa4NU5(kMMW-JmR#FZ`};_o{|87!00m z)V?bE`rULFRKfwQr`$1pxTlw?TmxSWt!Cc#q(nj&5yB_Sw#&tR)jg<~wSYIGF%Odw zVs>J7{NI!B3sOG5^Sj-CTF~x8H+SBEnxjyUmZ*_CvEzPIyJPA#XNCLRk!A$~-Dh)k zvn{Xk5;-Z1C+*3_IHjecFkSSVrP->sklmxUKc>p*&pq4gx}Y21eWF`?rK_fG2%O-{ z)bR<|Gg#6B4T@P~*p6L3I-kNOVO$g}ONJi!U8(0t%APtoRrg!2o7_u7bTk6|A|h*i z!4(g8EsOJ2iN^AKqvu~s`ItO@)1^PaIbPQ}U3nIwmLXudu2NSy9U{@qectMR=Gr+@ z){TsgW~O9klXTIVH-_jTSJ|XbUW|eS{RYw6jGW`=;CRyxcJzeZ`yZ+1-v_<)Fp6n7 zpYlk^!bV0$#*W-6QsQqpWgbNR`sgcTqFC9yOOxE+#7O}XZ3M({D!1do9Tn#wrDC#ZH)8v@BEb$zT<#{lw3)1<}&DDk5mSEv?D zztMP^ejUC;jC7cr;+>d)gZ=^E6w8zA_7*@cv_Ac`ABZy-iTexH7M8aE*@r|`GrGeu zd$>@z&)VI}T|-0%I|=#MsJBem<~F}J-y#psD)Jrb*E(+3`sGV5Hh?#9qCAxdrbz23 zLzIqLmwx^bQ6qUXfI-gYir-tfh@k0<^#6|PKw4Q8>*uUO*`y(-!u$@(W&ss*YK>Ow zyC*I4`3oBvucxyXrY?e^=Zb4jTf4JsbHuB6H6V>t&J@I)S&r6ntOVBCgiB&%loxx&=um!N`$#G##{Eji%T(ZBl->I z>S`jHaP;SE5k$siWB{4c`|^yCkXnbHW~V1vz3jB!@6tZgE#_Q=d=&liEPO#(L7@Ps zFozQv@|W=j#|fG=A4(vkSr6YNP3>B_S=XhLKtJ(u{27&Od!rIRm2_b~Mr5Z=pOun8 z;vf0B89x!XajL=8;Ih|O>TIk&keE?2G=|I(^0&(<#`SMp|L!q=e-FvIhB8n9uxfSR zU6t6Nx*5pD9su53vhGm%yJ2ayU(H#)!BoC(3;=e_S!088{C|};)r_Paq}*fHo<+uc zF(?g*N)TI&f-aH96?!Ij_JQ;*EIR?q|1cI!2^J6s)y*4nPP4o4Q=%aMfWZ?W!}W28 z{S;^BhjU|x!H(4e1B5jKzO43QeqH~%I&8m0ev(9tyc1l%@%>w7Z7cwTGycx`rT{c% zmNfo}$wX8YID>v-V*ut~6|o42wCt%`nS+CWtTAIZrCK}%O0EwjeloTV#00RlAsmdYHDD zYzEHve;o6Pwk_VRsjlYy4&Y-dmGo;otaumw!HIYOzljegAUiM=!22M>9sIsnc?G&W z6P6LGw=AChe!QLu25%Z*Q&nr4*i>OvjWpj8Mx$LS?a-k^lgc)5D_~_A(wE_jXT9hh z6h?7(ZT~)|zJ0Up`l^yd{?pLuf8yyl@zt8Ab!^v0vV0(n>qXdG=Lo)$og|$g*8#8g z+?qC_=rs}fLx;0=Le{J(!Wh#M%;K-p=sCjovrSf;%LHOfUd)8g`i=h8fEV-`yAJP; zAQIz@W<6|RO z*_^z?JK?19brpB5u;5j;M&v4q{$R&y{YE2GvxvhA=N)4B&G@BJuEKI@Rn!mrz79D} z|67InvK2|}tpmcFevR})a>T^pYJfl(lGEmD5@9EmM)1{sVY3&lhS1UY-C0Ui5HtVN zB5cBAoOzYGFF+WAAk-#>V;g$Jpqhhhql-m~H-!hwg*&d!ELMn?Z& z#ArqW%RrVTG72N^Z;LO_KJeLZ_Vl_E`lh_1CUIWGI|zYj02s5%z_OZtySlDmp}u(% zf;;PHNXt&lH7vZwoKlho*0C}$xL|i5BjrNhS+m=#gF4cl6x;8K2vx5}SUpwBLt)XT z^ac`I z6^o(ts#eZxF;z*8l~s(Qk?i(=C&W-OGy@T~1X(`iQH@A+N2Ogp$#Q8sEr4k_uE9cc zeyOhZ?mo~t9kcHKKImF!v=aWbd>#jZ-;jFaA*O)A3TuDHQFpllaW)5eX%QeEv%mMr zB(9ea@siU5`lQ<7XW5O^m(w0ruN9P)A;|hV?D;O8+d);dy4v&WX!`o<>ge=gGfTsu zUY%yt+FDny>=g9Z&R@>(Wu$z|w!vr1Vrr8~g)r#BK~2jX8eS8<-DsmV8XIVd1qiCTLkuJt>TRJ2qZbc4W2{KwzeQ+yu=RmR&p# zWAobbpVI}N$unL>1omzDmp*t(z}p1}$L8?GU53zalc67iC_E=kSX`Pwd~vm8$uOtc zOjX5o5ldDNM#L4y#CczD|A8`LYsYRyTP6A^X%C@3l%mn-*R)Ebq!1tBvmnf~tsU2* z;$LNuo`_kBhG{ZNmq0c1%67f|DZH(_qDa!-AHj#ZCc5=kybizH@`*?sybm%@Cg|v@ ze7qq1zRE~-+l6A6qA3&S15%M#ep$8Ae1LhcZw2OE&9A-J|Ac$nCOv)&qj0%=Vwdl0 z0ma4H`H?jL(3%u3Mr;l4T#@%E<+_8~)vJ#U|DtP%e(on5stp0K=R|DzHGjlJzhHD` z=A&%gc1|x1M_2SCKi5TXdIJTm*tA;ff|Qm`22#$Lmmrs_0HmFn*SBaj+v-CW2DJ=B zPZgTpY}48hcfvAKS6yAbo)k=V3RdFj^FhUxx?uF8OZSv}{9WNwU##|)sJZEVAOzb5 zzri!n@sCuSSmAH^=-NFv0FTYiHHZx}Y~Q;5;){<&`|L1v?-mXJ0f-sqb& z0L5mJp;C&PK(WIcq+#Pq-_nwybxPasS;dK|vv%kG=gKcv?e^O;;Tsx(4eMC#T*FDv zUUocx)D#^o#+*kQ)!f3cnIv9?2E=^7wFI*j!X-f9mO10wwsjPWkmhmtp-NF{XH(EPP zChxqMWv-Rhii1R+`II`Oq>6*udB#T8u(d1czPJG@jEzQD{^yaOti(9&(}K;?`2ly{ydt2N|cD;I1NG*SxHW4yHqqie5j#sbyr`G zrATL{vG#>D4kav$^1|7-06+x`iDd_kQ9btnv!{Q9CjIi=R{)ohac+BStDwfC@Enri z4r&b<+w8(KwZ?ktEcG>5Iq$9kvJw&!8Z0!*AEpm`fhCrUkh@%g8|l7c%qC0Ps#MV) z{z)DNgQwcxl%H|WIIy3=${v02GM8E-0I@3G-(O7xb<;EN1a&HVX^M+=m8>{t3&Ib} zh-N!Dg@$6%?)f8kM4oSP*^7bV6y(*7fHD_NLzFcdqP+PTW`p|o(PAJ{DLvP`NN4*H zNb|kR>_$?K=F0K_+jy{BnMr~4e8>eQQrUp(2cjx3RSC|~N=eF7yw?vgcl-z;u`KBR zo*^wfH>_q8;%hh1s@#dP1&z0)OiSa%)VKQY5QY5|uL4d{Vo|Hte)@@t36ag9AM&?G zS8YQqM(}u)udpnsUaRmq(M!oQ-pkbd!IsAift0SH!)-Xb$d*V?oMiUVpD9m!89CB` zA|)ewG5r7@J|7vIkwE`{d58UW^`d2f{b=rtXa`rHx<>qEB%dc3>X__!e}<|-3(L$@@{o3^e5c03q!qLCLT2uo7!!uc7)FyE$hna05% zE2go>g;jD;tgZam*G-}wfxNN?#-^oU(#RQPlp+y z1>G*jToqyOc6cu)m_|u9CQYd@oSizdExbD(;AQgGTckjU3{^>xze~@#)n{+r z9!RlcyhZ&=^+}u)KKaPJ1q73Wo7~!`-;elgK)@RRIJXgH1?}Otl&enA8F43q*8J9g zY%(|h|(h_X!=f}A$M78U}PO<6D!TVFss+MxU8(N!8K$w_cuKIjpxxagi;#f zLPN*xz1s_=Ul6NX`$vbA*GDQMb63OU#qp%D6#TD*cTN9i_Ztu06-+Jt77G@U{$5`` z*F!La8!~_3aF*%5+Z&#;b=5kiXKC=A%^{h_!{B6EXMh>wvLvG;uQ(Ly8g^&H6zNjM}%9Z=~VBR z_l=xz>iVcG6@e0r24Ju)Hk8Lbch1s&QQSZtqExroLG9Uo<ng34kCG6)n72IfF#)7M zK5n3W4PL&w?)9Vp0w`Ejb7C`wYL(|fIt?kroyWg4a z`ahQ*QzEXk0Eh5jH2GBC0eNs^b>vJ>sH#aQe-P@qM9VE&;TFOT2=PF8pTuJ>$JZDO z3kw4`+RH_c%{dmoRdSG2eV&ayYLbYrIR&upjs_#Kk0%Yi0NSvoMhWP<0?w@pI;qY5 zQEf5Mto|p?&%FD;QxI+L`8?CVKG6sXyi{wDS;rOzb3QSYl zfPm8Uj*qx zC8A?xWmPshI%?2mSSnayx<8SraY^Db(s8&#F3860YtU0Nl)bmT!o71KzV;U9Qz6-d zt^m^#n-dxu`a;ups=xoYc9q0?LH9<82J--Fj}w~)4%mSw0j!gRGS z#a-$~6fS$!7u4D$++k@V^Hr)CeF3=*1q@wp#ib93R(fAm;F+8l*qE{)QDk31oh@c2a0@6zo5CQ2D1f)hfh%_mo zCRk`vA}tX@5~YP6YC=f+5BJ^omv6lCXN=9^?0w2UYpuQ3oO4IsHqqO^M{19dkkEdJ z{w*^hA>oHxZP#x=PndnKk&w`~rT}v*uUn5j9iBV8dpW~lLPCBSNht&v`NF;kLeE`^ zh5KLlcAk>f`?RVVE&4IWM#*YXCPXallTSt0J1A`TQmTE2>E-pyTt7B@Q(F_?EPMW$ zv5REf7nUhTRMZlpy}$hzne^q$*Gnciq_auy7Z1N6O-=dAtG`DmM?_ThbPWvQN*#Odx<9(3Mr>c@oP~0o(`&o4BiEbL(ocVR;iiUO41a-M@V`!dcH#U8 zQ>bV}_vS~pb46rX$-^+w*wfe)(S$|JETymgZow{kNPUWxR`qGy6MH;ujkw!$olFiF zw-^;911lki_1=U_Cexo>+qh*>vWaKb>BDZA`>U> z@9J*yxa@POVzIJUB?))m^JA#j#)*(wgV#vwpm6=?|HR{iZD1~ zcq4eZF;?>>&nf(PofI}am{WcIhuid@C^s42?cW?7!X6pmDvnQBsSF0k?tPP4`Uf^x zBKt|IoYkY1V%~$I_y@PL4=<1;cj!jk%qWV<#mDuAZ zExRUD+k*E^c>MY;rYtO7Yj#S6=*5$pls4sziy`hGraD|ec;p+mM)`6uJzUEe- z@wWw{`;KVRWg$XBph?KB8|Ho)3l!Ar!Szh~GN~fx@z1fW9ouW;)V+?l|M^nxQH+Fz z^OXmWRfbbv?464@-YGHPx5G>)uCz2?ExMuPZH|T~7D+tV!c}vfAndPv9@U$5ci?hIBQ7~*1 zLiG+{iT%%Ci@pUtGl4*lEv<-)i#zTwbitaJ(3nV|8{fT~7;`aA!xuI-aJSHeml7%> zs{NMOyRAk4QkzC@Nr~Y=p(*y#PN9q|)5+JhF{;2tHDW{xrN?cTkeWlsE(xLA(&Bzj z-54;<+RE40cX}mA8@?y(MGf~+rG)x6xT~v*qQ!@bWIT+b?lxL?@d9dKcJ~yu(dNS> zoKkDYDn%$<0AmR09^-BIyHG5O@6CAB2m#yLXVsWZl!s zgH3REpEVzl)qHw|CMm4ZN-QZXbh2W5=(U(st_LtS%IqiGWkRmC5?$NlWWIa@&B$HQ zZE=c6Ra%*6-`0ONtNCQ7+(UR@$$H0dXSv2eEgC!__ENqEi%lW-^z=;P27Cy6t=r2p zU%EWcbTj!JDw>55r=(qR{l+U|0*Aw$C=YtVb563fLJH^3f(76%s#N+?`2fU=@_Gx)_ci*5>Yk`+=2GdX1tKN zCU-$vLO6aNaAjr9wp&z0!%ie%+Z;4EBn{gfw3B5=lZD81r@=Ht$@ zDuKU9^OJ_BKI}40uliy17TaOHae3=fqNHNa%BZy~8y$n)bvIb=ZCP2F`6^Tkd15F? z#z2+t%P}oTLj|#%qvK`mMp=s#*Nfnhw^?4RzA}Nu1^!}Cn6Qxj=@!5&5_UOA#c6)* zLn+2v_mzPFtnLU~sMo6*xDX*ANrn_AiT-O_|Lfk-@Su?;xv*5Cb~w+bRrLgzvJn=RUOGwR zcYo~Q8kZZO)8VPJe6-ifiJd33_Z5DO2IBNn>SSN-K6 zGBPsWNCeqJH90G^CNqD0a)HcT+3pZ4PvK4%tK)HQclTIILDX*tmGqXwZN9_=$U#I{ z>qG4I#LLqTGoUlwm!WS1Z}v+%fuNV{b+)F`4O;(~;h;JKwQ$5kN_^Yx> zo)pb@!mEKDAxaKhs&tUEl$4ODNCDk6H8p+DMh^}R9UH+e42>)N$sx)_P1`UVc?vf< zwK6n>dNn5RB2iXS=%5RbStS;(!bYvciCDLpIsAvcb7TuvN+?QoVu4&cM@4wsBgpC) z9;u;1`(L~1zx4*M4!k*8(hW4D+q7C|PqFl^_73M(s$!7_#HumStG7p`2k`W%A~<>P zUe$DQG1%1`2=dj^tcP3e#b&Kik7IYgQQMAnx2`8urvQ@z_X94zu+?rLtZJ9S&Q}5L z$RKv10Pg!X9Y?VT?()8hcT!KMsQ}ON0oQcTBVAH=&yt@Yy}rH$$y~gFm}7IwE9>&vAr+`m%} z5HHp#y|_P?odtJ6Ge2>-pFHTtZ`}_zt}IX*EivqFr^A><

VU<%sCcslRiPzC!?W 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 E7Yp+k00000 diff --git a/icons/obj/machines/mining_machines.dmi b/icons/obj/machines/mining_machines.dmi index b3a682b88827fd795b9b2e1d359ba589232b4e09..a7567e9b94912a2163cb4ef185de322549f81a9a 100644 GIT binary patch literal 4123 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 literal 9397 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 s { + const { act, data, config } = useBackend(context); + + return ( + + + + +

+ + + act('idcard')} + /> + + + {data.insertedId ? `${data.points} ${data.pointName} points` : "No ID inserted."} + + +
+ + +
+ + {data.availableItems.map((item, index) => ( + + + + +
+
+ + + + ); +}; diff --git a/tgui/packages/tgui/routes.tsx b/tgui/packages/tgui/routes.tsx index 32fcb2b56cb..9cd5263840a 100644 --- a/tgui/packages/tgui/routes.tsx +++ b/tgui/packages/tgui/routes.tsx @@ -83,7 +83,9 @@ const interfaceSubdirectories = [ ]; const interfacePath = (name: string) => { - let built: [string?] = []; + let built: [string?] = [ + name, + ]; for (let i = 0; i < interfaceSubdirectories.length; i++) { let dir = interfaceSubdirectories[i]; built.push(`${dir}/${name}.js`); @@ -113,7 +115,7 @@ export const getRoutedComponent = store => { return directlyRouteComponent(config?.interface); }; -export const directlyRouteComponent = (name) => { +export const directlyRouteComponent = (name: string) => { let esModule; const got: Array = interfacePath(name) as Array; for (let i = 0; i < got.length; i++) { @@ -136,7 +138,10 @@ export const directlyRouteComponent = (name) => { if (!esModule) { return routingNotFound; } - const Component = esModule[name]; + // pull out any /'s as the interface is often a path, not just the interface export + const nameHasABackslash = name.lastIndexOf("/"); + const realName = nameHasABackslash === -1 ? name : name.substring(nameHasABackslash + 1); + const Component = esModule[realName]; if (!Component) { return routingMissingExport; }