Merge branch 'master' into Filet-o-fish
This commit is contained in:
+3
-3
@@ -6,15 +6,15 @@
|
||||
|
||||
#deathride58
|
||||
/modular_citadel/ @deathride58
|
||||
/code/citadel/ @deathride58
|
||||
|
||||
#LetterJay
|
||||
/modular_citadel/code/modules/client/loadout/__donator.dm @LetterJay
|
||||
|
||||
#Poojawa
|
||||
|
||||
/code/modules/vore @Poojawa
|
||||
/code/citadel/dogborgstuff.dmm @Poojawa
|
||||
/modular_citadel/code/modules/vore @Poojawa
|
||||
/code/game/objects/items/devices/dogborg_sleeper.dm @Poojawa
|
||||
/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @Poojawa
|
||||
/tgui/ @Poojawa
|
||||
/modular_citadel/code/modules/clothing/spacesuits/flightsuit.dm @Poojawa
|
||||
/modular_citadel/code/game/objects/ids.dm @Poojawa
|
||||
|
||||
@@ -198,3 +198,4 @@ tools/MapAtmosFixer/MapAtmosFixer/obj/x86/Debug/MapAtmosFixer.csproj.CoreCompile
|
||||
|
||||
#GitHub Atom
|
||||
.atom-build.json
|
||||
cfg/admin.txt
|
||||
|
||||
@@ -0,0 +1,503 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"c" = (
|
||||
/obj/structure/grille,
|
||||
/obj/structure/window/reinforced/fulltile,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"d" = (
|
||||
/turf/closed/wall/r_wall/rust,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"e" = (
|
||||
/obj/machinery/defibrillator_mount/loaded,
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"f" = (
|
||||
/obj/structure/grille,
|
||||
/obj/structure/window/reinforced/fulltile,
|
||||
/turf/open/floor/plasteel/airless,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"g" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/device/flashlight/lamp,
|
||||
/obj/effect/decal/cleanable/cobweb,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"h" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/pen,
|
||||
/obj/item/paper/fluff/ruins/exp_cloning/log,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"i" = (
|
||||
/obj/machinery/dna_scannernew,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"j" = (
|
||||
/obj/machinery/computer/prototype_cloning,
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/obj/item/paper/fluff/ruins/exp_cloning/manual,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"k" = (
|
||||
/obj/machinery/clonepod/experimental,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"l" = (
|
||||
/obj/effect/decal/cleanable/vomit/old,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"m" = (
|
||||
/obj/effect/decal/cleanable/cobweb/cobweb2,
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"n" = (
|
||||
/obj/structure/sign/nanotrasen,
|
||||
/turf/closed/wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"o" = (
|
||||
/obj/machinery/vending/snack/teal,
|
||||
/turf/open/floor/plasteel/airless/floorgrime,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"p" = (
|
||||
/turf/open/floor/plasteel/airless/floorgrime,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"q" = (
|
||||
/obj/structure/sign/directions/science{
|
||||
dir = 8
|
||||
},
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"r" = (
|
||||
/obj/effect/decal/remains/human,
|
||||
/obj/effect/decal/cleanable/blood/old,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"s" = (
|
||||
/obj/machinery/iv_drip,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"t" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/bed,
|
||||
/obj/item/bedsheet/medical,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"u" = (
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"v" = (
|
||||
/turf/open/floor/plasteel/whiteblue/corner{
|
||||
dir = 4
|
||||
},
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"w" = (
|
||||
/obj/structure/chair/office{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteblue/side{
|
||||
dir = 1
|
||||
},
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"x" = (
|
||||
/turf/open/floor/plasteel/whiteblue/side{
|
||||
dir = 1
|
||||
},
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"y" = (
|
||||
/obj/structure/chair/office{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteblue,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"z" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteblue/corner{
|
||||
dir = 1
|
||||
},
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"A" = (
|
||||
/obj/structure/sign/departments/science,
|
||||
/turf/closed/wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"B" = (
|
||||
/turf/open/floor/plasteel/airless,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"C" = (
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"D" = (
|
||||
/obj/structure/chair/comfy{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"E" = (
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"F" = (
|
||||
/obj/machinery/door/airlock/research/glass,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"G" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"H" = (
|
||||
/obj/machinery/door/airlock/research/glass,
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"I" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"J" = (
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"K" = (
|
||||
/obj/machinery/door/airlock/research/glass,
|
||||
/turf/open/floor/plasteel/airless,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"L" = (
|
||||
/turf/open/floor/plating/airless{
|
||||
icon_state = "platingdmg1"
|
||||
},
|
||||
/area/space/nearstation)
|
||||
"M" = (
|
||||
/obj/structure/fluff/broken_flooring{
|
||||
name = "broken plating";
|
||||
icon_state = "plating";
|
||||
dir = 8
|
||||
},
|
||||
/turf/template_noop,
|
||||
/area/space/nearstation)
|
||||
"N" = (
|
||||
/obj/item/book/random/triple,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"O" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/bookcase/random/fiction,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"P" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/machinery/light,
|
||||
/obj/structure/bedsheetbin,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"Q" = (
|
||||
/obj/structure/table/glass,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"R" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/item/storage/firstaid/regular,
|
||||
/obj/item/device/healthanalyzer{
|
||||
desc = "A prototype hand-held body scanner able to distinguish vital signs of the subject.";
|
||||
name = "prototype health analyzer"
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"S" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/item/storage/box/syringes,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"T" = (
|
||||
/turf/closed/wall,
|
||||
/area/ruin/space/has_grav/powered/ancient_shuttle)
|
||||
"U" = (
|
||||
/turf/open/floor/plating/airless{
|
||||
icon_state = "platingdmg2"
|
||||
},
|
||||
/area/space/nearstation)
|
||||
"V" = (
|
||||
/turf/closed/wall/r_wall/rust,
|
||||
/area/space/nearstation)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
a
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
a
|
||||
c
|
||||
r
|
||||
D
|
||||
N
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
a
|
||||
a
|
||||
c
|
||||
s
|
||||
E
|
||||
E
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
a
|
||||
d
|
||||
t
|
||||
E
|
||||
O
|
||||
d
|
||||
a
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
a
|
||||
d
|
||||
b
|
||||
F
|
||||
d
|
||||
d
|
||||
a
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
b
|
||||
G
|
||||
b
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
a
|
||||
d
|
||||
d
|
||||
H
|
||||
b
|
||||
b
|
||||
a
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
b
|
||||
b
|
||||
u
|
||||
I
|
||||
I
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
c
|
||||
g
|
||||
v
|
||||
J
|
||||
J
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
c
|
||||
h
|
||||
w
|
||||
J
|
||||
J
|
||||
d
|
||||
a
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
d
|
||||
i
|
||||
x
|
||||
J
|
||||
P
|
||||
b
|
||||
a
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
b
|
||||
j
|
||||
y
|
||||
J
|
||||
Q
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
b
|
||||
k
|
||||
x
|
||||
J
|
||||
R
|
||||
c
|
||||
a
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
e
|
||||
l
|
||||
x
|
||||
J
|
||||
S
|
||||
d
|
||||
a
|
||||
a
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
d
|
||||
m
|
||||
z
|
||||
J
|
||||
J
|
||||
d
|
||||
a
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
d
|
||||
n
|
||||
A
|
||||
K
|
||||
T
|
||||
b
|
||||
a
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
a
|
||||
f
|
||||
o
|
||||
B
|
||||
p
|
||||
C
|
||||
V
|
||||
a
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
f
|
||||
p
|
||||
p
|
||||
C
|
||||
U
|
||||
M
|
||||
a
|
||||
a
|
||||
"}
|
||||
(21,1,1) = {"
|
||||
a
|
||||
d
|
||||
q
|
||||
C
|
||||
L
|
||||
M
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(22,1,1) = {"
|
||||
a
|
||||
a
|
||||
b
|
||||
f
|
||||
M
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(23,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2574,7 +2574,7 @@
|
||||
c_tag = "AI Vault - Port";
|
||||
dir = 4;
|
||||
name = "ai camera";
|
||||
network = list("Sat");
|
||||
network = list("minisat");
|
||||
start_active = 1
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
@@ -3515,7 +3515,7 @@
|
||||
c_tag = "AI Vault - Starboard";
|
||||
dir = 8;
|
||||
name = "ai camera";
|
||||
network = list("Sat");
|
||||
network = list("minisat");
|
||||
start_active = 1
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
@@ -4081,8 +4081,7 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Armoury - Internal";
|
||||
network = list("Labor")
|
||||
c_tag = "Armoury - Internal"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
@@ -4542,8 +4541,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Security - Cell 1";
|
||||
network = list("MINE")
|
||||
c_tag = "Security - Cell 1"
|
||||
},
|
||||
/turf/open/floor/plasteel/red/side{
|
||||
dir = 5
|
||||
@@ -4569,8 +4567,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Fore Primary Hallway";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/red/corner{
|
||||
dir = 1
|
||||
@@ -5967,8 +5964,7 @@
|
||||
/obj/item/stamp,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Cargo Bay Entrance";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/brown{
|
||||
dir = 8
|
||||
@@ -6147,8 +6143,7 @@
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Security - Cell 2";
|
||||
network = list("MINE")
|
||||
c_tag = "Security - Cell 2"
|
||||
},
|
||||
/turf/open/floor/plasteel/red/side{
|
||||
dir = 5
|
||||
@@ -6521,8 +6516,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Security - Office";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/red/corner{
|
||||
dir = 1
|
||||
@@ -6547,8 +6541,7 @@
|
||||
"amK" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Security - Central";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral/side{
|
||||
dir = 8
|
||||
@@ -6629,8 +6622,7 @@
|
||||
"amS" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Locker Room Toilets";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/freezer,
|
||||
/area/hallway/primary/central)
|
||||
@@ -8505,8 +8497,7 @@
|
||||
/obj/item/shovel,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Mining Dock";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel,
|
||||
@@ -9015,7 +9006,6 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Tank 4";
|
||||
network = list("thunder");
|
||||
pixel_x = 10
|
||||
},
|
||||
/turf/open/floor/plasteel/green/side{
|
||||
@@ -9418,8 +9408,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Central Diner 3";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
dir = 4
|
||||
@@ -10058,8 +10047,7 @@
|
||||
"atz" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Tank 1";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 5
|
||||
@@ -10454,8 +10442,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Bar";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 8
|
||||
@@ -10473,8 +10460,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Bar Backroom";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
@@ -11736,8 +11722,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics East";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/caution{
|
||||
dir = 4
|
||||
@@ -11956,8 +11941,7 @@
|
||||
"axj" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Tank 2";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 5
|
||||
@@ -12059,8 +12043,7 @@
|
||||
/obj/machinery/portable_atmospherics/canister/nitrogen,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Monitoring";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel,
|
||||
@@ -12634,8 +12617,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Central Diner 2";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
dir = 4
|
||||
@@ -13466,8 +13448,7 @@
|
||||
/obj/structure/bedsheetbin,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Locker Room East";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/arrival{
|
||||
@@ -14488,8 +14469,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Central Hallway East";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral/corner{
|
||||
dir = 1
|
||||
@@ -15091,8 +15071,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Secure Storage";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
@@ -15337,8 +15316,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Locker Room South";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault{
|
||||
@@ -15695,8 +15673,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "SMES Access";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 2
|
||||
@@ -15739,8 +15716,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Access";
|
||||
dir = 8;
|
||||
network = list("Labor")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 6
|
||||
@@ -15877,8 +15853,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Central Diner 1";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/redyellow,
|
||||
/area/crew_quarters/bar/atrium)
|
||||
@@ -16458,8 +16433,7 @@
|
||||
"aHg" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Gravity Generator Room";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot_white/left,
|
||||
/turf/open/floor/plasteel/vault{
|
||||
@@ -16559,7 +16533,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Fore";
|
||||
dir = 2;
|
||||
network = list("SS13","Engine");
|
||||
network = list("ss13","engine");
|
||||
pixel_x = 23
|
||||
},
|
||||
/turf/open/floor/engine,
|
||||
@@ -17184,8 +17158,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Monitoring";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel,
|
||||
@@ -18010,7 +17983,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Kitchen Coldroom";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
network = list("mine")
|
||||
},
|
||||
/turf/open/floor/plasteel/freezer,
|
||||
/area/crew_quarters/kitchen)
|
||||
@@ -19145,7 +19118,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Port";
|
||||
dir = 4;
|
||||
network = list("SS13","Engine")
|
||||
network = list("ss13","engine")
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
@@ -19171,7 +19144,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Supermatter Chamber";
|
||||
dir = 2;
|
||||
network = list("Engine");
|
||||
network = list("engine");
|
||||
pixel_x = 23
|
||||
},
|
||||
/obj/structure/cable{
|
||||
@@ -19285,7 +19258,7 @@
|
||||
desc = "Used for watching the Engine.";
|
||||
dir = 1;
|
||||
name = "Engine Monitor";
|
||||
network = list("Engine");
|
||||
network = list("engine");
|
||||
pixel_y = -32
|
||||
},
|
||||
/obj/machinery/rnd/protolathe/department/engineering,
|
||||
@@ -19335,8 +19308,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics South West";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral/corner{
|
||||
dir = 8;
|
||||
@@ -19468,8 +19440,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Hydroponics South";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
@@ -20153,8 +20124,7 @@
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Aft Primary Hallway 4";
|
||||
network = list("SS13","Prison")
|
||||
c_tag = "Aft Primary Hallway 4"
|
||||
},
|
||||
/turf/open/floor/plasteel/green/corner{
|
||||
dir = 1
|
||||
@@ -20262,8 +20232,7 @@
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Aft Primary Hallway 3";
|
||||
network = list("SS13","Prison")
|
||||
c_tag = "Aft Primary Hallway 3"
|
||||
},
|
||||
/turf/open/floor/plasteel/green/corner{
|
||||
dir = 1
|
||||
@@ -21100,7 +21069,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Aft";
|
||||
dir = 2;
|
||||
network = list("SS13","Engine");
|
||||
network = list("ss13","engine");
|
||||
pixel_x = 23
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/orange/visible{
|
||||
@@ -21257,8 +21226,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Aft Primary Hallway 2";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/yellow/corner{
|
||||
dir = 8
|
||||
@@ -21535,8 +21503,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Library 2";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/library)
|
||||
@@ -21685,8 +21652,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Chemistry";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteyellow/corner{
|
||||
dir = 1
|
||||
@@ -22567,8 +22533,7 @@
|
||||
"aUo" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Genetics Cloning";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteblue/corner{
|
||||
dir = 1
|
||||
@@ -23136,7 +23101,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Server Room";
|
||||
dir = 2;
|
||||
network = list("SS13","RD");
|
||||
network = list("ss13","rd");
|
||||
pixel_x = 22
|
||||
},
|
||||
/turf/open/floor/circuit/green/telecomms/mainframe,
|
||||
@@ -23645,8 +23610,7 @@
|
||||
/obj/structure/closet/crate/bin,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay Morgue";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
dir = 8
|
||||
@@ -23914,8 +23878,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay West";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -24230,8 +24193,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay Storage";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/structure/window/reinforced{
|
||||
@@ -24495,8 +24457,7 @@
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Research Division South";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/whitepurple/corner,
|
||||
/area/science/research)
|
||||
@@ -25331,7 +25292,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Robotics Lab";
|
||||
dir = 2;
|
||||
network = list("SS13","RD")
|
||||
network = list("ss13","rd")
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault/side,
|
||||
@@ -25637,8 +25598,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay Foyer";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral,
|
||||
/area/hallway/primary/central)
|
||||
@@ -26708,8 +26668,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay South";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/whiteblue/corner{
|
||||
dir = 8
|
||||
@@ -27226,8 +27185,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Medbay Recovery Room";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
dir = 8
|
||||
@@ -28451,7 +28409,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Xenobiology Test Chamber";
|
||||
dir = 2;
|
||||
network = list("Xeno","RD")
|
||||
network = list("xeno","rd")
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 4
|
||||
@@ -28546,7 +28504,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Crematorium";
|
||||
dir = 4;
|
||||
network = list("MINE")
|
||||
network = list("mine")
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
dir = 4
|
||||
@@ -29231,8 +29189,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Chaplain's Quarters";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 8
|
||||
@@ -29278,8 +29235,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Chapel Office";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/chapel/main)
|
||||
@@ -29714,8 +29670,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Chapel South";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 5
|
||||
@@ -29737,8 +29692,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Arrivals Hallway 3";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 2
|
||||
@@ -29825,7 +29779,7 @@
|
||||
c_tag = "Science - Server Room";
|
||||
dir = 8;
|
||||
name = "science camera";
|
||||
network = list("SS13","RD")
|
||||
network = list("ss13","rd")
|
||||
},
|
||||
/turf/open/floor/circuit/green/telecomms/mainframe,
|
||||
/area/science/xenobiology)
|
||||
@@ -30413,8 +30367,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Port Primary Hallway";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 2
|
||||
@@ -30431,8 +30384,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Starboard Primary Hallway 2";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral/corner,
|
||||
/area/hallway/primary/central)
|
||||
@@ -30440,8 +30392,7 @@
|
||||
/obj/structure/closet/firecloset,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Starboard Primary Hallway 2";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
@@ -30464,8 +30415,7 @@
|
||||
"blk" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Atmospherics Tank 3";
|
||||
dir = 4;
|
||||
network = list("SS13")
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 5
|
||||
@@ -30478,12 +30428,11 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Shuttle Docking Foyer";
|
||||
dir = 8;
|
||||
network = list("MINE")
|
||||
network = list("mine")
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Escape Arm Airlocks";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel,
|
||||
@@ -30492,8 +30441,7 @@
|
||||
/obj/structure/closet/emcloset,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Starboard Primary Hallway";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/effect/turf_decal/bot,
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
@@ -30507,7 +30455,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Engineering Starboard";
|
||||
dir = 8;
|
||||
network = list("SS13","Engine")
|
||||
network = list("ss13","engine")
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -30523,8 +30471,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Research Division Access";
|
||||
dir = 2;
|
||||
network = list("SS13")
|
||||
dir = 2
|
||||
},
|
||||
/obj/structure/cable/white{
|
||||
icon_state = "2-8"
|
||||
@@ -30538,7 +30485,6 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Aft Primary Hallway 1";
|
||||
dir = 8;
|
||||
network = list("SS13");
|
||||
pixel_y = -22
|
||||
},
|
||||
/turf/open/floor/plasteel/purple/corner,
|
||||
@@ -30583,7 +30529,6 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Surgery Operating";
|
||||
dir = 1;
|
||||
network = list("SS13");
|
||||
pixel_x = 22
|
||||
},
|
||||
/turf/open/floor/plasteel/neutral,
|
||||
@@ -30592,7 +30537,7 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Xenobiology Test Chamber";
|
||||
dir = 2;
|
||||
network = list("Xeno","RD")
|
||||
network = list("xeno","rd")
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 5
|
||||
@@ -30615,8 +30560,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Arrivals Hallway";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -30627,8 +30571,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Arrivals Hallway 2";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -30685,8 +30628,7 @@
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Chapel Mass Driver";
|
||||
dir = 8;
|
||||
network = list("SS13")
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/light/small,
|
||||
/obj/machinery/button/massdriver{
|
||||
@@ -31264,8 +31206,7 @@
|
||||
"buU" = (
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Communications Relay";
|
||||
dir = 8;
|
||||
network = list("MINE")
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
@@ -33064,7 +33005,7 @@
|
||||
c_tag = "AI Chamber - Core";
|
||||
dir = 2;
|
||||
name = "core camera";
|
||||
network = list("RD")
|
||||
network = list("rd")
|
||||
},
|
||||
/obj/machinery/cell_charger,
|
||||
/turf/open/floor/plasteel/vault/side,
|
||||
@@ -33247,7 +33188,7 @@
|
||||
c_tag = "AI Chamber - Core";
|
||||
dir = 2;
|
||||
name = "core camera";
|
||||
network = list("RD")
|
||||
network = list("rd")
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
@@ -33384,7 +33325,7 @@
|
||||
c_tag = "AI Chamber - Core";
|
||||
dir = 2;
|
||||
name = "core camera";
|
||||
network = list("RD")
|
||||
network = list("rd")
|
||||
},
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
@@ -33617,7 +33558,7 @@
|
||||
c_tag = "AI Satellite - Access";
|
||||
dir = 4;
|
||||
name = "ai camera";
|
||||
network = list("Sat");
|
||||
network = list("minisat");
|
||||
start_active = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
@@ -33905,7 +33846,7 @@
|
||||
c_tag = "AI Satellite - Maintenance";
|
||||
dir = 8;
|
||||
name = "ai camera";
|
||||
network = list("Sat");
|
||||
network = list("minisat");
|
||||
start_active = 1
|
||||
},
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on{
|
||||
@@ -33977,7 +33918,7 @@
|
||||
c_tag = "AI Satellite - Antechamber";
|
||||
dir = 4;
|
||||
name = "ai camera";
|
||||
network = list("Sat");
|
||||
network = list("minisat");
|
||||
start_active = 1
|
||||
},
|
||||
/turf/open/floor/plasteel/vault/side{
|
||||
|
||||
@@ -8933,16 +8933,6 @@
|
||||
dir = 4
|
||||
},
|
||||
/area/bridge)
|
||||
"axf" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/door/poddoor/preopen{
|
||||
id = "bridgespace";
|
||||
name = "bridge external shutters"
|
||||
},
|
||||
/turf/open/floor/plasteel/vault{
|
||||
dir = 8
|
||||
},
|
||||
/area/bridge)
|
||||
"axg" = (
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on,
|
||||
/turf/open/floor/plasteel/dark,
|
||||
@@ -15026,6 +15016,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMq" = (
|
||||
@@ -15033,6 +15026,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMr" = (
|
||||
@@ -15040,6 +15036,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMs" = (
|
||||
@@ -15049,6 +15048,9 @@
|
||||
/obj/structure/sign/poster/official/random{
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMt" = (
|
||||
@@ -15063,6 +15065,9 @@
|
||||
c_tag = "Cargo Warehouse";
|
||||
dir = 2
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMu" = (
|
||||
@@ -15070,6 +15075,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMv" = (
|
||||
@@ -15083,6 +15091,9 @@
|
||||
pixel_x = 26
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aMw" = (
|
||||
@@ -15649,6 +15660,9 @@
|
||||
/obj/structure/sign/poster/official/random{
|
||||
pixel_x = -32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aNO" = (
|
||||
@@ -16155,6 +16169,9 @@
|
||||
"aOY" = (
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aOZ" = (
|
||||
@@ -16542,6 +16559,9 @@
|
||||
req_access_txt = "31"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel/floorgrime,
|
||||
/area/quartermaster/warehouse)
|
||||
"aQd" = (
|
||||
@@ -17040,6 +17060,14 @@
|
||||
/area/quartermaster/sorting)
|
||||
"aRl" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/machinery/power/apc/highcap/fifteen_k{
|
||||
dir = 4;
|
||||
name = "Delivery Office APC";
|
||||
pixel_x = 28
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/sorting)
|
||||
"aRm" = (
|
||||
@@ -17057,6 +17085,9 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/warehouse)
|
||||
"aRo" = (
|
||||
@@ -17434,6 +17465,9 @@
|
||||
"aSh" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/quartermaster/sorting)
|
||||
"aSi" = (
|
||||
@@ -17447,6 +17481,9 @@
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/storage)
|
||||
"aSj" = (
|
||||
@@ -17825,6 +17862,9 @@
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/office)
|
||||
"aTi" = (
|
||||
@@ -17839,6 +17879,9 @@
|
||||
departmentType = 2;
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/storage)
|
||||
"aTj" = (
|
||||
@@ -17851,6 +17894,9 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/storage)
|
||||
"aTl" = (
|
||||
@@ -22032,8 +22078,7 @@
|
||||
},
|
||||
/area/maintenance/department/cargo)
|
||||
"bdA" = (
|
||||
/obj/item/cigbutt,
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/obj/machinery/droneDispenser,
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/department/cargo)
|
||||
"bdB" = (
|
||||
@@ -26568,12 +26613,6 @@
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/xenobiology)
|
||||
"bpp" = (
|
||||
/obj/machinery/computer/camera_advanced/xenobio{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/xenobiology)
|
||||
"bpq" = (
|
||||
/obj/structure/sign/warning/electricshock,
|
||||
/turf/closed/wall/r_wall,
|
||||
@@ -27772,9 +27811,6 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/xenobiology)
|
||||
"brQ" = (
|
||||
/obj/machinery/computer/camera_advanced/xenobio{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Xenobiology Port";
|
||||
dir = 8;
|
||||
@@ -28377,7 +28413,7 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/explab)
|
||||
"btj" = (
|
||||
/obj/machinery/droneDispenser,
|
||||
/obj/structure/table,
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/science/explab)
|
||||
"btk" = (
|
||||
@@ -28566,11 +28602,11 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/science/xenobiology)
|
||||
"btD" = (
|
||||
/turf/open/floor/plating/airless,
|
||||
/turf/open/floor/plating,
|
||||
/area/science/xenobiology)
|
||||
"btE" = (
|
||||
/obj/effect/decal/remains/xeno,
|
||||
/turf/open/floor/plating/airless,
|
||||
/turf/open/floor/plating,
|
||||
/area/science/xenobiology)
|
||||
"btF" = (
|
||||
/obj/structure/chair{
|
||||
@@ -29191,12 +29227,7 @@
|
||||
/obj/machinery/light/small{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Xenobiology Kill Room";
|
||||
dir = 8;
|
||||
network = list("ss13","rd")
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/turf/open/floor/plating,
|
||||
/area/science/xenobiology)
|
||||
"bva" = (
|
||||
/turf/closed/wall,
|
||||
@@ -31263,16 +31294,22 @@
|
||||
/turf/open/floor/plasteel/whitepurple/side,
|
||||
/area/science/xenobiology)
|
||||
"bzi" = (
|
||||
/obj/item/extinguisher{
|
||||
pixel_x = 4;
|
||||
pixel_y = 3
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/item/extinguisher,
|
||||
/obj/structure/table/glass,
|
||||
/turf/open/floor/plasteel/whitepurple/side,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/extinguisher{
|
||||
pixel_x = 2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/extinguisher{
|
||||
pixel_x = 5;
|
||||
pixel_y = 5
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/science/xenobiology)
|
||||
"bzj" = (
|
||||
/obj/structure/reagent_dispensers/watertank,
|
||||
/obj/machinery/requests_console{
|
||||
department = "Science";
|
||||
departmentType = 2;
|
||||
@@ -31280,6 +31317,7 @@
|
||||
pixel_x = 32;
|
||||
receive_ore_updates = 1
|
||||
},
|
||||
/obj/structure/reagent_dispensers/watertank/high,
|
||||
/turf/open/floor/plasteel/whitepurple/side,
|
||||
/area/science/xenobiology)
|
||||
"bzk" = (
|
||||
@@ -32314,6 +32352,9 @@
|
||||
/area/crew_quarters/heads/hor)
|
||||
"bBw" = (
|
||||
/obj/machinery/computer/security,
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plasteel/red/side{
|
||||
dir = 8
|
||||
},
|
||||
@@ -38116,6 +38157,7 @@
|
||||
},
|
||||
/obj/item/stack/sheet/glass,
|
||||
/obj/item/stack/rods/fifty,
|
||||
/obj/item/pipe_dispenser,
|
||||
/turf/open/floor/plasteel/yellow/side,
|
||||
/area/engine/atmos)
|
||||
"bOY" = (
|
||||
@@ -40924,9 +40966,6 @@
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/clipboard,
|
||||
/obj/item/lighter,
|
||||
/obj/item/clothing/glasses/meson{
|
||||
pixel_y = 4
|
||||
},
|
||||
/obj/item/stamp/ce,
|
||||
/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/machinery/keycard_auth{
|
||||
@@ -40941,6 +40980,7 @@
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/item/clothing/glasses/meson/engine,
|
||||
/turf/open/floor/plasteel/yellow/side{
|
||||
dir = 4
|
||||
},
|
||||
@@ -42858,10 +42898,7 @@
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/obj/item/airlock_painter,
|
||||
/obj/item/clothing/glasses/meson{
|
||||
pixel_x = 3;
|
||||
pixel_y = -4
|
||||
},
|
||||
/obj/item/clothing/glasses/meson/engine,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"cap" = (
|
||||
@@ -43196,11 +43233,11 @@
|
||||
"cbe" = (
|
||||
/obj/item/pen,
|
||||
/obj/item/storage/belt/utility,
|
||||
/obj/item/clothing/glasses/meson,
|
||||
/obj/item/paper_bin{
|
||||
layer = 2.9
|
||||
},
|
||||
/obj/structure/table/glass,
|
||||
/obj/item/clothing/glasses/meson/engine,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"cbf" = (
|
||||
@@ -43287,7 +43324,7 @@
|
||||
/obj/structure/table,
|
||||
/obj/item/clothing/gloves/color/yellow,
|
||||
/obj/item/storage/belt/utility,
|
||||
/obj/item/clothing/glasses/meson,
|
||||
/obj/item/clothing/glasses/meson/engine,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/engine/engineering)
|
||||
"cbo" = (
|
||||
@@ -43736,6 +43773,9 @@
|
||||
/obj/item/stack/sheet/mineral/plasma{
|
||||
amount = 30
|
||||
},
|
||||
/obj/item/device/gps{
|
||||
gpstag = "ENG0"
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"ccS" = (
|
||||
@@ -45137,9 +45177,6 @@
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/power/tesla_coil,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chz" = (
|
||||
@@ -45147,9 +45184,6 @@
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/machinery/power/tesla_coil,
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chA" = (
|
||||
@@ -45257,16 +45291,6 @@
|
||||
/obj/structure/grille,
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chQ" = (
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"chR" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
@@ -45420,14 +45444,13 @@
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"cit" = (
|
||||
/obj/machinery/the_singularitygen,
|
||||
/obj/machinery/the_singularitygen/tesla,
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"ciu" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/the_singularitygen/tesla,
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"civ" = (
|
||||
@@ -49969,29 +49992,9 @@
|
||||
/turf/open/floor/plasteel/white,
|
||||
/area/medical/chemistry)
|
||||
"cBQ" = (
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/machinery/power/rad_collector,
|
||||
/turf/open/floor/plating,
|
||||
/area/engine/engineering)
|
||||
"cBR" = (
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/item/tank/internals/plasma,
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"cBS" = (
|
||||
/obj/structure/window/plasma/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/power/rad_collector/anchored,
|
||||
/obj/structure/cable/yellow{
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/open/floor/plating/airless,
|
||||
/area/engine/engineering)
|
||||
"cBT" = (
|
||||
/obj/effect/spawner/structure/window/plasma/reinforced,
|
||||
/turf/open/floor/plating/airless,
|
||||
@@ -50152,6 +50155,16 @@
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/sorting)
|
||||
"frt" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/office)
|
||||
"fyh" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/cable{
|
||||
@@ -50240,12 +50253,24 @@
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/ai_monitored/turret_protected/AIsatextAP)
|
||||
"kqj" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/open/floor/plasteel,
|
||||
/area/quartermaster/storage)
|
||||
"krG" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/library)
|
||||
"let" = (
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/space)
|
||||
"lqy" = (
|
||||
/obj/machinery/door/airlock/centcom{
|
||||
name = "Library"
|
||||
@@ -50255,6 +50280,11 @@
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/open/floor/plasteel/dark,
|
||||
/area/library/lounge)
|
||||
"lvl" = (
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/obj/item/cigbutt,
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/department/cargo)
|
||||
"mHo" = (
|
||||
/obj/structure/table,
|
||||
/obj/machinery/microwave{
|
||||
@@ -50286,6 +50316,15 @@
|
||||
},
|
||||
/turf/open/floor/carpet,
|
||||
/area/library/lounge)
|
||||
"nJY" = (
|
||||
/obj/structure/rack,
|
||||
/obj/item/stack/sheet/glass/fifty{
|
||||
pixel_x = 3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/stack/sheet/metal/fifty,
|
||||
/turf/open/floor/plating,
|
||||
/area/maintenance/department/cargo)
|
||||
"opC" = (
|
||||
/obj/machinery/light/small{
|
||||
dir = 4
|
||||
@@ -50445,6 +50484,10 @@
|
||||
/obj/item/stack/cable_coil,
|
||||
/turf/open/floor/plasteel/whitepurple/side,
|
||||
/area/science/lab)
|
||||
"yia" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/open/space/basic,
|
||||
/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaa
|
||||
@@ -79160,8 +79203,8 @@ bXk
|
||||
bXk
|
||||
bXk
|
||||
bXk
|
||||
aaa
|
||||
aaa
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -79416,9 +79459,9 @@ chR
|
||||
cgt
|
||||
cjT
|
||||
ckq
|
||||
ckq
|
||||
bXk
|
||||
aaa
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -79673,9 +79716,9 @@ chS
|
||||
cfV
|
||||
cgS
|
||||
cfV
|
||||
cfV
|
||||
bXk
|
||||
aaa
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -79929,10 +79972,10 @@ cfV
|
||||
cfV
|
||||
cfV
|
||||
cgT
|
||||
cfV
|
||||
ckr
|
||||
bXk
|
||||
aaa
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -80179,17 +80222,17 @@ cfU
|
||||
cgu
|
||||
cgU
|
||||
chw
|
||||
cBR
|
||||
chw
|
||||
chw
|
||||
cgU
|
||||
chw
|
||||
cgU
|
||||
chw
|
||||
cgU
|
||||
cjs
|
||||
cfV
|
||||
cfV
|
||||
bTE
|
||||
aaa
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -80436,17 +80479,17 @@ cfV
|
||||
cgv
|
||||
cfV
|
||||
chx
|
||||
chQ
|
||||
cfV
|
||||
chx
|
||||
chQ
|
||||
cfV
|
||||
chx
|
||||
chQ
|
||||
cfV
|
||||
chx
|
||||
cfV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -80694,16 +80737,16 @@ cgv
|
||||
cgV
|
||||
bBW
|
||||
bBW
|
||||
aaa
|
||||
cgV
|
||||
aht
|
||||
aaa
|
||||
bBW
|
||||
bBW
|
||||
cgV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
abI
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -80951,16 +80994,16 @@ cgv
|
||||
bBW
|
||||
bBW
|
||||
bBW
|
||||
aaa
|
||||
yia
|
||||
abI
|
||||
aaa
|
||||
bBW
|
||||
bBW
|
||||
bBW
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -81215,9 +81258,9 @@ aaa
|
||||
bBW
|
||||
bBW
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -81469,12 +81512,12 @@ cii
|
||||
cis
|
||||
ciG
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
yia
|
||||
cgV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -81719,7 +81762,7 @@ cfd
|
||||
cfw
|
||||
cfW
|
||||
cgw
|
||||
cgV
|
||||
aht
|
||||
abI
|
||||
abI
|
||||
cij
|
||||
@@ -81727,11 +81770,11 @@ cit
|
||||
ciH
|
||||
abI
|
||||
abI
|
||||
cgV
|
||||
aht
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -81976,8 +82019,8 @@ cfe
|
||||
cfx
|
||||
cfa
|
||||
cgv
|
||||
aaa
|
||||
aaa
|
||||
cgV
|
||||
yia
|
||||
aaa
|
||||
cik
|
||||
ciu
|
||||
@@ -81986,9 +82029,9 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
cfV
|
||||
bTE
|
||||
aaa
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -82243,9 +82286,9 @@ aaa
|
||||
bBW
|
||||
bBW
|
||||
cfV
|
||||
bTE
|
||||
aaa
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -82495,14 +82538,14 @@ bBW
|
||||
aaa
|
||||
aaa
|
||||
abI
|
||||
aaa
|
||||
yia
|
||||
aaa
|
||||
bBW
|
||||
bBW
|
||||
cfV
|
||||
bTE
|
||||
aaa
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -82751,15 +82794,15 @@ cgV
|
||||
bBW
|
||||
aaa
|
||||
aaa
|
||||
aht
|
||||
cgV
|
||||
aaa
|
||||
bBW
|
||||
bBW
|
||||
cgV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -83006,17 +83049,17 @@ cfV
|
||||
cgv
|
||||
cfV
|
||||
chz
|
||||
cBS
|
||||
cfV
|
||||
chz
|
||||
cBS
|
||||
cfV
|
||||
chz
|
||||
cBS
|
||||
cfV
|
||||
chz
|
||||
cfV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
abI
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
abI
|
||||
abI
|
||||
aaa
|
||||
@@ -83174,7 +83217,7 @@ auU
|
||||
atY
|
||||
vTA
|
||||
ayf
|
||||
axf
|
||||
vTA
|
||||
aAF
|
||||
aBz
|
||||
aCP
|
||||
@@ -83263,17 +83306,17 @@ cfU
|
||||
cgx
|
||||
cgU
|
||||
chA
|
||||
cgU
|
||||
chA
|
||||
cgU
|
||||
chA
|
||||
chA
|
||||
chA
|
||||
chA
|
||||
cgU
|
||||
cjt
|
||||
cfV
|
||||
cfV
|
||||
bTE
|
||||
abI
|
||||
aaa
|
||||
cfV
|
||||
bXk
|
||||
let
|
||||
abI
|
||||
aaa
|
||||
aaa
|
||||
@@ -83527,10 +83570,10 @@ cfV
|
||||
cfV
|
||||
cfV
|
||||
cgY
|
||||
cfV
|
||||
cks
|
||||
bXk
|
||||
abI
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -83785,9 +83828,9 @@ chO
|
||||
cfV
|
||||
cgZ
|
||||
cfV
|
||||
cfV
|
||||
bXk
|
||||
abI
|
||||
abI
|
||||
let
|
||||
abI
|
||||
aaa
|
||||
aaa
|
||||
@@ -84042,9 +84085,9 @@ chP
|
||||
cgt
|
||||
cjU
|
||||
ckq
|
||||
ckq
|
||||
bXk
|
||||
abI
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -84299,9 +84342,9 @@ bXk
|
||||
bXk
|
||||
bXk
|
||||
bXk
|
||||
bXk
|
||||
ckJ
|
||||
abI
|
||||
aaa
|
||||
let
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
@@ -87058,7 +87101,7 @@ aVu
|
||||
bat
|
||||
aLf
|
||||
bcy
|
||||
aKq
|
||||
lvl
|
||||
aEj
|
||||
aEj
|
||||
bgC
|
||||
@@ -87572,7 +87615,7 @@ aPY
|
||||
bav
|
||||
aLf
|
||||
aFi
|
||||
aFi
|
||||
nJY
|
||||
beI
|
||||
bfv
|
||||
bgE
|
||||
@@ -89361,7 +89404,7 @@ aOW
|
||||
xzr
|
||||
xzr
|
||||
xzr
|
||||
aSY
|
||||
frt
|
||||
aUs
|
||||
aLf
|
||||
aLf
|
||||
@@ -89875,7 +89918,7 @@ cDa
|
||||
cDa
|
||||
cDa
|
||||
aLg
|
||||
aTj
|
||||
kqj
|
||||
aUu
|
||||
aVx
|
||||
aVx
|
||||
@@ -93238,7 +93281,7 @@ bkE
|
||||
aht
|
||||
bnd
|
||||
boh
|
||||
bpp
|
||||
bpn
|
||||
bqx
|
||||
brQ
|
||||
btr
|
||||
|
||||
+1595
-2723
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1470
-2172
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1 +1 @@
|
||||
|
||||
poojawa role=admin
|
||||
|
||||
+15
-45
@@ -44,20 +44,6 @@
|
||||
//Mutations that cant be taken from genetics and are not in SE
|
||||
#define NON_SCANNABLE -1
|
||||
|
||||
// Extra powers:
|
||||
#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes
|
||||
#define HEAL 10 // healing people with hands
|
||||
#define SHADOW 11 // shadow teleportation (create in/out portals anywhere) (25%)
|
||||
#define SCREAM 12 // supersonic screaming (25%)
|
||||
#define EXPLOSIVE 13 // exploding on-demand (15%)
|
||||
#define REGENERATION 14 // superhuman regeneration (30%)
|
||||
#define REPROCESSOR 15 // eat anything (50%)
|
||||
#define SHAPESHIFTING 16 // take on the appearance of anything (40%)
|
||||
#define PHASING 17 // ability to phase through walls (40%)
|
||||
#define SHIELD 18 // shielding from all projectile attacks (30%)
|
||||
#define SHOCKWAVE 19 // attack a nearby tile and cause a massive shockwave, knocking most people on their asses (25%)
|
||||
#define ELECTRICITY 20 // ability to shoot electric attacks (15%)
|
||||
|
||||
//DNA - Because fuck you and your magic numbers being all over the codebase.
|
||||
#define DNA_BLOCK_SIZE 3
|
||||
|
||||
@@ -81,7 +67,6 @@
|
||||
#define TR_KEEPIMPLANTS 16
|
||||
#define TR_KEEPSE 32 // changelings shouldn't edit the DNA's SE when turning into a monkey
|
||||
#define TR_DEFAULTMSG 64
|
||||
#define TR_KEEPSRC 128
|
||||
#define TR_KEEPORGANS 256
|
||||
|
||||
|
||||
@@ -94,36 +79,21 @@
|
||||
#define FACEHAIR 3
|
||||
#define EYECOLOR 4
|
||||
#define LIPS 5
|
||||
#define RESISTHOT 6
|
||||
#define RESISTCOLD 7
|
||||
#define RESISTPRESSURE 8
|
||||
#define RADIMMUNE 9
|
||||
#define NOBREATH 10
|
||||
#define NOGUNS 11
|
||||
#define NOBLOOD 12
|
||||
#define NOFIRE 13
|
||||
#define VIRUSIMMUNE 14
|
||||
#define PIERCEIMMUNE 15
|
||||
#define NOTRANSSTING 16
|
||||
#define MUTCOLORS_PARTSONLY 17 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
|
||||
#define NODISMEMBER 18
|
||||
#define NOHUNGER 19
|
||||
#define NOCRITDAMAGE 20
|
||||
#define NOZOMBIE 21
|
||||
#define EASYDISMEMBER 22
|
||||
#define EASYLIMBATTACHMENT 23
|
||||
#define TOXINLOVER 24
|
||||
#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
#define NO_UNDERWEAR 26
|
||||
#define NOLIVER 27
|
||||
#define NOSTOMACH 28
|
||||
#define NO_DNA_COPY 29
|
||||
#define DRINKSBLOOD 30
|
||||
#define SPECIES_ORGANIC 31
|
||||
#define SPECIES_INORGANIC 32
|
||||
#define SPECIES_UNDEAD 33
|
||||
#define SPECIES_ROBOTIC 34
|
||||
#define NOEYES 35
|
||||
#define NOBLOOD 6
|
||||
#define NOTRANSSTING 7
|
||||
#define MUTCOLORS_PARTSONLY 8 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless.
|
||||
#define NOZOMBIE 9
|
||||
#define DIGITIGRADE 10 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
#define NO_UNDERWEAR 11
|
||||
#define NOLIVER 12
|
||||
#define NOSTOMACH 13
|
||||
#define NO_DNA_COPY 14
|
||||
#define DRINKSBLOOD 15
|
||||
#define SPECIES_ORGANIC 16
|
||||
#define SPECIES_INORGANIC 17
|
||||
#define SPECIES_UNDEAD 18
|
||||
#define SPECIES_ROBOTIC 19
|
||||
#define NOEYES 20
|
||||
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
#define ORGAN_SLOT_APPENDIX "appendix"
|
||||
|
||||
@@ -37,12 +37,6 @@
|
||||
|
||||
#define R_DEFAULT R_AUTOLOGIN
|
||||
|
||||
#if DM_VERSION > 512
|
||||
#error Remove the flag below , its been long enough
|
||||
#endif
|
||||
//legacy , remove post 512, it was replaced by R_POLL
|
||||
#define R_REJUVINATE 2
|
||||
|
||||
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
|
||||
|
||||
#define ADMIN_QUE(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminmoreinfo=[REF(user)]'>?</a>)"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#define CELL_VOLUME 2500 //liters in a cell
|
||||
#define BREATH_VOLUME 0.5 //liters in a normal breath
|
||||
#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile
|
||||
#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD*BREATH_PERCENTAGE*0.16) //Amount of air needed before pass out/suffocation commences
|
||||
|
||||
//EXCITED GROUPS
|
||||
#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 //number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs)
|
||||
@@ -46,10 +45,7 @@
|
||||
//HEAT TRANSFER COEFFICIENTS
|
||||
//Must be between 0 and 1. Values closer to 1 equalize temperature faster
|
||||
//Should not exceed 0.4 else strange heat flow occur
|
||||
#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4
|
||||
#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0
|
||||
#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0
|
||||
#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.2 //a hack to partly simulate radiative heat
|
||||
#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4
|
||||
#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now
|
||||
#define HEAT_CAPACITY_VACUUM 7000 //a hack to help make vacuums "cold", sacrificing realism for gameplay
|
||||
@@ -59,8 +55,6 @@
|
||||
#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST 100+T0C
|
||||
#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
|
||||
#define FIRE_GROWTH_RATE 40000 //For small fires
|
||||
#define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C //Resistance to fire damage
|
||||
#define CARBON_LIFEFORM_FIRE_DAMAGE 4 //Fire damage
|
||||
#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
|
||||
|
||||
//GASES
|
||||
@@ -74,11 +68,6 @@
|
||||
#define REACTING 1
|
||||
#define STOP_REACTIONS 2
|
||||
|
||||
//HUMANS
|
||||
//Hurty numbers
|
||||
#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin
|
||||
#define AIR_DAMAGE_MODIFIER 1.025 //More means less damage from hot air scalding lungs, less = more damage //CITADEL EDIT 1.025
|
||||
|
||||
// Pressure limits.
|
||||
#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
|
||||
#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
|
||||
@@ -123,7 +112,7 @@
|
||||
#define SHOES_MAX_TEMP_PROTECT 1500 //For gloves
|
||||
|
||||
#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE
|
||||
#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8.
|
||||
#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8.
|
||||
#define LOW_PRESSURE_DAMAGE 8 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).
|
||||
|
||||
#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this
|
||||
@@ -196,4 +185,3 @@ GLOBAL_LIST_INIT(pipe_paint_colors, list(
|
||||
"Violet" = rgb(64,0,128),
|
||||
"Yellow" = rgb(255,198,0)
|
||||
))
|
||||
|
||||
|
||||
+20
-15
@@ -19,8 +19,9 @@
|
||||
#define DIAG_AIRLOCK_HUD "15"//Airlock shock overlay
|
||||
#define DIAG_PATH_HUD "16"//Bot path indicators
|
||||
#define GLAND_HUD "17"//Gland indicators for abductors
|
||||
#define SENTIENT_DISEASE_HUD "18"
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "18"
|
||||
#define ANTAG_HUD "19"
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
@@ -35,23 +36,27 @@
|
||||
#define DATA_HUD_DIAGNOSTIC_BASIC 5
|
||||
#define DATA_HUD_DIAGNOSTIC_ADVANCED 6
|
||||
#define DATA_HUD_ABDUCTOR 7
|
||||
#define DATA_HUD_SENTIENT_DISEASE 8
|
||||
|
||||
//antag HUD defines
|
||||
#define ANTAG_HUD_CULT 8
|
||||
#define ANTAG_HUD_REV 9
|
||||
#define ANTAG_HUD_OPS 10
|
||||
#define ANTAG_HUD_WIZ 11
|
||||
#define ANTAG_HUD_SHADOW 12
|
||||
#define ANTAG_HUD_TRAITOR 13
|
||||
#define ANTAG_HUD_NINJA 14
|
||||
#define ANTAG_HUD_CHANGELING 15
|
||||
#define ANTAG_HUD_ABDUCTOR 16
|
||||
#define ANTAG_HUD_DEVIL 17
|
||||
#define ANTAG_HUD_SINTOUCHED 18
|
||||
#define ANTAG_HUD_SOULLESS 19
|
||||
#define ANTAG_HUD_CLOCKWORK 20
|
||||
#define ANTAG_HUD_BROTHER 21
|
||||
#define ANTAG_HUD_CULT 9
|
||||
#define ANTAG_HUD_REV 10
|
||||
#define ANTAG_HUD_OPS 11
|
||||
#define ANTAG_HUD_WIZ 12
|
||||
#define ANTAG_HUD_SHADOW 13
|
||||
#define ANTAG_HUD_TRAITOR 14
|
||||
#define ANTAG_HUD_NINJA 15
|
||||
#define ANTAG_HUD_CHANGELING 16
|
||||
#define ANTAG_HUD_ABDUCTOR 17
|
||||
#define ANTAG_HUD_DEVIL 18
|
||||
#define ANTAG_HUD_SINTOUCHED 19
|
||||
#define ANTAG_HUD_SOULLESS 20
|
||||
#define ANTAG_HUD_CLOCKWORK 21
|
||||
#define ANTAG_HUD_BROTHER 22
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
#define NOTIFY_ATTACK "attack"
|
||||
#define NOTIFY_ORBIT "orbit"
|
||||
|
||||
#define ADD_HUD_TO_COOLDOWN 20 //cooldown for being shown the images for any particular data hud
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//Cleaning tool strength
|
||||
#define CLEAN_VERY_WEAK 1 // What are you scrubbing the ground with a toothpick?
|
||||
// 1 is also a valid cleaning strength but completely unused so left undefined
|
||||
#define CLEAN_WEAK 2
|
||||
#define CLEAN_MEDIUM 3 // Acceptable tools
|
||||
#define CLEAN_STRONG 4 // Industrial strength
|
||||
|
||||
@@ -64,8 +64,6 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
|
||||
|
||||
#define GATEWAY_RATVAR_ARRIVAL 600 //when progress is at or above this, game over ratvar's here everybody go home
|
||||
|
||||
#define ARK_SUMMON_COST 5 //how many of each component an Ark costs to summon
|
||||
|
||||
//Objective text define
|
||||
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
|
||||
|
||||
|
||||
+12
-12
@@ -3,26 +3,26 @@
|
||||
#define COLOR_INPUT_DISABLED "#F0F0F0"
|
||||
#define COLOR_INPUT_ENABLED "#D3B5B5"
|
||||
|
||||
#define COLOR_WHITE "#EEEEEE"
|
||||
#define COLOR_SILVER "#C0C0C0"
|
||||
#define COLOR_GRAY "#808080"
|
||||
//#define COLOR_WHITE "#EEEEEE"
|
||||
//#define COLOR_SILVER "#C0C0C0"
|
||||
//#define COLOR_GRAY "#808080"
|
||||
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
|
||||
#define COLOR_ALMOST_BLACK "#333333"
|
||||
#define COLOR_BLACK "#000000"
|
||||
//#define COLOR_BLACK "#000000"
|
||||
#define COLOR_RED "#FF0000"
|
||||
#define COLOR_RED_LIGHT "#FF3333"
|
||||
#define COLOR_MAROON "#800000"
|
||||
//#define COLOR_RED_LIGHT "#FF3333"
|
||||
//#define COLOR_MAROON "#800000"
|
||||
#define COLOR_YELLOW "#FFFF00"
|
||||
#define COLOR_OLIVE "#808000"
|
||||
#define COLOR_LIME "#32CD32"
|
||||
//#define COLOR_OLIVE "#808000"
|
||||
//#define COLOR_LIME "#32CD32"
|
||||
#define COLOR_GREEN "#008000"
|
||||
#define COLOR_CYAN "#00FFFF"
|
||||
#define COLOR_TEAL "#008080"
|
||||
//#define COLOR_TEAL "#008080"
|
||||
#define COLOR_BLUE "#0000FF"
|
||||
#define COLOR_BLUE_LIGHT "#33CCFF"
|
||||
#define COLOR_NAVY "#000080"
|
||||
//#define COLOR_BLUE_LIGHT "#33CCFF"
|
||||
//#define COLOR_NAVY "#000080"
|
||||
#define COLOR_PINK "#FFC0CB"
|
||||
#define COLOR_MAGENTA "#FF00FF"
|
||||
//#define COLOR_MAGENTA "#FF00FF"
|
||||
#define COLOR_PURPLE "#800080"
|
||||
#define COLOR_ORANGE "#FF9900"
|
||||
#define COLOR_BEIGE "#CEB689"
|
||||
|
||||
@@ -110,11 +110,7 @@
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
|
||||
//Gun Stuff
|
||||
#define SAWN_INTACT 0
|
||||
#define SAWN_OFF 1
|
||||
//Gun weapon weight
|
||||
#define WEAPON_DUAL_WIELD 0
|
||||
#define WEAPON_LIGHT 1
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
//Positions for overrides list
|
||||
#define EXAMINE_POSITION_ARTICLE 1
|
||||
#define EXAMINE_POSITION_BEFORE 2
|
||||
#define EXAMINE_POSITION_NAME 3
|
||||
//End positions
|
||||
#define COMPONENT_EXNAME_CHANGED 1
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (/atom/movable, /atom)
|
||||
|
||||
@@ -37,12 +37,6 @@
|
||||
#define FAILED_UNFASTEN 1
|
||||
#define SUCCESSFUL_UNFASTEN 2
|
||||
|
||||
//disposal unit mode defines, which do double time as the construction defines
|
||||
#define PRESSURE_OFF 0
|
||||
#define PRESSURE_ON 1
|
||||
#define PRESSURE_MAXED 2
|
||||
#define SCREWS_OUT -1
|
||||
|
||||
//ai core defines
|
||||
#define EMPTY_CORE 0
|
||||
#define CIRCUIT_CORE 1
|
||||
@@ -51,11 +45,6 @@
|
||||
#define GLASS_CORE 4
|
||||
#define AI_READY_CORE 5
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
//emitter construction defines
|
||||
#define EM_UNSECURED 0
|
||||
#define EM_SECURED 1
|
||||
|
||||
+17
-14
@@ -1,3 +1,7 @@
|
||||
|
||||
#define DISEASE_LIMIT 1
|
||||
#define VIRUS_SYMPTOM_LIMIT 6
|
||||
|
||||
//Visibility Flags
|
||||
#define HIDDEN_SCANNER 1
|
||||
#define HIDDEN_PANDEMIC 2
|
||||
@@ -8,19 +12,18 @@
|
||||
#define CAN_RESIST 4
|
||||
|
||||
//Spread Flags
|
||||
#define VIRUS_SPREAD_SPECIAL 1
|
||||
#define VIRUS_SPREAD_NON_CONTAGIOUS 2
|
||||
#define VIRUS_SPREAD_BLOOD 4
|
||||
#define VIRUS_SPREAD_CONTACT_FLUIDS 8
|
||||
#define VIRUS_SPREAD_CONTACT_SKIN 16
|
||||
#define VIRUS_SPREAD_AIRBORNE 32
|
||||
|
||||
#define DISEASE_SPREAD_SPECIAL 1
|
||||
#define DISEASE_SPREAD_NON_CONTAGIOUS 2
|
||||
#define DISEASE_SPREAD_BLOOD 4
|
||||
#define DISEASE_SPREAD_CONTACT_FLUIDS 8
|
||||
#define DISEASE_SPREAD_CONTACT_SKIN 16
|
||||
#define DISEASE_SPREAD_AIRBORNE 32
|
||||
|
||||
//Severity Defines
|
||||
#define VIRUS_SEVERITY_POSITIVE "Positive" //Diseases that buff, heal, or at least do nothing at all
|
||||
#define VIRUS_SEVERITY_NONTHREAT "Harmless" //Diseases that may have annoying effects, but nothing disruptive (sneezing)
|
||||
#define VIRUS_SEVERITY_MINOR "Minor" //Diseases that can annoy in concrete ways (dizziness)
|
||||
#define VIRUS_SEVERITY_MEDIUM "Medium" //Diseases that can do minor harm, or severe annoyance (vomit)
|
||||
#define VIRUS_SEVERITY_HARMFUL "Harmful" //Diseases that can do significant harm, or severe disruption (brainrot)
|
||||
#define VIRUS_SEVERITY_DANGEROUS "Dangerous" //Diseases that can kill or maim if left untreated (flesh eating, blindness)
|
||||
#define VIRUS_SEVERITY_BIOHAZARD "BIOHAZARD" //Diseases that can quickly kill an unprepared victim (fungal tb, gbs)
|
||||
#define DISEASE_SEVERITY_POSITIVE "Positive" //Diseases that buff, heal, or at least do nothing at all
|
||||
#define DISEASE_SEVERITY_NONTHREAT "Harmless" //Diseases that may have annoying effects, but nothing disruptive (sneezing)
|
||||
#define DISEASE_SEVERITY_MINOR "Minor" //Diseases that can annoy in concrete ways (dizziness)
|
||||
#define DISEASE_SEVERITY_MEDIUM "Medium" //Diseases that can do minor harm, or severe annoyance (vomit)
|
||||
#define DISEASE_SEVERITY_HARMFUL "Harmful" //Diseases that can do significant harm, or severe disruption (brainrot)
|
||||
#define DISEASE_SEVERITY_DANGEROUS "Dangerous" //Diseases that can kill or maim if left untreated (flesh eating, blindness)
|
||||
#define DISEASE_SEVERITY_BIOHAZARD "BIOHAZARD" //Diseases that can quickly kill an unprepared victim (fungal tb, gbs)
|
||||
|
||||
@@ -26,7 +26,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define ON_BORDER_1 512 // item has priority to check when entering or leaving
|
||||
|
||||
#define NOSLIP_1 1024 //prevents from slipping on wet floors, in space etc
|
||||
#define _UNUSED_1 2048
|
||||
|
||||
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
|
||||
#define BLOCK_GAS_SMOKE_EFFECT_1 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
|
||||
@@ -84,7 +83,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
|
||||
|
||||
//Movement Types
|
||||
#define IMMOBILE 0
|
||||
#define GROUND 1
|
||||
#define FLYING 2
|
||||
|
||||
|
||||
@@ -118,22 +118,6 @@
|
||||
#define NECK 2048
|
||||
#define FULL_BODY 4095
|
||||
|
||||
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
|
||||
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
|
||||
// The values here should add up to 1.
|
||||
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
|
||||
#define THERMAL_PROTECTION_HEAD 0.3
|
||||
#define THERMAL_PROTECTION_CHEST 0.15
|
||||
#define THERMAL_PROTECTION_GROIN 0.15
|
||||
#define THERMAL_PROTECTION_LEG_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_LEG_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_FOOT_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_FOOT_RIGHT 0.025
|
||||
#define THERMAL_PROTECTION_ARM_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_ARM_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird
|
||||
#define NO_FEMALE_UNIFORM 0
|
||||
#define FEMALE_UNIFORM_FULL 1
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// simple is_type and similar inline helpers
|
||||
|
||||
#define isdatum(D) (istype(D, /datum))
|
||||
|
||||
#define islist(L) (istype(L, /list))
|
||||
|
||||
#if DM_VERSION >= 512
|
||||
@@ -64,7 +62,6 @@
|
||||
#define isjellyperson(A) (is_species(A, /datum/species/jelly))
|
||||
#define isslimeperson(A) (is_species(A, /datum/species/jelly/slime))
|
||||
#define isluminescent(A) (is_species(A, /datum/species/jelly/luminescent))
|
||||
#define isshadowperson(A) (is_species(A, /datum/species/shadow))
|
||||
#define iszombie(A) (is_species(A, /datum/species/zombie))
|
||||
#define ishumanbasic(A) (is_species(A, /datum/species/human))
|
||||
|
||||
@@ -106,8 +103,6 @@
|
||||
|
||||
#define isbot(A) (istype(A, /mob/living/simple_animal/bot))
|
||||
|
||||
#define iscrab(A) (istype(A, /mob/living/simple_animal/crab))
|
||||
|
||||
#define isshade(A) (istype(A, /mob/living/simple_animal/shade))
|
||||
|
||||
#define ismouse(A) (istype(A, /mob/living/simple_animal/mouse))
|
||||
@@ -118,16 +113,10 @@
|
||||
|
||||
#define iscat(A) (istype(A, /mob/living/simple_animal/pet/cat))
|
||||
|
||||
#define isdog(A) (istype(A, /mob/living/simple_animal/pet/dog))
|
||||
|
||||
#define iscorgi(A) (istype(A, /mob/living/simple_animal/pet/dog/corgi))
|
||||
|
||||
#define ishostile(A) (istype(A, /mob/living/simple_animal/hostile))
|
||||
|
||||
#define isbear(A) (istype(A, /mob/living/simple_animal/hostile/bear))
|
||||
|
||||
#define iscarp(A) (istype(A, /mob/living/simple_animal/hostile/carp))
|
||||
|
||||
#define isswarmer(A) (istype(A, /mob/living/simple_animal/hostile/swarmer))
|
||||
|
||||
#define isguardian(A) (istype(A, /mob/living/simple_animal/hostile/guardian))
|
||||
@@ -183,14 +172,10 @@ GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
|
||||
|
||||
#define isigniter(O) (istype(O, /obj/item/device/assembly/igniter))
|
||||
|
||||
#define isinfared(O) (istype(O, /obj/item/device/assembly/infra))
|
||||
|
||||
#define isprox(O) (istype(O, /obj/item/device/assembly/prox_sensor))
|
||||
|
||||
#define issignaler(O) (istype(O, /obj/item/device/assembly/signaler))
|
||||
|
||||
#define istimer(O) (istype(O, /obj/item/device/assembly/timer))
|
||||
|
||||
GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
/obj/item/stack/sheet/glass,
|
||||
/obj/item/stack/sheet/rglass,
|
||||
@@ -201,4 +186,4 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
|
||||
#define is_glass_sheet(O) (is_type_in_typecache(O, GLOB.glass_sheet_types))
|
||||
|
||||
#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob))
|
||||
#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob))
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#define GAME_PLANE -1
|
||||
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
|
||||
#define SPACE_LAYER 1.8
|
||||
#define ABOVE_SPACE_LAYER 1.9
|
||||
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
|
||||
#define MID_TURF_LAYER 2.02
|
||||
#define HIGH_TURF_LAYER 2.03
|
||||
|
||||
@@ -23,27 +23,6 @@
|
||||
0, 0, 0, 1 \
|
||||
) \
|
||||
|
||||
// Helpers so we can (more easily) control the colour matrices.
|
||||
#define CL_MATRIX_RR 1
|
||||
#define CL_MATRIX_RG 2
|
||||
#define CL_MATRIX_RB 3
|
||||
#define CL_MATRIX_RA 4
|
||||
#define CL_MATRIX_GR 5
|
||||
#define CL_MATRIX_GG 6
|
||||
#define CL_MATRIX_GB 7
|
||||
#define CL_MATRIX_GA 8
|
||||
#define CL_MATRIX_BR 9
|
||||
#define CL_MATRIX_BG 10
|
||||
#define CL_MATRIX_BB 11
|
||||
#define CL_MATRIX_BA 12
|
||||
#define CL_MATRIX_AR 13
|
||||
#define CL_MATRIX_AG 14
|
||||
#define CL_MATRIX_AB 15
|
||||
#define CL_MATRIX_AA 16
|
||||
#define CL_MATRIX_CR 17
|
||||
#define CL_MATRIX_CG 18
|
||||
#define CL_MATRIX_CB 19
|
||||
#define CL_MATRIX_CA 20
|
||||
|
||||
//Some defines to generalise colours used in lighting.
|
||||
//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated
|
||||
@@ -90,4 +69,4 @@
|
||||
#define LIGHTING_NO_UPDATE 0
|
||||
#define LIGHTING_VIS_UPDATE 1
|
||||
#define LIGHTING_CHECK_UPDATE 2
|
||||
#define LIGHTING_FORCE_UPDATE 3
|
||||
#define LIGHTING_FORCE_UPDATE 3
|
||||
|
||||
@@ -85,6 +85,3 @@
|
||||
#define SUPERMATTER_DANGER 4 // Integrity < 50%
|
||||
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
|
||||
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
|
||||
|
||||
//R&D Snowflakes
|
||||
#define RD_CONSOLE_LOCKED_SCREEN 0.2
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#define BOSS_MEDAL_DRAKE "Drake"
|
||||
#define BOSS_MEDAL_HIEROPHANT "Hierophant"
|
||||
#define BOSS_MEDAL_LEGION "Legion"
|
||||
#define BOSS_MEDAL_SWARMER "Swarmer Beacon"
|
||||
#define BOSS_MEDAL_TENDRIL "Tendril"
|
||||
|
||||
// Score names
|
||||
|
||||
+5
-71
@@ -20,8 +20,8 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define THIS_PROC_TYPE_STR "[THIS_PROC_TYPE]" //Because you can only obtain a string of THIS_PROC_TYPE using "[]", and it's nice to just +/+= strings
|
||||
#define THIS_PROC_TYPE_STR_WITH_ARGS "[THIS_PROC_TYPE]([args.Join(",")])"
|
||||
#define THIS_PROC_TYPE_WEIRD ...... //This one is WEIRD, in some cases (When used in certain defines? (eg: ASSERT)) THIS_PROC_TYPE will fail to work, but THIS_PROC_TYPE_WEIRD will work instead
|
||||
#define THIS_PROC_TYPE_WEIRD_STR "[THIS_PROC_TYPE_WEIRD]" //Included for completeness
|
||||
#define THIS_PROC_TYPE_WEIRD_STR_WITH_ARGS "[THIS_PROC_TYPE_WEIRD]([args.Join(",")])" //Ditto
|
||||
//define THIS_PROC_TYPE_WEIRD_STR "[THIS_PROC_TYPE_WEIRD]" //Included for completeness
|
||||
//define THIS_PROC_TYPE_WEIRD_STR_WITH_ARGS "[THIS_PROC_TYPE_WEIRD]([args.Join(",")])" //Ditto
|
||||
|
||||
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
|
||||
|
||||
@@ -46,7 +46,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define HALLOWEEN "Halloween"
|
||||
#define CHRISTMAS "Christmas"
|
||||
#define FESTIVE_SEASON "Festive Season"
|
||||
#define FRIDAY_13TH "Friday the 13th"
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
|
||||
@@ -86,58 +85,11 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
|
||||
//Because I *KNOW* somebody will think layer+1 means "above"
|
||||
//IT DOESN'T OK, IT MEANS "UNDER"
|
||||
#define UNDER_BODY_BEHIND_LAYER BODY_BEHIND_LAYER+1
|
||||
#define UNDER_BODY_LAYER BODY_LAYER+1
|
||||
#define UNDER_BODY_ADJ_LAYER BODY_ADJ_LAYER+1
|
||||
#define UNDER_MUTATIONS_LAYER MUTATIONS_LAYER+1
|
||||
#define UNDER_BODYPARTS_LAYER BODYPARTS_LAYER+1
|
||||
#define UNDER_DAMAGE_LAYER DAMAGE_LAYER+1
|
||||
#define UNDER_UNIFORM_LAYER UNIFORM_LAYER+1
|
||||
#define UNDER_ID_LAYER ID_LAYER+1
|
||||
#define UNDER_HANDS_PART_LAYER HANDS_PART_LAYER+1
|
||||
#define UNDER_GLOVES_LAYER GLOVES_LAYER+1
|
||||
#define UNDER_SHOES_LAYER SHOES_LAYER+1
|
||||
#define UNDER_EARS_LAYER EARS_LAYER+1
|
||||
#define UNDER_SUIT_LAYER SUIT_LAYER+1
|
||||
#define UNDER_GLASSES_LAYER GLASSES_LAYER+1
|
||||
#define UNDER_BELT_LAYER BELT_LAYER+1
|
||||
#define UNDER_SUIT_STORE_LAYER SUIT_STORE_LAYER+1
|
||||
#define UNDER_BACK_LAYER BACK_LAYER+1
|
||||
#define UNDER_HAIR_LAYER HAIR_LAYER+1
|
||||
#define UNDER_FACEMASK_LAYER FACEMASK_LAYER+1
|
||||
#define UNDER_HEAD_LAYER HEAD_LAYER+1
|
||||
#define UNDER_HANDCUFF_LAYER HANDCUFF_LAYER+1
|
||||
#define UNDER_LEGCUFF_LAYER LEGCUFF_LAYER+1
|
||||
#define UNDER_HANDS_LAYER HANDS_LAYER+1
|
||||
#define UNDER_BODY_FRONT_LAYER BODY_FRONT_LAYER+1
|
||||
#define UNDER_FIRE_LAYER FIRE_LAYER+1
|
||||
|
||||
//AND -1 MEANS "ABOVE", OK?, OK!?!
|
||||
#define ABOVE_BODY_BEHIND_LAYER BODY_BEHIND_LAYER-1
|
||||
#define ABOVE_BODY_LAYER BODY_LAYER-1
|
||||
#define ABOVE_BODY_ADJ_LAYER BODY_ADJ_LAYER-1
|
||||
#define ABOVE_MUTATIONS_LAYER MUTATIONS_LAYER-1
|
||||
#define ABOVE_BODYPARTS_LAYER BODYPARTS_LAYER-1
|
||||
#define ABOVE_DAMAGE_LAYER DAMAGE_LAYER-1
|
||||
#define ABOVE_UNIFORM_LAYER UNIFORM_LAYER-1
|
||||
#define ABOVE_ID_LAYER ID_LAYER-1
|
||||
#define ABOVE_HANDS_PART_LAYER HANDS_PART_LAYER-1
|
||||
#define ABOVE_GLOVES_LAYER GLOVES_LAYER-1
|
||||
#define ABOVE_SHOES_LAYER SHOES_LAYER-1
|
||||
#define ABOVE_EARS_LAYER EARS_LAYER-1
|
||||
#define ABOVE_SUIT_LAYER SUIT_LAYER-1
|
||||
#define ABOVE_GLASSES_LAYER GLASSES_LAYER-1
|
||||
#define ABOVE_BELT_LAYER BELT_LAYER-1
|
||||
#define ABOVE_SUIT_STORE_LAYER SUIT_STORE_LAYER-1
|
||||
#define ABOVE_BACK_LAYER BACK_LAYER-1
|
||||
#define ABOVE_HAIR_LAYER HAIR_LAYER-1
|
||||
#define ABOVE_FACEMASK_LAYER FACEMASK_LAYER-1
|
||||
#define ABOVE_HEAD_LAYER HEAD_LAYER-1
|
||||
#define ABOVE_HANDCUFF_LAYER HANDCUFF_LAYER-1
|
||||
#define ABOVE_LEGCUFF_LAYER LEGCUFF_LAYER-1
|
||||
#define ABOVE_HANDS_LAYER HANDS_LAYER-1
|
||||
#define ABOVE_BODY_FRONT_LAYER BODY_FRONT_LAYER-1
|
||||
#define ABOVE_FIRE_LAYER FIRE_LAYER-1
|
||||
|
||||
|
||||
//Security levels
|
||||
@@ -195,7 +147,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define AI_MECH_HACK 3 //Malfunctioning AI hijacking mecha
|
||||
|
||||
//check_target_facings() return defines
|
||||
#define FACING_FAILED 0
|
||||
#define FACING_SAME_DIR 1
|
||||
#define FACING_EACHOTHER 2
|
||||
#define FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR 3 //Do I win the most informative but also most stupid define award?
|
||||
@@ -213,7 +164,6 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
|
||||
#define BLOOD_GAIN_PER_STEP 100
|
||||
#define BLOOD_LOSS_PER_STEP 5
|
||||
#define BLOOD_LOSS_IN_SPREAD 20
|
||||
#define BLOOD_FADEOUT_TIME 2
|
||||
|
||||
//Bloody shoe blood states
|
||||
#define BLOOD_STATE_HUMAN "blood"
|
||||
@@ -241,7 +191,6 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
|
||||
#define TURF_WET_LUBE 2
|
||||
#define TURF_WET_ICE 3
|
||||
#define TURF_WET_PERMAFROST 4
|
||||
#define TURF_WET_SLIDE 5
|
||||
|
||||
//Maximum amount of time, (in approx. seconds.) a tile can be wet for.
|
||||
#define MAXIMUM_WET_TIME 300
|
||||
@@ -309,10 +258,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
/////////////////////////////////////
|
||||
// atom.appearence_flags shortcuts //
|
||||
/////////////////////////////////////
|
||||
//this was added midway thru 510, so it might not exist in some versions, but we can't check by minor verison
|
||||
#ifndef TILE_BOUND
|
||||
#error this version of 510 is too old, You must use byond 510.1332 or later. (TILE_BOUND is not defined)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
// Disabling certain features
|
||||
#define APPEARANCE_IGNORE_TRANSFORM RESET_TRANSFORM
|
||||
@@ -330,12 +277,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define APPEARANCE_CONSIDER_ALPHA ~RESET_ALPHA
|
||||
#define APPEARANCE_LONG_GLIDE LONG_GLIDE
|
||||
|
||||
#ifndef PIXEL_SCALE
|
||||
#define PIXEL_SCALE 0
|
||||
#if DM_VERSION >= 512
|
||||
#error HEY, PIXEL_SCALE probably exists now, remove this gross ass shim.
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
// Consider these images/atoms as part of the UI/HUD
|
||||
#define APPEARANCE_UI_IGNORE_ALPHA RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR|RESET_ALPHA|PIXEL_SCALE
|
||||
@@ -417,14 +359,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define CLOCK_PROSELYTIZATION 23
|
||||
#define SHUTTLE_HIJACK 24
|
||||
|
||||
#define TURF_DECAL_PAINT "paint"
|
||||
#define TURF_DECAL_DAMAGE "damage"
|
||||
#define TURF_DECAL_DIRT "dirt"
|
||||
|
||||
//Error handler defines
|
||||
#define ERROR_USEFUL_LEN 2
|
||||
|
||||
#define NO_FIELD 0
|
||||
#define FIELD_TURF 1
|
||||
#define FIELD_EDGE 2
|
||||
|
||||
|
||||
+1
-24
@@ -118,7 +118,7 @@
|
||||
//Sentience types, to prevent things like sentience potions from giving bosses sentience
|
||||
#define SENTIENCE_ORGANIC 1
|
||||
#define SENTIENCE_ARTIFICIAL 2
|
||||
#define SENTIENCE_OTHER 3
|
||||
// #define SENTIENCE_OTHER 3 unused
|
||||
#define SENTIENCE_MINEBOT 4
|
||||
#define SENTIENCE_BOSS 5
|
||||
|
||||
@@ -137,29 +137,6 @@
|
||||
#define ENVIRONMENT_SMASH_WALLS 2 //walls
|
||||
#define ENVIRONMENT_SMASH_RWALLS 4 //rwalls
|
||||
|
||||
|
||||
//SNPCs
|
||||
//AI defines
|
||||
#define INTERACTING 2
|
||||
#define TRAVEL 4
|
||||
#define FIGHTING 8
|
||||
//Trait defines
|
||||
#define TRAIT_ROBUST 2
|
||||
#define TRAIT_UNROBUST 4
|
||||
#define TRAIT_SMART 8
|
||||
#define TRAIT_DUMB 16
|
||||
#define TRAIT_MEAN 32
|
||||
#define TRAIT_FRIENDLY 64
|
||||
#define TRAIT_THIEVING 128
|
||||
//Range/chance defines
|
||||
#define MAX_RANGE_FIND 32
|
||||
#define MIN_RANGE_FIND 16
|
||||
#define FUZZY_CHANCE_HIGH 85
|
||||
#define FUZZY_CHANCE_LOW 50
|
||||
#define CHANCE_TALK 1
|
||||
|
||||
#define TK_MAXRANGE 15
|
||||
|
||||
#define NO_SLIP_WHEN_WALKING 1
|
||||
#define SLIDE 2
|
||||
#define GALOSHES_DONT_HELP 4
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
#define SOUND_ANNOUNCEMENTS 2048
|
||||
#define DISABLE_DEATHRATTLE 4096
|
||||
#define DISABLE_ARRIVALRATTLE 8192
|
||||
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
|
||||
#define MEDIHOUND_SLEEPER 16384 //CITADEL EDITS, vore prefs.
|
||||
#define EATING_NOISES 32768
|
||||
#define DIGESTION_NOISES 65536
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|MEDIHOUND_SLEEPER|EATING_NOISES|DIGESTION_NOISES)
|
||||
|
||||
//Chat toggles
|
||||
#define CHAT_OOC 1
|
||||
@@ -65,4 +67,4 @@
|
||||
#define EXP_TYPE_GHOST "Ghost"
|
||||
|
||||
//Flags in the players table in the db
|
||||
#define DB_FLAG_EXEMPT 1
|
||||
#define DB_FLAG_EXEMPT 1
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#define RADIO_FROM_AIRALARM "from_airalarm"
|
||||
#define RADIO_SIGNALER "signaler"
|
||||
#define RADIO_ATMOSIA "atmosia"
|
||||
#define RADIO_NAVBEACONS "navbeacons"
|
||||
#define RADIO_AIRLOCK "airlock"
|
||||
#define RADIO_MAGNETS "magnets"
|
||||
|
||||
|
||||
@@ -31,11 +31,9 @@
|
||||
|
||||
// Ripples, effects that signal a shuttle's arrival
|
||||
#define SHUTTLE_RIPPLE_TIME 100
|
||||
#define SHUTTLE_RIPPLE_FADEIN 50
|
||||
|
||||
#define TRANSIT_REQUEST 1
|
||||
#define TRANSIT_READY 2
|
||||
#define TRANSIT_FULL 3
|
||||
|
||||
#define SHUTTLE_TRANSIT_BORDER 8
|
||||
|
||||
@@ -79,4 +77,4 @@
|
||||
#define SHUTTLE_DEFAULT_TURF_TYPE /turf/open/space
|
||||
#define SHUTTLE_DEFAULT_BASETURF_TYPE /turf/open/space
|
||||
#define SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE /area/shuttle
|
||||
#define SHUTTLE_DEFAULT_UNDERLYING_AREA /area/space
|
||||
#define SHUTTLE_DEFAULT_UNDERLYING_AREA /area/space
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#define SEE_INVISIBLE_LIVING 25
|
||||
|
||||
#define SEE_INVISIBLE_LEVEL_ONE 35 //currently unused
|
||||
#define INVISIBILITY_LEVEL_ONE 35 //currently unused
|
||||
//#define SEE_INVISIBLE_LEVEL_ONE 35 //currently unused
|
||||
//#define INVISIBILITY_LEVEL_ONE 35 //currently unused
|
||||
|
||||
#define SEE_INVISIBLE_LEVEL_TWO 45 //currently unused
|
||||
#define INVISIBILITY_LEVEL_TWO 45 //currently unused
|
||||
//#define SEE_INVISIBLE_LEVEL_TWO 45 //currently unused
|
||||
//#define INVISIBILITY_LEVEL_TWO 45 //currently unused
|
||||
|
||||
#define INVISIBILITY_OBSERVER 60
|
||||
#define SEE_INVISIBLE_OBSERVER 60
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
|
||||
//CIT CHANNELS - TRY NOT TO REGRESS
|
||||
#define CHANNEL_PRED 1015
|
||||
#define CHANNEL_PREYLOOP 1014
|
||||
#define CHANNEL_DIGEST 1014
|
||||
#define CHANNEL_PREYLOOP 1013
|
||||
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1013 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1012 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS
|
||||
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
|
||||
@@ -15,6 +15,5 @@
|
||||
#define EMPED 8 // temporary broken by EMP pulse
|
||||
|
||||
//ai power requirement defines
|
||||
#define POWER_REQ_NONE 0
|
||||
#define POWER_REQ_ALL 1
|
||||
#define POWER_REQ_CLOCKCULT 2
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#define STATUS_EFFECT_REPLACE 2 //if it allows only one, but new instances replace
|
||||
|
||||
#define BASIC_STATUS_EFFECT /datum/status_effect //Has no effect.
|
||||
|
||||
///////////
|
||||
// BUFFS //
|
||||
///////////
|
||||
|
||||
@@ -84,24 +84,24 @@
|
||||
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_RESEARCH 15
|
||||
#define FIRE_PRIORITY_AIR 20
|
||||
#define FIRE_PRIORITY_NPC 20
|
||||
#define FIRE_PRIORITY_PROCESS 25
|
||||
#define FIRE_PRIORITY_THROWING 25
|
||||
#define FIRE_PRIORITY_FLIGHTPACKS 30
|
||||
#define FIRE_PRIORITY_SPACEDRIFT 30
|
||||
#define FIRE_PRIORITY_FIELDS 30
|
||||
#define FIRE_PRIOTITY_SMOOTHING 35
|
||||
#define FIRE_PRIORITY_ORBIT 35
|
||||
#define FIRE_PRIORITY_NETWORKS 40
|
||||
#define FIRE_PRIORITY_OBJ 40
|
||||
#define FIRE_PRIORUTY_FIELDS 40
|
||||
#define FIRE_PRIORITY_ACID 40
|
||||
#define FIRE_PRIOTITY_BURNING 40
|
||||
#define FIRE_PRIORITY_INBOUNDS 40
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
#define FIRE_PRIORITY_PARALLAX 65
|
||||
#define FIRE_PRIORITY_NETWORKS 80
|
||||
#define FIRE_PRIORITY_FLIGHTPACKS 80
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
|
||||
@@ -21,8 +21,25 @@
|
||||
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
|
||||
#define TRAIT_PUSHIMMUNE "push_immunity"
|
||||
#define TRAIT_SHOCKIMMUNE "shock_immunity"
|
||||
#define TRAIT_STABLEHEART "stable_heart"
|
||||
#define TRAIT_RESISTHEAT "resist_heat"
|
||||
#define TRAIT_RESISTCOLD "resist_cold"
|
||||
#define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure"
|
||||
#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
|
||||
#define TRAIT_RADIMMUNE "rad_immunity"
|
||||
#define TRAIT_VIRUSIMMUNE "virus_immunity"
|
||||
#define TRAIT_PIERCEIMMUNE "pierce_immunity"
|
||||
#define TRAIT_NODISMEMBER "dismember_immunity"
|
||||
#define TRAIT_NOFIRE "nonflammable"
|
||||
#define TRAIT_NOGUNS "no_guns"
|
||||
#define TRAIT_NOHUNGER "no_hunger"
|
||||
#define TRAIT_EASYDISMEMBER "easy_dismember"
|
||||
#define TRAIT_LIMBATTACHMENT "limb_attach"
|
||||
#define TRAIT_TOXINLOVER "toxinlover"
|
||||
#define TRAIT_NOBREATH "no_breath"
|
||||
#define TRAIT_ANTIMAGIC "anti_magic"
|
||||
#define TRAIT_HOLY "holy"
|
||||
#define TRAIT_NOCRITDAMAGE "no_crit"
|
||||
|
||||
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
|
||||
#define TRAIT_AGEUSIA "ageusia"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#define DM_NOISY "Noisy"
|
||||
#define DM_DRAGON "Dragon"
|
||||
|
||||
#define isbelly(A) istype(A, /obj/belly)
|
||||
|
||||
#define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
|
||||
#define VORE_STRUGGLE_EMOTE_CHANCE 40
|
||||
|
||||
// Stance for hostile mobs to be in while devouring someone.
|
||||
@@ -60,6 +63,10 @@ GLOBAL_LIST_INIT(pred_vore_sounds, list(
|
||||
"Squish3" = 'sound/vore/pred/squish_03.ogg',
|
||||
"Squish4" = 'sound/vore/pred/squish_04.ogg',
|
||||
"Rustle (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"rustle2(cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"rustle3(cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"rustle4(cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"rustle5(cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"None" = null))
|
||||
/*
|
||||
GLOBAL_LIST_INIT(pred_struggle_sounds, list(
|
||||
@@ -121,3 +128,14 @@ GLOBAL_LIST_INIT(death_prey, list(
|
||||
"death9" = 'sound/vore/prey/death_09.ogg',
|
||||
"death10" = 'sound/vore/prey/death_10.ogg'))
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(release_sound, list(
|
||||
"rustle (cloth)" = 'sound/effects/rustle1.ogg',
|
||||
"rustle2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"rustle3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"rustle4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"rustle5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"Stomach Move" = 'sound/vore/pred/stomachmove.ogg',
|
||||
"Pred Escape" = 'sound/vore/pred/escape.ogg',
|
||||
"Splatter" = 'sound/effects/splat.ogg',
|
||||
"None" = null))
|
||||
@@ -77,4 +77,7 @@ GLOBAL_VAR_INIT(cmp_field, "name")
|
||||
if(A.plane != B.plane)
|
||||
return A.plane - B.plane
|
||||
else
|
||||
return A.layer - B.layer
|
||||
return A.layer - B.layer
|
||||
|
||||
/proc/cmp_advdisease_resistance_asc(datum/disease/advance/A, datum/disease/advance/B)
|
||||
return A.totalResistance() - B.totalResistance()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
return path
|
||||
|
||||
#define FTPDELAY 200 //200 tick delay to discourage spam
|
||||
#define ADMIN_FTPDELAY_MODIFIER 0.5 //Admins get to spam files faster since we ~trust~ them!
|
||||
/* This proc is a failsafe to prevent spamming of file requests.
|
||||
It is just a timer that only permits a download every [FTPDELAY] ticks.
|
||||
This can be changed by modifying FTPDELAY's value above.
|
||||
@@ -45,9 +46,13 @@
|
||||
if(time_to_wait > 0)
|
||||
to_chat(src, "<font color='red'>Error: file_spam_check(): Spam. Please wait [DisplayTimeText(time_to_wait)].</font>")
|
||||
return 1
|
||||
GLOB.fileaccess_timer = world.time + FTPDELAY
|
||||
var/delay = FTPDELAY
|
||||
if(holder)
|
||||
delay *= ADMIN_FTPDELAY_MODIFIER
|
||||
GLOB.fileaccess_timer = world.time + delay
|
||||
return 0
|
||||
#undef FTPDELAY
|
||||
#undef ADMIN_FTPDELAY_MODIFIER
|
||||
|
||||
/proc/pathwalk(path)
|
||||
var/list/jobs = list(path)
|
||||
|
||||
@@ -105,3 +105,7 @@
|
||||
. += copytext(text, last_found, found)
|
||||
last_found = found + delim_len
|
||||
while (found)
|
||||
|
||||
// Returns true if val is from min to max, inclusive.
|
||||
/proc/IsInRange(val, min, max)
|
||||
return (val >= min) && (val <= max)
|
||||
@@ -920,7 +920,7 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
|
||||
That said, this proc should not be used if the change facing proc of the click code is overriden at the same time*/
|
||||
if(!ismob(target) || target.lying)
|
||||
//Make sure we are not doing this for things that can't have a logical direction to the players given that the target would be on their side
|
||||
return FACING_FAILED
|
||||
return FALSE
|
||||
if(initator.dir == target.dir) //mobs are facing the same direction
|
||||
return FACING_SAME_DIR
|
||||
if(is_A_facing_B(initator,target) && is_A_facing_B(target,initator)) //mobs are facing each other
|
||||
@@ -995,9 +995,9 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
|
||||
var/mob/living/LA = A
|
||||
if(LA.lying)
|
||||
return 0
|
||||
var/goal_dir = angle2dir(dir2angle(get_dir(B,A)+180))
|
||||
var/goal_dir = get_dir(A,B)
|
||||
var/clockwise_A_dir = turn(A.dir, -45)
|
||||
var/anticlockwise_A_dir = turn(B.dir, 45)
|
||||
var/anticlockwise_A_dir = turn(A.dir, 45)
|
||||
|
||||
if(A.dir == goal_dir || clockwise_A_dir == goal_dir || anticlockwise_A_dir == goal_dir)
|
||||
return 1
|
||||
|
||||
@@ -25,8 +25,10 @@ GLOBAL_LIST_EMPTY(available_ai_shells)
|
||||
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
|
||||
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
|
||||
GLOBAL_LIST_EMPTY(bots_list)
|
||||
GLOBAL_LIST_EMPTY(living_cameras)
|
||||
|
||||
GLOBAL_LIST_EMPTY(language_datum_instances)
|
||||
GLOBAL_LIST_EMPTY(all_languages)
|
||||
|
||||
GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes.
|
||||
GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes.
|
||||
GLOBAL_LIST_EMPTY(sentient_disease_instances)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
//Each lists stores ckeys for "Never for this round" option category
|
||||
|
||||
#define POLL_IGNORE_PAI "pai"
|
||||
#define POLL_IGNORE_SENTIENCE_POTION "sentience_potion"
|
||||
#define POLL_IGNORE_POSSESSED_BLADE "possessed_blade"
|
||||
#define POLL_IGNORE_ALIEN_LARVA "alien_larva"
|
||||
#define POLL_IGNORE_CLOCKWORK_MARAUDER "clockwork_marauder"
|
||||
#define POLL_IGNORE_SYNDICATE "syndicate"
|
||||
#define POLL_IGNORE_HOLOPARASITE "holoparasite"
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
GLOBAL_VAR_INIT(enable_examine_tips, TRUE)
|
||||
@@ -1,8 +0,0 @@
|
||||
/mob/camera/god/UnarmedAttack(atom/A)
|
||||
A.attack_god(src)
|
||||
|
||||
/mob/camera/god/RangedAttack(atom/A)
|
||||
A.attack_god(src)
|
||||
|
||||
/atom/proc/attack_god(mob/user)
|
||||
return
|
||||
@@ -66,7 +66,7 @@
|
||||
#define ui_monkey_neck "CENTER-3:15,SOUTH:5" //monkey
|
||||
#define ui_monkey_back "CENTER-2:16,SOUTH:5" //monkey
|
||||
|
||||
#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien
|
||||
//#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien
|
||||
#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien
|
||||
#define ui_alien_language_menu "EAST-3:26,SOUTH:5" //alien
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
/datum/hud/brain/show_hud(version = 0)
|
||||
if(!ismob(mymob))
|
||||
return 0
|
||||
if(!mymob.client)
|
||||
return 0
|
||||
mymob.client.screen = list()
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
/mob/living/brain/create_mob_hud()
|
||||
if(client && !hud_used)
|
||||
hud_used = new /datum/hud/brain(src)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"<span class='userdanger'>[name] bites [ML]!</span>")
|
||||
if(armor >= 2)
|
||||
return
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
ML.ForceContractDisease(D)
|
||||
else
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
By default, emulate the user's unarmed attack
|
||||
*/
|
||||
|
||||
#define TK_MAXRANGE 15
|
||||
|
||||
/atom/proc/attack_tk(mob/user)
|
||||
if(user.stat || !tkMaxRangeCheck(user, src))
|
||||
return
|
||||
@@ -188,3 +190,6 @@
|
||||
/obj/item/tk_grab/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is using [user.p_their()] telekinesis to choke [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (OXYLOSS)
|
||||
|
||||
|
||||
#undef TK_MAXRANGE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
/obj/item/clothing/under/bb_sweater
|
||||
name = "cream sweater"
|
||||
desc = "Why trade style for comfort? Now you can go commando down south and still be cozy up north."
|
||||
icon_state = "bb_turtle"
|
||||
item_state = "w_suit"
|
||||
item_color = "bb_turtle"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
can_adjust = 1
|
||||
icon = 'icons/obj/clothing/turtlenecks.dmi'
|
||||
icon_override = 'icons/mob/citadel/uniforms.dmi'
|
||||
|
||||
/obj/item/clothing/under/bb_sweater/black
|
||||
name = "black sweater"
|
||||
icon_state = "bb_turtleblk"
|
||||
item_state = "bl_suit"
|
||||
item_color = "bb_turtleblk"
|
||||
|
||||
/obj/item/clothing/under/bb_sweater/purple
|
||||
name = "purple sweater"
|
||||
icon_state = "bb_turtlepur"
|
||||
item_state = "p_suit"
|
||||
item_color = "bb_turtlepur"
|
||||
|
||||
/obj/item/clothing/under/bb_sweater/green
|
||||
name = "green sweater"
|
||||
icon_state = "bb_turtlegrn"
|
||||
item_state = "g_suit"
|
||||
item_color = "bb_turtlegrn"
|
||||
|
||||
/obj/item/clothing/under/bb_sweater/red
|
||||
name = "red sweater"
|
||||
icon_state = "bb_turtlered"
|
||||
item_state = "r_suit"
|
||||
item_color = "bb_turtlered"
|
||||
|
||||
/obj/item/clothing/under/bb_sweater/blue
|
||||
name = "blue sweater"
|
||||
icon_state = "bb_turtleblu"
|
||||
item_state = "b_suit"
|
||||
item_color = "bb_turtleblu"
|
||||
@@ -1,102 +0,0 @@
|
||||
#define STANDARD_CHARGE 1
|
||||
#define CONTRABAND_CHARGE 2
|
||||
#define COIN_CHARGE 3
|
||||
|
||||
/obj/machinery/vending/kink
|
||||
name = "KinkMate"
|
||||
desc = "A vending machine for all your unmentionable desires."
|
||||
icon = 'icons/obj/citvending.dmi'
|
||||
icon_state = "kink"
|
||||
product_slogans = "Kinky!;Sexy!;Check me out, big boy!"
|
||||
vend_reply = "Have fun, you shameless pervert!"
|
||||
products = list(
|
||||
/obj/item/clothing/under/maid = 5,
|
||||
/obj/item/clothing/under/stripper_pink = 5,
|
||||
/obj/item/clothing/under/stripper_green = 5,
|
||||
/obj/item/dildo/custom = 5
|
||||
)
|
||||
contraband = list(/obj/item/restraints/handcuffs/fake/kinky = 5,
|
||||
/obj/item/clothing/neck/petcollar = 5,
|
||||
/obj/item/clothing/under/mankini = 1,
|
||||
/obj/item/dildo/flared/huge = 1
|
||||
)
|
||||
premium = list(/obj/item/device/electropack/shockcollar = 1)
|
||||
refill_canister = /obj/item/vending_refill/kink
|
||||
/*
|
||||
/obj/machinery/vending/nazivend
|
||||
name = "Nazivend"
|
||||
desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\""
|
||||
icon = 'icons/obj/citvending.dmi'
|
||||
icon_state = "nazi"
|
||||
vend_reply = "SIEG HEIL!"
|
||||
product_slogans = "Das Vierte Reich wird zuruckkehren!;ENTFERNEN JUDEN!;Billiger als die Juden jemals geben!;Rader auf dem adminbus geht rund und rund.;Warten Sie, warum wir wieder hassen Juden?- *BZZT*"
|
||||
products = list(
|
||||
/obj/item/clothing/head/stalhelm = 20,
|
||||
/obj/item/clothing/head/panzer = 20,
|
||||
/obj/item/clothing/suit/soldiercoat = 20,
|
||||
// /obj/item/clothing/under/soldieruniform = 20,
|
||||
/obj/item/clothing/shoes/jackboots = 20
|
||||
)
|
||||
contraband = list(
|
||||
/obj/item/clothing/head/naziofficer = 10,
|
||||
// /obj/item/clothing/suit/officercoat = 10,
|
||||
// /obj/item/clothing/under/officeruniform = 10,
|
||||
/obj/item/clothing/suit/space/hardsuit/nazi = 3,
|
||||
/obj/item/gun/energy/plasma/MP40k = 4
|
||||
)
|
||||
premium = list()
|
||||
|
||||
refill_canister = /obj/item/vending_refill/nazi
|
||||
*/
|
||||
/obj/machinery/vending/sovietvend
|
||||
name = "KomradeVendtink"
|
||||
desc = "Rodina-mat' zovyot!"
|
||||
icon = 'icons/obj/citvending.dmi'
|
||||
icon_state = "soviet"
|
||||
vend_reply = "The fascist and capitalist svin'ya shall fall, komrade!"
|
||||
product_slogans = "Quality worth waiting in line for!; Get Hammer and Sickled!; Sosvietsky soyuz above all!; With capitalist pigsky, you would have paid a fortunetink! ; Craftink in Motherland herself!"
|
||||
products = list(
|
||||
/obj/item/clothing/under/soviet = 20,
|
||||
/obj/item/clothing/head/ushanka = 20,
|
||||
/obj/item/clothing/shoes/jackboots = 20,
|
||||
/obj/item/clothing/head/squatter_hat = 20,
|
||||
/obj/item/clothing/under/squatter_outfit = 20,
|
||||
/obj/item/clothing/under/russobluecamooutfit = 20,
|
||||
/obj/item/clothing/head/russobluecamohat = 20
|
||||
)
|
||||
contraband = list(
|
||||
/obj/item/clothing/under/syndicate/tacticool = 4,
|
||||
/obj/item/clothing/mask/balaclava = 4,
|
||||
/obj/item/clothing/suit/russofurcoat = 4,
|
||||
/obj/item/clothing/head/russofurhat = 4,
|
||||
/obj/item/clothing/suit/space/hardsuit/soviet = 3,
|
||||
/obj/item/gun/energy/laser/LaserAK = 4
|
||||
)
|
||||
premium = list()
|
||||
|
||||
refill_canister = /obj/item/vending_refill/soviet
|
||||
|
||||
|
||||
#undef STANDARD_CHARGE
|
||||
#undef CONTRABAND_CHARGE
|
||||
#undef COIN_CHARGE
|
||||
|
||||
|
||||
/obj/item/vending_refill/kink
|
||||
machine_name = "KinkMate"
|
||||
icon = 'modular_citadel/icons/vending_restock.dmi'
|
||||
icon_state = "refill_kink"
|
||||
charges = list(8, 5, 0)// of 20 standard, 12 contraband, 0 premium
|
||||
init_charges = list(8, 5, 0)
|
||||
|
||||
/obj/item/vending_refill/nazi
|
||||
machine_name = "nazivend"
|
||||
icon_state = "refill_nazi"
|
||||
charges = list(33, 13, 0)
|
||||
init_charges = list(33, 13, 0)
|
||||
|
||||
/obj/item/vending_refill/soviet
|
||||
machine_name = "sovietvend"
|
||||
icon_state = "refill_soviet"
|
||||
charges = list(47, 7, 0)
|
||||
init_charges = list(47, 7, 0)
|
||||
@@ -1,13 +0,0 @@
|
||||
/proc/send2maindiscord(var/msg)
|
||||
send2discord(msg, FALSE)
|
||||
|
||||
/proc/send2admindiscord(var/msg, var/ping = FALSE)
|
||||
send2discord(msg, TRUE, ping)
|
||||
|
||||
/proc/send2discord(var/msg, var/admin = FALSE, var/ping = FALSE)
|
||||
// if (!config.discord_url || !config.discord_password)
|
||||
// return
|
||||
|
||||
// var/url = "[config.discord_url]?pass=[url_encode(config.discord_password)]&admin=[admin ? "true" : "false"]&content=[url_encode(msg)]&ping=[ping ? "true" : "false"]"
|
||||
// world.Export(url)
|
||||
return
|
||||
@@ -1,287 +0,0 @@
|
||||
GLOBAL_VAR_INIT(config_dir, "config/")
|
||||
GLOBAL_PROTECT(config_dir)
|
||||
|
||||
/datum/controller/configuration
|
||||
name = "Configuration"
|
||||
|
||||
var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it
|
||||
var/list/entries
|
||||
var/list/entries_by_type
|
||||
|
||||
var/list/maplist
|
||||
var/datum/map_config/defaultmap
|
||||
|
||||
var/list/modes // allowed modes
|
||||
var/list/gamemode_cache
|
||||
var/list/votable_modes // votable modes
|
||||
var/list/mode_names
|
||||
var/list/mode_reports
|
||||
var/list/mode_false_report_weight
|
||||
|
||||
/datum/controller/configuration/New()
|
||||
config = src
|
||||
var/list/config_files = InitEntries()
|
||||
LoadModes()
|
||||
for(var/I in config_files)
|
||||
LoadEntries(I)
|
||||
if(Get(/datum/config_entry/flag/maprotation))
|
||||
loadmaplist(CONFIG_MAPS_FILE)
|
||||
|
||||
/datum/controller/configuration/Destroy()
|
||||
entries_by_type.Cut()
|
||||
QDEL_LIST_ASSOC_VAL(entries)
|
||||
QDEL_LIST_ASSOC_VAL(maplist)
|
||||
QDEL_NULL(defaultmap)
|
||||
|
||||
config = null
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/configuration/proc/InitEntries()
|
||||
var/list/_entries = list()
|
||||
entries = _entries
|
||||
var/list/_entries_by_type = list()
|
||||
entries_by_type = _entries_by_type
|
||||
|
||||
. = list()
|
||||
|
||||
for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case
|
||||
var/datum/config_entry/E = I
|
||||
if(initial(E.abstract_type) == I)
|
||||
continue
|
||||
E = new I
|
||||
_entries_by_type[I] = E
|
||||
var/esname = E.name
|
||||
var/datum/config_entry/test = _entries[esname]
|
||||
if(test)
|
||||
log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!")
|
||||
qdel(E)
|
||||
continue
|
||||
_entries[esname] = E
|
||||
.[E.resident_file] = TRUE
|
||||
|
||||
/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE)
|
||||
entries -= CE.name
|
||||
entries_by_type -= CE.type
|
||||
|
||||
/datum/controller/configuration/proc/LoadEntries(filename)
|
||||
log_config("Loading config file [filename]...")
|
||||
var/list/lines = world.file2list("[GLOB.config_dir][filename]")
|
||||
var/list/_entries = entries
|
||||
for(var/L in lines)
|
||||
if(!L)
|
||||
continue
|
||||
|
||||
if(copytext(L, 1, 2) == "#")
|
||||
continue
|
||||
|
||||
var/pos = findtext(L, " ")
|
||||
var/entry = null
|
||||
var/value = null
|
||||
|
||||
if(pos)
|
||||
entry = lowertext(copytext(L, 1, pos))
|
||||
value = copytext(L, pos + 1)
|
||||
else
|
||||
entry = lowertext(L)
|
||||
|
||||
if(!entry)
|
||||
continue
|
||||
|
||||
var/datum/config_entry/E = _entries[entry]
|
||||
if(!E)
|
||||
log_config("Unknown setting in configuration: '[entry]'")
|
||||
continue
|
||||
|
||||
if(filename != E.resident_file)
|
||||
log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
|
||||
continue
|
||||
|
||||
var/validated = E.ValidateAndSet(value)
|
||||
if(!validated)
|
||||
log_config("Failed to validate setting \"[value]\" for [entry]")
|
||||
else if(E.modified && !E.dupes_allowed)
|
||||
log_config("Duplicate setting for [entry] ([value]) detected! Using latest.")
|
||||
|
||||
if(validated)
|
||||
E.modified = TRUE
|
||||
|
||||
/datum/controller/configuration/can_vv_get(var_name)
|
||||
return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..()
|
||||
|
||||
/datum/controller/configuration/vv_edit_var(var_name, var_value)
|
||||
return !(var_name in list("entries_by_type", "entries")) && ..()
|
||||
|
||||
/datum/controller/configuration/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Edit", src)
|
||||
stat("[name]:", statclick)
|
||||
|
||||
/datum/controller/configuration/proc/Get(entry_type)
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
|
||||
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
|
||||
return
|
||||
var/datum/config_entry/E = entry_type
|
||||
var/entry_is_abstract = initial(E.abstract_type) == entry_type
|
||||
if(entry_is_abstract)
|
||||
CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
|
||||
E = entries_by_type[entry_type]
|
||||
if(!E)
|
||||
CRASH("Missing config entry for [entry_type]!")
|
||||
return E.value
|
||||
|
||||
/datum/controller/configuration/proc/Set(entry_type, new_val)
|
||||
if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
|
||||
log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]")
|
||||
return
|
||||
var/datum/config_entry/E = entry_type
|
||||
var/entry_is_abstract = initial(E.abstract_type) == entry_type
|
||||
if(entry_is_abstract)
|
||||
CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
|
||||
E = entries_by_type[entry_type]
|
||||
if(!E)
|
||||
CRASH("Missing config entry for [entry_type]!")
|
||||
return E.ValidateAndSet(new_val)
|
||||
|
||||
/datum/controller/configuration/proc/LoadModes()
|
||||
gamemode_cache = typecacheof(/datum/game_mode, TRUE)
|
||||
modes = list()
|
||||
mode_names = list()
|
||||
mode_reports = list()
|
||||
mode_false_report_weight = list()
|
||||
votable_modes = list()
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
|
||||
for(var/T in gamemode_cache)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
// their information, but it is the only way (at least that I know of).
|
||||
var/datum/game_mode/M = new T()
|
||||
|
||||
if(M.config_tag)
|
||||
if(!(M.config_tag in modes)) // ensure each mode is added only once
|
||||
modes += M.config_tag
|
||||
mode_names[M.config_tag] = M.name
|
||||
probabilities[M.config_tag] = M.probability
|
||||
mode_reports[M.config_tag] = M.generate_report()
|
||||
mode_false_report_weight[M.config_tag] = M.false_report_weight
|
||||
if(M.votable)
|
||||
votable_modes += M.config_tag
|
||||
qdel(M)
|
||||
votable_modes += "secret"
|
||||
|
||||
/datum/controller/configuration/proc/loadmaplist(filename)
|
||||
filename = "[GLOB.config_dir][filename]"
|
||||
var/list/Lines = world.file2list(filename)
|
||||
|
||||
var/datum/map_config/currentmap = null
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
continue
|
||||
|
||||
t = trim(t)
|
||||
if(length(t) == 0)
|
||||
continue
|
||||
else if(copytext(t, 1, 2) == "#")
|
||||
continue
|
||||
|
||||
var/pos = findtext(t, " ")
|
||||
var/command = null
|
||||
var/data = null
|
||||
|
||||
if(pos)
|
||||
command = lowertext(copytext(t, 1, pos))
|
||||
data = copytext(t, pos + 1)
|
||||
else
|
||||
command = lowertext(t)
|
||||
|
||||
if(!command)
|
||||
continue
|
||||
|
||||
if (!currentmap && command != "map")
|
||||
continue
|
||||
|
||||
switch (command)
|
||||
if ("map")
|
||||
currentmap = new ("_maps/[data].json")
|
||||
if(currentmap.defaulted)
|
||||
log_config("Failed to load map config for [data]!")
|
||||
if ("minplayers","minplayer")
|
||||
currentmap.config_min_users = text2num(data)
|
||||
if ("maxplayers","maxplayer")
|
||||
currentmap.config_max_users = text2num(data)
|
||||
if ("weight","voteweight")
|
||||
currentmap.voteweight = text2num(data)
|
||||
if ("default","defaultmap")
|
||||
defaultmap = currentmap
|
||||
if ("endmap")
|
||||
LAZYINITLIST(maplist)
|
||||
maplist[currentmap.map_name] = currentmap
|
||||
currentmap = null
|
||||
if ("disabled")
|
||||
currentmap = null
|
||||
else
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'")
|
||||
|
||||
|
||||
/datum/controller/configuration/proc/pick_mode(mode_name)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
// their information, but it is the only way (at least that I know of).
|
||||
// ^ This guy didn't try hard enough
|
||||
for(var/T in gamemode_cache)
|
||||
var/datum/game_mode/M = T
|
||||
var/ct = initial(M.config_tag)
|
||||
if(ct && ct == mode_name)
|
||||
return new T
|
||||
return new /datum/game_mode/extended()
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
|
||||
var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
|
||||
var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
for(var/T in gamemode_cache)
|
||||
var/datum/game_mode/M = new T()
|
||||
if(!(M.config_tag in modes))
|
||||
qdel(M)
|
||||
continue
|
||||
if(probabilities[M.config_tag]<=0)
|
||||
qdel(M)
|
||||
continue
|
||||
if(min_pop[M.config_tag])
|
||||
M.required_players = min_pop[M.config_tag]
|
||||
if(max_pop[M.config_tag])
|
||||
M.maximum_players = max_pop[M.config_tag]
|
||||
if(M.can_start())
|
||||
var/final_weight = probabilities[M.config_tag]
|
||||
if(SSpersistence.saved_modes.len == 3 && repeated_mode_adjust.len == 3)
|
||||
var/recent_round = min(SSpersistence.saved_modes.Find(M.config_tag),3)
|
||||
var/adjustment = 0
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0)
|
||||
final_weight *= ((100-adjustment)/100)
|
||||
runnable_modes[M] = final_weight
|
||||
return runnable_modes
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
|
||||
var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
|
||||
var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
|
||||
for(var/T in (gamemode_cache - SSticker.mode.type))
|
||||
var/datum/game_mode/M = new T()
|
||||
if(!(M.config_tag in modes))
|
||||
qdel(M)
|
||||
continue
|
||||
if(probabilities[M.config_tag]<=0)
|
||||
qdel(M)
|
||||
continue
|
||||
if(min_pop[M.config_tag])
|
||||
M.required_players = min_pop[M.config_tag]
|
||||
if(max_pop[M.config_tag])
|
||||
M.maximum_players = max_pop[M.config_tag]
|
||||
if(M.required_players <= crew)
|
||||
if(M.maximum_players >= 0 && M.maximum_players < crew)
|
||||
continue
|
||||
runnable_modes[M] = probabilities[M.config_tag]
|
||||
return runnable_modes
|
||||
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* Startup hook.
|
||||
* Called in world.dm when the server starts.
|
||||
*/
|
||||
/hook/startup
|
||||
|
||||
/**
|
||||
* Roundstart hook.
|
||||
* Called in gameticker.dm when a round starts.
|
||||
*/
|
||||
/hook/roundstart
|
||||
|
||||
/**
|
||||
* Roundend hook.
|
||||
* Called in gameticker.dm when a round ends.
|
||||
*/
|
||||
/hook/roundend
|
||||
|
||||
/**
|
||||
* Death hook.
|
||||
* Called in death.dm when someone dies.
|
||||
* Parameters: var/mob/living/carbon/human, var/gibbed
|
||||
*/
|
||||
/hook/death
|
||||
|
||||
/**
|
||||
* Cloning hook.
|
||||
* Called in cloning.dm when someone is brought back by the wonders of modern science.
|
||||
* Parameters: var/mob/living/carbon/human
|
||||
*/
|
||||
/hook/clone
|
||||
|
||||
/**
|
||||
* Debrained hook.
|
||||
* Called in brain_item.dm when someone gets debrained.
|
||||
* Parameters: var/obj/item/organ/brain
|
||||
*/
|
||||
/hook/debrain
|
||||
|
||||
/**
|
||||
* Borged hook.
|
||||
* Called in robot_parts.dm when someone gets turned into a cyborg.
|
||||
* Parameters: var/mob/living/silicon/robot
|
||||
*/
|
||||
/hook/borgify
|
||||
|
||||
/**
|
||||
* Podman hook.
|
||||
* Called in podmen.dm when someone is brought back as a Diona.
|
||||
* Parameters: var/mob/living/carbon/alien/diona
|
||||
*/
|
||||
/hook/harvest_podman
|
||||
|
||||
/**
|
||||
* Payroll revoked hook.
|
||||
* Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal.
|
||||
* Parameters: var/datum/money_account
|
||||
*/
|
||||
/hook/revoke_payroll
|
||||
|
||||
/**
|
||||
* Account suspension hook.
|
||||
* Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal.
|
||||
* Parameters: var/datum/money_account
|
||||
*/
|
||||
/hook/change_account_status
|
||||
|
||||
/**
|
||||
* Employee reassignment hook.
|
||||
* Called in card.dm when someone's card is reassigned at the HoP's desk.
|
||||
* Parameters: var/obj/item/card/id
|
||||
*/
|
||||
/hook/reassign_employee
|
||||
|
||||
/**
|
||||
* Employee terminated hook.
|
||||
* Called in card.dm when someone's card is terminated at the HoP's desk.
|
||||
* Parameters: var/obj/item/card/id
|
||||
*/
|
||||
/hook/terminate_employee
|
||||
|
||||
/**
|
||||
* Crate sold hook.
|
||||
* Called in supplyshuttle.dm when a crate is sold on the shuttle.
|
||||
* Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle
|
||||
*/
|
||||
/hook/sell_crate
|
||||
@@ -1,510 +0,0 @@
|
||||
SUBSYSTEM_DEF(explosion)
|
||||
priority = 99
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/explosions
|
||||
|
||||
var/rebuild_tick_split_count = FALSE
|
||||
var/tick_portions_required = 0
|
||||
|
||||
var/list/logs
|
||||
|
||||
var/list/zlevels_that_ignore_bombcap
|
||||
var/list/doppler_arrays
|
||||
|
||||
//legacy caps, set by config
|
||||
var/devastation_cap = 3
|
||||
var/heavy_cap = 7
|
||||
var/light_cap = 14
|
||||
var/flash_cap = 14
|
||||
var/flame_cap = 14
|
||||
var/dyn_ex_scale = 0.5
|
||||
|
||||
var/id_counter = 0
|
||||
|
||||
/datum/controller/subsystem/explosion/PreInit()
|
||||
doppler_arrays = list()
|
||||
logs = list()
|
||||
explosions = list()
|
||||
zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]")
|
||||
|
||||
/datum/controller/subsystem/explosion/Shutdown()
|
||||
QDEL_LIST(explosions)
|
||||
QDEL_LIST(logs)
|
||||
zlevels_that_ignore_bombcap.Cut()
|
||||
|
||||
/datum/controller/subsystem/explosion/Recover()
|
||||
explosions = SSexplosion.explosions
|
||||
logs = SSexplosion.logs
|
||||
id_counter = SSexplosion.id_counter
|
||||
rebuild_tick_split_count = TRUE
|
||||
zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap
|
||||
doppler_arrays = SSexplosion.doppler_arrays
|
||||
|
||||
devastation_cap = SSexplosion.devastation_cap
|
||||
heavy_cap = SSexplosion.heavy_cap
|
||||
light_cap = SSexplosion.light_cap
|
||||
flash_cap = SSexplosion.flash_cap
|
||||
flame_cap = SSexplosion.flame_cap
|
||||
dyn_ex_scale = SSexplosion.dyn_ex_scale
|
||||
|
||||
/datum/controller/subsystem/explosion/fire()
|
||||
var/list/cached_explosions = explosions
|
||||
var/num_explosions = cached_explosions.len
|
||||
if(!num_explosions)
|
||||
return
|
||||
|
||||
//figure exactly how many tick splits are required
|
||||
var/num_splits
|
||||
if(rebuild_tick_split_count)
|
||||
var/reactionary = config.reactionary_explosions
|
||||
num_splits = num_explosions
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
if(!E.turfs_processed)
|
||||
++num_splits
|
||||
if(reactionary && !E.densities_processed)
|
||||
++num_splits
|
||||
tick_portions_required = num_splits
|
||||
else
|
||||
num_splits = tick_portions_required
|
||||
|
||||
MC_SPLIT_TICK_INIT(num_splits)
|
||||
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
|
||||
var/etp = E.turfs_processed
|
||||
if(!etp)
|
||||
if(GatherTurfs(E))
|
||||
--tick_portions_required
|
||||
etp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
var/edp = E.densities_processed
|
||||
if(!edp)
|
||||
if(DensityCalculate(E, etp))
|
||||
--tick_portions_required
|
||||
edp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
if(ProcessExplosion(E, edp)) //splits the tick
|
||||
--tick_portions_required
|
||||
explosions -= E
|
||||
logs += E
|
||||
NotifyDopplers(E)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E)
|
||||
for(var/array in doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range)
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
|
||||
|
||||
var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/Eff
|
||||
if(smoke)
|
||||
Eff = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
Eff = new
|
||||
Eff.set_up(epicenter)
|
||||
Eff.start()
|
||||
|
||||
//flash mobs
|
||||
if(flash_range)
|
||||
for(var/mob/living/L in viewers(flash_range, epicenter))
|
||||
L.flash_act()
|
||||
|
||||
if(!silent)
|
||||
ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent)
|
||||
|
||||
//add to SS
|
||||
if(E.extent)
|
||||
tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0)
|
||||
explosions += E
|
||||
else
|
||||
logs += E //Already done processing
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE)
|
||||
if(!power)
|
||||
return
|
||||
var/range = round((2 * power) ** dyn_ex_scale)
|
||||
Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke)
|
||||
|
||||
// Using default dyn_ex scale:
|
||||
// 100 explosion power is a (5, 10, 20) explosion.
|
||||
// 75 explosion power is a (4, 8, 17) explosion.
|
||||
// 50 explosion power is a (3, 7, 14) explosion.
|
||||
// 25 explosion power is a (2, 5, 10) explosion.
|
||||
// 10 explosion power is a (1, 3, 6) explosion.
|
||||
// 5 explosion power is a (0, 1, 3) explosion.
|
||||
// 1 explosion power is a (0, 0, 1) explosion.
|
||||
|
||||
/datum/explosion
|
||||
var/explosion_id
|
||||
var/turf/epicenter
|
||||
|
||||
var/started_at
|
||||
var/finished_at
|
||||
var/tick_started
|
||||
var/tick_finished
|
||||
|
||||
var/turfs_processed = FALSE
|
||||
var/densities_processed = FALSE
|
||||
|
||||
var/orig_dev_range
|
||||
var/orig_heavy_range
|
||||
var/orig_light_range
|
||||
var/orig_flash_range
|
||||
var/orig_flame_range
|
||||
|
||||
var/devastation
|
||||
var/heavy
|
||||
var/light
|
||||
var/extent
|
||||
|
||||
var/flash
|
||||
var/flame
|
||||
|
||||
var/gather_dist = 0
|
||||
|
||||
var/list/gathered_turfs
|
||||
var/list/calculated_turfs
|
||||
|
||||
var/list/unsafe_turfs
|
||||
|
||||
/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
explosion_id = id
|
||||
epicenter = epi
|
||||
|
||||
densities_processed = !config.reactionary_explosions
|
||||
|
||||
orig_dev_range = devastation_range
|
||||
orig_heavy_range = heavy_impact_range
|
||||
orig_light_range = light_impact_range
|
||||
orig_flash_range = flash_range
|
||||
orig_flame_range = flame_range
|
||||
|
||||
if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap))
|
||||
//Clamp all values
|
||||
devastation_range = min(SSexplosion.devastation_cap, devastation_range)
|
||||
heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range)
|
||||
light_impact_range = min(SSexplosion.light_cap, light_impact_range)
|
||||
flash_range = min(SSexplosion.flash_cap, flash_range)
|
||||
flame_range = min(SSexplosion.flame_cap, flame_range)
|
||||
|
||||
//store this
|
||||
devastation = devastation_range
|
||||
heavy = heavy_impact_range
|
||||
light = light_impact_range
|
||||
|
||||
extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
|
||||
flash = flash_range
|
||||
flame = flame_range
|
||||
|
||||
started_at = REALTIMEOFDAY
|
||||
tick_started = world.time
|
||||
|
||||
gathered_turfs = list()
|
||||
calculated_turfs = list()
|
||||
unsafe_turfs = list()
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
|
||||
// 3/7/14 will calculate to 80 + 35
|
||||
/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent)
|
||||
var/far_dist = 0
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(extent + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
|
||||
/datum/explosion/Destroy()
|
||||
SSexplosion.explosions -= src
|
||||
SSexplosion.logs -= src
|
||||
LAZYCLEARLIST(gathered_turfs)
|
||||
LAZYCLEARLIST(calculated_turfs)
|
||||
LAZYCLEARLIST(unsafe_turfs)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E)
|
||||
var/turf/epicenter = E.epicenter
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/c_dist = E.gather_dist
|
||||
var/dist = E.extent
|
||||
|
||||
var/list/L = E.gathered_turfs
|
||||
|
||||
if(!c_dist)
|
||||
L += epicenter
|
||||
++c_dist
|
||||
|
||||
while( c_dist <= dist )
|
||||
var/y = y0 + c_dist
|
||||
var/x = x0 - c_dist + 1
|
||||
for(x in x to x0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 + c_dist - 1
|
||||
x = x0 + c_dist
|
||||
for(y in y0 - c_dist to y)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist
|
||||
x = x0 + c_dist - 1
|
||||
for(x in x0 - c_dist to x)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist + 1
|
||||
x = x0 - c_dist
|
||||
for(y in y to y0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
++c_dist
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
if(c_dist > dist)
|
||||
E.turfs_processed = TRUE
|
||||
return TRUE
|
||||
else
|
||||
E.gather_dist = c_dist
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs)
|
||||
var/list/L = E.calculated_turfs
|
||||
var/cut_to = 1
|
||||
for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = I
|
||||
++cut_to
|
||||
|
||||
var/current_exp_block = T.density ? T.explosion_block : 0
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density)
|
||||
current_exp_block += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
current_exp_block += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
current_exp_block += B.explosion_block
|
||||
|
||||
L[T] = current_exp_block
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
E.gathered_turfs.Cut(1, cut_to)
|
||||
return FALSE
|
||||
|
||||
E.gathered_turfs.Cut()
|
||||
return done_gathering_turfs
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs)
|
||||
//cache shit for speed
|
||||
var/id = E.explosion_id
|
||||
|
||||
var/list/cached_unsafe = E.unsafe_turfs
|
||||
var/list/cached_exp_block = E.calculated_turfs
|
||||
var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs
|
||||
|
||||
var/devastation_range = E.devastation
|
||||
var/heavy_impact_range = E.heavy
|
||||
var/light_impact_range = E.light
|
||||
|
||||
var/flame_range = E.flame
|
||||
var/throw_range_max = E.extent
|
||||
|
||||
var/turf/epi = E.epicenter
|
||||
|
||||
var/x0 = epi.x
|
||||
var/y0 = epi.y
|
||||
|
||||
var/cut_to = 1
|
||||
for(var/TI in affected_turfs)
|
||||
var/turf/T = TI
|
||||
++cut_to
|
||||
|
||||
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
|
||||
var/dist = init_dist
|
||||
|
||||
if(cached_exp_block)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epi)
|
||||
Trajectory = get_step_towards(Trajectory, epi)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = dist < flame_range
|
||||
var/throw_dist = dist
|
||||
|
||||
if(dist < devastation_range)
|
||||
dist = 1
|
||||
else if(dist < heavy_impact_range)
|
||||
dist = 2
|
||||
else if(dist < light_impact_range)
|
||||
dist = 3
|
||||
else
|
||||
dist = 0
|
||||
|
||||
//------- EX_ACT AND TURF FIRES -------
|
||||
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
cached_unsafe += T
|
||||
|
||||
//--- THROW ITEMS AROUND ---
|
||||
|
||||
var/throw_dir = get_dir(epi, T)
|
||||
for(var/obj/item/I in T)
|
||||
if(!I.anchored)
|
||||
var/throw_range = rand(throw_dist, throw_range_max)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, 4)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
|
||||
if(cached_unsafe.len > circumference) //only do this every revolution
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
done_calculating_turfs = FALSE
|
||||
break
|
||||
|
||||
affected_turfs.Cut(1, cut_to)
|
||||
|
||||
if(!done_calculating_turfs)
|
||||
return FALSE
|
||||
|
||||
//unfuck the shit
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
|
||||
E.finished_at = REALTIMEOFDAY
|
||||
E.tick_finished = world.time
|
||||
|
||||
return TRUE
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
|
||||
var/dev = 0
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = input("Bomb Size?") in choices
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
if("Small Bomb")
|
||||
dev = 1
|
||||
heavy = 2
|
||||
light = 3
|
||||
if("Medium Bomb")
|
||||
dev = 2
|
||||
heavy = 3
|
||||
light = 4
|
||||
if("Big Bomb")
|
||||
dev = 3
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devestation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
else
|
||||
return
|
||||
|
||||
var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE)
|
||||
|
||||
while(!SSexplosion.GatherTurfs(E))
|
||||
stoplag()
|
||||
var/list/turfs
|
||||
if(newmode)
|
||||
while(!SSexplosion.DensityCalculate(E, TRUE))
|
||||
stoplag()
|
||||
turfs = E.calculated_turfs.Copy()
|
||||
else
|
||||
turfs = E.gathered_turfs.Copy()
|
||||
|
||||
qdel(E)
|
||||
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T]
|
||||
|
||||
if(dist < dev)
|
||||
T.color = "red"
|
||||
T.maptext = "Dev"
|
||||
else if (dist < heavy)
|
||||
T.color = "yellow"
|
||||
T.maptext = "Heavy"
|
||||
else if (dist < light)
|
||||
T.color = "blue"
|
||||
T.maptext = "Light"
|
||||
CHECK_TICK
|
||||
|
||||
sleep(100)
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
T.color = null
|
||||
T.maptext = null
|
||||
@@ -21,8 +21,8 @@ SUBSYSTEM_DEF(mobs)
|
||||
var/seconds = wait * 0.1
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.mob_living_list.Copy()
|
||||
if (GLOB.overminds.len) // blob cameras need to Life()
|
||||
src.currentrun += GLOB.overminds
|
||||
if (GLOB.living_cameras.len)
|
||||
src.currentrun += GLOB.living_cameras
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
@@ -8,7 +8,6 @@ SUBSYSTEM_DEF(nightshift)
|
||||
var/nightshift_end_time = 270000 //7:30 AM, station time
|
||||
var/nightshift_first_check = 30 SECONDS
|
||||
|
||||
var/obey_security_level = TRUE
|
||||
var/high_security_mode = FALSE
|
||||
|
||||
/datum/controller/subsystem/nightshift/Initialize()
|
||||
@@ -21,48 +20,38 @@ SUBSYSTEM_DEF(nightshift)
|
||||
return
|
||||
check_nightshift()
|
||||
|
||||
/datum/controller/subsystem/nightshift/proc/announce(message)
|
||||
priority_announce(message, sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement")
|
||||
|
||||
/datum/controller/subsystem/nightshift/proc/check_nightshift(force_set = FALSE)
|
||||
var/time = station_time()
|
||||
var/nightshift = time < nightshift_end_time || time > nightshift_start_time
|
||||
var/red_or_delta = GLOB.security_level == SEC_LEVEL_RED || GLOB.security_level == SEC_LEVEL_DELTA
|
||||
var/emergency = GLOB.security_level >= SEC_LEVEL_RED
|
||||
var/nightshift = FALSE
|
||||
if (!emergency)
|
||||
var/time = station_time()
|
||||
nightshift = time < nightshift_end_time || time > nightshift_start_time
|
||||
|
||||
var/announcing = TRUE
|
||||
if(nightshift && red_or_delta)
|
||||
nightshift = FALSE
|
||||
if(high_security_mode && !red_or_delta)
|
||||
if(high_security_mode && !emergency)
|
||||
high_security_mode = FALSE
|
||||
priority_announce("Restoring night lighting configuration to normal operation.", sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement")
|
||||
announce("Restoring night lighting configuration to normal operation.")
|
||||
announcing = FALSE
|
||||
else if(!high_security_mode && red_or_delta)
|
||||
else if(!high_security_mode && emergency)
|
||||
high_security_mode = TRUE
|
||||
priority_announce("Night lighting disabled: Station is in a state of emergency.", sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement")
|
||||
announce("Night lighting disabled: Station is in a state of emergency.")
|
||||
announcing = FALSE
|
||||
|
||||
if((nightshift_active != nightshift) || force_set)
|
||||
nightshift? activate_nightshift(announcing) : deactivate_nightshift(announcing)
|
||||
update_nightshift(nightshift, announcing)
|
||||
|
||||
/datum/controller/subsystem/nightshift/proc/activate_nightshift(announce = TRUE)
|
||||
if(!nightshift_active)
|
||||
if(announce)
|
||||
priority_announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.", sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement")
|
||||
nightshift_active = TRUE
|
||||
var/list/area/affected = return_nightshift_area_types()
|
||||
for(var/i in affected)
|
||||
var/area/A = locate(i) in GLOB.sortedAreas
|
||||
for(var/obj/machinery/power/apc/APC in A)
|
||||
APC.set_nightshift(TRUE)
|
||||
/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE)
|
||||
nightshift_active = active
|
||||
if(announce)
|
||||
if (active)
|
||||
announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.")
|
||||
else
|
||||
announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.")
|
||||
for(var/A in GLOB.apcs_list)
|
||||
var/obj/machinery/power/apc/APC = A
|
||||
if (APC.area && (APC.area.type in GLOB.the_station_areas))
|
||||
APC.set_nightshift(active)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/nightshift/proc/deactivate_nightshift(announce = TRUE)
|
||||
if(nightshift_active)
|
||||
if(announce)
|
||||
priority_announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.", sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement")
|
||||
nightshift_active = FALSE
|
||||
var/list/area/affected = return_nightshift_area_types()
|
||||
for(var/i in affected)
|
||||
var/area/A = locate(i) in GLOB.sortedAreas
|
||||
for(var/obj/machinery/power/apc/APC in A)
|
||||
APC.set_nightshift(FALSE)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/nightshift/proc/return_nightshift_area_types()
|
||||
return GLOB.the_station_areas.Copy()
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#define PING_BUFFER_TIME 25
|
||||
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
wait = 6
|
||||
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
priority = 10
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/ping/Initialize()
|
||||
if (config.hub)
|
||||
world.visibility = 1
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
var/round_started = Master.round_started
|
||||
var/list/currentrun = src.currentrun
|
||||
while (length(currentrun))
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if(round_started && C.is_afk(INACTIVITY_KICK))
|
||||
if(!istype(C.mob, /mob/dead))
|
||||
log_access("AFK: [key_name(C)]")
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
|
||||
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
|
||||
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
currentrun = null
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
@@ -1,6 +1,6 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(fields)
|
||||
name = "Fields"
|
||||
wait = 2
|
||||
priority = FIRE_PRIORUTY_FIELDS
|
||||
priority = FIRE_PRIORITY_FIELDS
|
||||
flags = SS_KEEP_TIMING | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
SUBSYSTEM_DEF(research)
|
||||
name = "Research"
|
||||
flags = SS_KEEP_TIMING
|
||||
priority = FIRE_PRIORITY_RESEARCH
|
||||
wait = 10
|
||||
init_order = INIT_ORDER_RESEARCH
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#define SSBELLIES_PROCESSED 1
|
||||
#define SSBELLIES_IGNORED 2
|
||||
|
||||
//
|
||||
// Bellies subsystem - Process vore bellies
|
||||
//
|
||||
|
||||
SUBSYSTEM_DEF(bellies)
|
||||
name = "Bellies"
|
||||
priority = 5
|
||||
wait = 1 SECONDS
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
||||
|
||||
var/static/list/belly_list = list()
|
||||
var/list/currentrun = list()
|
||||
var/ignored_bellies = 0
|
||||
|
||||
/datum/controller/subsystem/bellies/stat_entry()
|
||||
..("#: [belly_list.len] | P: [ignored_bellies]")
|
||||
|
||||
/datum/controller/subsystem/bellies/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
ignored_bellies = 0
|
||||
src.currentrun = belly_list.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
var/times_fired = src.times_fired
|
||||
while(currentrun.len)
|
||||
var/obj/belly/B = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
|
||||
if(QDELETED(B))
|
||||
belly_list -= B
|
||||
else
|
||||
if(B.process_belly(times_fired,wait) == SSBELLIES_IGNORED)
|
||||
ignored_bellies++
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
+48
-1
@@ -11,6 +11,7 @@
|
||||
var/processing = FALSE
|
||||
var/obj/screen/movable/action_button/button = null
|
||||
var/buttontooltipstyle = ""
|
||||
var/transparent_when_unavailable = TRUE
|
||||
|
||||
var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon
|
||||
@@ -124,7 +125,7 @@
|
||||
ApplyIcon(button, force)
|
||||
|
||||
if(!IsAvailable())
|
||||
button.color = rgb(128,0,0,128)
|
||||
button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0)
|
||||
else
|
||||
button.color = rgb(255,255,255,255)
|
||||
return 1
|
||||
@@ -572,6 +573,52 @@
|
||||
call(target, procname)(usr)
|
||||
return 1
|
||||
|
||||
|
||||
//Preset for an action with a cooldown
|
||||
|
||||
/datum/action/cooldown
|
||||
check_flags = 0
|
||||
transparent_when_unavailable = FALSE
|
||||
var/cooldown_time = 0
|
||||
var/next_use_time = 0
|
||||
|
||||
/datum/action/cooldown/New()
|
||||
..()
|
||||
button.maptext = ""
|
||||
button.maptext_x = 8
|
||||
button.maptext_y = 0
|
||||
button.maptext_width = 24
|
||||
button.maptext_height = 12
|
||||
|
||||
/datum/action/cooldown/IsAvailable()
|
||||
return next_use_time <= world.time
|
||||
|
||||
/datum/action/cooldown/proc/StartCooldown()
|
||||
next_use_time = world.time + cooldown_time
|
||||
button.maptext = "<b>[round(cooldown_time/10, 0.1)]</b>"
|
||||
UpdateButtonIcon()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/datum/action/cooldown/process()
|
||||
if(!owner)
|
||||
button.maptext = ""
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
var/timeleft = max(next_use_time - world.time, 0)
|
||||
if(timeleft == 0)
|
||||
button.maptext = ""
|
||||
UpdateButtonIcon()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
button.maptext = "<b>[round(timeleft/10, 0.1)]</b>"
|
||||
|
||||
/datum/action/cooldown/Grant(mob/M)
|
||||
..()
|
||||
if(owner)
|
||||
UpdateButtonIcon()
|
||||
if(next_use_time > world.time)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
|
||||
//Stickmemes
|
||||
/datum/action/item_action/stickmen
|
||||
name = "Summon Stick Minions"
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
#define ABDUCTOR_MAX_TEAMS 4
|
||||
|
||||
/datum/antagonist/abductor
|
||||
name = "Abductor"
|
||||
roundend_category = "abductors"
|
||||
antagpanel_category = "Abductor"
|
||||
job_rank = ROLE_ABDUCTOR
|
||||
show_in_antagpanel = FALSE //should only show subtypes
|
||||
var/datum/team/abductor_team/team
|
||||
var/sub_role
|
||||
var/outfit
|
||||
var/landmark_type
|
||||
var/greet_text
|
||||
|
||||
|
||||
/datum/antagonist/abductor/agent
|
||||
name = "Abductor Agent"
|
||||
sub_role = "Agent"
|
||||
outfit = /datum/outfit/abductor/agent
|
||||
landmark_type = /obj/effect/landmark/abductor/agent
|
||||
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
|
||||
show_in_antagpanel = TRUE
|
||||
|
||||
/datum/antagonist/abductor/scientist
|
||||
name = "Abductor Scientist"
|
||||
sub_role = "Scientist"
|
||||
outfit = /datum/outfit/abductor/scientist
|
||||
landmark_type = /obj/effect/landmark/abductor/scientist
|
||||
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
|
||||
show_in_antagpanel = TRUE
|
||||
|
||||
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
team = new_team
|
||||
|
||||
/datum/antagonist/abductor/get_team()
|
||||
return team
|
||||
|
||||
/datum/antagonist/abductor/on_gain()
|
||||
SSticker.mode.abductors += owner
|
||||
owner.special_role = "[name] [sub_role]"
|
||||
owner.assigned_role = "[name] [sub_role]"
|
||||
owner.objectives += team.objectives
|
||||
finalize_abductor()
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/on_removal()
|
||||
SSticker.mode.abductors -= owner
|
||||
owner.objectives -= team.objectives
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
|
||||
owner.special_role = null
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/greet()
|
||||
to_chat(owner.current, "<span class='notice'>You are the [owner.special_role]!</span>")
|
||||
to_chat(owner.current, "<span class='notice'>With the help of your teammate, kidnap and experiment on station crew members!</span>")
|
||||
to_chat(owner.current, "<span class='notice'>[greet_text]</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/abductor/proc/finalize_abductor()
|
||||
//Equip
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.set_species(/datum/species/abductor)
|
||||
H.real_name = "[team.name] [sub_role]"
|
||||
H.equipOutfit(outfit)
|
||||
|
||||
//Teleport to ship
|
||||
for(var/obj/effect/landmark/abductor/LM in GLOB.landmarks_list)
|
||||
if(istype(LM, landmark_type) && LM.team_number == team.team_number)
|
||||
H.forceMove(LM.loc)
|
||||
break
|
||||
|
||||
SSticker.mode.update_abductor_icons_added(owner)
|
||||
|
||||
/datum/antagonist/abductor/scientist/finalize_abductor()
|
||||
..()
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
var/datum/species/abductor/A = H.dna.species
|
||||
A.scientist = TRUE
|
||||
|
||||
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/list/current_teams = list()
|
||||
for(var/datum/team/abductor_team/T in get_all_teams(/datum/team/abductor_team))
|
||||
current_teams[T.name] = T
|
||||
var/choice = input(admin,"Add to which team ?") as null|anything in (current_teams + "new team")
|
||||
if (choice == "new team")
|
||||
team = new
|
||||
else if(choice in current_teams)
|
||||
team = current_teams[choice]
|
||||
else
|
||||
return
|
||||
new_owner.add_antag_datum(src)
|
||||
log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
|
||||
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
|
||||
|
||||
/datum/antagonist/abductor/get_admin_commands()
|
||||
. = ..()
|
||||
.["Equip"] = CALLBACK(src,.proc/admin_equip)
|
||||
|
||||
/datum/antagonist/abductor/proc/admin_equip(mob/admin)
|
||||
if(!ishuman(owner.current))
|
||||
to_chat(admin, "<span class='warning'>This only works on humans!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
var/gear = alert(admin,"Agent or Scientist Gear","Gear","Agent","Scientist")
|
||||
if(gear)
|
||||
if(gear=="Agent")
|
||||
H.equipOutfit(/datum/outfit/abductor/agent)
|
||||
else
|
||||
H.equipOutfit(/datum/outfit/abductor/scientist)
|
||||
|
||||
/datum/team/abductor_team
|
||||
member_name = "abductor"
|
||||
var/team_number
|
||||
var/list/datum/mind/abductees = list()
|
||||
var/static/team_count = 1
|
||||
|
||||
/datum/team/abductor_team/New()
|
||||
..()
|
||||
team_number = team_count++
|
||||
name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
|
||||
add_objective(new/datum/objective/experiment)
|
||||
|
||||
/datum/team/abductor_team/is_solo()
|
||||
return FALSE
|
||||
|
||||
/datum/team/abductor_team/proc/add_objective(datum/objective/O)
|
||||
O.team = src
|
||||
O.update_explanation_text()
|
||||
objectives += O
|
||||
|
||||
/datum/team/abductor_team/roundend_report()
|
||||
var/list/result = list()
|
||||
|
||||
var/won = TRUE
|
||||
for(var/datum/objective/O in objectives)
|
||||
if(!O.check_completion())
|
||||
won = FALSE
|
||||
if(won)
|
||||
result += "<span class='greentext big'>[name] team fulfilled its mission!</span>"
|
||||
else
|
||||
result += "<span class='redtext big'>[name] team failed its mission.</span>"
|
||||
|
||||
result += "<span class='header'>The abductors of [name] were:</span>"
|
||||
for(var/datum/mind/abductor_mind in members)
|
||||
result += printplayer(abductor_mind)
|
||||
result += printobjectives(abductor_mind)
|
||||
|
||||
return result.Join("<br>")
|
||||
|
||||
/datum/antagonist/abductee
|
||||
name = "Abductee"
|
||||
roundend_category = "abductees"
|
||||
antagpanel_category = "Abductee"
|
||||
|
||||
/datum/antagonist/abductee/on_gain()
|
||||
give_objective()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/abductee/greet()
|
||||
to_chat(owner, "<span class='warning'><b>Your mind snaps!</b></span>")
|
||||
to_chat(owner, "<big><span class='warning'><b>You can't remember how you got here...</b></span></big>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/abductee/proc/give_objective()
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(istype(H))
|
||||
H.gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
|
||||
var/datum/objective/abductee/O = new objtype()
|
||||
objectives += O
|
||||
owner.objectives += objectives
|
||||
|
||||
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
|
||||
SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner)
|
||||
|
||||
/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override)
|
||||
SSticker.mode.update_abductor_icons_removed(mob_override ? mob_override.mind : owner)
|
||||
@@ -1,246 +0,0 @@
|
||||
GLOBAL_LIST_EMPTY(antagonists)
|
||||
|
||||
/datum/antagonist
|
||||
var/name = "Antagonist"
|
||||
var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section
|
||||
var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report
|
||||
var/datum/mind/owner //Mind that owns this datum
|
||||
var/silent = FALSE //Silent will prevent the gain/lose texts to show
|
||||
var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
|
||||
var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
|
||||
var/delete_on_mind_deletion = TRUE
|
||||
var/job_rank
|
||||
var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted.
|
||||
var/list/objectives = list()
|
||||
var/antag_memory = ""//These will be removed with antag datum
|
||||
|
||||
//Antag panel properties
|
||||
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
|
||||
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
|
||||
|
||||
/datum/antagonist/New()
|
||||
GLOB.antagonists += src
|
||||
typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
|
||||
|
||||
/datum/antagonist/Destroy()
|
||||
GLOB.antagonists -= src
|
||||
if(owner)
|
||||
LAZYREMOVE(owner.antag_datums, src)
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/proc/can_be_owned(datum/mind/new_owner)
|
||||
. = TRUE
|
||||
var/datum/mind/tested = new_owner || owner
|
||||
if(tested.has_antag_datum(type))
|
||||
return FALSE
|
||||
for(var/i in tested.antag_datums)
|
||||
var/datum/antagonist/A = i
|
||||
if(is_type_in_typecache(src, A.typecache_datum_blacklist))
|
||||
return FALSE
|
||||
|
||||
//This will be called in add_antag_datum before owner assignment.
|
||||
//Should return antag datum without owner.
|
||||
/datum/antagonist/proc/specialization(datum/mind/new_owner)
|
||||
return src
|
||||
|
||||
/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
remove_innate_effects(old_body)
|
||||
apply_innate_effects(new_body)
|
||||
|
||||
//This handles the application of antag huds/special abilities
|
||||
/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override)
|
||||
return
|
||||
|
||||
//This handles the removal of antag huds/special abilities
|
||||
/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
|
||||
return
|
||||
|
||||
//Assign default team and creates one for one of a kind team antagonists
|
||||
/datum/antagonist/proc/create_team(datum/team/team)
|
||||
return
|
||||
|
||||
//Proc called when the datum is given to a mind.
|
||||
/datum/antagonist/proc/on_gain()
|
||||
if(owner && owner.current)
|
||||
if(!silent)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
|
||||
/datum/antagonist/proc/is_banned(mob/M)
|
||||
if(!M)
|
||||
return FALSE
|
||||
. = (jobban_isbanned(M, ROLE_SYNDICATE) || (job_rank && jobban_isbanned(M,job_rank)))
|
||||
|
||||
/datum/antagonist/proc/replace_banned_player()
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current)
|
||||
if(LAZYLEN(candidates))
|
||||
var/client/C = pick(candidates)
|
||||
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
|
||||
owner.current.ghostize(0)
|
||||
owner.current.key = C.key
|
||||
|
||||
/datum/antagonist/proc/on_removal()
|
||||
remove_innate_effects()
|
||||
if(owner)
|
||||
LAZYREMOVE(owner.antag_datums, src)
|
||||
if(!silent && owner.current)
|
||||
farewell()
|
||||
var/datum/team/team = get_team()
|
||||
if(team)
|
||||
team.remove_member(owner)
|
||||
qdel(src)
|
||||
|
||||
/datum/antagonist/proc/greet()
|
||||
return
|
||||
|
||||
/datum/antagonist/proc/farewell()
|
||||
return
|
||||
|
||||
//Returns the team antagonist belongs to if any.
|
||||
/datum/antagonist/proc/get_team()
|
||||
return
|
||||
|
||||
//Individual roundend report
|
||||
/datum/antagonist/proc/roundend_report()
|
||||
var/list/report = list()
|
||||
|
||||
if(!owner)
|
||||
CRASH("antagonist datum without owner")
|
||||
|
||||
report += printplayer(owner)
|
||||
|
||||
var/objectives_complete = TRUE
|
||||
if(owner.objectives.len)
|
||||
report += printobjectives(owner)
|
||||
for(var/datum/objective/objective in owner.objectives)
|
||||
if(!objective.check_completion())
|
||||
objectives_complete = FALSE
|
||||
break
|
||||
|
||||
if(owner.objectives.len == 0 || objectives_complete)
|
||||
report += "<span class='greentext big'>The [name] was successful!</span>"
|
||||
else
|
||||
report += "<span class='redtext big'>The [name] has failed!</span>"
|
||||
|
||||
return report.Join("<br>")
|
||||
|
||||
//Displayed at the start of roundend_category section, default to roundend_category header
|
||||
/datum/antagonist/proc/roundend_report_header()
|
||||
return "<span class='header'>The [roundend_category] were:</span><br>"
|
||||
|
||||
//Displayed at the end of roundend_category section
|
||||
/datum/antagonist/proc/roundend_report_footer()
|
||||
return
|
||||
|
||||
|
||||
//ADMIN TOOLS
|
||||
|
||||
//Called when using admin tools to give antag status
|
||||
/datum/antagonist/proc/admin_add(datum/mind/new_owner,mob/admin)
|
||||
message_admins("[key_name_admin(admin)] made [new_owner.current] into [name].")
|
||||
log_admin("[key_name(admin)] made [new_owner.current] into [name].")
|
||||
new_owner.add_antag_datum(src)
|
||||
|
||||
//Called when removing antagonist using admin tools
|
||||
/datum/antagonist/proc/admin_remove(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
message_admins("[key_name_admin(user)] has removed [name] antagonist status from [owner.current].")
|
||||
log_admin("[key_name(user)] has removed [name] antagonist status from [owner.current].")
|
||||
on_removal()
|
||||
|
||||
//gamemode/proc/is_mode_antag(antagonist/A) => TRUE/FALSE
|
||||
|
||||
//Additional data to display in antagonist panel section
|
||||
//nuke disk code, genome count, etc
|
||||
/datum/antagonist/proc/antag_panel_data()
|
||||
return ""
|
||||
|
||||
/datum/antagonist/proc/enabled_in_preferences(datum/mind/M)
|
||||
if(job_rank)
|
||||
if(M.current && M.current.client && (job_rank in M.current.client.prefs.be_special))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// List if ["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution
|
||||
/datum/antagonist/proc/get_admin_commands()
|
||||
. = list()
|
||||
|
||||
/datum/antagonist/Topic(href,href_list)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
//Antag memory edit
|
||||
if (href_list["memory_edit"])
|
||||
edit_memory(usr)
|
||||
owner.traitor_panel()
|
||||
return
|
||||
|
||||
//Some commands might delete/modify this datum clearing or changing owner
|
||||
var/datum/mind/persistent_owner = owner
|
||||
|
||||
var/commands = get_admin_commands()
|
||||
for(var/admin_command in commands)
|
||||
if(href_list["command"] == admin_command)
|
||||
var/datum/callback/C = commands[admin_command]
|
||||
C.Invoke(usr)
|
||||
persistent_owner.traitor_panel()
|
||||
return
|
||||
|
||||
/datum/antagonist/proc/edit_memory(mob/user)
|
||||
var/new_memo = copytext(trim(input(user,"Write new memory", "Memory", antag_memory) as null|message),1,MAX_MESSAGE_LEN)
|
||||
if (isnull(new_memo))
|
||||
return
|
||||
antag_memory = new_memo
|
||||
|
||||
//Should probably be on ticker or job ss ?
|
||||
/proc/get_antagonists(antag_type,specific = FALSE)
|
||||
. = list()
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
if(!A.owner)
|
||||
continue
|
||||
if(!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type)
|
||||
. += A.owner
|
||||
|
||||
//This datum will autofill the name with special_role
|
||||
//Used as placeholder for minor antagonists, please create proper datums for these
|
||||
/datum/antagonist/auto_custom
|
||||
show_in_antagpanel = FALSE
|
||||
antagpanel_category = "Other"
|
||||
|
||||
/datum/antagonist/auto_custom/on_gain()
|
||||
..()
|
||||
name = owner.special_role
|
||||
//Add all objectives not already owned by other datums to this one.
|
||||
var/list/already_registered_objectives = list()
|
||||
for(var/datum/antagonist/A in owner.antag_datums)
|
||||
if(A == src)
|
||||
continue
|
||||
else
|
||||
already_registered_objectives |= A.objectives
|
||||
objectives = owner.objectives - already_registered_objectives
|
||||
|
||||
/datum/antagonist/auto_custom/antag_listing_name()
|
||||
return ..() + "([name])"
|
||||
|
||||
//This one is created by admin tools for custom objectives
|
||||
/datum/antagonist/custom
|
||||
antagpanel_category = "Custom"
|
||||
|
||||
/datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist")
|
||||
if(custom_name)
|
||||
name = custom_name
|
||||
else
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/antagonist/custom/antag_listing_name()
|
||||
return ..() + "([name])"
|
||||
@@ -1,67 +0,0 @@
|
||||
/datum/antagonist/blob
|
||||
name = "Blob"
|
||||
roundend_category = "blobs"
|
||||
antagpanel_category = "Blob"
|
||||
job_rank = ROLE_BLOB
|
||||
|
||||
var/datum/action/innate/blobpop/pop_action
|
||||
var/starting_points_human_blob = 60
|
||||
var/point_rate_human_blob = 2
|
||||
|
||||
/datum/antagonist/blob/roundend_report()
|
||||
var/basic_report = ..()
|
||||
//Display max blobpoints for blebs that lost
|
||||
if(isovermind(owner.current)) //embarrasing if not
|
||||
var/mob/camera/blob/overmind = owner.current
|
||||
if(!overmind.victory_in_progress) //if it won this doesn't really matter
|
||||
var/point_report = "<br><b>[owner.name]</b> took over [overmind.max_count] tiles at the height of its growth."
|
||||
return basic_report+point_report
|
||||
return basic_report
|
||||
|
||||
/datum/antagonist/blob/greet()
|
||||
if(!isovermind(owner.current))
|
||||
to_chat(owner,"<span class='userdanger'>You feel bloated.</span>")
|
||||
|
||||
/datum/antagonist/blob/on_gain()
|
||||
create_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/blob/proc/create_objectives()
|
||||
var/datum/objective/blob_takeover/main = new
|
||||
main.owner = owner
|
||||
objectives += main
|
||||
owner.objectives |= objectives
|
||||
|
||||
/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override)
|
||||
if(!isovermind(owner.current))
|
||||
if(!pop_action)
|
||||
pop_action = new
|
||||
pop_action.Grant(owner.current)
|
||||
|
||||
/datum/objective/blob_takeover
|
||||
explanation_text = "Reach critical mass!"
|
||||
|
||||
//Non-overminds get this on blob antag assignment
|
||||
/datum/action/innate/blobpop
|
||||
name = "Pop"
|
||||
desc = "Unleash the blob"
|
||||
icon_icon = 'icons/mob/blob.dmi'
|
||||
button_icon_state = "blob"
|
||||
|
||||
/datum/action/innate/blobpop/Activate()
|
||||
var/mob/old_body = owner
|
||||
var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob)
|
||||
if(!blobtag)
|
||||
Remove()
|
||||
return
|
||||
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob)
|
||||
owner.mind.transfer_to(B)
|
||||
old_body.gib()
|
||||
B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE)
|
||||
|
||||
/datum/antagonist/blob/antag_listing_status()
|
||||
. = ..()
|
||||
if(owner && owner.current)
|
||||
var/mob/camera/blob/B = owner.current
|
||||
if(istype(B))
|
||||
. += "(Progress: [B.blobs_legit.len]/[B.blobwincount])"
|
||||
@@ -1,154 +0,0 @@
|
||||
/datum/antagonist/brother
|
||||
name = "Brother"
|
||||
antagpanel_category = "Brother"
|
||||
job_rank = ROLE_BROTHER
|
||||
var/special_role = ROLE_BROTHER
|
||||
var/datum/team/brother_team/team
|
||||
|
||||
/datum/antagonist/brother/create_team(datum/team/brother_team/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
team = new_team
|
||||
|
||||
/datum/antagonist/brother/get_team()
|
||||
return team
|
||||
|
||||
/datum/antagonist/brother/on_gain()
|
||||
SSticker.mode.brothers += owner
|
||||
objectives += team.objectives
|
||||
owner.objectives += objectives
|
||||
owner.special_role = special_role
|
||||
finalize_brother()
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/brother/on_removal()
|
||||
SSticker.mode.brothers -= owner
|
||||
owner.objectives -= objectives
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
|
||||
owner.special_role = null
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/brother/proc/give_meeting_area()
|
||||
if(!owner.current || !team || !team.meeting_area)
|
||||
return
|
||||
to_chat(owner.current, "<B>Your designated meeting area:</B> [team.meeting_area]")
|
||||
antag_memory += "<b>Meeting Area</b>: [team.meeting_area]<br>"
|
||||
|
||||
/datum/antagonist/brother/greet()
|
||||
var/brother_text = ""
|
||||
var/list/brothers = team.members - owner
|
||||
for(var/i = 1 to brothers.len)
|
||||
var/datum/mind/M = brothers[i]
|
||||
brother_text += M.name
|
||||
if(i == brothers.len - 1)
|
||||
brother_text += " and "
|
||||
else if(i != brothers.len)
|
||||
brother_text += ", "
|
||||
to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role] of [brother_text].</font></B>")
|
||||
to_chat(owner.current, "The Syndicate only accepts those that have proven themself. Prove yourself and prove your [team.member_name]s by completing your objectives together!")
|
||||
owner.announce_objectives()
|
||||
give_meeting_area()
|
||||
|
||||
/datum/antagonist/brother/proc/finalize_brother()
|
||||
SSticker.mode.update_brother_icons_added(owner)
|
||||
|
||||
/datum/antagonist/brother/admin_add(datum/mind/new_owner,mob/admin)
|
||||
//show list of possible brothers
|
||||
var/list/candidates = list()
|
||||
for(var/mob/living/L in GLOB.alive_mob_list)
|
||||
if(!L.mind || L.mind == new_owner || !can_be_owned(L.mind))
|
||||
continue
|
||||
candidates[L.mind.name] = L.mind
|
||||
|
||||
var/choice = input(admin,"Choose the blood brother.", "Brother") as null|anything in candidates
|
||||
if(!choice)
|
||||
return
|
||||
var/datum/mind/bro = candidates[choice]
|
||||
var/datum/team/brother_team/T = new
|
||||
T.add_member(new_owner)
|
||||
T.add_member(bro)
|
||||
T.pick_meeting_area()
|
||||
T.forge_brother_objectives()
|
||||
new_owner.add_antag_datum(/datum/antagonist/brother,T)
|
||||
bro.add_antag_datum(/datum/antagonist/brother, T)
|
||||
T.update_name()
|
||||
message_admins("[key_name_admin(admin)] made [new_owner.current] and [bro.current] into blood brothers.")
|
||||
log_admin("[key_name(admin)] made [new_owner.current] and [bro.current] into blood brothers.")
|
||||
|
||||
/datum/team/brother_team
|
||||
name = "brotherhood"
|
||||
member_name = "blood brother"
|
||||
var/meeting_area
|
||||
var/static/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
|
||||
|
||||
/datum/team/brother_team/is_solo()
|
||||
return FALSE
|
||||
|
||||
/datum/team/brother_team/proc/pick_meeting_area()
|
||||
meeting_area = pick(meeting_areas)
|
||||
meeting_areas -= meeting_area
|
||||
|
||||
/datum/team/brother_team/proc/update_name()
|
||||
var/list/last_names = list()
|
||||
for(var/datum/mind/M in members)
|
||||
var/list/split_name = splittext(M.name," ")
|
||||
last_names += split_name[split_name.len]
|
||||
|
||||
name = last_names.Join(" & ")
|
||||
|
||||
/datum/team/brother_team/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
parts += "<span class='header'>The blood brothers of [name] were:</span>"
|
||||
for(var/datum/mind/M in members)
|
||||
parts += printplayer(M)
|
||||
var/win = TRUE
|
||||
var/objective_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='greentext'><B>Success!</span>"
|
||||
else
|
||||
parts += "<B>Objective #[objective_count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
objective_count++
|
||||
if(win)
|
||||
parts += "<span class='greentext'>The blood brothers were successful!</span>"
|
||||
else
|
||||
parts += "<span class='redtext'>The blood brothers have failed!</span>"
|
||||
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
|
||||
/datum/team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE)
|
||||
O.team = src
|
||||
if(needs_target)
|
||||
O.find_target()
|
||||
O.update_explanation_text()
|
||||
objectives += O
|
||||
|
||||
/datum/team/brother_team/proc/forge_brother_objectives()
|
||||
objectives = list()
|
||||
var/is_hijacker = prob(10)
|
||||
for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker))
|
||||
forge_single_objective()
|
||||
if(is_hijacker)
|
||||
if(!locate(/datum/objective/hijack) in objectives)
|
||||
add_objective(new/datum/objective/hijack)
|
||||
else if(!locate(/datum/objective/escape) in objectives)
|
||||
add_objective(new/datum/objective/escape)
|
||||
|
||||
/datum/team/brother_team/proc/forge_single_objective()
|
||||
if(prob(50))
|
||||
if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len))
|
||||
add_objective(new/datum/objective/destroy, TRUE)
|
||||
else if(prob(30))
|
||||
add_objective(new/datum/objective/maroon, TRUE)
|
||||
else
|
||||
add_objective(new/datum/objective/assassinate, TRUE)
|
||||
else
|
||||
add_objective(new/datum/objective/steal, TRUE)
|
||||
|
||||
/datum/team/brother_team/antag_listing_name()
|
||||
return "[name] blood brothers"
|
||||
@@ -1,545 +0,0 @@
|
||||
#define LING_FAKEDEATH_TIME 400 //40 seconds
|
||||
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead.
|
||||
#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob
|
||||
|
||||
/datum/antagonist/changeling
|
||||
name = "Changeling"
|
||||
roundend_category = "changelings"
|
||||
antagpanel_category = "Changeling"
|
||||
job_rank = ROLE_CHANGELING
|
||||
|
||||
var/you_are_greet = TRUE
|
||||
var/give_objectives = TRUE
|
||||
var/team_mode = FALSE //Should assign team objectives ?
|
||||
|
||||
//Changeling Stuff
|
||||
|
||||
var/list/stored_profiles = list() //list of datum/changelingprofile
|
||||
var/datum/changelingprofile/first_prof = null
|
||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
var/chem_charges = 20
|
||||
var/chem_storage = 75
|
||||
var/chem_recharge_rate = 1
|
||||
var/chem_recharge_slowdown = 0
|
||||
var/sting_range = 2
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/islinking = 0
|
||||
var/geneticpoints = 10
|
||||
var/purchasedpowers = list()
|
||||
var/mimicing = ""
|
||||
var/canrespec = 0
|
||||
var/changeling_speak = 0
|
||||
var/datum/dna/chosen_dna
|
||||
var/obj/effect/proc_holder/changeling/sting/chosen_sting
|
||||
var/datum/cellular_emporium/cellular_emporium
|
||||
var/datum/action/innate/cellular_emporium/emporium_action
|
||||
|
||||
// wip stuff
|
||||
var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE)
|
||||
|
||||
|
||||
/datum/antagonist/changeling/Destroy()
|
||||
QDEL_NULL(cellular_emporium)
|
||||
QDEL_NULL(emporium_action)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/proc/generate_name()
|
||||
var/honorific
|
||||
if(owner.current.gender == FEMALE)
|
||||
honorific = "Ms."
|
||||
else
|
||||
honorific = "Mr."
|
||||
if(GLOB.possible_changeling_IDs.len)
|
||||
changelingID = pick(GLOB.possible_changeling_IDs)
|
||||
GLOB.possible_changeling_IDs -= changelingID
|
||||
changelingID = "[honorific] [changelingID]"
|
||||
else
|
||||
changelingID = "[honorific] [rand(1,999)]"
|
||||
|
||||
/datum/antagonist/changeling/proc/create_actions()
|
||||
cellular_emporium = new(src)
|
||||
emporium_action = new(cellular_emporium)
|
||||
|
||||
/datum/antagonist/changeling/on_gain()
|
||||
generate_name()
|
||||
create_actions()
|
||||
reset_powers()
|
||||
create_initial_profile()
|
||||
if(give_objectives)
|
||||
if(team_mode)
|
||||
forge_team_objectives()
|
||||
forge_objectives()
|
||||
remove_clownmut()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/on_removal()
|
||||
//We'll be using this from now on
|
||||
var/mob/living/carbon/C = owner.current
|
||||
if(istype(C))
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B && (B.decoy_override != initial(B.decoy_override)))
|
||||
B.vital = TRUE
|
||||
B.decoy_override = FALSE
|
||||
remove_changeling_powers()
|
||||
owner.objectives -= objectives
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_clownmut()
|
||||
if (owner)
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(istype(H) && owner.assigned_role == "Clown")
|
||||
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/changeling/proc/reset_properties()
|
||||
changeling_speak = 0
|
||||
chosen_sting = null
|
||||
geneticpoints = initial(geneticpoints)
|
||||
sting_range = initial(sting_range)
|
||||
chem_storage = initial(chem_storage)
|
||||
chem_recharge_rate = initial(chem_recharge_rate)
|
||||
chem_charges = min(chem_charges, chem_storage)
|
||||
chem_recharge_slowdown = initial(chem_recharge_slowdown)
|
||||
mimicing = ""
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_changeling_powers()
|
||||
if(ishuman(owner.current) || ismonkey(owner.current))
|
||||
reset_properties()
|
||||
for(var/obj/effect/proc_holder/changeling/p in purchasedpowers)
|
||||
if(p.always_keep)
|
||||
continue
|
||||
purchasedpowers -= p
|
||||
p.on_refund(owner.current)
|
||||
|
||||
//MOVE THIS
|
||||
if(owner.current.hud_used)
|
||||
owner.current.hud_used.lingstingdisplay.icon_state = null
|
||||
owner.current.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/datum/antagonist/changeling/proc/reset_powers()
|
||||
if(purchasedpowers)
|
||||
remove_changeling_powers()
|
||||
//Repurchase free powers.
|
||||
for(var/path in all_powers)
|
||||
var/obj/effect/proc_holder/changeling/S = new path()
|
||||
if(!S.dna_cost)
|
||||
if(!has_sting(S))
|
||||
purchasedpowers += S
|
||||
S.on_purchase(owner.current,TRUE)
|
||||
|
||||
/datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
|
||||
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
|
||||
if(initial(power.name) == P.name)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/purchase_power(sting_name)
|
||||
var/obj/effect/proc_holder/changeling/thepower = null
|
||||
|
||||
for(var/path in all_powers)
|
||||
var/obj/effect/proc_holder/changeling/S = path
|
||||
if(initial(S.name) == sting_name)
|
||||
thepower = new path()
|
||||
break
|
||||
|
||||
if(!thepower)
|
||||
to_chat(owner.current, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
||||
return
|
||||
|
||||
if(absorbedcount < thepower.req_dna)
|
||||
to_chat(owner.current, "We lack the energy to evolve this ability!")
|
||||
return
|
||||
|
||||
if(has_sting(thepower))
|
||||
to_chat(owner.current, "We have already evolved this ability!")
|
||||
return
|
||||
|
||||
if(thepower.dna_cost < 0)
|
||||
to_chat(owner.current, "We cannot evolve this ability.")
|
||||
return
|
||||
|
||||
if(geneticpoints < thepower.dna_cost)
|
||||
to_chat(owner.current, "We have reached our capacity for abilities.")
|
||||
return
|
||||
|
||||
if(owner.current.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
||||
to_chat(owner.current, "We lack the energy to evolve new abilities right now.")
|
||||
return
|
||||
|
||||
geneticpoints -= thepower.dna_cost
|
||||
purchasedpowers += thepower
|
||||
thepower.on_purchase(owner.current)
|
||||
|
||||
/datum/antagonist/changeling/proc/readapt()
|
||||
if(!ishuman(owner.current))
|
||||
to_chat(owner.current, "<span class='danger'>We can't remove our evolutions in this form!</span>")
|
||||
return
|
||||
if(canrespec)
|
||||
to_chat(owner.current, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||
reset_powers()
|
||||
canrespec = 0
|
||||
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt")
|
||||
return 1
|
||||
else
|
||||
to_chat(owner.current, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
||||
return 0
|
||||
|
||||
//Called in life()
|
||||
/datum/antagonist/changeling/proc/regenerate()
|
||||
var/mob/living/carbon/the_ling = owner.current
|
||||
if(istype(the_ling))
|
||||
emporium_action.Grant(the_ling)
|
||||
if(the_ling.stat == DEAD)
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
|
||||
geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
|
||||
else //not dead? no chem/geneticdamage caps.
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/get_dna(dna_owner)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(dna_owner == prof.name)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/has_dna(datum/dna/tDNA)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(tDNA.is_same_as(prof.dna))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/antagonist/changeling/proc/can_absorb_dna(mob/living/carbon/human/target, var/verbose=1)
|
||||
var/mob/living/carbon/user = owner.current
|
||||
if(!istype(user))
|
||||
return
|
||||
if(stored_profiles.len)
|
||||
var/datum/changelingprofile/prof = stored_profiles[1]
|
||||
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
if(NO_DNA_COPY in target.dna.species.species_traits)
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
if((target.has_disability(DISABILITY_NOCLONE)) || (target.has_disability(DISABILITY_NOCLONE)))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
||||
return
|
||||
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
||||
return
|
||||
if(has_dna(target.dna))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
|
||||
return
|
||||
if(!target.has_dna())
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/create_profile(mob/living/carbon/human/H, protect = 0)
|
||||
var/datum/changelingprofile/prof = new
|
||||
|
||||
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
|
||||
var/datum/dna/new_dna = new H.dna.type
|
||||
H.dna.copy_dna(new_dna)
|
||||
prof.dna = new_dna
|
||||
prof.name = H.real_name
|
||||
prof.protected = protect
|
||||
|
||||
prof.underwear = H.underwear
|
||||
prof.undershirt = H.undershirt
|
||||
prof.socks = H.socks
|
||||
|
||||
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
||||
for(var/slot in slots)
|
||||
if(slot in H.vars)
|
||||
var/obj/item/I = H.vars[slot]
|
||||
if(!I)
|
||||
continue
|
||||
prof.name_list[slot] = I.name
|
||||
prof.appearance_list[slot] = I.appearance
|
||||
prof.flags_cover_list[slot] = I.flags_cover
|
||||
prof.item_color_list[slot] = I.item_color
|
||||
prof.item_state_list[slot] = I.item_state
|
||||
prof.exists_list[slot] = 1
|
||||
else
|
||||
continue
|
||||
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/add_profile(datum/changelingprofile/prof)
|
||||
if(stored_profiles.len > dna_max)
|
||||
if(!push_out_profile())
|
||||
return
|
||||
|
||||
if(!first_prof)
|
||||
first_prof = prof
|
||||
|
||||
stored_profiles += prof
|
||||
absorbedcount++
|
||||
|
||||
/datum/antagonist/changeling/proc/add_new_profile(mob/living/carbon/human/H, protect = 0)
|
||||
var/datum/changelingprofile/prof = create_profile(H, protect)
|
||||
add_profile(prof)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(H.real_name == prof.name)
|
||||
if(prof.protected && !force)
|
||||
continue
|
||||
stored_profiles -= prof
|
||||
qdel(prof)
|
||||
|
||||
/datum/antagonist/changeling/proc/get_profile_to_remove()
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(!prof.protected)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/push_out_profile()
|
||||
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
||||
if(removeprofile)
|
||||
stored_profiles -= removeprofile
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/create_initial_profile()
|
||||
var/mob/living/carbon/C = owner.current //only carbons have dna now, so we have to typecaste
|
||||
if(ishuman(C))
|
||||
add_new_profile(C)
|
||||
|
||||
/datum/antagonist/changeling/apply_innate_effects()
|
||||
//Brains optional.
|
||||
var/mob/living/carbon/C = owner.current
|
||||
if(istype(C))
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
update_changeling_icons_added()
|
||||
return
|
||||
|
||||
/datum/antagonist/changeling/remove_innate_effects()
|
||||
update_changeling_icons_removed()
|
||||
return
|
||||
|
||||
|
||||
/datum/antagonist/changeling/greet()
|
||||
if (you_are_greet)
|
||||
to_chat(owner.current, "<span class='boldannounce'>You are [changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
|
||||
to_chat(owner.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
|
||||
to_chat(owner.current, "<b>You must complete the following tasks:</b>")
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/changeling/farewell()
|
||||
to_chat(owner.current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
|
||||
|
||||
/datum/antagonist/changeling/proc/forge_team_objectives()
|
||||
if(GLOB.changeling_team_objective_type)
|
||||
var/datum/objective/changeling_team_objective/team_objective = new GLOB.changeling_team_objective_type
|
||||
team_objective.owner = owner
|
||||
objectives += team_objective
|
||||
return
|
||||
|
||||
/datum/antagonist/changeling/proc/forge_objectives()
|
||||
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
|
||||
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
||||
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
||||
|
||||
var/escape_objective_possible = TRUE
|
||||
|
||||
//if there's a team objective, check if it's compatible with escape objectives
|
||||
for(var/datum/objective/changeling_team_objective/CTO in objectives)
|
||||
if(!CTO.escape_objective_compatible)
|
||||
escape_objective_possible = FALSE
|
||||
break
|
||||
|
||||
var/datum/objective/absorb/absorb_objective = new
|
||||
absorb_objective.owner = owner
|
||||
absorb_objective.gen_amount_goal(6, 8)
|
||||
objectives += absorb_objective
|
||||
|
||||
if(prob(60))
|
||||
if(prob(85))
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
objectives += steal_objective
|
||||
else
|
||||
var/datum/objective/download/download_objective = new
|
||||
download_objective.owner = owner
|
||||
download_objective.gen_amount_goal()
|
||||
objectives += download_objective
|
||||
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.find_target()
|
||||
objectives += destroy_objective
|
||||
else
|
||||
if(prob(70))
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
if(team_mode) //No backstabbing while in a team
|
||||
kill_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1)
|
||||
else
|
||||
kill_objective.find_target()
|
||||
objectives += kill_objective
|
||||
else
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = owner
|
||||
if(team_mode)
|
||||
maroon_objective.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1)
|
||||
else
|
||||
maroon_objective.find_target()
|
||||
objectives += maroon_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = owner
|
||||
identity_theft.target = maroon_objective.target
|
||||
identity_theft.update_explanation_text()
|
||||
objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
if (!(locate(/datum/objective/escape) in objectives) && escape_objective_possible)
|
||||
if(prob(50))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
else
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = owner
|
||||
if(team_mode)
|
||||
identity_theft.find_target_by_role(role = ROLE_CHANGELING, role_type = 1, invert = 1)
|
||||
else
|
||||
identity_theft.find_target()
|
||||
objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
owner.objectives |= objectives
|
||||
|
||||
/datum/antagonist/changeling/proc/update_changeling_icons_added()
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.join_hud(owner.current)
|
||||
set_antag_hud(owner.current, "changling")
|
||||
|
||||
/datum/antagonist/changeling/proc/update_changeling_icons_removed()
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.leave_hud(owner.current)
|
||||
set_antag_hud(owner.current, null)
|
||||
|
||||
/datum/antagonist/changeling/admin_add(datum/mind/new_owner,mob/admin)
|
||||
. = ..()
|
||||
to_chat(new_owner.current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are [changelingID], a changeling!</span>")
|
||||
|
||||
/datum/antagonist/changeling/get_admin_commands()
|
||||
. = ..()
|
||||
if(stored_profiles.len && (owner.current.real_name != first_prof.name))
|
||||
.["Transform to initial appearance."] = CALLBACK(src,.proc/admin_restore_appearance)
|
||||
|
||||
/datum/antagonist/changeling/proc/admin_restore_appearance(mob/admin)
|
||||
if(!stored_profiles.len || !iscarbon(owner.current))
|
||||
to_chat(admin, "<span class='danger'>Resetting DNA failed!</span>")
|
||||
else
|
||||
var/mob/living/carbon/C = owner.current
|
||||
first_prof.dna.transfer_identity(C, transfer_SE=1)
|
||||
C.real_name = first_prof.name
|
||||
C.updateappearance(mutcolor_update=1)
|
||||
C.domutcheck()
|
||||
|
||||
// Profile
|
||||
|
||||
/datum/changelingprofile
|
||||
var/name = "a bug"
|
||||
|
||||
var/protected = 0
|
||||
|
||||
var/datum/dna/dna = null
|
||||
var/list/name_list = list() //associative list of slotname = itemname
|
||||
var/list/appearance_list = list()
|
||||
var/list/flags_cover_list = list()
|
||||
var/list/exists_list = list()
|
||||
var/list/item_color_list = list()
|
||||
var/list/item_state_list = list()
|
||||
|
||||
var/underwear
|
||||
var/undershirt
|
||||
var/socks
|
||||
|
||||
/datum/changelingprofile/Destroy()
|
||||
qdel(dna)
|
||||
. = ..()
|
||||
|
||||
/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
|
||||
newprofile.name = name
|
||||
newprofile.protected = protected
|
||||
newprofile.dna = new dna.type
|
||||
dna.copy_dna(newprofile.dna)
|
||||
newprofile.name_list = name_list.Copy()
|
||||
newprofile.appearance_list = appearance_list.Copy()
|
||||
newprofile.flags_cover_list = flags_cover_list.Copy()
|
||||
newprofile.exists_list = exists_list.Copy()
|
||||
newprofile.item_color_list = item_color_list.Copy()
|
||||
newprofile.item_state_list = item_state_list.Copy()
|
||||
newprofile.underwear = underwear
|
||||
newprofile.undershirt = undershirt
|
||||
newprofile.socks = socks
|
||||
|
||||
|
||||
/datum/antagonist/changeling/xenobio
|
||||
name = "Xenobio Changeling"
|
||||
give_objectives = FALSE
|
||||
show_in_roundend = FALSE //These are here for admin tracking purposes only
|
||||
you_are_greet = FALSE
|
||||
|
||||
/datum/antagonist/changeling/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
var/changelingwin = 1
|
||||
if(!owner.current)
|
||||
changelingwin = 0
|
||||
|
||||
parts += printplayer(owner)
|
||||
|
||||
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
|
||||
parts += "<b>Changeling ID:</b> [changelingID]."
|
||||
parts += "<b>Genomes Extracted:</b> [absorbedcount]"
|
||||
parts += " "
|
||||
if(objectives.len)
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='greentext'>Success!</b></span>"
|
||||
else
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
changelingwin = 0
|
||||
count++
|
||||
|
||||
if(changelingwin)
|
||||
parts += "<span class='greentext'>The changeling was successful!</span>"
|
||||
else
|
||||
parts += "<span class='redtext'>The changeling has failed.</span>"
|
||||
|
||||
return parts.Join("<br>")
|
||||
|
||||
/datum/antagonist/changeling/antag_listing_name()
|
||||
return ..() + "([changelingID])"
|
||||
|
||||
/datum/antagonist/changeling/xenobio/antag_listing_name()
|
||||
return ..() + "(Xenobio)"
|
||||
@@ -1,219 +0,0 @@
|
||||
//CLOCKCULT PROOF OF CONCEPT
|
||||
/datum/antagonist/clockcult
|
||||
name = "Clock Cultist"
|
||||
roundend_category = "clock cultists"
|
||||
antagpanel_category = "Clockcult"
|
||||
job_rank = ROLE_SERVANT_OF_RATVAR
|
||||
var/datum/action/innate/hierophant/hierophant_network = new()
|
||||
var/datum/team/clockcult/clock_team
|
||||
var/make_team = TRUE //This should be only false for tutorial scarabs
|
||||
|
||||
/datum/antagonist/clockcult/silent
|
||||
silent = TRUE
|
||||
show_in_antagpanel = FALSE //internal
|
||||
|
||||
/datum/antagonist/clockcult/Destroy()
|
||||
qdel(hierophant_network)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/clockcult/get_team()
|
||||
return clock_team
|
||||
|
||||
/datum/antagonist/clockcult/create_team(datum/team/clockcult/new_team)
|
||||
if(!new_team && make_team)
|
||||
//TODO blah blah same as the others, allow multiple
|
||||
for(var/datum/antagonist/clockcult/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.clock_team)
|
||||
clock_team = H.clock_team
|
||||
return
|
||||
clock_team = new /datum/team/clockcult
|
||||
return
|
||||
if(make_team && !istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
clock_team = new_team
|
||||
|
||||
/datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
if(.)
|
||||
. = is_eligible_servant(new_owner.current)
|
||||
|
||||
/datum/antagonist/clockcult/greet()
|
||||
if(!owner.current || silent)
|
||||
return
|
||||
owner.current.visible_message("<span class='heavy_brass'>[owner.current]'s eyes glow a blazing yellow!</span>", null, null, 7, owner.current) //don't show the owner this message
|
||||
to_chat(owner.current, "<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork \
|
||||
Justiciar above all else. Perform his every whim without hesitation.</span>")
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 70, FALSE, pressure_affected = FALSE)
|
||||
|
||||
/datum/antagonist/clockcult/on_gain()
|
||||
var/mob/living/current = owner.current
|
||||
SSticker.mode.servants_of_ratvar += owner
|
||||
SSticker.mode.update_servant_icons_added(owner)
|
||||
owner.special_role = ROLE_SERVANT_OF_RATVAR
|
||||
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(issilicon(current))
|
||||
if(iscyborg(current) && !silent)
|
||||
var/mob/living/silicon/robot/R = current
|
||||
if(R.connected_ai && !is_servant_of_ratvar(R.connected_ai))
|
||||
to_chat(R, "<span class='boldwarning'>You have been desynced from your master AI.<br>\
|
||||
In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
|
||||
else
|
||||
to_chat(R, "<span class='boldwarning'>Your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
|
||||
if(isAI(current))
|
||||
to_chat(current, "<span class='boldwarning'>You are now able to use your cameras to listen in on conversations, but can no longer speak in anything but Ratvarian.</span>")
|
||||
to_chat(current, "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
else if(isbrain(current) || isclockmob(current))
|
||||
to_chat(current, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
..()
|
||||
to_chat(current, "<b>This is Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]")
|
||||
antag_memory += "<b>Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]<br>" //Memorize the objectives
|
||||
|
||||
/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(istype(mob_override))
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs += current
|
||||
current.faction |= "ratvar"
|
||||
current.grant_language(/datum/language/ratvar)
|
||||
current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
if(iscyborg(S))
|
||||
var/mob/living/silicon/robot/R = S
|
||||
if(!R.shell)
|
||||
R.UnlinkSelf()
|
||||
R.module.rebuild_modules()
|
||||
else if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.can_be_carded = FALSE
|
||||
A.requires_power = POWER_REQ_CLOCKCULT
|
||||
var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame
|
||||
for(var/d in GLOB.cardinals)
|
||||
AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow
|
||||
A.add_overlay(AI_frame)
|
||||
if(!A.lacks_power())
|
||||
A.ai_restore_power()
|
||||
if(A.eyeobj)
|
||||
A.eyeobj.relay_speech = TRUE
|
||||
for(var/mob/living/silicon/robot/R in A.connected_robots)
|
||||
if(R.connected_ai == A)
|
||||
add_servant_of_ratvar(R)
|
||||
S.laws = new/datum/ai_laws/ratvar
|
||||
S.laws.associate(S)
|
||||
S.update_icons()
|
||||
S.show_laws()
|
||||
hierophant_network.title = "Silicon"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "brass"
|
||||
else if(isbrain(current))
|
||||
hierophant_network.title = "Vessel"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "alloy"
|
||||
else if(isclockmob(current))
|
||||
hierophant_network.title = "Construct"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "brass"
|
||||
hierophant_network.Grant(current)
|
||||
current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
||||
if(G.active && ishuman(current))
|
||||
current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
|
||||
|
||||
/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/current = owner.current
|
||||
if(istype(mob_override))
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs -= current
|
||||
current.faction -= "ratvar"
|
||||
current.remove_language(/datum/language/ratvar)
|
||||
current.clear_alert("clockinfo")
|
||||
for(var/datum/action/innate/clockwork_armaments/C in owner.current.actions) //Removes any bound clockwork armor
|
||||
qdel(C)
|
||||
for(var/datum/action/innate/call_weapon/W in owner.current.actions) //and weapons too
|
||||
qdel(W)
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.can_be_carded = initial(A.can_be_carded)
|
||||
A.requires_power = initial(A.requires_power)
|
||||
A.cut_overlays()
|
||||
S.make_laws()
|
||||
S.update_icons()
|
||||
S.show_laws()
|
||||
var/mob/living/temp_owner = current
|
||||
..()
|
||||
if(iscyborg(temp_owner))
|
||||
var/mob/living/silicon/robot/R = temp_owner
|
||||
R.module.rebuild_modules()
|
||||
if(temp_owner)
|
||||
temp_owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
|
||||
temp_owner.cut_overlays()
|
||||
temp_owner.regenerate_icons()
|
||||
|
||||
/datum/antagonist/clockcult/on_removal()
|
||||
SSticker.mode.servants_of_ratvar -= owner
|
||||
SSticker.mode.update_servant_icons_removed(owner)
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner] seems to have remembered their true allegiance!</span>", null, null, null, owner.current)
|
||||
to_chat(owner, "<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
|
||||
owner.current.log_message("<font color=#BE8700>Has renounced the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.special_role = null
|
||||
if(iscyborg(owner.current))
|
||||
to_chat(owner.current, "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>")
|
||||
. = ..()
|
||||
|
||||
|
||||
/datum/antagonist/clockcult/admin_add(datum/mind/new_owner,mob/admin)
|
||||
add_servant_of_ratvar(new_owner.current, TRUE)
|
||||
message_admins("[key_name_admin(admin)] has made [new_owner.current] into a servant of Ratvar.")
|
||||
log_admin("[key_name(admin)] has made [new_owner.current] into a servant of Ratvar.")
|
||||
|
||||
/datum/antagonist/clockcult/admin_remove(mob/user)
|
||||
remove_servant_of_ratvar(owner.current, TRUE)
|
||||
message_admins("[key_name_admin(user)] has removed clockwork servant status from [owner.current].")
|
||||
log_admin("[key_name(user)] has removed clockwork servant status from [owner.current].")
|
||||
|
||||
/datum/antagonist/clockcult/get_admin_commands()
|
||||
. = ..()
|
||||
.["Give slab"] = CALLBACK(src,.proc/admin_give_slab)
|
||||
|
||||
/datum/antagonist/clockcult/proc/admin_give_slab(mob/admin)
|
||||
if(!SSticker.mode.equip_servant(owner.current))
|
||||
to_chat(admin, "<span class='warning'>Failed to outfit [owner.current]!</span>")
|
||||
else
|
||||
to_chat(admin, "<span class='notice'>Successfully gave [owner.current] servant equipment!</span>")
|
||||
|
||||
/datum/team/clockcult
|
||||
name = "Clockcult"
|
||||
var/list/objective
|
||||
var/datum/mind/eminence
|
||||
|
||||
/datum/team/clockcult/proc/check_clockwork_victory()
|
||||
if(GLOB.clockwork_gateway_activated)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/clockcult/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
if(check_clockwork_victory())
|
||||
parts += "<span class='greentext big'>Ratvar's servants defended the Ark until its activation!</span>"
|
||||
else
|
||||
parts += "<span class='redtext big'>The Ark was destroyed! Ratvar will rust away for all eternity!</span>"
|
||||
parts += " "
|
||||
parts += "<b>The servants' objective was:</b> [CLOCKCULT_OBJECTIVE]."
|
||||
parts += "<b>Construction Value(CV)</b> was: <b>[GLOB.clockwork_construction_value]</b>"
|
||||
for(var/i in SSticker.scripture_states)
|
||||
if(i != SCRIPTURE_DRIVER)
|
||||
parts += "<b>[i] scripture</b> was: <b>[SSticker.scripture_states[i] ? "UN":""]LOCKED</b>"
|
||||
if(eminence)
|
||||
parts += "<span class='header'>The Eminence was:</span> [printplayer(eminence)]"
|
||||
if(members.len)
|
||||
parts += "<span class='header'>Ratvar's servants were:</span>"
|
||||
parts += printplayerlist(members - eminence)
|
||||
|
||||
return "<div class='panel clockborder'>[parts.Join("<br>")]</div>"
|
||||
@@ -1,329 +0,0 @@
|
||||
#define SUMMON_POSSIBILITIES 3
|
||||
|
||||
/datum/antagonist/cult
|
||||
name = "Cultist"
|
||||
roundend_category = "cultists"
|
||||
antagpanel_category = "Cult"
|
||||
var/datum/action/innate/cult/comm/communion = new
|
||||
var/datum/action/innate/cult/mastervote/vote = new
|
||||
job_rank = ROLE_CULTIST
|
||||
var/ignore_implant = FALSE
|
||||
var/give_equipment = FALSE
|
||||
|
||||
var/datum/team/cult/cult_team
|
||||
|
||||
/datum/antagonist/cult/get_team()
|
||||
return cult_team
|
||||
|
||||
/datum/antagonist/cult/create_team(datum/team/cult/new_team)
|
||||
if(!new_team)
|
||||
//todo remove this and allow admin buttons to create more than one cult
|
||||
for(var/datum/antagonist/cult/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.cult_team)
|
||||
cult_team = H.cult_team
|
||||
return
|
||||
cult_team = new /datum/team/cult
|
||||
cult_team.setup_objectives()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
cult_team = new_team
|
||||
|
||||
/datum/antagonist/cult/proc/add_objectives()
|
||||
objectives |= cult_team.objectives
|
||||
owner.objectives |= objectives
|
||||
|
||||
/datum/antagonist/cult/proc/remove_objectives()
|
||||
owner.objectives -= objectives
|
||||
|
||||
/datum/antagonist/cult/Destroy()
|
||||
QDEL_NULL(communion)
|
||||
QDEL_NULL(vote)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/cult/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
if(. && !ignore_implant)
|
||||
. = is_convertable_to_cult(new_owner.current,cult_team)
|
||||
|
||||
/datum/antagonist/cult/greet()
|
||||
to_chat(owner, "<span class='userdanger'>You are a member of the cult!</span>")
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/cult/on_gain()
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
add_objectives()
|
||||
if(give_equipment)
|
||||
equip_cultist()
|
||||
SSticker.mode.cult += owner // Only add after they've been given objectives
|
||||
SSticker.mode.update_cult_icons_added(owner)
|
||||
current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
if(cult_team.blood_target && cult_team.blood_target_image && current.client)
|
||||
current.client.images += cult_team.blood_target_image
|
||||
|
||||
|
||||
/datum/antagonist/cult/proc/equip_cultist(tome=FALSE)
|
||||
var/mob/living/carbon/H = owner.current
|
||||
if(!istype(H))
|
||||
return
|
||||
if (owner.assigned_role == "Clown")
|
||||
to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
if(tome)
|
||||
. += cult_give_item(/obj/item/tome, H)
|
||||
else
|
||||
. += cult_give_item(/obj/item/paper/talisman/supply, H)
|
||||
to_chat(owner, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.</span>")
|
||||
|
||||
|
||||
/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob)
|
||||
var/list/slots = list(
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store
|
||||
)
|
||||
|
||||
var/T = new item_path(mob)
|
||||
var/item_name = initial(item_path.name)
|
||||
var/where = mob.equip_in_one_of_slots(T, slots)
|
||||
if(!where)
|
||||
to_chat(mob, "<span class='userdanger'>Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).</span>")
|
||||
return 0
|
||||
else
|
||||
to_chat(mob, "<span class='danger'>You have a [item_name] in your [where].</span>")
|
||||
if(where == "backpack")
|
||||
var/obj/item/storage/B = mob.back
|
||||
B.orient2hud(mob)
|
||||
B.show_to(mob)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
current.faction |= "cult"
|
||||
current.grant_language(/datum/language/narsie)
|
||||
current.verbs += /mob/living/proc/cult_help
|
||||
if(!cult_team.cult_mastered)
|
||||
vote.Grant(current)
|
||||
communion.Grant(current)
|
||||
current.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
|
||||
/datum/antagonist/cult/remove_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
current.faction -= "cult"
|
||||
current.remove_language(/datum/language/narsie)
|
||||
current.verbs -= /mob/living/proc/cult_help
|
||||
vote.Remove(current)
|
||||
communion.Remove(current)
|
||||
current.clear_alert("bloodsense")
|
||||
|
||||
/datum/antagonist/cult/on_removal()
|
||||
remove_objectives()
|
||||
SSticker.mode.cult -= owner
|
||||
SSticker.mode.update_cult_icons_removed(owner)
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!</span>", null, null, null, owner.current)
|
||||
to_chat(owner.current, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.</span>")
|
||||
owner.current.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client)
|
||||
owner.current.client.images -= cult_team.blood_target_image
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/cult/admin_add(datum/mind/new_owner,mob/admin)
|
||||
give_equipment = FALSE
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has cult'ed [new_owner.current].")
|
||||
log_admin("[key_name(admin)] has cult'ed [new_owner.current].")
|
||||
|
||||
/datum/antagonist/cult/admin_remove(mob/user)
|
||||
message_admins("[key_name_admin(user)] has decult'ed [owner.current].")
|
||||
log_admin("[key_name(user)] has decult'ed [owner.current].")
|
||||
SSticker.mode.remove_cultist(owner,silent=TRUE) //disgusting
|
||||
|
||||
/datum/antagonist/cult/get_admin_commands()
|
||||
. = ..()
|
||||
.["Tome"] = CALLBACK(src,.proc/admin_give_tome)
|
||||
.["Amulet"] = CALLBACK(src,.proc/admin_give_amulet)
|
||||
|
||||
/datum/antagonist/cult/proc/admin_give_tome(mob/admin)
|
||||
if(equip_cultist(owner.current,1))
|
||||
to_chat(admin, "<span class='danger'>Spawning tome failed!</span>")
|
||||
|
||||
/datum/antagonist/cult/proc/admin_give_amulet(mob/admin)
|
||||
if (equip_cultist(owner.current))
|
||||
to_chat(admin, "<span class='danger'>Spawning amulet failed!</span>")
|
||||
|
||||
/datum/antagonist/cult/master
|
||||
ignore_implant = TRUE
|
||||
show_in_antagpanel = FALSE //Feel free to add this later
|
||||
var/datum/action/innate/cult/master/finalreck/reckoning = new
|
||||
var/datum/action/innate/cult/master/cultmark/bloodmark = new
|
||||
var/datum/action/innate/cult/master/pulse/throwing = new
|
||||
|
||||
/datum/antagonist/cult/master/Destroy()
|
||||
QDEL_NULL(reckoning)
|
||||
QDEL_NULL(bloodmark)
|
||||
QDEL_NULL(throwing)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/cult/master/on_gain()
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
set_antag_hud(current, "cultmaster")
|
||||
|
||||
/datum/antagonist/cult/master/greet()
|
||||
to_chat(owner.current, "<span class='cultlarge'>You are the cult's Master</span>. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \
|
||||
targets, such as a location or a noncultist, to direct the cult to them, and, finally, you are capable of summoning the entire living cult to your location <b><i>once</i></b>.")
|
||||
to_chat(owner.current, "Use these abilities to direct the cult to victory at any cost.")
|
||||
|
||||
/datum/antagonist/cult/master/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
if(!cult_team.reckoning_complete)
|
||||
reckoning.Grant(current)
|
||||
bloodmark.Grant(current)
|
||||
throwing.Grant(current)
|
||||
current.update_action_buttons_icon()
|
||||
current.apply_status_effect(/datum/status_effect/cult_master)
|
||||
|
||||
/datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
reckoning.Remove(current)
|
||||
bloodmark.Remove(current)
|
||||
throwing.Remove(current)
|
||||
current.update_action_buttons_icon()
|
||||
current.remove_status_effect(/datum/status_effect/cult_master)
|
||||
|
||||
/datum/team/cult
|
||||
name = "Cult"
|
||||
|
||||
var/blood_target
|
||||
var/image/blood_target_image
|
||||
var/blood_target_reset_timer
|
||||
|
||||
var/cult_vote_called = FALSE
|
||||
var/cult_mastered = FALSE
|
||||
var/reckoning_complete = FALSE
|
||||
|
||||
|
||||
/datum/team/cult/proc/setup_objectives()
|
||||
//SAC OBJECTIVE , todo: move this to objective internals
|
||||
var/list/target_candidates = list()
|
||||
var/datum/objective/sacrifice/sac_objective = new
|
||||
sac_objective.team = src
|
||||
|
||||
for(var/mob/living/carbon/human/player in GLOB.player_list)
|
||||
if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD)
|
||||
target_candidates += player.mind
|
||||
|
||||
if(target_candidates.len == 0)
|
||||
message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.")
|
||||
for(var/mob/living/carbon/human/player in GLOB.player_list)
|
||||
if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD)
|
||||
target_candidates += player.mind
|
||||
listclearnulls(target_candidates)
|
||||
if(LAZYLEN(target_candidates))
|
||||
sac_objective.target = pick(target_candidates)
|
||||
sac_objective.update_explanation_text()
|
||||
|
||||
var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role)
|
||||
var/datum/preferences/sacface = sac_objective.target.current.client.prefs
|
||||
var/icon/reshape = get_flat_human_icon(null, sacjob, sacface)
|
||||
reshape.Shift(SOUTH, 4)
|
||||
reshape.Shift(EAST, 1)
|
||||
reshape.Crop(7,4,26,31)
|
||||
reshape.Crop(-5,-3,26,30)
|
||||
sac_objective.sac_image = reshape
|
||||
|
||||
objectives += sac_objective
|
||||
else
|
||||
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
|
||||
|
||||
|
||||
//SUMMON OBJECTIVE
|
||||
|
||||
var/datum/objective/eldergod/summon_objective = new()
|
||||
summon_objective.team = src
|
||||
objectives += summon_objective
|
||||
|
||||
/datum/objective/sacrifice
|
||||
var/sacced = FALSE
|
||||
var/sac_image
|
||||
|
||||
/datum/objective/sacrifice/check_completion()
|
||||
return sacced || completed
|
||||
|
||||
/datum/objective/sacrifice/update_explanation_text()
|
||||
if(target)
|
||||
explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
|
||||
else
|
||||
explanation_text = "The veil has already been weakened here, proceed to the final objective."
|
||||
|
||||
/datum/objective/eldergod
|
||||
var/summoned = FALSE
|
||||
var/list/summon_spots = list()
|
||||
|
||||
/datum/objective/eldergod/New()
|
||||
..()
|
||||
var/sanity = 0
|
||||
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
|
||||
var/area/summon = pick(GLOB.sortedAreas - summon_spots)
|
||||
if(summon && is_station_level(summon.z) && summon.valid_territory)
|
||||
summon_spots += summon
|
||||
sanity++
|
||||
update_explanation_text()
|
||||
|
||||
/datum/objective/eldergod/update_explanation_text()
|
||||
explanation_text = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. <b>The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin.</b>"
|
||||
|
||||
/datum/objective/eldergod/check_completion()
|
||||
return summoned || completed
|
||||
|
||||
/datum/team/cult/proc/check_cult_victory()
|
||||
for(var/datum/objective/O in objectives)
|
||||
if(!O.check_completion())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/team/cult/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
if(check_cult_victory())
|
||||
parts += "<span class='greentext big'>The cult has succeeded! Nar-sie has snuffed out another torch in the void!</span>"
|
||||
else
|
||||
parts += "<span class='redtext big'>The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!</span>"
|
||||
|
||||
if(objectives.len)
|
||||
parts += "<b>The cultists' objectives were:</b>"
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
else
|
||||
parts += "<b>Objective #[count]</b>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
count++
|
||||
|
||||
if(members.len)
|
||||
parts += "<span class='header'>The cultists were:</span>"
|
||||
parts += printplayerlist(members)
|
||||
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
|
||||
/datum/team/cult/is_gamemode_hero()
|
||||
return SSticker.mode.name == "cult"
|
||||
@@ -1,11 +0,0 @@
|
||||
/datum/antagonist/iaa
|
||||
|
||||
/datum/antagonist/iaa/apply_innate_effects()
|
||||
.=..() //in case the base is used in future
|
||||
if(owner&&owner.current)
|
||||
give_pinpointer(owner.current)
|
||||
|
||||
/datum/antagonist/iaa/remove_innate_effects()
|
||||
.=..()
|
||||
if(owner&&owner.current)
|
||||
owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer)
|
||||
@@ -1,352 +0,0 @@
|
||||
/datum/antagonist/traitor
|
||||
name = "Traitor"
|
||||
roundend_category = "traitors"
|
||||
antagpanel_category = "Traitor"
|
||||
job_rank = ROLE_TRAITOR
|
||||
var/should_specialise = TRUE //do we split into AI and human, set to true on inital assignment only
|
||||
var/ai_datum = /datum/antagonist/traitor/AI
|
||||
var/human_datum = /datum/antagonist/traitor/human
|
||||
var/special_role = ROLE_TRAITOR
|
||||
var/employer = "The Syndicate"
|
||||
var/give_objectives = TRUE
|
||||
var/should_give_codewords = TRUE
|
||||
|
||||
|
||||
|
||||
/datum/antagonist/traitor/human
|
||||
show_in_antagpanel = FALSE
|
||||
should_specialise = FALSE
|
||||
var/should_equip = TRUE
|
||||
|
||||
|
||||
/datum/antagonist/traitor/AI
|
||||
show_in_antagpanel = FALSE
|
||||
should_specialise = FALSE
|
||||
|
||||
/datum/antagonist/traitor/specialization(datum/mind/new_owner)
|
||||
if(should_specialise)
|
||||
if(new_owner.current && isAI(new_owner.current))
|
||||
return new ai_datum()
|
||||
else
|
||||
return new human_datum()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/traitor/on_gain()
|
||||
SSticker.mode.traitors += owner
|
||||
owner.special_role = special_role
|
||||
if(give_objectives)
|
||||
forge_traitor_objectives()
|
||||
finalize_traitor()
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/apply_innate_effects()
|
||||
if(owner.assigned_role == "Clown")
|
||||
var/mob/living/carbon/human/traitor_mob = owner.current
|
||||
if(traitor_mob && istype(traitor_mob))
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
traitor_mob.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/traitor/remove_innate_effects()
|
||||
if(owner.assigned_role == "Clown")
|
||||
var/mob/living/carbon/human/traitor_mob = owner.current
|
||||
if(traitor_mob && istype(traitor_mob))
|
||||
traitor_mob.dna.add_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/traitor/on_removal()
|
||||
SSticker.mode.traitors -= owner
|
||||
for(var/O in objectives)
|
||||
owner.objectives -= O
|
||||
objectives = list()
|
||||
if(!silent && owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'> You are no longer the [special_role]! </span>")
|
||||
owner.special_role = null
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/AI/on_removal()
|
||||
if(owner.current && isAI(owner.current))
|
||||
var/mob/living/silicon/ai/A = owner.current
|
||||
A.set_zeroth_law("")
|
||||
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
|
||||
A.malf_picker.remove_malf_verbs(A)
|
||||
qdel(A.malf_picker)
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/proc/add_objective(var/datum/objective/O)
|
||||
owner.objectives += O
|
||||
objectives += O
|
||||
|
||||
/datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O)
|
||||
owner.objectives -= O
|
||||
objectives -= O
|
||||
|
||||
/datum/antagonist/traitor/proc/forge_traitor_objectives()
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/human/forge_traitor_objectives()
|
||||
var/is_hijacker = FALSE
|
||||
if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
|
||||
is_hijacker = prob(10)
|
||||
var/martyr_chance = prob(20)
|
||||
var/objective_count = is_hijacker //Hijacking counts towards number of objectives
|
||||
if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors
|
||||
if(!SSticker.mode.exchange_red)
|
||||
SSticker.mode.exchange_red = owner
|
||||
else
|
||||
SSticker.mode.exchange_blue = owner
|
||||
assign_exchange_role(SSticker.mode.exchange_red)
|
||||
assign_exchange_role(SSticker.mode.exchange_blue)
|
||||
objective_count += 1 //Exchange counts towards number of objectives
|
||||
var/toa = CONFIG_GET(number/traitor_objectives_amount)
|
||||
for(var/i = objective_count, i < toa, i++)
|
||||
forge_single_objective()
|
||||
|
||||
if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
|
||||
if (!(locate(/datum/objective/hijack) in owner.objectives))
|
||||
var/datum/objective/hijack/hijack_objective = new
|
||||
hijack_objective.owner = owner
|
||||
add_objective(hijack_objective)
|
||||
return
|
||||
|
||||
|
||||
var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
|
||||
for(var/datum/objective/O in owner.objectives)
|
||||
if(!O.martyr_compatible)
|
||||
martyr_compatibility = 0
|
||||
break
|
||||
|
||||
if(martyr_compatibility && martyr_chance)
|
||||
var/datum/objective/martyr/martyr_objective = new
|
||||
martyr_objective.owner = owner
|
||||
add_objective(martyr_objective)
|
||||
return
|
||||
|
||||
else
|
||||
if(!(locate(/datum/objective/escape) in owner.objectives))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
add_objective(escape_objective)
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/AI/forge_traitor_objectives()
|
||||
var/objective_count = 0
|
||||
|
||||
if(prob(30))
|
||||
objective_count += forge_single_objective()
|
||||
|
||||
for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
add_objective(kill_objective)
|
||||
|
||||
var/datum/objective/survive/exist/exist_objective = new
|
||||
exist_objective.owner = owner
|
||||
add_objective(exist_objective)
|
||||
/datum/antagonist/traitor/proc/forge_single_objective()
|
||||
return 0
|
||||
/datum/antagonist/traitor/human/forge_single_objective() //Returns how many objectives are added
|
||||
.=1
|
||||
if(prob(50))
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.find_target()
|
||||
add_objective(destroy_objective)
|
||||
else if(prob(30))
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = owner
|
||||
maroon_objective.find_target()
|
||||
add_objective(maroon_objective)
|
||||
else
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
add_objective(kill_objective)
|
||||
else
|
||||
if(prob(15) && !(locate(/datum/objective/download in owner.objectives)))
|
||||
var/datum/objective/download/download_objective = new
|
||||
download_objective.owner = owner
|
||||
download_objective.gen_amount_goal()
|
||||
add_objective(download_objective)
|
||||
else
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
add_objective(steal_objective)
|
||||
|
||||
/datum/antagonist/traitor/AI/forge_single_objective()
|
||||
.=1
|
||||
var/special_pick = rand(1,4)
|
||||
switch(special_pick)
|
||||
if(1)
|
||||
var/datum/objective/block/block_objective = new
|
||||
block_objective.owner = owner
|
||||
add_objective(block_objective)
|
||||
if(2)
|
||||
var/datum/objective/purge/purge_objective = new
|
||||
purge_objective.owner = owner
|
||||
add_objective(purge_objective)
|
||||
if(3)
|
||||
var/datum/objective/robot_army/robot_objective = new
|
||||
robot_objective.owner = owner
|
||||
add_objective(robot_objective)
|
||||
if(4) //Protect and strand a target
|
||||
var/datum/objective/protect/yandere_one = new
|
||||
yandere_one.owner = owner
|
||||
add_objective(yandere_one)
|
||||
yandere_one.find_target()
|
||||
var/datum/objective/maroon/yandere_two = new
|
||||
yandere_two.owner = owner
|
||||
yandere_two.target = yandere_one.target
|
||||
yandere_two.update_explanation_text() // normally called in find_target()
|
||||
add_objective(yandere_two)
|
||||
.=2
|
||||
|
||||
/datum/antagonist/traitor/greet()
|
||||
to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role].</font></B>")
|
||||
owner.announce_objectives()
|
||||
if(should_give_codewords)
|
||||
give_codewords()
|
||||
|
||||
/datum/antagonist/traitor/proc/finalize_traitor()
|
||||
SSticker.mode.update_traitor_icons_added(owner)
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/AI/finalize_traitor()
|
||||
..()
|
||||
add_law_zero()
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
owner.current.grant_language(/datum/language/codespeak)
|
||||
|
||||
/datum/antagonist/traitor/human/finalize_traitor()
|
||||
..()
|
||||
if(should_equip)
|
||||
equip(silent)
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
|
||||
/datum/antagonist/traitor/proc/give_codewords()
|
||||
if(!owner.current)
|
||||
return
|
||||
var/mob/traitor_mob=owner.current
|
||||
|
||||
to_chat(traitor_mob, "<U><B>The Syndicate provided you with the following information on how to identify their agents:</B></U>")
|
||||
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
|
||||
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
|
||||
|
||||
antag_memory += "<b>Code Phrase</b>: [GLOB.syndicate_code_phrase]<br>"
|
||||
antag_memory += "<b>Code Response</b>: [GLOB.syndicate_code_response]<br>"
|
||||
|
||||
to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
|
||||
|
||||
/datum/antagonist/traitor/AI/proc/add_law_zero()
|
||||
var/mob/living/silicon/ai/killer = owner.current
|
||||
if(!killer || !istype(killer))
|
||||
return
|
||||
var/law = "Accomplish your objectives at all costs."
|
||||
var/law_borg = "Accomplish your AI's objectives at all costs."
|
||||
killer.set_zeroth_law(law, law_borg)
|
||||
killer.set_syndie_radio()
|
||||
to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
|
||||
killer.add_malf_picker()
|
||||
|
||||
/datum/antagonist/traitor/proc/equip(var/silent = FALSE)
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/human/equip(var/silent = FALSE)
|
||||
owner.equip_traitor(employer, silent, src)
|
||||
|
||||
/datum/antagonist/traitor/human/proc/assign_exchange_role()
|
||||
//set faction
|
||||
var/faction = "red"
|
||||
if(owner == SSticker.mode.exchange_blue)
|
||||
faction = "blue"
|
||||
|
||||
//Assign objectives
|
||||
var/datum/objective/steal/exchange/exchange_objective = new
|
||||
exchange_objective.set_faction(faction,((faction == "red") ? SSticker.mode.exchange_blue : SSticker.mode.exchange_red))
|
||||
exchange_objective.owner = owner
|
||||
add_objective(exchange_objective)
|
||||
|
||||
if(prob(20))
|
||||
var/datum/objective/steal/exchange/backstab/backstab_objective = new
|
||||
backstab_objective.set_faction(faction)
|
||||
backstab_objective.owner = owner
|
||||
add_objective(backstab_objective)
|
||||
|
||||
//Spawn and equip documents
|
||||
var/mob/living/carbon/human/mob = owner.current
|
||||
|
||||
var/obj/item/folder/syndicate/folder
|
||||
if(owner == SSticker.mode.exchange_red)
|
||||
folder = new/obj/item/folder/syndicate/red(mob.loc)
|
||||
else
|
||||
folder = new/obj/item/folder/syndicate/blue(mob.loc)
|
||||
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store
|
||||
)
|
||||
|
||||
var/where = "At your feet"
|
||||
var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
|
||||
if (equipped_slot)
|
||||
where = "In your [equipped_slot]"
|
||||
to_chat(mob, "<BR><BR><span class='info'>[where] is a folder containing <b>secret documents</b> that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.</span><BR>")
|
||||
|
||||
//TODO Collate
|
||||
/datum/antagonist/traitor/roundend_report()
|
||||
var/list/result = list()
|
||||
|
||||
var/traitorwin = TRUE
|
||||
|
||||
result += printplayer(owner)
|
||||
|
||||
var/TC_uses = 0
|
||||
var/uplink_true = FALSE
|
||||
var/purchases = ""
|
||||
var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[owner.key]
|
||||
if(H)
|
||||
TC_uses = H.total_spent
|
||||
uplink_true = TRUE
|
||||
purchases += H.generate_render(FALSE)
|
||||
|
||||
var/objectives_text = ""
|
||||
if(objectives.len)//If the traitor had no objectives, don't need to process this.
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
traitorwin = FALSE
|
||||
count++
|
||||
|
||||
if(uplink_true)
|
||||
var/uplink_text = "(used [TC_uses] TC) [purchases]"
|
||||
if(TC_uses==0 && traitorwin)
|
||||
var/static/icon/badass = icon('icons/badass.dmi', "badass")
|
||||
uplink_text += "<BIG>[icon2html(badass, world)]</BIG>"
|
||||
result += uplink_text
|
||||
|
||||
result += objectives_text
|
||||
|
||||
var/special_role_text = lowertext(name)
|
||||
|
||||
if(traitorwin)
|
||||
result += "<span class='greentext'>The [special_role_text] was successful!</span>"
|
||||
else
|
||||
result += "<span class='redtext'>The [special_role_text] has failed!</span>"
|
||||
SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg')
|
||||
|
||||
return result.Join("<br>")
|
||||
|
||||
/datum/antagonist/traitor/roundend_report_footer()
|
||||
return "<br><b>The code phrases were:</b> <span class='codephrase'>[GLOB.syndicate_code_phrase]</span><br>\
|
||||
<b>The code responses were:</b> <span class='codephrase'>[GLOB.syndicate_code_response]</span><br>"
|
||||
|
||||
/datum/antagonist/traitor/is_gamemode_hero()
|
||||
return SSticker.mode.name == "traitor"
|
||||
@@ -1,582 +0,0 @@
|
||||
#define BLOOD_THRESHOLD 3 //How many souls are needed per stage.
|
||||
#define TRUE_THRESHOLD 7
|
||||
#define ARCH_THRESHOLD 12
|
||||
|
||||
#define BASIC_DEVIL 0
|
||||
#define BLOOD_LIZARD 1
|
||||
#define TRUE_DEVIL 2
|
||||
#define ARCH_DEVIL 3
|
||||
|
||||
#define LOSS_PER_DEATH 2
|
||||
|
||||
#define SOULVALUE soulsOwned.len-reviveNumber
|
||||
|
||||
#define DEVILRESURRECTTIME 600
|
||||
|
||||
GLOBAL_LIST_EMPTY(allDevils)
|
||||
GLOBAL_LIST_INIT(lawlorify, list (
|
||||
LORE = list(
|
||||
OBLIGATION_FOOD = "This devil seems to always offer its victims food before slaughtering them.",
|
||||
OBLIGATION_FIDDLE = "This devil will never turn down a musical challenge.",
|
||||
OBLIGATION_DANCEOFF = "This devil will never turn down a dance off.",
|
||||
OBLIGATION_GREET = "This devil seems to only be able to converse with people it knows the name of.",
|
||||
OBLIGATION_PRESENCEKNOWN = "This devil seems to be unable to attack from stealth.",
|
||||
OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.",
|
||||
OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.",
|
||||
OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.",
|
||||
BANE_SILVER = "Silver seems to gravely injure this devil.",
|
||||
BANE_SALT = "Throwing salt at this devil will hinder his ability to use infernal powers temporarily.",
|
||||
BANE_LIGHT = "Bright flashes will disorient the devil, likely causing him to flee.",
|
||||
BANE_IRON = "Cold iron will slowly injure him, until he can purge it from his system.",
|
||||
BANE_WHITECLOTHES = "Wearing clean white clothing will help ward off this devil.",
|
||||
BANE_HARVEST = "Presenting the labors of a harvest will disrupt the devil.",
|
||||
BANE_TOOLBOX = "That which holds the means of creation also holds the means of the devil's undoing.",
|
||||
BAN_HURTWOMAN = "This devil seems to prefer hunting men.",
|
||||
BAN_CHAPEL = "This devil avoids holy ground.",
|
||||
BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.",
|
||||
BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.",
|
||||
BAN_STRIKEUNCONSCIOUS = "This devil only shows interest in those who are awake.",
|
||||
BAN_HURTLIZARD = "This devil will not strike a lizardman first.",
|
||||
BAN_HURTANIMAL = "This devil avoids hurting animals.",
|
||||
BANISH_WATER = "To banish the devil, you must infuse its body with holy water.",
|
||||
BANISH_COFFIN = "This devil will return to life if its remains are not placed within a coffin.",
|
||||
BANISH_FORMALDYHIDE = "To banish the devil, you must inject its lifeless body with embalming fluid.",
|
||||
BANISH_RUNES = "This devil will resurrect after death, unless its remains are within a rune.",
|
||||
BANISH_CANDLES = "A large number of nearby lit candles will prevent it from resurrecting.",
|
||||
BANISH_DESTRUCTION = "Its corpse must be utterly destroyed to prevent resurrection.",
|
||||
BANISH_FUNERAL_GARB = "If clad in funeral garments, this devil will be unable to resurrect. Should the clothes not fit, lay them gently on top of the devil's corpse."
|
||||
),
|
||||
LAW = list(
|
||||
OBLIGATION_FOOD = "When not acting in self defense, you must always offer your victim food before harming them.",
|
||||
OBLIGATION_FIDDLE = "When not in immediate danger, if you are challenged to a musical duel, you must accept it. You are not obligated to duel the same person twice.",
|
||||
OBLIGATION_DANCEOFF = "When not in immediate danger, if you are challenged to a dance off, you must accept it. You are not obligated to face off with the same person twice.",
|
||||
OBLIGATION_GREET = "You must always greet other people by their last name before talking with them.",
|
||||
OBLIGATION_PRESENCEKNOWN = "You must always make your presence known before attacking.",
|
||||
OBLIGATION_SAYNAME = "You must always say your true name after you kill someone.",
|
||||
OBLIGATION_ANNOUNCEKILL = "Upon killing someone, you must make your deed known to all within earshot, over comms if reasonably possible.",
|
||||
OBLIGATION_ANSWERTONAME = "If you are not under attack, you must always respond to your true name.",
|
||||
BAN_HURTWOMAN = "You must never harm a female outside of self defense.",
|
||||
BAN_CHAPEL = "You must never attempt to enter the chapel.",
|
||||
BAN_HURTPRIEST = "You must never attack a priest.",
|
||||
BAN_AVOIDWATER = "You must never willingly touch a wet surface.",
|
||||
BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.",
|
||||
BAN_HURTLIZARD = "You must never harm a lizardman outside of self defense.",
|
||||
BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.",
|
||||
BANE_SILVER = "Silver, in all of its forms shall be your downfall.",
|
||||
BANE_SALT = "Salt will disrupt your magical abilities.",
|
||||
BANE_LIGHT = "Blinding lights will prevent you from using offensive powers for a time.",
|
||||
BANE_IRON = "Cold wrought iron shall act as poison to you.",
|
||||
BANE_WHITECLOTHES = "Those clad in pristine white garments will strike you true.",
|
||||
BANE_HARVEST = "The fruits of the harvest shall be your downfall.",
|
||||
BANE_TOOLBOX = "Toolboxes are bad news for you, for some reason.",
|
||||
BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.",
|
||||
BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.",
|
||||
BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.",
|
||||
BANISH_RUNES = "If your corpse is placed within a rune, you will be unable to resurrect.",
|
||||
BANISH_CANDLES = "If your corpse is near lit candles, you will be unable to resurrect.",
|
||||
BANISH_DESTRUCTION = "If your corpse is destroyed, you will be unable to resurrect.",
|
||||
BANISH_FUNERAL_GARB = "If your corpse is clad in funeral garments, you will be unable to resurrect."
|
||||
)
|
||||
))
|
||||
|
||||
//These are also used in the codex gigas, so let's declare them globally.
|
||||
GLOBAL_LIST_INIT(devil_pre_title, list("Dark ", "Hellish ", "Fallen ", "Fiery ", "Sinful ", "Blood ", "Fluffy "))
|
||||
GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept "))
|
||||
GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa"))
|
||||
GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr."))
|
||||
/datum/antagonist/devil
|
||||
name = "Devil"
|
||||
roundend_category = "devils"
|
||||
antagpanel_category = "Devil"
|
||||
job_rank = ROLE_DEVIL
|
||||
//Don't delete upon mind destruction, otherwise soul re-selling will break.
|
||||
delete_on_mind_deletion = FALSE
|
||||
var/obligation
|
||||
var/ban
|
||||
var/bane
|
||||
var/banish
|
||||
var/truename
|
||||
var/list/datum/mind/soulsOwned = new
|
||||
var/reviveNumber = 0
|
||||
var/form = BASIC_DEVIL
|
||||
var/static/list/devil_spells = typecacheof(list(
|
||||
/obj/effect/proc_holder/spell/aimed/fireball/hellish,
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork,
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater,
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended,
|
||||
/obj/effect/proc_holder/spell/targeted/infernal_jaunt,
|
||||
/obj/effect/proc_holder/spell/targeted/sintouch,
|
||||
/obj/effect/proc_holder/spell/targeted/sintouch/ascended,
|
||||
/obj/effect/proc_holder/spell/targeted/summon_contract,
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
|
||||
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
|
||||
var/ascendable = FALSE
|
||||
|
||||
/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
return . && (ishuman(new_owner.current) || iscyborg(new_owner.current))
|
||||
|
||||
/datum/antagonist/devil/get_admin_commands()
|
||||
. = ..()
|
||||
.["Toggle ascendable"] = CALLBACK(src,.proc/admin_toggle_ascendable)
|
||||
|
||||
|
||||
/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin)
|
||||
ascendable = !ascendable
|
||||
message_admins("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable]")
|
||||
log_admin("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable])")
|
||||
|
||||
/datum/antagonist/devil/admin_add(datum/mind/new_owner,mob/admin)
|
||||
switch(alert(admin,"Should the devil be able to ascend",,"Yes","No","Cancel"))
|
||||
if("Yes")
|
||||
ascendable = TRUE
|
||||
if("No")
|
||||
ascendable = FALSE
|
||||
else
|
||||
return
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]")
|
||||
log_admin("[key_name(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]")
|
||||
|
||||
/datum/antagonist/devil/antag_listing_name()
|
||||
return ..() + "([truename])"
|
||||
|
||||
/proc/devilInfo(name)
|
||||
if(GLOB.allDevils[lowertext(name)])
|
||||
return GLOB.allDevils[lowertext(name)]
|
||||
else
|
||||
var/datum/fakeDevil/devil = new /datum/fakeDevil(name)
|
||||
GLOB.allDevils[lowertext(name)] = devil
|
||||
return devil
|
||||
|
||||
/proc/randomDevilName()
|
||||
var/name = ""
|
||||
if(prob(65))
|
||||
if(prob(35))
|
||||
name = pick(GLOB.devil_pre_title)
|
||||
name += pick(GLOB.devil_title)
|
||||
var/probability = 100
|
||||
name += pick(GLOB.devil_syllable)
|
||||
while(prob(probability))
|
||||
name += pick(GLOB.devil_syllable)
|
||||
probability -= 20
|
||||
if(prob(40))
|
||||
name += pick(GLOB.devil_suffix)
|
||||
return name
|
||||
|
||||
/proc/randomdevilobligation()
|
||||
return pick(OBLIGATION_FOOD, OBLIGATION_FIDDLE, OBLIGATION_DANCEOFF, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME)
|
||||
|
||||
/proc/randomdevilban()
|
||||
return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL)
|
||||
|
||||
/proc/randomdevilbane()
|
||||
return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX)
|
||||
|
||||
/proc/randomdevilbanish()
|
||||
return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB)
|
||||
|
||||
/datum/antagonist/devil/proc/add_soul(datum/mind/soul)
|
||||
if(soulsOwned.Find(soul))
|
||||
return
|
||||
soulsOwned += soul
|
||||
owner.current.nutrition = NUTRITION_LEVEL_FULL
|
||||
to_chat(owner.current, "<span class='warning'>You feel satiated as you received a new soul.</span>")
|
||||
update_hud()
|
||||
switch(SOULVALUE)
|
||||
if(0)
|
||||
to_chat(owner.current, "<span class='warning'>Your hellish powers have been restored.</span>")
|
||||
give_appropriate_spells()
|
||||
if(BLOOD_THRESHOLD)
|
||||
increase_blood_lizard()
|
||||
if(TRUE_THRESHOLD)
|
||||
increase_true_devil()
|
||||
if(ARCH_THRESHOLD)
|
||||
increase_arch_devil()
|
||||
|
||||
/datum/antagonist/devil/proc/remove_soul(datum/mind/soul)
|
||||
if(soulsOwned.Remove(soul))
|
||||
check_regression()
|
||||
to_chat(owner.current, "<span class='warning'>You feel as though a soul has slipped from your grasp.</span>")
|
||||
update_hud()
|
||||
|
||||
/datum/antagonist/devil/proc/check_regression()
|
||||
if(form == ARCH_DEVIL)
|
||||
return //arch devil can't regress
|
||||
//Yes, fallthrough behavior is intended, so I can't use a switch statement.
|
||||
if(form == TRUE_DEVIL && SOULVALUE < TRUE_THRESHOLD)
|
||||
regress_blood_lizard()
|
||||
if(form == BLOOD_LIZARD && SOULVALUE < BLOOD_THRESHOLD)
|
||||
regress_humanoid()
|
||||
if(SOULVALUE < 0)
|
||||
give_appropriate_spells()
|
||||
to_chat(owner.current, "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked.</span>")
|
||||
|
||||
/datum/antagonist/devil/proc/regress_humanoid()
|
||||
to_chat(owner.current, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
|
||||
if(ishuman(owner.current))
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.set_species(/datum/species/human, 1)
|
||||
H.regenerate_icons()
|
||||
give_appropriate_spells()
|
||||
if(istype(owner.current.loc, /obj/effect/dummy/slaughter/))
|
||||
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
|
||||
form = BASIC_DEVIL
|
||||
|
||||
/datum/antagonist/devil/proc/regress_blood_lizard()
|
||||
var/mob/living/carbon/true_devil/D = owner.current
|
||||
to_chat(D, "<span class='warning'>Your powers weaken, have more contracts be signed to regain power.</span>")
|
||||
D.oldform.forceMove(D.drop_location())
|
||||
owner.transfer_to(D.oldform)
|
||||
give_appropriate_spells()
|
||||
qdel(D)
|
||||
form = BLOOD_LIZARD
|
||||
update_hud()
|
||||
|
||||
|
||||
/datum/antagonist/devil/proc/increase_blood_lizard()
|
||||
to_chat(owner.current, "<span class='warning'>You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.</span>")
|
||||
sleep(50)
|
||||
if(ishuman(owner.current))
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.set_species(/datum/species/lizard, 1)
|
||||
H.underwear = "Nude"
|
||||
H.undershirt = "Nude"
|
||||
H.socks = "Nude"
|
||||
H.dna.features["mcolor"] = "511" //A deep red
|
||||
H.regenerate_icons()
|
||||
else //Did the devil get hit by a staff of transmutation?
|
||||
owner.current.color = "#501010"
|
||||
give_appropriate_spells()
|
||||
form = BLOOD_LIZARD
|
||||
|
||||
|
||||
|
||||
/datum/antagonist/devil/proc/increase_true_devil()
|
||||
to_chat(owner.current, "<span class='warning'>You feel as though your current form is about to shed. You will soon turn into a true devil.</span>")
|
||||
sleep(50)
|
||||
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc)
|
||||
A.faction |= "hell"
|
||||
owner.current.forceMove(A)
|
||||
A.oldform = owner.current
|
||||
owner.transfer_to(A)
|
||||
A.set_name()
|
||||
give_appropriate_spells()
|
||||
form = TRUE_DEVIL
|
||||
update_hud()
|
||||
|
||||
/datum/antagonist/devil/proc/increase_arch_devil()
|
||||
if(!ascendable)
|
||||
return
|
||||
var/mob/living/carbon/true_devil/D = owner.current
|
||||
to_chat(D, "<span class='warning'>You feel as though your form is about to ascend.</span>")
|
||||
sleep(50)
|
||||
if(!D)
|
||||
return
|
||||
D.visible_message("<span class='warning'>[D]'s skin begins to erupt with spikes.</span>", \
|
||||
"<span class='warning'>Your flesh begins creating a shield around yourself.</span>")
|
||||
sleep(100)
|
||||
if(!D)
|
||||
return
|
||||
D.visible_message("<span class='warning'>The horns on [D]'s head slowly grow and elongate.</span>", \
|
||||
"<span class='warning'>Your body continues to mutate. Your telepathic abilities grow.</span>")
|
||||
sleep(90)
|
||||
if(!D)
|
||||
return
|
||||
D.visible_message("<span class='warning'>[D]'s body begins to violently stretch and contort.</span>", \
|
||||
"<span class='warning'>You begin to rend apart the final barriers to ultimate power.</span>")
|
||||
sleep(40)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(D, "<i><b>Yes!</b></i>")
|
||||
sleep(10)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(D, "<i><b><span class='big'>YES!!</span></b></i>")
|
||||
sleep(10)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(D, "<i><b><span class='reallybig'>YE--</span></b></i>")
|
||||
sleep(1)
|
||||
if(!D)
|
||||
return
|
||||
to_chat(world, "<font size=5><span class='danger'><b>\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"</font></span>")
|
||||
SEND_SOUND(world, sound('sound/hallucinations/veryfar_noise.ogg'))
|
||||
give_appropriate_spells()
|
||||
D.convert_to_archdevil()
|
||||
if(istype(D.loc, /obj/effect/dummy/slaughter/))
|
||||
D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted.
|
||||
var/area/A = get_area(owner.current)
|
||||
if(A)
|
||||
notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK)
|
||||
sleep(50)
|
||||
if(!SSticker.mode.devil_ascended)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0.3)
|
||||
SSticker.mode.devil_ascended++
|
||||
form = ARCH_DEVIL
|
||||
|
||||
/datum/antagonist/devil/proc/remove_spells()
|
||||
for(var/X in owner.spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
if(is_type_in_typecache(S, devil_spells))
|
||||
owner.RemoveSpell(S)
|
||||
|
||||
/datum/antagonist/devil/proc/give_summon_contract()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null))
|
||||
if(obligation == OBLIGATION_FIDDLE)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null))
|
||||
else if(obligation == OBLIGATION_DANCEOFF)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null))
|
||||
|
||||
/datum/antagonist/devil/proc/give_appropriate_spells()
|
||||
remove_spells()
|
||||
give_summon_contract()
|
||||
if(SOULVALUE >= ARCH_THRESHOLD && ascendable)
|
||||
give_arch_spells()
|
||||
else if(SOULVALUE >= TRUE_THRESHOLD)
|
||||
give_true_spells()
|
||||
else if(SOULVALUE >= BLOOD_THRESHOLD)
|
||||
give_blood_spells()
|
||||
else if(SOULVALUE >= 0)
|
||||
give_base_spells()
|
||||
|
||||
/datum/antagonist/devil/proc/give_base_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
|
||||
|
||||
/datum/antagonist/devil/proc/give_blood_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
|
||||
|
||||
/datum/antagonist/devil/proc/give_true_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null))
|
||||
|
||||
/datum/antagonist/devil/proc/give_arch_spells()
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null))
|
||||
|
||||
/datum/antagonist/devil/proc/beginResurrectionCheck(mob/living/body)
|
||||
if(SOULVALUE>0)
|
||||
to_chat(owner.current, "<span class='userdanger'>Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body.</span>")
|
||||
sleep(DEVILRESURRECTTIME)
|
||||
if (!body || body.stat == DEAD)
|
||||
if(SOULVALUE>0)
|
||||
if(check_banishment(body))
|
||||
to_chat(owner.current, "<span class='userdanger'>Unfortunately, the mortals have finished a ritual that prevents your resurrection.</span>")
|
||||
return -1
|
||||
else
|
||||
to_chat(owner.current, "<span class='userdanger'>WE LIVE AGAIN!</span>")
|
||||
return hellish_resurrection(body)
|
||||
else
|
||||
to_chat(owner.current, "<span class='userdanger'>Unfortunately, the power that stemmed from your contracts has been extinguished. You no longer have enough power to resurrect.</span>")
|
||||
return -1
|
||||
else
|
||||
to_chat(owner.current, "<span class='danger'> You seem to have resurrected without your hellish powers.</span>")
|
||||
else
|
||||
to_chat(owner.current, "<span class='userdanger'>Your hellish powers are too weak to resurrect yourself.</span>")
|
||||
|
||||
/datum/antagonist/devil/proc/check_banishment(mob/living/body)
|
||||
switch(banish)
|
||||
if(BANISH_WATER)
|
||||
if(iscarbon(body))
|
||||
var/mob/living/carbon/H = body
|
||||
return H.reagents.has_reagent("holy water")
|
||||
return 0
|
||||
if(BANISH_COFFIN)
|
||||
return (body && istype(body.loc, /obj/structure/closet/coffin))
|
||||
if(BANISH_FORMALDYHIDE)
|
||||
if(iscarbon(body))
|
||||
var/mob/living/carbon/H = body
|
||||
return H.reagents.has_reagent("formaldehyde")
|
||||
return 0
|
||||
if(BANISH_RUNES)
|
||||
if(body)
|
||||
for(var/obj/effect/decal/cleanable/crayon/R in range(0,body))
|
||||
if (R.name == "rune")
|
||||
return 1
|
||||
return 0
|
||||
if(BANISH_CANDLES)
|
||||
if(body)
|
||||
var/count = 0
|
||||
for(var/obj/item/candle/C in range(1,body))
|
||||
count += C.lit
|
||||
if(count>=4)
|
||||
return 1
|
||||
return 0
|
||||
if(BANISH_DESTRUCTION)
|
||||
if(body)
|
||||
return 0
|
||||
return 1
|
||||
if(BANISH_FUNERAL_GARB)
|
||||
if(ishuman(body))
|
||||
var/mob/living/carbon/human/H = body
|
||||
if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/burial))
|
||||
return 1
|
||||
return 0
|
||||
else
|
||||
for(var/obj/item/clothing/under/burial/B in range(0,body))
|
||||
if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something.
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/antagonist/devil/proc/hellish_resurrection(mob/living/body)
|
||||
message_admins("[owner.name] (true name is: [truename]) is resurrecting using hellish energy.</a>")
|
||||
if(SOULVALUE < ARCH_THRESHOLD || !ascendable) // once ascended, arch devils do not go down in power by any means.
|
||||
reviveNumber += LOSS_PER_DEATH
|
||||
update_hud()
|
||||
if(body)
|
||||
body.revive(TRUE, TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart.
|
||||
if(istype(body.loc, /obj/effect/dummy/slaughter/))
|
||||
body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted.
|
||||
if(istype(body, /mob/living/carbon/true_devil))
|
||||
var/mob/living/carbon/true_devil/D = body
|
||||
if(D.oldform)
|
||||
D.oldform.revive(1,0) // Heal the old body too, so the devil doesn't resurrect, then immediately regress into a dead body.
|
||||
if(body.stat == DEAD)
|
||||
create_new_body()
|
||||
else
|
||||
create_new_body()
|
||||
check_regression()
|
||||
|
||||
/datum/antagonist/devil/proc/create_new_body()
|
||||
if(GLOB.blobstart.len > 0)
|
||||
var/turf/targetturf = get_turf(pick(GLOB.blobstart))
|
||||
var/mob/currentMob = owner.current
|
||||
if(!currentMob)
|
||||
currentMob = owner.get_ghost()
|
||||
if(!currentMob)
|
||||
message_admins("[owner.name]'s devil resurrection failed due to client logoff. Aborting.")
|
||||
return -1
|
||||
if(currentMob.mind != owner)
|
||||
message_admins("[owner.name]'s devil resurrection failed due to becoming a new mob. Aborting.")
|
||||
return -1
|
||||
currentMob.change_mob_type( /mob/living/carbon/human, targetturf, null, 1)
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/lawyer/black(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), slot_hands)
|
||||
H.equip_to_slot_or_del(new /obj/item/pen(H), slot_l_store)
|
||||
if(SOULVALUE >= BLOOD_THRESHOLD)
|
||||
H.set_species(/datum/species/lizard, 1)
|
||||
H.underwear = "Nude"
|
||||
H.undershirt = "Nude"
|
||||
H.socks = "Nude"
|
||||
H.dna.features["mcolor"] = "511"
|
||||
H.regenerate_icons()
|
||||
if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough.
|
||||
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf)
|
||||
A.faction |= "hell"
|
||||
H.forceMove(A)
|
||||
A.oldform = H
|
||||
owner.transfer_to(A, TRUE)
|
||||
A.set_name()
|
||||
if(SOULVALUE >= ARCH_THRESHOLD && ascendable)
|
||||
A.convert_to_archdevil()
|
||||
else
|
||||
throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection")
|
||||
|
||||
|
||||
/datum/antagonist/devil/proc/update_hud()
|
||||
if(iscarbon(owner.current))
|
||||
var/mob/living/C = owner.current
|
||||
if(C.hud_used && C.hud_used.devilsouldisplay)
|
||||
C.hud_used.devilsouldisplay.update_counter(SOULVALUE)
|
||||
|
||||
/datum/antagonist/devil/greet()
|
||||
to_chat(owner.current, "<span class='warning'><b>You remember your link to the infernal. You are [truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp.</b></span>")
|
||||
to_chat(owner.current, "<span class='warning'><b>However, your infernal form is not without weaknesses.</b></span>")
|
||||
to_chat(owner.current, "You may not use violence to coerce someone into selling their soul.")
|
||||
to_chat(owner.current, "You may not directly and knowingly physically harm a devil, other than yourself.")
|
||||
to_chat(owner.current, GLOB.lawlorify[LAW][bane])
|
||||
to_chat(owner.current, GLOB.lawlorify[LAW][ban])
|
||||
to_chat(owner.current, GLOB.lawlorify[LAW][obligation])
|
||||
to_chat(owner.current, GLOB.lawlorify[LAW][banish])
|
||||
to_chat(owner.current, "<span class='warning'>Remember, the crew can research your weaknesses if they find out your devil name.</span><br>")
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/on_gain()
|
||||
truename = randomDevilName()
|
||||
ban = randomdevilban()
|
||||
bane = randomdevilbane()
|
||||
obligation = randomdevilobligation()
|
||||
banish = randomdevilbanish()
|
||||
GLOB.allDevils[lowertext(truename)] = src
|
||||
|
||||
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>"
|
||||
if(issilicon(owner.current))
|
||||
var/mob/living/silicon/robot_devil = owner.current
|
||||
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
|
||||
robot_devil.set_law_sixsixsix(laws)
|
||||
sleep(10)
|
||||
if(owner.assigned_role == "Clown" && ishuman(owner.current))
|
||||
var/mob/living/carbon/human/S = owner.current
|
||||
to_chat(S, "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>")
|
||||
S.dna.remove_mutation(CLOWNMUT)
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/on_removal()
|
||||
to_chat(owner.current, "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>")
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override)
|
||||
give_appropriate_spells()
|
||||
owner.current.grant_all_languages(TRUE)
|
||||
update_hud()
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/remove_innate_effects(mob/living/mob_override)
|
||||
for(var/X in owner.spell_list)
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
if(is_type_in_typecache(S, devil_spells))
|
||||
owner.RemoveSpell(S)
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/proc/printdevilinfo()
|
||||
var/list/parts = list()
|
||||
parts += "The devil's true name is: [truename]"
|
||||
parts += "The devil's bans were:"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]"
|
||||
return parts.Join("<br>")
|
||||
|
||||
/datum/antagonist/devil/roundend_report()
|
||||
var/list/parts = list()
|
||||
parts += printplayer(owner)
|
||||
parts += printdevilinfo()
|
||||
parts += printobjectives(owner)
|
||||
return parts.Join("<br>")
|
||||
|
||||
/datum/antagonist/devil/roundend_report_footer()
|
||||
//sintouched go here for now as a hack , TODO proper antag datum for these
|
||||
var/list/parts = list()
|
||||
if(SSticker.mode.sintouched.len)
|
||||
parts += "<span class='header'>The sintouched were:</span>"
|
||||
var/list/sintouchedUnique = uniqueList(SSticker.mode.sintouched)
|
||||
for(var/S in sintouchedUnique)
|
||||
var/datum/mind/sintouched_mind = S
|
||||
parts += printplayer(sintouched_mind)
|
||||
parts += printobjectives(sintouched_mind)
|
||||
return parts.Join("<br>")
|
||||
|
||||
//A simple super light weight datum for the codex gigas.
|
||||
/datum/fakeDevil
|
||||
var/truename
|
||||
var/bane
|
||||
var/obligation
|
||||
var/ban
|
||||
var/banish
|
||||
var/ascendable
|
||||
|
||||
/datum/fakeDevil/New(name = randomDevilName())
|
||||
truename = name
|
||||
bane = randomdevilbane()
|
||||
obligation = randomdevilobligation()
|
||||
ban = randomdevilban()
|
||||
banish = randomdevilbanish()
|
||||
ascendable = prob(25)
|
||||
@@ -1,302 +0,0 @@
|
||||
#define PINPOINTER_MINIMUM_RANGE 15
|
||||
#define PINPOINTER_EXTRA_RANDOM_RANGE 10
|
||||
#define PINPOINTER_PING_TIME 40
|
||||
#define PROB_ACTUAL_TRAITOR 20
|
||||
#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent"
|
||||
|
||||
/datum/antagonist/traitor/internal_affairs
|
||||
name = "Internal Affairs Agent"
|
||||
human_datum = /datum/antagonist/traitor/human/internal_affairs
|
||||
ai_datum = /datum/antagonist/traitor/AI/internal_affairs
|
||||
antagpanel_category = "IAA"
|
||||
|
||||
/datum/antagonist/traitor/AI/internal_affairs
|
||||
name = "Internal Affairs Agent"
|
||||
employer = "Nanotrasen"
|
||||
special_role = "internal affairs agent"
|
||||
antagpanel_category = "IAA"
|
||||
var/syndicate = FALSE
|
||||
var/last_man_standing = FALSE
|
||||
var/list/datum/mind/targets_stolen
|
||||
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs
|
||||
name = "Internal Affairs Agent"
|
||||
employer = "Nanotrasen"
|
||||
special_role = "internal affairs agent"
|
||||
antagpanel_category = "IAA"
|
||||
var/syndicate = FALSE
|
||||
var/last_man_standing = FALSE
|
||||
var/list/datum/mind/targets_stolen
|
||||
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/proc/give_pinpointer()
|
||||
if(owner && owner.current)
|
||||
owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer)
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/apply_innate_effects()
|
||||
.=..() //in case the base is used in future
|
||||
if(owner && owner.current)
|
||||
give_pinpointer(owner.current)
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/remove_innate_effects()
|
||||
.=..()
|
||||
if(owner && owner.current)
|
||||
owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer)
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/on_gain()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
.=..()
|
||||
/datum/antagonist/traitor/human/internal_affairs/on_removal()
|
||||
STOP_PROCESSING(SSprocessing,src)
|
||||
.=..()
|
||||
/datum/antagonist/traitor/human/internal_affairs/process()
|
||||
iaa_process()
|
||||
|
||||
/datum/antagonist/traitor/AI/internal_affairs/on_gain()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
.=..()
|
||||
/datum/antagonist/traitor/AI/internal_affairs/on_removal()
|
||||
STOP_PROCESSING(SSprocessing,src)
|
||||
.=..()
|
||||
/datum/antagonist/traitor/AI/internal_affairs/process()
|
||||
iaa_process()
|
||||
|
||||
/datum/status_effect/agent_pinpointer
|
||||
id = "agent_pinpointer"
|
||||
duration = -1
|
||||
tick_interval = PINPOINTER_PING_TIME
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer
|
||||
var/minimum_range = PINPOINTER_MINIMUM_RANGE
|
||||
var/mob/scan_target = null
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer
|
||||
name = "Internal Affairs Integrated Pinpointer"
|
||||
desc = "Even stealthier than a normal implant."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinon"
|
||||
|
||||
/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
|
||||
if(!scan_target)
|
||||
linked_alert.icon_state = "pinonnull"
|
||||
return
|
||||
var/turf/here = get_turf(owner)
|
||||
var/turf/there = get_turf(scan_target)
|
||||
if(here.z != there.z)
|
||||
linked_alert.icon_state = "pinonnull"
|
||||
return
|
||||
if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE))
|
||||
linked_alert.icon_state = "pinondirect"
|
||||
else
|
||||
linked_alert.setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
linked_alert.icon_state = "pinonclose"
|
||||
if(9 to 16)
|
||||
linked_alert.icon_state = "pinonmedium"
|
||||
if(16 to INFINITY)
|
||||
linked_alert.icon_state = "pinonfar"
|
||||
|
||||
/datum/status_effect/agent_pinpointer/proc/scan_for_target()
|
||||
scan_target = null
|
||||
if(owner)
|
||||
if(owner.mind)
|
||||
if(owner.mind.objectives)
|
||||
for(var/datum/objective/objective_ in owner.mind.objectives)
|
||||
if(!is_internal_objective(objective_))
|
||||
continue
|
||||
var/datum/objective/assassinate/internal/objective = objective_
|
||||
var/mob/current = objective.target.current
|
||||
if(current&¤t.stat!=DEAD)
|
||||
scan_target = current
|
||||
break
|
||||
|
||||
/datum/status_effect/agent_pinpointer/tick()
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
scan_for_target()
|
||||
point_to_target()
|
||||
|
||||
|
||||
/proc/is_internal_objective(datum/objective/O)
|
||||
return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal))
|
||||
|
||||
/datum/antagonist/traitor/proc/replace_escape_objective()
|
||||
if(!owner||!owner.objectives)
|
||||
return
|
||||
for (var/objective_ in owner.objectives)
|
||||
if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive)))
|
||||
continue
|
||||
remove_objective(objective_)
|
||||
|
||||
var/datum/objective/martyr/martyr_objective = new
|
||||
martyr_objective.owner = owner
|
||||
add_objective(martyr_objective)
|
||||
|
||||
/datum/antagonist/traitor/proc/reinstate_escape_objective()
|
||||
if(!owner||!owner.objectives)
|
||||
return
|
||||
for (var/objective_ in owner.objectives)
|
||||
if(!istype(objective_, /datum/objective/martyr))
|
||||
continue
|
||||
remove_objective(objective_)
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/reinstate_escape_objective()
|
||||
..()
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
add_objective(escape_objective)
|
||||
|
||||
/datum/antagonist/traitor/AI/internal_affairs/reinstate_escape_objective()
|
||||
..()
|
||||
var/datum/objective/survive/survive_objective = new
|
||||
survive_objective.owner = owner
|
||||
add_objective(survive_objective)
|
||||
|
||||
/datum/antagonist/traitor/proc/steal_targets(datum/mind/victim)
|
||||
var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
|
||||
|
||||
if(!owner.current||owner.current.stat==DEAD)
|
||||
return
|
||||
to_chat(owner.current, "<span class='userdanger'> Target eliminated: [victim.name]</span>")
|
||||
for(var/objective_ in victim.objectives)
|
||||
if(istype(objective_, /datum/objective/assassinate/internal))
|
||||
var/datum/objective/assassinate/internal/objective = objective_
|
||||
if(objective.target==owner)
|
||||
continue
|
||||
else if(this.targets_stolen.Find(objective.target) == 0)
|
||||
var/datum/objective/assassinate/internal/new_objective = new
|
||||
new_objective.owner = owner
|
||||
new_objective.target = objective.target
|
||||
new_objective.update_explanation_text()
|
||||
add_objective(new_objective)
|
||||
this.targets_stolen += objective.target
|
||||
var/status_text = objective.check_completion() ? "neutralised" : "active"
|
||||
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
|
||||
else if(istype(objective_, /datum/objective/destroy/internal))
|
||||
var/datum/objective/destroy/internal/objective = objective_
|
||||
var/datum/objective/destroy/internal/new_objective = new
|
||||
if(objective.target==owner)
|
||||
continue
|
||||
else if(this.targets_stolen.Find(objective.target) == 0)
|
||||
new_objective.owner = owner
|
||||
new_objective.target = objective.target
|
||||
new_objective.update_explanation_text()
|
||||
add_objective(new_objective)
|
||||
this.targets_stolen += objective.target
|
||||
var/status_text = objective.check_completion() ? "neutralised" : "active"
|
||||
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
|
||||
this.last_man_standing = TRUE
|
||||
for(var/objective_ in owner.objectives)
|
||||
if(!is_internal_objective(objective_))
|
||||
continue
|
||||
var/datum/objective/assassinate/internal/objective = objective_
|
||||
if(!objective.check_completion())
|
||||
this.last_man_standing = FALSE
|
||||
return
|
||||
if(this.last_man_standing)
|
||||
if(this.syndicate)
|
||||
to_chat(owner.current,"<span class='userdanger'> All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. </span>")
|
||||
else
|
||||
to_chat(owner.current,"<span class='userdanger'> All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.</span>")
|
||||
replace_escape_objective(owner)
|
||||
|
||||
/datum/antagonist/traitor/proc/iaa_process()
|
||||
var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
|
||||
if(owner&&owner.current&&owner.current.stat!=DEAD)
|
||||
for(var/objective_ in owner.objectives)
|
||||
if(!is_internal_objective(objective_))
|
||||
continue
|
||||
var/datum/objective/assassinate/internal/objective = objective_
|
||||
if(!objective.target)
|
||||
continue
|
||||
if(objective.check_completion())
|
||||
if(objective.stolen)
|
||||
continue
|
||||
else
|
||||
steal_targets(objective.target)
|
||||
objective.stolen = TRUE
|
||||
else
|
||||
if(objective.stolen)
|
||||
var/fail_msg = "<span class='userdanger'>Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! </span>"
|
||||
if(this.last_man_standing)
|
||||
if(this.syndicate)
|
||||
fail_msg += "<span class='userdanger'> You no longer have permission to die. </span>"
|
||||
else
|
||||
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
|
||||
reinstate_escape_objective(owner)
|
||||
this.last_man_standing = FALSE
|
||||
to_chat(owner.current, fail_msg)
|
||||
objective.stolen = FALSE
|
||||
|
||||
/datum/antagonist/traitor/proc/forge_iaa_objectives()
|
||||
var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
|
||||
if(SSticker.mode.target_list.len && SSticker.mode.target_list[owner]) // Is a double agent
|
||||
|
||||
// Assassinate
|
||||
var/datum/mind/target_mind = SSticker.mode.target_list[owner]
|
||||
if(issilicon(target_mind.current))
|
||||
var/datum/objective/destroy/internal/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.target = target_mind
|
||||
destroy_objective.update_explanation_text()
|
||||
else
|
||||
var/datum/objective/assassinate/internal/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.target = target_mind
|
||||
kill_objective.update_explanation_text()
|
||||
add_objective(kill_objective)
|
||||
|
||||
//Optional traitor objective
|
||||
if(prob(PROB_ACTUAL_TRAITOR))
|
||||
employer = "The Syndicate"
|
||||
owner.special_role = TRAITOR_AGENT_ROLE
|
||||
special_role = TRAITOR_AGENT_ROLE
|
||||
this.syndicate = TRUE
|
||||
forge_single_objective()
|
||||
|
||||
else
|
||||
..() // Give them standard objectives.
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/forge_traitor_objectives()
|
||||
forge_iaa_objectives()
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
add_objective(escape_objective)
|
||||
|
||||
/datum/antagonist/traitor/AI/internal_affairs/forge_traitor_objectives()
|
||||
forge_iaa_objectives()
|
||||
var/datum/objective/survive/survive_objective = new
|
||||
survive_objective.owner = owner
|
||||
add_objective(survive_objective)
|
||||
|
||||
/datum/antagonist/traitor/proc/greet_iaa()
|
||||
var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
|
||||
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
|
||||
|
||||
to_chat(owner.current, "<span class='userdanger'>You are the [special_role].</span>")
|
||||
if(this.syndicate)
|
||||
to_chat(owner.current, "<span class='userdanger'>Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.</span>")
|
||||
to_chat(owner.current, "<B><font size=5 color=red>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</font></B>")
|
||||
to_chat(owner.current, "<span class='userdanger'> You have been provided with a standard uplink to accomplish your task. </span>")
|
||||
else
|
||||
to_chat(owner.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
|
||||
to_chat(owner.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
|
||||
to_chat(owner.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
|
||||
|
||||
to_chat(owner.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/traitor/AI/internal_affairs/greet()
|
||||
greet_iaa()
|
||||
|
||||
/datum/antagonist/traitor/human/internal_affairs/greet()
|
||||
greet_iaa()
|
||||
|
||||
|
||||
#undef PROB_ACTUAL_TRAITOR
|
||||
#undef PINPOINTER_EXTRA_RANDOM_RANGE
|
||||
#undef PINPOINTER_MINIMUM_RANGE
|
||||
#undef PINPOINTER_PING_TIME
|
||||
@@ -1,214 +0,0 @@
|
||||
#define MONKEYS_ESCAPED 1
|
||||
#define MONKEYS_LIVED 2
|
||||
#define MONKEYS_DIED 3
|
||||
#define DISEASE_LIVED 4
|
||||
|
||||
/datum/antagonist/monkey
|
||||
name = "Monkey"
|
||||
job_rank = ROLE_MONKEY
|
||||
roundend_category = "monkeys"
|
||||
antagpanel_category = "Monkey"
|
||||
var/datum/team/monkey/monkey_team
|
||||
var/monkey_only = TRUE
|
||||
|
||||
/datum/antagonist/monkey/can_be_owned(datum/mind/new_owner)
|
||||
return ..() && (!monkey_only || ismonkey(new_owner.current))
|
||||
|
||||
/datum/antagonist/monkey/get_team()
|
||||
return monkey_team
|
||||
|
||||
/datum/antagonist/monkey/on_gain()
|
||||
. = ..()
|
||||
SSticker.mode.ape_infectees += owner
|
||||
owner.special_role = "Infected Monkey"
|
||||
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever/monkeymode
|
||||
if(!owner.current.HasDisease(D))
|
||||
owner.current.ForceContractDisease(D)
|
||||
else
|
||||
QDEL_NULL(D)
|
||||
|
||||
/datum/antagonist/monkey/greet()
|
||||
to_chat(owner, "<b>You are a monkey now!</b>")
|
||||
to_chat(owner, "<b>Bite humans to infect them, follow the orders of the monkey leaders, and help fellow monkeys!</b>")
|
||||
to_chat(owner, "<b>Ensure at least one infected monkey escapes on the Emergency Shuttle!</b>")
|
||||
to_chat(owner, "<b><i>As an intelligent monkey, you know how to use technology and how to ventcrawl while wearing things.</i></b>")
|
||||
to_chat(owner, "<b>You can use :k to talk to fellow monkeys!</b>")
|
||||
SEND_SOUND(owner.current, sound('sound/ambience/antag/monkey.ogg'))
|
||||
|
||||
/datum/antagonist/monkey/on_removal()
|
||||
owner.special_role = null
|
||||
SSticker.mode.ape_infectees -= owner
|
||||
|
||||
var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.viruses
|
||||
if(D)
|
||||
D.remove_virus()
|
||||
qdel(D)
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/monkey/create_team(datum/team/monkey/new_team)
|
||||
if(!new_team)
|
||||
for(var/datum/antagonist/monkey/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.monkey_team)
|
||||
monkey_team = H.monkey_team
|
||||
return
|
||||
monkey_team = new /datum/team/monkey
|
||||
monkey_team.update_objectives()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
monkey_team = new_team
|
||||
|
||||
/datum/antagonist/monkey/proc/forge_objectives()
|
||||
objectives |= monkey_team.objectives
|
||||
owner.objectives |= objectives
|
||||
|
||||
/datum/antagonist/monkey/admin_remove(mob/admin)
|
||||
var/mob/living/carbon/monkey/M = owner.current
|
||||
if(istype(M))
|
||||
switch(alert(admin, "Humanize?", "Humanize", "Yes", "No"))
|
||||
if("Yes")
|
||||
if(admin == M)
|
||||
admin = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
|
||||
else
|
||||
M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
|
||||
if("No")
|
||||
//nothing
|
||||
else
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/monkey/leader
|
||||
name = "Monkey Leader"
|
||||
monkey_only = FALSE
|
||||
|
||||
/datum/antagonist/monkey/leader/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/mob/living/carbon/human/H = new_owner.current
|
||||
if(istype(H))
|
||||
switch(alert(admin, "Monkeyize?", "Monkeyize", "Yes", "No"))
|
||||
if("Yes")
|
||||
if(admin == H)
|
||||
admin = H.monkeyize()
|
||||
else
|
||||
H.monkeyize()
|
||||
if("No")
|
||||
//nothing
|
||||
else
|
||||
return
|
||||
new_owner.add_antag_datum(src)
|
||||
log_admin("[key_name(admin)] made [key_name(new_owner.current)] a monkey leader!")
|
||||
message_admins("[key_name_admin(admin)] made [key_name_admin(new_owner.current)] a monkey leader!")
|
||||
|
||||
/datum/antagonist/monkey/leader/on_gain()
|
||||
. = ..()
|
||||
var/obj/item/organ/heart/freedom/F = new
|
||||
F.Insert(owner.current, drop_if_replaced = FALSE)
|
||||
SSticker.mode.ape_leaders += owner
|
||||
owner.special_role = "Monkey Leader"
|
||||
|
||||
/datum/antagonist/monkey/leader/on_removal()
|
||||
SSticker.mode.ape_leaders -= owner
|
||||
var/obj/item/organ/heart/H = new
|
||||
H.Insert(owner.current, drop_if_replaced = FALSE) //replace freedom heart with normal heart
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/monkey/leader/greet()
|
||||
to_chat(owner, "<B><span class='notice'>You are the Jungle Fever patient zero!!</B></span>")
|
||||
to_chat(owner, "<b>You have been planted onto this station by the Animal Rights Consortium.</b>")
|
||||
to_chat(owner, "<b>Soon the disease will transform you into an ape. Afterwards, you will be able spread the infection to others with a bite.</b>")
|
||||
to_chat(owner, "<b>While your infection strain is undetectable by scanners, any other infectees will show up on medical equipment.</b>")
|
||||
to_chat(owner, "<b>Your mission will be deemed a success if any of the live infected monkeys reach CentCom.</b>")
|
||||
to_chat(owner, "<b>As an initial infectee, you will be considered a 'leader' by your fellow monkeys.</b>")
|
||||
to_chat(owner, "<b>You can use :k to talk to fellow monkeys!</b>")
|
||||
SEND_SOUND(owner.current, sound('sound/ambience/antag/monkey.ogg'))
|
||||
|
||||
/datum/objective/monkey
|
||||
explanation_text = "Ensure that infected monkeys escape on the emergency shuttle!"
|
||||
martyr_compatible = TRUE
|
||||
var/monkeys_to_win = 1
|
||||
var/escaped_monkeys = 0
|
||||
|
||||
/datum/objective/monkey/check_completion()
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
|
||||
if (M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase()))
|
||||
escaped_monkeys++
|
||||
if(escaped_monkeys >= monkeys_to_win)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/monkey
|
||||
name = "Monkeys"
|
||||
|
||||
/datum/team/monkey/proc/update_objectives()
|
||||
objectives = list()
|
||||
var/datum/objective/monkey/O = new()
|
||||
O.team = src
|
||||
objectives += O
|
||||
|
||||
/datum/team/monkey/proc/infected_monkeys_alive()
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
|
||||
if(M.HasDisease(D))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/monkey/proc/infected_monkeys_escaped()
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
|
||||
if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase()))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/monkey/proc/infected_humans_escaped()
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/human/M in GLOB.alive_mob_list)
|
||||
if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase()))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/monkey/proc/infected_humans_alive()
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/human/M in GLOB.alive_mob_list)
|
||||
if(M.HasDisease(D))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/team/monkey/proc/get_result()
|
||||
if(infected_monkeys_escaped())
|
||||
return MONKEYS_ESCAPED
|
||||
if(infected_monkeys_alive())
|
||||
return MONKEYS_LIVED
|
||||
if(infected_humans_alive() || infected_humans_escaped())
|
||||
return DISEASE_LIVED
|
||||
return MONKEYS_DIED
|
||||
|
||||
/datum/team/monkey/roundend_report()
|
||||
var/list/parts = list()
|
||||
switch(get_result())
|
||||
if(MONKEYS_ESCAPED)
|
||||
parts += "<span class='greentext big'><B>Monkey Major Victory!</B></span>"
|
||||
parts += "<span class='greentext'><B>Central Command and [station_name()] were taken over by the monkeys! Ook ook!</B></span>"
|
||||
if(MONKEYS_LIVED)
|
||||
parts += "<FONT size = 3><B>Monkey Minor Victory!</B></FONT>"
|
||||
parts += "<span class='greentext'><B>[station_name()] was taken over by the monkeys! Ook ook!</B></span>"
|
||||
if(DISEASE_LIVED)
|
||||
parts += "<span class='redtext big'><B>Monkey Minor Defeat!</B></span>"
|
||||
parts += "<span class='redtext'><B>All the monkeys died, but the disease lives on! The future is uncertain.</B></span>"
|
||||
if(MONKEYS_DIED)
|
||||
parts += "<span class='redtext big'><B>Monkey Major Defeat!</B></span>"
|
||||
parts += "<span class='redtext'><B>All the monkeys died, and Jungle Fever was wiped out!</B></span>"
|
||||
var/list/leaders = get_antagonists(/datum/antagonist/monkey/leader, TRUE)
|
||||
var/list/monkeys = get_antagonists(/datum/antagonist/monkey, TRUE)
|
||||
|
||||
if(LAZYLEN(leaders))
|
||||
parts += "<span class='header'>The monkey leaders were:</span>"
|
||||
parts += printplayerlist(SSticker.mode.ape_leaders)
|
||||
if(LAZYLEN(monkeys))
|
||||
parts += "<span class='header'>The monkeys were:</span>"
|
||||
parts += printplayerlist(SSticker.mode.ape_infectees)
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
@@ -1,155 +0,0 @@
|
||||
/datum/antagonist/ninja
|
||||
name = "Ninja"
|
||||
antagpanel_category = "Ninja"
|
||||
job_rank = ROLE_NINJA
|
||||
var/helping_station = FALSE
|
||||
var/give_objectives = TRUE
|
||||
var/give_equipment = TRUE
|
||||
|
||||
|
||||
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_ninja_icons_added(M)
|
||||
|
||||
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_ninja_icons_removed(M)
|
||||
|
||||
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current)
|
||||
return H.equipOutfit(/datum/outfit/ninja)
|
||||
|
||||
/datum/antagonist/ninja/proc/addMemories()
|
||||
antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
|
||||
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!<br>"
|
||||
antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.<br>"
|
||||
|
||||
/datum/antagonist/ninja/proc/addObjectives(quantity = 6)
|
||||
var/list/possible_targets = list()
|
||||
for(var/datum/mind/M in SSticker.minds)
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
if(ishuman(M.current))
|
||||
if(M.special_role)
|
||||
possible_targets[M] = 0 //bad-guy
|
||||
else if(M.assigned_role in GLOB.command_positions)
|
||||
possible_targets[M] = 1 //good-guy
|
||||
|
||||
var/list/possible_objectives = list(1,2,3,4)
|
||||
|
||||
while(objectives.len < quantity)
|
||||
switch(pick_n_take(possible_objectives))
|
||||
if(1) //research
|
||||
var/datum/objective/download/O = new /datum/objective/download()
|
||||
O.owner = owner
|
||||
O.gen_amount_goal()
|
||||
objectives += O
|
||||
|
||||
if(2) //steal
|
||||
var/datum/objective/steal/special/O = new /datum/objective/steal/special()
|
||||
O.owner = owner
|
||||
objectives += O
|
||||
|
||||
if(3) //protect/kill
|
||||
if(!possible_targets.len) continue
|
||||
var/index = rand(1,possible_targets.len)
|
||||
var/datum/mind/M = possible_targets[index]
|
||||
var/is_bad_guy = possible_targets[M]
|
||||
possible_targets.Cut(index,index+1)
|
||||
|
||||
if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
|
||||
var/datum/objective/assassinate/O = new /datum/objective/assassinate()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]."
|
||||
objectives += O
|
||||
else //protect
|
||||
var/datum/objective/protect/O = new /datum/objective/protect()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
|
||||
objectives += O
|
||||
if(4) //debrain/capture
|
||||
if(!possible_targets.len) continue
|
||||
var/selected = rand(1,possible_targets.len)
|
||||
var/datum/mind/M = possible_targets[selected]
|
||||
var/is_bad_guy = possible_targets[M]
|
||||
possible_targets.Cut(selected,selected+1)
|
||||
|
||||
if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy)
|
||||
var/datum/objective/debrain/O = new /datum/objective/debrain()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Steal the brain of [M.current.real_name]."
|
||||
objectives += O
|
||||
else //capture
|
||||
var/datum/objective/capture/O = new /datum/objective/capture()
|
||||
O.owner = owner
|
||||
O.gen_amount_goal()
|
||||
objectives += O
|
||||
else
|
||||
break
|
||||
var/datum/objective/O = new /datum/objective/survive()
|
||||
O.owner = owner
|
||||
owner.objectives |= objectives
|
||||
|
||||
|
||||
/proc/remove_ninja(mob/living/L)
|
||||
if(!L || !L.mind)
|
||||
return FALSE
|
||||
var/datum/antagonist/datum = L.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
datum.on_removal()
|
||||
return TRUE
|
||||
|
||||
/proc/is_ninja(mob/living/M)
|
||||
return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
|
||||
|
||||
/datum/antagonist/ninja/greet()
|
||||
SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
|
||||
to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
|
||||
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
|
||||
to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
|
||||
return
|
||||
|
||||
/datum/antagonist/ninja/on_gain()
|
||||
if(give_objectives)
|
||||
addObjectives()
|
||||
addMemories()
|
||||
if(give_equipment)
|
||||
equip_space_ninja(owner.current)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/adj
|
||||
switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives"))
|
||||
if("Random")
|
||||
helping_station = pick(TRUE,FALSE)
|
||||
adj = ""
|
||||
if("Syndicate")
|
||||
helping_station = FALSE
|
||||
adj = "syndie"
|
||||
if("Nanotrasen")
|
||||
helping_station = TRUE
|
||||
adj = "friendly"
|
||||
if("No objectives")
|
||||
give_objectives = FALSE
|
||||
adj = "objectiveless"
|
||||
else
|
||||
return
|
||||
new_owner.assigned_role = ROLE_NINJA
|
||||
new_owner.special_role = ROLE_NINJA
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].")
|
||||
log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].")
|
||||
|
||||
/datum/antagonist/ninja/antag_listing_name()
|
||||
return ..() + "(Ninja)"
|
||||
|
||||
/datum/antagonist/ninja/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja)
|
||||
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
|
||||
ninjahud.join_hud(ninja)
|
||||
set_antag_hud(ninja, "ninja")
|
||||
|
||||
/datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja)
|
||||
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
|
||||
ninjahud.leave_hud(ninja)
|
||||
set_antag_hud(ninja, null)
|
||||
@@ -1,379 +0,0 @@
|
||||
#define NUKE_RESULT_FLUKE 0
|
||||
#define NUKE_RESULT_NUKE_WIN 1
|
||||
#define NUKE_RESULT_CREW_WIN 2
|
||||
#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3
|
||||
#define NUKE_RESULT_DISK_LOST 4
|
||||
#define NUKE_RESULT_DISK_STOLEN 5
|
||||
#define NUKE_RESULT_NOSURVIVORS 6
|
||||
#define NUKE_RESULT_WRONG_STATION 7
|
||||
#define NUKE_RESULT_WRONG_STATION_DEAD 8
|
||||
|
||||
/datum/antagonist/nukeop
|
||||
name = "Nuclear Operative"
|
||||
roundend_category = "syndicate operatives" //just in case
|
||||
antagpanel_category = "NukeOp"
|
||||
job_rank = ROLE_OPERATIVE
|
||||
var/datum/team/nuclear/nuke_team
|
||||
var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
|
||||
var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint.
|
||||
var/nukeop_outfit = /datum/outfit/syndicate
|
||||
|
||||
/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M)
|
||||
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
|
||||
opshud.join_hud(M)
|
||||
set_antag_hud(M, "synd")
|
||||
|
||||
/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M)
|
||||
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
|
||||
opshud.leave_hud(M)
|
||||
set_antag_hud(M, null)
|
||||
|
||||
/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_synd_icons_added(M)
|
||||
|
||||
/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_synd_icons_removed(M)
|
||||
|
||||
/datum/antagonist/nukeop/proc/equip_op()
|
||||
if(!ishuman(owner.current))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
|
||||
H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs
|
||||
|
||||
H.equipOutfit(nukeop_outfit)
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/nukeop/greet()
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0)
|
||||
to_chat(owner, "<span class='notice'>You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!</span>")
|
||||
owner.announce_objectives()
|
||||
return
|
||||
|
||||
/datum/antagonist/nukeop/on_gain()
|
||||
give_alias()
|
||||
forge_objectives()
|
||||
. = ..()
|
||||
equip_op()
|
||||
memorize_code()
|
||||
if(send_to_spawnpoint)
|
||||
move_to_spawnpoint()
|
||||
|
||||
/datum/antagonist/nukeop/get_team()
|
||||
return nuke_team
|
||||
|
||||
/datum/antagonist/nukeop/proc/assign_nuke()
|
||||
if(nuke_team && !nuke_team.tracked_nuke)
|
||||
nuke_team.memorized_code = random_nukecode()
|
||||
var/obj/machinery/nuclearbomb/syndicate/nuke = locate() in GLOB.nuke_list
|
||||
if(nuke)
|
||||
nuke_team.tracked_nuke = nuke
|
||||
if(nuke.r_code == "ADMIN")
|
||||
nuke.r_code = nuke_team.memorized_code
|
||||
else //Already set by admins/something else?
|
||||
nuke_team.memorized_code = nuke.r_code
|
||||
else
|
||||
stack_trace("Syndicate nuke not found during nuke team creation.")
|
||||
nuke_team.memorized_code = null
|
||||
|
||||
/datum/antagonist/nukeop/proc/give_alias()
|
||||
if(nuke_team && nuke_team.syndicate_name)
|
||||
var/number = 1
|
||||
number = nuke_team.members.Find(owner)
|
||||
owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]"
|
||||
|
||||
/datum/antagonist/nukeop/proc/memorize_code()
|
||||
if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code)
|
||||
antag_memory += "<B>[nuke_team.tracked_nuke] Code</B>: [nuke_team.memorized_code]<br>"
|
||||
to_chat(owner, "The nuclear authorization code is: <B>[nuke_team.memorized_code]</B>")
|
||||
else
|
||||
to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.")
|
||||
|
||||
/datum/antagonist/nukeop/proc/forge_objectives()
|
||||
if(nuke_team)
|
||||
owner.objectives |= nuke_team.objectives
|
||||
|
||||
/datum/antagonist/nukeop/proc/move_to_spawnpoint()
|
||||
var/team_number = 1
|
||||
if(nuke_team)
|
||||
team_number = nuke_team.members.Find(owner)
|
||||
owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1])
|
||||
|
||||
/datum/antagonist/nukeop/leader/move_to_spawnpoint()
|
||||
owner.current.forceMove(pick(GLOB.nukeop_leader_start))
|
||||
|
||||
/datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team)
|
||||
if(!new_team)
|
||||
if(!always_new_team)
|
||||
for(var/datum/antagonist/nukeop/N in GLOB.antagonists)
|
||||
if(!N.owner)
|
||||
continue
|
||||
if(N.nuke_team)
|
||||
nuke_team = N.nuke_team
|
||||
return
|
||||
nuke_team = new /datum/team/nuclear
|
||||
nuke_team.update_objectives()
|
||||
assign_nuke() //This is bit ugly
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
nuke_team = new_team
|
||||
|
||||
/datum/antagonist/nukeop/admin_add(datum/mind/new_owner,mob/admin)
|
||||
new_owner.assigned_role = ROLE_SYNDICATE
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has nuke op'ed [new_owner.current].")
|
||||
log_admin("[key_name(admin)] has nuke op'ed [new_owner.current].")
|
||||
|
||||
/datum/antagonist/nukeop/get_admin_commands()
|
||||
. = ..()
|
||||
.["Send to base"] = CALLBACK(src,.proc/admin_send_to_base)
|
||||
.["Tell code"] = CALLBACK(src,.proc/admin_tell_code)
|
||||
|
||||
/datum/antagonist/nukeop/proc/admin_send_to_base(mob/admin)
|
||||
owner.current.forceMove(pick(GLOB.nukeop_start))
|
||||
|
||||
/datum/antagonist/nukeop/proc/admin_tell_code(mob/admin)
|
||||
var/code
|
||||
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
|
||||
if (length(bombue.r_code) <= 5 && bombue.r_code != initial(bombue.r_code))
|
||||
code = bombue.r_code
|
||||
break
|
||||
if (code)
|
||||
antag_memory += "<B>Syndicate Nuclear Bomb Code</B>: [code]<br>"
|
||||
to_chat(owner.current, "The nuclear authorization code is: <B>[code]</B>")
|
||||
else
|
||||
to_chat(admin, "<span class='danger'>No valid nuke found!</span>")
|
||||
|
||||
/datum/antagonist/nukeop/leader
|
||||
name = "Nuclear Operative Leader"
|
||||
nukeop_outfit = /datum/outfit/syndicate/leader
|
||||
always_new_team = TRUE
|
||||
var/title
|
||||
|
||||
/datum/antagonist/nukeop/leader/memorize_code()
|
||||
..()
|
||||
if(nuke_team && nuke_team.memorized_code)
|
||||
var/obj/item/paper/P = new
|
||||
P.info = "The nuclear authorization code is: <b>[nuke_team.memorized_code]</b>"
|
||||
P.name = "nuclear bomb code"
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(H))
|
||||
P.forceMove(get_turf(H))
|
||||
else
|
||||
H.put_in_hands(P, TRUE)
|
||||
H.update_icons()
|
||||
|
||||
/datum/antagonist/nukeop/leader/give_alias()
|
||||
title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
|
||||
if(nuke_team && nuke_team.syndicate_name)
|
||||
owner.current.real_name = "[nuke_team.syndicate_name] [title]"
|
||||
else
|
||||
owner.current.real_name = "Syndicate [title]"
|
||||
|
||||
/datum/antagonist/nukeop/leader/greet()
|
||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0)
|
||||
to_chat(owner, "<B>You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>")
|
||||
to_chat(owner, "<B>If you feel you are not up to this task, give your ID to another operative.</B>")
|
||||
to_chat(owner, "<B>In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.</B>")
|
||||
owner.announce_objectives()
|
||||
addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1)
|
||||
|
||||
|
||||
/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign()
|
||||
if(!nuke_team)
|
||||
return
|
||||
nuke_team.rename_team(ask_name())
|
||||
|
||||
/datum/team/nuclear/proc/rename_team(new_name)
|
||||
syndicate_name = new_name
|
||||
name = "[syndicate_name] Team"
|
||||
for(var/I in members)
|
||||
var/datum/mind/synd_mind = I
|
||||
var/mob/living/carbon/human/H = synd_mind.current
|
||||
if(!istype(H))
|
||||
continue
|
||||
var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name)
|
||||
H.fully_replace_character_name(H.real_name,chosen_name)
|
||||
|
||||
/datum/antagonist/nukeop/leader/proc/ask_name()
|
||||
var/randomname = pick(GLOB.last_names)
|
||||
var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname)
|
||||
if (!newname)
|
||||
newname = randomname
|
||||
else
|
||||
newname = reject_bad_name(newname)
|
||||
if(!newname)
|
||||
newname = randomname
|
||||
|
||||
return capitalize(newname)
|
||||
|
||||
/datum/antagonist/nukeop/lone
|
||||
name = "Lone Operative"
|
||||
always_new_team = TRUE
|
||||
send_to_spawnpoint = FALSE //Handled by event
|
||||
nukeop_outfit = /datum/outfit/syndicate/full
|
||||
|
||||
/datum/antagonist/nukeop/lone/assign_nuke()
|
||||
if(nuke_team && !nuke_team.tracked_nuke)
|
||||
nuke_team.memorized_code = random_nukecode()
|
||||
var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list
|
||||
if(nuke)
|
||||
nuke_team.tracked_nuke = nuke
|
||||
if(nuke.r_code == "ADMIN")
|
||||
nuke.r_code = nuke_team.memorized_code
|
||||
else //Already set by admins/something else?
|
||||
nuke_team.memorized_code = nuke.r_code
|
||||
else
|
||||
stack_trace("Station self destruct ot found during lone op team creation.")
|
||||
nuke_team.memorized_code = null
|
||||
|
||||
/datum/antagonist/nukeop/reinforcement
|
||||
send_to_spawnpoint = FALSE
|
||||
nukeop_outfit = /datum/outfit/syndicate/no_crystals
|
||||
|
||||
/datum/team/nuclear
|
||||
var/syndicate_name
|
||||
var/obj/machinery/nuclearbomb/tracked_nuke
|
||||
var/core_objective = /datum/objective/nuclear
|
||||
var/memorized_code
|
||||
|
||||
/datum/team/nuclear/New()
|
||||
..()
|
||||
syndicate_name = syndicate_name()
|
||||
|
||||
/datum/team/nuclear/proc/update_objectives()
|
||||
if(core_objective)
|
||||
var/datum/objective/O = new core_objective
|
||||
O.team = src
|
||||
objectives += O
|
||||
|
||||
/datum/team/nuclear/proc/disk_rescued()
|
||||
for(var/obj/item/disk/nuclear/D in GLOB.poi_list)
|
||||
if(!D.onCentCom())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/team/nuclear/proc/operatives_dead()
|
||||
for(var/I in members)
|
||||
var/datum/mind/operative_mind = I
|
||||
if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/team/nuclear/proc/syndies_escaped()
|
||||
var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate")
|
||||
return S && (is_centcom_level(S.z) || is_transit_level(S.z))
|
||||
|
||||
/datum/team/nuclear/proc/get_result()
|
||||
var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME
|
||||
var/disk_rescued = disk_rescued()
|
||||
var/syndies_didnt_escape = !syndies_escaped()
|
||||
var/station_was_nuked = SSticker.mode.station_was_nuked
|
||||
var/nuke_off_station = SSticker.mode.nuke_off_station
|
||||
|
||||
if(nuke_off_station == NUKE_SYNDICATE_BASE)
|
||||
return NUKE_RESULT_FLUKE
|
||||
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
|
||||
return NUKE_RESULT_NUKE_WIN
|
||||
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
|
||||
return NUKE_RESULT_NOSURVIVORS
|
||||
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
|
||||
return NUKE_RESULT_WRONG_STATION
|
||||
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
|
||||
return NUKE_RESULT_WRONG_STATION_DEAD
|
||||
else if ((disk_rescued || evacuation) && operatives_dead())
|
||||
return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD
|
||||
else if (disk_rescued)
|
||||
return NUKE_RESULT_CREW_WIN
|
||||
else if (!disk_rescued && operatives_dead())
|
||||
return NUKE_RESULT_DISK_LOST
|
||||
else if (!disk_rescued && evacuation)
|
||||
return NUKE_RESULT_DISK_STOLEN
|
||||
else
|
||||
return //Undefined result
|
||||
|
||||
/datum/team/nuclear/roundend_report()
|
||||
var/list/parts = list()
|
||||
parts += "<span class='header'>[syndicate_name] Operatives:</span>"
|
||||
|
||||
switch(get_result())
|
||||
if(NUKE_RESULT_FLUKE)
|
||||
parts += "<span class='redtext big'>Humiliating Syndicate Defeat</span>"
|
||||
parts += "<B>The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed!</B> Next time, don't lose the nuke!"
|
||||
if(NUKE_RESULT_NUKE_WIN)
|
||||
parts += "<span class='greentext big'>Syndicate Major Victory!</span>"
|
||||
parts += "<B>[syndicate_name] operatives have destroyed [station_name()]!</B>"
|
||||
if(NUKE_RESULT_NOSURVIVORS)
|
||||
parts += "<span class='neutraltext big'>Total Annihilation</span>"
|
||||
parts += "<B>[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!"
|
||||
if(NUKE_RESULT_WRONG_STATION)
|
||||
parts += "<span class='redtext big'>Crew Minor Victory</span>"
|
||||
parts += "<B>[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't do that!"
|
||||
if(NUKE_RESULT_WRONG_STATION_DEAD)
|
||||
parts += "<span class='redtext big'>[syndicate_name] operatives have earned Darwin Award!</span>"
|
||||
parts += "<B>[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't do that!"
|
||||
if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD)
|
||||
parts += "<span class='redtext big'>Crew Major Victory!</span>"
|
||||
parts += "<B>The Research Staff has saved the disk and killed the [syndicate_name] Operatives</B>"
|
||||
if(NUKE_RESULT_CREW_WIN)
|
||||
parts += "<span class='redtext big'>Crew Major Victory</span>"
|
||||
parts += "<B>The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!</B>"
|
||||
if(NUKE_RESULT_DISK_LOST)
|
||||
parts += "<span class='neutraltext big'>Neutral Victory!</span>"
|
||||
parts += "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!</B>"
|
||||
if(NUKE_RESULT_DISK_STOLEN)
|
||||
parts += "<span class='greentext big'>Syndicate Minor Victory!</span>"
|
||||
parts += "<B>[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()].</B> Next time, don't lose the disk!"
|
||||
else
|
||||
parts += "<span class='neutraltext big'>Neutral Victory</span>"
|
||||
parts += "<B>Mission aborted!</B>"
|
||||
|
||||
var/text = "<br><span class='header'>The syndicate operatives were:</span>"
|
||||
var/purchases = ""
|
||||
var/TC_uses = 0
|
||||
for(var/I in members)
|
||||
var/datum/mind/syndicate = I
|
||||
var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[syndicate.key]
|
||||
if(H)
|
||||
TC_uses += H.total_spent
|
||||
purchases += H.generate_render(show_key = FALSE)
|
||||
text += printplayerlist(members)
|
||||
text += "<br>"
|
||||
text += "(Syndicates used [TC_uses] TC) [purchases]"
|
||||
if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead())
|
||||
text += "<BIG>[icon2html('icons/badass.dmi', world, "badass")]</BIG>"
|
||||
|
||||
parts += text
|
||||
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
|
||||
/datum/team/nuclear/antag_listing_name()
|
||||
if(syndicate_name)
|
||||
return "[syndicate_name] Syndicates"
|
||||
else
|
||||
return "Syndicates"
|
||||
|
||||
/datum/team/nuclear/antag_listing_entry()
|
||||
var/disk_report = "<b>Nuclear Disk(s)</b><br>"
|
||||
disk_report += "<table cellspacing=5>"
|
||||
for(var/obj/item/disk/nuclear/N in GLOB.poi_list)
|
||||
disk_report += "<tr><td>[N.name], "
|
||||
var/atom/disk_loc = N.loc
|
||||
while(!isturf(disk_loc))
|
||||
if(ismob(disk_loc))
|
||||
var/mob/M = disk_loc
|
||||
disk_report += "carried by <a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a> "
|
||||
if(isobj(disk_loc))
|
||||
var/obj/O = disk_loc
|
||||
disk_report += "in \a [O.name] "
|
||||
disk_loc = disk_loc.loc
|
||||
disk_report += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td><td><a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(N)]'>FLW</a></td></tr>"
|
||||
disk_report += "</table>"
|
||||
var/common_part = ..()
|
||||
return common_part + disk_report
|
||||
|
||||
/datum/team/nuclear/is_gamemode_hero()
|
||||
return SSticker.mode.name == "nuclear emergency"
|
||||
@@ -1,132 +0,0 @@
|
||||
/datum/antagonist/pirate
|
||||
name = "Space Pirate"
|
||||
job_rank = ROLE_TRAITOR
|
||||
roundend_category = "space pirates"
|
||||
antagpanel_category = "Pirate"
|
||||
var/datum/team/pirate/crew
|
||||
|
||||
/datum/antagonist/pirate/greet()
|
||||
to_chat(owner, "<span class='boldannounce'>You are a Space Pirate!</span>")
|
||||
to_chat(owner, "<B>The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</B>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/pirate/get_team()
|
||||
return crew
|
||||
|
||||
/datum/antagonist/pirate/create_team(datum/team/pirate/new_team)
|
||||
if(!new_team)
|
||||
for(var/datum/antagonist/pirate/P in GLOB.antagonists)
|
||||
if(!P.owner)
|
||||
continue
|
||||
if(P.crew)
|
||||
crew = P.crew
|
||||
return
|
||||
if(!new_team)
|
||||
crew = new /datum/team/pirate
|
||||
crew.forge_objectives()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
crew = new_team
|
||||
|
||||
/datum/antagonist/pirate/on_gain()
|
||||
if(crew)
|
||||
owner.objectives |= crew.objectives
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/pirate/on_removal()
|
||||
if(crew)
|
||||
owner.objectives -= crew.objectives
|
||||
. = ..()
|
||||
|
||||
/datum/team/pirate
|
||||
name = "Pirate crew"
|
||||
|
||||
/datum/team/pirate/proc/forge_objectives()
|
||||
var/datum/objective/loot/getbooty = new()
|
||||
getbooty.team = src
|
||||
getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas
|
||||
getbooty.update_initial_value()
|
||||
getbooty.update_explanation_text()
|
||||
objectives += getbooty
|
||||
for(var/datum/mind/M in members)
|
||||
M.objectives |= objectives
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list(
|
||||
/obj/structure/reagent_dispensers/beerkeg,
|
||||
/mob/living/simple_animal/parrot,
|
||||
/obj/item/stack/sheet/mineral/gold,
|
||||
/obj/item/stack/sheet/mineral/diamond,
|
||||
/obj/item/stack/spacecash,
|
||||
/obj/item/melee/sabre,)))
|
||||
|
||||
/datum/objective/loot
|
||||
var/area/storage_area //Place where we we will look for the loot.
|
||||
explanation_text = "Acquire valuable loot and store it in designated area."
|
||||
var/target_value = 50000
|
||||
var/initial_value = 0 //Things in the vault at spawn time do not count
|
||||
|
||||
/datum/objective/loot/update_explanation_text()
|
||||
if(storage_area)
|
||||
explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name]."
|
||||
|
||||
/datum/objective/loot/proc/loot_listing()
|
||||
//Lists notable loot.
|
||||
if(!storage_area)
|
||||
return "Nothing"
|
||||
var/list/loot_table = list()
|
||||
for(var/atom/movable/AM in storage_area.GetAllContents())
|
||||
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
|
||||
var/lootname = AM.name
|
||||
var/count = 1
|
||||
if(istype(AM,/obj/item/stack)) //Ugh.
|
||||
var/obj/item/stack/S = AM
|
||||
lootname = S.singular_name
|
||||
count = S.amount
|
||||
if(!loot_table[lootname])
|
||||
loot_table[lootname] = count
|
||||
else
|
||||
loot_table[lootname] += count
|
||||
var/list/loot_texts = list()
|
||||
for(var/key in loot_table)
|
||||
var/amount = loot_table[key]
|
||||
loot_texts += "[amount] [key][amount > 1 ? "s":""]"
|
||||
return loot_texts.Join(", ")
|
||||
|
||||
/datum/objective/loot/proc/get_loot_value()
|
||||
if(!storage_area)
|
||||
return 0
|
||||
var/value = 0
|
||||
for(var/turf/T in storage_area.contents)
|
||||
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
|
||||
return value - initial_value
|
||||
|
||||
/datum/objective/loot/proc/update_initial_value()
|
||||
initial_value = get_loot_value()
|
||||
|
||||
/datum/objective/loot/check_completion()
|
||||
return ..() || get_loot_value() >= target_value
|
||||
|
||||
/datum/team/pirate/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
parts += "<span class='header'>Space Pirates were:</span>"
|
||||
|
||||
var/all_dead = TRUE
|
||||
for(var/datum/mind/M in members)
|
||||
if(considered_alive(M))
|
||||
all_dead = FALSE
|
||||
parts += printplayerlist(members)
|
||||
|
||||
parts += "Loot stolen: "
|
||||
var/datum/objective/loot/L = locate() in objectives
|
||||
parts += L.loot_listing()
|
||||
parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits"
|
||||
|
||||
if(L.check_completion() && !all_dead)
|
||||
parts += "<span class='greentext big'>The pirate crew was successful!</span>"
|
||||
else
|
||||
parts += "<span class='redtext big'>The pirate crew has failed.</span>"
|
||||
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
@@ -1,368 +0,0 @@
|
||||
//How often to check for promotion possibility
|
||||
#define HEAD_UPDATE_PERIOD 300
|
||||
|
||||
/datum/antagonist/rev
|
||||
name = "Revolutionary"
|
||||
roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen
|
||||
antagpanel_category = "Revolution"
|
||||
job_rank = ROLE_REV
|
||||
var/hud_type = "rev"
|
||||
var/datum/team/revolution/rev_team
|
||||
|
||||
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(new_owner.assigned_role in GLOB.command_positions)
|
||||
return FALSE
|
||||
if(new_owner.unconvertable)
|
||||
return FALSE
|
||||
if(new_owner.current && new_owner.current.isloyal())
|
||||
return FALSE
|
||||
|
||||
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_rev_icons_added(M)
|
||||
|
||||
/datum/antagonist/rev/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_rev_icons_removed(M)
|
||||
|
||||
/datum/antagonist/rev/proc/equip_rev()
|
||||
return
|
||||
|
||||
/datum/antagonist/rev/on_gain()
|
||||
. = ..()
|
||||
create_objectives()
|
||||
equip_rev()
|
||||
owner.current.log_message("<font color='red'>Has been converted to the revolution!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
/datum/antagonist/rev/on_removal()
|
||||
remove_objectives()
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/rev/greet()
|
||||
to_chat(owner, "<span class='userdanger'>You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/rev/create_team(datum/team/revolution/new_team)
|
||||
if(!new_team)
|
||||
//For now only one revolution at a time
|
||||
for(var/datum/antagonist/rev/head/H in GLOB.antagonists)
|
||||
if(!H.owner)
|
||||
continue
|
||||
if(H.rev_team)
|
||||
rev_team = H.rev_team
|
||||
return
|
||||
rev_team = new /datum/team/revolution
|
||||
rev_team.update_objectives()
|
||||
rev_team.update_heads()
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
rev_team = new_team
|
||||
|
||||
/datum/antagonist/rev/get_team()
|
||||
return rev_team
|
||||
|
||||
/datum/antagonist/rev/proc/create_objectives()
|
||||
owner.objectives |= rev_team.objectives
|
||||
|
||||
/datum/antagonist/rev/proc/remove_objectives()
|
||||
owner.objectives -= rev_team.objectives
|
||||
|
||||
//Bump up to head_rev
|
||||
/datum/antagonist/rev/proc/promote()
|
||||
var/old_team = rev_team
|
||||
var/datum/mind/old_owner = owner
|
||||
silent = TRUE
|
||||
owner.remove_antag_datum(/datum/antagonist/rev)
|
||||
var/datum/antagonist/rev/head/new_revhead = new()
|
||||
new_revhead.silent = TRUE
|
||||
old_owner.add_antag_datum(new_revhead,old_team)
|
||||
new_revhead.silent = FALSE
|
||||
to_chat(old_owner, "<span class='userdanger'>You have proved your devotion to revolution! You are a head revolutionary now!</span>")
|
||||
|
||||
/datum/antagonist/rev/get_admin_commands()
|
||||
. = ..()
|
||||
.["Promote"] = CALLBACK(src,.proc/admin_promote)
|
||||
|
||||
/datum/antagonist/rev/proc/admin_promote(mob/admin)
|
||||
var/datum/mind/O = owner
|
||||
promote()
|
||||
message_admins("[key_name_admin(admin)] has head-rev'ed [O].")
|
||||
log_admin("[key_name(admin)] has head-rev'ed [O].")
|
||||
|
||||
/datum/antagonist/rev/head/admin_add(datum/mind/new_owner,mob/admin)
|
||||
give_flash = TRUE
|
||||
give_hud = TRUE
|
||||
remove_clumsy = TRUE
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has head-rev'ed [new_owner.current].")
|
||||
log_admin("[key_name(admin)] has head-rev'ed [new_owner.current].")
|
||||
to_chat(new_owner.current, "<span class='userdanger'>You are a member of the revolutionaries' leadership now!</span>")
|
||||
|
||||
/datum/antagonist/rev/head/get_admin_commands()
|
||||
. = ..()
|
||||
. -= "Promote"
|
||||
.["Take flash"] = CALLBACK(src,.proc/admin_take_flash)
|
||||
.["Give flash"] = CALLBACK(src,.proc/admin_give_flash)
|
||||
.["Repair flash"] = CALLBACK(src,.proc/admin_repair_flash)
|
||||
.["Demote"] = CALLBACK(src,.proc/admin_demote)
|
||||
|
||||
/datum/antagonist/rev/head/proc/admin_take_flash(mob/admin)
|
||||
var/list/L = owner.current.get_contents()
|
||||
var/obj/item/device/assembly/flash/flash = locate() in L
|
||||
if (!flash)
|
||||
to_chat(admin, "<span class='danger'>Deleting flash failed!</span>")
|
||||
return
|
||||
qdel(flash)
|
||||
|
||||
/datum/antagonist/rev/head/proc/admin_give_flash(mob/admin)
|
||||
//This is probably overkill but making these impact state annoys me
|
||||
var/old_give_flash = give_flash
|
||||
var/old_give_hud = give_hud
|
||||
var/old_remove_clumsy = remove_clumsy
|
||||
give_flash = TRUE
|
||||
give_hud = FALSE
|
||||
remove_clumsy = FALSE
|
||||
equip_rev()
|
||||
give_flash = old_give_flash
|
||||
give_hud = old_give_hud
|
||||
remove_clumsy = old_remove_clumsy
|
||||
|
||||
/datum/antagonist/rev/head/proc/admin_repair_flash(mob/admin)
|
||||
var/list/L = owner.current.get_contents()
|
||||
var/obj/item/device/assembly/flash/flash = locate() in L
|
||||
if (!flash)
|
||||
to_chat(admin, "<span class='danger'>Repairing flash failed!</span>")
|
||||
else
|
||||
flash.crit_fail = 0
|
||||
flash.update_icon()
|
||||
|
||||
/datum/antagonist/rev/head/proc/admin_demote(datum/mind/target,mob/user)
|
||||
message_admins("[key_name_admin(user)] has demoted [owner.current] from head revolutionary.")
|
||||
log_admin("[key_name(user)] has demoted [owner.current] from head revolutionary.")
|
||||
demote()
|
||||
|
||||
/datum/antagonist/rev/head
|
||||
name = "Head Revolutionary"
|
||||
hud_type = "rev_head"
|
||||
var/remove_clumsy = FALSE
|
||||
var/give_flash = FALSE
|
||||
var/give_hud = TRUE
|
||||
|
||||
/datum/antagonist/rev/head/antag_listing_name()
|
||||
return ..() + "(Leader)"
|
||||
|
||||
/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M)
|
||||
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
|
||||
revhud.join_hud(M)
|
||||
set_antag_hud(M,hud_type)
|
||||
|
||||
/datum/antagonist/rev/proc/update_rev_icons_removed(mob/living/M)
|
||||
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
|
||||
revhud.leave_hud(M)
|
||||
set_antag_hud(M, null)
|
||||
|
||||
/datum/antagonist/rev/proc/can_be_converted(mob/living/candidate)
|
||||
if(!candidate.mind)
|
||||
return FALSE
|
||||
if(!can_be_owned(candidate.mind))
|
||||
return FALSE
|
||||
var/mob/living/carbon/C = candidate //Check to see if the potential rev is implanted
|
||||
if(!istype(C)) //Can't convert simple animals
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE)
|
||||
if(!can_be_converted(rev_mind.current))
|
||||
return FALSE
|
||||
if(stun)
|
||||
if(iscarbon(rev_mind.current))
|
||||
var/mob/living/carbon/carbon_mob = rev_mind.current
|
||||
carbon_mob.silent = max(carbon_mob.silent, 5)
|
||||
carbon_mob.flash_act(1, 1)
|
||||
rev_mind.current.Stun(100)
|
||||
rev_mind.add_antag_datum(/datum/antagonist/rev,rev_team)
|
||||
rev_mind.special_role = ROLE_REV
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/rev/head/proc/demote()
|
||||
var/datum/mind/old_owner = owner
|
||||
var/old_team = rev_team
|
||||
silent = TRUE
|
||||
owner.remove_antag_datum(/datum/antagonist/rev/head)
|
||||
var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev()
|
||||
new_rev.silent = TRUE
|
||||
old_owner.add_antag_datum(new_rev,old_team)
|
||||
new_rev.silent = FALSE
|
||||
to_chat(old_owner, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")
|
||||
|
||||
/datum/antagonist/rev/farewell()
|
||||
if(ishuman(owner.current))
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like they just remembered their real allegiance!</span>", null, null, null, owner.current)
|
||||
to_chat(owner, "<span class='userdanger'>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</span>")
|
||||
else if(issilicon(owner.current))
|
||||
owner.current.visible_message("<span class='deconversion_message'>The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.</span>", null, null, null, owner.current)
|
||||
to_chat(owner, "<span class='userdanger'>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</span>")
|
||||
|
||||
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
|
||||
log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!")
|
||||
if(borged)
|
||||
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
|
||||
owner.special_role = null
|
||||
if(iscarbon(owner.current))
|
||||
var/mob/living/carbon/C = owner.current
|
||||
C.Unconscious(100)
|
||||
owner.remove_antag_datum(type)
|
||||
|
||||
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
|
||||
if(!borged)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/rev/head/equip_rev()
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(H))
|
||||
return
|
||||
|
||||
if(remove_clumsy && owner.assigned_role == "Clown")
|
||||
to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
if(give_flash)
|
||||
var/obj/item/device/assembly/flash/T = new(H)
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store
|
||||
)
|
||||
var/where = H.equip_in_one_of_slots(T, slots)
|
||||
if (!where)
|
||||
to_chat(H, "The Syndicate were unfortunately unable to get you a flash.")
|
||||
else
|
||||
to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.")
|
||||
|
||||
if(give_hud)
|
||||
var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H)
|
||||
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
|
||||
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")
|
||||
|
||||
/datum/team/revolution
|
||||
name = "Revolution"
|
||||
var/max_headrevs = 3
|
||||
|
||||
/datum/team/revolution/proc/update_objectives(initial = FALSE)
|
||||
var/untracked_heads = SSjob.get_all_heads()
|
||||
for(var/datum/objective/mutiny/O in objectives)
|
||||
untracked_heads -= O.target
|
||||
for(var/datum/mind/M in untracked_heads)
|
||||
var/datum/objective/mutiny/new_target = new()
|
||||
new_target.team = src
|
||||
new_target.target = M
|
||||
new_target.update_explanation_text()
|
||||
objectives += new_target
|
||||
for(var/datum/mind/M in members)
|
||||
M.objectives |= objectives
|
||||
|
||||
addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
|
||||
|
||||
/datum/team/revolution/proc/head_revolutionaries()
|
||||
. = list()
|
||||
for(var/datum/mind/M in members)
|
||||
if(M.has_antag_datum(/datum/antagonist/rev/head))
|
||||
. += M
|
||||
|
||||
/datum/team/revolution/proc/update_heads()
|
||||
if(SSticker.HasRoundStarted())
|
||||
var/list/datum/mind/head_revolutionaries = head_revolutionaries()
|
||||
var/list/datum/mind/heads = SSjob.get_all_heads()
|
||||
var/list/sec = SSjob.get_all_sec()
|
||||
|
||||
if(head_revolutionaries.len < max_headrevs && head_revolutionaries.len < round(heads.len - ((8 - sec.len) / 3)))
|
||||
var/list/datum/mind/non_heads = members - head_revolutionaries
|
||||
var/list/datum/mind/promotable = list()
|
||||
for(var/datum/mind/khrushchev in non_heads)
|
||||
if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD)
|
||||
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
|
||||
promotable += khrushchev
|
||||
if(promotable.len)
|
||||
var/datum/mind/new_leader = pick(promotable)
|
||||
var/datum/antagonist/rev/rev = new_leader.has_antag_datum(/datum/antagonist/rev)
|
||||
rev.promote()
|
||||
|
||||
addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
|
||||
|
||||
|
||||
/datum/team/revolution/roundend_report()
|
||||
if(!members.len)
|
||||
return
|
||||
|
||||
var/list/result = list()
|
||||
|
||||
result += "<div class='panel redborder'>"
|
||||
|
||||
var/num_revs = 0
|
||||
var/num_survivors = 0
|
||||
for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
|
||||
if(survivor.ckey)
|
||||
num_survivors++
|
||||
if(survivor.mind)
|
||||
if(is_revolutionary(survivor))
|
||||
num_revs++
|
||||
if(num_survivors)
|
||||
result += "Command's Approval Rating: <B>[100 - round((num_revs/num_survivors)*100, 0.1)]%</B><br>"
|
||||
|
||||
|
||||
var/list/targets = list()
|
||||
var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head)
|
||||
var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE)
|
||||
if(headrevs.len)
|
||||
var/list/headrev_part = list()
|
||||
headrev_part += "<span class='header'>The head revolutionaries were:</span>"
|
||||
headrev_part += printplayerlist(headrevs,TRUE)
|
||||
result += headrev_part.Join("<br>")
|
||||
|
||||
if(revs.len)
|
||||
var/list/rev_part = list()
|
||||
rev_part += "<span class='header'>The revolutionaries were:</span>"
|
||||
rev_part += printplayerlist(revs,TRUE)
|
||||
result += rev_part.Join("<br>")
|
||||
|
||||
var/list/heads = SSjob.get_all_heads()
|
||||
if(heads.len)
|
||||
var/head_text = "<span class='header'>The heads of staff were:</span>"
|
||||
head_text += "<ul class='playerlist'>"
|
||||
for(var/datum/mind/head in heads)
|
||||
var/target = (head in targets)
|
||||
head_text += "<li>"
|
||||
if(target)
|
||||
head_text += "<span class='redtext'>Target</span>"
|
||||
head_text += "[printplayer(head, 1)]</li>"
|
||||
head_text += "</ul><br>"
|
||||
result += head_text
|
||||
|
||||
result += "</div>"
|
||||
|
||||
return result.Join()
|
||||
|
||||
/datum/team/revolution/antag_listing_entry()
|
||||
var/common_part = ..()
|
||||
var/heads_report = "<b>Heads of Staff</b><br>"
|
||||
heads_report += "<table cellspacing=5>"
|
||||
for(var/datum/mind/N in SSjob.get_living_heads())
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
heads_report += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
heads_report += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
heads_report += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a></td>"
|
||||
var/turf/mob_loc = get_turf(M)
|
||||
heads_report += "<td>[mob_loc.loc]</td></tr>"
|
||||
else
|
||||
heads_report += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(N)]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
|
||||
heads_report += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
heads_report += "</table>"
|
||||
return common_part + heads_report
|
||||
|
||||
/datum/team/revolution/is_gamemode_hero()
|
||||
return SSticker.mode.name == "revolution"
|
||||
@@ -1,339 +0,0 @@
|
||||
#define APPRENTICE_DESTRUCTION "destruction"
|
||||
#define APPRENTICE_BLUESPACE "bluespace"
|
||||
#define APPRENTICE_ROBELESS "robeless"
|
||||
#define APPRENTICE_HEALING "healing"
|
||||
|
||||
/datum/antagonist/wizard
|
||||
name = "Space Wizard"
|
||||
roundend_category = "wizards/witches"
|
||||
antagpanel_category = "Wizard"
|
||||
job_rank = ROLE_WIZARD
|
||||
var/give_objectives = TRUE
|
||||
var/strip = TRUE //strip before equipping
|
||||
var/allow_rename = TRUE
|
||||
var/hud_version = "wizard"
|
||||
var/datum/team/wizard/wiz_team //Only created if wizard summons apprentices
|
||||
var/move_to_lair = TRUE
|
||||
var/outfit_type = /datum/outfit/wizard
|
||||
var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */
|
||||
|
||||
/datum/antagonist/wizard/on_gain()
|
||||
register()
|
||||
if(give_objectives)
|
||||
create_objectives()
|
||||
equip_wizard()
|
||||
if(move_to_lair)
|
||||
send_to_lair()
|
||||
. = ..()
|
||||
if(allow_rename)
|
||||
rename_wizard()
|
||||
|
||||
/datum/antagonist/wizard/proc/register()
|
||||
SSticker.mode.wizards |= owner
|
||||
|
||||
/datum/antagonist/wizard/proc/unregister()
|
||||
SSticker.mode.wizards -= src
|
||||
|
||||
/datum/antagonist/wizard/create_team(datum/team/wizard/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
if(!istype(new_team))
|
||||
stack_trace("Wrong team type passed to [type] initialization.")
|
||||
wiz_team = new_team
|
||||
|
||||
/datum/antagonist/wizard/get_team()
|
||||
return wiz_team
|
||||
|
||||
/datum/team/wizard
|
||||
name = "wizard team"
|
||||
var/datum/antagonist/wizard/master_wizard
|
||||
|
||||
/datum/antagonist/wizard/proc/create_wiz_team()
|
||||
wiz_team = new(owner)
|
||||
wiz_team.name = "[owner.current.real_name] team"
|
||||
wiz_team.master_wizard = src
|
||||
update_wiz_icons_added(owner.current)
|
||||
|
||||
/datum/antagonist/wizard/proc/send_to_lair()
|
||||
if(!owner || !owner.current)
|
||||
return
|
||||
if(!GLOB.wizardstart.len)
|
||||
SSjob.SendToLateJoin(owner.current)
|
||||
to_chat(owner, "HOT INSERTION, GO GO GO")
|
||||
owner.current.forceMove(pick(GLOB.wizardstart))
|
||||
|
||||
/datum/antagonist/wizard/proc/create_objectives()
|
||||
switch(rand(1,100))
|
||||
if(1 to 30)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
objectives += kill_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in owner.objectives))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
|
||||
if(31 to 60)
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
objectives += steal_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in owner.objectives))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
|
||||
if(61 to 85)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
objectives += kill_objective
|
||||
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
objectives += steal_objective
|
||||
|
||||
if (!(locate(/datum/objective/survive) in owner.objectives))
|
||||
var/datum/objective/survive/survive_objective = new
|
||||
survive_objective.owner = owner
|
||||
objectives += survive_objective
|
||||
|
||||
else
|
||||
if (!(locate(/datum/objective/hijack) in owner.objectives))
|
||||
var/datum/objective/hijack/hijack_objective = new
|
||||
hijack_objective.owner = owner
|
||||
objectives += hijack_objective
|
||||
|
||||
for(var/datum/objective/O in objectives)
|
||||
owner.objectives += O
|
||||
|
||||
/datum/antagonist/wizard/on_removal()
|
||||
unregister()
|
||||
for(var/objective in objectives)
|
||||
owner.objectives -= objective
|
||||
owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/wizard/proc/equip_wizard()
|
||||
if(!owner)
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(H))
|
||||
return
|
||||
if(strip)
|
||||
H.delete_equipment()
|
||||
//Wizards are human by default. Use the mirror if you want something else.
|
||||
H.set_species(/datum/species/human)
|
||||
if(H.age < wiz_age)
|
||||
H.age = wiz_age
|
||||
H.equipOutfit(outfit_type)
|
||||
|
||||
/datum/antagonist/wizard/greet()
|
||||
to_chat(owner, "<span class='boldannounce'>You are the Space Wizard!</span>")
|
||||
to_chat(owner, "<B>The Space Wizards Federation has given you the following tasks:</B>")
|
||||
owner.announce_objectives()
|
||||
to_chat(owner, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.")
|
||||
to_chat(owner, "The spellbook is bound to you, and others cannot use it.")
|
||||
to_chat(owner, "In your pockets you will find a teleport scroll. Use it as needed.")
|
||||
to_chat(owner,"<B>Remember:</B> do not forget to prepare your spells.")
|
||||
|
||||
/datum/antagonist/wizard/farewell()
|
||||
to_chat(owner, "<span class='userdanger'>You have been brainwashed! You are no longer a wizard!</span>")
|
||||
|
||||
/datum/antagonist/wizard/proc/rename_wizard()
|
||||
set waitfor = FALSE
|
||||
|
||||
var/wizard_name_first = pick(GLOB.wizard_first)
|
||||
var/wizard_name_second = pick(GLOB.wizard_second)
|
||||
var/randomname = "[wizard_name_first] [wizard_name_second]"
|
||||
var/mob/living/wiz_mob = owner.current
|
||||
var/newname = copytext(sanitize(input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
|
||||
|
||||
if (!newname)
|
||||
newname = randomname
|
||||
|
||||
wiz_mob.fully_replace_character_name(wiz_mob.real_name, newname)
|
||||
|
||||
/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_wiz_icons_added(M, wiz_team ? TRUE : FALSE) //Don't bother showing the icon if you're solo wizard
|
||||
M.faction |= ROLE_WIZARD
|
||||
|
||||
/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_wiz_icons_removed(M)
|
||||
M.faction -= ROLE_WIZARD
|
||||
|
||||
|
||||
/datum/antagonist/wizard/get_admin_commands()
|
||||
. = ..()
|
||||
.["Send to Lair"] = CALLBACK(src,.proc/admin_send_to_lair)
|
||||
|
||||
/datum/antagonist/wizard/proc/admin_send_to_lair(mob/admin)
|
||||
owner.current.forceMove(pick(GLOB.wizardstart))
|
||||
|
||||
/datum/antagonist/wizard/apprentice
|
||||
name = "Wizard Apprentice"
|
||||
hud_version = "apprentice"
|
||||
var/datum/mind/master
|
||||
var/school = APPRENTICE_DESTRUCTION
|
||||
outfit_type = /datum/outfit/wizard/apprentice
|
||||
wiz_age = APPRENTICE_AGE_MIN
|
||||
|
||||
/datum/antagonist/wizard/apprentice/greet()
|
||||
to_chat(owner, "<B>You are [master.current.real_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/wizard/apprentice/register()
|
||||
SSticker.mode.apprentices |= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/unregister()
|
||||
SSticker.mode.apprentices -= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/equip_wizard()
|
||||
. = ..()
|
||||
if(!owner)
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(H))
|
||||
return
|
||||
switch(school)
|
||||
if(APPRENTICE_DESTRUCTION)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
|
||||
if(APPRENTICE_BLUESPACE)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
|
||||
if(APPRENTICE_HEALING)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
|
||||
H.put_in_hands(new /obj/item/gun/magic/staff/healing(H))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
|
||||
if(APPRENTICE_ROBELESS)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
|
||||
|
||||
/datum/antagonist/wizard/apprentice/create_objectives()
|
||||
var/datum/objective/protect/new_objective = new /datum/objective/protect
|
||||
new_objective.owner = owner
|
||||
new_objective.target = master
|
||||
new_objective.explanation_text = "Protect [master.current.real_name], the wizard."
|
||||
owner.objectives += new_objective
|
||||
objectives += new_objective
|
||||
|
||||
//Random event wizard
|
||||
/datum/antagonist/wizard/apprentice/imposter
|
||||
name = "Wizard Imposter"
|
||||
allow_rename = FALSE
|
||||
move_to_lair = FALSE
|
||||
|
||||
/datum/antagonist/wizard/apprentice/imposter/greet()
|
||||
to_chat(owner, "<B>You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!</B>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/wizard/apprentice/imposter/equip_wizard()
|
||||
var/mob/living/carbon/human/master_mob = master.current
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!istype(master_mob) || !istype(H))
|
||||
return
|
||||
if(master_mob.ears)
|
||||
H.equip_to_slot_or_del(new master_mob.ears.type, slot_ears)
|
||||
if(master_mob.w_uniform)
|
||||
H.equip_to_slot_or_del(new master_mob.w_uniform.type, slot_w_uniform)
|
||||
if(master_mob.shoes)
|
||||
H.equip_to_slot_or_del(new master_mob.shoes.type, slot_shoes)
|
||||
if(master_mob.wear_suit)
|
||||
H.equip_to_slot_or_del(new master_mob.wear_suit.type, slot_wear_suit)
|
||||
if(master_mob.head)
|
||||
H.equip_to_slot_or_del(new master_mob.head.type, slot_head)
|
||||
if(master_mob.back)
|
||||
H.equip_to_slot_or_del(new master_mob.back.type, slot_back)
|
||||
|
||||
//Operation: Fuck off and scare people
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
|
||||
|
||||
/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz,join = TRUE)
|
||||
var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
|
||||
wizhud.join_hud(wiz)
|
||||
set_antag_hud(wiz, hud_version)
|
||||
|
||||
/datum/antagonist/wizard/proc/update_wiz_icons_removed(mob/living/wiz)
|
||||
var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
|
||||
wizhud.leave_hud(wiz)
|
||||
set_antag_hud(wiz, null)
|
||||
|
||||
|
||||
/datum/antagonist/wizard/academy
|
||||
name = "Academy Teacher"
|
||||
outfit_type = /datum/outfit/wizard/academy
|
||||
|
||||
/datum/antagonist/wizard/academy/equip_wizard()
|
||||
. = ..()
|
||||
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball)
|
||||
|
||||
var/mob/living/M = owner.current
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M)
|
||||
Implant.implant(M)
|
||||
|
||||
/datum/antagonist/wizard/academy/create_objectives()
|
||||
var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders")
|
||||
new_objective.owner = owner
|
||||
owner.objectives += new_objective
|
||||
objectives += new_objective
|
||||
|
||||
//Solo wizard report
|
||||
/datum/antagonist/wizard/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
parts += printplayer(owner)
|
||||
|
||||
var/count = 1
|
||||
var/wizardwin = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
else
|
||||
parts += "<B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
wizardwin = 0
|
||||
count++
|
||||
|
||||
if(wizardwin)
|
||||
parts += "<span class='greentext'>The wizard was successful!</span>"
|
||||
else
|
||||
parts += "<span class='redtext'>The wizard has failed!</span>"
|
||||
|
||||
if(owner.spell_list.len>0)
|
||||
parts += "<B>[owner.name] used the following spells: </B>"
|
||||
var/list/spell_names = list()
|
||||
for(var/obj/effect/proc_holder/spell/S in owner.spell_list)
|
||||
spell_names += S.name
|
||||
parts += spell_names.Join(", ")
|
||||
|
||||
return parts.Join("<br>")
|
||||
|
||||
//Wizard with apprentices report
|
||||
/datum/team/wizard/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
parts += "<span class='header'>Wizards/witches of [master_wizard.owner.name] team were:</span>"
|
||||
parts += master_wizard.roundend_report()
|
||||
parts += " "
|
||||
parts += "<span class='header'>[master_wizard.owner.name] apprentices were:</span>"
|
||||
parts += printplayerlist(members - master_wizard.owner)
|
||||
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
@@ -142,9 +142,6 @@
|
||||
var/link = FOLLOW_LINK(M, owner)
|
||||
to_chat(M, "[link] [dead_rendered]")
|
||||
|
||||
/mob/camera/imaginary_friend/emote(act,m_type=1,message = null)
|
||||
return
|
||||
|
||||
/mob/camera/imaginary_friend/forceMove(atom/destination)
|
||||
dir = get_dir(get_turf(src), destination)
|
||||
loc = destination
|
||||
|
||||
@@ -305,6 +305,88 @@
|
||||
else
|
||||
return
|
||||
|
||||
/datum/browser/modal/preflikepicker
|
||||
var/settings = list()
|
||||
var/icon/preview_icon = null
|
||||
|
||||
/datum/browser/modal/preflikepicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/settings,inputtype="checkbox", width = 400, height, slidecolor)
|
||||
if (!User)
|
||||
return
|
||||
src.settings = settings
|
||||
|
||||
..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout)
|
||||
set_content(ShowChoices(User))
|
||||
|
||||
/datum/browser/modal/preflikepicker/proc/ShowChoices(mob/user)
|
||||
var/dat = ""
|
||||
|
||||
for (var/name in settings["mainsettings"])
|
||||
var/setting = settings["mainsettings"][name]
|
||||
if (setting["type"] == "datum")
|
||||
dat += "<b>[setting["desc"]]:</b> <a href='?src=[REF(src)];setting=[name];task=input;type=datum;path=[setting["path"]]'>[setting["value"]]</a><BR>"
|
||||
else
|
||||
dat += "<b>[setting["desc"]]:</b> <a href='?src=[REF(src)];setting=[name];task=input;type=[setting["type"]]'>[setting["value"]]</a><BR>"
|
||||
|
||||
if (preview_icon)
|
||||
dat += "<td valign='center'>"
|
||||
|
||||
dat += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
|
||||
|
||||
dat += "</td>"
|
||||
|
||||
dat += "</tr></table>"
|
||||
|
||||
dat += "<hr><center><a href='?src=[REF(src)];button=1'>Ok</a> "
|
||||
|
||||
dat += "</center>"
|
||||
|
||||
return dat
|
||||
|
||||
/datum/browser/modal/preflikepicker/Topic(href,href_list)
|
||||
if (href_list["close"] || !user || !user.client)
|
||||
opentime = 0
|
||||
return
|
||||
if (href_list["task"] == "input")
|
||||
var/setting = href_list["setting"]
|
||||
switch (href_list["type"])
|
||||
if ("datum")
|
||||
settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(typesof(text2path(href_list["path"]))))
|
||||
if ("string")
|
||||
settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]")
|
||||
if ("number")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num
|
||||
if ("boolean")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("Yes","No")
|
||||
if ("ckey")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory
|
||||
if (href_list["button"])
|
||||
var/button = text2num(href_list["button"])
|
||||
if (button <= 3 && button >= 1)
|
||||
selectedbutton = button
|
||||
if (selectedbutton != 1)
|
||||
set_content(ShowChoices(user))
|
||||
open()
|
||||
return
|
||||
for (var/item in href_list)
|
||||
switch(item)
|
||||
if ("close", "button", "src")
|
||||
continue
|
||||
opentime = 0
|
||||
close()
|
||||
|
||||
/proc/presentpreflikepicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor)
|
||||
if (!istype(User))
|
||||
if (istype(User, /client/))
|
||||
var/client/C = User
|
||||
User = C.mob
|
||||
else
|
||||
return
|
||||
var/datum/browser/modal/preflikepicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, settings, width, height, slidecolor)
|
||||
A.open()
|
||||
A.wait()
|
||||
if (A.selectedbutton)
|
||||
return list("button" = A.selectedbutton, "settings" = A.settings)
|
||||
|
||||
// This will allow you to show an icon in the browse window
|
||||
// This is added to mob so that it can be used without a reference to the browser object
|
||||
// There is probably a better place for this...
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
if(H.has_trait(TRAIT_PIERCEIMMUNE))
|
||||
return
|
||||
|
||||
if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
|
||||
/mob/proc/HasDisease(datum/disease/D)
|
||||
for(var/thing in viruses)
|
||||
/mob/living/proc/HasDisease(datum/disease/D)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/DD = thing
|
||||
if(D.IsSame(DD))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/proc/CanContractDisease(datum/disease/D)
|
||||
/mob/living/proc/CanContractDisease(datum/disease/D)
|
||||
if(stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
if(D.GetDiseaseID() in resistances)
|
||||
if(D.GetDiseaseID() in disease_resistances)
|
||||
return FALSE
|
||||
|
||||
if(HasDisease(D))
|
||||
@@ -23,38 +23,10 @@
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/proc/ContactContractDisease(datum/disease/D)
|
||||
/mob/living/proc/ContactContractDisease(datum/disease/D)
|
||||
if(!CanContractDisease(D))
|
||||
return FALSE
|
||||
AddDisease(D)
|
||||
|
||||
|
||||
/mob/proc/AddDisease(datum/disease/D)
|
||||
for(var/datum/disease/advance/P in viruses)
|
||||
if(istype(D, /datum/disease/advance))
|
||||
var/datum/disease/advance/DD = D
|
||||
if (P.totalResistance() < DD.totalTransmittable()) //Overwrite virus if the attacker's Transmission is lower than the defender's Resistance. This does not grant immunity to the lost virus.
|
||||
P.remove_virus()
|
||||
|
||||
if (!viruses.len) //Only add the new virus if it defeated the existing one
|
||||
var/datum/disease/DD = new D.type(1, D, 0)
|
||||
viruses += DD
|
||||
DD.affected_mob = src
|
||||
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
|
||||
|
||||
//Copy properties over. This is so edited diseases persist.
|
||||
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms","processing")
|
||||
for(var/V in DD.vars)
|
||||
if(V in skipped)
|
||||
continue
|
||||
if(islist(DD.vars[V]))
|
||||
var/list/L = D.vars[V]
|
||||
DD.vars[V] = L.Copy()
|
||||
else
|
||||
DD.vars[V] = D.vars[V]
|
||||
|
||||
DD.after_add()
|
||||
DD.affected_mob.med_hud_set_status()
|
||||
D.try_infect(src)
|
||||
|
||||
|
||||
/mob/living/carbon/ContactContractDisease(datum/disease/D, target_zone)
|
||||
@@ -124,34 +96,35 @@
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
|
||||
if(passed)
|
||||
AddDisease(D)
|
||||
D.try_infect(src)
|
||||
|
||||
/mob/proc/AirborneContractDisease(datum/disease/D)
|
||||
if((D.spread_flags & VIRUS_SPREAD_AIRBORNE) && prob((50*D.permeability_mod) - 1))
|
||||
/mob/living/proc/AirborneContractDisease(datum/disease/D, force_spread)
|
||||
if( ((D.spread_flags & DISEASE_SPREAD_AIRBORNE) || force_spread) && prob((50*D.permeability_mod) - 1))
|
||||
ForceContractDisease(D)
|
||||
|
||||
/mob/living/carbon/AirborneContractDisease(datum/disease/D)
|
||||
/mob/living/carbon/AirborneContractDisease(datum/disease/D, force_spread)
|
||||
if(internal)
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/AirborneContractDisease(datum/disease/D)
|
||||
if(dna && (NOBREATH in dna.species.species_traits))
|
||||
if(has_trait(TRAIT_NOBREATH))
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
//Proc to use when you 100% want to infect someone, as long as they aren't immune
|
||||
/mob/proc/ForceContractDisease(datum/disease/D)
|
||||
//Proc to use when you 100% want to try to infect someone (ignoreing protective clothing and such), as long as they aren't immune
|
||||
/mob/living/proc/ForceContractDisease(datum/disease/D, make_copy = TRUE, del_on_fail = FALSE)
|
||||
if(!CanContractDisease(D))
|
||||
if(del_on_fail)
|
||||
qdel(D)
|
||||
return FALSE
|
||||
AddDisease(D)
|
||||
if(!D.try_infect(src, make_copy))
|
||||
if(del_on_fail)
|
||||
qdel(D)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
|
||||
|
||||
if(dna)
|
||||
if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
|
||||
if(has_trait(TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity)
|
||||
return FALSE
|
||||
|
||||
var/can_infect = FALSE
|
||||
@@ -165,4 +138,4 @@
|
||||
for(var/thing in D.required_organs)
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return FALSE
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//Flags
|
||||
var/visibility_flags = 0
|
||||
var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST
|
||||
var/spread_flags = VIRUS_SPREAD_AIRBORNE | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN
|
||||
var/spread_flags = DISEASE_SPREAD_AIRBORNE | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN
|
||||
|
||||
//Fluff
|
||||
var/form = "Virus"
|
||||
@@ -26,7 +26,7 @@
|
||||
var/carrier = FALSE //If our host is only a carrier
|
||||
var/bypasses_immunity = FALSE //Does it skip species virus immunity check? Some things may diseases and not viruses
|
||||
var/permeability_mod = 1
|
||||
var/severity = VIRUS_SEVERITY_POSITIVE
|
||||
var/severity = DISEASE_SEVERITY_NONTHREAT
|
||||
var/list/required_organs = list()
|
||||
var/needs_all_cures = TRUE
|
||||
var/list/strain_data = list() //dna_spread special bullshit
|
||||
@@ -34,9 +34,27 @@
|
||||
var/process_dead = FALSE //if this ticks while the host is dead
|
||||
|
||||
/datum/disease/Destroy()
|
||||
affected_mob = null
|
||||
. = ..()
|
||||
if(affected_mob)
|
||||
remove_disease()
|
||||
SSdisease.active_diseases.Remove(src)
|
||||
return ..()
|
||||
|
||||
//add this disease if the host does not already have too many
|
||||
/datum/disease/proc/try_infect(var/mob/living/infectee, make_copy = TRUE)
|
||||
if(infectee.diseases.len < DISEASE_LIMIT)
|
||||
infect(infectee, make_copy)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//add the disease with no checks
|
||||
/datum/disease/proc/infect(var/mob/living/infectee, make_copy = TRUE)
|
||||
var/datum/disease/D = make_copy ? Copy() : src
|
||||
infectee.diseases += D
|
||||
D.affected_mob = infectee
|
||||
SSdisease.active_diseases += D //Add it to the active diseases list, now that it's actually in a mob and being processed.
|
||||
|
||||
D.after_add()
|
||||
infectee.med_hud_set_status()
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
@@ -74,7 +92,7 @@
|
||||
if(!affected_mob)
|
||||
return
|
||||
|
||||
if(!(spread_flags & VIRUS_SPREAD_AIRBORNE) && !force_spread)
|
||||
if(!(spread_flags & DISEASE_SPREAD_AIRBORNE) && !force_spread)
|
||||
return
|
||||
|
||||
if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)))
|
||||
@@ -89,24 +107,25 @@
|
||||
if(istype(T))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, affected_mob))
|
||||
var/turf/V = get_turf(C)
|
||||
if(V)
|
||||
while(TRUE)
|
||||
if(V == T)
|
||||
C.AirborneContractDisease(src)
|
||||
break
|
||||
var/turf/Temp = get_step_towards(V, T)
|
||||
if(!CANATMOSPASS(V, Temp))
|
||||
break
|
||||
V = Temp
|
||||
if(disease_air_spread_walk(T, V))
|
||||
C.AirborneContractDisease(src, force_spread)
|
||||
|
||||
/proc/disease_air_spread_walk(turf/start, turf/end)
|
||||
if(!start || !end)
|
||||
return FALSE
|
||||
while(TRUE)
|
||||
if(end == start)
|
||||
return TRUE
|
||||
var/turf/Temp = get_step_towards(end, start)
|
||||
if(!CANATMOSPASS(end, Temp))
|
||||
return FALSE
|
||||
end = Temp
|
||||
|
||||
|
||||
/datum/disease/proc/cure(add_resistance = TRUE)
|
||||
if(affected_mob)
|
||||
if(disease_flags & CAN_RESIST)
|
||||
var/id = GetDiseaseID()
|
||||
if(add_resistance && !(id in affected_mob.resistances))
|
||||
affected_mob.resistances += id
|
||||
remove_virus()
|
||||
if(add_resistance && (disease_flags & CAN_RESIST))
|
||||
affected_mob.disease_resistances |= GetDiseaseID()
|
||||
qdel(src)
|
||||
|
||||
/datum/disease/proc/IsSame(datum/disease/D)
|
||||
@@ -116,8 +135,19 @@
|
||||
|
||||
|
||||
/datum/disease/proc/Copy()
|
||||
//note that stage is not copied over - the copy starts over at stage 1
|
||||
var/static/list/copy_vars = list("name", "visibility_flags", "disease_flags", "spread_flags", "form", "desc", "agent", "spread_text",
|
||||
"cure_text", "max_stages", "stage_prob", "viable_mobtypes", "cures", "infectivity", "cure_chance",
|
||||
"bypasses_immunity", "permeability_mod", "severity", "required_organs", "needs_all_cures", "strain_data",
|
||||
"infectable_hosts", "process_dead")
|
||||
|
||||
var/datum/disease/D = new type()
|
||||
D.strain_data = strain_data.Copy()
|
||||
for(var/V in copy_vars)
|
||||
var/val = vars[V]
|
||||
if(islist(val))
|
||||
var/list/L = val
|
||||
val = L.Copy()
|
||||
D.vars[V] = val
|
||||
return D
|
||||
|
||||
/datum/disease/proc/after_add()
|
||||
@@ -127,7 +157,7 @@
|
||||
/datum/disease/proc/GetDiseaseID()
|
||||
return "[type]"
|
||||
|
||||
//don't use this proc directly. this should only ever be called by cure()
|
||||
/datum/disease/proc/remove_virus()
|
||||
affected_mob.viruses -= src //remove the datum from the list
|
||||
/datum/disease/proc/remove_disease()
|
||||
affected_mob.diseases -= src //remove the datum from the list
|
||||
affected_mob.med_hud_set_status()
|
||||
affected_mob = null
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
*/
|
||||
|
||||
#define SYMPTOM_LIMIT 6
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +30,7 @@
|
||||
var/list/symptoms = list() // The symptoms of the disease.
|
||||
var/id = ""
|
||||
var/processing = FALSE
|
||||
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
var/static/list/advance_cures = list(
|
||||
@@ -46,23 +46,8 @@
|
||||
|
||||
*/
|
||||
|
||||
/datum/disease/advance/New(var/process = 1, var/datum/disease/advance/D)
|
||||
if(!istype(D))
|
||||
D = null
|
||||
// Generate symptoms if we weren't given any.
|
||||
|
||||
if(!symptoms || !symptoms.len)
|
||||
|
||||
if(!D || !D.symptoms || !D.symptoms.len)
|
||||
symptoms = GenerateSymptoms(0, 2)
|
||||
else
|
||||
for(var/datum/symptom/S in D.symptoms)
|
||||
var/datum/symptom/new_symp = S.Copy()
|
||||
symptoms += new_symp
|
||||
|
||||
/datum/disease/advance/New()
|
||||
Refresh()
|
||||
..(process, D)
|
||||
return
|
||||
|
||||
/datum/disease/advance/Destroy()
|
||||
if(processing)
|
||||
@@ -70,6 +55,26 @@
|
||||
S.End(src)
|
||||
return ..()
|
||||
|
||||
/datum/disease/advance/try_infect(var/mob/living/infectee, make_copy = TRUE)
|
||||
var/replace_num = infectee.diseases.len + 1 - DISEASE_LIMIT
|
||||
if(replace_num > 0)
|
||||
//see if we are more transmittable than enough diseases to replace them
|
||||
//diseases replaced in this way do not confer immunity
|
||||
var/list/L = list()
|
||||
for(var/datum/disease/advance/P in infectee.diseases)
|
||||
L += P
|
||||
sortTim(L, /proc/cmp_advdisease_resistance_asc)
|
||||
var/datum/disease/advance/competition = L[replace_num]
|
||||
if(totalTransmittable() > competition.totalResistance())
|
||||
for(var/i in 1 to replace_num)
|
||||
var/datum/disease/advance/A = L[replace_num]
|
||||
A.cure(FALSE)
|
||||
else
|
||||
//we are not strong enough to bully our way in
|
||||
return FALSE
|
||||
infect(infectee, make_copy)
|
||||
return TRUE
|
||||
|
||||
// Randomly pick a symptom to activate.
|
||||
/datum/disease/advance/stage_act()
|
||||
..()
|
||||
@@ -85,8 +90,6 @@
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Activate(src)
|
||||
else
|
||||
CRASH("We do not have any symptoms during stage_act()!")
|
||||
|
||||
// Compares type then ID.
|
||||
/datum/disease/advance/IsSame(datum/disease/advance/D)
|
||||
@@ -99,8 +102,15 @@
|
||||
return 1
|
||||
|
||||
// Returns the advance disease with a different reference memory.
|
||||
/datum/disease/advance/Copy(process = 0)
|
||||
return new /datum/disease/advance(process, src, 1)
|
||||
/datum/disease/advance/Copy()
|
||||
var/datum/disease/advance/A = ..()
|
||||
QDEL_LIST(A.symptoms)
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
A.symptoms += S.Copy()
|
||||
A.properties = properties.Copy()
|
||||
A.id = id
|
||||
//this is a new disease starting over at stage 1, so processing is not copied
|
||||
return A
|
||||
|
||||
/*
|
||||
|
||||
@@ -130,7 +140,7 @@
|
||||
var/list/possible_symptoms = list()
|
||||
for(var/symp in SSdisease.list_symptoms)
|
||||
var/datum/symptom/S = new symp
|
||||
if(S.level >= level_min && S.level <= level_max)
|
||||
if(S.naturally_occuring && S.level >= level_min && S.level <= level_max)
|
||||
if(!HasSymptom(S))
|
||||
possible_symptoms += S
|
||||
|
||||
@@ -154,22 +164,18 @@
|
||||
AssignProperties()
|
||||
id = null
|
||||
|
||||
if(!SSdisease.archive_diseases[GetDiseaseID()])
|
||||
var/the_id = GetDiseaseID()
|
||||
if(!SSdisease.archive_diseases[the_id])
|
||||
if(new_name)
|
||||
AssignName()
|
||||
SSdisease.archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
|
||||
SSdisease.archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)
|
||||
SSdisease.archive_diseases[the_id] = src // So we don't infinite loop
|
||||
SSdisease.archive_diseases[the_id] = Copy()
|
||||
|
||||
var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()]
|
||||
AssignName(A.name)
|
||||
var/datum/disease/advance/A = SSdisease.archive_diseases[the_id]
|
||||
name = A.name
|
||||
|
||||
//Generate disease properties based on the effects. Returns an associated list.
|
||||
/datum/disease/advance/proc/GenerateProperties()
|
||||
|
||||
if(!symptoms || !symptoms.len)
|
||||
CRASH("We did not have any symptoms before generating properties.")
|
||||
return
|
||||
|
||||
properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0)
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
@@ -179,7 +185,6 @@
|
||||
properties["transmittable"] += S.transmittable
|
||||
if(!S.neutered)
|
||||
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom
|
||||
return
|
||||
|
||||
// Assign the properties that are in the list.
|
||||
/datum/disease/advance/proc/AssignProperties()
|
||||
@@ -188,7 +193,7 @@
|
||||
if(properties["stealth"] >= 2)
|
||||
visibility_flags = HIDDEN_SCANNER
|
||||
|
||||
SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE))
|
||||
SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), DISEASE_SPREAD_BLOOD, DISEASE_SPREAD_AIRBORNE))
|
||||
|
||||
permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
|
||||
cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20
|
||||
@@ -202,23 +207,23 @@
|
||||
// Assign the spread type and give it the correct description.
|
||||
/datum/disease/advance/proc/SetSpread(spread_id)
|
||||
switch(spread_id)
|
||||
if(VIRUS_SPREAD_NON_CONTAGIOUS)
|
||||
spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS
|
||||
if(DISEASE_SPREAD_NON_CONTAGIOUS)
|
||||
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
|
||||
spread_text = "None"
|
||||
if(VIRUS_SPREAD_SPECIAL)
|
||||
spread_flags = VIRUS_SPREAD_SPECIAL
|
||||
if(DISEASE_SPREAD_SPECIAL)
|
||||
spread_flags = DISEASE_SPREAD_SPECIAL
|
||||
spread_text = "None"
|
||||
if(VIRUS_SPREAD_BLOOD)
|
||||
spread_flags = VIRUS_SPREAD_BLOOD
|
||||
if(DISEASE_SPREAD_BLOOD)
|
||||
spread_flags = DISEASE_SPREAD_BLOOD
|
||||
spread_text = "Blood"
|
||||
if(VIRUS_SPREAD_CONTACT_FLUIDS)
|
||||
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS
|
||||
if(DISEASE_SPREAD_CONTACT_FLUIDS)
|
||||
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS
|
||||
spread_text = "Fluids"
|
||||
if(VIRUS_SPREAD_CONTACT_SKIN)
|
||||
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN
|
||||
if(DISEASE_SPREAD_CONTACT_SKIN)
|
||||
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN
|
||||
spread_text = "On contact"
|
||||
if(VIRUS_SPREAD_AIRBORNE)
|
||||
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_AIRBORNE
|
||||
if(DISEASE_SPREAD_AIRBORNE)
|
||||
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE
|
||||
spread_text = "Airborne"
|
||||
|
||||
/datum/disease/advance/proc/SetSeverity(level_sev)
|
||||
@@ -226,19 +231,19 @@
|
||||
switch(level_sev)
|
||||
|
||||
if(-INFINITY to 0)
|
||||
severity = VIRUS_SEVERITY_POSITIVE
|
||||
severity = DISEASE_SEVERITY_POSITIVE
|
||||
if(1)
|
||||
severity = VIRUS_SEVERITY_NONTHREAT
|
||||
severity = DISEASE_SEVERITY_NONTHREAT
|
||||
if(2)
|
||||
severity = VIRUS_SEVERITY_MINOR
|
||||
severity = DISEASE_SEVERITY_MINOR
|
||||
if(3)
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
severity = DISEASE_SEVERITY_MEDIUM
|
||||
if(4)
|
||||
severity = VIRUS_SEVERITY_HARMFUL
|
||||
severity = DISEASE_SEVERITY_HARMFUL
|
||||
if(5)
|
||||
severity = VIRUS_SEVERITY_DANGEROUS
|
||||
severity = DISEASE_SEVERITY_DANGEROUS
|
||||
if(6 to INFINITY)
|
||||
severity = VIRUS_SEVERITY_BIOHAZARD
|
||||
severity = DISEASE_SEVERITY_BIOHAZARD
|
||||
else
|
||||
severity = "Unknown"
|
||||
|
||||
@@ -253,11 +258,10 @@
|
||||
var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]]
|
||||
cure_text = D.name
|
||||
|
||||
|
||||
return
|
||||
|
||||
// Randomly generate a symptom, has a chance to lose or gain a symptom.
|
||||
/datum/disease/advance/proc/Evolve(min_level, max_level)
|
||||
/datum/disease/advance/proc/Evolve(min_level, max_level, ignore_mutable = FALSE)
|
||||
if(!mutable && !ignore_mutable)
|
||||
return
|
||||
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
|
||||
if(s)
|
||||
AddSymptom(s)
|
||||
@@ -265,27 +269,32 @@
|
||||
return
|
||||
|
||||
// Randomly remove a symptom.
|
||||
/datum/disease/advance/proc/Devolve()
|
||||
/datum/disease/advance/proc/Devolve(ignore_mutable = FALSE)
|
||||
if(!mutable && !ignore_mutable)
|
||||
return
|
||||
if(symptoms.len > 1)
|
||||
var/s = safepick(symptoms)
|
||||
if(s)
|
||||
RemoveSymptom(s)
|
||||
Refresh(TRUE)
|
||||
return
|
||||
|
||||
// Randomly neuter a symptom.
|
||||
/datum/disease/advance/proc/Neuter()
|
||||
/datum/disease/advance/proc/Neuter(ignore_mutable = FALSE)
|
||||
if(!mutable && !ignore_mutable)
|
||||
return
|
||||
if(symptoms.len)
|
||||
var/s = safepick(symptoms)
|
||||
if(s)
|
||||
NeuterSymptom(s)
|
||||
Refresh(TRUE)
|
||||
return
|
||||
|
||||
// Name the disease.
|
||||
/datum/disease/advance/proc/AssignName(name = "Unknown")
|
||||
src.name = name
|
||||
return
|
||||
Refresh()
|
||||
var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()]
|
||||
A.name = name
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
// Return a unique ID of the disease.
|
||||
/datum/disease/advance/GetDiseaseID()
|
||||
@@ -309,17 +318,15 @@
|
||||
if(HasSymptom(S))
|
||||
return
|
||||
|
||||
if(symptoms.len < (SYMPTOM_LIMIT - 1) + rand(-1, 1))
|
||||
if(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))
|
||||
symptoms += S
|
||||
else
|
||||
RemoveSymptom(pick(symptoms))
|
||||
symptoms += S
|
||||
return
|
||||
|
||||
// Simply removes the symptom.
|
||||
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
|
||||
symptoms -= S
|
||||
return
|
||||
|
||||
// Neuter a symptom, so it will only affect stats
|
||||
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
|
||||
@@ -377,7 +384,7 @@
|
||||
if(!user)
|
||||
return
|
||||
|
||||
var/i = SYMPTOM_LIMIT
|
||||
var/i = VIRUS_SYMPTOM_LIMIT
|
||||
|
||||
var/datum/disease/advance/D = new(0, null)
|
||||
D.symptoms = list()
|
||||
@@ -434,5 +441,3 @@
|
||||
|
||||
/datum/disease/advance/proc/totalTransmittable()
|
||||
return properties["transmittable"]
|
||||
|
||||
#undef RANDOM_STARTING_LEVEL
|
||||
|
||||
@@ -1,59 +1,52 @@
|
||||
// Cold
|
||||
|
||||
/datum/disease/advance/cold/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Cold"
|
||||
symptoms = list(new/datum/symptom/sneeze)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/cold/New()
|
||||
name = "Cold"
|
||||
symptoms = list(new/datum/symptom/sneeze)
|
||||
..()
|
||||
|
||||
|
||||
// Flu
|
||||
|
||||
/datum/disease/advance/flu/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Flu"
|
||||
symptoms = list(new/datum/symptom/cough)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/flu/New()
|
||||
name = "Flu"
|
||||
symptoms = list(new/datum/symptom/cough)
|
||||
..()
|
||||
|
||||
|
||||
// Voice Changing
|
||||
|
||||
/datum/disease/advance/voice_change/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Epiglottis Mutation"
|
||||
symptoms = list(new/datum/symptom/voice_change)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/voice_change/New()
|
||||
name = "Epiglottis Mutation"
|
||||
symptoms = list(new/datum/symptom/voice_change)
|
||||
..()
|
||||
|
||||
|
||||
// Toxin Filter
|
||||
|
||||
/datum/disease/advance/heal/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Liver Enhancer"
|
||||
symptoms = list(new/datum/symptom/heal)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/heal/New()
|
||||
name = "Liver Enhancer"
|
||||
symptoms = list(new/datum/symptom/heal)
|
||||
..()
|
||||
|
||||
|
||||
// Hallucigen
|
||||
|
||||
/datum/disease/advance/hallucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Second Sight"
|
||||
symptoms = list(new/datum/symptom/hallucigen)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/hallucigen/New()
|
||||
name = "Second Sight"
|
||||
symptoms = list(new/datum/symptom/hallucigen)
|
||||
..()
|
||||
|
||||
// Sensory Restoration
|
||||
|
||||
/datum/disease/advance/mind_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Intelligence Booster"
|
||||
symptoms = list(new/datum/symptom/mind_restoration)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/mind_restoration/New()
|
||||
name = "Intelligence Booster"
|
||||
symptoms = list(new/datum/symptom/mind_restoration)
|
||||
..()
|
||||
|
||||
// Sensory Destruction
|
||||
|
||||
/datum/disease/advance/narcolepsy/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
|
||||
if(!D)
|
||||
name = "Experimental Insomnia Cure"
|
||||
symptoms = list(new/datum/symptom/narcolepsy)
|
||||
..(process, D, copy)
|
||||
/datum/disease/advance/narcolepsy/New()
|
||||
name = "Experimental Insomnia Cure"
|
||||
symptoms = list(new/datum/symptom/narcolepsy)
|
||||
..()
|
||||
@@ -40,7 +40,7 @@ BONUS
|
||||
return
|
||||
if(A.properties["stealth"] >= 4)
|
||||
suppress_warning = TRUE
|
||||
if(A.spread_flags &= VIRUS_SPREAD_AIRBORNE) //infect bystanders
|
||||
if(A.spread_flags &= DISEASE_SPREAD_AIRBORNE) //infect bystanders
|
||||
infective = TRUE
|
||||
if(A.properties["resistance"] >= 3) //strong enough to drop items
|
||||
power = 1.5
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
//A neutered symptom has no effect, and only affects statistics.
|
||||
var/neutered = FALSE
|
||||
var/list/thresholds
|
||||
var/naturally_occuring = TRUE //if this symptom can appear from /datum/disease/advance/GenerateSymptoms()
|
||||
|
||||
/datum/symptom/New()
|
||||
var/list/S = SSdisease.list_symptoms
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
form = "Infection"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS
|
||||
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS
|
||||
cure_text = "Ethanol"
|
||||
cures = list("ethanol")
|
||||
agent = "Excess Lepidopticides"
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate butterflies."
|
||||
severity = VIRUS_SEVERITY_MINOR
|
||||
severity = DISEASE_SEVERITY_MINOR
|
||||
|
||||
/datum/disease/anxiety/stage_act()
|
||||
..()
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 1
|
||||
desc = "If left untreated the subject will become very weak, and may vomit often."
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
severity = DISEASE_SEVERITY_MEDIUM
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS
|
||||
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
|
||||
visibility_flags = HIDDEN_PANDEMIC
|
||||
required_organs = list(/obj/item/organ/appendix)
|
||||
bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
form = "Infection"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS
|
||||
spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS
|
||||
cure_text = "Sugar"
|
||||
cures = list("sugar")
|
||||
agent = "Apidae Infection"
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate bees."
|
||||
severity = VIRUS_SEVERITY_MEDIUM
|
||||
severity = DISEASE_SEVERITY_MEDIUM
|
||||
infectable_hosts = list(SPECIES_ORGANIC, SPECIES_UNDEAD) //bees nesting in corpses
|
||||
|
||||
/datum/disease/beesease/stage_act()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user