diff --git a/code/game/objects/items/robot/cyborg_gripper.dm b/code/game/objects/items/robot/cyborg_gripper.dm index cc392479255..fed26713359 100644 --- a/code/game/objects/items/robot/cyborg_gripper.dm +++ b/code/game/objects/items/robot/cyborg_gripper.dm @@ -1,10 +1,11 @@ /* CONTENTS: -0. generic define gripper -1. UNIVERSAL GRIPPER -2. MEDICAL GRIPPER -3. SERVICE GRIPPER -4. MINING GRIPPER -5. ENGINEERING GRIPPER +* 0. Generic Gripper +* 1. Gripper Types +* 1.1 Universal Gripper +* 1.2 Medical Gripper +* 1.3 Service Gripper +* 1.4 Mining Gripper +* 1.5 Engineering Gripper */ // Generic gripper. This should never appear anywhere. @@ -16,12 +17,12 @@ actions_types = list(/datum/action/item_action/drop_gripped_item) /// 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 and help them up. - var/can_help_up = FALSE /// Defines what items the gripper can carry. var/list/can_hold = list() /// Set to TRUE to allow ANY item to be held, bypassing can_hold checks. var/can_hold_all_items = FALSE + /// Set to TRUE to allow the gripper to shake people awake and help them up. + var/can_help_up = FALSE /// The item currently being held. var/obj/item/gripped_item @@ -39,7 +40,6 @@ . += "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) . = ..() can_hold = typecacheof(can_hold) @@ -62,9 +62,6 @@ return gripped_item.attack_self(user) -/obj/item/gripper/attack(mob/living/carbon/M, mob/living/carbon/user) - return - // This is required to ensure that the forceMove checks on some objects don't rip the gripper out of the borg's inventory and toss it on the floor. That would hurt, a lot! /obj/item/gripper/forceMove(atom/destination) return @@ -103,24 +100,8 @@ 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)) - return - pickup_target.AdjustSleeping(-10 SECONDS) - pickup_target.AdjustParalysis(-6 SECONDS) - pickup_target.AdjustStunned(-6 SECONDS) - pickup_target.AdjustWeakened(-6 SECONDS) - pickup_target.AdjustKnockDown(-6 SECONDS) - pickup_target.adjustStaminaLoss(-10) - pickup_target.resting = FALSE - pickup_target.stand_up() - playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - user.visible_message( - "[user] shakes [pickup_target] trying to wake [pickup_target.p_them()] up!", - "You shake [pickup_target] trying to wake [pickup_target.p_them()] up!" - ) + // Attack code will handle this. + if(ismob(target)) return // Everything past this point requires being able to engineer. @@ -169,10 +150,139 @@ "You remove [L] from [light]." ) -//////////////////////////////// -// MARK: UNIVERSAL GRIPPER -//////////////////////////////// -/// Universal gripper. Not supplied to any cyborg by default. Could be varedited onto a borg for event stuff. Functions almost like a real hand! +/obj/item/gripper/emag_act(mob/user) + emagged = !emagged + ..() + return TRUE + +/obj/item/gripper/attack(mob/living/M, mob/living/silicon/robot/user, params) + if(gripped_item) + return + + // If a human target is horizonal, try to help them up. Unless you're trying to kill them. + if(ishuman(M) && user.a_intent == INTENT_HELP && can_help_up) + var/mob/living/carbon/human/pickup_target = M + if(IS_HORIZONTAL(pickup_target)) + // Same restorative effects as when a human tries to help someone up. + pickup_target.AdjustSleeping(-10 SECONDS) + pickup_target.AdjustParalysis(-6 SECONDS) + pickup_target.AdjustStunned(-6 SECONDS) + pickup_target.AdjustWeakened(-6 SECONDS) + pickup_target.AdjustKnockDown(-6 SECONDS) + pickup_target.adjustStaminaLoss(-10) + pickup_target.resting = FALSE + pickup_target.stand_up() + playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + user.visible_message( + "[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 + + if(user.a_intent == INTENT_HELP) + if(M == user) + user.visible_message( + "[user] gives [user.p_themselves()] a hug to make [user.p_themselves()] feel better.", + "You give yourself a hug to make yourself feel better." + ) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + return + + // Checks if holder_type exists to prevent picking up animals like mice, because we're about to use the hands that borgs secretly have. + if(isanimal(M) && !M.holder_type) + var/list/modifiers = params2list(params) + // This enables borgs to get the floating heart icon and mob emote from simple_animals that have petbonus == TRUE. + M.attack_hand(user, modifiers) + + if(user.zone_selected == BODY_ZONE_HEAD) + user.visible_message( + "[user] playfully boops [M] on the head.", + "You playfully boop [M] on the head." + ) + user.do_attack_animation(M, ATTACK_EFFECT_BOOP) + playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) + return + + if(ishuman(M)) + user.visible_message( + "[user] hugs [M] to make [M.p_them()] feel better.", + "You hug [M] to make [M.p_them()] feel better." + ) + else + user.visible_message( + "[user] pets [M]!", + "You pet [M]!" + ) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + return + + if(user.a_intent == INTENT_HARM && !emagged) + if(M == user) + user.visible_message( + "[user] gives [user.p_themselves()] a firm bear-hug to make [user.p_themselves()] feel better.", + "You give yourself a firm bear-hug to make yourself feel better." + ) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + return + + if(!ishuman(M) || user.zone_selected == BODY_ZONE_HEAD) + user.visible_message( + "[user] bops [M] on the head!", + "You bop [M] on the head!" + ) + user.do_attack_animation(M, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) + else + user.visible_message( + "[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...", + "You hug [M] firmly to make [M.p_them()] feel better! [M] looks uncomfortable..." + ) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + return + + // Just in case. + if(!emagged) + return + + if(M == user) + user.visible_message( + "[user] punches [user.p_themselves()] in the face!.", + "You punch yourself in the face!" + ) + user.do_attack_animation(M, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/smash.ogg', 50, TRUE, -1) + user.adjustBruteLoss(15) + return + + if(ishuman(M)) + // Try to punch them in the face... Unless it fell off or something. + if(user.zone_selected == BODY_ZONE_HEAD && M.get_organ("head")) + user.visible_message( + "[user] punches [M] squarely in the face!", + "You punch [M] in the face!" + ) + var/obj/item/organ/external/head/their_face = M.get_organ("head") + user.do_attack_animation(M, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/smash.ogg', 50, TRUE, -1) + their_face.receive_damage(15) + M.UpdateDamageIcon() + return + + user.visible_message( + "[user] crushes [M] in [user.p_their()] grip!", + "You crush [M] in your grip!" + ) + playsound(loc, 'sound/weapons/smash.ogg', 50, TRUE, -1) + M.adjustBruteLoss(15) + +// MARK: Gripper Types + +/* +* Universal Gripper +* Not supplied to any cyborg by default. +* Can be varedited onto a borg for event stuff. +* Functions almost like a real hand! +*/ /obj/item/gripper/universal name = "cyborg gripper" desc = "A grasping tool for cyborgs. This one is not restricted by any restraining software, allowing it to handle any object the user wishes." @@ -185,9 +295,7 @@ . = ..() ADD_TRAIT(src,TRAIT_SURGICAL_OPEN_HAND, ROUNDSTART_TRAIT) -//////////////////////////////// -// MARK: MEDICAL GRIPPER -//////////////////////////////// +// Medical Gripper // For medical borgs, for doing medical stuff! // Not giving this anything to hold yet, but stuff may be added in the future. Organs/implants are currently viewed as too strong to hold. /obj/item/gripper/medical @@ -202,9 +310,7 @@ . = ..() ADD_TRAIT(src,TRAIT_SURGICAL_OPEN_HAND, ROUNDSTART_TRAIT) -//////////////////////////////// -// MARK: SERVICE GRIPPER -//////////////////////////////// +// Service Gripper // For service borgs. To make them slightly better at their job. /obj/item/gripper/service name = "service gripper" @@ -221,9 +327,7 @@ /obj/item/toy/plushie ) -//////////////////////////////// -// MARK: MINING GRIPPER -//////////////////////////////// +// Mining Gripper // For mining borgs. Mostly for self-application of goliath armour. /obj/item/gripper/mining name = "mining gripper" @@ -234,9 +338,7 @@ /obj/item/survivalcapsule ) -//////////////////////////////// -// MARK: ENGINEERING GRIPPER -//////////////////////////////// +// Engineering Gripper // For engineering and sabotage borgs, and drones. /obj/item/gripper/engineering name = "engineering gripper" diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e84bdd20be1..5c0a6ba3fa6 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -34,109 +34,3 @@ Keeping it in for adminabuse but the malf one is /obj/item/melee/baton/borg_stun playsound(loc, 'sound/weapons/egloves.ogg', 50, TRUE, -1) add_attack_logs(user, M, "Stunned with [src] ([uppertext(user.a_intent)])") - -#define CYBORG_HUGS 0 -#define CYBORG_HUG 1 -#define CYBORG_SHOCK 2 -#define CYBORG_CRUSH 3 - -/obj/item/borg/cyborghug - name = "hugging module" - icon_state = "hugmodule" - desc = "For when a someone really needs a hug." - var/mode = CYBORG_HUGS //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH - var/ccooldown = 0 - var/scooldown = 0 - var/shockallowed = FALSE //Can it be a stunarm when emagged. Only PK borgs get this by default. - -/obj/item/borg/cyborghug/attack_self(mob/living/user) - if(isrobot(user)) - var/mob/living/silicon/robot/P = user - if(P.emagged && shockallowed) - if(mode < CYBORG_CRUSH) - mode++ - else - mode = CYBORG_HUGS - else if(mode < CYBORG_HUG) - mode++ - else - mode = CYBORG_HUGS - switch(mode) - if(CYBORG_HUGS) - to_chat(user, "Power reset. Hugs!") - if(CYBORG_HUG) - to_chat(user, "Power increased!") - if(CYBORG_SHOCK) - to_chat(user, "BZZT. Electrifying arms...") - if(CYBORG_CRUSH) - to_chat(user, "ERROR: ARM ACTUATORS OVERLOADED.") - -/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user, params) - if(M == user) - return - switch(mode) - if(CYBORG_HUGS) - if(M.health >= 0) - if(isanimal(M) && !M.holder_type) // checks if holder_type exists to prevent picking up animals like mice - var/list/modifiers = params2list(params) - M.attack_hand(user, modifiers) //This enables borgs to get the floating heart icon and mob emote from simple_animal's that have petbonus == true. - return - if(user.zone_selected == BODY_ZONE_HEAD) - user.visible_message("[user] playfully boops [M] on the head!", "You playfully boop [M] on the head!") - user.do_attack_animation(M, ATTACK_EFFECT_BOOP) - playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) - else if(ishuman(M)) - if(M.resting) - user.visible_message("[user] shakes [M] trying to get [M.p_them()] up!", "You shake [M] trying to get [M.p_them()] up!") - M.stand_up() - else - user.visible_message("[user] hugs [M] to make [M.p_them()] feel better!", "You hug [M] to make [M.p_them()] feel better!") - else - user.visible_message("[user] pets [M]!", "You pet [M]!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - if(CYBORG_HUG) - if(M.health >= 0) - if(ishuman(M)) - if(M.resting) - user.visible_message("[user] shakes [M] trying to get [M.p_them()] up!", "You shake [M] trying to get [M.p_them()] up!") - M.resting = FALSE - M.stand_up() - else if(user.zone_selected == BODY_ZONE_HEAD) - user.visible_message("[user] bops [M] on the head!", "You bop [M] on the head!") - user.do_attack_animation(M, ATTACK_EFFECT_PUNCH) - else - user.visible_message("[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...", "You hug [M] firmly to make [M.p_them()] feel better! [M] looks uncomfortable...") - else - user.visible_message("[user] bops [M] on the head!", "You bop [M] on the head!") - playsound(loc, 'sound/weapons/tap.ogg', 50, TRUE, -1) - if(CYBORG_SHOCK) - if(scooldown < world.time) - if(M.health >= 0) - if(ishuman(M)) - M.electrocute_act(5, "[user]", flags = SHOCK_NOGLOVES) - user.visible_message("[user] electrocutes [M] with [user.p_their()] touch!", "You electrocute [M] with your touch!") - else - if(!isrobot(M)) - M.adjustFireLoss(10) - user.visible_message("[user] shocks [M]!", "You shock [M]!") - else - user.visible_message("[user] shocks [M]. It does not seem to have an effect", "You shock [M] to no effect.") - playsound(loc, 'sound/effects/sparks2.ogg', 50, TRUE, -1) - user.cell.use(500) - scooldown = world.time + 20 - if(CYBORG_CRUSH) - if(ccooldown < world.time) - if(M.health >= 0) - if(ishuman(M)) - user.visible_message("[user] crushes [M] in [user.p_their()] grip!", "You crush [M] in your grip!") - else - user.visible_message("[user] crushes [M]!", "You crush [M]!") - playsound(loc, 'sound/weapons/smash.ogg', 50, TRUE, -1) - M.adjustBruteLoss(15) - user.cell.use(300) - ccooldown = world.time + 10 - -#undef CYBORG_HUGS -#undef CYBORG_HUG -#undef CYBORG_SHOCK -#undef CYBORG_CRUSH diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 7ecc75569d7..fd4a98ed73d 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -324,7 +324,8 @@ /obj/item/robot_module/proc/handle_death(mob/living/silicon/robot/R, gibbed) return -// Medical cyborg module. +// MARK: Robot Modules +// Medical /obj/item/robot_module/medical name = "medical robot module" module_type = "Medical" @@ -337,7 +338,6 @@ /obj/item/borg_defib, /obj/item/handheld_defibrillator, /obj/item/roller_holder, - /obj/item/borg/cyborghug, /obj/item/reagent_containers/borghypo, /obj/item/scalpel/laser/laser1, /obj/item/hemostat, @@ -369,20 +369,24 @@ if(G) G.drop_gripped_item(silent = TRUE) -// Disable safeties on the borg's defib. +// Emag the robot's equipment. /obj/item/robot_module/medical/emag_act(mob/user) . = ..() for(var/obj/item/borg_defib/F in modules) F.emag_act() for(var/obj/item/reagent_containers/borghypo/F in modules) F.emag_act() + for(var/obj/item/gripper/F in modules) + F.emag_act() -// Enable safeties on the borg's defib. +// Remove the emagging on the robot's equipment. /obj/item/robot_module/medical/unemag() for(var/obj/item/borg_defib/F in modules) F.emag_act() for(var/obj/item/reagent_containers/borghypo/F in modules) F.emag_act() + for(var/obj/item/gripper/F in modules) + F.emag_act() return ..() /// Malf Syringe Gun @@ -438,7 +442,7 @@ if(emagged) reagents.check_and_add("facid", volume, 2 * coeff) -// Engineering cyborg module. +// Engineering /obj/item/robot_module/engineering name = "engineering robot module" module_type = "Engineer" @@ -485,7 +489,17 @@ if(istype(P)) P.drop_inventory(R) -// Security cyborg module. +/obj/item/robot_module/engineering/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/engineering/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + +// Security /obj/item/robot_module/security name = "security robot module" module_type = "Security" @@ -511,7 +525,7 @@ if(B) B.link_new_cell(unlink_cell) -// Janitor cyborg module. +// Janitor /obj/item/robot_module/janitor name = "janitorial robot module" module_type = "Janitor" @@ -602,7 +616,7 @@ H.KnockDown(4 SECONDS) add_attack_logs(user, H, "Leg swept with cyborg combat broom", ATKLOG_ALL) -// Service cyborg module. +// Service /obj/item/robot_module/butler name = "service robot module" module_type = "Service" @@ -639,6 +653,16 @@ if(istype(T)) T.drop_inventory(R) +/obj/item/robot_module/butler/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/butler/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + // 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 name = "Mickey Finn's Special Brew" @@ -667,6 +691,7 @@ R.add_language("Neo-Russkiya", 1) R.add_language("Tkachi", 1) +// Mining /obj/item/robot_module/miner name = "miner robot module" module_type = "Miner" @@ -698,6 +723,16 @@ if(istype(B)) B.drop_inventory(R) +/obj/item/robot_module/miner/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/miner/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + // 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") @@ -707,138 +742,7 @@ return TRUE return ..() -// Deathsquad cyborg module. -/obj/item/robot_module/deathsquad - name = "NT advanced combat module" - module_type = "Malf" - module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/melee/energy/sword/cyborg, - /obj/item/gun/energy/pulse/cyborg, - /obj/item/crowbar/cyborg/red, - ) - special_rechargables = list(/obj/item/gun/energy/pulse/cyborg) - -// Sydicate assault cyborg module. -/obj/item/robot_module/syndicate - name = "syndicate assault robot module" - module_type = "Malf" // cuz it looks cool - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/melee/energy/sword/cyborg, - /obj/item/gun/energy/printer, - /obj/item/gun/projectile/revolver/grenadelauncher/multi/cyborg, - /obj/item/card/emag, - /obj/item/crowbar/cyborg/red, - /obj/item/pinpointer/operative, - ) - -// Sydicate medical cyborg module. -/obj/item/robot_module/syndicate_medical - name = "syndicate medical robot module" - module_type = "Malf" - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/healthanalyzer/advanced, - /obj/item/reagent_scanner/adv, - /obj/item/bodyanalyzer/borg/syndicate, - /obj/item/borg_defib, - /obj/item/handheld_defibrillator, - /obj/item/roller_holder, - /obj/item/reagent_containers/borghypo/syndicate, - /obj/item/scalpel/laser/laser1, - /obj/item/hemostat, - /obj/item/retractor, - /obj/item/melee/energy/sword/cyborg/saw, //Energy saw -- primary weapon - /obj/item/surgicaldrill, - /obj/item/bonesetter, - /obj/item/bonegel, - /obj/item/FixOVein, - /obj/item/card/emag, - /obj/item/crowbar/cyborg/red, - /obj/item/pinpointer/operative, - /obj/item/stack/medical/bruise_pack/advanced/cyborg/syndicate, - /obj/item/stack/medical/ointment/advanced/cyborg/syndicate, - /obj/item/stack/medical/splint/cyborg/syndicate, - /obj/item/stack/nanopaste/cyborg/syndicate, - /obj/item/gun/medbeam, - /obj/item/extinguisher/mini, - /obj/item/gripper/medical, - ) - special_rechargables = list(/obj/item/extinguisher/mini) - -// Sydicate engineer/sabotuer cyborg module. -/obj/item/robot_module/syndicate_saboteur - name = "saboteur robot module" // Disguises are handled in the actual cyborg projector - module_type = "Malf" - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/rcd/borg/syndicate, - /obj/item/rpd, - /obj/item/extinguisher, - /obj/item/weldingtool/largetank/cyborg, - /obj/item/screwdriver/cyborg, - /obj/item/wrench/cyborg, - /obj/item/crowbar/cyborg, - /obj/item/wirecutters/cyborg, - /obj/item/multitool/cyborg, - /obj/item/t_scanner, - /obj/item/analyzer, - /obj/item/gripper/engineering, - /obj/item/melee/energy/sword/cyborg, - /obj/item/card/emag, - /obj/item/borg_chameleon, - /obj/item/pinpointer/operative, - /obj/item/stack/sheet/metal/cyborg, - /obj/item/stack/rods/cyborg, - /obj/item/stack/tile/plasteel/cyborg, - /obj/item/stack/cable_coil/cyborg, - /obj/item/stack/sheet/glass/cyborg, - /obj/item/stack/sheet/rglass/cyborg - ) - special_rechargables = list(/obj/item/extinguisher, /obj/item/weldingtool/largetank/cyborg) - -/obj/item/robot_module/destroyer - name = "destroyer robot module" - module_type = "Malf" - module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/crowbar/cyborg/red, - /obj/item/gun/energy/immolator/multi/cyborg, // See comments on /robot_module/combat below - /obj/item/melee/baton/loaded, // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats - /obj/item/restraints/handcuffs/cable/zipties/cyborg, - /obj/item/pickaxe/drill/jackhammer, // for breaking walls to execute flanking moves - /obj/item/borg/destroyer/mobility - ) - special_rechargables = list( - /obj/item/melee/baton/loaded, - /obj/item/gun/energy/immolator/multi/cyborg - ) - -/obj/item/robot_module/combat - name = "combat robot module" - module_type = "Malf" - module_actions = list(/datum/action/innate/robot_magpulse) - basic_modules = list( - /obj/item/flash/cyborg, - /obj/item/crowbar/cyborg/red, - /obj/item/gun/energy/immolator/multi/cyborg, // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot. - // Borg gets 40 shots of this weapon. Gamma Sec ERT gets 10. - // So, borg has way more burst damage, but also takes way longer to recharge / get back in the fight once depleted. Has to find a borg recharger and sit in it for ages. - // Organic gamma sec ERT carries alternate weapons, including a box of flashbangs, and can load up on a huge number of guns from science. Borg cannot do either. - // Overall, gamma borg has higher skill floor but lower skill ceiling. - /obj/item/melee/baton/loaded, // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats - /obj/item/restraints/handcuffs/cable/zipties/cyborg, - /obj/item/pickaxe/drill/jackhammer // for breaking walls to execute flanking moves - ) - special_rechargables = list( - /obj/item/melee/baton/loaded, - /obj/item/gun/energy/immolator/multi/cyborg - ) - -// Xenomorph cyborg module. +// Xeno Hunter /obj/item/robot_module/alien/hunter name = "alien hunter module" module_type = "Standard" @@ -859,7 +763,7 @@ . = ..() R.add_language("xenocommon", 1) -// Maintenance drone module. +// Maintenance Drone /obj/item/robot_module/drone name = "drone module" module_type = "Engineer" @@ -900,6 +804,169 @@ if(G) G.drop_gripped_item(silent = TRUE) +/obj/item/robot_module/drone/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/drone/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + +// Sydicate Assault cyborg module. +/obj/item/robot_module/syndicate + name = "syndicate assault robot module" + module_type = "Malf" // cuz it looks cool + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/melee/energy/sword/cyborg, + /obj/item/gun/energy/printer, + /obj/item/gun/projectile/revolver/grenadelauncher/multi/cyborg, + /obj/item/card/emag, + /obj/item/crowbar/cyborg/red, + /obj/item/pinpointer/operative, + ) + +// Sydicate Medical cyborg module. +/obj/item/robot_module/syndicate_medical + name = "syndicate medical robot module" + module_type = "Malf" + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/healthanalyzer/advanced, + /obj/item/reagent_scanner/adv, + /obj/item/bodyanalyzer/borg/syndicate, + /obj/item/borg_defib, + /obj/item/handheld_defibrillator, + /obj/item/roller_holder, + /obj/item/reagent_containers/borghypo/syndicate, + /obj/item/scalpel/laser/laser1, + /obj/item/hemostat, + /obj/item/retractor, + /obj/item/melee/energy/sword/cyborg/saw, //Energy saw -- primary weapon + /obj/item/surgicaldrill, + /obj/item/bonesetter, + /obj/item/bonegel, + /obj/item/FixOVein, + /obj/item/card/emag, + /obj/item/crowbar/cyborg/red, + /obj/item/pinpointer/operative, + /obj/item/stack/medical/bruise_pack/advanced/cyborg/syndicate, + /obj/item/stack/medical/ointment/advanced/cyborg/syndicate, + /obj/item/stack/medical/splint/cyborg/syndicate, + /obj/item/stack/nanopaste/cyborg/syndicate, + /obj/item/gun/medbeam, + /obj/item/extinguisher/mini, + /obj/item/gripper/medical, + ) + special_rechargables = list(/obj/item/extinguisher/mini) + +/obj/item/robot_module/syndicate_medical/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/syndicate_medical/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + +// Sydicate Sabotuer/Engineering cyborg module. +/obj/item/robot_module/syndicate_saboteur + name = "saboteur robot module" // Disguises are handled in the actual cyborg projector + module_type = "Malf" + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/rcd/borg/syndicate, + /obj/item/rpd, + /obj/item/extinguisher, + /obj/item/weldingtool/largetank/cyborg, + /obj/item/screwdriver/cyborg, + /obj/item/wrench/cyborg, + /obj/item/crowbar/cyborg, + /obj/item/wirecutters/cyborg, + /obj/item/multitool/cyborg, + /obj/item/t_scanner, + /obj/item/analyzer, + /obj/item/gripper/engineering, + /obj/item/melee/energy/sword/cyborg, + /obj/item/card/emag, + /obj/item/borg_chameleon, + /obj/item/pinpointer/operative, + /obj/item/stack/sheet/metal/cyborg, + /obj/item/stack/rods/cyborg, + /obj/item/stack/tile/plasteel/cyborg, + /obj/item/stack/cable_coil/cyborg, + /obj/item/stack/sheet/glass/cyborg, + /obj/item/stack/sheet/rglass/cyborg + ) + special_rechargables = list(/obj/item/extinguisher, /obj/item/weldingtool/largetank/cyborg) + +/obj/item/robot_module/syndicate_saboteur/emag_act(mob/user) + . = ..() + for(var/obj/item/gripper/F in modules) + F.emag_act() + +/obj/item/robot_module/syndicate_saboteur/unemag() + for(var/obj/item/gripper/F in modules) + F.emag_act() + return ..() + +// Gamma security module. +/obj/item/robot_module/combat + name = "combat robot module" + module_type = "Malf" + module_actions = list(/datum/action/innate/robot_magpulse) + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/crowbar/cyborg/red, + /obj/item/gun/energy/immolator/multi/cyborg, // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot. + // Borg gets 40 shots of this weapon. Gamma Sec ERT gets 10. + // So, borg has way more burst damage, but also takes way longer to recharge / get back in the fight once depleted. Has to find a borg recharger and sit in it for ages. + // Organic gamma sec ERT carries alternate weapons, including a box of flashbangs, and can load up on a huge number of guns from science. Borg cannot do either. + // Overall, gamma borg has higher skill floor but lower skill ceiling. + /obj/item/melee/baton/loaded, // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats + /obj/item/restraints/handcuffs/cable/zipties/cyborg, + /obj/item/pickaxe/drill/jackhammer // for breaking walls to execute flanking moves + ) + special_rechargables = list( + /obj/item/melee/baton/loaded, + /obj/item/gun/energy/immolator/multi/cyborg + ) + +// Destroyer security module. +/obj/item/robot_module/destroyer + name = "destroyer robot module" + module_type = "Malf" + module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/crowbar/cyborg/red, + /obj/item/gun/energy/immolator/multi/cyborg, // See comments on /robot_module/combat below + /obj/item/melee/baton/loaded, // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats + /obj/item/restraints/handcuffs/cable/zipties/cyborg, + /obj/item/pickaxe/drill/jackhammer, // for breaking walls to execute flanking moves + /obj/item/borg/destroyer/mobility + ) + special_rechargables = list( + /obj/item/melee/baton/loaded, + /obj/item/gun/energy/immolator/multi/cyborg + ) + +// Deathsquad +/obj/item/robot_module/deathsquad + name = "NT advanced combat module" + module_type = "Malf" + module_actions = list(/datum/action/innate/robot_sight/thermal, /datum/action/innate/robot_magpulse) + basic_modules = list( + /obj/item/flash/cyborg, + /obj/item/melee/energy/sword/cyborg, + /obj/item/gun/energy/pulse/cyborg, + /obj/item/crowbar/cyborg/red, + ) + special_rechargables = list(/obj/item/gun/energy/pulse/cyborg) + /// Checks whether this item is a module of the robot it is located in. /obj/item/proc/is_robot_module() if(!isrobot(loc))