diff --git a/citadel.dme b/citadel.dme index 837642e1522..8f4774d717d 100644 --- a/citadel.dme +++ b/citadel.dme @@ -1837,6 +1837,7 @@ #include "code\game\objects\items\gifts.dm" #include "code\game\objects\items\glassjar.dm" #include "code\game\objects\items\godfigures.dm" +#include "code\game\objects\items\gripper.dm" #include "code\game\objects\items\gunbox.dm" #include "code\game\objects\items\holosign_creator.dm" #include "code\game\objects\items\inducer.dm" @@ -4347,7 +4348,6 @@ #include "code\modules\mob\living\silicon\robot\items\robot_upgrade\sizeshift.dm" #include "code\modules\mob\living\silicon\robot\items\robot_upgrade\syndicate.dm" #include "code\modules\mob\living\silicon\robot\items\robot_upgrade\vtec.dm" -#include "code\modules\mob\living\silicon\robot\legacy_items\gripper.dm" #include "code\modules\mob\living\silicon\robot\legacy_items\robot_items.dm" #include "code\modules\mob\living\silicon\robot\legacy_items\robot_parts.dm" #include "code\modules\mob\living\silicon\robot\modules\cybersun.dm" diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 7846e51504f..8dc6961e681 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -113,16 +113,4 @@ /obj/machinery/computer/attackby(obj/item/I, mob/living/user, params, clickchain_flags, damage_multiplier) if(computer_deconstruction_screwdriver(user, I)) return - else - if(istype(I,/obj/item/gripper)) //Behold, Grippers and their horribleness. If ..() is called by any computers' attackby() now or in the future, this should let grippers work with them appropriately. - var/obj/item/gripper/B = I //B, for Borg. - if(!B.get_item()) - to_chat(user, "\The [B] is not holding anything.") - return - else - var/B_held = B.get_item() - to_chat(user, "You use \the [B] to use \the [B_held] with \the [src].") - playsound(src, "keyboard", 100, 1, 0) - attackby(B.get_item(), user, params, clickchain_flags, damage_multiplier) - return - return ..() + return ..() diff --git a/code/modules/mob/living/silicon/robot/legacy_items/gripper.dm b/code/game/objects/items/gripper.dm similarity index 78% rename from code/modules/mob/living/silicon/robot/legacy_items/gripper.dm rename to code/game/objects/items/gripper.dm index 20f46c36d14..7b7c15c3041 100644 --- a/code/modules/mob/living/silicon/robot/legacy_items/gripper.dm +++ b/code/game/objects/items/gripper.dm @@ -1,7 +1,9 @@ -// todo: this shouldn't be a robot item, this is generic. - -//Simple borg hand. -//Limited use. +/** + * Dynamic way to allow holding another item in an inventory slot / hand slot + * with a single static item of the item itself. + * + * Useful for cyborgs and rigsuits and more. + */ /obj/item/gripper name = "magnetic gripper" desc = "A simple grasping tool specialized in construction and engineering work." @@ -11,22 +13,8 @@ icon_state = "gripper" item_flags = ITEM_NO_BLUDGEON | ITEM_ENCUMBERS_WHILE_HELD - //Has a list of items that it can hold. - var/list/can_hold = list( - /obj/item/cell, - /obj/item/airlock_electronics, - /obj/item/tracker_electronics, - /obj/item/module/power_control, - /obj/item/stock_parts, - /obj/item/frame, - /obj/item/camera_assembly, - /obj/item/tank, - /obj/item/circuitboard, - /obj/item/smes_coil, - /obj/item/fuelrod/, - /obj/item/fuel_assembly/ - ) - + /// Has a list of items that it can hold. + var/list/can_hold /// currently held item VAR_PRIVATE/obj/item/wrapped @@ -42,6 +30,56 @@ remove_item(drop_location()) return ..() +/** + * Checks if an item should be able to be held in here. + */ +/obj/item/gripper/proc/can_hold(obj/item/item) + for(var/typepath in can_hold) + if(istype(item,typepath)) + return TRUE + return FALSE + +/obj/item/gripper/inv_slot_attached() + if(wrapped) + return list(wrapped, src) + return src + +//! WARNING WARNING GRIPPERS ARE STILL SHITCODE !// +//! This exact combination of hooks will make it work as expected. !// +//! It's realistically still pretty shitty. !// + +/obj/item/gripper/pickup(...) + . = ..() + wrapped?.pickup(arglist(args)) + +/obj/item/gripper/dropped(...) + . = ..() + wrapped?.dropped(arglist(args)) + +/obj/item/gripper/equipped(...) + . = ..() + wrapped?.equipped(arglist(args)) + +/obj/item/gripper/unequipped(...) + . = ..() + wrapped?.unequipped(arglist(args)) + +/obj/item/gripper/on_inv_equipped(...) + . = ..() + wrapped?.on_inv_equipped(arglist(args)) + +/obj/item/gripper/on_inv_unequipped(...) + . = ..() + wrapped?.on_inv_unequipped(arglist(args)) + +/obj/item/gripper/on_inv_pickup(...) + . = ..() + wrapped?.on_inv_pickup(arglist(args)) + +/obj/item/gripper/on_inv_dropped(...) + . = ..() + wrapped?.on_inv_dropped(arglist(args)) + /obj/item/gripper/proc/insert_item(obj/item/I) if(QDELETED(I)) return @@ -49,6 +87,11 @@ remove_item(drop_location()) wrapped = I I.forceMove(src) + // forcemove will have removed them from inv if they were inside + if(worn_slot) + I.pickup(inv_inside.owner, NONE, null) + I.equipped(inv_inside.owner, isnum(inv_slot_or_index) ? SLOT_ID_HANDS : inv_slot_or_index, NONE) + I.on_inv_equipped(inv_inside.owner, inv_inside, inv_slot_or_index, NONE, null) RegisterSignals(I, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(unwrap_hook)) /** @@ -60,6 +103,8 @@ var/obj/item/old = wrapped UnregisterSignal(wrapped, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) wrapped = null + // in theory the below should pull it out of inventory properly + // as worn_slot is set, which allows inventory hooks to fire. switch(newloc) if(null) old.moveToNullspace() @@ -84,7 +129,6 @@ return if(wrapped) return wrapped.attack_self(user) - return ..() /obj/item/gripper/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier) // todo: items should have a melee_receive_chain or something that @@ -125,11 +169,7 @@ return //Check if the item is blacklisted. - var/grab = 0 - for(var/typepath in can_hold) - if(istype(I,typepath)) - grab = 1 - break + var/grab = can_hold(I) //We can grab the item, finally. if(grab) @@ -171,11 +211,28 @@ desc = "A strange grasping tool that can hold anything a human can, but still maintains the limitations of application its more limited cousins have." icon_state = "gripper-omni" - can_hold = list(/obj/item) // Testing and Event gripper. +/obj/item/gripper/omni/can_hold(obj/item/item) + return TRUE /obj/item/gripper/omni/no_attack conf_inject_clickchain_flags = CLICKCHAIN_DO_NOT_ATTACK +/obj/item/gripper/engineering + can_hold = list( + /obj/item/cell, + /obj/item/airlock_electronics, + /obj/item/tracker_electronics, + /obj/item/module/power_control, + /obj/item/stock_parts, + /obj/item/frame, + /obj/item/camera_assembly, + /obj/item/tank, + /obj/item/circuitboard, + /obj/item/smes_coil, + /obj/item/fuelrod, + /obj/item/fuel_assembly, + ) + // VEEEEERY limited version for mining borgs. Basically only for swapping cells and upgrading the drills. /obj/item/gripper/miner name = "drill maintenance gripper" @@ -183,8 +240,8 @@ icon_state = "gripper-mining" can_hold = list( - /obj/item/cell, - /obj/item/stock_parts + /obj/item/cell, + /obj/item/stock_parts, ) /obj/item/gripper/security @@ -193,14 +250,14 @@ icon_state = "gripper-sec" can_hold = list( - /obj/item/paper, - /obj/item/paper_bundle, - /obj/item/pen, - /obj/item/sample, - /obj/item/forensics/sample_kit, - /obj/item/tape_recorder, - /obj/item/barrier_tape_roll, - /obj/item/uv_light + /obj/item/paper, + /obj/item/paper_bundle, + /obj/item/pen, + /obj/item/sample, + /obj/item/forensics/sample_kit, + /obj/item/tape_recorder, + /obj/item/barrier_tape_roll, + /obj/item/uv_light, ) /obj/item/gripper/paperwork @@ -213,8 +270,8 @@ /obj/item/paper_bundle, /obj/item/card/id, /obj/item/book, - /obj/item/newspaper - ) + /obj/item/newspaper, + ) /obj/item/gripper/medical name = "medical gripper" @@ -227,8 +284,8 @@ /obj/item/reagent_containers/blood, /obj/item/stack/material/phoron, /obj/item/implant, - /obj/item/nif - ) + /obj/item/nif, + ) /obj/item/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc name = "scientific gripper" @@ -253,9 +310,8 @@ /obj/item/slimepotion, /obj/item/slime_extract, /obj/item/reagent_containers/food/snacks/monkeycube, - /obj/item/nif - - ) + /obj/item/nif, + ) /obj/item/gripper/circuit name = "circuit assembly gripper" @@ -274,9 +330,8 @@ /obj/item/clothing/ears/circuitry, /obj/item/clothing/suit/circuitry, /obj/item/implant/integrated_circuit, - /obj/item/integrated_circuit - - ) + /obj/item/integrated_circuit, + ) /obj/item/gripper/service //Used to handle food, drinks, and seeds. name = "service gripper" @@ -292,8 +347,8 @@ /obj/item/plantspray, /obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/drinks, - /obj/item/storage/box/wings - ) + /obj/item/storage/box/wings, + ) /obj/item/gripper/gravekeeper //Used for handling grave things, flowers, etc. name = "grave gripper" @@ -303,8 +358,22 @@ can_hold = list( /obj/item/seeds, /obj/item/grown, - /obj/item/material/gravemarker - ) + /obj/item/material/gravemarker, + ) + +/obj/item/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item + +/obj/item/gripper/no_use/attack_self(mob/user, datum/event_args/actor/actor) + return + +/obj/item/gripper/no_use/organ + name = "organ gripper" + icon_state = "gripper-flesh" + desc = "A specialized grasping tool used to preserve and manipulate organic material." + + can_hold = list( + /obj/item/organ, + ) /obj/item/gripper/no_use/organ/Entered(var/atom/movable/AM) ..() @@ -318,11 +387,6 @@ var/obj/item/organ/O = AM O.unpreserve(GRIPPER_TRAIT) -/obj/item/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item - -/obj/item/gripper/no_use/attack_self(mob/user, datum/event_args/actor/actor) - return - /obj/item/gripper/no_use/organ/robotics name = "robotics organ gripper" icon_state = "gripper-flesh" @@ -332,8 +396,8 @@ /obj/item/organ/external, /obj/item/organ/internal/brain, //to insert into MMIs, /obj/item/organ/internal/cell, - /obj/item/organ/internal/eyes/robot - ) + /obj/item/organ/internal/eyes/robot, + ) /obj/item/gripper/no_use/mech name = "exosuit gripper" @@ -344,8 +408,8 @@ /obj/item/vehicle_part, /obj/item/vehicle_part/micro, /obj/item/vehicle_module, - /obj/item/vehicle_tracking_beacon - ) + /obj/item/vehicle_tracking_beacon, + ) /obj/item/gripper/no_use/loader //This is used to disallow building with metal. name = "sheet loader" @@ -353,14 +417,5 @@ icon_state = "gripper-sheet" can_hold = list( - /obj/item/stack/material - ) - -/obj/item/gripper/no_use/organ - name = "organ gripper" - icon_state = "gripper-flesh" - desc = "A specialized grasping tool used to preserve and manipulate organic material." - - can_hold = list( - /obj/item/organ - ) + /obj/item/stack/material, + ) diff --git a/code/game/rendering/actor_huds/huds/robot_inventory-screen_object.dm b/code/game/rendering/actor_huds/huds/robot_inventory-screen_object.dm index 48c02cecb14..dfdf6ffbd5c 100644 --- a/code/game/rendering/actor_huds/huds/robot_inventory-screen_object.dm +++ b/code/game/rendering/actor_huds/huds/robot_inventory-screen_object.dm @@ -154,6 +154,7 @@ name = "drawer" icon = 'icons/screen/hud/styles/common/storage.dmi' icon_state = "block" + vis_flags = VIS_INHERIT_LAYER | VIS_INHERIT_PLANE mouse_opacity = MOUSE_OPACITY_ICON var/atom/movable/screen/actor_hud/robot_inventory/robot_drawer_backplate/backplate var/obj/item/masquarading_as diff --git a/code/modules/economy/machines/mint.dm b/code/modules/economy/machines/mint.dm index daacc66ee43..48d0559e938 100644 --- a/code/modules/economy/machines/mint.dm +++ b/code/modules/economy/machines/mint.dm @@ -439,17 +439,6 @@ if(P.contents.len > 0) to_chat(user, "Some items are refused.") - else if(istype(O, /obj/item/gripper)) // Grippers. ~Mechoid. - var/obj/item/gripper/B = O //B, for Borg. - if(!B.get_item()) - to_chat(user, "\The [B] is not holding anything.") - return - else - var/B_held = B.get_item() - to_chat(user, "You use \the [B] to put \the [B_held] into \the [src] slot.") - attackby(B_held, user) - return - else to_chat(user, "\The [O] doesn't fit into the [src] slot.") return 1 diff --git a/code/modules/food/machinery/smartfridge.dm b/code/modules/food/machinery/smartfridge.dm index d75dd5222df..325a02f60dd 100644 --- a/code/modules/food/machinery/smartfridge.dm +++ b/code/modules/food/machinery/smartfridge.dm @@ -160,17 +160,6 @@ if(P.contents.len > 0) to_chat(user, "Some items are refused.") - else if(istype(O, /obj/item/gripper)) // Grippers. ~Mechoid. - var/obj/item/gripper/B = O //B, for Borg. - if(!B.get_item()) - to_chat(user, "\The [B] is not holding anything.") - return - else - var/B_held = B.get_item() - to_chat(user, "You use \the [B] to put \the [B_held] into \the [src].") - attackby(B_held, user) - return - else to_chat(user, "\The [src] smartly refuses [O].") return 1 diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 8c6ce141314..ebc2cd69ec7 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -12,9 +12,9 @@ /mob/living/silicon/robot/death(gibbed) if(camera) camera.status = 0 - var/obj/item/gripper/G = locate(/obj/item/gripper) in contents - if(G) - G.drop_item() + // drop all gripper items + for(var/obj/item/gripper/gripper in get_equipped_items()) + gripper.drop_item() var/obj/item/robot_builtin/dog_sleeper/S = locate(/obj/item/robot_builtin/dog_sleeper) in contents if(S) S.go_out() diff --git a/code/modules/mob/living/silicon/robot/modules/drone.dm b/code/modules/mob/living/silicon/robot/modules/drone.dm index e36f29f9a45..e98297a857a 100644 --- a/code/modules/mob/living/silicon/robot/modules/drone.dm +++ b/code/modules/mob/living/silicon/robot/modules/drone.dm @@ -34,7 +34,7 @@ /obj/item/tool/wirecutters/cyborg, /obj/item/multitool, /obj/item/lightreplacer, - /obj/item/gripper, + /obj/item/gripper/engineering, /obj/item/mop, /obj/item/gripper/no_use/loader, /obj/item/extinguisher, diff --git a/code/modules/mob/living/silicon/robot/modules/nanotrasen/engineering.dm b/code/modules/mob/living/silicon/robot/modules/nanotrasen/engineering.dm index ab7418d7162..fd8ffe40569 100644 --- a/code/modules/mob/living/silicon/robot/modules/nanotrasen/engineering.dm +++ b/code/modules/mob/living/silicon/robot/modules/nanotrasen/engineering.dm @@ -81,7 +81,7 @@ GENERATE_ROBOT_MODULE_PRESET(/nanotrasen/engineering) /obj/item/geiger_counter/cyborg, /obj/item/pipe_painter, /obj/item/floor_painter, - /obj/item/gripper, + /obj/item/gripper/engineering, /obj/item/gripper/no_use/loader, /obj/item/pipe_dispenser, /obj/item/gripper/circuit, diff --git a/code/modules/mob/living/silicon/robot/robot-composition.dm b/code/modules/mob/living/silicon/robot/robot-composition.dm index b3397b224ea..3e8aa925e99 100644 --- a/code/modules/mob/living/silicon/robot/robot-composition.dm +++ b/code/modules/mob/living/silicon/robot/robot-composition.dm @@ -136,7 +136,7 @@ if(module_provisioning) QDEL_NULL(module_provisioning) if(module_legacy) - module_legacy.Reset() + module_legacy.Reset(src) QDEL_NULL(module_legacy) // set src.module = module diff --git a/code/modules/mob/living/silicon/robot/robot-inventory.dm b/code/modules/mob/living/silicon/robot/robot-inventory.dm index a9341d835de..b3ea3c8b95b 100644 --- a/code/modules/mob/living/silicon/robot/robot-inventory.dm +++ b/code/modules/mob/living/silicon/robot/robot-inventory.dm @@ -7,10 +7,3 @@ /mob/living/silicon/robot/should_allow_pickup(obj/item/item, datum/event_args/actor/actor, silent) return item in robot_inventory?.provided_items - -/mob/living/silicon/robot/is_in_inventory(obj/item/item) - return ..() || is_in_inventory_robot(item) - -/mob/living/silicon/robot/proc/is_in_inventory_robot(obj/item/item) - // Bespoke check that an item is in gripper, as grippers don't count as an inventory slot. - return istype(item.loc, /obj/item/gripper) && item.loc.loc == src diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index abc71d65092..487c460677c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -957,7 +957,7 @@ cleaned_human.clean_blood(1) to_chat(cleaned_human, "[src] cleans your face!") - for(var/obj/item/storage/bag/ore/ore_bag in inventory.get_held_items()) + for(var/obj/item/storage/bag/ore/ore_bag in inventory?.get_held_items()) if(ore_bag) if(isturf(loc)) var/turf/tile = loc @@ -997,6 +997,11 @@ state = 1 lockdown = state lockcharge = state + if(lockdown) + // we still need a better way of prying shit out of these guys + // but for now this is fine + for(var/obj/item/gripper/gripper in get_equipped_items()) + gripper.drop_item() update_mobility() /mob/living/silicon/robot/proc/sensor_mode() //Medical/Security HUD controller for borgs diff --git a/code/modules/reagents/chemistry/machinery.dm b/code/modules/reagents/chemistry/machinery.dm index e01cb659e1f..80d91f73fb1 100644 --- a/code/modules/reagents/chemistry/machinery.dm +++ b/code/modules/reagents/chemistry/machinery.dm @@ -127,18 +127,6 @@ src.updateUsrDialog() return 0 - if(istype(O,/obj/item/gripper)) - var/obj/item/gripper/B = O //B, for Borg. - if(!B.get_item()) - to_chat(user, "\The [B] is not holding anything.") - return 0 - else - var/B_held = B.get_item() - to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") - attackby(B_held, user) - - return 0 - if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) to_chat(user, "\The [O] is not suitable for blending.") return 1