diff --git a/code/game/objects/items/robot/cyborg_gripper.dm b/code/game/objects/items/robot/cyborg_gripper.dm index 6cd8446c8bb..fc8a1b15ebd 100644 --- a/code/game/objects/items/robot/cyborg_gripper.dm +++ b/code/game/objects/items/robot/cyborg_gripper.dm @@ -3,7 +3,8 @@ 1. UNIVERSAL GRIPPER 2. MEDICAL GRIPPER 3. SERVICE GRIPPER -4. ENGINEERING GRIPPER +4. MINING GRIPPER +5. ENGINEERING GRIPPER */ // Generic gripper. This should never appear anywhere. @@ -13,9 +14,9 @@ icon = 'icons/obj/device.dmi' icon_state = "gripper" actions_types = list(/datum/action/item_action/drop_gripped_item) - /// Set to TRUE to allow interaction with light fixtures and cell-containing machinery. + /// Set to TRUE to removal of cells/lights from machine objects containing them. var/engineering_machine_interaction = FALSE - /// Set to TRUE to allow the gripper to shake people awake/help them up. + /// Set to TRUE to allow the gripper to shake people awake and help them up. var/can_help_up = FALSE /// Defines what items the gripper can carry. var/list/can_hold = list() @@ -33,10 +34,10 @@ /obj/item/gripper/examine_more(mob/user) . = ..() - . += {"Cyborg grippers are well-developed, and despite some anatomical differences that manifest in some models, they can be used just as effectively as a regular hand with enough practice. - -Companies like Nanotrasen use software to limit the items that a cyborg can manipulate to a specific pre-defined list, \ -as part of their multi-layered protections to try and eliminate the chance of a hypothetical synthetic uprising, not wishing to see a repeat of the IPC uprising in 2525."} + . += "Cyborg grippers are well-developed, and despite some anatomical differences that manifest in some models, they can be used just as effectively as a regular hand with enough practice." + . += "" + . += "Companies like Nanotrasen use software to limit the items that a cyborg can manipulate to a specific pre-defined list, \ + as part of their multi-layered protections to try and eliminate the chance of a hypothetical synthetic uprising, not wishing to see a repeat of the IPC uprising in 2525." /obj/item/gripper/Initialize(mapload) @@ -69,10 +70,40 @@ as part of their multi-layered protections to try and eliminate the chance of a return /obj/item/gripper/afterattack(atom/target, mob/living/user, proximity, params) - //Target is invalid or we are not adjacent. + // Target is invalid or we are not adjacent. if(!target || !proximity) - return FALSE - // Shake people awake, get them on their feet. + return + + // Does the gripper already have an item? + if(gripped_item) + // Pass the attack on to the target. This might delete/relocate gripped_item. If the attackby doesn't resolve or delete the target or gripped_item, afterattack. + if(!target.attackby(gripped_item, user, params)) + gripped_item?.afterattack(target, user, 1, params) + // Check to see if there is still an item in the gripper (stackable items trigger this). + if(!gripped_item && length(contents)) + gripped_item = contents[1] + return + // If the gripper thinks it has something but it actually doesn't, we fix this. + if(gripped_item && !length(contents)) + gripped_item = null + return + + return TRUE + + // Is the gripper interacting with an item? + if(isitem(target)) + var/obj/item/I = target + // Make sure the item is something the gripper can hold + if(can_hold_all_items || is_type_in_typecache(I, can_hold)) + to_chat(user, "You collect [I].") + I.forceMove(src) + gripped_item = I + return + + to_chat(user, "You hold your gripper over [target], but no matter how hard you try, you cannot make yourself grab it.") + return + + // Have we come across a poor soul on the floor that has fallen and can't get up? if(ishuman(target) && can_help_up) var/mob/living/carbon/human/pickup_target = target if(!IS_HORIZONTAL(pickup_target)) @@ -90,72 +121,53 @@ as part of their multi-layered protections to try and eliminate the chance of a "[user] shakes [pickup_target] trying to wake [pickup_target.p_them()] up!", "You shake [pickup_target] trying to wake [pickup_target.p_them()] up!" ) - return FALSE - //Already have an item. - if(gripped_item) - - //Pass the attack on to the target. This might delete/relocate gripped_item. - if(!target.attackby(gripped_item, user, params)) - // If the attackby didn't resolve or delete the target or gripped_item, afterattack - // (Certain things, such as mountable frames, rely on afterattack) - gripped_item?.afterattack(target, user, 1, params) - - //If gripped_item either didn't get deleted, or it failed to be transfered to its target - if(!gripped_item && length(contents)) - gripped_item = contents[1] - return FALSE - else if(gripped_item && !contents.len) - gripped_item = null - return TRUE - - //Check that we're not pocketing a mob. - else if(isitem(target)) - var/obj/item/I = target - // Make sure the item is something the gripper can hold - if(can_hold_all_items || is_type_in_typecache(I, can_hold)) - to_chat(user, "You collect [I].") - I.forceMove(src) - gripped_item = I - return TRUE - - to_chat(user, "You hold your gripper over [target], but no matter how hard you try, you cannot make yourself grab it.") - return FALSE + return // Everything past this point requires being able to engineer. if(!engineering_machine_interaction) return - // APC cells. + + // Removing cells from APCs. if(istype(target, /obj/machinery/power/apc)) var/obj/machinery/power/apc/A = target if(A.opened && A.cell) gripped_item = A.cell - A.cell.add_fingerprint(user) A.cell.update_icon() A.cell.forceMove(src) A.cell = null - A.charging = APC_NOT_CHARGING A.update_icon() + user.visible_message( + "[user] removes the cell from [A]!", + "You remove the cell from [A]." + ) + return - user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") - // Cell Chargers - else if(istype(target, /obj/machinery/cell_charger)) + // Removing cells from cell chargers. + if(istype(target, /obj/machinery/cell_charger)) var/obj/machinery/cell_charger/cell_charger = target if(cell_charger.charging) gripped_item = cell_charger.charging cell_charger.charging.add_fingerprint(user) cell_charger.charging.forceMove(src) cell_charger.removecell() - // Putting lights in fixtures. - else if(istype(target, /obj/machinery/light)) + user.visible_message( + "[user] removes the cell from [cell_charger].", + "You remove the cell from [cell_charger]." + ) + return + + // Removing lights from fixtures. + if(istype(target, /obj/machinery/light)) var/obj/machinery/light/light = target var/obj/item/light/L = light.drop_light_tube() L.forceMove(src) gripped_item = L - user.visible_message("[user] removes the light from the fixture.", "You dislodge the light from the fixture.") - - return TRUE + user.visible_message( + "[user] removes [L] from [light].", + "You remove [L] from [light]." + ) //////////////////////////////// // MARK: UNIVERSAL GRIPPER @@ -201,6 +213,19 @@ as part of their multi-layered protections to try and eliminate the chance of a /obj/item/toy/plushie ) +//////////////////////////////// +// MARK: MINING GRIPPER +//////////////////////////////// +// For mining borgs. Mostly for self-application of goliath armour. +/obj/item/gripper/mining + name = "mining gripper" + desc = "A grasping tool for cyborgs. This ruggedized version will let you add goliath plating to yourself and activate survival capsules. You could also use it to swing a pickaxe if you don't feel like using your drill." + can_hold = list( + /obj/item/pickaxe, // Because the image of a mining borg ignoring its built-in drill and instead choosing to swing an old-fashioned pickaxe is funny. + /obj/item/stack/sheet/animalhide/goliath_hide, + /obj/item/survivalcapsule + ) + //////////////////////////////// // MARK: ENGINEERING GRIPPER //////////////////////////////// diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index ab552133134..aa71a2d1dab 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -320,6 +320,7 @@ /obj/item/robot_module/proc/handle_custom_removal(component_id, mob/living/user, obj/item/W) return FALSE +/// Overriden for specific modules if they have storage items. These should have their contents emptied out onto the floor. /obj/item/robot_module/proc/handle_death(mob/living/silicon/robot/R, gibbed) return @@ -477,8 +478,11 @@ /obj/item/robot_module/engineering/handle_death(mob/living/silicon/robot/R, gibbed) var/obj/item/gripper/engineering/G = locate(/obj/item/gripper/engineering) in modules + var/obj/item/storage/part_replacer/P = locate(/obj/item/storage/part_replacer) in modules if(G) G.drop_gripped_item(silent = TRUE) + if(istype(P)) + P.drop_inventory(R) // Security cyborg module. /obj/item/robot_module/security @@ -531,6 +535,11 @@ /obj/item/extinguisher/mini ) +/obj/item/robot_module/janitor/handle_death(mob/living/silicon/robot/R, gibbed) + var/obj/item/storage/bag/trash/T = locate(/obj/item/storage/bag/trash) in modules + if(istype(T)) + T.drop_inventory(R) + /obj/item/robot_module/janitor/Initialize(mapload) . = ..() var/mob/living/silicon/robot/R = loc @@ -623,8 +632,11 @@ /obj/item/robot_module/butler/handle_death(mob/living/silicon/robot/R, gibbed) var/obj/item/gripper/service/G = locate(/obj/item/gripper/service) in modules + var/obj/item/storage/bag/tray/cyborg/T = locate(/obj/item/storage/bag/tray/cyborg) in modules if(G) G.drop_gripped_item(silent = TRUE) + if(istype(T)) + T.drop_inventory(R) // This is a special type of beer given when emagged, one sip and the target falls asleep. /obj/item/reagent_containers/drinks/cans/beer/sleepy_beer @@ -654,12 +666,6 @@ R.add_language("Neo-Russkiya", 1) R.add_language("Tkachi", 1) -/obj/item/robot_module/butler/handle_death(mob/living/silicon/robot/R, gibbed) - var/obj/item/storage/bag/tray/cyborg/T = locate(/obj/item/storage/bag/tray/cyborg) in modules - if(istype(T)) - T.drop_inventory(R) - - /obj/item/robot_module/miner name = "miner robot module" module_type = "Miner" @@ -676,12 +682,21 @@ /obj/item/extinguisher/mini, /obj/item/t_scanner/adv_mining_scanner/cyborg, /obj/item/gun/energy/kinetic_accelerator/cyborg, - /obj/item/gps/cyborg + /obj/item/gps/cyborg, + /obj/item/gripper/mining ) emag_modules = list(/obj/item/pickaxe/drill/jackhammer) malf_modules = list(/obj/item/gun/energy/kinetic_accelerator/cyborg/malf) special_rechargables = list(/obj/item/extinguisher/mini, /obj/item/weldingtool/mini) +/obj/item/robot_module/miner/handle_death(mob/living/silicon/robot/R, gibbed) + var/obj/item/gripper/mining/G = locate(/obj/item/gripper/mining) in modules + var/obj/item/storage/bag/ore/B = locate(/obj/item/storage/bag/ore) in modules + if(G) + G.drop_gripped_item(silent = TRUE) + if(istype(B)) + B.drop_inventory(R) + // This makes it so others can crowbar out KA upgrades from the miner borg. /obj/item/robot_module/miner/handle_custom_removal(component_id, mob/living/user, obj/item/W) if(component_id == "KA modkits")