From 4bbefe0679b631e2fa44424e4ef1e3266cdedcbd Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 22 Aug 2024 06:29:44 +0200 Subject: [PATCH] [MIRROR] Add big manipulator. (#29500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add big manipulator. (#84888) ## About The Pull Request Sprites Update by ArcaneMusic: ![Снимок экрана 2024-07-24 081415](https://github.com/user-attachments/assets/db557ba1-c87e-4751-9cbe-55f543f7bdd3) Video: https://youtu.be/JoFvwwFzVvA Text: Big manipulator is a new machine crafting from circuit board which can be created on engi/rnd/cargo/service techfabs. Big manipulator performs a simple function of take and drop item. You can unsecre it with wrench left click and rotate manipulator hand with rigth wrench click. Big manipulator speed depends on the tier of servo part inside it: 2/1.4/0.8/0.2 Seconds from 1/2/3/4 servo tier. ## Why It's Good For The Game Provides more logistics mechanics for conveyor belt designs and other cargo transportation. ## Changelog :cl: by Xackii, sprites by ArcaneMusic add: Added big manipulators. /:cl: --------- Co-authored-by: Time-Green <7501474+Time-Green@ users.noreply.github.com> * Add big manipulator. --------- Co-authored-by: Xackii <120736708+Xackii@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@ users.noreply.github.com> --- .../greyscale_configs/greyscale_effects.dm | 5 + .../greyscale_configs/greyscale_objects.dm | 5 + .../json_configs/big_manipulator.json | 15 + .../json_configs/manipulator_hand.json | 15 + code/game/machinery/big_manipulator.dm | 282 ++++++++++++++++++ .../machines/machine_circuitboards.dm | 8 + .../research/designs/machine_designs.dm | 10 + .../research/techweb/nodes/engi_nodes.dm | 1 + icons/obj/machines/big_manipulator.dmi | Bin 0 -> 504 bytes .../big_manipulator_core.dmi | Bin 0 -> 589 bytes .../big_manipulator_hand.dmi | Bin 0 -> 1219 bytes tgstation.dme | 1 + .../tgui/interfaces/BigManipulator.tsx | 30 ++ 13 files changed, 372 insertions(+) create mode 100644 code/datums/greyscale/json_configs/big_manipulator.json create mode 100644 code/datums/greyscale/json_configs/manipulator_hand.json create mode 100644 code/game/machinery/big_manipulator.dm create mode 100644 icons/obj/machines/big_manipulator.dmi create mode 100644 icons/obj/machines/big_manipulator_parts/big_manipulator_core.dmi create mode 100644 icons/obj/machines/big_manipulator_parts/big_manipulator_hand.dmi create mode 100644 tgui/packages/tgui/interfaces/BigManipulator.tsx 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 34db9013a89..91cfb618c21 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_effects.dm @@ -2,3 +2,8 @@ name = "Transmutation Rune" icon_file = 'icons/effects/96x96.dmi' json_config = 'code/datums/greyscale/json_configs/heretic_rune.json' + +/datum/greyscale_config/manipulator_hand + name = "Manipulator Hand" + 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/greyscale/config_types/greyscale_configs/greyscale_objects.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_objects.dm index 7202c41ecc5..9556612be18 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_objects.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_objects.dm @@ -3,6 +3,11 @@ icon_file = 'icons/obj/doors/airlocks/material/material.dmi' json_config = 'code/datums/greyscale/json_configs/material_airlock.json' +/datum/greyscale_config/big_manipulator + name = "Big Manipulator" + icon_file = 'icons/obj/machines/big_manipulator_parts/big_manipulator_core.dmi' + json_config = 'code/datums/greyscale/json_configs/big_manipulator.json' + // // BENCHES // diff --git a/code/datums/greyscale/json_configs/big_manipulator.json b/code/datums/greyscale/json_configs/big_manipulator.json new file mode 100644 index 00000000000..c7f96bac2ab --- /dev/null +++ b/code/datums/greyscale/json_configs/big_manipulator.json @@ -0,0 +1,15 @@ +{ + "core": [ + { + "type": "icon_state", + "icon_state": "core", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "core_colour", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/greyscale/json_configs/manipulator_hand.json b/code/datums/greyscale/json_configs/manipulator_hand.json new file mode 100644 index 00000000000..be7c96df62b --- /dev/null +++ b/code/datums/greyscale/json_configs/manipulator_hand.json @@ -0,0 +1,15 @@ +{ + "hand": [ + { + "type": "icon_state", + "icon_state": "hand", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "hand_colour", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/game/machinery/big_manipulator.dm b/code/game/machinery/big_manipulator.dm new file mode 100644 index 00000000000..d81c9d222a6 --- /dev/null +++ b/code/game/machinery/big_manipulator.dm @@ -0,0 +1,282 @@ +/// Manipulator 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..." + icon = 'icons/obj/machines/big_manipulator_parts/big_manipulator_core.dmi' + icon_state = "core" + density = TRUE + circuit = /obj/item/circuitboard/machine/big_manipulator + greyscale_colors = "#d8ce13" + greyscale_config = /datum/greyscale_config/big_manipulator + /// How many time manipulator need to take and drop item. + var/working_speed = 2 SECONDS + /// 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. + var/on = FALSE + /// Dir to get turf where we take items. + var/take_here = NORTH + /// Dir to get turf where we drop items. + var/drop_here = SOUTH + /// Turf where we take items. + var/turf/take_turf + /// Turf where we drop items. + var/turf/drop_turf + /// Obj inside manipulator. + var/datum/weakref/containment_obj + /// Other manipulator component. + var/obj/effect/manipulator_hand + +/obj/machinery/big_manipulator/Initialize(mapload) + . = ..() + take_and_drop_turfs_check() + create_manipulator_hand() + RegisterSignal(manipulator_hand, COMSIG_QDELETING, PROC_REF(on_hand_qdel)) + manipulator_lvl() + if(on) + press_on(pressed_by = null) + +/obj/machinery/big_manipulator/examine(mob/user) + . = ..() + . += "You can change direction with alternative wrench usage." + +/obj/machinery/big_manipulator/Destroy(force) + . = ..() + qdel(manipulator_hand) + if(isnull(containment_obj)) + return + var/obj/obj_resolve = containment_obj?.resolve() + obj_resolve?.forceMove(get_turf(obj_resolve)) + +/obj/machinery/big_manipulator/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + take_and_drop_turfs_check() + if(isnull(get_turf(src))) + qdel(manipulator_hand) + return + if(!manipulator_hand) + create_manipulator_hand() + manipulator_hand.forceMove(get_turf(src)) + +/obj/machinery/big_manipulator/wrench_act(mob/living/user, obj/item/tool) + . = ..() + default_unfasten_wrench(user, tool, time = 1 SECONDS) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/big_manipulator/wrench_act_secondary(mob/living/user, obj/item/tool) + . = ..() + if(on_work || on) + to_chat(user, span_warning("[src] is activated!")) + return ITEM_INTERACT_BLOCKING + rotate_big_hand() + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/big_manipulator/can_be_unfasten_wrench(mob/user, silent) + if(on_work || on) + to_chat(user, span_warning("[src] is activated!")) + return FAILED_UNFASTEN + return ..() + +/obj/machinery/big_manipulator/default_unfasten_wrench(mob/user, obj/item/wrench, time) + . = ..() + if(. == SUCCESSFUL_UNFASTEN) + take_and_drop_turfs_check() + +/obj/machinery/big_manipulator/screwdriver_act(mob/living/user, obj/item/tool) + if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool)) + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + +/obj/machinery/big_manipulator/crowbar_act(mob/living/user, obj/item/tool) + . = ..() + if(default_deconstruction_crowbar(tool)) + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + +/obj/machinery/big_manipulator/RefreshParts() + . = ..() + + manipulator_lvl() + +/// Creat manipulator hand effect on manipulator core. +/obj/machinery/big_manipulator/proc/create_manipulator_hand() + manipulator_hand = new/obj/effect/big_manipulator_hand(get_turf(src)) + manipulator_hand.dir = take_here + +/// Check servo tier and change manipulator speed, power_use and colour. +/obj/machinery/big_manipulator/proc/manipulator_lvl() + var/datum/stock_part/servo/locate_servo = locate() in component_parts + if(!locate_servo) + return + switch(locate_servo.tier) + if(-INFINITY to 1) + working_speed = 2 SECONDS + power_use_lvl = 0.2 + set_greyscale(COLOR_YELLOW) + manipulator_hand?.set_greyscale(COLOR_YELLOW) + if(2) + working_speed = 1.4 SECONDS + power_use_lvl = 0.4 + set_greyscale(COLOR_ORANGE) + manipulator_hand?.set_greyscale(COLOR_ORANGE) + if(3) + working_speed = 0.8 SECONDS + power_use_lvl = 0.6 + set_greyscale(COLOR_RED) + manipulator_hand?.set_greyscale(COLOR_RED) + if(4 to INFINITY) + working_speed = 0.2 SECONDS + power_use_lvl = 0.8 + set_greyscale(COLOR_PURPLE) + manipulator_hand?.set_greyscale(COLOR_PURPLE) + + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * power_use_lvl + +/// Changing take and drop turf tiles when we anchore manipulator or if manipulator not in turf. +/obj/machinery/big_manipulator/proc/take_and_drop_turfs_check() + if(anchored && isturf(src.loc)) + take_turf = get_step(src, take_here) + drop_turf = get_step(src, drop_here) + else + take_turf = null + drop_turf = null + +/// Changing take and drop turf dirs and also changing manipulator hand sprite dir. +/obj/machinery/big_manipulator/proc/rotate_big_hand() + switch(take_here) + if(NORTH) + take_here = EAST + drop_here = WEST + if(EAST) + take_here = SOUTH + drop_here = NORTH + if(SOUTH) + take_here = WEST + drop_here = EAST + if(WEST) + take_here = NORTH + drop_here = SOUTH + manipulator_hand.dir = take_here + take_and_drop_turfs_check() + +/// Deliting hand will destroy our manipulator core. +/obj/machinery/big_manipulator/proc/on_hand_qdel() + SIGNAL_HANDLER + + 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(isclosedturf(drop_turf)) + on = !on + say("Output blocked") + return FALSE + for(var/obj/item/take_item in take_turf.contents) + try_take_thing(take_turf, take_item) + break + + return TRUE + +/// First take and drop proc from [take and drop procs loop]: +/// Check if we can take item from take_turf to work with him. This proc also calling from ATOM_ENTERED signal. +/obj/machinery/big_manipulator/proc/try_take_thing(datum/source, atom/movable/target) + SIGNAL_HANDLER + + if(!on) + return + if(!anchored) + return + if(QDELETED(source) || QDELETED(target)) + return + if(!isturf(target.loc)) + return + if(on_work) + return + if(!use_energy(active_power_usage, force = FALSE)) + on = FALSE + say("Not enough energy!") + return + if(isitem(target)) + start_work(target) + +/// Second take and drop proc from [take and drop procs loop]: +/// Taking our item and start manipulator hand rotate animation. +/obj/machinery/big_manipulator/proc/start_work(atom/movable/target) + target.forceMove(src) + containment_obj = WEAKREF(target) + on_work = TRUE + do_rotate_animation(1) + addtimer(CALLBACK(src, PROC_REF(drop_thing), target), working_speed) + +/// Third take and drop proc from [take and drop procs loop]: +/// Drop our item and start manipulator hand backward animation. +/obj/machinery/big_manipulator/proc/drop_thing(atom/movable/target) + target.forceMove(drop_turf) + do_rotate_animation(0) + addtimer(CALLBACK(src, PROC_REF(end_work)), working_speed) + +/// 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() + +/// 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) + +/// 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) + +/// Proc call when we press on/off button +/obj/machinery/big_manipulator/proc/press_on(pressed_by) + if(pressed_by) + on = !on + if(!is_work_check()) + return + if(on) + RegisterSignal(take_turf, COMSIG_ATOM_ENTERED, PROC_REF(try_take_thing)) + else + UnregisterSignal(take_turf, COMSIG_ATOM_ENTERED) + +/obj/machinery/big_manipulator/ui_interact(mob/user, datum/tgui/ui) + if(!anchored) + to_chat(user, span_warning("[src] isn't attached to the ground!")) + ui?.close() + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BigManipulator") + ui.open() + +/obj/machinery/big_manipulator/ui_data(mob/user) + var/list/data = list() + data["active"] = on + return data + +/obj/machinery/big_manipulator/ui_act(action, params, datum/tgui/ui) + . = ..() + if(.) + return + switch(action) + if("on") + press_on(pressed_by = TRUE) + return TRUE + +/// 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..." + icon = 'icons/obj/machines/big_manipulator_parts/big_manipulator_hand.dmi' + icon_state = "hand" + layer = LOW_ITEM_LAYER + anchored = TRUE + greyscale_config = /datum/greyscale_config/manipulator_hand + pixel_x = -32 + pixel_y = -32 diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 23f6402880d..6c2c107fc85 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1712,3 +1712,11 @@ /datum/stock_part/capacitor = 2, /datum/stock_part/micro_laser = 2, /obj/item/stack/sheet/glass = 1) + +/obj/item/circuitboard/machine/big_manipulator + name = "Big Manipulator" + greyscale_colors = CIRCUIT_COLOR_ENGINEERING + build_path = /obj/machinery/big_manipulator + req_components = list( + /datum/stock_part/servo = 1, + ) diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index f2067548f45..d07deca2926 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -1247,3 +1247,13 @@ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_SERVICE ) departmental_flags = DEPARTMENT_BITFLAG_SERVICE + +/datum/design/board/big_manipulator + name = "Big Manipulator Board" + desc = "The circuit board for a big manipulator." + id = "big_manipulator" + build_path = /obj/item/circuitboard/machine/big_manipulator + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ENGINEERING + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SERVICE diff --git a/code/modules/research/techweb/nodes/engi_nodes.dm b/code/modules/research/techweb/nodes/engi_nodes.dm index 0fe1b7bd75f..949b880d1f2 100644 --- a/code/modules/research/techweb/nodes/engi_nodes.dm +++ b/code/modules/research/techweb/nodes/engi_nodes.dm @@ -126,6 +126,7 @@ "firelock_board", "trapdoor_electronics", "blast", + "big_manipulator", "tile_sprayer", "airlock_painter", "decal_painter", diff --git a/icons/obj/machines/big_manipulator.dmi b/icons/obj/machines/big_manipulator.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b6e878e1898427f00258da730b18a012a39d67e4 GIT binary patch literal 504 zcmVpfo43B)=#=y(qslFGY!qGbOXA7$|GV#hF%= zn41b=W7m_MlUN=PlqxDALtiRx+msbt{anCa0swp2Lyq!|ksts70P#sgK~zYI?UYLn zf-n$gwg~>p?<7f`+3sIYtaI4)Xv200DGTPE!Ct z=GbNc0047(R9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM z;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+Ilm}XiHkEOv#1!zHRR$gNJ>0RZh$Chinb1d{*&0a8gsK~y-6)siu8gD@0^@sKb@s=-Ug zh7-VJ2qVG+NFBPs&?!rZlqpk?(lHFI6)YT}iNpnZfgYe2;4ZbncBr7q+<(A&?|uG_ zpP#1vBcX>ofbn$4zzv2LvzY1S7eMI%h?A6Q6A$W`NfEPjn=u_y<$(!h^05e$Y|j@x z+bI9AV9LcQv#s2C5Ei630n@7RdxO0M^xgu6;PN8^$UBSV`foizPE=^+PXjrt6$Sf* ze*>Wd`Ar}KtGWpUb?r*vbuH`jk8XM7cL3n`c<1rwSpvJaZZS)F3(xKn$F%d9rx(#k zPxhhgTd6l^{#d(4cFe3x-bt^vMIt*kOqWcA$Y(XC5{P_Ioxi5)IEk>y9c*0r+LTCX z_w!(SlK_f9%%cI-)aa6DN2HPUHDQ5isRr8cC>{Z3eZox zC%d}lIXXF|WM&;cb?WKc*K-#w2FeEdueuLZ%vciS7tG-B>_!@pQ(P4iQR0$XoLrPy zP?DLS$G}iACpfI2sPy}n;DV1|pJ;jOYMncCK6pc@!A0W-k95xaXr5#!(mA`s!Z^tI zvay%KoJW(6ObSs5)>JmsckS#pR^7ZpVo7_q@mdW-bI~JaE}p z`P?^H8Qzzxy;(l@k_7_;^F>b=$B>FSZ)YD2yX7F#W^BurdVGS71Lq!w3G5jjat*w; z?Xt5Md50gm#|$b%EQfZx$3Rj>tgFW5|4kr)@~`ff0(n=ansD0!+IV^%oazfEp(B*e6Q@)38Muo zlZ!hSalBx9y4lS}W|@LZ-IcaGuff06dCm7gTUKbI1Xka$m@2aqn zV~?r`PgUUgoHJRRPc;iBsjj@}9pbGKud-!{$!?Do>LGvXPrlGv*f&8Ur{1FHR7;6G zci@upI*VJvr=GaEo;dgWd3VTry+4zV#h0EtUtjOO&p_i}u9BDDp-7pU%Rieo*R3ku z_hR|p9CxFDN+Ojj%TLhdq6#t7( zHn-0E_vCQH+~?++%i^E$Z}E+vd`4{^qJK8_i|YL^?Y54bMm%!XJ2P?w=s>CmNESI^40^6HXl~!Wlf5~2PdoyX!Y?r zy_DDWgo~BW8!1hvY1~U|SG#phI2mZNDf*%g|ICiVI$NSe^!XzVCIsEk{neN6%_laO zxvbjX%UNyFBUk>}f1UhO*>9iEKlH}j=u6BtUNL^xiKX%J@>$vYYQFe$?0$G!I&858 zgYc`_wI_r5cT70QnZKRo>U z>h9-fo6h^CSJr)>cj2jDdg{UB*}twjryWk`pW*1c#bLJ91GVrSUzqhBorRmcKXED| dxytziJCE1X>0ErJcY$RKgQu&X%Q~loCICgw8C(DW literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 19e73a540ad..4fb8267b38e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2116,6 +2116,7 @@ #include "code\game\machinery\autolathe.dm" #include "code\game\machinery\bank_machine.dm" #include "code\game\machinery\barsigns.dm" +#include "code\game\machinery\big_manipulator.dm" #include "code\game\machinery\botlaunchpad.dm" #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" diff --git a/tgui/packages/tgui/interfaces/BigManipulator.tsx b/tgui/packages/tgui/interfaces/BigManipulator.tsx new file mode 100644 index 00000000000..6a5501b5664 --- /dev/null +++ b/tgui/packages/tgui/interfaces/BigManipulator.tsx @@ -0,0 +1,30 @@ +import { BooleanLike } from 'common/react'; + +import { useBackend } from '../backend'; +import { Button, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type ManipulatorData = { + active: BooleanLike; +}; + +export const BigManipulator = (props) => { + const { data, act } = useBackend(); + const { active } = data; + return ( + + +
+ +
+
+
+ ); +};