diff --git a/_maps/map_files/generic/centcomm.dmm b/_maps/map_files/generic/centcomm.dmm index 43f777c72cc..5a1e80fe9dc 100644 --- a/_maps/map_files/generic/centcomm.dmm +++ b/_maps/map_files/generic/centcomm.dmm @@ -25,9 +25,6 @@ /obj/structure/window/reinforced, /turf/simulated/wall/indestructible/riveted, /area/space/centcomm) -"ag" = ( -/turf/simulated/wall/indestructible/fakedoor, -/area/ninja/holding) "ah" = ( /obj/effect/mapping_helpers/airlock/access/all/centcomm/general, /obj/machinery/door/airlock/centcom{ @@ -107,9 +104,6 @@ }, /turf/simulated/floor/holofloor, /area/holodeck/source_knightarena) -"at" = ( -/turf/simulated/wall/indestructible/fakedoor, -/area/ninja/outpost) "au" = ( /obj/machinery/abductor/experiment{ team = 1 @@ -399,11 +393,14 @@ /obj/item/hemostat/alien, /turf/simulated/floor/plating/abductor, /area/abductor_ship) -"bz" = ( -/obj/structure/ninjatele{ - pixel_y = 25 +"bx" = ( +/obj/structure/table/glass/reinforced/plastitanium, +/obj/machinery/kitchen_machine/microwave/upgraded{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 }, -/turf/simulated/floor/plasteel/dark, +/turf/simulated/floor/plasteel/full, /area/ninja/outpost) "bB" = ( /obj/effect/landmark/abductor/scientist, @@ -473,13 +470,6 @@ "bM" = ( /turf/simulated/floor/holofloor, /area/holodeck/source_emptycourt) -"bN" = ( -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) -"bO" = ( -/obj/structure/closet/secure_closet/bar, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "bP" = ( /obj/effect/landmark/abductor/scientist{ team = 4 @@ -491,9 +481,8 @@ /turf/simulated/floor/plasteel/dark, /area/ghost_bar) "bR" = ( -/obj/structure/reagent_dispensers/beerkeg, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "bS" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8; @@ -525,10 +514,6 @@ /obj/effect/turf_decal/tiles/department/virology/side, /turf/simulated/floor/holofloor, /area/holodeck/source_emptycourt) -"bY" = ( -/obj/machinery/economy/vending/boozeomat, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "bZ" = ( /obj/structure/chair/sofa/right, /turf/simulated/floor/carpet/black, @@ -581,26 +566,6 @@ "ch" = ( /turf/simulated/floor/holofloor/space, /area/holodeck/source_space) -"ci" = ( -/obj/structure/table, -/obj/item/storage/box/donkpockets{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/donkpockets{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/donkpockets{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/donkpockets{ - pixel_x = 3; - pixel_y = 3 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "cj" = ( /obj/machinery/abductor/gland_dispenser, /turf/simulated/floor/plating/abductor, @@ -621,12 +586,6 @@ }, /turf/simulated/floor/holofloor, /area/holodeck/source_basketball) -"co" = ( -/obj/structure/rack, -/obj/item/camera, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "cp" = ( /obj/structure/table/abductor, /obj/item/bonegel/alien, @@ -646,29 +605,12 @@ /obj/structure/bed/abductor, /turf/simulated/floor/plating/abductor, /area/abductor_ship) -"cs" = ( -/obj/structure/rack, -/obj/item/toy/sword, -/obj/item/gun/projectile/revolver/capgun, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"ct" = ( -/obj/machinery/prize_counter, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "cu" = ( /obj/effect/turf_decal/tiles/department/security/side{ dir = 8 }, /turf/simulated/floor/holofloor, /area/holodeck/source_thunderdomecourt) -"cv" = ( -/obj/machinery/computer/arcade, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "cw" = ( /obj/effect/turf_decal/tiles/department/security/side{ dir = 1 @@ -683,14 +625,6 @@ }, /turf/simulated/floor/holofloor, /area/holodeck/source_boxingcourt) -"cy" = ( -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) -"cz" = ( -/obj/effect/overlay/palmtree_r, -/obj/effect/overlay/coconut, -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) "cA" = ( /obj/structure/flora/grass/both, /turf/simulated/floor/holofloor{ @@ -728,9 +662,9 @@ /turf/simulated/floor/holofloor, /area/holodeck/source_basketball) "cG" = ( -/obj/effect/overlay/palmtree_l, -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) +/obj/structure/chair/stool/bar, +/turf/simulated/floor/plasteel/dark, +/area/ninja/outpost) "cH" = ( /obj/structure/table/wood, /obj/item/tank/internals/emergency_oxygen/double/vox, @@ -822,32 +756,10 @@ }, /turf/simulated/floor/carpet/green, /area/ghost_bar) -"cY" = ( -/obj/structure/table, -/obj/machinery/kitchen_machine/microwave/upgraded, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) -"cZ" = ( -/obj/structure/table, -/obj/item/clothing/head/that{ - pixel_x = 4; - pixel_y = 6 - }, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "da" = ( -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"db" = ( -/obj/structure/chair/stool, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"dc" = ( -/obj/item/camera, -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) +/obj/structure/showcase, +/turf/simulated/floor/wood, +/area/ninja/outpost) "dd" = ( /obj/item/electropack{ pixel_x = -5 @@ -864,21 +776,6 @@ /obj/structure/chair/office/dark, /turf/simulated/floor/plasteel/dark, /area/ghost_bar) -"df" = ( -/turf/simulated/wall/indestructible/fakeglass, -/area/ninja/outpost) -"dh" = ( -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/machinery/sleeper/upgraded, -/turf/simulated/floor/carpet/grimey, -/area/ninja/outpost) -"di" = ( -/obj/structure/table, -/obj/machinery/recharger, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "dj" = ( /obj/effect/turf_decal/tiles/department/security/side{ dir = 8 @@ -937,9 +834,7 @@ /turf/simulated/floor/plasteel/stairs/right, /area/syndicate_mothership) "du" = ( -/obj/structure/table, -/obj/item/reagent_containers/drinks/shaker, -/turf/simulated/floor/plasteel/freezer, +/turf/simulated/floor/plasteel/dark, /area/ninja/holding) "dv" = ( /obj/machinery/atmospherics/unary/cryo_cell/upgraded, @@ -948,25 +843,6 @@ }, /turf/simulated/floor/plasteel/white, /area/centcom/control) -"dw" = ( -/obj/structure/table, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) -"dx" = ( -/obj/structure/table, -/obj/item/lighter/zippo, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) -"dy" = ( -/obj/structure/table, -/obj/item/reagent_containers/drinks/cans/cola, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) -"dz" = ( -/obj/structure/table, -/obj/item/dice/d20, -/turf/simulated/floor/plasteel/freezer, -/area/ninja/holding) "dA" = ( /obj/structure/flora/tree/dead, /turf/simulated/floor/holofloor{ @@ -995,18 +871,6 @@ }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/syndicate) -"dE" = ( -/obj/structure/chair/stool, -/obj/item/clothing/head/bandana{ - pixel_y = -10 - }, -/obj/item/clothing/glasses/sunglasses, -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) -"dF" = ( -/obj/structure/chair/stool, -/turf/simulated/floor/beach/away/sand, -/area/ninja/holding) "dG" = ( /obj/effect/turf_decal/tiles/department/virology/side{ dir = 1 @@ -1050,32 +914,10 @@ /obj/structure/closet/wardrobe/mixed, /turf/simulated/floor/mineral/plastitanium/red, /area/ghost_bar) -"dT" = ( -/obj/effect/landmark/spawner/ninjastart, -/turf/simulated/floor/carpet/grimey, -/area/ninja/outpost) -"dU" = ( -/turf/simulated/floor/carpet/grimey, -/area/ninja/outpost) -"dV" = ( -/obj/structure/rack, -/obj/item/clothing/head/that{ - pixel_x = 4; - pixel_y = 6 +"dS" = ( +/turf/simulated/wall/indestructible/fakedoor{ + name = "Spider Clan Jail Cell" }, -/obj/item/clothing/under/suit/black, -/obj/item/clothing/suit/wcoat, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"dW" = ( -/obj/structure/chair/stool/bar, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"dX" = ( -/obj/item/beach_ball, -/turf/simulated/floor/beach/away/sand, /area/ninja/holding) "dY" = ( /obj/effect/turf_decal/tiles/department/virology/side{ @@ -1101,12 +943,6 @@ "ed" = ( /turf/simulated/floor/wood, /area/wizard_station) -"ee" = ( -/obj/structure/rack, -/obj/item/storage/fancy/crayons, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "ef" = ( /obj/machinery/chem_dispenser/beer, /obj/structure/table/reinforced, @@ -1119,14 +955,6 @@ /obj/effect/landmark/spawner/prisonwarp, /turf/simulated/floor/plating, /area/centcom) -"eh" = ( -/obj/machinery/economy/vending/coffee, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "ei" = ( /obj/effect/mapping_helpers/airlock/access/all/centcomm/general, /obj/machinery/door/airlock/centcom{ @@ -1201,25 +1029,6 @@ /obj/structure/sign/public/cryo, /turf/simulated/wall/indestructible/syndicate/no_diagonal, /area/ghost_bar) -"ey" = ( -/obj/structure/chair/stool, -/obj/machinery/computer/security/telescreen{ - desc = "Damn, they better have /tg/thechannel on these things."; - icon_state = "entertainment"; - name = "Entertainment monitor"; - pixel_y = -30 - }, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"ez" = ( -/obj/machinery/economy/vending/snack, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "eA" = ( /obj/structure/chair/stool{ dir = 1 @@ -1238,13 +1047,6 @@ }, /turf/simulated/floor/holofloor, /area/holodeck/source_basketball) -"eE" = ( -/turf/simulated/floor/beach/away/coastline, -/area/ninja/holding) -"eF" = ( -/obj/item/clothing/head/collectable/paper, -/turf/simulated/floor/beach/away/coastline, -/area/ninja/holding) "eG" = ( /obj/effect/turf_decal/tiles/department/security/side{ dir = 8 @@ -1349,33 +1151,6 @@ /obj/effect/spawner/window/plastitanium, /turf/simulated/floor/plating, /area/shuttle/administration) -"eY" = ( -/obj/machinery/economy/vending/cigarette, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"eZ" = ( -/obj/structure/table, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"fa" = ( -/obj/structure/chair/stool, -/obj/machinery/light/spot, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"fb" = ( -/obj/machinery/economy/vending/cola, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) -"fc" = ( -/turf/simulated/floor/beach/away/water, -/area/ninja/holding) "fd" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -1386,22 +1161,9 @@ /obj/item/clipboard, /turf/simulated/floor/plasteel/dark, /area/centcom/specops) -"fe" = ( -/obj/machinery/poolcontroller/invisible, -/turf/simulated/floor/beach/away/water, -/area/ninja/holding) "fg" = ( /turf/simulated/wall/indestructible/wood, /area/ninja/holding) -"fi" = ( -/obj/effect/spawner/window/reinforced, -/turf/simulated/floor/plating, -/area/ninja/holding) -"fj" = ( -/obj/effect/turf_decal/delivery, -/obj/effect/turf_decal/tiles/dark/checker, -/turf/simulated/floor/plasteel/white, -/area/ninja/holding) "fk" = ( /obj/machinery/door/airlock/hatch/syndicate{ autoclose = 0; @@ -1454,10 +1216,6 @@ }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) -"fu" = ( -/obj/effect/landmark/spawner/holding_facility, -/turf/simulated/floor/engine, -/area/ninja/holding) "fv" = ( /obj/structure/table/wood, /obj/item/reagent_containers/drinks/mug/novelty, @@ -1490,6 +1248,10 @@ /obj/structure/sign/service/bar, /turf/simulated/wall/indestructible/riveted, /area/ghost_bar) +"fD" = ( +/obj/machinery/economy/vending/coffee/free, +/turf/simulated/floor/plasteel/dark, +/area/ninja/outpost) "fE" = ( /obj/structure/table, /obj/item/storage/box/handcuffs, @@ -1655,6 +1417,10 @@ /obj/effect/baseturf_helper/asteroid/snow, /turf/simulated/wall/indestructible/rock/snow, /area/syndicate_mothership) +"gg" = ( +/obj/structure/showcase, +/turf/simulated/floor/wood, +/area/ninja/holding) "gh" = ( /turf/simulated/wall/indestructible/opsglass, /area/centcom) @@ -2295,10 +2061,10 @@ /area/tdome/tdomeobserve) "ib" = ( /obj/structure/table/wood, +/obj/effect/turf_decal/tiles/jobs/bar/checker, /obj/machinery/chem_dispenser/soda{ dir = 8 }, -/obj/effect/turf_decal/tiles/jobs/bar/checker, /turf/simulated/floor/plasteel, /area/tdome/tdomeobserve) "ic" = ( @@ -3552,6 +3318,10 @@ }, /turf/simulated/floor/plasteel, /area/admin) +"md" = ( +/obj/structure/chair/wood, +/turf/simulated/floor/bamboo, +/area/ninja/outpost) "me" = ( /obj/structure/rack, /obj/item/clothing/glasses/sunglasses{ @@ -3629,6 +3399,10 @@ /obj/mecha/combat/marauder/seraph/loaded, /turf/simulated/floor/plasteel, /area/admin) +"mn" = ( +/obj/effect/landmark/spawner/ninja_prison_warp, +/turf/simulated/floor/plasteel/dark, +/area/ninja/holding) "mo" = ( /obj/machinery/washing_machine, /turf/simulated/floor/plasteel/freezer, @@ -3730,6 +3504,12 @@ }, /turf/simulated/floor/plasteel, /area/admin) +"mE" = ( +/obj/structure/bed/wood, +/obj/item/bedsheet/black, +/obj/effect/landmark/spawner/ninja, +/turf/simulated/floor/wood, +/area/ninja/outpost) "mF" = ( /obj/structure/table, /obj/item/stack/sheet/glass{ @@ -4490,6 +4270,13 @@ }, /turf/simulated/floor/backrooms_carpet, /area/backrooms) +"pa" = ( +/obj/structure/table/glass/reinforced/plastitanium, +/obj/machinery/chem_dispenser/soda{ + dir = 1 + }, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "pc" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -4960,6 +4747,9 @@ }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/assault_pod) +"qQ" = ( +/turf/simulated/floor/bamboo/tatami/black, +/area/ninja/outpost) "qR" = ( /turf/simulated/wall/indestructible, /area/ghost_bar) @@ -5845,6 +5635,12 @@ /obj/structure/lattice, /turf/space, /area/space/nearstation/centcom) +"tM" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/simulated/floor/bamboo, +/area/ninja/outpost) "tN" = ( /obj/machinery/door/window/classic/normal{ dir = 1 @@ -6251,6 +6047,9 @@ }, /turf/simulated/floor/carpet, /area/admin) +"vo" = ( +/turf/simulated/floor/carpet/black, +/area/ninja/outpost) "vq" = ( /obj/structure/chair/sofa/corp, /turf/simulated/floor/transparent/glass, @@ -6464,6 +6263,11 @@ /obj/item/soap, /turf/simulated/floor/plasteel/freezer, /area/trader_station/sol) +"we" = ( +/obj/structure/table/glass/reinforced/plastitanium, +/obj/item/reagent_containers/cooking/sushimat, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "wf" = ( /obj/structure/mirror{ pixel_x = 28 @@ -7059,6 +6863,9 @@ }, /turf/simulated/floor/transparent/glass, /area/centcom/specops) +"yi" = ( +/turf/simulated/wall/indestructible/syndicate, +/area/ninja/holding) "yj" = ( /obj/structure/table/wood/fancy/royalblack, /obj/item/gun/projectile/automatic/pistol, @@ -7455,6 +7262,9 @@ }, /turf/simulated/floor/wood, /area/syndicate_mothership) +"zX" = ( +/turf/simulated/wall/indestructible/syndicate, +/area/ninja/outpost) "zY" = ( /obj/structure/table/reinforced, /obj/machinery/cooking/stovetop, @@ -7893,12 +7703,6 @@ /obj/structure/stone_tile/slab/cracked, /turf/simulated/floor/lava/lava_land_surface, /area/ruin/space/bubblegum_arena) -"Bw" = ( -/obj/structure/ninjatele{ - pixel_x = -28 - }, -/turf/simulated/floor/plasteel/dark, -/area/admin) "Bx" = ( /obj/machinery/light/small{ dir = 4 @@ -7906,11 +7710,10 @@ /turf/simulated/floor/carpet/arcade, /area/ghost_bar) "By" = ( -/obj/structure/ninjatele{ - pixel_x = 28 - }, -/turf/simulated/floor/plasteel/dark, -/area/admin) +/obj/structure/table/wood, +/obj/item/reagent_containers/drinks/tea, +/turf/simulated/floor/bamboo, +/area/ninja/outpost) "Bz" = ( /obj/machinery/door/airlock/external{ id_tag = "s_docking_airlock"; @@ -8339,7 +8142,7 @@ /area/space/centcomm) "Dd" = ( /obj/structure/rack, -/obj/item/clothing/suit/space/space_ninja, +/obj/item/clothing/suit/space_ninja, /turf/simulated/floor/engine, /area/admin) "De" = ( @@ -8398,7 +8201,7 @@ /area/ghost_bar) "Dv" = ( /obj/structure/rack, -/obj/item/clothing/head/helmet/space/space_ninja, +/obj/item/clothing/head/helmet/space_ninja, /turf/simulated/floor/engine, /area/admin) "Dw" = ( @@ -8647,6 +8450,11 @@ }, /turf/simulated/floor/wood, /area/centcom/evac) +"En" = ( +/obj/structure/closet/crate, +/obj/item/storage/box/donkpockets, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "Eo" = ( /turf/simulated/floor/holofloor{ icon_state = "sand"; @@ -8943,6 +8751,12 @@ /obj/machinery/shower/directional/south, /turf/simulated/floor/plasteel/freezer, /area/syndicate_mothership) +"FB" = ( +/obj/structure/mineral_door/wood{ + name = "Main chamber" + }, +/turf/simulated/floor/wood, +/area/ninja/outpost) "FC" = ( /obj/docking_port/stationary{ dir = 2; @@ -9368,6 +9182,9 @@ }, /turf/simulated/floor/plating, /area/centcom/suppy) +"He" = ( +/turf/simulated/floor/bamboo, +/area/ninja/outpost) "Hg" = ( /turf/simulated/wall/indestructible/riveted, /area/centcom/evac) @@ -9496,6 +9313,10 @@ /obj/structure/sign/public/drop, /turf/simulated/wall/indestructible/syndicate/no_diagonal, /area/syndicate_mothership) +"HM" = ( +/obj/machinery/economy/vending/boozeomat, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "HN" = ( /turf/simulated/floor/indestructible/necropolis, /area/ruin/space/bubblegum_arena) @@ -9929,6 +9750,10 @@ /obj/effect/turf_decal/tiles/dark/checker, /turf/simulated/floor/plasteel/white, /area/tdome/tdomeobserve) +"JC" = ( +/obj/structure/dresser, +/turf/simulated/floor/wood, +/area/ninja/outpost) "JE" = ( /obj/item/stack/sheet/plasmaglass/fifty, /obj/item/stack/sheet/plasmaglass/fifty, @@ -9971,6 +9796,10 @@ }, /turf/simulated/floor/plasteel/dark, /area/centcom/gamma) +"JN" = ( +/obj/structure/bed, +/turf/simulated/floor/plasteel/dark, +/area/ninja/holding) "JO" = ( /obj/structure/sign/cargo/dock, /turf/simulated/wall/indestructible/riveted, @@ -10544,6 +10373,10 @@ }, /turf/simulated/floor/plasteel, /area/tdome/arena) +"LR" = ( +/obj/structure/table/glass/reinforced/plastitanium, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "LT" = ( /obj/structure/table/wood/fancy/royalblack, /obj/item/storage/fancy/matches, @@ -10575,6 +10408,10 @@ }, /turf/simulated/floor/wood, /area/ghost_bar) +"Mc" = ( +/obj/item/kirbyplants/large, +/turf/simulated/floor/wood, +/area/ninja/outpost) "Md" = ( /obj/structure/sign/public/arcade, /turf/simulated/wall/indestructible/syndicate/no_diagonal, @@ -10603,6 +10440,10 @@ }, /turf/simulated/floor/plasteel/dark, /area/centcom/gamma) +"Mi" = ( +/obj/item/throwing_star, +/turf/simulated/floor/plasteel/dark, +/area/ninja/outpost) "Mk" = ( /obj/machinery/door_control/no_emag{ id = "thunderdomegen"; @@ -10627,6 +10468,12 @@ /obj/item/storage/box/trackimp, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) +"Mp" = ( +/obj/structure/mirror{ + pixel_x = 32 + }, +/turf/simulated/floor/wood, +/area/ninja/outpost) "Mq" = ( /obj/structure/table/glass/reinforced/plastitanium, /obj/machinery/computer/security/telescreen, @@ -10676,6 +10523,13 @@ }, /turf/simulated/floor/plasteel/dark, /area/centcom/suppy) +"MA" = ( +/obj/machinery/door/airlock/hatch{ + desc = "Danger: May contain robustness"; + name = "Dojo" + }, +/turf/simulated/floor/wood, +/area/ninja/outpost) "MD" = ( /obj/machinery/door/airlock/centcom{ hackProof = 1; @@ -11028,6 +10882,10 @@ }, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/administration) +"NL" = ( +/obj/structure/table/wood, +/turf/simulated/floor/bamboo, +/area/ninja/outpost) "NN" = ( /obj/structure/chair/office/dark{ dir = 8 @@ -11292,6 +11150,9 @@ }, /turf/simulated/floor/plasteel/dark, /area/centcom/specops) +"OJ" = ( +/turf/simulated/floor/wood, +/area/ninja/holding) "OK" = ( /turf/simulated/floor/plating/asteroid/ancient/airless, /area/space/nearstation/centcom) @@ -11549,6 +11410,10 @@ /obj/structure/sign/service/bar, /turf/simulated/wall/indestructible/syndicate/no_diagonal, /area/ghost_bar) +"PL" = ( +/obj/machinery/economy/vending/cigarette/free, +/turf/simulated/floor/plasteel/dark, +/area/ninja/outpost) "PM" = ( /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/metal/fifty, @@ -12254,6 +12119,11 @@ }, /turf/simulated/floor/plasteel, /area/centcom/evac) +"Sg" = ( +/obj/structure/table/glass/reinforced/plastitanium, +/obj/item/reagent_containers/cooking/board, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "Sh" = ( /obj/structure/table/wood, /obj/item/storage/bag/dice, @@ -12388,6 +12258,24 @@ /obj/machinery/door/airlock/centcom, /turf/simulated/floor/wood, /area/ghost_bar) +"SJ" = ( +/obj/structure/closet/crate/freezer, +/obj/item/food/sliced/sushi_sake, +/obj/item/food/sliced/sushi_sake, +/obj/item/food/sliced/sushi_masago, +/obj/item/food/sliced/sushi_masago, +/obj/item/food/sliced/sushi_ikura, +/obj/item/food/sliced/sushi_ikura, +/obj/item/food/sliced/sushi_ebi, +/obj/item/food/sliced/sushi_ebi, +/obj/item/food/sliced/sushi_tobiko, +/obj/item/food/sliced/sushi_tobiko, +/obj/item/food/sliced/sushi_tai, +/obj/item/food/sliced/sushi_tai, +/obj/item/food/sushi_unagi, +/obj/item/food/sushi_unagi, +/turf/simulated/floor/plasteel/full, +/area/ninja/outpost) "SK" = ( /obj/structure/table/reinforced, /obj/item/storage/toolbox/mechanical, @@ -12574,6 +12462,9 @@ /obj/machinery/computer/camera_advanced/shuttle_docker/ert, /turf/simulated/floor/mineral/plastitanium/red, /area/shuttle/specops) +"TE" = ( +/turf/simulated/floor/wood, +/area/ninja/outpost) "TF" = ( /obj/machinery/recharger/wallcharger/upgraded{ pixel_x = 4; @@ -13145,6 +13036,10 @@ }, /turf/simulated/floor/plasteel, /area/centcom/evac) +"VM" = ( +/obj/structure/toilet/directional/north, +/turf/simulated/floor/plasteel/dark, +/area/ninja/holding) "VN" = ( /obj/effect/spawner/window/reinforced, /turf/simulated/floor/plating, @@ -13499,6 +13394,10 @@ /obj/item/kirbyplants/large, /turf/simulated/floor/transparent/glass/reinforced, /area/centcom/control) +"WY" = ( +/obj/structure/bookcase/random, +/turf/simulated/floor/wood, +/area/ninja/outpost) "WZ" = ( /obj/structure/table/reinforced, /obj/item/crowbar/red, @@ -13572,6 +13471,11 @@ }, /turf/simulated/floor/plasteel, /area/centcom/evac) +"Xm" = ( +/obj/structure/target_stake, +/obj/item/target, +/turf/simulated/floor/plasteel/dark, +/area/ninja/outpost) "Xn" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/poddoor/multi_tile/impassable/triple{ @@ -50033,10 +49937,10 @@ aN aN aN aN -ac -df -df -ac +aN +aN +aN +aN aN aN aN @@ -50290,10 +50194,10 @@ aN aN aN aN -ac -dU -dT -ac +aN +aN +aN +aN aN aN aN @@ -50545,12 +50449,12 @@ aN aN aN aN -ac -at -ac -dh -dU -ac +aN +aN +aN +aN +aN +aN aN aN aN @@ -50802,12 +50706,12 @@ aN aN aN aN -ac -aB -aB -aB -aB -ac +aN +aN +aN +aN +aN +aN aN aN aN @@ -51059,12 +50963,12 @@ aN aN aN aN -ac -bz -aB -aB -aB -ac +aN +aN +aN +aN +aN +aN aN aN aN @@ -51316,12 +51220,12 @@ aN aN aN aN -ac -aB -aB -aB -aB -ac +aN +aN +aN +aN +aN +aN aN aN aN @@ -51573,12 +51477,12 @@ aN aN aN aN -ac -ac -ac -ac -ac -ac +aN +aN +aN +aN +aN +aN aN aN aN @@ -51830,15 +51734,15 @@ aN aN aN aN -fg -fg -fg -fg -fg -fg -fg -fg -fg +aN +aN +aN +aN +aN +aN +aN +aN +aN aN aN aN @@ -52086,27 +51990,27 @@ aN aN aN aN -aN -fg -cY -cY -di -dV -ee -ee -eY -fg -fg -fg -fg -aN -aN -aN -aN -aN -aN -aN -aN +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi +yi aN aN aN @@ -52343,27 +52247,27 @@ aN aN aN aN -aN -ae -bN -bN -bN -da -da -da -da -fi -fu -fu -fg -aN -aN -aN -aN -aN -aN -aN -aN +yi +VM +mn +JN +yi +VM +mn +JN +yi +VM +mn +JN +yi +VM +mn +JN +yi +VM +mn +JN +yi aN aN aN @@ -52600,27 +52504,27 @@ aN aN aN aN -aN -ae -bO -bN +yi du -dW -da -da -da -fj -fu -fu -fg -aN -aN -aN -aN -aN -aN -aN -aN +du +du +ae +du +du +du +ae +du +du +du +ae +du +du +du +ae +du +du +du +yi aN aN aN @@ -52857,27 +52761,27 @@ aN aN aN aN -aN +yi +dS ae -bR -bN -dw -dW -da -da -da -fj -fu -fu -fg -aN -aN -aN -aN -aN -aN -aN -aN +ae +yi +dS +ae +ae +yi +dS +ae +ae +yi +dS +ae +ae +yi +dS +ae +ae +yi aN aN aN @@ -53113,29 +53017,29 @@ aN aN aN aN -aN -aN -ae -bR -bN -dx -dW -da -da -da -fi -fu -fu +yi fg -aN -aN -aN -aN -aN -aN -aN -aN -aN +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +fg +yi aN aN aN @@ -53370,29 +53274,29 @@ aN aN aN aN -aN -aN +yi fg -bY -bN -dy -dW -da -da -db +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ +gg +OJ +gg +OJ +OJ +OJ +OJ +OJ +OJ +OJ +OJ fg -fg -fg -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN +yi aN aN aN @@ -53627,29 +53531,29 @@ aN aN aN aN -aN -aN -fg -ci -cZ -dz -dW -da -ey -eZ -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +MA +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +zX aN aN aN @@ -53884,29 +53788,29 @@ aN aN aN aN -aN -aN -fg -co +zX +zX +ac da -da -da -da -da -fa -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +TE +TE +TE +TE +TE +TE +TE +TE +TE +PL +fD +aB +aB +cG +we +bR +pa +ac +zX aN aN aN @@ -54142,28 +54046,28 @@ aN aN aN aN -aN -fg -cs -da -da -da -da -da -db -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +TE +TE +TE +TE +TE +TE +TE +TE +TE +TE +aB +aB +aB +aB +cG +LR +bR +bx +ac +zX aN aN aN @@ -54399,28 +54303,28 @@ aN aN aN aN -aN -fg -ct -da -da -da -da -ey -eZ -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +Mc +TE +He +He +He +He +He +He +TE +TE +aB +qQ +qQ +qQ +cG +Sg +bR +HM +ac +zX aN aN aN @@ -54656,28 +54560,28 @@ aN aN aN aN -aN -fg -cv -db -da -da -da -da -db -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +WY +TE +He +md +By +NL +tM +He +TE +TE +aB +qQ +qQ +qQ +cG +LR +bR +En +ac +zX aN aN aN @@ -54913,28 +54817,28 @@ aN aN aN aN -aN -fg -cy -cy -cy -cy -eh -ez -fb -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +WY +TE +He +md +NL +NL +tM +He +TE +TE +aB +qQ +qQ +qQ +cG +LR +bR +SJ +ac +zX aN aN aN @@ -55170,28 +55074,28 @@ aN aN aN aN -aN -fg -cz -cy -cy -cy -cy -eE -fc -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +WY +TE +He +md +NL +By +tM +He +TE +TE +aB +aB +aB +aB +aB +bR +bR +bR +ac +zX aN aN aN @@ -55427,28 +55331,28 @@ aN aN aN aN -aN -fg -cy -cy -dE -cy -cy -eE -fc -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +WY +TE +He +md +By +NL +tM +He +TE +TE +aB +aB +aB +ac +ac +ac +ac +ac +ac +zX aN aN aN @@ -55684,28 +55588,28 @@ aN aN aN aN -aN -ag -cy -dc -cy -dX -cy -eE -fc -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +Mc +TE +He +He +He +He +He +He +TE +TE +aB +aB +aB +ac +Mc +TE +TE +TE +ac +zX aN aN aN @@ -55941,28 +55845,28 @@ aN aN aN aN -aN -fg -cy -cy -dF -cy -cy -eF -fc -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +TE +TE +TE +TE +TE +TE +TE +TE +TE +TE +aB +aB +aB +FB +TE +vo +vo +mE +ac +zX aN aN aN @@ -56198,28 +56102,28 @@ aN aN aN aN -aN -fg -cG -cy -cz -cy -cy -eE -fe -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +da +TE +TE +TE +TE +TE +TE +TE +TE +TE +aB +aB +aB +ac +JC +Mp +TE +TE +ac +zX aN aN aN @@ -56455,28 +56359,28 @@ aN aN aN aN -aN -fg -fg -fg -fg -fg -fg -fg -fg -fg -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +aB +Mi +aB +ac +ac +ac +ac +ac +ac +zX aN aN aN @@ -56712,28 +56616,28 @@ aN aN aN aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN -aN +zX +zX +zX +zX +zX +zX +zX +zX +zX +zX +zX +ac +Mi +Xm +Mi +ac +zX +zX +zX +zX +zX +zX aN aN aN @@ -56979,13 +56883,13 @@ aN aN aN aN -aN -aN -aN -aN -aN -aN -aN +zX +ac +ac +ac +ac +ac +zX aN aN aN @@ -57236,13 +57140,13 @@ aN aN aN aN -aN -aN -aN -aN -aN -aN -aN +zX +zX +zX +zX +zX +zX +zX aN aN aN @@ -72507,7 +72411,7 @@ wk vK Bf Bp -Bw +vK wk wk wk @@ -74049,7 +73953,7 @@ wk vK Bg Bq -By +vK wk wk wk diff --git a/code/__DEFINES/gamemode.dm b/code/__DEFINES/gamemode.dm index cf3fc5af889..d4c9eebed37 100644 --- a/code/__DEFINES/gamemode.dm +++ b/code/__DEFINES/gamemode.dm @@ -64,6 +64,7 @@ #define SPECIAL_ROLE_TOURIST "Tourist" #define SPECIAL_ROLE_HERETIC "Heretic" #define SPECIAL_ROLE_EVENTMISC "Event Role" +#define SPECIAL_ROLE_NINJA "Space Ninja" // Constants used by code which checks the status of nuclear blasts during a // round, regardless of original game mode, e.g. setting the ending cinematic. diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index b73f39bf14a..8c86281e709 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -45,6 +45,7 @@ #define ROLE_EVENTMISC "eventmisc" #define ROLE_GHOST "ghost role" #define ROLE_ELITE "lavaland elite" +#define ROLE_NINJA "ninja" // Misc jobban categories #define ROLEBAN_AHUD "AntagHUD" @@ -71,6 +72,7 @@ GLOBAL_LIST_INIT(special_roles_antags, list( ROLE_WIZARD = /datum/game_mode/wizard, // Wizard ROLE_MIND_FLAYER, ROLE_HERETIC, + ROLE_NINJA, // UNUSED/BROKEN ANTAGS // ROLE_HOG_GOD = /datum/game_mode/hand_of_god, diff --git a/code/__DEFINES/rolebans.dm b/code/__DEFINES/rolebans.dm index b4d3d033424..62f6b39b497 100644 --- a/code/__DEFINES/rolebans.dm +++ b/code/__DEFINES/rolebans.dm @@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(antag_roles, list( ROLE_GUARDIAN, ROLE_MORPH, ROLE_TSPIDER, + ROLE_NINJA, )) // Bannable other roles diff --git a/code/__DEFINES/uplinks_defines.dm b/code/__DEFINES/uplinks_defines.dm index c8bdcd52ef7..beb98ecc593 100644 --- a/code/__DEFINES/uplinks_defines.dm +++ b/code/__DEFINES/uplinks_defines.dm @@ -1,5 +1,6 @@ #define UPLINK_TYPE_TRAITOR "traitor" #define UPLINK_TYPE_NUCLEAR "nuclear" +#define UPLINK_TYPE_NINJA "ninja" #define UPLINK_TYPE_SST "sst" #define UPLINK_TYPE_SIT "sit" #define UPLINK_TYPE_ADMIN "admin" diff --git a/code/_globalvars/mapping_vars.dm b/code/_globalvars/mapping_vars.dm index 281d279806d..0e359da6558 100644 --- a/code/_globalvars/mapping_vars.dm +++ b/code/_globalvars/mapping_vars.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(newplayer_start) GLOBAL_LIST_EMPTY(latejoin) GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these GLOBAL_LIST_EMPTY(syndieprisonwarp) //contractor targets go to these +GLOBAL_LIST_EMPTY(ninjaprisonwarp) // ninja targets go to these GLOBAL_LIST_EMPTY(antagextractwarp) // exfiltrating antags go here GLOBAL_LIST_EMPTY(backroomswarp) //backrooms hallucinators go to these GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these. @@ -37,7 +38,6 @@ GLOBAL_LIST_EMPTY(aroomwarp) GLOBAL_LIST_EMPTY(prisonsecuritywarp) //prison security goes to these GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped GLOBAL_LIST_EMPTY(nukedisc_respawn) -GLOBAL_LIST_EMPTY(ninjastart) GLOBAL_LIST_EMPTY(carplist) //list of all carp-spawn landmarks GLOBAL_LIST_EMPTY(syndicateofficer) GLOBAL_LIST_EMPTY(roundstart_observer_start) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 11b09031fc9..21245dc3fde 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -408,6 +408,18 @@ else . += "thrall|NO" +/datum/mind/proc/memory_edit_space_ninja(mob/living/carbon/human/H) + . = _memory_edit_header("space_ninja") + var/datum/antagonist/space_ninja/ninja = has_antag_datum(/datum/antagonist/space_ninja) + if(ninja) + . += "SPACE NINJA|no" + if(!ninja.has_antag_objectives()) + . += "
Objectives are empty! Randomize!" + else + . += "space_ninja|NO" + + . += _memory_edit_role_enabled(ROLE_NINJA) + /datum/mind/proc/memory_edit_mind_flayer(mob/living/carbon/human/H) . = _memory_edit_header("mind_flayer") var/datum/antagonist/mindflayer/flayer = has_antag_datum(/datum/antagonist/mindflayer) @@ -605,6 +617,8 @@ sections["changeling"] = memory_edit_changeling(H) /** VAMPIRE ***/ sections["vampire"] = memory_edit_vampire(H) + /** SPACE NINJA */ + sections["space_ninja"] = memory_edit_space_ninja(H) /** MINDFLAYER ***/ sections["mind_flayer"] = memory_edit_mind_flayer(H) /** HERETIC ***/ @@ -1169,6 +1183,19 @@ log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]") message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]") + else if(href_list["space_ninja"]) + switch(href_list["space_ninja"]) + if("clear") + if(has_antag_datum(/datum/antagonist/space_ninja)) + remove_antag_datum(/datum/antagonist/space_ninja) + log_admin("[key_name(usr)] has de-ninja'd [key_name(current)].") + message_admins("[key_name(usr)] has de-ninja'd [key_name(current)].") + if("space_ninja") + make_space_ninja() + log_admin("[key_name(usr)] has ninja'd [key_name(current)].") + to_chat(current, "Your training awakens, and a myserious set of gear teleports in around you... You are a Space Ninja!") + message_admins("[key_name(usr)] has ninja'd [key_name(current)].") + else if(href_list["vampthrall"]) switch(href_list["vampthrall"]) if("clear") @@ -1826,6 +1853,11 @@ add_antag_datum(/datum/antagonist/mindflayer) SSticker.mode.mindflayers |= src +/datum/mind/proc/make_space_ninja() + if(!has_antag_datum(/datum/antagonist/space_ninja)) + add_antag_datum(/datum/antagonist/space_ninja) + SSticker.mode.ninjas |= src + /datum/mind/proc/make_heretic() if(!has_antag_datum(/datum/antagonist/heretic)) add_antag_datum(/datum/antagonist/heretic) diff --git a/code/datums/uplink_items/uplink_general.dm b/code/datums/uplink_items/uplink_general.dm index becc5a73129..a47c7130e33 100644 --- a/code/datums/uplink_items/uplink_general.dm +++ b/code/datums/uplink_items/uplink_general.dm @@ -182,6 +182,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous category = "Highly Visible and Dangerous Weapons" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/dangerous/pistol name = "FK-69 Stechkin Pistol" @@ -243,7 +244,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/chainsaw/syndie cost = 65 surplus = 0 // This has caused major problems with un-needed chainsaw massacres. Bwoink bait. - excludefrom = list(UPLINK_TYPE_NUCLEAR) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_NINJA) can_discount = FALSE // Too gamer. /datum/uplink_item/dangerous/universal_gun_kit @@ -275,6 +276,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "Ammunition" surplus = 0 // Getting these in a discount or surplus is not a good time. can_discount = FALSE + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/ammo/pistol name = "Stechkin - 10mm Magazine" @@ -317,6 +319,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/stealthy_weapons category = "Stealthy and Inconspicuous Weapons" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/stealthy_weapons/garrote name = "Fiber Wire Garrote" @@ -325,6 +328,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/garrote reference = "GAR" cost = 30 + excludefrom = list() /datum/uplink_item/stealthy_weapons/cameraflash name = "Camera Flash" @@ -342,6 +346,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "STK" item = /obj/item/storage/box/syndie_kit/throwing_weapons cost = 15 + excludefrom = list() /datum/uplink_item/stealthy_weapons/edagger name = "Energy Dagger" @@ -349,6 +354,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "EDP" item = /obj/item/pen/edagger cost = 10 + excludefrom = list() /datum/uplink_item/stealthy_weapons/foampistol name = "Toy Gun (with Stun Darts)" @@ -387,6 +393,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/reagent_containers/glass/bottle/traitor cost = 10 surplus = 0 // Requires another item to function. + excludefrom = list() /datum/uplink_item/stealthy_weapons/silencer name = "Universal Suppressor" @@ -416,6 +423,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/explosives category = "Grenades and Explosives" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/explosives/plastic_explosives name = "Composition C-4" @@ -487,6 +495,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "TARG" item = /obj/item/grenade/chem_grenade/tar cost = 7 + excludefrom = list() //////////////////////////////////////// // MARK: STEALTHY TOOLS @@ -494,6 +503,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/stealthy_tools category = "Stealth and Camouflage Items" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/stealthy_tools/forgers_kit name = "Forger's Kit" @@ -526,6 +536,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "THIG" item = /obj/item/clothing/glasses/chameleon/thermal cost = 15 + excludefrom = list() /datum/uplink_item/stealthy_tools/night name = "Nightvision Chameleon Glasses" @@ -533,6 +544,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "TNIG" item = /obj/item/clothing/glasses/chameleon/night cost = 5 + excludefrom = list() /datum/uplink_item/stealthy_tools/agent_card name = "Agent ID Card" @@ -547,6 +559,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "CP" item = /obj/item/chameleon cost = 25 + excludefrom = list() /datum/uplink_item/stealthy_tools/chameleon_counter name = "Chameleon Counterfeiter" @@ -562,6 +575,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/box/syndie_kit/camera_bug cost = 5 surplus = 90 + excludefrom = list() /datum/uplink_item/stealthy_tools/dnascrambler name = "DNA Scrambler" @@ -569,6 +583,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "DNAS" item = /obj/item/dnascrambler cost = 7 + excludefrom = list() /datum/uplink_item/stealthy_tools/smugglersatchel name = "Smuggler's Satchel" @@ -615,6 +630,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "HM" item = /obj/item/handheld_mirror cost = 5 + excludefrom = list() //////////////////////////////////////// // MARK: DEVICES AND TOOLS @@ -623,6 +639,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/device_tools category = "Devices and Tools" abstract = 1 + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/device_tools/emag name = "Cryptographic Sequencer" @@ -658,6 +675,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "NCAI" item = /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium cost = 10 + excludefrom = list() /datum/uplink_item/device_tools/syndicate_teleporter name = "Experimental Syndicate Teleporter" @@ -692,6 +710,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "TAR" item = /obj/item/reagent_containers/spray/sticky_tar cost = 10 + excludefrom = list() /datum/uplink_item/device_tools/binary name = "Binary Translator Key" @@ -739,6 +758,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) name = "Advanced Pinpointer" desc = "A pinpointer that tracks any specified coordinates, DNA string, high value item or the nuclear authentication disk." reference = "ADVP" + excludefrom = list() item = /obj/item/pinpointer/advpinpointer cost = 10 can_discount = FALSE @@ -749,6 +769,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "AID" item = /obj/item/multitool/ai_detect cost = 5 + excludefrom = list() /datum/uplink_item/device_tools/jammer name = "Radio Jammer" @@ -756,6 +777,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "RJ" item = /obj/item/jammer cost = 20 + excludefrom = list() /datum/uplink_item/device_tools/decoy_nade name = "Decoy Grenade Kit" @@ -763,6 +785,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "DCY" item = /obj/item/storage/box/syndie_kit/decoy cost = 20 + excludefrom = list() //////////////////////////////////////// // MARK: SPACE SUITS AND HARDSUITS @@ -771,6 +794,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/suits category = "Space Suits and MODsuits" surplus = 10 //I am setting this to 10 as there are a bunch of modsuit parts in here that should be weighted to 10. Suits and modsuits adjusted below. + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/suits/space_suit name = "Syndicate Space Suit" @@ -787,6 +811,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "MSTV" item = /obj/item/mod/module/visor/thermal cost = 15 // Don't forget, you need to get a modsuit to go with this + excludefrom = list() /datum/uplink_item/suits/night name = "MODsuit Night Visor Module" @@ -794,6 +819,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "MSNV" item = /obj/item/mod/module/visor/night cost = 5 // It's night vision, rnd pumps out those goggles for anyone man. + excludefrom = list() /datum/uplink_item/suits/plate_compression name = "MODsuit Plate Compression Module" @@ -809,6 +835,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "MSCM" item = /obj/item/mod/module/chameleon cost = 10 + excludefrom = list() /datum/uplink_item/suits/noslip name = "MODsuit Anti-Slip Module" @@ -816,6 +843,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "MSNS" item = /obj/item/mod/module/noslip cost = 5 + excludefrom = list() /datum/uplink_item/suits/springlock_module name = "Heavily Modified Springlock MODsuit Module" @@ -831,6 +859,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "FNAF" item = /obj/item/mod/module/springlock/bite_of_87 cost = 5 + excludefrom = list() /datum/uplink_item/suits/hidden_holster name = "Hidden Holster Module" @@ -845,6 +874,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "SGM" item = /obj/item/mod/module/dispenser/smoke cost = 10 + excludefrom = list() //////////////////////////////////////// // MARK: IMPLANTS @@ -852,6 +882,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/bio_chips category = "Bio-chips" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/bio_chips/freedom name = "Freedom Bio-chip" @@ -873,6 +904,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "ESI" item = /obj/item/bio_chip_implanter/storage cost = 40 + excludefrom = list() /datum/uplink_item/bio_chips/mindslave name = "Mindslave Bio-chip" @@ -917,6 +949,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/cyber_implants category = "Cybernetic Implants" + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/cyber_implants/hackerman_deck name = "Binyat Wireless Hacking System Autoimplanter" @@ -935,6 +968,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "RZR" item = /obj/item/autosurgeon/organ/syndicate/oneuse/razorwire cost = 20 + excludefrom = list() /datum/uplink_item/cyber_implants/scope_eyes name = "Hardened Kaleido Optics Eyes Autoimplanter" @@ -944,6 +978,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "KOE" item = /obj/item/autosurgeon/organ/syndicate/oneuse/scope_eyes cost = 10 + excludefrom = list() /datum/uplink_item/cyber_implants/mantis_kit name = "'Naginata' Mantis Blades Kit" @@ -956,7 +991,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 50 surplus = 0 can_discount = FALSE - excludefrom = list(UPLINK_TYPE_NUCLEAR) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_NINJA) //////////////////////////////////////// // MARK: POINTLESS BADASSERY @@ -965,6 +1000,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/badass category = "(Pointless) Badassery" surplus = 0 + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/badass/pen name = "Syndicate Fountain Pen" @@ -1025,6 +1061,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "Bundles and Telecrystals" surplus = 0 can_discount = FALSE + excludefrom = list(UPLINK_TYPE_NINJA) /datum/uplink_item/bundles_tc/telecrystal name = "Raw Telecrystal" diff --git a/code/datums/uplink_items/uplink_nuclear.dm b/code/datums/uplink_items/uplink_nuclear.dm index 2a88befdb8e..1b76874a77f 100644 --- a/code/datums/uplink_items/uplink_nuclear.dm +++ b/code/datums/uplink_items/uplink_nuclear.dm @@ -550,7 +550,7 @@ reference = "KMI" item = /obj/item/bio_chip_implanter/krav_maga cost = 25 - uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/bio_chips/uplink/nuclear name = "Nuclear Uplink Bio-chip" @@ -661,34 +661,34 @@ /datum/uplink_item/stealthy_weapons/cqc/nuke reference = "NCQC" cost = 40 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/explosives/syndicate_bomb/nuke reference = "NSB" cost = 55 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) hijack_only = FALSE /datum/uplink_item/explosives/emp_bomb/nuke reference = "NSBEMP" cost = 50 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/explosives/atmosfiregrenades/nuke reference = "NAPG" cost = 60 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/stealthy_tools/chameleon/nuke reference = "NCHAM" item = /obj/item/storage/box/syndie_kit/chameleon/nuke cost = 30 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/stealthy_tools/syndigaloshes/nuke reference = "NNSSS" cost = 20 - excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/explosives/detomatix/nuclear desc = "When inserted into a personal digital assistant, this cartridge gives you five opportunities to detonate PDAs of crew members who have their message feature enabled. The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer. It has a chance to detonate your PDA. This version comes with a program to toggle your nuclear shuttle blast doors remotely." diff --git a/code/datums/uplink_items/uplink_special.dm b/code/datums/uplink_items/uplink_special.dm index c98f3a1ed6e..b48e2a393d8 100644 --- a/code/datums/uplink_items/uplink_special.dm +++ b/code/datums/uplink_items/uplink_special.dm @@ -3,7 +3,7 @@ category = "Special Offers" can_discount = FALSE surplus = 0 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA) /datum/uplink_item/special/autosurgeon name = "Syndicate Autosurgeon" diff --git a/code/datums/uplink_items/uplink_traitor.dm b/code/datums/uplink_items/uplink_traitor.dm index e2e8df793c6..f08211589fa 100644 --- a/code/datums/uplink_items/uplink_traitor.dm +++ b/code/datums/uplink_items/uplink_traitor.dm @@ -4,7 +4,7 @@ /datum/uplink_item/jobspecific category = "Job Specific Tools" - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) // Stops the job specific category appearing for nukies + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) // Stops the job specific category appearing for nukies //Clown /datum/uplink_item/jobspecific/clowngrenade @@ -347,7 +347,7 @@ reference = "PP" item = /obj/item/storage/box/syndie_kit/poisoner cost = 10 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) job = list("Head of Personnel", "Quartermaster", "Cargo Technician", "Librarian", "Coroner", "Psychiatrist", "Virologist") // Tarot card generator, librarian and Chaplain. @@ -368,7 +368,7 @@ /datum/uplink_item/species_restricted category = "Species Specific Gear" - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) // Stops the job specific category appearing for nukies + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) // Stops the job specific category appearing for nukies //skrell /datum/uplink_item/species_restricted/lovepen @@ -469,7 +469,7 @@ reference = "BLSG" item = /obj/item/gun/projectile/automatic/shotgun/bulldog/traitor cost = 50 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/ammo/bull_rubbershot name = "Bulldog - 12g Rubbershot Magazine" @@ -477,7 +477,7 @@ reference = "12BRU" item = /obj/item/ammo_box/magazine/m12g/rubbershot cost = 10 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/dangerous/guardian name = "Holoparasites" @@ -485,7 +485,7 @@ desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an organic host as a home base and source of fuel. \ The holoparasites are unable to incoporate themselves to changeling and vampire agents." item = /obj/item/storage/box/syndie_kit/guardian/uplink - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) cost = 60 refund_path = /obj/item/guardiancreator/tech/choose refundable = TRUE @@ -506,7 +506,7 @@ reference = "SCS" item = /obj/item/sleeping_carp_scroll cost = 65 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) can_discount = FALSE /datum/uplink_item/stealthy_weapons/bearserk @@ -525,7 +525,7 @@ reference = "SBM" item = /obj/item/storage/belt/military/traitor cost = 10 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/stealthy_tools/frame name = "F.R.A.M.E. PDA Cartridge" @@ -535,7 +535,7 @@ telecrystals normally." reference = "FRAME" item = /obj/item/cartridge/frame - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) cost = 20 /datum/uplink_item/stealthy_tools/voice_modulator @@ -589,7 +589,7 @@ reference = "CGM" item = /obj/item/clothing/gloves/color/black/krav_maga cost = 50 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/device_tools/extraction_beacon name = "Extraction Flare" @@ -597,7 +597,7 @@ reference = "EXTF" item = /obj/item/wormhole_jaunter/extraction limited_stock = 1 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/device_tools/hyper_medipen name = "Hyper-regenerative Medipen" @@ -615,7 +615,7 @@ item = /obj/item/thermal_drill/syndicate cost = 5 surplus = 0 // I feel like its amazing for one objective and one objective only. Far too specific. - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/suits/modsuit name = "Syndicate MODsuit" @@ -628,7 +628,7 @@ item = /obj/item/mod/control/pre_equipped/traitor cost = 30 surplus = 60 //I have upped the chance of modsuits from 40, as I do feel they are much more worthwhile with the base modsuit no longer being 8 tc, and the high armor values of the elite. - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/suits/modsuit_elite name = "Syndicate Elite MODsuit" @@ -638,7 +638,7 @@ item = /obj/item/mod/control/pre_equipped/traitor_elite cost = 45 //45 to start, no holopara / ebow. surplus = 60 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /// Nukies get Nuclear Uplink Bio-chip instead /datum/uplink_item/bio_chips/uplink @@ -647,7 +647,7 @@ reference = "UI" item = /obj/item/bio_chip_implanter/uplink cost = 70 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) surplus = 0 can_discount = FALSE @@ -661,7 +661,7 @@ reference = "QLSC" item = /obj/item/autosurgeon/organ/syndicate/oneuse/sensory_enhancer cost = 40 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) //No, nukies do not get to dodge bullets. + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) //No, nukies do not get to dodge bullets. /datum/uplink_item/species_restricted/skinmonger name = "Skinmonger Autoimplanter" @@ -680,7 +680,7 @@ reference = "SPC" item = /obj/item/deck/cards/syndicate cost = 2 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) surplus = 40 /datum/uplink_item/badass/plasticbag @@ -689,7 +689,7 @@ reference = "PBAG" item = /obj/item/storage/bag/plasticbag cost = 1 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/bundles_tc/contractor name = "Syndicate Contractor Kit" @@ -697,7 +697,7 @@ reference = "SCOK" cost = 100 item = /obj/item/storage/box/syndie_kit/contractor - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/bundles_tc/contractor/spawn_item(turf/loc, obj/item/uplink/U) var/datum/mind/mind = usr.mind @@ -729,7 +729,7 @@ reference = "SYB" item = /obj/item/beacon/syndicate/bundle cost = 100 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) /datum/uplink_item/bundles_tc/surplus_crate name = "Syndicate Surplus Crate" @@ -737,7 +737,7 @@ reference = "SYSC" cost = 100 item = /obj/item/storage/box/syndie_kit/bundle - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) var/crate_value = 250 uses_special_spawn = TRUE @@ -768,7 +768,7 @@ reference = "SB" item = /obj/item/beacon/syndicate/bomb cost = 40 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) surplus = 0 hijack_only = TRUE @@ -779,7 +779,7 @@ reference = "SBEMP" item = /obj/item/beacon/syndicate/bomb/emp cost = 40 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) surplus = 0 can_discount = FALSE @@ -794,7 +794,7 @@ reference = "APG" item = /obj/item/storage/box/syndie_kit/atmosfiregrenades cost = 50 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) surplus = 0 hijack_only = TRUE @@ -822,4 +822,4 @@ reference = "DEPC" item = /obj/item/cartridge/syndicate cost = 30 - excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) + excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 9161902301e..56390217672 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -74,6 +74,8 @@ var/list/datum/mind/wizards = list() /// A list of all minds that are wizard apprentices var/list/datum/mind/apprentices = list() + /// A list of all minds that are ninjas + var/list/datum/mind/ninjas = list() /// The cult team datum var/datum/team/cult/cult_team diff --git a/code/game/gamemodes/ninja_objectives.dm b/code/game/gamemodes/ninja_objectives.dm new file mode 100644 index 00000000000..2bee7d95a1d --- /dev/null +++ b/code/game/gamemodes/ninja_objectives.dm @@ -0,0 +1,352 @@ +#define NINJA_OBJECTIVE_EASY 10 +#define NINJA_OBJECTIVE_NORMAL 20 +#define NINJA_OBJECTIVE_HARD 40 + +/datum/objective/ninja + /// Can you only roll this objective once? + var/onlyone = FALSE + /// Does this objective come with special gear + var/special_equipment_path + /// Rewarded currency for objective completion + var/reward_tc = NINJA_OBJECTIVE_EASY + +/datum/objective/ninja/New(text, datum/team/team_to_join, datum/mind/_owner) + . = ..() + if(special_equipment_path) + addtimer(CALLBACK(src, PROC_REF(hand_out_equipment)), 3 SECONDS, TIMER_DELETE_ME) + +/datum/objective/ninja/proc/hand_out_equipment() + give_kit(special_equipment_path) + +/datum/objective/ninja/is_invalid_target(datum/mind/possible_target) + . = ..() + if(possible_target.current) + var/turf/current_location = get_turf(possible_target.current) + if(current_location && !is_station_level(current_location.z)) + return TARGET_INVALID_UNREACHABLE + +/datum/objective/ninja/proc/complete_objective() + for(var/datum/mind/M in get_owners()) + var/mob/living/carbon/human/H = M.current + if(!ishuman(H)) + continue + var/obj/item/bio_chip/uplink/ninja/nuplink = locate(/obj/item/bio_chip/uplink/ninja) in H + if(!nuplink) + continue + nuplink.hidden_uplink.uses += reward_tc + completed = TRUE + +/datum/objective/ninja/proc/check_objective_conditions() + return TRUE + +/datum/objective/ninja/kill + name = "Kill a Target" + reward_tc = NINJA_OBJECTIVE_NORMAL + +/datum/objective/ninja/kill/update_explanation_text() + if(target?.current) + explanation_text = "Kill [target.current.real_name], the [target.assigned_role]. Scan the corpse with your scanner to verify that the deed is done." + var/datum/job/target_job = SSjobs.GetJob(target.assigned_role) + if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY) + reward_tc = NINJA_OBJECTIVE_HARD + +/datum/objective/ninja/capture + name = "Capture a Target" + reward_tc = NINJA_OBJECTIVE_NORMAL + /// The kidnapee's belongings. Set upon capture. + var/list/obj/item/victim_belongings = null + /// Temporary objects that are available to the kidnapee during their time in jail. These are deleted when the victim is returned. + var/list/obj/temp_objs = null + /// Prisoner jail timer handle. On completion, returns the prisoner back to station. + var/prisoner_timer_handle = null + +/datum/objective/ninja/capture/update_explanation_text() + if(target?.current) + explanation_text = "Capture [target.current.real_name], the [target.assigned_role]. Use your energy net to capture them so that we can interrogate them at one of our many secret dojos." + var/datum/job/target_job = SSjobs.GetJob(target.assigned_role) + if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY) + reward_tc = NINJA_OBJECTIVE_HARD + if(target_job.job_department_flags & DEP_FLAG_SERVICE) + reward_tc = NINJA_OBJECTIVE_EASY + +/datum/objective/ninja/capture/proc/handle_capture(mob/living/sucker, turf/T) + var/mob/living/carbon/human/H = sucker + + // Prepare their return + prisoner_timer_handle = addtimer(CALLBACK(src, PROC_REF(handle_target_return), sucker, T), rand(3 MINUTES, 5 MINUTES), TIMER_STOPPABLE) + + LAZYSET(GLOB.prisoner_belongings.prisoners, sucker, src) + + // Shove all of the victim's items in the secure locker. + victim_belongings = list() + var/list/obj/item/stuff_to_transfer = list() + + // Cybernetic implants get removed first (to deal with NODROP stuff) + for(var/obj/item/organ/internal/cyberimp/I in H.internal_organs) + // Greys get to keep their implant + if(isgrey(H) && istype(I, /obj/item/organ/internal/cyberimp/brain/speech_translator)) + continue + // IPCs keep this implant, free of charge! + if(ismachineperson(H) && istype(I, /obj/item/organ/internal/cyberimp/arm/power_cord)) + continue + // Try removing it + I = I.remove(H) + if(I) + stuff_to_transfer += I + + // Skrell headpocket. They already have a check in place to limit what's placed in them. + var/obj/item/organ/internal/headpocket/C = H.get_int_organ(/obj/item/organ/internal/headpocket) + if(C?.held_item) + GLOB.prisoner_belongings.give_item(C.held_item) + victim_belongings += C.held_item + C.held_item = null + + if(sucker.back) // Lets not bork modsuits in funny ways. + var/obj/modsuit_safety = sucker.back + sucker.drop_item_to_ground(modsuit_safety) + stuff_to_transfer += modsuit_safety + // Regular items get removed in second + for(var/obj/item/I in sucker) + // Keep their uniform and shoes + if(I == H.w_uniform || I == H.shoes) + continue + // Plasmamen are no use if they're crispy + if(isplasmaman(H) && I == H.head) + continue + + // Any kind of implant gets potentially removed (mindshield, freedoms, etc) + if(istype(I, /obj/item/bio_chip)) + if(istype(I, /obj/item/bio_chip/storage)) // Storage items are removed and placed in the confiscation locker before the implant is taken. + var/obj/item/bio_chip/storage/storage_chip = I + for(var/it in storage_chip.storage) + storage_chip.storage.remove_from_storage(it) + stuff_to_transfer += it + qdel(I) + continue + + if(sucker.drop_item_to_ground(I)) + stuff_to_transfer += I + + // Remove accessories from the suit if present + if(length(H.w_uniform?.accessories)) + for(var/obj/item/clothing/accessory/A in H.w_uniform.accessories) + H.w_uniform.detach_accessory(A, null) + H.drop_item_to_ground(A) + stuff_to_transfer += A + + // Transfer it all (or drop it if not possible) + for(var/obj/item/i as anything in stuff_to_transfer) + if(GLOB.prisoner_belongings.give_item(i)) + victim_belongings += i + else if(!((ABSTRACT|NODROP) in i.flags)) // Anything that can't be put on hold, just drop it on the ground + i.forceMove(T) + + // Give some species the necessary to survive. Courtesy of the Syndicate. + if(istype(H)) + var/obj/item/tank/internals/emergency_oxygen/tank + var/obj/item/clothing/mask/breath/mask + if(isvox(H)) + tank = new /obj/item/tank/internals/emergency_oxygen/nitrogen(H) + mask = new /obj/item/clothing/mask/breath/vox(H) + else if(isplasmaman(H)) + tank = new /obj/item/tank/internals/emergency_oxygen/plasma(H) + mask = new /obj/item/clothing/mask/breath(H) + + if(tank) + H.equip_to_appropriate_slot(tank) + H.equip_to_appropriate_slot(mask) + tank.toggle_internals(H, TRUE) + + sucker.reagents.add_reagent("mutadone", 1) // 1u of mutadone for the Hulk:tm: experience + sucker.update_icons() + + // Supply them with some chow. How generous is the Syndicate? + var/obj/item/food/sliced/bread/food = new(get_turf(sucker)) + food.name = "stale bread" + food.desc = "Looks like your captors care for their prisoners as much as their bread." + food.trash = null + if(prob(10)) + // Mold adds a bit of spice to it + food.name = "moldy bread" + food.reagents.add_reagent("fungus", 1) + + var/obj/item/reagent_containers/drinks/drinkingglass/drink = new(get_turf(sucker)) + drink.reagents.add_reagent("tea", 25) // British coders beware, tea in glasses + + var/obj/item/coin/antagtoken/passingtime = new(get_turf(sucker)) + + temp_objs = list(food, drink, passingtime) + + // Narrate their kidnapping and torturing experience. + if(sucker.stat != DEAD) + // Heal them up - gets them out of crit/soft crit. + sucker.reagents.add_reagent("omnizine", 10) + + to_chat(sucker, SPAN_WARNING("You feel strange...")) + sucker.Paralyse(30 SECONDS) + sucker.EyeBlind(35 SECONDS) + sucker.EyeBlurry(35 SECONDS) + sucker.AdjustConfused(35 SECONDS) + + for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.alive_mob_list) + if(G.summoner == sucker) + sucker.remove_guardian_actions() + to_chat(G, SPAN_DANGER("You feel your body ripped to shreds as you're forcibly removed from your summoner!")) + to_chat(sucker, SPAN_WARNING("You feel some part of you missing, you're not who you used to be...")) + G.ghostize() + qdel(G) + + sleep(6 SECONDS) + to_chat(sucker, SPAN_WARNING("That portal did something to you...")) + + sleep(6.5 SECONDS) + to_chat(sucker, SPAN_WARNING("Your head pounds... It feels like it's going to burst out your skull!")) + + sleep(3 SECONDS) + to_chat(sucker, SPAN_WARNING("Your head pounds...")) + + sleep(10 SECONDS) + to_chat(sucker, "A million voices echo in your head... \"Your mind held many valuable secrets - \ + we thank you for providing them. Your value is expended, and you will be ransomed back to your station. We always get paid, \ + so it's only a matter of time before we send you back...\"") + + to_chat(sucker, SPAN_DANGER("You have been kidnapped and interrogated for valuable information! You will be sent back to the station in a few minutes...")) + +/datum/objective/ninja/capture/proc/handle_target_return(mob/living/M, turf/T) + // Make a closet to return the target and their items neatly + var/obj/structure/closet/closet = new(T) + + // Return their items + for(var/i in victim_belongings) + var/obj/item/I = GLOB.prisoner_belongings.remove_item(i) + if(!I) + continue + I.forceMove(closet) + + victim_belongings = list() + + // Clean up + var/obj/item/bio_chip/uplink/uplink_implant = locate() in M + uplink_implant?.hidden_uplink?.is_jammed = FALSE + + QDEL_LIST_CONTENTS(temp_objs) + + // Injuries due to questioning + injure_target(M) + + // Return them a bit confused. + M.visible_message(SPAN_NOTICE("[M] vanishes...")) + M.forceMove(closet) + M.Paralyse(3 SECONDS) + M.EyeBlurry(5 SECONDS) + M.AdjustConfused(5 SECONDS) + M.Dizzy(70 SECONDS) + do_sparks(4, FALSE, T) + + prisoner_timer_handle = null + GLOB.prisoner_belongings.prisoners[M] = null + +/datum/objective/ninja/capture/proc/injure_target(mob/living/M) + var/obj/item/organ/external/injury_target + if(prob(20)) // See if they're !!!lucky!!! enough to just chop a hand or foot off first, or even !!LUCKIER!! that it chose an already amputated limb + injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)) + if(!injury_target) + return + default_damage(M) + injury_target.droplimb() + to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! Oh god, something's missing!")) + return + // Species specific punishments first + if(ismachineperson(M)) + M.emp_act(EMP_HEAVY) + M.adjustBrainLoss(30) + to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like some of your components are loose!")) + return + default_damage(M) // Now that we won't accidentally kill an IPC we can make everyone take damage + if(isslimeperson(M)) + injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)) + if(!injury_target) + return + injury_target.cause_internal_bleeding() + injury_target = M.get_organ(BODY_ZONE_CHEST) + injury_target.cause_internal_bleeding() + to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like your inner membrane has been punctured!")) + return + if(prob(25)) // You either get broken ribs, or a broken limb and IB if you made it this far + injury_target = M.get_organ(BODY_ZONE_CHEST) + injury_target.fracture() + else + injury_target = M.get_organ(pick(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_R_LEG)) + if(!injury_target) + return + injury_target.fracture() + injury_target.cause_internal_bleeding() + +/datum/objective/ninja/capture/proc/default_damage(mob/living/M) + M.adjustBruteLoss(40) + M.adjustBrainLoss(25) + +/datum/objective/ninja/hack_rnd + name = "Hack RnD" + explanation_text = "A client wants access to Nanotrasen's research databank. Use your scanner on their servers to give them a way inside." + needs_target = FALSE + onlyone = TRUE + +/datum/objective/ninja/interrogate_ai + name = "Interrogate AI" + explanation_text = "We wish to expunge some data from their AI system. Use your scanner on an active AI core to wirelessly transfer it to us for interrogation." + needs_target = FALSE + onlyone = TRUE + reward_tc = NINJA_OBJECTIVE_HARD + +/datum/objective/ninja/interrogate_ai/check_objective_conditions() // If there is no AI, you don't get the objective. + if(!length(GLOB.ai_list)) + return FALSE + return TRUE + +/datum/objective/ninja/steal_supermatter + name = "Steal Supermatter" + explanation_text = "Steal the supermatter crystal, using the net gun we have modified for you. The crystal will sell well to the highest bidder." + needs_target = FALSE + onlyone = TRUE + reward_tc = NINJA_OBJECTIVE_HARD + +/datum/objective/ninja/steal_supermatter/check_objective_conditions() // If there is no supermatter, you don't get the objective. + return !isnull(GLOB.main_supermatter_engine) + +/datum/objective/ninja/insert_spider_rod + name = "Sabotage Fission Reactor" + explanation_text = "Insert a spider-clan uranium 238 fuel rod into the station's fission reactor, then scan the reactor chamber while it is active." + needs_target = FALSE + onlyone = TRUE + reward_tc = NINJA_OBJECTIVE_HARD + special_equipment_path = /obj/item/beacon/ninja_rod_spawner + +/datum/objective/ninja/insert_spider_rod/check_objective_conditions() // If there is no reactor, you don't get the objective. + return !isnull(GLOB.main_fission_reactor) + +/datum/objective/ninja/bomb_department + name = "Bomb Department" + needs_target = FALSE + special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb + explanation_text = "Use the special flare provided to call down and arm a spider bomb. The target department is inscribed on the flare." + reward_tc = NINJA_OBJECTIVE_NORMAL + +/datum/objective/ninja/bomb_department/emp + name = "EMP Department" + explanation_text = "Use the special flare provided to call down and arm an EMP bomb. The target department is inscribed on the flare." + special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/emp + +/datum/objective/ninja/bomb_department/spiders + name = "Spider Bomb Department" + explanation_text = "Use the special flare provided to call down and arm a Spider bomb. The target department is inscribed on the flare." + special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/spiders + +/datum/objective/ninja_exfiltrate + name = "Exfiltrate" + explanation_text = "Use your exfiltration flare to escape the station when your work is done." + needs_target = FALSE + +#undef NINJA_OBJECTIVE_EASY +#undef NINJA_OBJECTIVE_NORMAL +#undef NINJA_OBJECTIVE_HARD diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 104acefda2a..ccae8956d5c 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1014,6 +1014,17 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays) add_fingerprint(user) if(!headbutt_shock_check(user)) return ITEM_INTERACT_COMPLETE + if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP) + if(locked) + if(!do_after_once(user, 5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE)) + return ITEM_INTERACT_COMPLETE + unlock() + return ITEM_INTERACT_COMPLETE + else + if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE)) + return ITEM_INTERACT_COMPLETE + open() + return ITEM_INTERACT_COMPLETE if(panel_open) if(istype(used, /obj/item/kitchen/utensil/fork)) return NONE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 852fbc342bb..47b2e3869fa 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -317,7 +317,11 @@ //If it's in the process of opening/closing, ignore the click if(operating) return ITEM_INTERACT_COMPLETE - + if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP) + if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE)) + return ITEM_INTERACT_COMPLETE + open() + return ITEM_INTERACT_COMPLETE add_fingerprint(user) return ..() diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index a6198fe72d4..57834061b4f 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -104,6 +104,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp name = "revenantspawn" icon_state = "Rev" +/obj/effect/landmark/spawner/ninja + name = "ninjaspawn" + /obj/effect/landmark/spawner/bubblegum_arena name = "bubblegum_arena_human" icon_state = "Explorer" @@ -142,13 +145,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp spawner_list = GLOB.ertdirector return ..() -/obj/effect/landmark/spawner/ninjastart - name = "ninjastart" - -/obj/effect/landmark/spawner/ninjastart/Initialize(mapload) - spawner_list = GLOB.ninjastart - return ..() - /obj/effect/landmark/spawner/aroomwarp name = "aroomwarp" @@ -198,6 +194,13 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp spawner_list = GLOB.syndieprisonwarp return ..() +/obj/effect/landmark/spawner/ninja_prison_warp + name = "ninja prison warp" + +/obj/effect/landmark/spawner/ninja_prison_warp/Initialize(mapload) + spawner_list = GLOB.ninjaprisonwarp + return ..() + /obj/effect/landmark/spawner/antag_extract_warp name = "antagextractwarp" @@ -230,9 +233,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp /obj/effect/landmark/spawner/commando_manual name = "Deathsquad Commando Manual" -/obj/effect/landmark/spawner/holding_facility - name = "Holding Facility" - /obj/effect/landmark/spawner/holocarp name = "Holocarp Spawn" diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 7ced265c2f6..dfd2f60905c 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -44,6 +44,19 @@ syndicate = TRUE emagged = TRUE +// Spawns a spider fuel rod for ninja objectives +/obj/item/beacon/ninja_rod_spawner + name = "spider clan beacon" + desc = "A label on it reads: Activate to have a spider clan brand fuel rod teleported to your location." + origin_tech = "bluespace=6;syndicate=3" + +/obj/item/beacon/ninja_rod_spawner/attack_self__legacy__attackchain(mob/user) + if(!user) + return + var/obj/item/nuclear_rod/fuel/uranium_238/spiders/new_rod = new(user.loc) + qdel(src) + user.put_in_hands(new_rod) + // SINGULO BEACON SPAWNER /obj/item/beacon/syndicate name = "suspicious beacon" diff --git a/code/game/objects/items/weapons/melee/melee.dm b/code/game/objects/items/weapons/melee/melee.dm index a7c589edece..2137c09cedc 100644 --- a/code/game/objects/items/weapons/melee/melee.dm +++ b/code/game/objects/items/weapons/melee/melee.dm @@ -594,3 +594,34 @@ playsound(src, pick('sound/weapons/bulletflyby.ogg','sound/weapons/bulletflyby2.ogg','sound/weapons/bulletflyby3.ogg'), 75, 1) return TRUE return FALSE + +// MARK: KATANA +/obj/item/katana + name = "katana" + desc = "Woefully underpowered in D20." + icon = 'icons/obj/weapons/melee.dmi' + icon_state = "katana" + lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' + flags = CONDUCT + slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK + flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 // Look, you can strap it to your back. You can strap it to your waist too. + force = 40 + throwforce = 10 + sharp = TRUE + w_class = WEIGHT_CLASS_BULKY + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50) + resistance_flags = FIRE_PROOF + needs_permit = TRUE + + new_attack_chain = TRUE + +/obj/item/katana/Initialize(mapload) + . = ..() + AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) + +/obj/item/katana/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") + return BRUTELOSS diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 1102d284349..ff091d01491 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -78,34 +78,6 @@ desc = "An engraved and fancy version of the claymore. It appears to be less sharp than it's more functional cousin." force = 20 -/obj/item/katana - name = "katana" - desc = "Woefully underpowered in D20." - icon = 'icons/obj/weapons/melee.dmi' - icon_state = "katana" - lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - flags = CONDUCT - slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK - flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 //Look, you can strap it to your back. You can strap it to your waist too. - force = 40 - throwforce = 10 - sharp = TRUE - w_class = WEIGHT_CLASS_BULKY - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50) - resistance_flags = FIRE_PROOF - needs_permit = TRUE - -/obj/item/katana/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES) - -/obj/item/katana/suicide_act(mob/user) - user.visible_message(SPAN_SUICIDE("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!")) - return BRUTELOSS - /obj/item/harpoon name = "harpoon" desc = "Tharr she blows!" diff --git a/code/game/objects/structures/misc_structures.dm b/code/game/objects/structures/misc_structures.dm index dfa0b0b50d4..f02bdd9f248 100644 --- a/code/game/objects/structures/misc_structures.dm +++ b/code/game/objects/structures/misc_structures.dm @@ -76,35 +76,6 @@ else icon_state = "signpost_wood" -/obj/structure/ninjatele - name = "Long-Distance Teleportation Console" - desc = "A console used to send a Spider Clan operative long distances rapidly." - icon = 'icons/obj/ninjaobjects.dmi' - icon_state = "teleconsole" - anchored = TRUE - -/obj/structure/ninjatele/attack_hand(mob/user as mob) - if(user.mind.special_role=="Ninja") - switch(tgui_alert(user, "Phase Jaunt relay primed, target locked as [station_name()], initiate VOID-shift translocation? (Warning! Internals required!)", "Void Shift", list("Yes", "No"))) - if("Yes") - if(user.z != src.z) - return - - user.loc.loc.Exited(user) - user.loc = pick(GLOB.carplist) // In the future, possibly make specific NinjaTele landmarks, and give him an option to teleport to North/South/East/West of SS13 instead of just hijacking a carpspawn. - - playsound(user.loc, 'sound/effects/phasein.ogg', 25, 1) - playsound(user.loc, 'sound/effects/sparks2.ogg', 50, 1) - new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(user), user.dir) - to_chat(user, "[SPAN_BOLDNOTICE("VOID-Shift")] translocation successful") - - if("No") - to_chat(user, SPAN_DANGER("Process aborted!")) - return - - else - to_chat(user, "[SPAN_DANGER("FĆAL �Rr�R")]: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") - /obj/structure/respawner name = "\improper Long-Distance Cloning Machine" desc = "Top-of-the-line Nanotrasen technology allows for cloning of crew members from off-station upon bluespace request." diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 99187e022e1..7791b69c376 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -433,8 +433,8 @@ if(length(SSticker.mode.apprentices)) dat += check_role_table("Apprentices", SSticker.mode.apprentices) - /*if(length(ticker.mode.ninjas)) - dat += check_role_table("Ninjas", ticker.mode.ninjas)*/ + if(length(SSticker.mode.ninjas)) + dat += check_role_table("Ninjas", SSticker.mode.ninjas) if(SSticker.mode.cult_team) dat += check_role_table("Cultists", SSticker.mode.cult_team.members) diff --git a/code/modules/antagonists/space_ninja/datum_space_ninja.dm b/code/modules/antagonists/space_ninja/datum_space_ninja.dm new file mode 100644 index 00000000000..bcec786aec4 --- /dev/null +++ b/code/modules/antagonists/space_ninja/datum_space_ninja.dm @@ -0,0 +1,95 @@ +RESTRICT_TYPE(/datum/antagonist/space_ninja) + +// Spider Clan Space Ninja +/datum/antagonist/space_ninja + name = "Space Ninja" + roundend_category = "ninjas" + job_rank = ROLE_NINJA + special_role = SPECIAL_ROLE_NINJA + antag_hud_name = "hud_ninja" + antag_hud_type = ANTAG_HUD_NINJA + clown_gain_text = "Your spider clan training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." + clown_removal_text = "You lose your spider clan training and return to your own clumsy, clownish self." + wiki_page_name = "Space Ninja" + var/give_uplink = TRUE + blurb_r = 200 + blurb_a = 0.75 + boss_title = "Spider Clan Daimyo" + /// Number of missions needed to complete + var/mission_goal = 4 + +/datum/antagonist/space_ninja/on_gain() + ..() + mission_goal = 4 + (length(GLOB.crew_list) / 10) + SEND_SOUND(owner.current, sound('sound/ambience/antag/ninjaalert.ogg')) + +/datum/antagonist/space_ninja/give_objectives() + forge_objectives() + +/datum/antagonist/space_ninja/exfiltrate(mob/living/carbon/human/extractor, obj/item/radio/radio) + extractor.equipOutfit(/datum/outfit/admin/ghostbar_antag/space_ninja) + radio.autosay("--ZZZT!- Domo Ar!g@to, [extractor.real_name]. Your training paid -^%&!-ZZT!-", "Spider Clan HQ", "Security") + SSblackbox.record_feedback("tally", "successful_extraction", 1, "Space Ninja") + +/datum/antagonist/space_ninja/finalize_antag() + . = ..() + equip_ninja() + +/datum/antagonist/space_ninja/add_owner_to_gamemode() + SSticker.mode.ninjas |= owner + +/datum/antagonist/space_ninja/remove_owner_from_gamemode() + SSticker.mode.ninjas -= owner + +/datum/antagonist/space_ninja/proc/equip_ninja() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/new_ninja = owner.current + new_ninja.delete_equipment() + if(isvox(new_ninja)) + new_ninja.equipOutfit(/datum/outfit/space_ninja/vox) + else + new_ninja.equipOutfit(/datum/outfit/space_ninja) + +/datum/antagonist/space_ninja/proc/forge_objectives() + var/list/moderate_objectives = list( + /datum/objective/ninja/capture = 8, + /datum/objective/ninja/kill = 8, + /datum/objective/ninja/hack_rnd = 5, + /datum/objective/ninja/bomb_department/emp = 3, + /datum/objective/ninja/bomb_department/spiders = 3, + ) + var/list/all_ninja_objectives = list( + /datum/objective/ninja/capture = 8, + /datum/objective/ninja/kill = 8, + /datum/objective/ninja/hack_rnd = 4, + /datum/objective/ninja/bomb_department = 3, + /datum/objective/ninja/bomb_department/emp = 3, + /datum/objective/ninja/bomb_department/spiders = 3, + /datum/objective/ninja/steal_supermatter = 3, + /datum/objective/ninja/insert_spider_rod = 3, + /datum/objective/ninja/interrogate_ai = 3, + ) + for(var/i in 1 to mission_goal) + if(i <= mission_goal / 2) // This ensures some easier objectives are rolled to allow ninjas to work up to harder ones. + forge_objective(moderate_objectives) + continue + forge_objective(all_ninja_objectives) + add_antag_objective(/datum/objective/ninja_exfiltrate) + +/datum/antagonist/space_ninja/proc/forge_objective(list/objective_list) + + var/datum/objective/ninja/new_objective = pickweight(objective_list) + var/datum/objective/ninja/obj_item = new new_objective() // Needed to do to check validity and reroll + if(!obj_item.check_objective_conditions()) + forge_objective(objective_list) + qdel(obj_item) + return + qdel(obj_item) + if(new_objective.onlyone) + var/list/current_objectives = get_antag_objectives() + for(var/datum/objective/ninja/c_objective in current_objectives) + if(istype(c_objective, new_objective)) + forge_objective(objective_list) + return + add_antag_objective(new_objective) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index f8879f25944..d75ac947f49 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -7,6 +7,7 @@ GLOBAL_LIST_INIT(special_role_times, list( ROLE_TRAITOR = 7, ROLE_CHANGELING = 14, ROLE_WIZARD = 14, + ROLE_NINJA = 14, ROLE_REV = 14, ROLE_VAMPIRE = 14, ROLE_BLOB = 14, diff --git a/code/modules/clothing/gloves/colored_gloves.dm b/code/modules/clothing/gloves/colored_gloves.dm index db73cdafd91..fcdc4b4eff5 100644 --- a/code/modules/clothing/gloves/colored_gloves.dm +++ b/code/modules/clothing/gloves/colored_gloves.dm @@ -46,7 +46,7 @@ var/can_be_cut = 1 sprite_sheets = list( "Vox" = 'icons/mob/clothing/species/vox/gloves.dmi', - "Skkulakin" = 'icons/mob/clothing/species/skkulakin/gloves.dmi', + "Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi', "Drask" = 'icons/mob/clothing/species/drask/gloves.dmi', "Grey" = 'icons/mob/clothing/species/grey/gloves.dmi', "Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi', diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 29a921e83c9..1601c7f9f63 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -177,7 +177,6 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/radiation_storm, 10, TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spider_infestation, 10, TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/ion_storm, 10), - //new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), TRUE), // NON-BAY EVENTS new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/mass_hallucination, 10), new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/brand_intelligence, 5, TRUE), @@ -216,6 +215,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/demon_incursion, 10, TRUE, _first_run_time = 35 MINUTES), new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/disease_outbreak, 8, TRUE), new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/revenant, 9), + new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/space_ninja, 9), new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_morph, 16, is_one_shot = TRUE), //new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_floor_cluwne, 15, is_one_shot = TRUE) //new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_pulsedemon, 20, is_one_shot = TRUE) diff --git a/code/modules/events/space_ninja.dm b/code/modules/events/space_ninja.dm new file mode 100644 index 00000000000..ece87cb3e52 --- /dev/null +++ b/code/modules/events/space_ninja.dm @@ -0,0 +1,86 @@ +/datum/event/space_ninja + name = "Space Ninja" + role_weights = list(ASSIGNMENT_SECURITY = 2) + role_requirements = list(ASSIGNMENT_CREW = 20, ASSIGNMENT_SECURITY = 2) + nominal_severity = EVENT_LEVEL_MAJOR + +/datum/event/space_ninja/start() + INVOKE_ASYNC(src, PROC_REF(poll_ninja)) + +/datum/event/space_ninja/proc/poll_ninja(list/potential_ninjas) + var/list/candidates = list() + if(!potential_ninjas) + candidates = SSghost_spawns.poll_candidates("Do you want to play as a space ninja?", ROLE_NINJA, TRUE) + else + candidates = potential_ninjas + if(!length(candidates)) + kill() + return + var/mob/new_ninja + while(length(candidates)) + new_ninja = pick_n_take(candidates) + if(jobban_isbanned(new_ninja, ROLE_TRAITOR)) + continue + break + if(!new_ninja) + kill() + return + + var/gender_pref = input_async(new_ninja, "Please select a gender (10 seconds):", list("Male", "Female")) + addtimer(CALLBACK(src, PROC_REF(get_species), candidates, new_ninja, gender_pref), 10 SECONDS) + +/datum/event/space_ninja/proc/get_species(list/potential_ninjas, mob/new_ninja, datum/async_input/gender_pref) + gender_pref.close() + var/sel_gender = gender_pref.result + if(!sel_gender) // Player was AFK and did not select a gender + poll_ninja(potential_ninjas) + return + var/species_pref = input_async(new_ninja, "Please select a species (10 seconds):", list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine", "Random")) + addtimer(CALLBACK(src, PROC_REF(create_ninja), potential_ninjas, new_ninja, sel_gender, species_pref), 10 SECONDS) + +/datum/event/space_ninja/proc/create_ninja(list/potential_ninjas, mob/new_ninja, sel_gender, datum/async_input/species_pref) + species_pref.close() + var/sel_species = species_pref.result + if(!sel_species) // Player was AFK and did not select a species + poll_ninja(potential_ninjas) + return + if(!new_ninja || !new_ninja.client) + poll_ninja(potential_ninjas) + return + + var/list/spawn_locs = list() + for(var/obj/effect/landmark/spawner/ninja/N in GLOB.landmarks_list) + spawn_locs += get_turf(N) + if(!length(spawn_locs)) + message_admins("Unable to spawn ninja - no valid spawn locations.") + return + + var/mob/living/carbon/human/M = new(pick(spawn_locs)) + + M.ckey = new_ninja.ckey + dust_if_respawnable(new_ninja) + + if(sel_gender == "Male") + M.change_gender(MALE) + M.change_body_type(MALE) + else + M.change_gender(FEMALE) + M.change_body_type(FEMALE) + + if(sel_species == "Random") + sel_species = pick("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine") + if(sel_species == "Slime") + sel_species = "Slime People" + var/datum/species/S = GLOB.all_species[sel_species] + var/species = S.type + M.set_species(species, TRUE) + M.dna.ready_dna(M) + M.cleanSE() + M.overeatduration = 0 + M.age = rand(23, 35) + M.regenerate_icons() + + M.mind = new + M.mind.bind_to(M) + M.mind.set_original_mob(M) + M.mind.make_space_ninja() diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm index f81c47b420f..2dd5aa816b5 100644 --- a/code/modules/mod/mod_clothes.dm +++ b/code/modules/mod/mod_clothes.dm @@ -11,6 +11,11 @@ permeability_coefficient = 0.01 sprite_sheets = list( "Grey" = 'icons/mob/clothing/modsuit/species/grey_helmets.dmi', + "Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi', + "Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi', + "Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi', + "Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi', + "Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi', "Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi', "Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi', "Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi', @@ -37,13 +42,17 @@ insert_max = 0 hide_tail_by_species = list("modsuit") sprite_sheets = list( + "Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi', + "Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi', + "Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi', + "Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi', + "Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi', "Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi', "Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi', "Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi', "Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi' ) - /obj/item/clothing/gloves/mod name = "MOD gauntlets" desc = "A pair of gauntlets for a MODsuit." @@ -56,13 +65,17 @@ cold_protection = HANDS|ARMS permeability_coefficient = 0.01 sprite_sheets = list( + "Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi', + "Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi', + "Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi', + "Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi', + "Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi', "Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi', "Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi', "Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi', "Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi' ) - /obj/item/clothing/shoes/mod name = "MOD boots" desc = "A pair of boots for a MODsuit." @@ -75,6 +88,11 @@ cold_protection = FEET|LEGS permeability_coefficient = 0.01 sprite_sheets = list( + "Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi', + "Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi', + "Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi', + "Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi', + "Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi', "Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi', "Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi', "Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi', diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 664c102e262..9cb3665924c 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -1384,3 +1384,58 @@ /// considering this should not be used, it's getting just DS armor, not infinity in everything. /obj/item/mod/armor/mod_theme_administrative armor = list(MELEE = 200, BULLET = 200, LASER = 50, ENERGY = 50, BOMB = INFINITY, RAD = INFINITY, FIRE = INFINITY, ACID = INFINITY) + +/datum/mod_theme/ninja + name = "'Shinobi' stealthsuit" + desc = "A specialized modsuit worn by the spider clan's elite ninja operatives." + default_skin = "ninja" + armor_type_1 = /obj/item/mod/armor/mod_theme_ninja + resistance_flags = FIRE_PROOF | ACID_PROOF + flag_2_flags = RAD_PROTECT_CONTENTS_2 + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT + siemens_coefficient = 0 + slowdown_inactive = 1 + slowdown_active = 0.3 + ui_theme = "syndicate" + allowed_suit_storage = list( + /obj/item/katana/energy, + /obj/item/wormhole_jaunter/ninja_bomb, + /obj/item/throwing_star, + /obj/item/restraints/legcuffs/bola, + /obj/item/gun, + /obj/item/ninja_scanner, + ) + skins = list( + "ninja" = list( + HELMET_FLAGS = list( + UNSEALED_LAYER = null, + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDMAGE | BLOCKHAIR, + UNSEALED_INVISIBILITY = HIDEFACE, + SEALED_INVISIBILITY = HIDEMASK | HIDEEYES | HIDEEARS | HIDEFACE, + UNSEALED_COVER = HEADCOVERSMOUTH, + SEALED_COVER = HEADCOVERSEYES, + CAN_OVERSLOT = TRUE, + ), + CHESTPLATE_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDMAGE, + SEALED_INVISIBILITY = HIDEJUMPSUIT | HIDETAIL, + CAN_OVERSLOT = TRUE, + ), + GAUNTLETS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDMAGE, + CAN_OVERSLOT = TRUE, + ), + BOOTS_FLAGS = list( + UNSEALED_CLOTHING = THICKMATERIAL, + SEALED_CLOTHING = STOPSPRESSUREDMAGE, + CAN_OVERSLOT = TRUE, + ), + ), + ) + +/obj/item/mod/armor/mod_theme_ninja + + armor = list(MELEE = 50, BULLET = 35, LASER = 35, ENERGY = 30, BOMB = 25, RAD = 200, FIRE = INFINITY, ACID = INFINITY) diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 52da3adcce3..5259c440c06 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -569,6 +569,25 @@ /obj/item/mod/module/jetpack/advanced, ) +/obj/item/mod/control/pre_equipped/ninja + icon_state = "ninja-control" + theme = /datum/mod_theme/ninja + starting_frequency = MODLINK_FREQ_SYNDICATE + applied_cell = /obj/item/stock_parts/cell/bluespace + applied_modules = list( + /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/jetpack/advanced, + /obj/item/mod/module/dispenser/smoke, + /obj/item/mod/module/shinobi_stealth, + /obj/item/mod/module/shinobi_freedom, + /obj/item/mod/module/shinobi_stims, + /obj/item/mod/module/noslip, + ) + default_pins = list( + /obj/item/mod/module/jetpack/advanced, + /obj/item/mod/module/dispenser/smoke, + ) + //these exist for the prefs menu /obj/item/mod/control/pre_equipped/empty starting_frequency = null diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index b4f2e47eabf..dacf8bfa6d4 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -641,3 +641,77 @@ /obj/item/mod/module/anomaly_locked/teslawall/prebuilt prebuilt = TRUE removable = FALSE // No switching it into another suit / no free anomaly core + +/obj/item/mod/module/shinobi_stealth + name = "MOD shinobi stealth module" + desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stealth technology in the classic ninja scarf." + icon_state = "armor_booster" + origin_tech = "combat=5;bluespace=6;syndicate=4" + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + removable = FALSE + /// Linked sneaking action + var/datum/action/cooldown/ninja/ninja_cloak/cloak_action + +/obj/item/mod/module/shinobi_stealth/Initialize(mapload) + . = ..() + cloak_action = new(src) + +/obj/item/mod/module/shinobi_stealth/on_suit_activation() + . = ..() + cloak_action.Grant(mod.wearer) + +/obj/item/mod/module/shinobi_stealth/on_suit_deactivation(deleting = FALSE) + if(deleting) + return + cloak_action.stop_sneaking() + cloak_action.Remove(mod.wearer) + +/obj/item/mod/module/shinobi_freedom + name = "MOD shinobi escape module" + desc = "An advanced module, designed by the Spider Clan, that replicates the advanced escaping technology in the classic ninja boots." + icon_state = "armor_booster" + origin_tech = "combat=5;bluespace=6;syndicate=4" + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + removable = FALSE + /// Linked freedom action + var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action + +/obj/item/mod/module/shinobi_freedom/Initialize(mapload) + . = ..() + freedoms_action = new(src) + +/obj/item/mod/module/shinobi_freedom/on_suit_activation() + . = ..() + ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src) + freedoms_action.Grant(mod.wearer) + +/obj/item/mod/module/shinobi_freedom/on_suit_deactivation(deleting = FALSE) + if(deleting) + return + REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src) + freedoms_action.Remove(mod.wearer) + +/obj/item/mod/module/shinobi_stims + name = "MOD shinobi stimulant module" + desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stimulants technology in the classic ninja kabuto." + icon_state = "armor_booster" + origin_tech = "combat=5;bluespace=6;syndicate=4" + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2 + removable = FALSE + /// Linked stims action + var/datum/action/cooldown/ninja/stim_suit/antistun_action + +/obj/item/mod/module/shinobi_stims/Initialize(mapload) + . = ..() + antistun_action = new(src) + +/obj/item/mod/module/shinobi_stims/on_suit_activation() + . = ..() + ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src) + antistun_action.Grant(mod.wearer) + +/obj/item/mod/module/shinobi_stims/on_suit_deactivation(deleting = FALSE) + if(deleting) + return + REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src) + antistun_action.Remove(mod.wearer) diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm deleted file mode 100644 index dc6da8238a5..00000000000 --- a/code/modules/ninja/energy_katana.dm +++ /dev/null @@ -1,76 +0,0 @@ -/obj/item/katana/energy - name = "energy katana" - desc = "A katana infused with a strong energy." - icon = 'icons/obj/weapons/energy_melee.dmi' - icon_state = "energy_katana" - throwforce = 20 - armor_penetration_percentage = 50 - armor_penetration_flat = 10 - var/cooldown = 0 // Because spam aint cool, yo. - var/datum/effect_system/spark_spread/spark_system - -/obj/item/katana/energy/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - playsound(user, 'sound/weapons/blade1.ogg', 50, TRUE, -1) - return ..() - -/obj/item/katana/energy/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag, click_parameters) - if(!user || !target) - return - - if(proximity_flag && user.mind.special_role == "Ninja" && !cooldown && isobj(target)) - cooldown = 1 - spark_system.start() - playsound(user, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - playsound(user, 'sound/weapons/blade1.ogg', 50, 1) - user.visible_message(SPAN_DANGER("[user] masterfully slices [target]!"), SPAN_NOTICE("You masterfully slice [target]!")) - target.emag_act(user) - sleep(15) - cooldown = 0 - -/*/obj/item/katana/energy/throw_impact(atom/hit_atom) - if(ishuman(hit_atom)) - var/mob/living/carbon/human/H = hit_atom - if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit - if(SN.energyKatana && SN.energyKatana == src) - returnToOwner(H, 0, 1) - return - ..()*/ - -/obj/item/katana/energy/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) - if(!istype(user)) - return - loc = get_turf(src) - - if(doSpark) - spark_system.start() - playsound(get_turf(src), "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - - var/msg = "" - - if(user.put_in_hands(src)) - msg = "Your Energy Katana teleports into your hand!" - else if(user.equip_to_slot_if_possible(src, ITEM_SLOT_BELT, FALSE, TRUE)) - msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!" - else - loc = get_turf(user) - msg = "Your Energy Katana teleports to your location!" - - if(caught) - if(loc == user) - msg = "You catch your Energy Katana!" - else - msg = "Your Energy Katana lands at your feet!" - - if(msg) - to_chat(user, SPAN_NOTICE("[msg]")) - -/obj/item/katana/energy/Initialize(mapload) - . = ..() - spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(5, 0, src) - spark_system.attach(src) - -/obj/item/katana/energy/Destroy() - QDEL_NULL(spark_system) - return ..() diff --git a/code/modules/ninja/ninja_actions.dm b/code/modules/ninja/ninja_actions.dm new file mode 100644 index 00000000000..480eb1a176d --- /dev/null +++ b/code/modules/ninja/ninja_actions.dm @@ -0,0 +1,101 @@ +/datum/action/cooldown/ninja + background_icon_state = "bg_ninja" + button_icon_state = "genetic_view" + +/datum/action/cooldown/ninja/ninja_cloak + name = "Ninja's Stealth" + desc = "Toggles whether you are currently sneaking, reducing your visibility and movement speed. Enhanced effects in darkness." + button_icon_state = "vampire_cloak" + cooldown_time = 2 SECONDS + var/sneaking = FALSE + +/datum/action/cooldown/ninja/ninja_cloak/proc/update_action_name() + name = "[initial(name)] ([sneaking ? "Deactivate" : "Activate"])" + SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME) + build_all_button_icons() + +/datum/action/cooldown/ninja/ninja_cloak/proc/stop_sneaking() + if(!ishuman(owner)) + return + var/mob/living/carbon/human/H = owner + sneaking = FALSE + STOP_PROCESSING(SSobj, src) + UnregisterSignal(H, COMSIG_ATTACK) + UnregisterSignal(H, COMSIG_ATTACK_BY) + H.set_alpha_tracking(ALPHA_VISIBLE, src) + REMOVE_TRAIT(owner, TRAIT_GOTTAGOSLOW, src) + +/datum/action/cooldown/ninja/ninja_cloak/process() + . = ..() + if(!ishuman(owner)) + return + var/mob/living/carbon/human/H = owner + if(H.stat) + stop_sneaking() + return + if(!sneaking) + stop_sneaking() + return + var/turf/simulated/T = get_turf(H) + var/light_available = T.get_lumcount() * 10 + + if(light_available <= 2) + H.set_alpha_tracking(ALPHA_VISIBLE * 0.1, src) + return + H.set_alpha_tracking(ALPHA_VISIBLE * 0.5, src) + +/datum/action/cooldown/ninja/ninja_cloak/Activate(atom/target) + if(!ishuman(owner)) + return + + var/mob/living/carbon/human/H = owner + + sneaking = !sneaking + update_action_name() + if(sneaking) + to_chat(H, "You are now sneaking around. Stick to the darkness to conceal yourself better.") + START_PROCESSING(SSobj, src) + RegisterSignal(owner, COMSIG_ATTACK, PROC_REF(stop_sneaking)) + RegisterSignal(owner, COMSIG_ATTACK_BY, PROC_REF(stop_sneaking)) + ADD_TRAIT(owner, TRAIT_GOTTAGOSLOW, src) + else + to_chat(H, "You are no longer sneaking around.") + stop_sneaking() + StartCooldown() + +/datum/action/cooldown/ninja/freedom_shoes + name = "Ninja's Mobility" + desc = "Breaks free of leg restraints. 2 Minute cooldown." + button_icon = 'icons/obj/bio_chips.dmi' + button_icon_state = "freedom" + cooldown_time = 2 MINUTES + +/datum/action/cooldown/ninja/freedom_shoes/Activate(atom/target) + if(!ishuman(owner)) + return + var/mob/living/carbon/human/H = owner + H.clear_legcuffs(TRUE) + H.SetKnockDown(0) + H.stand_up(TRUE) + StartCooldown() + +/datum/action/cooldown/ninja/stim_suit + name = "Ninja's Tenacity" + desc = "Activates an injector within your suit, pumping you with a small hit of stimulants. 2 Minute cooldown." + button_icon = 'icons/obj/bio_chips.dmi' + button_icon_state = "adrenal" + cooldown_time = 2 MINUTES + +/datum/action/cooldown/ninja/stim_suit/Activate(atom/target) + if(!ishuman(owner)) + return + var/mob/living/carbon/human/H = owner + H.SetStunned(0) + H.SetWeakened(0) + H.SetKnockDown(0) + H.SetParalysis(0) + H.adjustStaminaLoss(-75) + H.stand_up(TRUE) + SEND_SIGNAL(H, COMSIG_LIVING_CLEAR_STUNS) + H.reagents.add_reagent("stimulative_agent", 1) // 10 Seconds. + StartCooldown() diff --git a/code/modules/ninja/ninja_clothes.dm b/code/modules/ninja/ninja_clothes.dm new file mode 100644 index 00000000000..55fdd3a12af --- /dev/null +++ b/code/modules/ninja/ninja_clothes.dm @@ -0,0 +1,195 @@ +/obj/item/clothing/head/helmet/space_ninja + desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." + name = "ninja fukumen" + icon_state = "s-ninja" + inhand_icon_state = "s-ninja_hood" + flags = BLOCKHAIR + flags_inv = HIDEEARS|HIDEEYES|HIDEFACE + armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY) + origin_tech = "combat=5;materials=5;syndicate=2" + blockTracking = 1 + icon_monitor = 'icons/mob/clothing/species/machine/monitor/hood.dmi' + sprite_sheets = list( + "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi', + "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi', + "Skrell" = 'icons/mob/clothing/species/skrell/head.dmi', + "Vox" = 'icons/mob/clothing/species/vox/head.dmi', + "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi', + "Drask" = 'icons/mob/clothing/species/drask/head.dmi', + "Grey" = 'icons/mob/clothing/species/grey/head.dmi', + "Nian" = 'icons/mob/clothing/species/nian/head.dmi', + "Diona" = 'icons/mob/clothing/species/diona/head.dmi', + "Kidan" = 'icons/mob/clothing/species/kidan/head.dmi', + "Skkulakin" = 'icons/mob/clothing/species/vox/head.dmi', + ) + /// Tracking the cloak action + var/datum/action/cooldown/ninja/ninja_cloak/cloak_action + +/obj/item/clothing/head/helmet/space_ninja/Initialize(mapload) + . = ..() + cloak_action = new(src) + +/obj/item/clothing/head/helmet/space_ninja/equipped(mob/user, slot, initial) + . = ..() + if(!ishuman(user)) + return + if(slot != ITEM_SLOT_HEAD) + return + cloak_action.Grant(user) + +/obj/item/clothing/head/helmet/space_ninja/dropped(mob/user, silent) + . = ..() + cloak_action.stop_sneaking() + cloak_action.Remove(user) + +/obj/item/clothing/mask/gas/space_ninja + name = "ninja mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." + icon_state = "s-ninja" + inhand_icon_state = "s-ninja_mask" + flash_protect = FLASH_PROTECTION_FLASH + origin_tech = "combat=4;materials=4;syndicate=1" + icon_monitor = 'icons/mob/clothing/species/machine/monitor/mask.dmi' + sprite_sheets = list( + "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', + "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', + "Skrell" = 'icons/mob/clothing/species/skrell/mask.dmi', + "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', + "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi', + "Drask" = 'icons/mob/clothing/species/drask/mask.dmi', + "Grey" = 'icons/mob/clothing/species/grey/mask.dmi', + "Nian" = 'icons/mob/clothing/species/nian/mask.dmi', + "Diona" = 'icons/mob/clothing/species/diona/mask.dmi', + "Kidan" = 'icons/mob/clothing/species/kidan/mask.dmi', + "Skkulakin" = 'icons/mob/clothing/species/skkulakin/mask.dmi', + ) + var/obj/item/voice_changer/voice_changer + +/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload) + . = ..() + voice_changer = new(src) + +/obj/item/clothing/mask/gas/space_ninja/Destroy() + QDEL_NULL(voice_changer) + return ..() + +/obj/item/clothing/gloves/space_ninja + desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." + name = "ninja tekko" + icon_state = "s-ninja" + siemens_coefficient = 0 + pickpocket = TRUE // Master of stealth, you can pick a pocket + armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY) + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT + origin_tech = "combat=5;materials=5;syndicate=2" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/gloves.dmi', + "Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi', + "Drask" = 'icons/mob/clothing/species/drask/gloves.dmi', + "Diona" = 'icons/mob/clothing/species/diona/gloves.dmi', + "Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi', + ) + +/obj/item/clothing/shoes/space_ninja + name = "ninja jaka-tabi" + desc = "A pair of split-toed rubber-soled shoes. Excellent for running and even better for smashing skulls." + icon_state = "s-ninja" + permeability_coefficient = 0.01 + no_slip = TRUE + armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY) + cold_protection = FEET + min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT + heat_protection = FEET + max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT + origin_tech = "combat=5;materials=5;syndicate=2" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/shoes.dmi', + "Drask" = 'icons/mob/clothing/species/drask/shoes.dmi', + "Diona" = 'icons/mob/clothing/species/diona/shoes.dmi', + "Kidan" = 'icons/mob/clothing/species/kidan/shoes.dmi', + "Skkulakin" = 'icons/mob/clothing/species/vox/shoes.dmi', + ) + /// Linked freedoms action + var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action + +/obj/item/clothing/shoes/space_ninja/Initialize(mapload) + . = ..() + freedoms_action = new(src) + +/obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot, initial) + . = ..() + if(!ishuman(user)) + return + if(slot != ITEM_SLOT_SHOES) + return + ADD_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src) + freedoms_action.Grant(user) + +/obj/item/clothing/shoes/space_ninja/dropped(mob/user, silent) + . = ..() + REMOVE_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src) + freedoms_action.Remove(user) + +/obj/item/clothing/suit/space_ninja + name = "ninja uwagi" + desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins." + icon_state = "s-ninja" + inhand_icon_state = "s-ninja_suit" + allowed = list( + /obj/item/gun, + /obj/item/ammo_box, + /obj/item/melee/baton, + /obj/item/tank/internals, + /obj/item/katana/energy, + /obj/item/restraints/handcuffs, + /obj/item/ninja_scanner + ) + flags_inv = HIDEJUMPSUIT + armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY) + origin_tech = "combat=5;materials=5;syndicate=2" + sprite_sheets = list( + "Vox" = 'icons/mob/clothing/species/vox/suit.dmi', + "Drask" = 'icons/mob/clothing/species/drask/suit.dmi', + "Grey" = 'icons/mob/clothing/species/grey/suit.dmi', + "Nian" = 'icons/mob/clothing/species/nian/suit.dmi', + "Diona" = 'icons/mob/clothing/species/diona/suit.dmi', + "Kidan" = 'icons/mob/clothing/species/kidan/suit.dmi', + "Skkulakin" = 'icons/mob/clothing/species/vox/suit.dmi', + ) + /// Linked stims action + var/datum/action/cooldown/ninja/stim_suit/antistun_action + +/obj/item/clothing/suit/space_ninja/Initialize(mapload) + . = ..() + antistun_action = new(src) + +/obj/item/clothing/suit/space_ninja/equipped(mob/user, slot, initial) + . = ..() + if(!ishuman(user)) + return + if(slot != ITEM_SLOT_OUTER_SUIT) + return + antistun_action.Grant(user) + +/obj/item/clothing/suit/space_ninja/dropped(mob/user, silent) + . = ..() + antistun_action.Remove(user) + +/obj/item/storage/bag/garment/syndie/ninja_suit + name = "ninja suit garment bag" + +/obj/item/storage/bag/garment/syndie/ninja_suit/populate_contents() + new /obj/item/clothing/under/syndicate(src) + new /obj/item/clothing/shoes/space_ninja(src) + new /obj/item/clothing/gloves/space_ninja(src) + new /obj/item/clothing/head/helmet/space_ninja(src) + new /obj/item/clothing/mask/gas/space_ninja(src) + new /obj/item/clothing/suit/space_ninja(src) + +/obj/item/card/id/syndicate/ninja + name = "ninja card" + initial_access = list(ACCESS_MAINT_TUNNELS) + icon_state = "data" diff --git a/code/modules/ninja/ninja_deployables.dm b/code/modules/ninja/ninja_deployables.dm new file mode 100644 index 00000000000..d9cb45c1d61 --- /dev/null +++ b/code/modules/ninja/ninja_deployables.dm @@ -0,0 +1,181 @@ +/obj/machinery/syndicatebomb/ninja + name = "spider clan bomb" + payload = /obj/item/bombcore/ninja + +/obj/machinery/syndicatebomb/ninja/emp + name = "spider clan EMP bomb" + payload = /obj/item/bombcore/emp/ninja + +/obj/machinery/syndicatebomb/ninja/spiders + name = "spider bomb" + payload = /obj/item/bombcore/badmin/summon/ninja_spiders + +/obj/item/bombcore/ninja + desc = "A powerful secondary explosive of spider clan design and unknown composition, it should be stable under normal conditions..." + range_heavy = 3 + range_medium = 8 + range_light = 15 + range_flame = 17 + +/obj/item/bombcore/emp/ninja + light_emp = 24 + heavy_emp = 12 + +/obj/item/bombcore/badmin/summon/ninja_spiders + summon_path = /mob/living/basic/giant_spider + amt_summon = 12 + +/obj/item/wormhole_jaunter/ninja_bomb + name = "spider clan bomb deployment flare" + icon = 'icons/obj/lighting.dmi' + desc = "A single-use flare that will bring a high-yield payload to the location it was lit at." + icon_state = "flare-contractor" + inhand_icon_state = "flare" + /// What area should be blow up? + var/area/bomb_target + /// What kind of bomb is it + var/obj/machinery/syndicatebomb/bomb_type = /obj/machinery/syndicatebomb/ninja + +/obj/item/wormhole_jaunter/ninja_bomb/Initialize(mapload) + . = ..() + var/list/possible_areas = list( + // Rooms + /area/station/hallway/primary/aft, + /area/station/engineering/atmos, + /area/station/public/arcade, + /area/station/maintenance/assembly_line, + /area/station/public/storage/tools/auxiliary, + /area/station/command/office/blueshield, + /area/station/supply/storage, + /area/station/service/chapel, + /area/station/service/chapel/office, + /area/station/service/clown, + /area/station/legal/courtroom, + /area/station/public/toilet, + /area/station/engineering/control, + /area/station/engineering/controlroom, + /area/station/hallway/secondary/exit, + /area/holodeck/alphadeck, + /area/station/service/hydroponics, + /area/station/service/library, + /area/station/service/mime, + /area/station/supply/miningdock, + /area/station/medical/morgue, + /area/station/public/storage/office, + /area/station/public/pet_store, + /area/station/public/storage/tools, + /area/station/public/mrchangs, + /area/station/science/research, + /area/station/security/checkpoint, + /area/station/engineering/tech_storage, + /area/station/command/teleporter, + /area/station/science/storage, + /area/station/science/misc_lab, + /area/station/science/xenobiology, + /area/station/turret_protected/aisat/interior, + /area/station/aisat/atmos, + /area/station/aisat/hall, + /area/station/aisat/service, + /area/station/service/bar, + /area/station/supply/office, + /area/station/medical/chemistry, + /area/station/command/office/ce, + /area/station/command/office/cmo, + /area/station/medical/cloning, + /area/station/medical/cryo, + /area/station/public/dorms, + /area/station/engineering/equipmentstorage, + /area/station/engineering/break_room, + /area/station/ai_monitored/storage/eva, + /area/station/supply/expedition, + /area/station/science/genetics, + /area/station/engineering/gravitygenerator, + /area/station/command/office/hop, + /area/station/command/meeting_room, + /area/station/service/kitchen, + /area/station/science/robotics/chargebay, + /area/station/medical/medbay, + /area/station/medical/medbay2, + /area/station/medical/medbay3, + /area/station/medical/reception, + /area/station/medical/storage, + /area/station/medical/sleeper, + /area/station/command/server, + /area/station/command/office/ntrep, + /area/station/medical/paramedic, + /area/station/hallway/primary/port, + /area/station/supply/qm, + /area/station/command/office/rd, + /area/station/science/rnd, + /area/station/science/robotics, + /area/station/medical/surgery/primary, + /area/station/medical/surgery/secondary, + /area/station/telecomms/chamber, + /area/station/engineering/secure_storage + ) + while(!bomb_target) + var/area/selected_area = pick_n_take(possible_areas) + for(var/area/potential in SSmapping.existing_station_areas) + if(potential.type != selected_area) + continue + bomb_target = potential + break + +/obj/item/wormhole_jaunter/ninja_bomb/examine(mob/user) + . = ..() + if(isAntag(user)) + . += SPAN_WARNING("The target bomb location is: [bomb_target.name]") + +/obj/item/wormhole_jaunter/ninja_bomb/activate(mob/user) + if(!turf_check(user)) + return + var/obj/effect/temp_visual/ninja_bomb/F = new /obj/effect/temp_visual/ninja_bomb(get_turf(src)) + user.drop_item() + forceMove(F) + log_and_message_admins("[user] activated a ninja bomb flare.") + addtimer(CALLBACK(src, PROC_REF(spawn_bomb), user), 5 SECONDS) + +/obj/item/wormhole_jaunter/ninja_bomb/proc/spawn_bomb(mob/user) + new /obj/effect/decal/cleanable/ash(get_turf(src)) + var/obj/machinery/syndicatebomb/new_bomb = new bomb_type(get_turf(src)) + new_bomb.anchored = TRUE + new_bomb.activate() + var/objectives = user.mind.get_all_objectives() + for(var/datum/objective/ninja/bomb_department/bomb_dep in objectives) + if(!bomb_dep.completed) + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + bomb_dep.complete_objective() + qdel(src) + +/obj/item/wormhole_jaunter/ninja_bomb/turf_check(mob/user) + var/turf/device_turf = get_turf(user) + if(!device_turf) + to_chat(user, "You're having difficulties getting the [name] to work.") + return FALSE + var/area/our_area = get_area(device_turf) + if(!istype(our_area, bomb_target)) + to_chat(user, "You're having difficulties getting the [name] to work.") + return FALSE + return TRUE + +/obj/item/wormhole_jaunter/ninja_bomb/emp + bomb_type = /obj/machinery/syndicatebomb/ninja/emp + +/obj/item/wormhole_jaunter/ninja_bomb/spiders + bomb_type = /obj/machinery/syndicatebomb/ninja/spiders + +/obj/effect/temp_visual/ninja_bomb + name = "spider clan bomb deployment flare" + layer = BELOW_MOB_LAYER + icon = 'icons/obj/lighting.dmi' + icon_state = "flare-contractor-on" + duration = 5.1 SECONDS + /// Sound that plays when activated + var/activation_sound = 'sound/goonstation/misc/matchstick_light.ogg' + /// Light emitted when activated + var/emitted_color = "#1faf2b" + +/obj/effect/temp_visual/ninja_bomb/Initialize(mapload) + . = ..() + playsound(loc, activation_sound, 50, TRUE) + set_light(8, l_color = emitted_color) diff --git a/code/modules/ninja/ninja_outfits.dm b/code/modules/ninja/ninja_outfits.dm new file mode 100644 index 00000000000..ed8ca10a200 --- /dev/null +++ b/code/modules/ninja/ninja_outfits.dm @@ -0,0 +1,54 @@ +/datum/outfit/space_ninja + name = "Space Ninja" + uniform = /obj/item/clothing/under/syndicate + shoes = /obj/item/clothing/shoes/space_ninja + gloves = /obj/item/clothing/gloves/space_ninja + head = /obj/item/clothing/head/helmet/space_ninja + mask = /obj/item/clothing/mask/gas/space_ninja + glasses = /obj/item/clothing/glasses/night + suit = /obj/item/clothing/suit/space_ninja + belt = /obj/item/katana/energy + id = /obj/item/card/id/syndicate/ninja + back = /obj/item/storage/backpack/satchel + l_ear = /obj/item/radio/headset + box = /obj/item/storage/box/survival_syndie + backpack_contents = list( + /obj/item/storage/box/syndie_kit/throwing_weapons, + /obj/item/ninja_scanner, + /obj/item/gun/energy/kinetic_accelerator/energy_net, + /obj/item/wormhole_jaunter/extraction, + /obj/item/teleportation_scroll/apprentice, + ) + bio_chips = list( + /obj/item/bio_chip/dust, + /obj/item/bio_chip/uplink/ninja + ) + +/datum/outfit/space_ninja/vox + name = "Space Ninja - Vox" + +/datum/outfit/space_ninja/vox/post_equip(mob/living/carbon/human/H, visualsOnly) + . = ..() + var/obj/item/tank/internal_tank = new /obj/item/tank/internals/emergency_oxygen/double/vox(H) + if(!H.equip_to_appropriate_slot(internal_tank)) + if(!H.put_in_any_hand_if_possible(internal_tank)) + H.drop_item_to_ground(H.l_hand) + H.equip_or_collect(internal_tank, ITEM_SLOT_LEFT_HAND) + to_chat(H, "Could not find an empty slot for internals! Please report this as a bug") + H.internal = internal_tank + +/datum/outfit/admin/ghostbar_antag/space_ninja + name = "Ghostbar Space Ninja" + uniform = /obj/item/clothing/under/syndicate + shoes = /obj/item/clothing/shoes/space_ninja + gloves = /obj/item/clothing/gloves/space_ninja + head = /obj/item/clothing/head/helmet/space_ninja + mask = /obj/item/clothing/mask/gas/space_ninja + suit = /obj/item/clothing/suit/space_ninja + belt = /obj/item/toy/katana + back = /obj/item/storage/backpack/satchel + backpack_contents = list( + /obj/item/storage/box/engineer = 1, + /obj/item/flashlight = 1, + /obj/item/food/syndidonkpocket = 1, + ) diff --git a/code/modules/ninja/ninja_scanner.dm b/code/modules/ninja/ninja_scanner.dm new file mode 100644 index 00000000000..1fa9504d194 --- /dev/null +++ b/code/modules/ninja/ninja_scanner.dm @@ -0,0 +1,143 @@ +/obj/item/ninja_scanner + name = "spider scanner" + desc = "Advanced multi-use scanning device used by the spider clan to confirm bounty completion. Scan the corpses of dead or netted crew to redeem your bounties." + icon = 'icons/obj/device.dmi' + icon_state = "ninja_scanner" + slot_flags = ITEM_SLOT_BELT + force = 9 // Can be used as a weapon in an emergency + hitsound = 'sound/weapons/genhit1.ogg' + new_attack_chain = TRUE + +/obj/item/ninja_scanner/attack(mob/living/target, mob/living/user, params) + if(user.a_intent == INTENT_HARM) + return ..() + if(!user.mind) + return ..() + var/list/obj_list = user.mind.get_all_objectives() + if(!length(obj_list)) + to_chat(user, SPAN_WARNING("You have no objectives!")) + return TRUE + for(var/datum/objective/ninja/ninja_obj in obj_list) + if(ninja_obj.completed) + continue + if(istype(ninja_obj, /datum/objective/ninja/kill)) + if(target.stat != DEAD) + continue + if(!ninja_obj.target.current || target != ninja_obj.target.current) + continue + user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \ + SPAN_NOTICE("You begin to scan [target]!")) + if(!do_after_once(user, 8 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan.")) + return TRUE + ninja_obj.completed = TRUE + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + ninja_obj.complete_objective() + return TRUE + + if(istype(ninja_obj, /datum/objective/ninja/capture)) + var/datum/objective/ninja/capture/cap_obj = ninja_obj + if(target != ninja_obj.target.current) + continue + if(target.stat == DEAD) + if(!target.ghost_can_reenter()) // Target is DNR. Reroll. + to_chat(user, SPAN_NOTICE("Target is unrecoverable. Finding a new target...")) + ninja_obj.on_target_cryo() + else + to_chat(user, SPAN_NOTICE("Target is dead. Dead people don't talk. Esnure they are revived, then send them to us.")) + continue + if(!target.buckled) + continue + var/obj/structure/bed/energy_net/trapped_net + for(var/obj/structure/bed/energy_net/net in target.loc) + trapped_net = net + break + if(!trapped_net) + continue + user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \ + SPAN_NOTICE("You begin to scan [target]!")) + if(!do_after_once(user, 5 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan.")) + return TRUE + target.unbuckle(TRUE) + trapped_net.Destroy() + var/target_loc = target.loc + do_teleport(target, pick(GLOB.ninjaprisonwarp), 0, TRUE, bypass_area_flag = TRUE) + var/mob/living/carbon/c_target = target + if(istype(c_target)) + var/obj/item/restraints/handcuffs/cuffs = target.get_item_by_slot(ITEM_SLOT_HANDCUFFED) + qdel(cuffs) + c_target.handcuffed = FALSE + c_target.update_handcuffed() + cap_obj.handle_capture(target, target_loc) + ninja_obj.completed = TRUE + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + ninja_obj.complete_objective() + return TRUE + + if(istype(ninja_obj, /datum/objective/ninja/interrogate_ai)) + if(!is_ai(target)) + return TRUE + var/mob/living/silicon/ai/AI = target + user.visible_message(SPAN_DANGER("[user] begins to use [src] to upload [AI]!"), \ + SPAN_NOTICE("You begin to upload [AI]!")) + if(!do_after_once(user, 8 SECONDS, target = AI, allow_moving = FALSE, attempt_cancel_message = "You stop uploading [AI] before completing the upload.")) + return TRUE + var/obj/item/aicard/card = new() + AI.take_overall_damage(50) + AI.transfer_ai(AI_TRANS_TO_CARD, user, null, card) + var/list/possible_spawns = GLOB.maints_loot_spawns + while(length(possible_spawns)) + var/turf/current_turf = pick_n_take(possible_spawns) + if(!is_station_level(current_turf)) + continue + if(!current_turf.density) + do_teleport(card, current_turf) + break + // Someone built a wall over it, check the surroundings + var/list/open_turfs = current_turf.AdjacentTurfs(open_only = TRUE) + if(length(open_turfs)) + do_teleport(card, pick(open_turfs)) + break + ninja_obj.completed = TRUE + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + ninja_obj.complete_objective() + return TRUE + return ..() + +/obj/item/ninja_scanner/attack_obj(obj/attacked_obj, mob/living/user, params) + if(user.a_intent == INTENT_HARM) + return ..() + if(!user.mind) + return ..() + var/list/obj_list = user.mind.get_all_objectives() + if(!length(obj_list)) + to_chat(user, SPAN_WARNING("You have no objectives!")) + return TRUE + for(var/datum/objective/ninja/ninja_obj in obj_list) + if(ninja_obj.completed) + continue + if(istype(ninja_obj, /datum/objective/ninja/hack_rnd) && istype(attacked_obj, /obj/machinery/computer/rnd_network_controller)) + if(!do_after_once(user, 12 SECONDS, target = attacked_obj, allow_moving = FALSE, attempt_cancel_message = "You stop hacking [attacked_obj] before completing the download.")) + return TRUE + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + var/obj/machinery/computer/rnd_network_controller/rnd = attacked_obj + rnd.research_files.known_tech = list() + ninja_obj.completed = TRUE + ninja_obj.complete_objective() + return TRUE + if(istype(ninja_obj, /datum/objective/ninja/insert_spider_rod) && istype(attacked_obj, /obj/machinery/atmospherics/reactor_chamber)) + var/obj/machinery/atmospherics/reactor_chamber/r_chamber = attacked_obj + if(!r_chamber.held_rod) + to_chat(user, SPAN_NOTICE("There is no rod in [r_chamber].")) + return TRUE + if(!istype(r_chamber.held_rod, /obj/item/nuclear_rod/fuel/uranium_238/spiders)) + to_chat(user, SPAN_NOTICE("The rod in [r_chamber] is not one of ours.")) + return TRUE + if(r_chamber.linked_reactor.offline) + to_chat(user, SPAN_NOTICE("[r_chamber.linked_reactor] is not online.")) + return TRUE + to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink.")) + ninja_obj.completed = TRUE + ninja_obj.complete_objective() + return TRUE + + return ..() diff --git a/code/modules/ninja/ninja_uplink.dm b/code/modules/ninja/ninja_uplink.dm new file mode 100644 index 00000000000..f5bcd4ad287 --- /dev/null +++ b/code/modules/ninja/ninja_uplink.dm @@ -0,0 +1,91 @@ +/obj/item/bio_chip/uplink/ninja + name = "spider clan uplink bio-chip" + desc = "Purchase things from the spider clan with earned currency." + +/obj/item/bio_chip/uplink/ninja/Initialize(mapload) + . = ..() + if(hidden_uplink) + hidden_uplink.update_uplink_type(UPLINK_TYPE_NINJA) + hidden_uplink.uses = 0 + +/datum/uplink_item/ninja + category = "Spider Clan Provisions" + surplus = 0 + uplinktypes = list(UPLINK_TYPE_NINJA) + +/datum/uplink_item/ninja/shuriken_printer + name = "Shuriken Printer" + desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens." + reference = "SPR" + item = /obj/item/shuriken_printer + cost = 25 + +/datum/uplink_item/ninja/ninja_modsuit + name = "'Shinobi' Stealth Modsuit" + desc = "A specialized modsuit worn by the spider clan's elite ninja operatives." + reference = "SNBMOD" + item = /obj/item/mod/control/pre_equipped/ninja + cost = 45 + +/datum/uplink_item/ninja/energy_katana + name = "Energy Katana" + desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool." + reference = "EKAT" + item = /obj/item/katana/energy + cost = 20 + +/datum/uplink_item/ninja/energy_net + name = "Energy Net Projector" + desc = "A non-lethal weapon favored by the Spider Clan. Targets struck will find themselves trapped in an energy net." + reference = "ENET" + item = /obj/item/gun/energy/kinetic_accelerator/energy_net + cost = 30 + +/datum/uplink_item/ninja/spider_bomb + name = "Spider Bomb" + desc = "An evil device fabricated by the Spider Clan. This bomb contains a large number of dehydrated spider-cubes that will all activate upon detonation. These spiders do not discern friend from foe - all non-spiders make for good food." + reference = "SPBM" + item = /obj/machinery/syndicatebomb/ninja/spiders + cost = 65 + +/datum/uplink_item/ninja/hood + name = "Ninja Scarf" + desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." + reference = "NJSC" + item = /obj/item/clothing/head/helmet/space_ninja + cost = 10 + +/datum/uplink_item/ninja/mask + name = "Ninja Mask" + desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." + reference = "NJMSK" + item = /obj/item/clothing/mask/gas/space_ninja + cost = 10 + +/datum/uplink_item/ninja/gloves + name = "Ninja Gloves" + desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." + reference = "NJGL" + item = /obj/item/clothing/gloves/space_ninja + cost = 10 + +/datum/uplink_item/ninja/shoes + name = "Ninja Shoes" + desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." + reference = "NJSH" + item = /obj/item/clothing/shoes/space_ninja + cost = 10 + +/datum/uplink_item/ninja/suit + name = "Ninja Kabuto" + desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins." + reference = "NJKB" + item = /obj/item/clothing/suit/space_ninja + cost = 10 + +/datum/uplink_item/ninja/suit_bundle + name = "Full Ninja Outfit" + desc = "A bulk purchase of a full ninja outfit. Good for if you somehow lost the other set of highly advanced Spider Clan equipment." + reference = "NJST" + item = /obj/item/clothing/suit/space_ninja + cost = 40 diff --git a/code/modules/ninja/ninja_weapons.dm b/code/modules/ninja/ninja_weapons.dm new file mode 100644 index 00000000000..19510c93174 --- /dev/null +++ b/code/modules/ninja/ninja_weapons.dm @@ -0,0 +1,227 @@ +/obj/item/katana/energy + name = "energy katana" + desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool." + icon = 'icons/obj/weapons/energy_melee.dmi' + icon_state = "energy_katana" + force = 30 + embed_chance = 75 + throwforce = 20 + armor_penetration_percentage = 50 + armor_penetration_flat = 10 + origin_tech = "combat=6;syndicate=4" + hitsound = 'sound/weapons/blade1.ogg' + /// Is the weapon gripped or not? + var/gripped = FALSE + +/obj/item/katana/energy/activate_self(mob/living/carbon/human/user) + . = ..() + if(!ishuman(user)) + return + var/is_proper_modsuit = FALSE + if(istype(user.gloves, /obj/item/clothing/gloves/mod)) + var/obj/item/mod/control/modsuit = user.get_item_by_slot(ITEM_SLOT_BACK) + if(istype(modsuit) && istype(modsuit.theme, /datum/mod_theme/ninja)) + is_proper_modsuit = TRUE + if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja) && !is_proper_modsuit) + return + if(!gripped) + gripped = TRUE + to_chat(user, SPAN_NOTICE("You tighten your grip on [src], ensuring you won't drop it.")) + set_nodrop(TRUE, user) + return + gripped = FALSE + to_chat(user, SPAN_NOTICE("You relax your grip on [src].")) + set_nodrop(FALSE, user) + +/obj/item/katana/energy/dropped(mob/user, silent) + . = ..() + gripped = FALSE + to_chat(user, SPAN_WARNING("Your grip on [src] is loosened!")) + set_nodrop(FALSE, user) + +/obj/item/katana/energy/equipped(mob/user, slot, initial) + . = ..() + if(gripped) + gripped = FALSE + to_chat(user, SPAN_NOTICE("You relax your grip on [src].")) + set_nodrop(FALSE, user) + +/obj/item/katana/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + . = ..() + if(!.) // they did not block the attack + return + if(isprojectile(hitby)) + var/obj/projectile/P = hitby + if(P.reflectability == REFLECTABILITY_ENERGY) + owner.visible_message(SPAN_DANGER("[owner] parries [attack_text] with [src]!")) + add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]") + return -1 + owner.visible_message(SPAN_DANGER("[owner] blocks [attack_text] with [src]!")) + playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE) + return TRUE + return TRUE + +/obj/item/energy_shuriken + name = "energy shuriken" + desc = "An ancient weapon, redefined. The blade hums with an electric edge, using itself as fuel." + icon = 'icons/obj/weapons/melee.dmi' + icon_state = "energy-shuriken" + inhand_icon_state = "eshield0" + lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' + force = 5 + throwforce = 30 // This is never used on mobs since this has a 100% embed chance. + throw_speed = 4 + embedded_pain_multiplier = 4 + w_class = WEIGHT_CLASS_SMALL + embed_chance = 100 + embedded_fall_chance = 0 + sharp = TRUE + resistance_flags = FIRE_PROOF + +/obj/item/energy_shuriken/Initialize(mapload) + . = ..() + // Only lasts so long. Delete self after some time. + addtimer(CALLBACK(src, PROC_REF(qdel), src), 30 SECONDS) + +/obj/item/energy_shuriken/throw_impact(atom/target) + . = ..() + if(!ishuman(target)) + return + var/mob/living/carbon/human/H = target + H.apply_damage(60, STAMINA) + +/obj/item/shuriken_printer + name = "shuriken printer" + desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens." + icon = 'icons/obj/weapons/melee.dmi' + icon_state = "shuriken-pouch" + inhand_icon_state = "eshield0" + lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' + origin_tech = "combat=6;syndicate=5" + force = 5 + slot_flags = ITEM_SLOT_BELT + w_class = WEIGHT_CLASS_SMALL + resistance_flags = FIRE_PROOF + + new_attack_chain = TRUE + /// What is the maximum number of energy shurikens the printer can hold? + var/maximum_stars = 4 + /// What is the current number of energy shurikens the printer is holding? + var/current_stars = 2 + /// How long the cooldown is to print more shurikens + var/printing_time = 30 SECONDS + /// Timer used to print stars + var/fabrication_timer + +/obj/item/shuriken_printer/Initialize(mapload) + . = ..() + fabrication_timer = addtimer(CALLBACK(src, PROC_REF(print_star)), 30 SECONDS, TIMER_LOOP | TIMER_STOPPABLE) + +/obj/item/shuriken_printer/examine(mob/user) + . = ..() + . += SPAN_NOTICE("Alt-click to draw an energy shuriken!") + . += SPAN_NOTICE("It has [current_stars] stored.") + +/obj/item/shuriken_printer/AltClick(mob/living/carbon/user, modifiers) + if(!iscarbon(user)) + return ..() + if(current_stars < 1) + return ..() + current_stars-- + var/obj/item/energy_shuriken/star = new /obj/item/energy_shuriken(get_turf(src), src) + user.put_in_hands(star) + to_chat(user, SPAN_NOTICE("You draw [star] from [src].")) + user.throw_mode_on() + +/obj/item/shuriken_printer/proc/print_star() + if(current_stars < maximum_stars) + current_stars++ + +/obj/item/gun/energy/kinetic_accelerator/energy_net + name = "energy net projector" + desc = "A non-lethal weapon favored by the Spider Clan. Targets stunned by this weapon will be trapped in an energy net for extraction." + icon_state = "energy-net-gun" + inhand_icon_state = "energy-net-gun" + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=2000) + origin_tech = "combat=6;magnets=4;syndicate=4" + suppressed = TRUE + ammo_type = list(/obj/item/ammo_casing/energy/net) + unique_rename = FALSE + overheat_time = 3 SECONDS + holds_charge = TRUE + unique_frequency = TRUE + can_flashlight = FALSE + max_mod_capacity = 0 + empty_state = "energy-net-gun_empty" + can_holster = TRUE + +/obj/item/gun/energy/kinetic_accelerator/energy_net/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SILENT_INSERTION, ROUNDSTART_TRAIT) + +/obj/item/ammo_casing/energy/net + projectile_type = /obj/projectile/energy/net + muzzle_flash_color = null + muzzle_flash_effect = /obj/effect/temp_visual/target_angled/muzzle_flash + select_name = "energy net" + e_cost = 500 + fire_sound = 'sound/weapons/bolathrow.ogg' + +/obj/projectile/energy/net + name = "energy net" + icon_state = "net-end" + nodamage = 1 + stamina = 60 + knockdown = 4 SECONDS + speed = 1.5 + +/obj/projectile/energy/net/fire(setAngle) + if(firer) + firer.Beam(src, icon_state = "net-beam", time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/floor) + return ..() + +/obj/projectile/energy/net/on_hit(atom/target, blocked, hit_zone) + . = ..() + if(!firer) + return + if(!ishuman(target)) + return + var/mob/living/carbon/human/H = target + if(!H.stam_paralyzed) + return + var/obj/item/restraints/handcuffs/cable/zipties/cuff = new() + cuff.apply_cuffs(H, firer) + var/obj/structure/bed/energy_net/net = new(H.loc) + net.buckle_mob(H, TRUE) + +/obj/structure/bed/energy_net + name = "energy net" + desc = "A pulsing array of green energy that can securely hold a victim in place." + icon = 'icons/effects/effects.dmi' + icon_state = "e-net" + +/obj/structure/bed/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user) + if(!has_buckled_mobs()) + Destroy() // We don't exist if nothing is being held + for(var/buck in buckled_mobs) // No net, no buckles + var/mob/living/M = buck + if(M != user) + if(!do_after(user, 10 SECONDS, target = src)) + if(M && M.buckled) + to_chat(user, SPAN_WARNING("You fail to release [M] from \the [src]!")) + return + M.visible_message(SPAN_NOTICE("[user.name] pulls [M.name] free from the energy net!"),\ + SPAN_NOTICE("[user.name] pulls you free from the energy net."),\ + SPAN_ITALICS("You hear a small zap...")) + unbuckle_mob(M) + Destroy() + if(!M.buckled) + return + M.visible_message(SPAN_WARNING("[M.name] breaks free from the energy net!"),\ + SPAN_NOTICE("You break free from the energy net!"),\ + SPAN_ITALICS("You hear a small zap...")) + unbuckle_mob(M) + Destroy() diff --git a/code/modules/ninja/suit/ninja_gloves.dm b/code/modules/ninja/suit/ninja_gloves.dm deleted file mode 100644 index 8291930fdf2..00000000000 --- a/code/modules/ninja/suit/ninja_gloves.dm +++ /dev/null @@ -1,12 +0,0 @@ - - -/obj/item/clothing/gloves/space_ninja - desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance." - name = "ninja gloves" - icon_state = "s-ninja" - siemens_coefficient = 0 - pickpocket = 1 - cold_protection = HANDS - min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT - heat_protection = HANDS - max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT diff --git a/code/modules/ninja/suit/ninja_head.dm b/code/modules/ninja/suit/ninja_head.dm deleted file mode 100644 index 6b61ac93d42..00000000000 --- a/code/modules/ninja/suit/ninja_head.dm +++ /dev/null @@ -1,10 +0,0 @@ - - -/obj/item/clothing/head/helmet/space/space_ninja - desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear." - name = "ninja hood" - icon_state = "s-ninja" - inhand_icon_state = "s-ninja_hood" - flags_inv = HIDEEARS|HIDEEYES|HIDEFACE - armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY) - blockTracking = 1 diff --git a/code/modules/ninja/suit/ninja_mask.dm b/code/modules/ninja/suit/ninja_mask.dm deleted file mode 100644 index 9ea3e36c524..00000000000 --- a/code/modules/ninja/suit/ninja_mask.dm +++ /dev/null @@ -1,28 +0,0 @@ - -/* - -Contents: -- The Ninja Space Mask - -*/ - -/obj/item/clothing/mask/gas/space_ninja - name = "ninja mask" - desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement." - icon_state = "s-ninja(norm)" - inhand_icon_state = "s-ninja_mask" - sprite_sheets = list( - "Vox" = 'icons/mob/clothing/species/vox/mask.dmi', - "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi', - "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi', - "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi' - ) - var/obj/item/voice_changer/voice_changer - -/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload) - . = ..() - voice_changer = new(src) - -/obj/item/clothing/mask/gas/space_ninja/Destroy() - QDEL_NULL(voice_changer) - return ..() diff --git a/code/modules/ninja/suit/ninja_shoes.dm b/code/modules/ninja/suit/ninja_shoes.dm deleted file mode 100644 index 5095058efc1..00000000000 --- a/code/modules/ninja/suit/ninja_shoes.dm +++ /dev/null @@ -1,12 +0,0 @@ - -/obj/item/clothing/shoes/space_ninja - name = "ninja shoes" - desc = "A pair of running shoes. Excellent for running and even better for smashing skulls." - icon_state = "s-ninja" - permeability_coefficient = 0.01 - no_slip = TRUE - armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY) - cold_protection = FEET - min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT - heat_protection = FEET - max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT diff --git a/code/modules/ninja/suit/ninja_suit.dm b/code/modules/ninja/suit/ninja_suit.dm deleted file mode 100644 index 8d5a1b2c5f3..00000000000 --- a/code/modules/ninja/suit/ninja_suit.dm +++ /dev/null @@ -1,87 +0,0 @@ - -/* - -Contents: -- The Ninja Space Suit -- Ninja Space Suit Procs - -*/ - -/obj/item/clothing/suit/space/space_ninja - name = "ninja suit" - desc = "A unique, vacuum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." - icon_state = "s-ninja" - inhand_icon_state = "s-ninja_suit" - allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/melee/baton, /obj/item/tank/internals, /obj/item/stock_parts/cell) - slowdown = 0 - flags_inv = HIDEJUMPSUIT|HIDETAIL - armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY) - - var/suitActive = 0 - var/suitBusy = 0 - - var/obj/item/stock_parts/cell/suitCell - var/obj/item/clothing/head/helmet/space/space_ninja/suitHood - var/obj/item/clothing/gloves/space_ninja/suitGloves - var/obj/item/clothing/shoes/space_ninja/suitShoes - var/obj/item/clothing/mask/gas/space_ninja/suitMask - var/mob/living/carbon/human/suitOccupant - -/obj/item/clothing/suit/space/space_ninja/get_cell() - return suitCell - -/obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user) - if(!suitActive) - if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - to_chat(user, "ERROR: Unable to locate user.\nABORTING...") - return 0 - if(!istype(user.head, /obj/item/clothing/head/helmet/space/space_ninja)) - to_chat(user, "ERROR: Unable to locate hood.\nABORTING...") - return 0 - if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja)) - to_chat(user, "ERROR: Unable to locate gloves.\nABORTING...") - return 0 - if(!istype(user.shoes, /obj/item/clothing/shoes/space_ninja)) - to_chat(user, "ERROR: Unable to locate foot gear.\nABORTING...") - return 0 - if(!istype(user.wear_mask, /obj/item/clothing/mask/gas/space_ninja)) - to_chat(user, "ERROR: Unable to locate mask.\nABORTING...") - return 0 - - suitHood = user.head - suitMask = user.wear_mask - suitGloves = user.gloves - suitShoes = user.shoes - suitOccupant = user - - set_nodrop(TRUE) - suitHood.set_nodrop(TRUE) - suitMask.set_nodrop(TRUE) - suitGloves.set_nodrop(TRUE) - suitGloves.pickpocket = 1 - suitShoes.set_nodrop(TRUE) - suitShoes.slowdown = -2 - - icon_state = (user.gender == MALE ? "s-ninjan" : "s-ninjanf") - suitGloves.icon_state = "s-ninjan" - - return 1 - - else - set_nodrop(FALSE) - suitHood.set_nodrop(FALSE) - suitMask.set_nodrop(FALSE) - suitGloves.set_nodrop(FALSE) - suitGloves.pickpocket = 0 - suitShoes.set_nodrop(FALSE) - suitShoes.slowdown = -1 - icon_state = "s-ninja" - suitGloves.icon_state = "s-ninja" - - suitHood = null - suitMask = null - suitGloves = null - suitShoes = null - suitOccupant = null - - return 1 diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm deleted file mode 100644 index 94110b9dda5..00000000000 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ /dev/null @@ -1,92 +0,0 @@ - -//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. -//^ Old coder words may be false these days, Not taking the risk for now. - -/obj/item/clothing/suit/space/space_ninja/verb/toggle_suit() - set category = "Space Ninja - Equipment" - set name = "Toggle Suit" - - if(usr.mind.special_role == "Ninja") - if(suitBusy) - to_chat(usr, "ERROR: Suit systems busy, cannot initiate [suitActive ? "de-activation" : "activation"] protocols at this time.") - return - - suitBusy = 1 - - if(suitActive && (tgui_alert(usr, "Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", list("Yes", "No")) == "Yes")) - to_chat(usr, SPAN_DARKMBLUE("Now de-initializing...")) - - sleep(15) - to_chat(usr, SPAN_DARKMBLUE("Logging off, [usr.real_name]. Shutting down SpiderOS.")) - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("Primary system status: OFFLINE.\nBackup system status: OFFLINE.")) - - sleep(5) - to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE.")) - //TODO: Shut down any active abilities - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("Disconnecting neural-net interface... Success.")) - - QDEL_NULL(usr.hud_used) - usr.create_mob_hud() - usr.regenerate_icons() - - sleep(5) - to_chat(usr, SPAN_DARKMBLUE("Disengaging neural-net interface... Success.")) - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED.")) - //TODO: Grant verbs - toggle_suit_lock(usr) - usr.regenerate_icons() - suitBusy = 0 - suitActive = 0 - - else if(!suitActive) // Activate the suit. - to_chat(usr, SPAN_DARKMBLUE("Now initializing...")) - - sleep(15) - to_chat(usr, "Now establishing neural-net interface...") - if(usr.mind.special_role != "Ninja") - to_chat(usr, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") - return - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("Neural-net established. Now monitoring brainwave pattern. \nBrainwave pattern GREEN, proceeding.")) - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("Securing external locking mechanism...")) - if(!toggle_suit_lock(usr)) - return - - sleep(5) - to_chat(usr, SPAN_DARKMBLUE("Suit secured, extending neural-net interface...")) - - QDEL_NULL(usr.hud_used) - usr.hud_used = new /datum/hud/human(usr, 'icons/mob/screen_ninja.dmi', "#ffffff", 255) - if(usr.hud_used) - usr.hud_used.show_hud(usr.hud_used.hud_version) - usr.regenerate_icons() - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: ONLINE.\nCLOAK-tech device status:ONLINE")) - - sleep(5) - to_chat(usr, SPAN_DARKMBLUE("Primary system status: ONLINE.\nBackup system status: ONLINE.")) - if(suitCell) - to_chat(usr, SPAN_DARKMBLUE("Current energy capacity: [suitCell.charge]/[suitCell.maxcharge].")) - - sleep(10) - to_chat(usr, SPAN_DARKMBLUE("All systems operational. Welcome to SpiderOS, [usr.real_name].")) - //TODO: Grant ninja verbs here. - suitBusy = 0 - suitActive = 1 - - else - suitBusy = 0 - to_chat(usr, SPAN_DARKMBLUE("NOTICE: Suit de-activation protocols aborted.")) - else - to_chat(usr, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") - return diff --git a/code/modules/power/engines/fission/nuclear_rods.dm b/code/modules/power/engines/fission/nuclear_rods.dm index afadc317b30..781e69fa19f 100644 --- a/code/modules/power/engines/fission/nuclear_rods.dm +++ b/code/modules/power/engines/fission/nuclear_rods.dm @@ -105,6 +105,9 @@ else if(!rad_component) start_rads() +/obj/item/nuclear_rod/proc/do_special_effect() + return + /obj/item/nuclear_rod/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) . = ..() check_rad_shield() @@ -164,6 +167,17 @@ craftable = TRUE materials = list(MAT_METAL = 2000, MAT_URANIUM = 1000) +/obj/item/nuclear_rod/fuel/uranium_238/spiders + name = "spider-clan uranium 238 fuel rod" + desc = "A small fuel rod for most NGCR reactors. This one was green webs coating its surface, with tiny spiders skittering along them." + w_class = WEIGHT_CLASS_NORMAL + craftable = FALSE + adjacent_requirements = list() + +/obj/item/nuclear_rod/fuel/uranium_238/spiders/do_special_effect() + if(prob(5)) + new /mob/living/basic/spiderling(get_turf(src)) + /obj/item/nuclear_rod/fuel/weak_thorium name = "weak thorium fuel rod" desc = "A specialized fuel rod refined from uranium 238. This rod will last longer than normal, and won't generate as much heat." diff --git a/code/modules/power/engines/fission/reactor.dm b/code/modules/power/engines/fission/reactor.dm index 9af1ea11967..da3fd8f13b3 100644 --- a/code/modules/power/engines/fission/reactor.dm +++ b/code/modules/power/engines/fission/reactor.dm @@ -605,6 +605,7 @@ final_heat += heat_total final_power += power_total chamber.held_rod.durability -= durability_loss + chamber.held_rod.do_special_effect() if(final_heat) average_heatgen = final_heat / active_chambers diff --git a/code/modules/power/engines/supermatter/supermatter.dm b/code/modules/power/engines/supermatter/supermatter.dm index 36ec59663d5..adfacfcca23 100644 --- a/code/modules/power/engines/supermatter/supermatter.dm +++ b/code/modules/power/engines/supermatter/supermatter.dm @@ -245,6 +245,9 @@ /// How long has it been since we processed the crystal? var/tick_counter = 0 + /// Are we being stolen? + var/being_stolen = FALSE + /obj/machinery/atmospherics/supermatter_crystal/Initialize(mapload) . = ..() @@ -697,12 +700,31 @@ countdown() return 1 +/obj/machinery/atmospherics/supermatter_crystal/update_overlays() + . = ..() + overlays.Cut() + if(being_stolen) + . += "causality_field" + color = COLOR_GREEN + else + color = COLOR_WHITE + /obj/machinery/atmospherics/supermatter_crystal/bullet_act(obj/projectile/proj) var/turf/L = loc if(!istype(L)) return FALSE if(!istype(proj, /obj/projectile/beam/emitter/hitscan) && power_changes) investigate_log("has been hit by [proj] fired by [key_name(proj.firer)]", INVESTIGATE_SUPERMATTER) + if(istype(proj, /obj/projectile/energy/net)) + var/mob/living/carbon/user = proj.firer + var/list/obj_list = user.mind.get_all_objectives() + for(var/datum/objective/ninja/ninja_obj in obj_list) + if(ninja_obj.completed) + continue + if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter)) + continue + begin_theft() + return FALSE if(proj.flag != BULLET) if(power_changes) //This needs to be here I swear power += proj.damage * bullet_energy @@ -712,6 +734,32 @@ damage += proj.damage * bullet_energy return FALSE +/obj/machinery/atmospherics/supermatter_crystal/proc/begin_theft(mob/living/carbon/thief) + if(being_stolen) + return + message_admins("Ninja [thief] is beginning to steal the Supermatter Crystal.") + addtimer(src, CALLBACK(PROC_REF(complete_theft), thief), 3 MINUTES) + being_stolen = TRUE + update_icon() + +/obj/machinery/atmospherics/supermatter_crystal/proc/complete_theft(mob/living/carbon/thief) + if(!being_stolen) + return + if(!thief.mind) + return + var/list/obj_list = thief.mind.get_all_objectives() + if(!length(obj_list)) + return + for(var/datum/objective/ninja/ninja_obj in obj_list) + if(ninja_obj.completed) + continue + if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter)) + continue + ninja_obj.complete_objective() + break + message_admins("Ninja [thief] has stolen the Supermatter Crystal.") + qdel(src) + /obj/machinery/atmospherics/supermatter_crystal/singularity_act() var/gain = 100 investigate_log("Supermatter shard consumed by singularity.", INVESTIGATE_SINGULO) @@ -796,6 +844,15 @@ /obj/machinery/atmospherics/supermatter_crystal/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(!istype(used) || (used.flags & ABSTRACT) || !istype(user)) return ITEM_INTERACT_COMPLETE + + if(being_stolen) + to_chat(user, SPAN_WARNING("You begin to very carefully unfasten the net tangled around [src]!")) + if(!do_after_once(user, 5 SECONDS, TRUE, src)) + return ITEM_INTERACT_COMPLETE + being_stolen = FALSE + update_icon() + return ITEM_INTERACT_COMPLETE + if(moveable && default_unfasten_wrench(user, used, time = 20)) return ITEM_INTERACT_COMPLETE diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 4d8a64ffaac..d3a8f599c2f 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index ef45d2122cc..aa4c1f85250 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi index 74602be2cd9..8382b7c9150 100644 Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi index 79f3616db91..83673ef7c63 100644 Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi index 95a804fa631..2d0fa8ded2b 100644 Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi index a959bf06733..5d55cdd544a 100644 Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 02efa70efb0..273875290dd 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/modsuit/mod_clothing.dmi b/icons/mob/clothing/modsuit/mod_clothing.dmi index 767533a4faa..2b11edd7f54 100644 Binary files a/icons/mob/clothing/modsuit/mod_clothing.dmi and b/icons/mob/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/mob/clothing/modsuit/species/diona_modsuits.dmi b/icons/mob/clothing/modsuit/species/diona_modsuits.dmi new file mode 100644 index 00000000000..7d61dd7feda Binary files /dev/null and b/icons/mob/clothing/modsuit/species/diona_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/drask_modsuits.dmi b/icons/mob/clothing/modsuit/species/drask_modsuits.dmi new file mode 100644 index 00000000000..50b7dec3714 Binary files /dev/null and b/icons/mob/clothing/modsuit/species/drask_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/grey_helmets.dmi b/icons/mob/clothing/modsuit/species/grey_helmets.dmi index c3d6d995264..d6c1c0eac3e 100644 Binary files a/icons/mob/clothing/modsuit/species/grey_helmets.dmi and b/icons/mob/clothing/modsuit/species/grey_helmets.dmi differ diff --git a/icons/mob/clothing/modsuit/species/kidan_modsuits.dmi b/icons/mob/clothing/modsuit/species/kidan_modsuits.dmi new file mode 100644 index 00000000000..04905c00f7f Binary files /dev/null and b/icons/mob/clothing/modsuit/species/kidan_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/nian_modsuits.dmi b/icons/mob/clothing/modsuit/species/nian_modsuits.dmi new file mode 100644 index 00000000000..1851eb421a9 Binary files /dev/null and b/icons/mob/clothing/modsuit/species/nian_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/skrell_modsuits.dmi b/icons/mob/clothing/modsuit/species/skrell_modsuits.dmi new file mode 100644 index 00000000000..f8fba2b4140 Binary files /dev/null and b/icons/mob/clothing/modsuit/species/skrell_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/taj_modsuits.dmi b/icons/mob/clothing/modsuit/species/taj_modsuits.dmi index 68504935d6a..9bb93090282 100644 Binary files a/icons/mob/clothing/modsuit/species/taj_modsuits.dmi and b/icons/mob/clothing/modsuit/species/taj_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/unathi_modsuits.dmi b/icons/mob/clothing/modsuit/species/unathi_modsuits.dmi index 0f6a9594e3e..b213f06a4fb 100644 Binary files a/icons/mob/clothing/modsuit/species/unathi_modsuits.dmi and b/icons/mob/clothing/modsuit/species/unathi_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/vox_modsuits.dmi b/icons/mob/clothing/modsuit/species/vox_modsuits.dmi index 8ac2a37e068..b04557af04e 100644 Binary files a/icons/mob/clothing/modsuit/species/vox_modsuits.dmi and b/icons/mob/clothing/modsuit/species/vox_modsuits.dmi differ diff --git a/icons/mob/clothing/modsuit/species/vulp_modsuits.dmi b/icons/mob/clothing/modsuit/species/vulp_modsuits.dmi index b6ba4ccc0a1..088ff2a75ee 100644 Binary files a/icons/mob/clothing/modsuit/species/vulp_modsuits.dmi and b/icons/mob/clothing/modsuit/species/vulp_modsuits.dmi differ diff --git a/icons/mob/clothing/species/diona/gloves.dmi b/icons/mob/clothing/species/diona/gloves.dmi new file mode 100644 index 00000000000..0f5476d079d Binary files /dev/null and b/icons/mob/clothing/species/diona/gloves.dmi differ diff --git a/icons/mob/clothing/species/diona/head.dmi b/icons/mob/clothing/species/diona/head.dmi new file mode 100644 index 00000000000..6d0730c5b9c Binary files /dev/null and b/icons/mob/clothing/species/diona/head.dmi differ diff --git a/icons/mob/clothing/species/diona/mask.dmi b/icons/mob/clothing/species/diona/mask.dmi new file mode 100644 index 00000000000..f894d3f576c Binary files /dev/null and b/icons/mob/clothing/species/diona/mask.dmi differ diff --git a/icons/mob/clothing/species/diona/shoes.dmi b/icons/mob/clothing/species/diona/shoes.dmi new file mode 100644 index 00000000000..656fc62bb76 Binary files /dev/null and b/icons/mob/clothing/species/diona/shoes.dmi differ diff --git a/icons/mob/clothing/species/diona/suit.dmi b/icons/mob/clothing/species/diona/suit.dmi new file mode 100644 index 00000000000..bced7327cfe Binary files /dev/null and b/icons/mob/clothing/species/diona/suit.dmi differ diff --git a/icons/mob/clothing/species/drask/gloves.dmi b/icons/mob/clothing/species/drask/gloves.dmi index 01e46d55f2b..ffb56b05b6e 100644 Binary files a/icons/mob/clothing/species/drask/gloves.dmi and b/icons/mob/clothing/species/drask/gloves.dmi differ diff --git a/icons/mob/clothing/species/drask/head.dmi b/icons/mob/clothing/species/drask/head.dmi index afa56c5e6b7..9c2da14f14c 100644 Binary files a/icons/mob/clothing/species/drask/head.dmi and b/icons/mob/clothing/species/drask/head.dmi differ diff --git a/icons/mob/clothing/species/drask/mask.dmi b/icons/mob/clothing/species/drask/mask.dmi index 44a7cad1aa0..63f80d8760b 100644 Binary files a/icons/mob/clothing/species/drask/mask.dmi and b/icons/mob/clothing/species/drask/mask.dmi differ diff --git a/icons/mob/clothing/species/drask/shoes.dmi b/icons/mob/clothing/species/drask/shoes.dmi index 7758a0b0e11..94c711f3411 100644 Binary files a/icons/mob/clothing/species/drask/shoes.dmi and b/icons/mob/clothing/species/drask/shoes.dmi differ diff --git a/icons/mob/clothing/species/drask/suit.dmi b/icons/mob/clothing/species/drask/suit.dmi index 33e4bb7160e..7254ebe88a2 100644 Binary files a/icons/mob/clothing/species/drask/suit.dmi and b/icons/mob/clothing/species/drask/suit.dmi differ diff --git a/icons/mob/clothing/species/grey/head.dmi b/icons/mob/clothing/species/grey/head.dmi index 89c99343ecf..08208d5d645 100644 Binary files a/icons/mob/clothing/species/grey/head.dmi and b/icons/mob/clothing/species/grey/head.dmi differ diff --git a/icons/mob/clothing/species/grey/mask.dmi b/icons/mob/clothing/species/grey/mask.dmi index a625cb7f24b..5d0d2bbcf3a 100644 Binary files a/icons/mob/clothing/species/grey/mask.dmi and b/icons/mob/clothing/species/grey/mask.dmi differ diff --git a/icons/mob/clothing/species/grey/suit.dmi b/icons/mob/clothing/species/grey/suit.dmi index f4ed7e88679..879c923253f 100644 Binary files a/icons/mob/clothing/species/grey/suit.dmi and b/icons/mob/clothing/species/grey/suit.dmi differ diff --git a/icons/mob/clothing/species/kidan/gloves.dmi b/icons/mob/clothing/species/kidan/gloves.dmi index 9e9963baf73..cc6ab285852 100644 Binary files a/icons/mob/clothing/species/kidan/gloves.dmi and b/icons/mob/clothing/species/kidan/gloves.dmi differ diff --git a/icons/mob/clothing/species/kidan/head.dmi b/icons/mob/clothing/species/kidan/head.dmi index 6e99f871aed..8904bdf9927 100644 Binary files a/icons/mob/clothing/species/kidan/head.dmi and b/icons/mob/clothing/species/kidan/head.dmi differ diff --git a/icons/mob/clothing/species/kidan/mask.dmi b/icons/mob/clothing/species/kidan/mask.dmi index 89d446b9b37..86e5dfcff4a 100644 Binary files a/icons/mob/clothing/species/kidan/mask.dmi and b/icons/mob/clothing/species/kidan/mask.dmi differ diff --git a/icons/mob/clothing/species/kidan/shoes.dmi b/icons/mob/clothing/species/kidan/shoes.dmi new file mode 100644 index 00000000000..78c3c7e0f55 Binary files /dev/null and b/icons/mob/clothing/species/kidan/shoes.dmi differ diff --git a/icons/mob/clothing/species/kidan/suit.dmi b/icons/mob/clothing/species/kidan/suit.dmi index 5bd7a3dd1dc..4c8e020dd07 100644 Binary files a/icons/mob/clothing/species/kidan/suit.dmi and b/icons/mob/clothing/species/kidan/suit.dmi differ diff --git a/icons/mob/clothing/species/machine/monitor/hood.dmi b/icons/mob/clothing/species/machine/monitor/hood.dmi index e96062f9507..cd0d52b7579 100644 Binary files a/icons/mob/clothing/species/machine/monitor/hood.dmi and b/icons/mob/clothing/species/machine/monitor/hood.dmi differ diff --git a/icons/mob/clothing/species/machine/monitor/mask.dmi b/icons/mob/clothing/species/machine/monitor/mask.dmi new file mode 100644 index 00000000000..6f369e3a169 Binary files /dev/null and b/icons/mob/clothing/species/machine/monitor/mask.dmi differ diff --git a/icons/mob/clothing/species/nian/head.dmi b/icons/mob/clothing/species/nian/head.dmi index 6d183b6ffac..1dc428c5a8e 100644 Binary files a/icons/mob/clothing/species/nian/head.dmi and b/icons/mob/clothing/species/nian/head.dmi differ diff --git a/icons/mob/clothing/species/nian/mask.dmi b/icons/mob/clothing/species/nian/mask.dmi new file mode 100644 index 00000000000..ba3820578f3 Binary files /dev/null and b/icons/mob/clothing/species/nian/mask.dmi differ diff --git a/icons/mob/clothing/species/nian/suit.dmi b/icons/mob/clothing/species/nian/suit.dmi new file mode 100644 index 00000000000..60ad5713e4e Binary files /dev/null and b/icons/mob/clothing/species/nian/suit.dmi differ diff --git a/icons/mob/clothing/species/skkulakin/head.dmi b/icons/mob/clothing/species/skkulakin/head.dmi index 0342016f86c..0ee4a5edbec 100644 Binary files a/icons/mob/clothing/species/skkulakin/head.dmi and b/icons/mob/clothing/species/skkulakin/head.dmi differ diff --git a/icons/mob/clothing/species/skkulakin/mask.dmi b/icons/mob/clothing/species/skkulakin/mask.dmi index 129a9e4b309..124828021ce 100644 Binary files a/icons/mob/clothing/species/skkulakin/mask.dmi and b/icons/mob/clothing/species/skkulakin/mask.dmi differ diff --git a/icons/mob/clothing/species/skrell/head.dmi b/icons/mob/clothing/species/skrell/head.dmi index 9a97aa6605f..20f40eeaf39 100644 Binary files a/icons/mob/clothing/species/skrell/head.dmi and b/icons/mob/clothing/species/skrell/head.dmi differ diff --git a/icons/mob/clothing/species/skrell/mask.dmi b/icons/mob/clothing/species/skrell/mask.dmi index 65f617a604d..60a355b3a50 100644 Binary files a/icons/mob/clothing/species/skrell/mask.dmi and b/icons/mob/clothing/species/skrell/mask.dmi differ diff --git a/icons/mob/clothing/species/tajaran/head.dmi b/icons/mob/clothing/species/tajaran/head.dmi index e736cec01ce..9976107156a 100644 Binary files a/icons/mob/clothing/species/tajaran/head.dmi and b/icons/mob/clothing/species/tajaran/head.dmi differ diff --git a/icons/mob/clothing/species/tajaran/mask.dmi b/icons/mob/clothing/species/tajaran/mask.dmi index cbbc968481d..0532e2c0eab 100644 Binary files a/icons/mob/clothing/species/tajaran/mask.dmi and b/icons/mob/clothing/species/tajaran/mask.dmi differ diff --git a/icons/mob/clothing/species/unathi/head.dmi b/icons/mob/clothing/species/unathi/head.dmi index de9cf4a7713..43af3a3aeaf 100644 Binary files a/icons/mob/clothing/species/unathi/head.dmi and b/icons/mob/clothing/species/unathi/head.dmi differ diff --git a/icons/mob/clothing/species/unathi/mask.dmi b/icons/mob/clothing/species/unathi/mask.dmi index 54f560e7a63..377e06fe8de 100644 Binary files a/icons/mob/clothing/species/unathi/mask.dmi and b/icons/mob/clothing/species/unathi/mask.dmi differ diff --git a/icons/mob/clothing/species/vox/gloves.dmi b/icons/mob/clothing/species/vox/gloves.dmi index af691ab7a7e..cf8fb5e42df 100644 Binary files a/icons/mob/clothing/species/vox/gloves.dmi and b/icons/mob/clothing/species/vox/gloves.dmi differ diff --git a/icons/mob/clothing/species/vox/head.dmi b/icons/mob/clothing/species/vox/head.dmi index 0680c279d0a..73377359c54 100644 Binary files a/icons/mob/clothing/species/vox/head.dmi and b/icons/mob/clothing/species/vox/head.dmi differ diff --git a/icons/mob/clothing/species/vox/mask.dmi b/icons/mob/clothing/species/vox/mask.dmi index 26dbe766c39..f070896c8ae 100644 Binary files a/icons/mob/clothing/species/vox/mask.dmi and b/icons/mob/clothing/species/vox/mask.dmi differ diff --git a/icons/mob/clothing/species/vox/shoes.dmi b/icons/mob/clothing/species/vox/shoes.dmi index 2a76db03982..30bebe00bd1 100644 Binary files a/icons/mob/clothing/species/vox/shoes.dmi and b/icons/mob/clothing/species/vox/shoes.dmi differ diff --git a/icons/mob/clothing/species/vox/suit.dmi b/icons/mob/clothing/species/vox/suit.dmi index 2d3a3d78c9d..64d9b79b2f1 100644 Binary files a/icons/mob/clothing/species/vox/suit.dmi and b/icons/mob/clothing/species/vox/suit.dmi differ diff --git a/icons/mob/clothing/species/vulpkanin/head.dmi b/icons/mob/clothing/species/vulpkanin/head.dmi index 7a4a5cc9387..9e29ea702e0 100644 Binary files a/icons/mob/clothing/species/vulpkanin/head.dmi and b/icons/mob/clothing/species/vulpkanin/head.dmi differ diff --git a/icons/mob/clothing/species/vulpkanin/mask.dmi b/icons/mob/clothing/species/vulpkanin/mask.dmi index 435b372071a..66ec1f03575 100644 Binary files a/icons/mob/clothing/species/vulpkanin/mask.dmi and b/icons/mob/clothing/species/vulpkanin/mask.dmi differ diff --git a/icons/mob/clothing/suit.dmi b/icons/mob/clothing/suit.dmi index 19e5653262f..1cbd0762402 100644 Binary files a/icons/mob/clothing/suit.dmi and b/icons/mob/clothing/suit.dmi differ diff --git a/icons/mob/hud/antaghud.dmi b/icons/mob/hud/antaghud.dmi index 83e3258def6..5d522722709 100644 Binary files a/icons/mob/hud/antaghud.dmi and b/icons/mob/hud/antaghud.dmi differ diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index 61c5575e430..7a546b1255b 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index b18e637f99a..2d27afcb895 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 48b97e2763e..b4e812d2ea6 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index ebc2e68e7af..71537bfb99b 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 3b91d89b6ec..0ccf371080f 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_clothing.dmi b/icons/obj/clothing/modsuit/mod_clothing.dmi index 37d4316c7c0..70ab6906739 100644 Binary files a/icons/obj/clothing/modsuit/mod_clothing.dmi and b/icons/obj/clothing/modsuit/mod_clothing.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index c10b9396901..b45c8b27b0f 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index c0f587f592b..3cc01448303 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 5e0e58f477e..1803eb32644 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index 84218f24808..6ca66c5d168 100644 Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index ef09725bc90..b0a9d8dd1e1 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/weapons/energy_melee.dmi b/icons/obj/weapons/energy_melee.dmi index e8dea9c0848..a2ea548314b 100644 Binary files a/icons/obj/weapons/energy_melee.dmi and b/icons/obj/weapons/energy_melee.dmi differ diff --git a/icons/obj/weapons/melee.dmi b/icons/obj/weapons/melee.dmi index 74dabd82e32..aedd92d5e42 100644 Binary files a/icons/obj/weapons/melee.dmi and b/icons/obj/weapons/melee.dmi differ diff --git a/paradise.dme b/paradise.dme index dd2e87f3f94..83c0017f2b2 100644 --- a/paradise.dme +++ b/paradise.dme @@ -932,6 +932,7 @@ #include "code\game\dna\mutations\mutation_powers.dm" #include "code\game\gamemodes\game_mode.dm" #include "code\game\gamemodes\intercept_report.dm" +#include "code\game\gamemodes\ninja_objectives.dm" #include "code\game\gamemodes\objective.dm" #include "code\game\gamemodes\objective_holder.dm" #include "code\game\gamemodes\objectives_subtypes.dm" @@ -1875,6 +1876,7 @@ #include "code\modules\antagonists\revolutionary\datum_headrev.dm" #include "code\modules\antagonists\revolutionary\datum_revolutionary.dm" #include "code\modules\antagonists\revolutionary\team_revolution.dm" +#include "code\modules\antagonists\space_ninja\datum_space_ninja.dm" #include "code\modules\antagonists\survivalist\survivalist.dm" #include "code\modules\antagonists\traitor\datum_mindslave.dm" #include "code\modules\antagonists\traitor\datum_traitor.dm" @@ -2283,6 +2285,7 @@ #include "code\modules\events\sentience.dm" #include "code\modules\events\slaughterevent.dm" #include "code\modules\events\solarflare.dm" +#include "code\modules\events\space_ninja.dm" #include "code\modules\events\spacevine.dm" #include "code\modules\events\spider_infestation.dm" #include "code\modules\events\spider_terror.dm" @@ -3040,13 +3043,13 @@ #include "code\modules\newscaster\newsfeed_datums.dm" #include "code\modules\newscaster\obj\newscaster.dm" #include "code\modules\newscaster\obj\newspaper.dm" -#include "code\modules\ninja\energy_katana.dm" -#include "code\modules\ninja\suit\ninja_gloves.dm" -#include "code\modules\ninja\suit\ninja_head.dm" -#include "code\modules\ninja\suit\ninja_mask.dm" -#include "code\modules\ninja\suit\ninja_shoes.dm" -#include "code\modules\ninja\suit\ninja_suit.dm" -#include "code\modules\ninja\suit\suit_initialisation.dm" +#include "code\modules\ninja\ninja_actions.dm" +#include "code\modules\ninja\ninja_clothes.dm" +#include "code\modules\ninja\ninja_deployables.dm" +#include "code\modules\ninja\ninja_outfits.dm" +#include "code\modules\ninja\ninja_scanner.dm" +#include "code\modules\ninja\ninja_uplink.dm" +#include "code\modules\ninja\ninja_weapons.dm" #include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\desk_bell.dm" diff --git a/sound/ambience/antag/ninjaalert.ogg b/sound/ambience/antag/ninjaalert.ogg new file mode 100644 index 00000000000..2d6847400c0 Binary files /dev/null and b/sound/ambience/antag/ninjaalert.ogg differ