diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm
index 25fcbd6c7bd..c06013105a2 100644
--- a/code/datums/ghost_query.dm
+++ b/code/datums/ghost_query.dm
@@ -92,6 +92,13 @@
question = "An Alien has just been created on the facility. Would you like to play as them?"
be_special_flag = BE_ALIEN
+/datum/ghost_query/syndicate_drone
+ role_name = "Mercenary Drone"
+ question = "A team of dubious mercenaries have purchased a powerful drone, and they are attempting to activate it. Would you like to play as the drone?"
+ be_special_flag = BE_AI
+ check_bans = list("AI", "Cyborg", "Syndicate")
+ cutoff_number = 1
+
// Surface stuff.
/datum/ghost_query/lost_drone
role_name = "Lost Drone"
diff --git a/code/datums/uplink/backup.dm b/code/datums/uplink/backup.dm
new file mode 100644
index 00000000000..40f2a468f67
--- /dev/null
+++ b/code/datums/uplink/backup.dm
@@ -0,0 +1,35 @@
+/*********
+* Back up *
+**********/
+/datum/uplink_item/item/backup
+ category = /datum/uplink_category/backup
+ blacklisted = 1
+
+/datum/uplink_item/item/backup/syndicate_drone_protector
+ name = "Drone (Protector)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with a directional shield projector, a supressive fire energy weapon, \
+ a stunbaton, handcuffs, an agent ID, energy sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/protector
+
+/datum/uplink_item/item/backup/syndicate_drone_combat_medic
+ name = "Drone (Combat Medic)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with standard medical equipment, full set of surgery tools, \
+ a powerful hypospray that can create many potent chemicals, an agent ID, energy \
+ sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/combat_medic
+
+/datum/uplink_item/item/backup/syndicate_drone_mechanist
+ name = "Drone (Mechanist)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with a full set of tools, an RCD, the ability to unlock other bound synthetics, \
+ a cryptographic sequencer, an AI detector, the ability to analyze and repair full-body prosthetics, \
+ a set of construction materials, an ionic rapier, an agent ID, energy sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/mechanist
\ No newline at end of file
diff --git a/code/datums/uplink/uplink_categories.dm b/code/datums/uplink/uplink_categories.dm
index 7c65747f0b6..27760855947 100644
--- a/code/datums/uplink/uplink_categories.dm
+++ b/code/datums/uplink/uplink_categories.dm
@@ -49,4 +49,7 @@ datum/uplink_category/ammunition
name = "Highly Visible and Dangerous Weapons"
/datum/uplink_category/telecrystals
- name = "Telecrystals"
\ No newline at end of file
+ name = "Telecrystals"
+
+/datum/uplink_category/backup
+ name = "Backup"
\ No newline at end of file
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 5d67b6eece4..f47e04bbb06 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -263,3 +263,57 @@
icon_state = "pinonfar"
spawn(5) .()
+
+
+// This one only points to the ship. Useful if there is no nuking to occur today.
+/obj/item/weapon/pinpointer/shuttle
+ var/shuttle_comp_id = null
+ var/obj/machinery/computer/shuttle_control/our_shuttle = null
+
+/obj/item/weapon/pinpointer/shuttle/attack_self(mob/user as mob)
+ if(!active)
+ active = TRUE
+ find_shuttle()
+ to_chat(user, "Shuttle Locator active.")
+ else
+ active = FALSE
+ icon_state = "pinoff"
+ to_chat(user, "You deactivate the pinpointer.")
+
+/obj/item/weapon/pinpointer/shuttle/proc/find_shuttle()
+ if(!active)
+ return
+
+ if(!our_shuttle)
+ for(var/obj/machinery/computer/shuttle_control/S in machines)
+ if(S.shuttle_tag == shuttle_comp_id) // Shuttle tags are used so that it will work if the computer path changes, as it does on the southern cross map.
+ our_shuttle = S
+ break
+
+ if(!our_shuttle)
+ icon_state = "pinonnull"
+ return
+
+ if(loc.z != our_shuttle.z) //If you are on a different z-level from the shuttle
+ icon_state = "pinonnull"
+ else
+ set_dir(get_dir(src, our_shuttle))
+ switch(get_dist(src, our_shuttle))
+ if(0)
+ icon_state = "pinondirect"
+ if(1 to 8)
+ icon_state = "pinonclose"
+ if(9 to 16)
+ icon_state = "pinonmedium"
+ if(16 to INFINITY)
+ icon_state = "pinonfar"
+
+ spawn(5)
+ .()
+
+
+/obj/item/weapon/pinpointer/shuttle/merc
+ shuttle_comp_id = "Mercenary"
+
+/obj/item/weapon/pinpointer/shuttle/heist
+ shuttle_comp_id = "Skipjack"
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm
index db9e98a2661..0e550a08b20 100644
--- a/code/game/gamemodes/technomancer/assistance/assistance.dm
+++ b/code/game/gamemodes/technomancer/assistance/assistance.dm
@@ -10,90 +10,6 @@
cost = 300
obj_path = /obj/item/weapon/antag_spawner/technomancer_apprentice
-/obj/item/weapon/antag_spawner
- w_class = ITEMSIZE_TINY
- var/used = 0
- var/ghost_query_type = null
-
-/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T)
- return
-
-/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
- return
-
-/obj/item/weapon/antag_spawner/proc/request_player()
- if(!ghost_query_type)
- return
-
- var/datum/ghost_query/Q = new ghost_query_type()
- var/list/winner = Q.query()
- if(winner.len)
- var/mob/observer/dead/D = winner[1]
- spawn_antag(D.client, get_turf(src))
- else
- reset_search()
- return
-
-/obj/item/weapon/antag_spawner/proc/reset_search()
- return
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice
- name = "apprentice teleporter"
- desc = "A teleportation device, which will bring a less potent manipulator of space to you."
- icon = 'icons/obj/objects.dmi'
- icon_state = "oldshieldoff"
- ghost_query_type = /datum/ghost_query/apprentice
- var/searching = 0
- var/datum/effect/effect/system/spark_spread/sparks
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/New()
- ..()
- sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(5, 0, src)
- sparks.attach(loc)
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/Destroy()
- qdel(sparks)
- return ..()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user)
- user << "Teleporter attempting to lock on to your apprentice."
- request_player()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player()
- searching = 1
- icon_state = "oldshieldon"
- ..()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search()
- searching = 0
- if(!used)
- icon_state = "oldshieldoff"
- visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?")
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T)
- sparks.start()
- var/mob/living/carbon/human/H = new/mob/living/carbon/human(T)
- C.prefs.copy_to(H)
- H.key = C.key
-
- H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]."
- H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \
- of your own. You also have a catalog, to purchase your own functions and equipment as you see fit."
- H << "It would be wise to speak to your master, and learn what their plans are for today."
-
- spawn(1)
- technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0)
- equip_antag(H)
- used = 1
- qdel(src)
-
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob)
- var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER]
- antag_datum.equip_apprentice(technomancer_mob)
-
-
/*
// For when no one wants to play support.
/datum/technomancer/assistance/golem
diff --git a/code/game/objects/items/antag_spawners.dm b/code/game/objects/items/antag_spawners.dm
new file mode 100644
index 00000000000..ce358bc1ee2
--- /dev/null
+++ b/code/game/objects/items/antag_spawners.dm
@@ -0,0 +1,135 @@
+/obj/item/weapon/antag_spawner
+ w_class = ITEMSIZE_TINY
+ var/used = 0
+ var/ghost_query_type = null
+ var/searching = FALSE
+ var/datum/effect/effect/system/spark_spread/sparks
+
+/obj/item/weapon/antag_spawner/New()
+ ..()
+ sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(5, 0, src)
+ sparks.attach(loc)
+
+/obj/item/weapon/antag_spawner/Destroy()
+ qdel(sparks)
+ return ..()
+
+/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T)
+ return
+
+/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
+ return
+
+/obj/item/weapon/antag_spawner/proc/request_player()
+ if(!ghost_query_type)
+ return
+ if(searching)
+ return // Already searching.
+ searching = TRUE
+
+ var/datum/ghost_query/Q = new ghost_query_type()
+ var/list/winner = Q.query()
+ if(winner.len)
+ var/mob/observer/dead/D = winner[1]
+ spawn_antag(D.client, get_turf(src))
+ else
+ reset_search()
+ return
+
+/obj/item/weapon/antag_spawner/proc/reset_search()
+ searching = FALSE
+ return
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice
+ name = "apprentice teleporter"
+ desc = "A teleportation device, which will bring a less potent manipulator of space to you."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "oldshieldoff"
+ ghost_query_type = /datum/ghost_query/apprentice
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user)
+ user << "Teleporter attempting to lock on to your apprentice."
+ request_player()
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player()
+ icon_state = "oldshieldon"
+ ..()
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search()
+ ..()
+ if(!used)
+ icon_state = "oldshieldoff"
+ visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?")
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T)
+ sparks.start()
+ var/mob/living/carbon/human/H = new/mob/living/carbon/human(T)
+ C.prefs.copy_to(H)
+ H.key = C.key
+
+ H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]."
+ H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \
+ of your own. You also have a catalog, to purchase your own functions and equipment as you see fit."
+ H << "It would be wise to speak to your master, and learn what their plans are for today."
+
+ spawn(1)
+ technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0)
+ equip_antag(H)
+ used = 1
+ qdel(src)
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob)
+ var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER]
+ antag_datum.equip_apprentice(technomancer_mob)
+
+
+
+
+/obj/item/weapon/antag_spawner/syndicate_drone
+ name = "drone teleporter"
+ desc = "A teleportation device, which will bring a powerful and loyal drone to you."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "oldshieldoff"
+ ghost_query_type = /datum/ghost_query/syndicate_drone
+ var/drone_type = null
+
+/obj/item/weapon/antag_spawner/syndicate_drone/attack_self(mob/user)
+ to_chat(user, "Teleporter attempting to lock on to an available unit.")
+ request_player()
+
+/obj/item/weapon/antag_spawner/syndicate_drone/request_player()
+ icon_state = "oldshieldon"
+ ..()
+
+/obj/item/weapon/antag_spawner/syndicate_drone/reset_search()
+ ..()
+ if(!used)
+ icon_state = "oldshieldoff"
+ visible_message("The teleporter failed to find any available. Perhaps another attempt could be made later?")
+
+/obj/item/weapon/antag_spawner/syndicate_drone/spawn_antag(client/C, turf/T)
+ sparks.start()
+ var/mob/living/silicon/robot/R = new drone_type(T)
+
+ // Put this text here before ckey change so that their laws are shown below it, since borg login() shows it.
+ to_chat(C, "You are a Mercenary Drone, activated to serve your team.")
+ to_chat(C, "Be sure to examine your currently loaded lawset closely. It would be wise \
+ to speak with your team, and learn what their plan is for today.")
+
+ R.key = C.key
+// R.Namepick() // Apparnetly making someone a merc lets them pick a name, so this isn't needed.
+
+ spawn(1)
+ mercs.add_antagonist(R.mind, FALSE, TRUE, FALSE, FALSE, FALSE)
+ //add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
+ qdel(src)
+
+/obj/item/weapon/antag_spawner/syndicate_drone/protector
+ drone_type = /mob/living/silicon/robot/syndicate/protector
+
+/obj/item/weapon/antag_spawner/syndicate_drone/combat_medic
+ drone_type = /mob/living/silicon/robot/syndicate/combat_medic
+
+/obj/item/weapon/antag_spawner/syndicate_drone/mechanist
+ drone_type = /mob/living/silicon/robot/syndicate/mechanist
\ No newline at end of file
diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm
index b9b8af0c0df..e58f363bc15 100644
--- a/code/game/objects/items/devices/defib.dm
+++ b/code/game/objects/items/devices/defib.dm
@@ -542,6 +542,13 @@
var/mob/living/silicon/robot/R = src.loc
return (R.cell && R.cell.checked_use(charge_amt))
+/obj/item/weapon/shockpaddles/robot/combat
+ name = "combat defibrillator paddles"
+ desc = "A pair of advanced shockpaddles powered by a robot's internal power cell, able to penetrate thick clothing. This version \
+ appears to be optimized for combat situations, foregoing the safety inhabitors in favor of a faster charging time."
+ safety = 0
+ chargetime = (1 SECONDS)
+
/*
Shockpaddles that are linked to a base unit
*/
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index d79f584e2f2..733afcfbcab 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -178,6 +178,9 @@
/obj/item/weapon/rcd/borg
canRwall = 1
+/obj/item/weapon/rcd/borg/lesser
+ canRwall = FALSE
+
/obj/item/weapon/rcd/borg/useResource(var/amount, var/mob/user)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 3cd3d0c96e1..1ea7c154644 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1241,7 +1241,7 @@
W.message = message
W.add_fingerprint(src)
-/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone)
+/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone, var/ignore_thickness = FALSE)
. = 1
if(!target_zone)
@@ -1261,10 +1261,10 @@
else
switch(target_zone)
if(BP_HEAD)
- if(head && head.item_flags & THICKMATERIAL)
+ if(head && (head.item_flags & THICKMATERIAL) && !ignore_thickness)
. = 0
else
- if(wear_suit && wear_suit.item_flags & THICKMATERIAL)
+ if(wear_suit && (wear_suit.item_flags & THICKMATERIAL) && !ignore_thickness)
. = 0
if(!. && error_msg && user)
if(!fail_msg)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
index 2def8149ffd..f769cb29ab2 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
@@ -26,12 +26,13 @@
)
var/id
+// All syndie modules get these, and the base borg items (flash, crowbar, etc).
/obj/item/weapon/robot_module/robot/syndicate/New(var/mob/living/silicon/robot/R)
..()
loc = R
+ src.modules += new /obj/item/weapon/pinpointer/shuttle/merc(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
- src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src)
- src.modules += new /obj/item/weapon/card/emag(src)
+
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
@@ -43,3 +44,141 @@
src.modules -= id
id = null
return ..()
+
+// Gets a big shield and a gun that shoots really fast to scare the opposing force.
+/obj/item/weapon/robot_module/robot/syndicate/protector
+ name = "protector robot module"
+ sprites = list(
+ "Cerberus - Treaded" = "syndie_treadhound",
+ "Cerberus" = "syndie_bloodhound",
+ "Ares" = "squats",
+ "XI-ALP" = "syndi-heavy"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/protector/New(var/mob/living/silicon/robot/R)
+ ..()
+ src.modules += new /obj/item/shield_projector/rectangle/weak(src)
+ src.modules += new /obj/item/weapon/gun/energy/dakkalaser(src)
+ src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
+ src.modules += new /obj/item/weapon/melee/baton/robot(src)
+
+// 95% engi-borg and 15% roboticist.
+/obj/item/weapon/robot_module/robot/syndicate/mechanist
+ name = "mechanist robot module"
+ sprites = list(
+ "XI-GUS" = "spidersyndi",
+ "WTOperator" = "sleekhos"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/mechanist/New(var/mob/living/silicon/robot/R)
+ ..()
+ // General engineering/hacking.
+ src.modules += new /obj/item/borg/sight/meson(src)
+ src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src)
+ src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
+ src.modules += new /obj/item/weapon/wrench/cyborg(src)
+ src.modules += new /obj/item/weapon/wirecutters/cyborg(src)
+ src.modules += new /obj/item/device/multitool/ai_detector(src)
+ src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
+ src.modules += new /obj/item/weapon/rcd/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese.
+ src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier(src)
+
+ // FBP repair.
+ src.modules += new /obj/item/device/robotanalyzer(src)
+ src.modules += new /obj/item/weapon/shockpaddles/robot/jumper(src)
+ src.modules += new /obj/item/weapon/gripper/no_use/organ/robotics(src)
+
+ // Hacking other things.
+ src.modules += new /obj/item/weapon/card/robot(src)
+ src.modules += new /obj/item/weapon/card/emag(src)
+
+ // Materials.
+ var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
+ synths += nanite
+ var/datum/matter_synth/wire = new /datum/matter_synth/wire()
+ synths += wire
+ var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
+ synths += metal
+ var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
+ synths += glass
+
+ var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
+ N.uses_charge = 1
+ N.charge_costs = list(1000)
+ N.synths = list(nanite)
+ src.modules += N
+
+ var/obj/item/stack/material/cyborg/steel/M = new (src)
+ M.synths = list(metal)
+ src.modules += M
+
+ var/obj/item/stack/material/cyborg/glass/G = new (src)
+ G.synths = list(glass)
+ src.modules += G
+
+ var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
+ rods.synths = list(metal)
+ src.modules += rods
+
+ var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
+ C.synths = list(wire)
+ src.modules += C
+
+ var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
+ RG.synths = list(metal, glass)
+ src.modules += RG
+
+
+
+
+// Mediborg optimized for on-the-field healing, but can also do surgery if needed.
+/obj/item/weapon/robot_module/robot/syndicate/combat_medic
+ name = "combat medic robot module"
+ sprites = list(
+ "Telemachus" = "toiletbotantag"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/combat_medic/New(var/mob/living/silicon/robot/R)
+ ..()
+ src.modules += new /obj/item/borg/sight/hud/med(src)
+ src.modules += new /obj/item/device/healthanalyzer(src)
+ src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src)
+
+ // Surgery things.
+ src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/cautery/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/bonegel/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/FixOVein/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/bonesetter/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/surgicaldrill/cyborg(src)
+ src.modules += new /obj/item/weapon/gripper/no_use/organ(src)
+
+ // General healing.
+ src.modules += new /obj/item/weapon/gripper/medical(src)
+ src.modules += new /obj/item/weapon/shockpaddles/robot/combat(src)
+ src.modules += new /obj/item/weapon/reagent_containers/dropper(src) // Allows borg to fix necrosis apparently
+ src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
+ src.modules += new /obj/item/roller_holder(src)
+
+ // Materials.
+ var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
+ synths += medicine
+
+ var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
+ var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
+ var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
+ O.uses_charge = 1
+ O.charge_costs = list(1000)
+ O.synths = list(medicine)
+ B.uses_charge = 1
+ B.charge_costs = list(1000)
+ B.synths = list(medicine)
+ S.uses_charge = 1
+ S.charge_costs = list(1000)
+ S.synths = list(medicine)
+ src.modules += O
+ src.modules += B
+ src.modules += S
diff --git a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
index 9cc09b286a9..d722027ad3e 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
@@ -6,6 +6,7 @@
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/weapon/card/id
+ icon_selected = FALSE
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
index ba6890e835f..281e158a92c 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
@@ -6,6 +6,7 @@
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/weapon/card/id
+ icon_selected = FALSE
/mob/living/silicon/robot/lost/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm
new file mode 100644
index 00000000000..76496f4d4c5
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm
@@ -0,0 +1,46 @@
+/mob/living/silicon/robot/syndicate
+ lawupdate = 0
+ scrambledcodes = 1
+ icon_state = "syndie_bloodhound"
+ modtype = "Syndicate"
+ lawchannel = "State"
+ braintype = "Drone"
+ idcard_type = /obj/item/weapon/card/id/syndicate
+ icon_selected = FALSE
+
+/mob/living/silicon/robot/syndicate/init()
+ aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
+
+ mmi = new /obj/item/device/mmi/digital/robot(src) // Explicitly a drone.
+ overlays.Cut()
+ init_id()
+
+ updatename("Syndicate")
+
+ if(!cell)
+ cell = new /obj/item/weapon/cell/high(src) // 15k cell, because Antag.
+
+ laws = new /datum/ai_laws/syndicate_override()
+
+ radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
+ radio.recalculateChannels()
+
+ playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
+
+/mob/living/silicon/robot/syndicate/protector/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/protector(src)
+ updatename("Protector")
+
+/mob/living/silicon/robot/syndicate/mechanist/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/mechanist(src)
+ updatename("Mechanist")
+
+/mob/living/silicon/robot/syndicate/combat_medic/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/combat_medic(src)
+ updatename("Combat Medic")
+
+/mob/living/silicon/robot/syndicate/speech_bubble_appearance()
+ return "synthetic_evil"
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 46988c99340..d613f1f2062 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -177,4 +177,24 @@ obj/item/weapon/gun/energy/staff/focus
charge_cost = 200
user << "The [src.name] will now strike only a single person."
projectile_type = "/obj/item/projectile/forcebolt"
- */
\ No newline at end of file
+ */
+
+/obj/item/weapon/gun/energy/dakkalaser
+ name = "suppression gun"
+ desc = "A massive weapon, designed to pressure the opposition by raining down a torrent of energy pellets."
+ icon_state = "dakkalaser"
+ item_state = "dakkalaser"
+ fire_sound = 'sound/weapons/Laser.ogg'
+ w_class = ITEMSIZE_HUGE
+ charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon.
+ projectile_type = /obj/item/projectile/energy/blue_pellet
+ self_recharge = 1
+ accuracy = 5 // Suppressive weapons don't work too well if there's no risk of being hit.
+ burst_delay = 1 // Burst faster than average.
+ origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6)
+
+ firemodes = list(
+ list(mode_name="single shot", burst = 1, burst_accuracy = list(5), dispersion = list(0), charge_cost = 24),
+ list(mode_name="five shot burst", burst = 5, burst_accuracy = list(5,5,5,5,5), dispersion = list(1,1,1,1,1)),
+ list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
+ )
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 42be84f2ac0..dbc54fc4325 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -182,4 +182,17 @@
/obj/item/projectile/energy/plasmastun/on_hit(var/atom/target)
bang(target)
- . = ..()
\ No newline at end of file
+ . = ..()
+
+/obj/item/projectile/energy/blue_pellet
+ name = "suppressive pellet"
+ icon_state = "blue_pellet"
+ damage = 5
+ armor_penetration = 75
+ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ damage_type = BURN
+ check_armour = "energy"
+ light_color = "#0000FF"
+
+ embed_chance = 0
+ muzzle_type = /obj/effect/projectile/pulse/muzzle
\ No newline at end of file
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 8cfb75e20cb..8d09b903b6b 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -691,4 +691,21 @@
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
- to_chat(M, "You feel invigorated and calm.")
\ No newline at end of file
+ to_chat(M, "You feel invigorated and calm.")
+
+// This exists to cut the number of chemicals a merc borg has to juggle on their hypo.
+/datum/reagent/healing_nanites
+ name = "Restorative Nanites"
+ id = "healing_nanites"
+ description = "Miniature medical robots that swiftly restore bodily damage."
+ taste_description = "metal"
+ reagent_state = SOLID
+ color = "#555555"
+ metabolism = REM * 4 // Nanomachines gotta go fast.
+ scannable = 1
+
+/datum/reagent/healing_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ M.heal_organ_damage(2 * removed, 2 * removed)
+ M.adjustOxyLoss(-4 * removed)
+ M.adjustToxLoss(-2 * removed)
+ M.adjustCloneLoss(-2 * removed)
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 5c4a6bdce60..d0cd3cf9e60 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -12,6 +12,7 @@
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
+ var/bypass_protection = FALSE // If true, can inject through things like spacesuits and armor.
var/list/reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
var/list/reagent_volumes = list()
@@ -26,6 +27,13 @@
/obj/item/weapon/reagent_containers/borghypo/lost
reagent_ids = list("tricordrazine", "bicaridine", "dexalin", "anti_toxin", "tramadol", "spaceacillin")
+/obj/item/weapon/reagent_containers/borghypo/merc
+ name = "advanced cyborg hypospray"
+ desc = "An advanced nanite and chemical synthesizer and injection system, designed for heavy-duty medical equipment. This type is capable of safely bypassing \
+ thick materials that other hyposprays would struggle with."
+ bypass_protection = TRUE // Because mercs tend to be in spacesuits.
+ reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine")
+
/obj/item/weapon/reagent_containers/borghypo/New()
..()
@@ -72,7 +80,7 @@
user << "You cannot inject a robotic limb."
return
- if (M.can_inject(user, 1))
+ if(M.can_inject(user, 1, ignore_thickness = bypass_protection))
user << "You inject [M] with the injector."
M << "You feel a tiny prick!"
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index d32d479e3fb..35e6df449f8 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index 1550d6bf4b7..e037ce6f9b8 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 8af7372321f..90d6dcd1ea9 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/polaris.dme b/polaris.dme
index 737a2910cbb..1856f771ff8 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -279,6 +279,7 @@
#include "code\datums\uplink\ammunition.dm"
#include "code\datums\uplink\announcements.dm"
#include "code\datums\uplink\armor.dm"
+#include "code\datums\uplink\backup.dm"
#include "code\datums\uplink\badassery.dm"
#include "code\datums\uplink\grenades.dm"
#include "code\datums\uplink\hardsuit_modules.dm"
@@ -795,6 +796,7 @@
#include "code\game\objects\effects\decals\posters\polarisposters.dm"
#include "code\game\objects\effects\spawners\bombspawner.dm"
#include "code\game\objects\effects\spawners\gibspawner.dm"
+#include "code\game\objects\items\antag_spawners.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\bodybag.dm"
@@ -1774,7 +1776,6 @@
#include "code\modules\mob\living\silicon\robot\robot_damage.dm"
#include "code\modules\mob\living\silicon\robot\robot_items.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\drone\drone.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm"
@@ -1787,6 +1788,7 @@
#include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
+#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
#include "code\modules\mob\living\simple_animal\aliens\alien.dm"