From fab59437199ac7c2f66a07fa6095f2af0b01eb00 Mon Sep 17 00:00:00 2001 From: mcbalaam <104003807+mcbalaam@users.noreply.github.com> Date: Wed, 26 Mar 2025 16:44:54 +0700 Subject: [PATCH] Some minor Big Manipulator refactors (#90240) ## About The Pull Request guh I accidentally broke the manipulator while refactoring the UI because ALL OF A SUDDEN, one of three options is actually two options that are not in any way connected although they should be. And also there are three variables for storing action delays (???). I believe it's not about GBP in the first place, it's about taking responsibility for your own fuck-ups, so here I am. Removed some reused value variables, better autodoc readability, renamed some procs and variables, made more things into constants. ## Why It's Good For The Game ![image](https://github.com/user-attachments/assets/e850b3e5-441e-45c6-a25e-2bf28c958885) ## Changelog :cl: refactor: Minor Big Manipulator code refactoring /:cl: --------- Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> --- .../greyscale_configs/greyscale_effects.dm | 4 +- code/datums/wires/big_manipulator.dm | 18 +- code/game/machinery/big_manipulator.dm | 371 +++++++++--------- .../tgui/interfaces/BigManipulator.tsx | 41 +- 4 files changed, 222 insertions(+), 212 deletions(-) diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm index 91cfb618c21..4d55a21963f 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm @@ -3,7 +3,7 @@ icon_file = 'icons/effects/96x96.dmi' json_config = 'code/datums/greyscale/json_configs/heretic_rune.json' -/datum/greyscale_config/manipulator_hand - name = "Manipulator Hand" +/datum/greyscale_config/manipulator_arm + name = "Manipulator Arm" icon_file = 'icons/obj/machines/big_manipulator_parts/big_manipulator_hand.dmi' json_config = 'code/datums/greyscale/json_configs/manipulator_hand.json' diff --git a/code/datums/wires/big_manipulator.dm b/code/datums/wires/big_manipulator.dm index b23050c2978..f66786d06d0 100644 --- a/code/datums/wires/big_manipulator.dm +++ b/code/datums/wires/big_manipulator.dm @@ -21,11 +21,11 @@ /datum/wires/big_manipulator/get_status() var/obj/machinery/big_manipulator/manipulator_big = holder var/list/status = list() - status += "The big light bulb is [manipulator_big.on_button_cutted ? "went out" : manipulator_big.on ? "green" : "red"]." + status += "The big light bulb [manipulator_big.power_access_wire_cut ? "has went out" : "is glowing [manipulator_big.on ? "green" : "red"]"]." status += "The small red light shows: [isnull(manipulator_big.containment_obj) ? "empty" : "full"]." status += "Text on the yellow board shows: [manipulator_big.selected_type.name]." - status += "There are [manipulator_big.manipulate_mode] text on the small blue panel." - status += "The purple light is [manipulator_big.only_highest_priority ? "on" : "off"]." + status += "There are [manipulator_big.interaction_mode] text on the small blue panel." + status += "The purple light is [manipulator_big.override_priority ? "on" : "off"]." status += "The number on small white panel shows [manipulator_big.manipulator_throw_range]." return status @@ -35,20 +35,20 @@ if(WIRE_ON) manipulator_big.try_press_on(usr) if(WIRE_DROP) - manipulator_big.drop_containment_item() + manipulator_big.drop_held_object() if(WIRE_ITEM_TYPE) - manipulator_big.change_what_take_type() + manipulator_big.cycle_pickup_type() if(WIRE_CHANGE_MODE) manipulator_big.change_mode() if(WIRE_ONE_PRIORITY_BUTTON) - manipulator_big.only_highest_priority = !manipulator_big.only_highest_priority + manipulator_big.override_priority = !manipulator_big.override_priority if(WIRE_THROW_RANGE) - manipulator_big.change_throw_range() + manipulator_big.cycle_throw_range() /datum/wires/big_manipulator/on_cut(wire, mend, source) var/obj/machinery/big_manipulator/manipulator_big = holder if(wire == WIRE_ON) if(mend) - manipulator_big.on_button_cutted = FALSE + manipulator_big.power_access_wire_cut = FALSE return - manipulator_big.on_button_cutted = TRUE + manipulator_big.power_access_wire_cut = TRUE diff --git a/code/game/machinery/big_manipulator.dm b/code/game/machinery/big_manipulator.dm index 1bca57a28bf..b20276ff461 100644 --- a/code/game/machinery/big_manipulator.dm +++ b/code/game/machinery/big_manipulator.dm @@ -1,6 +1,6 @@ -#define DROP_ITEM_MODE "drop" -#define USE_ITEM_MODE "use" -#define THROW_ITEM_MODE "throw" +#define INTERACT_DROP "drop" +#define INTERACT_USE "use" +#define INTERACT_THROW "throw" #define TAKE_ITEMS 1 #define TAKE_CLOSETS 2 @@ -9,10 +9,22 @@ #define DELAY_STEP 0.1 #define MAX_DELAY 30 -/// Manipulator Core. Main part of the mechanism that carries out the entire process. +#define MIN_DELAY_TIER_1 2 +#define MIN_DELAY_TIER_2 1.4 +#define MIN_DELAY_TIER_3 0.8 +#define MIN_DELAY_TIER_4 0.2 + +#define STATUS_BUSY TRUE +#define STATUS_IDLE FALSE + +#define WORKER_SINGLE_USE "single" +#define WORKER_EMPTY_USE "empty" +#define WORKER_NORMAL_USE "normal" + +/// The Big Manipulator's core. Main part of the mechanism that carries out the entire process. /obj/machinery/big_manipulator name = "Big Manipulator" - desc = "Take and drop objects. Innovation..." + desc = "Operates different objects. Truly, a groundbreaking innovation..." icon = 'icons/obj/machines/big_manipulator_parts/big_manipulator_core.dmi' icon_state = "core" density = TRUE @@ -20,27 +32,24 @@ greyscale_colors = "#d8ce13" greyscale_config = /datum/greyscale_config/big_manipulator /// Min time manipulator can have in delay. Changing on upgrade. - var/min_working_speed = 2 - /// Ui number that shows manipulator delay. - var/delay_value = 2 - /// How many time manipulator need to take and drop item. - var/working_speed = 2 SECONDS + var/minimal_delay = MIN_DELAY_TIER_1 + /// The time it takes for the manipulator to complete the action cycle. + var/interaction_delay = MIN_DELAY_TIER_1 + /// Using high tier manipulators speeds up big manipulator and requires more energy. var/power_use_lvl = 0.2 - /// When manipulator already working with item inside he don't take any new items. - var/on_work = FALSE - /// Activate mechanism. + /// The status of the manipulator - `IDLE` or `BUSY`. + var/status = STATUS_IDLE + /// Is the manipulator turned on? var/on = FALSE - /// Dir to get turf where we take items. + /// The direction the manipulator arm will take items from. var/take_here = NORTH - /// Dir to get turf where we drop items. + /// The direction the manipulator arm will drop items to. var/drop_here = SOUTH - /// Turf where we take items. + /// The turf where the manipulator arm will take items from. var/turf/take_turf - /// Turf where we drop items. + /// The turf where the manipulator arm will drop items to. var/turf/drop_turf - /// How will manipulator manipulate the object? drop it out by default. - var/manipulate_mode = DROP_ITEM_MODE /// Priority settings depending on the manipulator drop mode that are available to this manipulator. Filled during Initialize. var/list/priority_settings_for_drop = list() /// Priority settings depending on the manipulator use mode that are available to this manipulator. Filled during Initialize. @@ -48,33 +57,31 @@ /// What priority settings are available to use at the moment. /// We also use this list to sort priorities from ascending to descending. var/list/allowed_priority_settings = list() - /// Obj inside manipulator. + /// The object inside the manipulator. var/datum/weakref/containment_obj - /// Obj used as filter + /// The object used as a filter. var/datum/weakref/filter_obj - /// Poor monkey that needs to use mode works. + /// The poor monkey that needs to use mode works. var/datum/weakref/monkey_worker /// weakref to id that locked this manipualtor. var/datum/weakref/locked_by_this_id /// Is manipulator locked by identity id. var/id_locked = FALSE - /// Other manipulator component. - var/obj/effect/big_manipulator_hand/manipulator_hand - /// Here some ui setting we can on/off: - /// If activated: after item was used manipulator will also drop it. - var/drop_item_after_use = TRUE - /// Allowe monkey to do use mode with empty hand. - var/use_with_empty_hand = FALSE - /// If activated: will select only 1 priority and will not continue to look at the priorities below. - var/only_highest_priority = FALSE - /// Var for throw item mode: changes the range from which the manipulator throws an object. + /// The manipulator's arm. + var/obj/effect/big_manipulator_arm/manipulator_arm + + /// How should the manipulator interact with the object? + var/interaction_mode = INTERACT_DROP + /// How should the worker interact with the object? + var/worker_interaction = WORKER_NORMAL_USE + /// The distance the thrown object should travel when thrown. var/manipulator_throw_range = 1 - /// Selected type that manipulator will take for take and drop loop. + /// Overrides the priority selection, only accessing the top priority list element. + var/override_priority = FALSE + /// The `type` the manipulator will interact with only. var/atom/selected_type - /// Just a lazy number to change selected_type type in array. - var/selected_type_by_number = 1 - /// Variable for the wire that disables the power button if the wire is cut. - var/on_button_cutted = FALSE + /// Is the power access wire cut? Disables the power button if `TRUE`. + var/power_access_wire_cut = FALSE /// List where we can set selected type. Taking items by Initialize. var/list/allowed_types_to_pick_up = list( /obj/item, @@ -84,11 +91,11 @@ /obj/machinery/big_manipulator/Initialize(mapload) . = ..() take_and_drop_turfs_check() - create_manipulator_hand() - RegisterSignal(manipulator_hand, COMSIG_QDELETING, PROC_REF(on_hand_qdel)) + create_manipulator_arm() + RegisterSignal(manipulator_arm, COMSIG_QDELETING, PROC_REF(on_hand_qdel)) manipulator_lvl() set_up_priority_settings() - selected_type = allowed_types_to_pick_up[selected_type_by_number] + selected_type = allowed_types_to_pick_up[1] if(on) press_on(pressed_by = null) set_wires(new /datum/wires/big_manipulator(src)) @@ -133,7 +140,7 @@ /obj/machinery/big_manipulator/Destroy(force) . = ..() - qdel(manipulator_hand) + qdel(manipulator_arm) if(!isnull(containment_obj)) var/obj/containment_resolve = containment_obj?.resolve() containment_resolve?.forceMove(get_turf(containment_resolve)) @@ -151,10 +158,10 @@ var/mob/living/carbon/human/species/monkey/poor_monkey = monkey_worker.resolve() if(gone != poor_monkey) return - if(!is_type_in_list(poor_monkey, manipulator_hand.vis_contents)) + if(!is_type_in_list(poor_monkey, manipulator_arm.vis_contents)) return - manipulator_hand.vis_contents -= poor_monkey - if(manipulate_mode == USE_ITEM_MODE) + manipulator_arm.vis_contents -= poor_monkey + if(interaction_mode == INTERACT_USE) change_mode() poor_monkey.remove_offsets(type) monkey_worker = null @@ -163,10 +170,10 @@ . = ..() take_and_drop_turfs_check() if(isnull(get_turf(src))) - qdel(manipulator_hand) + qdel(manipulator_arm) return - if(!manipulator_hand) - create_manipulator_hand() + if(!manipulator_arm) + create_manipulator_arm() /obj/machinery/big_manipulator/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() @@ -184,7 +191,7 @@ /obj/machinery/big_manipulator/wrench_act_secondary(mob/living/user, obj/item/tool) . = ..() - if(on_work || on) + if(status == STATUS_BUSY || on) to_chat(user, span_warning("[src] is activated!")) return ITEM_INTERACT_BLOCKING rotate_big_hand() @@ -192,7 +199,7 @@ return ITEM_INTERACT_SUCCESS /obj/machinery/big_manipulator/can_be_unfasten_wrench(mob/user, silent) - if(on_work || on) + if(status == STATUS_BUSY || on) to_chat(user, span_warning("[src] is activated!")) return FAILED_UNFASTEN return ..() @@ -229,7 +236,7 @@ /obj/machinery/big_manipulator/mouse_drop_dragged(atom/drop_point, mob/user, src_location, over_location, params) if(isnull(monkey_worker)) return - if(on_work) + if(status == STATUS_BUSY) balloon_alert(user, "turn it off first!") return var/mob/living/carbon/human/species/monkey/poor_monkey = monkey_worker.resolve() @@ -248,7 +255,7 @@ return if(!isnull(monkey_worker)) return - if(on_work) + if(status == STATUS_BUSY) balloon_alert(user, "turn it off first!") return var/mob/living/carbon/human/species/monkey/poor_monkey = monkey @@ -263,12 +270,12 @@ monkey_worker = WEAKREF(poor_monkey) poor_monkey.drop_all_held_items() poor_monkey.forceMove(src) - manipulator_hand.vis_contents += poor_monkey - poor_monkey.dir = manipulator_hand.dir + manipulator_arm.vis_contents += poor_monkey + poor_monkey.dir = manipulator_arm.dir poor_monkey.add_offsets( type, - x_add = 32 + manipulator_hand.calculate_item_offset(TRUE, pixels_to_offset = 16), - y_add = 32 + manipulator_hand.calculate_item_offset(FALSE, pixels_to_offset = 16) + x_add = 32 + manipulator_arm.calculate_item_offset(TRUE, pixels_to_offset = 16), + y_add = 32 + manipulator_arm.calculate_item_offset(FALSE, pixels_to_offset = 16) ) /obj/machinery/big_manipulator/attackby(obj/item/is_card, mob/user, params) @@ -292,10 +299,10 @@ balloon_alert(user, "successfully [!id_locked ? "un" : ""]locked") /// Creat manipulator hand effect on manipulator core. -/obj/machinery/big_manipulator/proc/create_manipulator_hand() - manipulator_hand = new/obj/effect/big_manipulator_hand(src) - manipulator_hand.dir = take_here - vis_contents += manipulator_hand +/obj/machinery/big_manipulator/proc/create_manipulator_arm() + manipulator_arm = new/obj/effect/big_manipulator_arm(src) + manipulator_arm.dir = take_here + vis_contents += manipulator_arm /// Check servo tier and change manipulator speed, power_use and colour. /obj/machinery/big_manipulator/proc/manipulator_lvl() @@ -304,29 +311,25 @@ return switch(locate_servo.tier) if(-INFINITY to 1) - min_working_speed = delay_value = 2 - working_speed = 2 SECONDS + minimal_delay = interaction_delay = MIN_DELAY_TIER_1 power_use_lvl = 0.2 set_greyscale(COLOR_YELLOW) - manipulator_hand?.set_greyscale(COLOR_YELLOW) + manipulator_arm?.set_greyscale(COLOR_YELLOW) if(2) - min_working_speed = delay_value = 1.4 - working_speed = 1.4 SECONDS + minimal_delay = interaction_delay = MIN_DELAY_TIER_2 power_use_lvl = 0.4 set_greyscale(COLOR_ORANGE) - manipulator_hand?.set_greyscale(COLOR_ORANGE) + manipulator_arm?.set_greyscale(COLOR_ORANGE) if(3) - min_working_speed = delay_value = 0.8 - working_speed = 0.8 SECONDS + minimal_delay = interaction_delay = MIN_DELAY_TIER_3 power_use_lvl = 0.6 set_greyscale(COLOR_RED) - manipulator_hand?.set_greyscale(COLOR_RED) + manipulator_arm?.set_greyscale(COLOR_RED) if(4 to INFINITY) - min_working_speed = delay_value = 0.2 - working_speed = 0.2 SECONDS + minimal_delay = interaction_delay = MIN_DELAY_TIER_4 power_use_lvl = 0.8 set_greyscale(COLOR_PURPLE) - manipulator_hand?.set_greyscale(COLOR_PURPLE) + manipulator_arm?.set_greyscale(COLOR_PURPLE) active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * power_use_lvl @@ -354,10 +357,10 @@ if(WEST) take_here = NORTH drop_here = SOUTH - manipulator_hand.dir = take_here + manipulator_arm.dir = take_here var/mob/monkey = monkey_worker?.resolve() if(!isnull(monkey)) - monkey.dir = manipulator_hand.dir + monkey.dir = manipulator_arm.dir take_and_drop_turfs_check() /// Deliting hand will destroy our manipulator core. @@ -367,9 +370,9 @@ deconstruct(TRUE) /// Pre take and drop proc from [take and drop procs loop]: -/// Check if we can start take and drop loop -/obj/machinery/big_manipulator/proc/is_work_check() - if(use_with_empty_hand) +/// Can we begin the `take-and-drop` loop? +/obj/machinery/big_manipulator/proc/is_ready_to_work() + if(worker_interaction == WORKER_EMPTY_USE) try_take_thing() return TRUE if(isclosedturf(drop_turf)) @@ -381,7 +384,6 @@ continue try_take_thing(take_turf, take_item) break - return TRUE /// First take and drop proc from [take and drop procs loop]: @@ -389,13 +391,13 @@ /obj/machinery/big_manipulator/proc/try_take_thing(datum/source, atom/movable/target) SIGNAL_HANDLER - var/empty_hand_check = use_with_empty_hand && manipulate_mode == USE_ITEM_MODE + var/empty_hand_check = worker_interaction == WORKER_EMPTY_USE && interaction_mode == INTERACT_USE if(!on) return if(!anchored) return - if(on_work) + if(status == STATUS_BUSY) return if(!empty_hand_check) if(QDELETED(source) || QDELETED(target)) @@ -416,24 +418,24 @@ if(!hand_is_empty) target.forceMove(src) containment_obj = WEAKREF(target) - manipulator_hand.update_claw(containment_obj) - on_work = TRUE + manipulator_arm.update_claw(containment_obj) + status = STATUS_BUSY do_rotate_animation(1) check_next_move(target, hand_is_empty) /// 2.5 take and drop proc from [take and drop procs loop]: -/// Choose what we will do with our item by checking the manipulate_mode. +/// Choose what we will do with our item by checking the interaction_mode. /obj/machinery/big_manipulator/proc/check_next_move(atom/movable/target, hand_is_empty = FALSE) if(hand_is_empty) - addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand)), working_speed) + addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand)), interaction_delay SECONDS) return - switch(manipulate_mode) - if(DROP_ITEM_MODE) - addtimer(CALLBACK(src, PROC_REF(drop_thing), target), working_speed) - if(USE_ITEM_MODE) - addtimer(CALLBACK(src, PROC_REF(use_thing), target), working_speed) - if(THROW_ITEM_MODE) - addtimer(CALLBACK(src, PROC_REF(throw_thing), target), working_speed) + switch(interaction_mode) + if(INTERACT_DROP) + addtimer(CALLBACK(src, PROC_REF(drop_thing), target), interaction_delay SECONDS) + if(INTERACT_USE) + addtimer(CALLBACK(src, PROC_REF(use_thing), target), interaction_delay SECONDS) + if(INTERACT_THROW) + addtimer(CALLBACK(src, PROC_REF(throw_thing), target), interaction_delay SECONDS) /// 3.1 take and drop proc from [take and drop procs loop]: /// Drop our item. @@ -441,7 +443,7 @@ /obj/machinery/big_manipulator/proc/drop_thing(atom/movable/target) var/where_we_drop = search_type_by_priority_in_drop_turf(allowed_priority_settings) if(isnull(where_we_drop)) - addtimer(CALLBACK(src, PROC_REF(drop_thing), target), working_speed) + addtimer(CALLBACK(src, PROC_REF(drop_thing), target), interaction_delay SECONDS) return if((where_we_drop == drop_turf) || !isitem(target)) target.forceMove(drop_turf) @@ -482,14 +484,14 @@ var/obj/item/im_item = target var/atom/type_to_use = search_type_by_priority_in_drop_turf(allowed_priority_settings) if(isnull(type_to_use)) - check_end_of_use(im_item, target, item_was_used = FALSE) + check_end_of_use(im_item, item_was_used = FALSE) return monkey_resolve.put_in_active_hand(im_item) if(im_item.GetComponent(/datum/component/two_handed)) /// Using two-handed items in two hands. im_item.attack_self(monkey_resolve) im_item.melee_attack_chain(monkey_resolve, type_to_use) do_attack_animation(drop_turf) - manipulator_hand.do_attack_animation(drop_turf) + manipulator_arm.do_attack_animation(drop_turf) check_end_of_use(im_item, item_was_used = TRUE) /obj/machinery/big_manipulator/proc/use_thing_with_empty_hand() @@ -497,7 +499,7 @@ if(isnull(monkey_resolve)) finish_manipulation() return - var/atom/type_to_use = search_type_by_priority_in_drop_turf(allowed_priority_settings, use_with_empty_hand && manipulate_mode == USE_ITEM_MODE) + var/atom/type_to_use = search_type_by_priority_in_drop_turf(allowed_priority_settings) if(isnull(type_to_use)) check_end_of_use_for_use_with_empty_hand() return @@ -511,14 +513,14 @@ else monkey_resolve.UnarmedAttack(type_to_use) do_attack_animation(drop_turf) - manipulator_hand.do_attack_animation(drop_turf) + manipulator_arm.do_attack_animation(drop_turf) check_end_of_use_for_use_with_empty_hand() /obj/machinery/big_manipulator/proc/check_end_of_use_for_use_with_empty_hand(obj/item/my_item, item_was_used) - if(!on || (!use_with_empty_hand && manipulate_mode == USE_ITEM_MODE)) + if(!on || (worker_interaction != WORKER_EMPTY_USE && interaction_mode == INTERACT_USE)) finish_manipulation() return - addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand), my_item), working_speed) + addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand), my_item), interaction_delay SECONDS) /// Check what we gonna do next with our item. Drop it or use again. /obj/machinery/big_manipulator/proc/check_end_of_use(obj/item/my_item, item_was_used) @@ -527,12 +529,12 @@ my_item.dir = get_dir(get_turf(my_item), get_turf(src)) finish_manipulation() return - if(drop_item_after_use && item_was_used) + if(worker_interaction == WORKER_SINGLE_USE && item_was_used) my_item.forceMove(drop_turf) my_item.dir = get_dir(get_turf(my_item), get_turf(src)) finish_manipulation() return - addtimer(CALLBACK(src, PROC_REF(use_thing), my_item), working_speed) + addtimer(CALLBACK(src, PROC_REF(use_thing), my_item), interaction_delay SECONDS) /// 3.3 take and drop proc from [take and drop procs loop]: /// Throw item away!!! @@ -546,31 +548,31 @@ im_item.forceMove(drop_turf) im_item.throw_at(get_edge_target_turf(get_turf(src), drop_here), manipulator_throw_range - 1, 2) src.do_attack_animation(drop_turf) - manipulator_hand.do_attack_animation(drop_turf) + manipulator_arm.do_attack_animation(drop_turf) finish_manipulation() /// End of thirds take and drop proc from [take and drop procs loop]: /// Starts manipulator hand backward animation. /obj/machinery/big_manipulator/proc/finish_manipulation() containment_obj = null - manipulator_hand.update_claw(null) + manipulator_arm.update_claw(null) do_rotate_animation(0) - addtimer(CALLBACK(src, PROC_REF(end_work)), working_speed) + addtimer(CALLBACK(src, PROC_REF(end_work)), interaction_delay SECONDS) /// Fourth and last take and drop proc from [take and drop procs loop]: /// Finishes work and begins to look for a new item for [take and drop procs loop]. /obj/machinery/big_manipulator/proc/end_work() - on_work = FALSE - is_work_check() + status = STATUS_IDLE + is_ready_to_work() /// Rotates manipulator hand 90 degrees. /obj/machinery/big_manipulator/proc/do_rotate_animation(backward) - animate(manipulator_hand, transform = matrix(90, MATRIX_ROTATE), working_speed*0.5) - addtimer(CALLBACK(src, PROC_REF(finish_rotate_animation), backward), working_speed*0.5) + animate(manipulator_arm, transform = matrix(90, MATRIX_ROTATE), interaction_delay SECONDS * 0.5) + addtimer(CALLBACK(src, PROC_REF(finish_rotate_animation), backward), interaction_delay SECONDS * 0.5) /// Rotates manipulator hand from 90 degrees to 180 or 0 if backward. /obj/machinery/big_manipulator/proc/finish_rotate_animation(backward) - animate(manipulator_hand, transform = matrix(180 * backward, MATRIX_ROTATE), working_speed*0.5) + animate(manipulator_arm, transform = matrix(180 * backward, MATRIX_ROTATE), interaction_delay SECONDS * 0.5) /obj/machinery/big_manipulator/proc/check_filter(atom/movable/target) if (target.anchored || HAS_TRAIT(target, TRAIT_NODROP)) @@ -590,26 +592,22 @@ /// Proc called when we changing item interaction mode. /obj/machinery/big_manipulator/proc/change_mode() - switch(manipulate_mode) - if(DROP_ITEM_MODE) - if(!isnull(monkey_worker)) - manipulate_mode = USE_ITEM_MODE - else - manipulate_mode = THROW_ITEM_MODE - if(USE_ITEM_MODE) - manipulate_mode = THROW_ITEM_MODE - if(THROW_ITEM_MODE) - manipulate_mode = DROP_ITEM_MODE + var/list/available_modes = list(INTERACT_DROP, INTERACT_USE, INTERACT_THROW) + + if(isnull(monkey_worker)) + available_modes = list(INTERACT_DROP, INTERACT_THROW) + + interaction_mode = cycle_value(interaction_mode, available_modes) update_priority_list() - is_work_check() + is_ready_to_work() /// Update priority list in ui. Creating new list and sort it by priority number. /obj/machinery/big_manipulator/proc/update_priority_list() allowed_priority_settings = list() var/list/priority_mode_list - if(manipulate_mode == DROP_ITEM_MODE) + if(interaction_mode == INTERACT_DROP) priority_mode_list = priority_settings_for_drop.Copy() - if(manipulate_mode == USE_ITEM_MODE) + if(interaction_mode == INTERACT_USE) priority_mode_list = priority_settings_for_use.Copy() if(isnull(priority_mode_list)) return @@ -619,12 +617,12 @@ continue allowed_priority_settings += what_priority -/// Proc thet return item by type in priority list. Selects item and increasing priority number if don't found req type. -/obj/machinery/big_manipulator/proc/search_type_by_priority_in_drop_turf(list/priority_list, empty_hand = FALSE) +/// Proc that return item by type in priority list. Selects item and increasing priority number if don't found req type. +/obj/machinery/big_manipulator/proc/search_type_by_priority_in_drop_turf(list/priority_list) var/lazy_counter = 1 for(var/datum/manipulator_priority/take_type in priority_list) - /// If we set only_highest_priority on TRUE we don't go to priority below. - if(lazy_counter > 1 && only_highest_priority) + /// If we set override_priority on TRUE we don't go to priority below. + if(lazy_counter > 1 && override_priority) return null /// If we need turf we don't check turf.contents and just return drop_turf. if(take_type.what_type == /turf) @@ -639,7 +637,7 @@ /obj/machinery/big_manipulator/proc/press_on(pressed_by) if(pressed_by) on = !on - if(!is_work_check()) + if(!is_ready_to_work()) return if(on) RegisterSignal(take_turf, COMSIG_ATOM_ENTERED, PROC_REF(try_take_thing)) @@ -650,37 +648,22 @@ /// Proc that check if button not cutted when we press on button. /obj/machinery/big_manipulator/proc/try_press_on(mob/user) - if(on_button_cutted) + if(power_access_wire_cut) balloon_alert(user, "button is cut off!") return press_on(pressed_by = TRUE) /// Drop item that manipulator is manipulating. -/obj/machinery/big_manipulator/proc/drop_containment_item() +/obj/machinery/big_manipulator/proc/drop_held_object() if(isnull(containment_obj)) return var/obj/obj_resolve = containment_obj?.resolve() obj_resolve?.forceMove(get_turf(obj_resolve)) finish_manipulation() -/// Changes the type of objects that the manipulator will pick up -/obj/machinery/big_manipulator/proc/change_what_take_type() - selected_type_by_number++ - if(selected_type_by_number > allowed_types_to_pick_up.len) - selected_type_by_number = 1 - selected_type = allowed_types_to_pick_up[selected_type_by_number] - is_work_check() - -/// Changes range with which the manipulator throws objects, from 1 to 7. -/obj/machinery/big_manipulator/proc/change_throw_range() - manipulator_throw_range++ - if(manipulator_throw_range > 7) - manipulator_throw_range = 1 - /// Changes manipulator working speed time. /obj/machinery/big_manipulator/proc/change_delay(new_delay) - delay_value = round(clamp(new_delay, min_working_speed, MAX_DELAY), DELAY_STEP) - working_speed = delay_value SECONDS + interaction_delay = round(clamp(new_delay, minimal_delay, MAX_DELAY), DELAY_STEP) /obj/machinery/big_manipulator/ui_interact(mob/user, datum/tgui/ui) if(id_locked) @@ -701,10 +684,9 @@ data["active"] = on data["item_as_filter"] = filter_obj?.resolve() data["selected_type"] = selected_type.name - data["manipulate_mode"] = manipulate_mode - data["drop_after_use"] = drop_item_after_use - data["empty_hand_use"] = use_with_empty_hand - data["highest_priority"] = only_highest_priority + data["interaction_mode"] = interaction_mode + data["worker_interaction"] = worker_interaction + data["highest_priority"] = override_priority data["throw_range"] = manipulator_throw_range var/list/priority_list = list() data["settings_list"] = list() @@ -714,8 +696,8 @@ priority_data["priority_width"] = allowed_setting.number priority_list += list(priority_data) data["settings_list"] = priority_list - data["min_delay"] = min_working_speed - data["delay_value"] = delay_value + data["min_delay"] = minimal_delay + data["interaction_delay"] = interaction_delay return data /obj/machinery/big_manipulator/ui_static_data(mob/user) @@ -733,10 +715,10 @@ try_press_on(ui.user) return TRUE if("drop") - drop_containment_item() + drop_held_object() return TRUE if("change_take_item_type") - change_what_take_type() + cycle_pickup_type() return TRUE if("change_mode") change_mode() @@ -749,7 +731,7 @@ if(give_obj_back) give_obj_back.forceMove(get_turf(src)) filter_obj = null - is_work_check() + is_ready_to_work() to_chat(living_user, span_warning("Filter removed")) return TRUE var/obj/item/get_active_held_item = living_user.get_active_held_item() @@ -758,17 +740,13 @@ return FALSE filter_obj = WEAKREF(get_active_held_item) get_active_held_item.forceMove(src) - is_work_check() + is_ready_to_work() return TRUE if("highest_priority_change") - only_highest_priority = !only_highest_priority + override_priority = !override_priority return TRUE - if("drop_use_change") - drop_item_after_use = !drop_item_after_use - return TRUE - if("empty_use_change") - use_with_empty_hand = !use_with_empty_hand - is_work_check() + if("worker_interaction_change") + cycle_worker_interaction() return TRUE if("change_priority") var/new_priority_number = params["priority"] @@ -780,8 +758,8 @@ break update_priority_list() return TRUE - if("change_throw_range") - change_throw_range() + if("cycle_throw_range") + cycle_throw_range() return TRUE if("changeDelay") change_delay(text2num(params["new_delay"])) @@ -796,15 +774,15 @@ break /// Manipulator hand. Effect we animate to show that the manipulator is working and moving something. -/obj/effect/big_manipulator_hand - name = "Manipulator claw" - desc = "Take and drop objects. Innovation..." +/obj/effect/big_manipulator_arm + name = "mechanical claw" + desc = "Takes and drops objects." icon = 'icons/obj/machines/big_manipulator_parts/big_manipulator_hand.dmi' icon_state = "hand" layer = LOW_ITEM_LAYER appearance_flags = KEEP_TOGETHER | LONG_GLIDE | TILE_BOUND | PIXEL_SCALE anchored = TRUE - greyscale_config = /datum/greyscale_config/manipulator_hand + greyscale_config = /datum/greyscale_config/manipulator_arm pixel_x = -32 pixel_y = -32 /// We get item from big manipulator and takes its icon to create overlay. @@ -812,11 +790,11 @@ /// Var to icon that used as overlay on manipulator claw to show what item it grabs. var/mutable_appearance/icon_overlay -/obj/effect/big_manipulator_hand/update_overlays() +/obj/effect/big_manipulator_arm/update_overlays() . = ..() . += update_item_overlay() -/obj/effect/big_manipulator_hand/proc/update_item_overlay() +/obj/effect/big_manipulator_arm/proc/update_item_overlay() if(isnull(item_in_my_claw)) return icon_overlay = null var/atom/movable/item_data = item_in_my_claw.resolve() @@ -828,12 +806,12 @@ return icon_overlay /// Updates item that is in the claw. -/obj/effect/big_manipulator_hand/proc/update_claw(clawed_item) +/obj/effect/big_manipulator_arm/proc/update_claw(clawed_item) item_in_my_claw = clawed_item update_appearance() /// Calculate x and y coordinates so that the item icon appears in the claw and not somewhere in the corner. -/obj/effect/big_manipulator_hand/proc/calculate_item_offset(is_x = TRUE, pixels_to_offset = 32) +/obj/effect/big_manipulator_arm/proc/calculate_item_offset(is_x = TRUE, pixels_to_offset = 32) var/offset switch(dir) if(NORTH) @@ -854,45 +832,66 @@ var/what_type /** * Place in the priority queue. The lower the number, the more important the priority. - * Doesn’t really matter what number you enter, user can set priority for themselves, + * Doesn't really matter what number you enter, user can set priority for themselves, * BUT!!! * Don't write the same numbers in the same parent otherwise something may go wrong. */ var/number /datum/manipulator_priority/for_drop/on_floor - name = "Drop on Floor" + name = "DROP ON FLOOR" what_type = /turf number = 1 /datum/manipulator_priority/for_drop/in_storage - name = "Drop in Storage" + name = "DROP IN STORAGE" what_type = /obj/item/storage number = 2 /datum/manipulator_priority/for_use/on_living - name = "Use on Living" + name = "USE ON LIVING" what_type = /mob/living number = 1 /datum/manipulator_priority/for_use/on_structure - name = "Use on Structure" + name = "USE ON STRUCTURE" what_type = /obj/structure number = 2 /datum/manipulator_priority/for_use/on_machinery - name = "Use on Machinery" + name = "USE ON MACHINERY" what_type = /obj/machinery number = 3 /datum/manipulator_priority/for_use/on_items - name = "Use on Items" + name = "USE ON ITEM" what_type = /obj/item number = 4 -#undef DROP_ITEM_MODE -#undef USE_ITEM_MODE -#undef THROW_ITEM_MODE +/// Cycles the given value in the given list. Retuns the next value in the list, or the first one if the list isn't long enough. +/obj/machinery/big_manipulator/proc/cycle_value(current_value, list/possible_values) + var/current_index = possible_values.Find(current_value) + if(current_index == null) + return possible_values[1] + + var/next_index = (current_index % possible_values.len) + 1 + return possible_values[next_index] + +/obj/machinery/big_manipulator/proc/cycle_worker_interaction() + var/list/worker_modes = list(WORKER_NORMAL_USE, WORKER_SINGLE_USE, WORKER_EMPTY_USE) + worker_interaction = cycle_value(worker_interaction, worker_modes) + +/obj/machinery/big_manipulator/proc/cycle_throw_range() + var/list/possible_ranges = list(1, 2, 3, 4, 5, 6, 7) + manipulator_throw_range = cycle_value(manipulator_throw_range, possible_ranges) + +/obj/machinery/big_manipulator/proc/cycle_pickup_type() + selected_type = cycle_value(selected_type, allowed_types_to_pick_up) + is_ready_to_work() + +#undef INTERACT_DROP +#undef INTERACT_USE +#undef INTERACT_THROW #undef TAKE_ITEMS #undef TAKE_CLOSETS @@ -900,3 +899,15 @@ #undef DELAY_STEP #undef MAX_DELAY + +#undef WORKER_NORMAL_USE +#undef WORKER_SINGLE_USE +#undef WORKER_EMPTY_USE + +#undef STATUS_IDLE +#undef STATUS_BUSY + +#undef MIN_DELAY_TIER_1 +#undef MIN_DELAY_TIER_2 +#undef MIN_DELAY_TIER_3 +#undef MIN_DELAY_TIER_4 diff --git a/tgui/packages/tgui/interfaces/BigManipulator.tsx b/tgui/packages/tgui/interfaces/BigManipulator.tsx index 28117f824c1..e0170a86709 100644 --- a/tgui/packages/tgui/interfaces/BigManipulator.tsx +++ b/tgui/packages/tgui/interfaces/BigManipulator.tsx @@ -13,16 +13,15 @@ import { Window } from '../layouts'; type ManipulatorData = { active: BooleanLike; - drop_after_use: BooleanLike; - empty_hand_use: BooleanLike; + interaction_delay: number; + worker_interaction: string; highest_priority: BooleanLike; - manipulate_mode: string; + interaction_mode: string; settings_list: PrioritySettings[]; throw_range: number; item_as_filter: string; selected_type: string; delay_step: number; - delay_value: number; min_delay: number; max_delay: number; }; @@ -34,7 +33,7 @@ type PrioritySettings = { const MasterControls = () => { const { act, data } = useBackend(); - const { delay_step, delay_value, min_delay, max_delay } = data; + const { delay_step, interaction_delay, min_delay, max_delay } = data; return ( Delay: @@ -54,7 +53,7 @@ const MasterControls = () => { style={{ marginTop: '-5px' }} step={delay_step} my={1} - value={delay_value} + value={interaction_delay} minValue={min_delay} maxValue={max_delay} unit="sec." @@ -133,10 +132,9 @@ export const BigManipulator = () => { const { data, act } = useBackend(); const { active, - manipulate_mode, + interaction_mode, settings_list, - drop_after_use, - empty_hand_use, + worker_interaction, highest_priority, throw_range, item_as_filter, @@ -171,12 +169,12 @@ export const BigManipulator = () => { act('change_mode')} tooltip="Cycle through interaction modes" /> - {manipulate_mode === 'throw' && ( + {interaction_mode === 'throw' && ( 1 ? 'S' : ''}`} @@ -191,17 +189,18 @@ export const BigManipulator = () => { onClick={() => act('change_take_item_type')} tooltip="Cycle through types of items to filter" /> - {manipulate_mode === 'use' && ( + {interaction_mode === 'use' && ( act('empty_use_change')} + content={worker_interaction.toUpperCase()} + onClick={() => act('worker_interaction_change')} tooltip={ - empty_hand_use - ? 'Interact with an empty hand' - : 'Drop the item after a single interaction cycle' + worker_interaction === 'normal' + ? 'Interact using the held item' + : worker_interaction === 'single' + ? 'Drop the item after a single cycle' + : 'Interact with an empty hand' } - selected={!!empty_hand_use} /> )} { tooltip="Click while holding an item to set filtering type" /> - {manipulate_mode !== 'throw' && ( + {interaction_mode !== 'throw' && ( act('highest_priority_change')} tooltip="Only interact with the highest dropoff point in the list" @@ -223,7 +222,7 @@ export const BigManipulator = () => {
- {manipulate_mode !== 'throw' && ( + {interaction_mode !== 'throw' && (
{settings_list.map((setting) => (