diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index ca59a03fd35..c4a20fbd29b 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -552,7 +552,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous/syndieborg name = "Syndicate Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel." + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. Comes in Assault, Medical, or Saboteur variants." reference = "SC" item = /obj/item/antag_spawner/borg_tele refund_path = /obj/item/antag_spawner/borg_tele diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 7a25f4ece1b..27132b75346 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -45,7 +45,7 @@ eject_all() playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6) QDEL_NULL(active_dummy) - to_chat(usr, "You deactivate \the [src].") + to_chat(usr, "You deactivate [src].") var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) T.icon = 'icons/effects/effects.dmi' flick("emppulse",T) @@ -58,7 +58,7 @@ var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc) C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, saved_underlays, src) qdel(O) - to_chat(usr, "You activate \the [src].") + to_chat(usr, "You activate [src].") var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src)) T.icon = 'icons/effects/effects.dmi' flick("emppulse",T) @@ -148,3 +148,102 @@ /obj/effect/dummy/chameleon/Destroy() master.disrupt(0) return ..() + +/obj/item/borg_chameleon + name = "cyborg chameleon projector" + icon = 'icons/obj/device.dmi' + icon_state = "shield0" + item_state = "electronic" + w_class = WEIGHT_CLASS_SMALL + var/active = FALSE + var/activationCost = 300 + var/activationUpkeep = 50 + var/disguise = "landmate" + var/mob/living/silicon/robot/syndicate/saboteur/S + +/obj/item/borg_chameleon/Destroy() + if(S) + S.cham_proj = null + return ..() + +/obj/item/borg_chameleon/dropped(mob/user) + . = ..() + disrupt(user) + +/obj/item/borg_chameleon/equipped(mob/user) + . = ..() + disrupt(user) + +/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/syndicate/saboteur/user) + if(user && user.cell && user.cell.charge > activationCost) + if(isturf(user.loc)) + toggle(user) + else + to_chat(user, "You can't use [src] while inside something!") + else + to_chat(user, "You need at least [activationCost] charge in your cell to use [src]!") + +/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/syndicate/saboteur/user) + if(active) + playsound(src, 'sound/effects/pop.ogg', 100, 1, -6) + to_chat(user, "You deactivate [src].") + deactivate(user) + else + to_chat(user, "You activate [src].") + var/start = user.filters.len + var/X + var/Y + var/rsq + var/i + var/f + for(i in 1 to 7) + do + X = 60 * rand() - 30 + Y = 60 * rand() - 30 + rsq = X * X + Y * Y + while(rsq < 100 || rsq > 900) + user.filters += filter(type = "wave", x = X, y = Y, size = rand() * 2.5 + 0.5, offset = rand()) + for(i in 1 to 7) + f = user.filters[start+i] + animate(f, offset = f:offset, time = 0, loop = 3, flags = ANIMATION_PARALLEL) + animate(offset = f:offset - 1, time = rand() * 20 + 10) + if(do_after(user, 50, target = user) && user.cell.use(activationCost)) + playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6) + to_chat(user, "You are now disguised as a Nanotrasen engineering cyborg.") + activate(user) + else + to_chat(user, "The chameleon field fizzles.") + do_sparks(3, FALSE, user) + for(i in 1 to min(7, user.filters.len)) // removing filters that are animating does nothing, we gotta stop the animations first + f = user.filters[start + i] + animate(f) + user.filters = null + +/obj/item/borg_chameleon/process() + if(S) + if(!S.cell || !S.cell.use(activationUpkeep)) + disrupt(S) + else + return PROCESS_KILL + +/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/syndicate/saboteur/user) + processing_objects.Add(src) + S = user + user.base_icon = disguise + user.icon_state = disguise + user.cham_proj = src + active = TRUE + user.update_icons() + +/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/syndicate/saboteur/user) + processing_objects.Remove(src) + S = user + user.base_icon = initial(user.base_icon) + user.icon_state = initial(user.icon_state) + active = FALSE + user.update_icons() + +/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/syndicate/saboteur/user) + if(active) + to_chat(user, "Your chameleon field deactivates.") + deactivate(user) diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index e4624a00ba6..2bf94ff465a 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -456,20 +456,24 @@ GLOBAL_LIST_INIT(rcd_door_types, list( /obj/item/rcd/proc/checkResource(amount, mob/user) return matter >= amount +/obj/item/rcd/borg + canRwall = 1 + var/use_multiplier = 160 + +/obj/item/rcd/borg/syndicate + use_multiplier = 80 + /obj/item/rcd/borg/useResource(amount, mob/user) if(!isrobot(user)) return 0 var/mob/living/silicon/robot/R = user - return R.cell.use(amount * 160) + return R.cell.use(amount * use_multiplier) /obj/item/rcd/borg/checkResource(amount, mob/user) if(!isrobot(user)) return 0 var/mob/living/silicon/robot/R = user - return R.cell.charge >= (amount * 160) - -/obj/item/rcd/borg - canRwall = 1 + return R.cell.charge >= (amount * use_multiplier) /obj/item/rcd/proc/detonate_pulse() audible_message("[src] begins to vibrate and \ diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 80a62f9c818..c8809ed98bf 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -19,7 +19,7 @@ var/checking = FALSE var/TC_cost = 0 var/borg_to_spawn - var/list/possible_types = list("Assault", "Medical") + var/list/possible_types = list("Assault", "Medical", "Saboteur") /obj/item/antag_spawner/borg_tele/attack_self(mob/user) if(used) @@ -43,6 +43,7 @@ var/mob/M = pick(borg_candidates) var/client/C = M.client spawn_antag(C, get_turf(src.loc), "syndieborg") + qdel(src) else checking = FALSE to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.") @@ -57,6 +58,8 @@ switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/syndicate/medical(T) + else if("Saboteur") + R = new /mob/living/silicon/robot/syndicate/saboteur(T) else R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default R.key = C.key diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2f4056f6149..a546e299cd6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1293,61 +1293,6 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) - - -/mob/living/silicon/robot/syndicate - base_icon = "syndie_bloodhound" - icon_state = "syndie_bloodhound" - lawupdate = 0 - scrambledcodes = 1 - pdahide = 1 - faction = list("syndicate") - designation = "Syndicate Assault" - modtype = "Syndicate" - req_access = list(access_syndicate) - ionpulse = 1 - magpulse = 1 - lawchannel = "State" - var/playstyle_string = "You are a Syndicate assault cyborg!
\ - You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ - Your cyborg LMG will slowly produce ammunition from your power supply, and your operative pinpointer will find and locate fellow nuclear operatives. \ - Help the operatives secure the disk at all costs!" - -/mob/living/silicon/robot/syndicate/New(loc) - ..() - cell.maxcharge = 25000 - cell.charge = 25000 - -/mob/living/silicon/robot/syndicate/init() - laws = new /datum/ai_laws/syndicate_override - module = new /obj/item/robot_module/syndicate(src) - - aiCamera = new/obj/item/camera/siliconcam/robot_camera(src) - radio = new /obj/item/radio/borg/syndicate(src) - radio.recalculateChannels() - - spawn(5) - if(playstyle_string) - to_chat(src, playstyle_string) - - playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) - -/mob/living/silicon/robot/syndicate/medical - base_icon = "syndi-medi" - icon_state = "syndi-medi" - modtype = "Syndicate Medical" - designation = "Syndicate Medical" - playstyle_string = "You are a Syndicate medical cyborg!
\ - You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ - Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \ - Your defibrillator paddles can revive operatives through their hardsuits, or can be used on harm intent to shock enemies! \ - Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \ - Help the operatives secure the disk at all costs!" - -/mob/living/silicon/robot/syndicate/medical/init() - ..() - module = new /obj/item/robot_module/syndicate_medical(src) - /mob/living/silicon/robot/combat base_icon = "droidcombat" icon_state = "droidcombat" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 2330d0ecd64..ee0cf0db06f 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -432,6 +432,46 @@ fix_modules() +/obj/item/robot_module/syndicate_saboteur + name = "engineering robot module" //to disguise in examine + module_type = "Malf" + + stacktypes = list( + /obj/item/stack/sheet/metal/cyborg = 50, + /obj/item/stack/sheet/glass/cyborg = 50, + /obj/item/stack/sheet/rglass/cyborg = 50, + /obj/item/stack/cable_coil/cyborg = 50, + /obj/item/stack/rods/cyborg = 60, + /obj/item/stack/tile/plasteel = 20 + ) + +/obj/item/robot_module/syndicate_saboteur/New() + ..() + modules += new /obj/item/rcd/borg/syndicate(src) + modules += new /obj/item/rpd(src) + modules += new /obj/item/extinguisher(src) + modules += new /obj/item/weldingtool/largetank/cyborg(src) + modules += new /obj/item/screwdriver/cyborg(src) + modules += new /obj/item/wrench/cyborg(src) + modules += new /obj/item/crowbar/cyborg(src) + modules += new /obj/item/wirecutters/cyborg(src) + modules += new /obj/item/multitool/cyborg(src) + modules += new /obj/item/t_scanner(src) + modules += new /obj/item/analyzer(src) + modules += new /obj/item/gripper(src) + modules += new /obj/item/melee/energy/sword/cyborg(src) + modules += new /obj/item/card/emag(src) + modules += new /obj/item/borg_chameleon(src) + modules += new /obj/item/pinpointer/operative(src) + emag = null + + for(var/T in stacktypes) + var/obj/item/stack/sheet/W = new T(src) + W.amount = stacktypes[T] + modules += W + + fix_modules() + /obj/item/robot_module/combat name = "combat robot module" module_type = "Malf" diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm new file mode 100644 index 00000000000..48179e8d374 --- /dev/null +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -0,0 +1,149 @@ +/mob/living/silicon/robot/syndicate + base_icon = "syndie_bloodhound" + icon_state = "syndie_bloodhound" + lawupdate = 0 + scrambledcodes = 1 + pdahide = 1 + faction = list("syndicate") + designation = "Syndicate Assault" + modtype = "Syndicate" + req_access = list(access_syndicate) + ionpulse = 1 + magpulse = 1 + lawchannel = "State" + var/playstyle_string = "You are a Syndicate assault cyborg!
\ + You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ + Your cyborg LMG will slowly produce ammunition from your power supply, and your operative pinpointer will find and locate fellow nuclear operatives. \ + Help the operatives secure the disk at all costs!" + +/mob/living/silicon/robot/syndicate/New(loc) + ..() + cell.maxcharge = 25000 + cell.charge = 25000 + +/mob/living/silicon/robot/syndicate/init() + laws = new /datum/ai_laws/syndicate_override + module = new /obj/item/robot_module/syndicate(src) + + aiCamera = new/obj/item/camera/siliconcam/robot_camera(src) + radio = new /obj/item/radio/borg/syndicate(src) + radio.recalculateChannels() + + spawn(5) + if(playstyle_string) + to_chat(src, playstyle_string) + + playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) + +/mob/living/silicon/robot/syndicate/medical + base_icon = "syndi-medi" + icon_state = "syndi-medi" + modtype = "Syndicate Medical" + designation = "Syndicate Medical" + playstyle_string = "You are a Syndicate medical cyborg!
\ + You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ + Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \ + Your defibrillator paddles can revive operatives through their hardsuits, or can be used on harm intent to shock enemies! \ + Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \ + Help the operatives secure the disk at all costs!" + +/mob/living/silicon/robot/syndicate/medical/init() + ..() + module = new /obj/item/robot_module/syndicate_medical(src) + +/mob/living/silicon/robot/syndicate/saboteur + base_icon = "syndi-engi" + icon_state = "syndi-engi" + modtype = "Syndicate Saboteur" + designation = "Syndicate Saboteur" + var/mail_destination = 0 + var/obj/item/borg_chameleon/cham_proj = null + playstyle_string = "You are a Syndicate saboteur cyborg!
\ + You are equipped with robust engineering tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ + Your built-in mail tagger will allow you to stealthily traverse the disposal network across the station. \ + Your cyborg chameleon projector allows you to assume the appearance of a Nanotrasen engineering cyborg, and undertake covert actions on the station. \ + You are able to hijack Nanotrasen cyborgs by emagging their internal components, make sure to flash them first. \ + You are armed with a standard energy sword, use it to ambush key targets if needed. Your pinpointer will let you locate fellow nuclear operatives to regroup.\ + Be aware that physical contact or taking damage will break your disguise. \ + Help the operatives secure the disk at all costs!" + +/mob/living/silicon/robot/syndicate/saboteur/init() + ..() + module = new /obj/item/robot_module/syndicate_saboteur(src) + var/obj/item/borg/upgrade/selfrepair/SR = new /obj/item/borg/upgrade/selfrepair(src) + SR.cyborg = src + SR.icon_state = "selfrepair_off" + var/datum/action/A = new /datum/action/item_action/toggle(SR) + A.Grant(src) + +/mob/living/silicon/robot/syndicate/saboteur/verb/modify_name() + set name = "Modify Name" + set desc = "Change your systems' registered name to fool Nanotrasen systems. No cost." + set category = "Saboteur" + rename_self(braintype, TRUE, TRUE) + +/mob/living/silicon/robot/syndicate/saboteur/verb/toggle_chameleon() + set name = "Toggle Chameleon Projector" + set desc = "Change your appearance to a Nanotrasen cyborg. Costs power to use and maintain." + set category = "Saboteur" + if(!cham_proj) + for(var/obj/item/borg_chameleon/C in contents) + cham_proj = C + for(var/obj/item/borg_chameleon/C in module.contents) + cham_proj = C + if(!cham_proj) + to_chat(src, "Error : No chameleon projector system found.") + return + cham_proj.attack_self(src) + +/mob/living/silicon/robot/syndicate/saboteur/verb/set_mail_tag() + set name = "Set Mail Tag" + set desc = "Tag yourself for delivery through the disposals system." + set category = "Saboteur" + + var/tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in GLOB.TAGGERLOCATIONS + + if(!tag || GLOB.TAGGERLOCATIONS[tag]) + mail_destination = 0 + return + + to_chat(src, "You configure your internal beacon, tagging yourself for delivery to '[tag]'.") + mail_destination = GLOB.TAGGERLOCATIONS.Find(tag) + + //Auto flush if we use this verb inside a disposal chute. + var/obj/machinery/disposal/D = src.loc + if(istype(D)) + to_chat(src, "\The [D] acknowledges your signal.") + D.flush_count = D.flush_every_ticks + + return + +/mob/living/silicon/robot/syndicate/saboteur/attackby() + if(cham_proj) + cham_proj.disrupt(src) + ..() + +/mob/living/silicon/robot/syndicate/saboteur/attack_hand() + if(cham_proj) + cham_proj.disrupt(src) + ..() + +/mob/living/silicon/robot/syndicate/saboteur/ex_act() + if(cham_proj) + cham_proj.disrupt(src) + ..() + +/mob/living/silicon/robot/syndicate/saboteur/emp_act() + if(cham_proj) + cham_proj.disrupt(src) + ..() + +/mob/living/silicon/robot/syndicate/saboteur/bullet_act() + if(cham_proj) + cham_proj.disrupt(src) + ..() + +/mob/living/silicon/robot/syndicate/saboteur/attackby() + if(cham_proj) + cham_proj.disrupt(src) + ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 46b7d1141b8..8115e4d9ff0 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -560,7 +560,7 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) objective.explanation_text = copytext(objective.explanation_text, 1, pos)+newname+copytext(objective.explanation_text, pos+length) return 1 -/mob/proc/rename_self(var/role, var/allow_numbers=0) +/mob/proc/rename_self(var/role, var/allow_numbers = FALSE, var/force = FALSE) spawn(0) var/oldname = real_name @@ -568,8 +568,11 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) var/newname for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name. - newname = input(src, "You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname) as text - if((world.time - time_passed) > 1800) + if(force) + newname = input(src, "Pick a new name.", "Name Change", oldname) as text + else + newname = input(src, "You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname) as text + if(((world.time - time_passed) > 1800) && !force) alert(src, "Unfortunately, more than 3 minutes have passed for selecting your name. If you are a robot, use the Namepick verb; otherwise, adminhelp.", "Name Change") return //took too long newname = reject_bad_name(newname,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index d0007ab7266..ef002caa1ec 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -417,6 +417,9 @@ for(var/mob/living/silicon/robot/drone/D in src) wrapcheck = 1 + for(var/mob/living/silicon/robot/syndicate/saboteur/R in src) + wrapcheck = 1 + for(var/obj/item/smallDelivery/O in src) wrapcheck = 1 @@ -461,7 +464,7 @@ AM.loc = src.loc AM.pipe_eject(0) - if(!istype(AM,/mob/living/silicon/robot/drone)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z + if(!istype(AM, /mob/living/silicon/robot/drone) && !istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z spawn(1) if(AM) AM.throw_at(target, 5, 1) @@ -523,7 +526,7 @@ //Check for any living mobs trigger hasmob. //hasmob effects whether the package goes to cargo or its tagged destination. for(var/mob/living/M in D) - if(M && M.stat != 2 && !istype(M,/mob/living/silicon/robot/drone)) + if(M && M.stat != 2 && !istype(M, /mob/living/silicon/robot/drone) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) hasmob = 1 //Checks 1 contents level deep. This means that players can be sent through disposals... @@ -531,7 +534,7 @@ for(var/obj/O in D) if(O.contents) for(var/mob/living/M in O.contents) - if(M && M.stat != 2 && !istype(M,/mob/living/silicon/robot/drone)) + if(M && M.stat != 2 && !istype(M,/mob/living/silicon/robot/drone) && !istype(M, /mob/living/silicon/robot/syndicate/saboteur)) hasmob = 1 // now everything inside the disposal gets put into the holder @@ -553,6 +556,9 @@ if(istype(AM, /mob/living/silicon/robot/drone)) var/mob/living/silicon/robot/drone/drone = AM destinationTag = drone.mail_destination + if(istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) + var/mob/living/silicon/robot/syndicate/saboteur/S = AM + destinationTag = S.mail_destination if(istype(AM, /obj/item/shippingPackage) && !hasmob) var/obj/item/shippingPackage/sp = AM if(sp.sealed) //only sealed packages get delivered to their intended destination @@ -1304,7 +1310,7 @@ for(var/atom/movable/AM in contents) AM.forceMove(loc) AM.pipe_eject(dir) - if(istype(AM,/mob/living/silicon/robot/drone)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z + if(istype(AM,/mob/living/silicon/robot/drone) || istype(AM, /mob/living/silicon/robot/syndicate/saboteur)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z return spawn(5) if(QDELETED(AM)) diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index 653dfd5dfa9..eb59b0288b3 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/paradise.dme b/paradise.dme index 49a3b73ee07..2eb1c792e56 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1798,6 +1798,7 @@ #include "code\modules\mob\living\silicon\robot\robot_module_actions.dm" #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" +#include "code\modules\mob\living\silicon\robot\syndicate.dm" #include "code\modules\mob\living\silicon\robot\update_status.dm" #include "code\modules\mob\living\silicon\robot\drone\drone.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"