diff --git a/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm b/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm
index f8be6a5fccc..82bb62e0908 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm
@@ -214,7 +214,7 @@
},
/area/ruin/space/tcommsat)
"lq" = (
-/obj/effect/spawner/random/pool/spaceloot/modsuit_syndie,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit,
/turf/simulated/floor/plating/airless,
/area/ruin/space/tcommsat)
"my" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm b/_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm
index 022a9a203e1..2ffe30eefbb 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm
@@ -22,7 +22,7 @@
/turf/template_noop,
/area/template_noop)
"af" = (
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space,
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup,
/turf/template_noop,
/area/template_noop)
"ag" = (
@@ -126,7 +126,7 @@
/area/ruin)
"aW" = (
/obj/structure/lattice,
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space,
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup,
/turf/template_noop,
/area/template_noop)
"aY" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm b/_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm
index bd07b50dc38..466e24b7cc3 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm
@@ -141,7 +141,7 @@
/turf/template_noop,
/area/template_noop)
"U" = (
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space,
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup,
/turf/template_noop,
/area/template_noop)
"V" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm b/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
index 7474a3c3748..f8ac4b5cfe7 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm
@@ -442,9 +442,7 @@
/area/ruin/space/syndicate_listening_station)
"Go" = (
/obj/structure/chair/office/dark,
-/mob/living/simple_animal/hostile/syndicate{
- name = "Syndicate Communications Officer"
- },
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/syndicate_listening_station)
"Gy" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/submaps/sieged_lab_submaps.dmm b/_maps/map_files/RandomRuins/SpaceRuins/submaps/sieged_lab_submaps.dmm
index 8b066c4298f..f0fab13debe 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/submaps/sieged_lab_submaps.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/submaps/sieged_lab_submaps.dmm
@@ -17,7 +17,7 @@
/area/template_noop)
"ax" = (
/obj/effect/map_effect/marker/mapmanip/submap/extract/ruin/sieged_lab/horiz_hallway,
-/mob/living/simple_animal/hostile/syndicate/melee,
+/mob/living/simple_animal/hostile/syndicate,
/turf/template_noop,
/area/template_noop)
"aK" = (
@@ -1625,7 +1625,7 @@
/turf/template_noop,
/area/template_noop)
"GI" = (
-/mob/living/simple_animal/hostile/syndicate/melee,
+/mob/living/simple_animal/hostile/syndicate,
/turf/simulated/floor/plasteel{
icon_state = "white"
},
@@ -1660,7 +1660,7 @@
/turf/simulated/floor/plating,
/area/template_noop)
"Hq" = (
-/mob/living/simple_animal/hostile/syndicate/melee,
+/mob/living/simple_animal/hostile/syndicate,
/turf/simulated/floor/plating,
/area/template_noop)
"HF" = (
@@ -2146,7 +2146,7 @@
},
/area/template_noop)
"Uq" = (
-/mob/living/simple_animal/hostile/syndicate/melee,
+/mob/living/simple_animal/hostile/syndicate,
/turf/template_noop,
/area/template_noop)
"UH" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm
index 63cc3040fdd..dc8db2a6f14 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm
@@ -142,7 +142,7 @@
/turf/template_noop,
/area/ruin/space/syndicate_druglab/asteroid)
"st" = (
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob,
/turf/simulated/floor/pod/dark,
/area/ruin/space/syndicate_druglab)
"sD" = (
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm
index 2ab0ea1a3a9..4ce36fd5684 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm
@@ -742,7 +742,7 @@
/area/template_noop)
"CR" = (
/obj/structure/chair/office/dark,
-/obj/effect/spawner/random/pool/spaceloot/modsuit_syndie,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob,
/turf/simulated/floor/engine,
/area/ruin/space/syndicakefactory)
"CW" = (
@@ -803,7 +803,7 @@
},
/area/ruin/space/syndicakefactory)
"EH" = (
-/obj/effect/mob_spawn/human/corpse/syndicatesoldier,
+/obj/effect/mob_spawn/human/corpse/syndicate,
/turf/simulated/floor/plasteel{
icon_state = "cafeteria"
},
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm
index f2d247630ed..cdcdf7e822e 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm
@@ -481,7 +481,7 @@
},
/area/syndicate_depot/core)
"bC" = (
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer,
+/mob/living/simple_animal/hostile/syndicate/depot/officer,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -838,7 +838,7 @@
/obj/machinery/atmospherics/pipe/simple/hidden{
dir = 4
},
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory,
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
@@ -879,7 +879,7 @@
/obj/machinery/atmospherics/unary/passive_vent/high_volume{
dir = 8
},
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer,
+/mob/living/simple_animal/hostile/syndicate/depot/officer,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm b/_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm
index ae5b9c8337d..203d8aea28a 100644
--- a/_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm
+++ b/_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm
@@ -40,11 +40,6 @@
/obj/item/clothing/mask/gas/syndicate,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/turreted_outpost/vault)
-"eg" = (
-/obj/structure/chair/comfy/red,
-/mob/living/simple_animal/hostile/syndicate/ranged,
-/turf/simulated/floor/plasteel/dark,
-/area/ruin/space/turreted_outpost)
"eh" = (
/obj/structure/cable/yellow{
icon_state = "1-8"
@@ -190,7 +185,7 @@
/obj/structure/cable{
icon_state = "4-8"
},
-/mob/living/simple_animal/hostile/syndicate/ranged,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/turreted_outpost)
"sp" = (
@@ -249,8 +244,8 @@
/turf/simulated/floor/plasteel/freezer,
/area/ruin/space/turreted_outpost)
"wW" = (
-/mob/living/simple_animal/hostile/syndicate/ranged,
/obj/structure/chair/comfy/red,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/turreted_outpost)
"xd" = (
@@ -322,10 +317,10 @@
/obj/structure/chair{
dir = 8
},
-/mob/living/simple_animal/hostile/syndicate/melee/autogib,
/obj/structure/cable{
icon_state = "1-2"
},
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/turreted_outpost)
"Cp" = (
@@ -375,7 +370,7 @@
/area/ruin/space/turreted_outpost)
"Fz" = (
/obj/structure/chair/comfy/red,
-/mob/living/simple_animal/hostile/syndicate/melee/autogib,
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit,
/turf/simulated/floor/plasteel/dark,
/area/ruin/space/turreted_outpost)
"Gd" = (
@@ -1129,7 +1124,7 @@ iq
qa
Ja
QB
-eg
+wW
HH
Ub
qK
diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm
index 79b2dcc3ab7..c58f741a19c 100644
--- a/code/datums/outfits/outfit_admin.dm
+++ b/code/datums/outfits/outfit_admin.dm
@@ -92,7 +92,7 @@
l_hand = /obj/item/tank/internals/oxygen/red
backpack_contents = list(
- /obj/item/storage/box/survival_syndi = 1,
+ /obj/item/storage/box/survival_syndie = 1,
/obj/item/gun/projectile/automatic/pistol = 1,
/obj/item/ammo_box/magazine/m10mm = 1,
/obj/item/crowbar/red = 1,
diff --git a/code/game/area/areas/depot-areas.dm b/code/game/area/areas/depot-areas.dm
index 52def39ba0d..7b047a22b06 100644
--- a/code/game/area/areas/depot-areas.dm
+++ b/code/game/area/areas/depot-areas.dm
@@ -254,7 +254,7 @@
var/obj/effect/landmark/L = thing
if(prob(50))
if(L.name == "syndi_depot_backup")
- var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/S = new /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space(get_turf(L))
+ var/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup/S = new /mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup(get_turf(L))
S.name = "Syndicate Backup " + "([rand(1, 1000)])"
S.depotarea = src
list_add(S, guard_list)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 99be8d840c2..ce855240606 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -281,7 +281,7 @@
synd_mob.equip_to_slot_or_del(new /obj/item/card/id/syndicate(synd_mob), ITEM_SLOT_ID)
synd_mob.equip_to_slot_or_del(new back(synd_mob), ITEM_SLOT_BACK)
synd_mob.equip_to_slot_or_del(new /obj/item/gun/projectile/automatic/pistol(synd_mob), ITEM_SLOT_BELT)
- synd_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival_syndi(synd_mob.back), ITEM_SLOT_IN_BACKPACK)
+ synd_mob.equip_to_slot_or_del(new /obj/item/storage/box/survival_syndie(synd_mob.back), ITEM_SLOT_IN_BACKPACK)
synd_mob.equip_to_slot_or_del(new /obj/item/pinpointer/nukeop(synd_mob), ITEM_SLOT_PDA)
var/obj/item/radio/uplink/nuclear/U = new /obj/item/radio/uplink/nuclear(synd_mob)
U.hidden_uplink.uplink_owner="[synd_mob.key]"
diff --git a/code/game/jobs/job/syndicate_jobs.dm b/code/game/jobs/job/syndicate_jobs.dm
index 68a462ccc48..99418e9aa27 100644
--- a/code/game/jobs/job/syndicate_jobs.dm
+++ b/code/game/jobs/job/syndicate_jobs.dm
@@ -28,7 +28,7 @@
l_ear = /obj/item/radio/headset/syndicate/alt/syndteam
pda = /obj/item/pinpointer/advpinpointer
id = /obj/item/card/id/syndicate/command
- box = /obj/item/storage/box/survival_syndi
+ box = /obj/item/storage/box/survival_syndie
backpack_contents = list(
/obj/item/flashlight = 1,
/obj/item/ammo_box/magazine/m50 = 2,
diff --git a/code/game/objects/effects/spawners/depot_spawners.dm b/code/game/objects/effects/spawners/depot_spawners.dm
index 153871d088e..0e9c2813c6a 100644
--- a/code/game/objects/effects/spawners/depot_spawners.dm
+++ b/code/game/objects/effects/spawners/depot_spawners.dm
@@ -20,8 +20,8 @@
/obj/effect/spawner/random/syndicate/mob
name = "50pc melee syndimob"
icon = 'icons/effects/spawner_icons.dmi'
- icon_state = "syndie_depot"
- loot = list(/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot)
+ icon_state = "syndicate"
+ loot = list(/mob/living/simple_animal/hostile/syndicate/depot)
spawn_loot_chance = 50
/obj/effect/spawner/random/syndicate/medbot
diff --git a/code/game/objects/effects/spawners/random/loot_spawners.dm b/code/game/objects/effects/spawners/random/loot_spawners.dm
index 2b74e43368f..79102c0711a 100644
--- a/code/game/objects/effects/spawners/random/loot_spawners.dm
+++ b/code/game/objects/effects/spawners/random/loot_spawners.dm
@@ -134,3 +134,12 @@
/obj/effect/spawner/random/bluespace_tap/food_uncommon = 3,
/obj/effect/spawner/random/bluespace_tap/food_rare,
)
+
+/obj/effect/spawner/random/syndie_mob_loot
+ loot = list(
+ /obj/item/reagent_containers/patch/styptic,
+ /obj/item/reagent_containers/patch/silver_sulf,
+ /obj/item/food/syndicake,
+ /obj/item/food/donkpocket,
+ /obj/effect/spawner/random/pool/spaceloot/syndicate/mixed,
+ )
diff --git a/code/game/objects/effects/spawners/random/pool/space_loot.dm b/code/game/objects/effects/spawners/random/pool/space_loot.dm
index 330791fe8ea..05fedf6472f 100644
--- a/code/game/objects/effects/spawners/random/pool/space_loot.dm
+++ b/code/game/objects/effects/spawners/random/pool/space_loot.dm
@@ -85,7 +85,7 @@
)
/obj/effect/spawner/random/pool/spaceloot/syndicate/stetchkin
- name = "syndicate depot loot, 20% stetchkin"
+ name = "syndicate depot loot, 80% stetchkin"
icon_state = "stetchkin"
spawn_loot_chance = 80
point_value = 25
@@ -208,7 +208,6 @@
/obj/item/mod/module/stealth,
)
-
/obj/effect/spawner/random/pool/spaceloot/syndicate/armory
name = "syndicate depot loot, armory"
// Combat orientated items that could give the player an advantage if an antag messes with them.
@@ -230,6 +229,10 @@
/obj/item/mod/module/stealth,
)
+/obj/effect/spawner/random/pool/spaceloot/syndicate/armory/elite/Initialize(mapload)
+ loot ^= list(/obj/item/mod/control/pre_equipped/traitor_elite)
+ . = ..()
+
/obj/effect/spawner/random/pool/spaceloot/syndicate/armory/depot
guaranteed = TRUE
spawn_inside = /obj/structure/closet/secure_closet/depot/armory
@@ -251,7 +254,6 @@
/obj/item/cqc_manual,
)
-
/obj/effect/spawner/random/pool/spaceloot/syndicate/mixed
loot = list(
/obj/effect/spawner/random/pool/spaceloot/syndicate/common = 30,
@@ -260,6 +262,39 @@
/obj/effect/spawner/random/pool/spaceloot/syndicate/armory = 1,
)
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob
+ icon = 'icons/effects/spawner_icons.dmi'
+ icon_state = "syndicate_random"
+ loot = list(
+ /obj/effect/spawner/random/pool/spaceloot/syndicate/mob/common = 80,
+ /obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit = 19,
+
+ // Let the massacre begin
+ /obj/effect/spawner/random/pool/spaceloot/syndicate/mob/elite, // 1%
+ )
+
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/elite
+ point_value = 200 // Guaranteed armory-tier loot on death
+ loot = list(/mob/living/simple_animal/hostile/syndicate/modsuit/elite)
+
+// Used when we want our mob to be protected from environment pressure
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit
+ icon_state = "syndicate_random_mod"
+ point_value = 6 // Modsuit chance
+ loot = list(
+ /mob/living/simple_animal/hostile/syndicate/modsuit,
+ /mob/living/simple_animal/hostile/syndicate/modsuit/ranged,
+ )
+
+/obj/effect/spawner/random/pool/spaceloot/syndicate/mob/common
+ icon_state = "syndicate"
+ point_value = 3
+ loot = list(
+ /mob/living/simple_animal/hostile/syndicate/ranged = 4,
+ /mob/living/simple_animal/hostile/syndicate = 3, // Melee is stronger than ranged variant most of the time
+ /mob/living/simple_animal/hostile/syndicate/shield,
+ )
+
// Only two of these
/obj/effect/spawner/random/pool/spaceloot/zoo
unique_picks = TRUE
@@ -270,11 +305,6 @@
/obj/item/gun/energy/temperature,
)
-/obj/effect/spawner/random/pool/spaceloot/modsuit_syndie
- point_value = 100
- spawn_loot_chance = 50
- loot = list(/mob/living/simple_animal/hostile/syndicate/ranged/space/autogib)
-
/obj/effect/spawner/random/pool/spaceloot/moonoutpost19
name = "moon outpost 19 loot spawner"
point_value = 30
@@ -315,7 +345,6 @@
spawn_random_offset = TRUE
spawn_random_offset_max_pixels = 8
-
/obj/effect/spawner/random/pool/spaceloot/mechtransport/storage1
loot = list(
/obj/item/mecha_parts/mecha_equipment/repair_droid,
@@ -335,4 +364,3 @@
/obj/effect/spawner/random/pool/spaceloot/mechtransport/storage4
loot = list(/obj/item/mecha_parts/core)
-
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index d8e4f776581..17e5d73a3d3 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -110,6 +110,12 @@
icon_state = "syndie_headset"
item_state = "syndie_headset"
+/obj/item/radio/headset/syndicate_fake
+ name = "syndicate headset"
+ desc = "A syndicate headset to set on your head."
+ icon_state = "syndie_headset"
+ item_state = "syndie_headset"
+
/obj/item/radio/headset/syndicate/syndteam
ks1type = /obj/item/encryptionkey/syndteam
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 9a026b2135b..5df6836396c 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -112,10 +112,11 @@
new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
new /obj/item/flashlight/flare/glowstick/emergency(src)
-/obj/item/storage/box/survival_syndi
- icon_state = "syndi_box"
+/obj/item/storage/box/survival_syndie
+ icon_state = "syndie_box"
+ desc = "A sleek, sturdy box."
-/obj/item/storage/box/survival_syndi/populate_contents()
+/obj/item/storage/box/survival_syndie/populate_contents()
new /obj/item/clothing/mask/gas/syndicate(src)
new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
new /obj/item/crowbar/small(src)
@@ -123,6 +124,24 @@
new /obj/item/reagent_containers/pill/initropidril(src)
new /obj/item/flashlight/flare/glowstick/red(src)
+/obj/item/storage/box/survival_syndie/traitor/populate_contents()
+ new /obj/item/clothing/mask/gas/syndicate(src)
+ new /obj/item/tank/internals/emergency_oxygen/engi/syndi(src)
+ new /obj/item/crowbar/small(src)
+ new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
+ new /obj/item/flashlight/flare/glowstick/red(src)
+
+/obj/item/storage/box/survival_syndie/traitor/loot/populate_contents()
+ new /obj/item/crowbar/small(src)
+ new /obj/item/reagent_containers/hypospray/autoinjector/epinephrine(src)
+ new /obj/item/flashlight/flare/glowstick/red(src)
+
+/obj/item/storage/box/syndie_kit/loot/populate_contents()
+ new /obj/effect/spawner/random/syndie_mob_loot(src)
+
+/obj/item/storage/box/syndie_kit/loot/elite/populate_contents()
+ new /obj/effect/spawner/random/pool/spaceloot/syndicate/armory/elite(src)
+
//////////////////
/* Common Boxes */
//////////////////
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index 4131c3c071e..f8919de1c21 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -131,7 +131,7 @@ GLOBAL_VAR_INIT(sent_syndicate_strike_team, 0)
equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(src), ITEM_SLOT_GLOVES)
equip_to_slot_or_del(new /obj/item/storage/backpack/security(src), ITEM_SLOT_BACK)
- equip_to_slot_or_del(new /obj/item/storage/box/survival_syndi(src), ITEM_SLOT_IN_BACKPACK)
+ equip_to_slot_or_del(new /obj/item/storage/box/survival_syndie(src), ITEM_SLOT_IN_BACKPACK)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver(src), ITEM_SLOT_IN_BACKPACK)
equip_to_slot_or_del(new /obj/item/ammo_box/a357(src), ITEM_SLOT_IN_BACKPACK)
diff --git a/code/modules/awaymissions/mob_spawn.dm b/code/modules/awaymissions/mob_spawn.dm
index 0edf26f7964..22b0b10b3db 100644
--- a/code/modules/awaymissions/mob_spawn.dm
+++ b/code/modules/awaymissions/mob_spawn.dm
@@ -207,7 +207,10 @@
var/suit_store = -1
var/hair_style
var/facial_hair_style
+ var/hair_color
+ var/facial_hair_color
var/skin_tone
+ var/eyes_color
var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset)
@@ -244,16 +247,28 @@
H.socks = "Nude"
var/obj/item/organ/external/head/D = H.get_organ("head")
if(istype(D))
+ if(eyes_color)
+ H.change_eye_color(eyes_color)
if(hair_style)
D.h_style = hair_style
else
D.h_style = random_hair_style(gender, D.dna.species.name)
- D.hair_colour = rand_hex_color()
+ if(hair_color)
+ D.hair_colour = hair_color
+ D.sec_hair_colour = hair_color
+ else
+ D.hair_colour = rand_hex_color()
+ D.sec_hair_colour = D.hair_colour
if(facial_hair_style)
D.f_style = facial_hair_style
else
D.f_style = random_facial_hair_style(gender, D.dna.species.name)
- D.facial_colour = rand_hex_color()
+ if(facial_hair_color)
+ D.facial_colour = facial_hair_color
+ D.sec_facial_colour = facial_hair_color
+ else
+ D.facial_colour = rand_hex_color()
+ D.sec_facial_colour = D.facial_colour
if(skin_tone)
H.s_tone = skin_tone
else
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 37c3a95a1df..0c8d6a0cd23 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -211,6 +211,12 @@
"Kidan" = 'icons/mob/clothing/species/kidan/eyes.dmi'
)
+/obj/item/clothing/glasses/night/syndicate_fake
+ name = "suspicious night vision goggles"
+ desc = "A dark red tacticool goggles anyone would go operate with."
+ icon_state = "securityhudnight"
+ color = "#d62d20" // I want it to color the on mob's sprite as well, but i don't know how to actually.
+
/obj/item/clothing/glasses/eyepatch
name = "eyepatch"
desc = "Yarr."
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index 4bfde7a21eb..22c79dcada1 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -1,64 +1,117 @@
//List of different corpse types
-/obj/effect/mob_spawn/human/corpse/syndicatesoldier
+// MARK: Syndicate
+/obj/effect/mob_spawn/human/corpse/syndicate
name = "Syndicate Operative"
- mob_name = "Syndicate Operative"
- hair_style = "bald"
- facial_hair_style = "shaved"
- id_job = "Operative"
+ id_job = "err#unkwn"
id_access_list = list(ACCESS_SYNDICATE)
- outfit = /datum/outfit/syndicatesoldiercorpse
+ outfit = /datum/outfit/syndicatecorpse
+ del_types = list()
+ disable_pda = TRUE
+ var/name_changed
+ var/name_to_add
+ var/num_to_add
-/datum/outfit/syndicatesoldiercorpse
+/obj/effect/mob_spawn/human/corpse/syndicate/Initialize(mapload)
+ if(!name_changed)
+ name_to_add = pick("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-ray", "Yankee", "Zulu")
+ num_to_add = rand(1, 1337)
+ mob_name = "[syndicate_name()] [name_to_add] #[num_to_add]"
+ name_changed = TRUE
+ brute_damage = rand(0, 200)
+ var/hcolor = pick("#000000", "#8B4513", "#FFD700")
+ var/ecolor = pick("#000000", "#8B4513", "#1E90FF")
+ hair_color = hcolor
+ facial_hair_color = hcolor
+ eyes_color = ecolor
+ skin_tone = pick(-50, -30, -10, 0, 0, 0, 10)
+ return ..()
+
+/datum/outfit/syndicatecorpse
name = "Corpse of a Syndicate Operative"
uniform = /obj/item/clothing/under/syndicate
- suit = /obj/item/clothing/suit/armor/vest
+ suit = /obj/item/clothing/suit/jacket/bomber/syndicate
+ glasses = /obj/item/clothing/glasses/night/syndicate_fake
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
- l_ear = /obj/item/radio/headset
- mask = /obj/item/clothing/mask/gas
- head = /obj/item/clothing/head/helmet/swat
- back = /obj/item/storage/backpack
+ l_ear = /obj/item/radio/headset/syndicate_fake
+ mask = /obj/item/clothing/mask/gas/syndicate
+ head = /obj/item/clothing/head/helmet/swat/syndicate
+ back = /obj/item/storage/backpack/satchel
+ belt = /obj/item/storage/belt/utility/syndi_researcher
+ box = /obj/item/storage/box/survival_syndie/traitor/loot
+ l_pocket = /obj/item/tank/internals/emergency_oxygen/engi/syndi
id = /obj/item/card/id/syndicate_fake
+ pda = /obj/item/pda/syndicate_fake
+ internals_slot = ITEM_SLOT_LEFT_POCKET
+ var/modsuit
+ var/armory_loot
+/datum/outfit/syndicatecorpse/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(modsuit && prob(5))
+ box = null
+ head = null
+ suit = null
+ l_pocket = null
+ back = modsuit
+ suit_store = /obj/item/tank/internals/oxygen/red
+ internals_slot = ITEM_SLOT_SUIT_STORE
+ if(armory_loot)
+ backpack_contents |= /obj/item/storage/box/syndie_kit/loot/elite
+ else if(prob(50))
+ backpack_contents |= /obj/item/storage/box/syndie_kit/loot
-/obj/effect/mob_spawn/human/corpse/syndicatecommando
+/datum/outfit/syndicatecorpse/post_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(H?.w_uniform)
+ var/obj/item/clothing/under/U = H.w_uniform
+ var/obj/item/clothing/accessory/holster/W = new /obj/item/clothing/accessory/holster(U)
+ U.accessories += W
+ W.on_attached(U)
+
+// MARK: Syndicate mod
+/obj/effect/mob_spawn/human/corpse/syndicate/modsuit
name = "Syndicate Commando"
- mob_name = "Syndicate Commando"
- hair_style = "bald"
- facial_hair_style = "shaved"
- id_job = "Operative"
- id_access_list = list(ACCESS_SYNDICATE)
- outfit = /datum/outfit/syndicatecommandocorpse
+ outfit = /datum/outfit/syndicatecorpse/modsuit
-/datum/outfit/syndicatecommandocorpse
+/obj/effect/mob_spawn/human/corpse/syndicate/modsuit/Initialize(mapload)
+ if(!name_changed)
+ name_to_add = pick("Aries", "Leo", "Sagittarius", "Taurus", "Virgo", "Capricorn", "Gemini", "Libra", "Aquarius", "Cancer", "Scorpio", "Pisces", "Rose", "Peony", "Lily", "Daisy", "Zinnia", "Ivy", "Iris", "Petunia", "Violet", "Lilac", "Orchid")
+ if(prob(95))
+ num_to_add = pick("II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX")
+ mob_name = num_to_add ? "[syndicate_name()] [name_to_add] [num_to_add]" : "[syndicate_name()] [name_to_add]"
+ name_changed = TRUE
+ return ..()
+
+/datum/outfit/syndicatecorpse/modsuit
name = "Corpse of a Syndicate Commando"
- uniform = /obj/item/clothing/under/syndicate
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- l_ear = /obj/item/radio/headset
- mask = /obj/item/clothing/mask/gas/syndicate
- back = /obj/item/mod/control/pre_equipped/traitor
- r_pocket = /obj/item/tank/internals/emergency_oxygen
- id = /obj/item/card/id/syndicate_fake
+ modsuit = /obj/item/mod/control/pre_equipped/traitor
-/obj/effect/mob_spawn/human/corpse/syndicatequartermaster
+// MARK: Syndicate elite mod
+/obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite
+ name = "Syndicate Overseer"
+ outfit = /datum/outfit/syndicatecorpse/modsuit/elite
+
+/obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite/Initialize(mapload)
+ if(!name_changed)
+ name_to_add = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord", "Berzerk", "Reaper", "Beast", "Hellwalker", "Slayer", "Oathbreaker", "Supreme Commander", "Overseer", "Butcher", "Executioner", "Judge", "Head of Shitcurity", "Unchained Predator", "Outlander", "DM1-5", "Scourge of Hell", "Doom")
+ mob_name = "[syndicate_name()] [name_to_add]"
+ name_changed = TRUE
+ return ..()
+
+/datum/outfit/syndicatecorpse/modsuit/elite
+ name = "Corpse of a Syndicate Overseer"
+ modsuit = /obj/item/mod/control/pre_equipped/traitor_elite
+ armory_loot = TRUE
+
+// MARK: Syndicate depot QM
+/obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite/depot
name = "Syndicate Quartermaster"
- mob_name = "Syndicate Quartermaster"
- hair_style = "bald"
- facial_hair_style = "shaved"
- id_job = "Operative"
- id_access_list = list(ACCESS_SYNDICATE)
- outfit = /datum/outfit/syndicatequartermastercorpse
+ outfit = /datum/outfit/syndicatecorpse/modsuit/elite/depot
-/datum/outfit/syndicatequartermastercorpse
+/datum/outfit/syndicatecorpse/modsuit/elite/depot
name = "Corpse of a Syndicate Quartermaster"
- uniform = /obj/item/clothing/under/syndicate
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- l_ear = /obj/item/radio/headset
- mask = /obj/item/clothing/mask/gas/syndicate
- r_pocket = /obj/item/tank/internals/emergency_oxygen
- id = /obj/item/card/id/syndicate_fake
+ armory_loot = FALSE
/obj/effect/mob_spawn/human/corpse/clown/corpse
roundstart = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
index 72c9092f354..0e67511ff03 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
@@ -1,136 +1,655 @@
+#define BLOOD_HELMET "helmetblood"
+#define BLOOD_MASK "maskblood"
+#define BLOOD_ARMOR "armorblood"
+#define BLOOD_SUIT "suitblood"
+#define BLOOD_HANDS "bloodyhands"
+#define BLOOD_SHOES "shoeblood"
+
+#define MELEE_WEAPON_NONE "slapper"
+#define MELEE_WEAPON_ESWORD "sword"
+#define MELEE_WEAPON_DSWORD "dsword"
+
+#define RANGED_WEAPON_PISTOL "gun"
+#define RANGED_WEAPON_C20R "c20r"
+#define RANGED_WEAPON_M90 "m90"
+#define RANGED_WEAPON_SR "sr"
+#define RANGED_WEAPON_SR_IDLE "sr-idle"
+
+#define SOUND_MOD 'sound/mecha/mechmove03.ogg'
+#define SOUND_SMG 'sound/weapons/gunshots/gunshot_smg.ogg'
+#define SOUND_AR 'sound/weapons/gunshots/gunshot_rifle.ogg'
+#define SOUND_SR 'sound/weapons/gunshots/gunshot_sniper.ogg'
+
+#define SYNDICATE "syndicate"
+#define RAIDER "syndicate_mod"
+#define JAEGER "syndicate_elite"
+
+#define VISOR_MASK "mask"
+#define VISOR_RAIDER "armor_booster"
+#define VISOR_JAEGER "elite_armor_booster"
+
+#define ESHIELD (1 << 0) // Do we have an energy shield in our hands that will reflect any energy projectiles?
+#define SWORD (1 << 1) // Whether we play activation/deactivation sound of e/dsword
+#define MODSUIT (1 << 2) // Do we wear a modsuit?
+#define ARMOR_BOOSTER (1 << 3) // If our armor booster currently active. Affects `damage_coeff` and overlay, used alongside `modsuit` only
+#define HEALING (1 << 4) // Are we currently healing ourselves?
+#define CRITICAL (1 << 5) // Are we in a critical condition?
+#define ADRENAL (1 << 6) // Do we have an adrenal bio-chip?
+
+//////////////////////////////
+// MARK: SYNDICATE MOB
+//////////////////////////////
/mob/living/simple_animal/hostile/syndicate
name = "Syndicate Operative"
desc = "Death to Nanotrasen."
icon = 'icons/mob/simple_human.dmi'
- icon_state = "syndicate"
- icon_living = "syndicate"
- icon_dead = "syndicate_dead" // Does not actually exist. del_on_death.
- icon_gib = "syndicate_gib" // Does not actually exist. del_on_death.
- mob_biotypes = MOB_ORGANIC | MOB_HUMANOID
- damage_coeff = list("brute" = 1, "fire" = 1, "tox" = 0, "clone" = 0, "stamina" = 0, "oxy" = 0)
- speak_chance = 0
- turns_per_move = 5
+ icon_state = SYNDICATE
+ icon_living = SYNDICATE
+ attacktext = "slashes"
response_help = "pokes the"
response_disarm = "shoves the"
response_harm = "hits the"
- speed = 0
- maxHealth = 150
- health = 150
- harm_intent_damage = 5
- melee_damage_lower = 15
- melee_damage_upper = 15
- attacktext = "punches"
- attack_sound = 'sound/weapons/punch1.ogg'
+ attack_sound = 'sound/weapons/blade1.ogg'
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) // We know how to use gasmasks
+ faction = list(SYNDICATE)
+ move_to_delay = 2.99 // Faster than human by 0.01
+ del_on_death = TRUE
+ mob_biotypes = MOB_ORGANIC | MOB_HUMANOID
+ move_resist = MOVE_FORCE_STRONG
+ footstep_type = FOOTSTEP_MOB_SHOE
+ sentience_type = SENTIENCE_OTHER
a_intent = INTENT_HARM
stat_attack = UNCONSCIOUS
- unsuitable_atmos_damage = 15
- faction = list("syndicate")
+ status_flags = 0
check_friendly_fire = TRUE
- status_flags = CANPUSH
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier,
- /obj/effect/decal/cleanable/blood/innards,
- /obj/effect/decal/cleanable/blood,
- /obj/effect/gibspawner/generic,
- /obj/effect/gibspawner/generic)
- del_on_death = TRUE
- sentience_type = SENTIENCE_OTHER
- footstep_type = FOOTSTEP_MOB_SHOE
robust_searching = TRUE
+ turns_per_move = 5
+ speed = 0
+ maxHealth = 200
+ health = 200
+ unsuitable_atmos_damage = 2 // 4 actually
+ damage_coeff = list(BRUTE = 0.9, BURN = 0.9, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) // Imitates our armor
+ melee_damage_lower = 30
+ melee_damage_upper = 30
+ armour_penetration_percentage = 50
+ loot = list(
+ /obj/effect/decal/cleanable/blood/innards,
+ /obj/effect/decal/cleanable/blood,
+ /obj/effect/gibspawner/generic,
+ /obj/effect/gibspawner/generic,
+ )
+ // Bitflags!
+ var/syndie_flags = 0
+ // What do we perform melee attacks with
+ var/melee_type = MELEE_WEAPON_ESWORD
+ // What do we perform ranged attacks with
+ var/ranged_type
+ // Corpse we spawn on death()
+ var/corpse = /obj/effect/mob_spawn/human/corpse/syndicate
+ // Weapon icon overlay we add when we have a target to attack
+ var/weapon
+ // Idle icon of our weapon (See elite mob with SR for example)
+ var/weapon_idle
+ // Overlay for our swat mask/armor booster visor
+ var/visor = VISOR_MASK
+ // %Chance to reflect an energy projectile. Used alongside `MELEE_WEAPON_ESWORD` only
+ var/reflect_chance = 10
+ // %Chance to deflect a melee hit. Used alongside `MELEE_WEAPON_DSWORD` only
+ var/deflect_chance = 15
+ // %Chance to fully block a hit
+ var/parry_chance = 10
+ // Icon we display on melee attack/parry
+ var/attack_icon
+ // For how long we do nothing
+ var/idle_cycle = 0
+ // Should we apply bloody mask? Used in AttackingTarget(), contains target's blood color
+ var/bloody
+ // For how long we have been under emergency effect?
+ var/emergency_cycle = 0
+ // Color of our blade
+ var/sword_color
+ // Colors for our blade
+ var/list/static/colormap = list(
+ 1 = LIGHT_COLOR_GREEN,
+ 2 = LIGHT_COLOR_RED,
+ 3 = LIGHT_COLOR_LIGHTBLUE,
+ 4 = LIGHT_COLOR_PURPLE,
+ )
+ COOLDOWN_DECLARE(emergency_heal_cooldown)
+ COOLDOWN_DECLARE(emote_react)
/mob/living/simple_animal/hostile/syndicate/Initialize(mapload)
. = ..()
- if(prob(50))
- loot |= /obj/item/salvage/loot/syndicate
+ if(syndie_flags & MODSUIT)
+ death_sound = SOUND_MOD
+ update_icon(UPDATE_OVERLAYS)
+ if(loot) // Prevents us from adding loot if there is none yet
+ if(prob(50))
+ loot |= /obj/item/salvage/loot/syndicate
+ loot |= corpse
+
+/mob/living/simple_animal/hostile/syndicate/proc/apply_blood()
+ var/list/static/bloody_parts
+ if(syndie_flags & MODSUIT)
+ bloody_parts = list(
+ BLOOD_HELMET,
+ BLOOD_ARMOR,
+ BLOOD_HANDS,
+ BLOOD_SHOES,
+ )
+ else
+ bloody_parts = list(
+ BLOOD_MASK,
+ BLOOD_HELMET,
+ BLOOD_SUIT,
+ BLOOD_HANDS,
+ BLOOD_SHOES,
+ )
+
+ for(var/bloody_part in bloody_parts)
+ var/mutable_appearance/bloodsies = mutable_appearance('icons/effects/blood.dmi', icon_state = bloody_part)
+ bloodsies.color = bloody
+ add_overlay(bloodsies)
+
+ // Other overlays should be always above blood
+ cut_overlay(weapon)
+ cut_overlay(weapon_idle)
+ cut_overlay("eshield")
+
+ update_icon(UPDATE_OVERLAYS)
+
+/mob/living/simple_animal/hostile/syndicate/proc/apply_visor()
+ if(!(syndie_flags & MODSUIT) || syndie_flags & ARMOR_BOOSTER)
+ cut_overlay("[visor]-off")
+ add_overlay(visor)
+ else if(syndie_flags & MODSUIT && !(syndie_flags & ARMOR_BOOSTER))
+ cut_overlay(visor)
+ add_overlay("[visor]-off")
+
+/mob/living/simple_animal/hostile/syndicate/proc/apply_weapon()
+ if(!attack_icon)
+ if(melee_type == MELEE_WEAPON_NONE)
+ attack_icon = MELEE_WEAPON_NONE
+ else
+ sword_color = rand(1,4)
+ attack_icon = "[melee_type][sword_color]"
+
+ if(target)
+ if(weapon_idle)
+ cut_overlay(weapon_idle)
+ if(ranged)
+ if(!weapon)
+ weapon = ranged_type
+ add_overlay(weapon)
+ else
+ if(melee_type != MELEE_WEAPON_NONE)
+ if(!weapon)
+ weapon = "[sword_color][melee_type]"
+ add_overlay(weapon)
+ if(sword_color)
+ set_light(2, l_color = colormap[sword_color])
+ if(!(syndie_flags & SWORD))
+ syndie_flags |= SWORD
+ else
+ if(sword_color)
+ set_light(0)
+ if(weapon)
+ cut_overlay(weapon)
+ if(weapon_idle)
+ add_overlay(weapon_idle)
+ if(syndie_flags & SWORD)
+ syndie_flags &= ~SWORD
+
+/mob/living/simple_animal/hostile/syndicate/proc/apply_eshield()
+ if(syndie_flags & ESHIELD)
+ add_overlay("eshield")
+
+/mob/living/simple_animal/hostile/syndicate/proc/apply_heal(amount, heal_sound)
+ adjustHealth(-amount)
+ if(heal_sound)
+ playsound(src, pick('sound/goonstation/items/mender.ogg', 'sound/goonstation/items/mender2.ogg'), 50, TRUE)
+ if(health == maxHealth && syndie_flags & HEALING)
+ syndie_flags &= ~HEALING
+ idle_cycle = 0
+ react_sound()
+
+/mob/living/simple_animal/hostile/syndicate/proc/emergency_heal()
+ if(!(syndie_flags & CRITICAL) && COOLDOWN_FINISHED(src, emergency_heal_cooldown))
+ syndie_flags |= CRITICAL
+ COOLDOWN_START(src, emergency_heal_cooldown, 60 SECONDS)
+ if(syndie_flags & ADRENAL)
+ move_to_delay = ranged ? 2.5 : 1.8
+ if(!ranged)
+ dodging = FALSE
+
+/mob/living/simple_animal/hostile/syndicate/proc/react_sound()
+ if(!COOLDOWN_FINISHED(src, emote_react))
+ return
+ if(prob(round(100-(health/maxHealth*100))*0.25))
+ COOLDOWN_START(src, emote_react, 10 SECONDS)
+ if(syndie_flags & CRITICAL && syndie_flags & ADRENAL)
+ playsound(src, 'sound/effects/mob_effects/knuckles.ogg', 50, TRUE)
+ custom_emote(EMOTE_VISIBLE, "cracks its fingers.")
+ else if(health >= maxHealth*0.75)
+ custom_emote(EMOTE_VISIBLE, "yawns...")
+ else if(health >= maxHealth*0.375)
+ custom_emote(EMOTE_VISIBLE, "sighs.")
+ else if(health >= maxHealth*0.125)
+ custom_emote(EMOTE_VISIBLE, "chokes!")
+ else
+ custom_emote(EMOTE_VISIBLE, "moans!")
+
+/mob/living/simple_animal/hostile/syndicate/proc/jedi_spin()
+ for(var/i in list(NORTH, SOUTH, EAST, WEST, EAST, SOUTH, NORTH, SOUTH, EAST, WEST, EAST, SOUTH))
+ setDir(i)
+ if(i == WEST)
+ SpinAnimation(7, 1)
+ sleep(1)
+
+/mob/living/simple_animal/hostile/syndicate/update_overlays()
+ . = ..()
+ apply_visor()
+ apply_eshield()
+ apply_weapon()
+
+/mob/living/simple_animal/hostile/syndicate/handle_environment(datum/gas_mixture/readonly_environment)
+ . = ..()
+ var/pressure = readonly_environment.return_pressure()
+ var/enough_pressure = FALSE
+ if(pressure > HAZARD_LOW_PRESSURE && pressure < HAZARD_HIGH_PRESSURE)
+ enough_pressure = TRUE
+ if(syndie_flags & MODSUIT)
+ if(!enough_pressure && syndie_flags & ARMOR_BOOSTER)
+ syndie_flags &= ~ARMOR_BOOSTER
+ damage_coeff[BRUTE] += 0.2
+ damage_coeff[BURN] += 0.1
+ playsound(src, SOUND_MOD, 25, TRUE)
+ apply_visor()
+ else if(enough_pressure && !(syndie_flags & ARMOR_BOOSTER))
+ syndie_flags |= ARMOR_BOOSTER
+ damage_coeff[BRUTE] -= 0.2
+ damage_coeff[BURN] -= 0.1
+ playsound(src, SOUND_MOD, 25, TRUE)
+ apply_visor()
+ else if(!enough_pressure)
+ adjustHealth(unsuitable_atmos_damage)
+
+/mob/living/simple_animal/hostile/syndicate/ListTargetsLazy()
+ // The normal ListTargetsLazy ignores walls, which is very bad. So we override it.
+ return ListTargets()
+
+/mob/living/simple_animal/hostile/syndicate/AIShouldSleep(list/possible_targets)
+ FindTarget(possible_targets, TRUE)
+ return FALSE
/mob/living/simple_animal/hostile/syndicate/Aggro()
. = ..()
if(target)
- playsound(loc, 'sound/misc/for_the_syndicate.ogg', 70, TRUE)
+ playsound(src, 'sound/misc/for_the_syndicate.ogg', 70, TRUE)
+ if(melee_type != MELEE_WEAPON_NONE && !(syndie_flags & SWORD))
+ playsound(src, 'sound/weapons/saberon.ogg', 35, TRUE)
+ update_icon(UPDATE_OVERLAYS)
-///////////////Sword and shield////////////
+/mob/living/simple_animal/hostile/syndicate/AttackingTarget()
+ if(ranged)
+ if(ranged_cooldown <= world.time)
+ OpenFire(target)
+ return
+ . = ..()
+ if(.)
+ if(!ranged && !bloody && ishuman(target) && melee_damage_upper && prob(25))
+ var/mob/living/carbon/human/victim = target
+ bloody = victim.dna.species.blood_color
+ apply_blood()
+ if(melee_type == MELEE_WEAPON_DSWORD && prob(50))
+ jedi_spin()
-/mob/living/simple_animal/hostile/syndicate/melee
- melee_damage_lower = 25
- melee_damage_upper = 30
- icon_state = "syndicate_sword"
- icon_living = "syndicate_sword"
- attacktext = "slashes"
- attack_sound = 'sound/weapons/blade1.ogg'
- armour_penetration_percentage = 40
- armour_penetration_flat = 10
- status_flags = 0
- var/melee_block_chance = 20
- var/ranged_block_chance = 35
+/mob/living/simple_animal/hostile/syndicate/Shoot(atom/targeted_atom)
+ if(QDELETED(targeted_atom) || targeted_atom == targets_from.loc || targeted_atom == targets_from)
+ return
+ var/turf/startloc = get_turf(targets_from)
+ var/turf/target_turf = get_turf(targeted_atom)
+ if(!target_turf)
+ return
+ if(casingtype)
+ // I know that is ABSOLUTELY terrible way to do that, but.. i don't know how to make it properly. I wasted a lot of time trying to, but only this is working somewhat good enough.
+ var/dx = abs(target_turf.x - startloc.x)
+ var/dy = abs(target_turf.y - startloc.y)
+ if(target_turf.x < startloc.x && target_turf.y > startloc.y)
+ if(dy > dx)
+ target_turf.pixel_x = 14
+ target_turf.pixel_y = 14
+ else if(dy < dx)
+ target_turf.pixel_x = -14
+ target_turf.pixel_y = -14
+ else if(target_turf.x < startloc.x && target_turf.y < startloc.y)
+ if(dy > dx)
+ target_turf.pixel_x = 14
+ target_turf.pixel_y = -14
+ else if(dy < dx)
+ target_turf.pixel_x = -14
+ target_turf.pixel_y = 14
+ else if(target_turf.x > startloc.x && target_turf.y > startloc.y)
+ if(dy > dx)
+ target_turf.pixel_x = -14
+ target_turf.pixel_y = 14
+ else if(dy < dx)
+ target_turf.pixel_x = 14
+ target_turf.pixel_y = -14
+ else if(target_turf.x > startloc.x && target_turf.y < startloc.y)
+ if(dy > dx)
+ target_turf.pixel_x = -14
+ target_turf.pixel_y = -14
+ else if(dy < dx)
+ target_turf.pixel_x = 14
+ target_turf.pixel_y = 14
+ var/obj/item/ammo_casing/casing = new casingtype(startloc)
+ playsound(src, projectilesound, 100, 1)
+ casing.fire(targeted_atom, src, zone_override = ran_zone(), firer_source_atom = src)
+ target_turf.pixel_x = initial(target_turf.pixel_x)
+ target_turf.pixel_y = initial(target_turf.pixel_y)
-/mob/living/simple_animal/hostile/syndicate/melee/attack_by(obj/item/O, mob/living/user, params)
- if(prob(melee_block_chance))
- visible_message("[src] blocks [O] with its shield!")
+/mob/living/simple_animal/hostile/syndicate/LoseTarget()
+ . = ..()
+ if(syndie_flags & SWORD && melee_type != MELEE_WEAPON_NONE)
+ playsound(src, 'sound/weapons/saberoff.ogg', 35, TRUE)
+ update_icon(UPDATE_OVERLAYS)
+
+/mob/living/simple_animal/hostile/syndicate/Life(seconds, times_fired)
+ . = ..()
+ if(stat != DEAD)
+ if(syndie_flags & CRITICAL)
+ emergency_cycle++
+ apply_heal(syndie_flags & ADRENAL ? 2 : 1) // Second breath
+ if(emergency_cycle >= 15)
+ syndie_flags &= ~CRITICAL
+ emergency_cycle = 0
+ if(syndie_flags & ADRENAL)
+ move_to_delay = initial(move_to_delay)
+ if(!ranged)
+ dodging = TRUE
+ if(!target && maxHealth > health && !(syndie_flags & HEALING))
+ if(idle_cycle >= 15)
+ syndie_flags |= HEALING
+ react_sound()
+ else
+ idle_cycle++
+
+ else if(target)
+ if(syndie_flags & HEALING)
+ syndie_flags &= ~HEALING
+ if(idle_cycle > 0)
+ idle_cycle = 0
+
+ else if(syndie_flags & HEALING)
+ var/datum/callback/cb = CALLBACK(src, PROC_REF(apply_heal), 8, TRUE)
+ var/delay = SSnpcpool.wait / 2
+ for(var/i in 1 to 2)
+ addtimer(cb, (i - 1)*delay)
+
+/mob/living/simple_animal/hostile/syndicate/adjustHealth(damage, updating_health = TRUE)
+ . = ..()
+ if(damage > 0)
+ if(prob(round(100-(health/maxHealth*100))) && health <= maxHealth*0.25)
+ emergency_heal()
+ if(syndie_flags & HEALING)
+ syndie_flags &= ~HEALING
+ if(idle_cycle > 0)
+ idle_cycle = 0
+ if(health < maxHealth*0.4)
+ react_sound()
+
+// Huge copypaste starts. Any ideas on how to shrink it down?
+/mob/living/simple_animal/hostile/syndicate/do_attack_animation(atom/A, visual_effect_icon, used_item = attack_icon, no_effect)
+ if(!no_effect && (visual_effect_icon || used_item))
+ do_item_attack_animation(A, visual_effect_icon, used_item)
+
+ if(A == src)
+ return
+ var/pixel_x_diff = 0
+ var/pixel_y_diff = 0
+ var/turn_dir = 1
+
+ var/direction = get_dir(src, A)
+ if(direction & NORTH)
+ pixel_y_diff = 8
+ turn_dir = prob(50) ? -1 : 1
+ else if(direction & SOUTH)
+ pixel_y_diff = -8
+ turn_dir = prob(50) ? -1 : 1
+
+ if(direction & EAST)
+ pixel_x_diff = 8
+ else if(direction & WEST)
+ pixel_x_diff = -8
+ turn_dir = -1
+
+ var/matrix/initial_transform = matrix(transform)
+ var/matrix/rotated_transform = transform.Turn(5 * turn_dir)
+ animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform = rotated_transform, time = 0.1 SECONDS, easing = CUBIC_EASING)
+ animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform = initial_transform, time = 0.2 SECONDS, easing = SINE_EASING)
+
+/mob/living/simple_animal/hostile/syndicate/do_item_attack_animation(atom/A, visual_effect_icon, used_item)
+ var/image/I
+ if(visual_effect_icon)
+ I = image('icons/effects/effects.dmi', A, visual_effect_icon, A.layer + 0.1)
+ else if(used_item)
+ I = image(icon, A, used_item, A.layer + 0.1)
+ I.plane = GAME_PLANE
+
+ I.transform *= 0.75
+ I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+
+ var/direction = get_dir(src, A)
+ if(direction & NORTH)
+ I.pixel_y = -16
+ else if(direction & SOUTH)
+ I.pixel_y = 16
+
+ if(direction & EAST)
+ I.pixel_x = -16
+ else if(direction & WEST)
+ I.pixel_x = 16
+
+ if(!direction)
+ I.pixel_z = 16
+
+ if(!I)
+ return
+
+ var/list/viewing = list()
+ for(var/mob/M in viewers(A))
+ if(M.client && M.client.prefs.toggles2 & PREFTOGGLE_2_ITEMATTACK)
+ viewing |= M.client
+
+ I.appearance_flags |= RESET_TRANSFORM | KEEP_APART
+ flick_overlay(I, viewing, 7)
+
+ var/t_color = "#ffffff"
+ if(ismob(src) && ismob(A) && !used_item)
+ var/mob/M = src
+ t_color = M.a_intent == INTENT_HARM ? "#ff0000" : "#ffffff"
+ animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 0.3 SECONDS, color = t_color)
+ animate(time = 0.1 SECONDS)
+ animate(alpha = 0, time = 0.3 SECONDS, easing = CIRCULAR_EASING | EASE_OUT)
+// Huge copypaste ends
+
+/mob/living/simple_animal/hostile/syndicate/attack_hand(mob/living/user)
+ if(melee_type == MELEE_WEAPON_DSWORD && prob(deflect_chance))
+ visible_message("[src] deflects [user]'s punch with its double-bladed sword!")
+ do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.attack_animal(src)
+ playsound(src, 'sound/weapons/parry.ogg', clamp(maxHealth-health, 40, 120))
+ return FINISH_ATTACK
+
+ if(prob(parry_chance))
+ visible_message("[src] parries [user]!")
+ do_attack_animation(src)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
+ playsound(src, 'sound/weapons/parry.ogg', clamp(maxHealth-health, 40, 120))
return FINISH_ATTACK
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj)
+/mob/living/simple_animal/hostile/syndicate/attack_by(obj/item/O, mob/living/user, params)
+ if(melee_type == MELEE_WEAPON_DSWORD && prob(deflect_chance))
+ visible_message("[src] deflects [O] with its double-bladed sword!")
+ do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.attack_animal(src)
+ playsound(src, 'sound/weapons/parry.ogg', clamp(maxHealth-health, 40, 120))
+ return FINISH_ATTACK
+
+ if(prob(parry_chance))
+ visible_message("[src] parries [O]!")
+ do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.do_attack_animation(src)
+ playsound(src, 'sound/weapons/parry.ogg', clamp(maxHealth-health, 40, 120))
+ return FINISH_ATTACK
+
+ return ..()
+
+/mob/living/simple_animal/hostile/syndicate/bullet_act(obj/item/projectile/Proj)
if(!Proj)
return
- if(prob(ranged_block_chance))
- visible_message("[src] blocks [Proj] with its shield!")
+ if(((melee_type == MELEE_WEAPON_DSWORD || syndie_flags & ESHIELD) || (melee_type == MELEE_WEAPON_ESWORD && prob(reflect_chance))) && Proj.is_reflectable(REFLECTABILITY_ENERGY))
+ if(melee_type == MELEE_WEAPON_ESWORD)
+ do_attack_animation(src)
+ playsound(src, 'sound/weapons/effects/ric3.ogg', clamp(maxHealth-health, 40, 120), TRUE)
+ Proj.reflect_back(src)
+ visible_message("[src] reflects [Proj] with its [syndie_flags & ESHIELD ? "shield" : "sword"]!")
+ return -1
+
+ if(melee_type != MELEE_WEAPON_NONE && prob(parry_chance))
+ do_attack_animation(src)
+ visible_message("[src] parries [Proj]!")
+ playsound(src, 'sound/weapons/parry.ogg', clamp(maxHealth-health, 40, 120))
return
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/autogib
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier,
- /obj/item/salvage/loot/syndicate,
- /obj/effect/decal/cleanable/blood/innards,
- /obj/effect/decal/cleanable/blood,
- /obj/effect/gibspawner/generic,
- /obj/effect/gibspawner/generic)
+//////////////////////////////
+// MARK: ESHIELD
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/shield
+ syndie_flags = ESHIELD
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot
- name = "Syndicate Operative"
- force_threshold = 6 // Prevents people using punches to bypass eshield
- robust_searching = TRUE // Together with stat_attack, ensures dionae/etc that regen are killed properly
- universal_speak = TRUE
- icon_state = "syndicate_swordonly"
- icon_living = "syndicate_swordonly"
- melee_block_chance = 0
- ranged_block_chance = 0
- del_on_death = TRUE
+//////////////////////////////
+// MARK: RANGED
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/ranged
+ melee_type = MELEE_WEAPON_NONE
+ ranged = TRUE
+ ranged_type = RANGED_WEAPON_C20R
+ projectilesound = SOUND_SMG
+ casingtype = /obj/item/ammo_casing/c45/nostamina
+ rapid = 2
+ retreat_distance = 5
+ minimum_distance = 5
+ parry_chance = 20
+
+//////////////////////////////
+// MARK: MODSUIT
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/modsuit
+ name = "Syndicate Commando"
+ damage_coeff = list(BRUTE = 0.7, BURN = 0.9, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
+ maxbodytemp = FIRE_SUIT_MAX_TEMP_PROTECT
+ minbodytemp = 0
+ icon_state = RAIDER
+ icon_living = RAIDER
+ visor = VISOR_RAIDER
+ syndie_flags = MODSUIT
+ reflect_chance = 15
+ parry_chance = 15
+ corpse = /obj/effect/mob_spawn/human/corpse/syndicate/modsuit
+ var/eshield_prob = 15 // Chance to be spawned with an eshield
+
+/mob/living/simple_animal/hostile/syndicate/modsuit/Initialize(mapload)
+ if(prob(eshield_prob))
+ syndie_flags |= ESHIELD
+ . = ..()
+
+/mob/living/simple_animal/hostile/syndicate/modsuit/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
+ return TRUE
+
+//////////////////////////////
+// MARK: MODSUIT RANGED
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/modsuit/ranged
+ melee_type = MELEE_WEAPON_NONE
+ ranged = TRUE
+ ranged_type = RANGED_WEAPON_C20R
+ projectilesound = SOUND_SMG
+ casingtype = /obj/item/ammo_casing/c45/nostamina
+ rapid = 3
+ retreat_distance = 5
+ minimum_distance = 5
+ parry_chance = 20
+
+//////////////////////////////
+// MARK: ELITE MODSUIT
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/modsuit/elite
+ name = "Syndicate Overseer"
+ damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
+ maxbodytemp = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ icon_state = JAEGER
+ icon_living = JAEGER
+ visor = VISOR_JAEGER
+ syndie_flags = MODSUIT | ADRENAL
+ eshield_prob = 0
+ melee_type = MELEE_WEAPON_DSWORD
+ melee_damage_lower = 34
+ melee_damage_upper = 34
+ parry_chance = 30
+ corpse = /obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite
+
+/mob/living/simple_animal/hostile/syndicate/modsuit/elite/Initialize(mapload)
+ if(prob(50))
+ melee_type = MELEE_WEAPON_NONE
+ ranged = TRUE
+ ranged_type = RANGED_WEAPON_SR
+ weapon_idle = RANGED_WEAPON_SR_IDLE
+ projectilesound = SOUND_SR
+ casingtype = /obj/item/ammo_casing/penetrator
+ retreat_distance = 2
+ minimum_distance = 2
+ . = ..()
+
+//////////////////////////////
+// MARK: DEPOT
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/depot
var/area/syndicate_depot/core/depotarea
- var/raised_alert = FALSE
- var/alert_on_death = FALSE
+ var/raised_alert
+ var/alert_on_death
var/alert_on_timeout = TRUE
var/alert_on_spacing = TRUE
- var/alert_on_shield_breach = FALSE
- var/seen_enemy = FALSE
- var/seen_enemy_name = null
- var/seen_revived_enemy = FALSE
+ var/alert_on_shield_breach
+ var/seen_enemy
+ var/seen_enemy_name
+ var/seen_revived_enemy
var/aggro_cycles = 0
var/scan_cycles = 0
- var/shield_key = FALSE
+ var/shield_key
var/turf/spawn_turf
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/Initialize(mapload)
+/mob/living/simple_animal/hostile/syndicate/depot/Initialize(mapload)
. = ..()
- name = "[name] [pick(GLOB.last_names)]"
depotarea = get_area(src)
spawn_turf = get_turf(src)
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/ListTargetsLazy()
- // The normal ListTargetsLazy ignores walls, which is very bad in the case of depot mobs. So we override it.
- return ListTargets()
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/Aggro()
+/mob/living/simple_animal/hostile/syndicate/depot/Aggro()
. = ..()
if(!istype(depotarea))
return
if(target)
if(!seen_enemy)
seen_enemy = TRUE
- if(!ranged)
- playsound(loc, 'sound/weapons/saberon.ogg', 35, TRUE)
if(alert_on_shield_breach)
if(length(depotarea.shield_list))
raise_alert("[name] reports that [target] is trying to breach the armory shield!")
@@ -154,7 +673,7 @@
// This prevents someone from aggroing a depot mob, then hiding in a locker, perfectly safe, while the mob stands there getting killed by their friends.
LoseTarget()
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/handle_automated_action()
+/mob/living/simple_animal/hostile/syndicate/depot/handle_automated_action()
. = ..()
if(!.)
return
@@ -191,17 +710,13 @@
else
scan_cycles++
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/AIShouldSleep(list/possible_targets)
- FindTarget(possible_targets, TRUE)
- return FALSE
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/proc/raise_alert(reason)
+/mob/living/simple_animal/hostile/syndicate/depot/proc/raise_alert(reason)
if(istype(depotarea) && (!raised_alert || seen_revived_enemy) && !depotarea.used_self_destruct)
raised_alert = TRUE
say("Intruder!")
depotarea.increase_alert(reason)
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/drop_loot()
+/mob/living/simple_animal/hostile/syndicate/depot/drop_loot()
// If a depot syndicate dies after the depot has been destroyed, assume it
// was gibbed as part of the destruction and don't drop its loot.
if(istype(depotarea) && depotarea.destroyed)
@@ -209,7 +724,7 @@
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/death()
+/mob/living/simple_animal/hostile/syndicate/depot/death()
if(!istype(depotarea))
return ..()
if(alert_on_death)
@@ -224,162 +739,129 @@
new /obj/effect/gibspawner/human(get_turf(src))
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/CanPass(atom/movable/mover, border_dir)
+/mob/living/simple_animal/hostile/syndicate/depot/CanPass(atom/movable/mover, border_dir)
if(isliving(mover))
var/mob/living/blocker = mover
if(faction_check_mob(blocker))
- return 1
+ return TRUE
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer
- name = "Syndicate Officer"
- icon_state = "syndicate_sword"
- icon_living = "syndicate_sword"
- melee_block_chance = 20
- ranged_block_chance = 35
- alert_on_death = TRUE
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/Initialize(mapload)
- . = ..()
- if(prob(50))
- // 50% chance of switching to ranged variant.
- attacktext = "punches"
- attack_sound = 'sound/weapons/cqchit1.ogg'
- ranged = TRUE
- rapid = 3
- retreat_distance = 5
- minimum_distance = 3
- ranged_block_chance = 0
- icon_state = "syndicate_pistol"
- icon_living = "syndicate_pistol"
- projectiletype = /obj/item/projectile/bullet/armourpiercing
- projectilesound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory
- name = "Syndicate Quartermaster"
- icon_state = "syndicate_stormtrooper_sword"
- icon_living = "syndicate_stormtrooper_sword"
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- armour_penetration_percentage = 50 // same as e-sword
+//////////////////////////////
+// MARK: DEPOT MODSUIT
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit
+ name = "Syndicate Commando"
+ damage_coeff = list(BRUTE = 0.7, BURN = 0.9, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
+ maxbodytemp = FIRE_SUIT_MAX_TEMP_PROTECT
minbodytemp = 0
- maxHealth = 250
- health = 250
- melee_block_chance = 40
- ranged_block_chance = 35 // same as officer's
- alert_on_shield_breach = TRUE
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatequartermaster, /obj/effect/decal/cleanable/blood/innards, /obj/effect/decal/cleanable/blood, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic)
+ icon_state = RAIDER
+ icon_living = RAIDER
+ visor = VISOR_RAIDER
+ syndie_flags = MODSUIT
+ reflect_chance = 15
+ parry_chance = 15
+ corpse = /obj/effect/mob_spawn/human/corpse/syndicate/modsuit
+ var/eshield_prob = 75 // Chance to be spawned with an eshield
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
- return TRUE // he should be able to chase us in space
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/Initialize(mapload)
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/Initialize(mapload)
+ if(prob(eshield_prob))
+ syndie_flags |= ESHIELD
. = ..()
- if(prob(50))
- // 50% chance of switching to extremely dangerous ranged variant
- attacktext = "punches"
- attack_sound = 'sound/weapons/cqchit1.ogg'
- ranged = TRUE
- retreat_distance = 2
- minimum_distance = 2
- ranged_block_chance = 0
- icon_state = "syndicate_stormtrooper_shotgun"
- icon_living = "syndicate_stormtrooper_shotgun"
- speed = 2
- projectiletype = /obj/item/projectile/bullet/sniper/penetrator // Ignores cover.
- projectilesound = 'sound/weapons/gunshots/gunshot_sniper.ogg'
- loot |= /obj/item/salvage/loot/syndicate
- return INITIALIZE_HINT_LATELOAD
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/LateInitialize()
- if(istype(depotarea))
- var/list/key_candidates = list()
- for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in GLOB.alive_mob_list)
- key_candidates += O
- if(length(key_candidates))
- var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O = pick(key_candidates)
- O.shield_key = TRUE
- depotarea.shields_up()
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
+ return TRUE
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/death() // i hope it's all right
- if(!istype(depotarea))
- return ..()
- if(!length(depotarea.shield_list)) // not opening lockers without getting shields down
- depotarea.unlock_lockers()
- return ..()
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space
- name = "Syndicate Backup"
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- icon_state = "syndicate_space_sword"
- icon_living = "syndicate_space_sword"
- speed = 1
+//////////////////////////////
+// MARK: DEPOT BACKUP
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup
wander = FALSE
alert_on_spacing = FALSE // So it chasing players in space doesn't make depot explode.
alert_on_timeout = FALSE // So random fauna doesn't make depot explode.
+ corpse = null
loot = list() // Explodes, doesn't drop loot.
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
- return TRUE
-
-/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/death()
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup/death()
visible_message("[src] explodes!")
- playsound(loc, 'sound/items/timer.ogg', 30, FALSE)
+ playsound(src, 'sound/items/timer.ogg', 30, FALSE)
explosion(src, 0, 4, 4, flame_range = 2, adminlog = FALSE, cause = "[name] autogib")
qdel(src)
-/mob/living/simple_animal/hostile/syndicate/melee/space
- name = "Syndicate Commando"
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- icon_state = "syndicate_space_sword"
- icon_living = "syndicate_space_sword"
- speed = 1.5
- death_sound = 'sound/mecha/mechmove03.ogg'
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatecommando,
- /obj/effect/decal/cleanable/blood/innards,
- /obj/effect/decal/cleanable/blood,
- /obj/effect/gibspawner/generic,
- /obj/effect/gibspawner/generic)
+//////////////////////////////
+// MARK: DEPOT OFFICER
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/depot/officer
+ name = "Syndicate Officer"
+ syndie_flags = ESHIELD
+ alert_on_death = TRUE
+ parry_chance = 20
-/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
- return TRUE
+/mob/living/simple_animal/hostile/syndicate/depot/officer/Initialize(mapload)
+ if(prob(50))
+ // 50% chance of switching to ranged variant.
+ melee_type = MELEE_WEAPON_NONE
+ ranged = TRUE
+ ranged_type = RANGED_WEAPON_M90
+ projectilesound = SOUND_AR
+ casingtype = /obj/item/ammo_casing/a556
+ rapid = 3
+ retreat_distance = 5
+ minimum_distance = 3
+ . = ..()
-/mob/living/simple_animal/hostile/syndicate/ranged
- ranged = TRUE
- rapid = 2
- retreat_distance = 5
- minimum_distance = 5
- icon_state = "syndicate_smg"
- icon_living = "syndicate_smg"
- projectilesound = 'sound/weapons/gunshots/gunshot.ogg'
- casingtype = /obj/item/ammo_casing/c45
+//////////////////////////////
+// MARK: DEPOT QM
+//////////////////////////////
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite
+ name = "Syndicate Quartermaster"
+ damage_coeff = list(BRUTE = 0.6, BURN = 0.6, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
+ maxbodytemp = FIRE_IMMUNITY_MAX_TEMP_PROTECT
+ icon_state = JAEGER
+ icon_living = JAEGER
+ visor = VISOR_JAEGER
+ alert_on_shield_breach = TRUE
+ syndie_flags = MODSUIT | ADRENAL
+ eshield_prob = 0
+ melee_type = MELEE_WEAPON_DSWORD
+ melee_damage_lower = 34
+ melee_damage_upper = 34
+ parry_chance = 30
+ corpse = /obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite/depot
-/mob/living/simple_animal/hostile/syndicate/ranged/space
- icon_state = "syndicate_space_smg"
- icon_living = "syndicate_space_smg"
- name = "Syndicate Commando"
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- speed = 1.5
- death_sound = 'sound/mecha/mechmove03.ogg'
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatecommando,
- /obj/effect/decal/cleanable/blood/innards,
- /obj/effect/decal/cleanable/blood,
- /obj/effect/gibspawner/generic,
- /obj/effect/gibspawner/generic)
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite/Initialize(mapload)
+ if(prob(50))
+ // 50% chance of switching to ranged variant.
+ melee_type = MELEE_WEAPON_NONE
+ ranged = TRUE
+ ranged_type = RANGED_WEAPON_SR
+ weapon_idle = RANGED_WEAPON_SR_IDLE
+ projectilesound = SOUND_SR
+ casingtype = /obj/item/ammo_casing/penetrator // Ignores cover.
+ retreat_distance = 2
+ minimum_distance = 2
+ . = ..()
+ return INITIALIZE_HINT_LATELOAD
-/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
- return TRUE
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite/LateInitialize()
+ if(istype(depotarea))
+ var/list/key_candidates = list()
+ for(var/mob/living/simple_animal/hostile/syndicate/depot/officer/O in GLOB.alive_mob_list)
+ key_candidates += O
+ if(length(key_candidates))
+ var/mob/living/simple_animal/hostile/syndicate/depot/officer/O = pick(key_candidates)
+ O.shield_key = TRUE
+ depotarea.shields_up()
-/mob/living/simple_animal/hostile/syndicate/ranged/space/autogib
- loot = list(/obj/item/salvage/loot/syndicate,
- /obj/effect/mob_spawn/human/corpse/syndicatecommando,
- /obj/effect/decal/cleanable/blood/innards,
- /obj/effect/decal/cleanable/blood,
- /obj/effect/gibspawner/generic,
- /obj/effect/gibspawner/generic)
+/mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite/death()
+ if(!istype(depotarea))
+ return ..()
+ if(!length(depotarea.shield_list)) // Not opening lockers without getting shields down
+ depotarea.unlock_lockers()
+ return ..()
+//////////////////////////////
+// MARK: VISCERATOR
+//////////////////////////////
/mob/living/simple_animal/hostile/viscerator
name = "viscerator"
desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
@@ -396,7 +878,7 @@
melee_damage_upper = 15
attacktext = "cuts"
attack_sound = 'sound/weapons/bladeslice.ogg'
- faction = list("syndicate")
+ faction = list(SYNDICATE)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
mob_size = MOB_SIZE_TINY
@@ -409,3 +891,41 @@
/mob/living/simple_animal/hostile/viscerator/Initialize(mapload)
. = ..()
AddComponent(/datum/component/swarming)
+
+#undef BLOOD_HELMET
+#undef BLOOD_MASK
+#undef BLOOD_ARMOR
+#undef BLOOD_SUIT
+#undef BLOOD_HANDS
+#undef BLOOD_SHOES
+
+#undef MELEE_WEAPON_NONE
+#undef MELEE_WEAPON_ESWORD
+#undef MELEE_WEAPON_DSWORD
+
+#undef RANGED_WEAPON_PISTOL
+#undef RANGED_WEAPON_C20R
+#undef RANGED_WEAPON_M90
+#undef RANGED_WEAPON_SR
+#undef RANGED_WEAPON_SR_IDLE
+
+#undef SOUND_MOD
+#undef SOUND_SMG
+#undef SOUND_AR
+#undef SOUND_SR
+
+#undef SYNDICATE
+#undef RAIDER
+#undef JAEGER
+
+#undef VISOR_MASK
+#undef VISOR_RAIDER
+#undef VISOR_JAEGER
+
+#undef ESHIELD
+#undef SWORD
+#undef MODSUIT
+#undef ARMOR_BOOSTER
+#undef HEALING
+#undef CRITICAL
+#undef ADRENAL
diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index c7b7099a357..5d535f3c519 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -270,8 +270,7 @@
/obj/item/mod/control/pre_equipped/traitor/Initialize(mapload)
. = ..()
- new /obj/item/clothing/mask/gas/syndicate(bag)
- new /obj/item/tank/internals/emergency_oxygen/engi/syndi(bag)
+ new /obj/item/storage/box/survival_syndie/traitor(bag)
/obj/item/mod/control/pre_equipped/traitor_elite
starting_frequency = MODLINK_FREQ_SYNDICATE
@@ -292,8 +291,7 @@
/obj/item/mod/control/pre_equipped/traitor_elite/Initialize(mapload)
. = ..()
- new /obj/item/clothing/mask/gas/syndicate(bag)
- new /obj/item/tank/internals/emergency_oxygen/engi/syndi(bag)
+ new /obj/item/storage/box/survival_syndie/traitor(bag)
/obj/item/mod/control/pre_equipped/nuclear
starting_frequency = MODLINK_FREQ_SYNDICATE
diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm
index 05e1be0b5d2..7bb4aea2527 100644
--- a/code/modules/pda/pdas.dm
+++ b/code/modules/pda/pdas.dm
@@ -147,7 +147,12 @@
..()
var/datum/data/pda/app/messenger/M = find_program(/datum/data/pda/app/messenger)
if(M)
- M.m_hidden = 1
+ M.m_hidden = TRUE
+
+/obj/item/pda/syndicate_fake
+ icon_state = "pda-syndi"
+ name = "Military PDA"
+ default_pen = /obj/item/pen/multi/syndicate
/obj/item/pda/chaplain
icon_state = "pda-chaplain"
diff --git a/code/modules/procedural_mapping/mapGenerators/syndicate_mapgen.dm b/code/modules/procedural_mapping/mapGenerators/syndicate_mapgen.dm
index a29ea754436..f1cf72d2d96 100644
--- a/code/modules/procedural_mapping/mapGenerators/syndicate_mapgen.dm
+++ b/code/modules/procedural_mapping/mapGenerators/syndicate_mapgen.dm
@@ -17,8 +17,7 @@
/datum/map_generator_module/splatter_layer/syndie_mobs
clusterCheckFlags = MAP_GENERATOR_CLUSTER_CHECK_SAME_ATOMS
- spawnableAtoms = list(/mob/living/simple_animal/hostile/syndicate = 30, \
- /mob/living/simple_animal/hostile/syndicate/melee = 20, \
+ spawnableAtoms = list(/mob/living/simple_animal/hostile/syndicate = 50, \
/mob/living/simple_animal/hostile/syndicate/ranged = 20, \
/mob/living/simple_animal/hostile/viscerator = 30)
spawnableTurfs = list()
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index b8adad970ed..07c6378ed2a 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -138,7 +138,7 @@
muzzle_flash_range = MUZZLE_FLASH_RANGE_NORMAL
/obj/item/ammo_casing/c45/nostamina
- projectile_type = /obj/item/projectile/bullet/midbullet3
+ projectile_type = /obj/item/projectile/bullet/weakbullet3
/obj/item/ammo_casing/n762
name = "7.62x38mmR round"
diff --git a/icons/effects/spawner_icons.dmi b/icons/effects/spawner_icons.dmi
index 9ba31a537ca..91f4b0fde68 100644
Binary files a/icons/effects/spawner_icons.dmi and b/icons/effects/spawner_icons.dmi differ
diff --git a/icons/mob/simple_human.dmi b/icons/mob/simple_human.dmi
index 30a715e13cd..4b7bfccbe49 100644
Binary files a/icons/mob/simple_human.dmi and b/icons/mob/simple_human.dmi differ
diff --git a/icons/obj/boxes.dmi b/icons/obj/boxes.dmi
index e0c018cb6d6..502423c891a 100644
Binary files a/icons/obj/boxes.dmi and b/icons/obj/boxes.dmi differ
diff --git a/tools/UpdatePaths/Scripts/28706_syndicate_mobs.txt b/tools/UpdatePaths/Scripts/28706_syndicate_mobs.txt
new file mode 100644
index 00000000000..d20cb3f967e
--- /dev/null
+++ b/tools/UpdatePaths/Scripts/28706_syndicate_mobs.txt
@@ -0,0 +1,14 @@
+/obj/item/storage/box/survival_syndi : /obj/item/storage/box/survival_syndie{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee : /mob/living/simple_animal/hostile/syndicate{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee/autogib : /mob/living/simple_animal/hostile/syndicate{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot : /mob/living/simple_animal/hostile/syndicate/depot{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer : /mob/living/simple_animal/hostile/syndicate/depot/officer{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory : /mob/living/simple_animal/hostile/syndicate/depot/modsuit/elite{@OLD}
+/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space : /mob/living/simple_animal/hostile/syndicate/depot/modsuit/backup
+/mob/living/simple_animal/hostile/syndicate/melee/space : /mob/living/simple_animal/hostile/syndicate/modsuit{@OLD}
+/mob/living/simple_animal/hostile/syndicate/ranged/space/@SUBTYPES : /mob/living/simple_animal/hostile/syndicate/modsuit/ranged{@OLD}
+/obj/effect/spawner/random/pool/spaceloot/modsuit_syndie : /obj/effect/spawner/random/pool/spaceloot/syndicate/mob/modsuit{@OLD}
+/obj/effect/spawner/random/pool/spaceloot/modsuit_syndie/corpse : /obj/effect/mob_spawn/human/corpse/syndicate/modsuit{@OLD}
+/obj/effect/mob_spawn/human/corpse/syndicatesoldier : /obj/effect/mob_spawn/human/corpse/syndicate{@OLD}
+/obj/effect/mob_spawn/human/corpse/syndicatecommando : /obj/effect/mob_spawn/human/corpse/syndicate/modsuit{@OLD}
+/obj/effect/mob_spawn/human/corpse/syndicatequartermaster : /obj/effect/mob_spawn/human/corpse/syndicate/modsuit/elite{@OLD}