mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 12:04:48 +01:00
Merge remote-tracking branch 'Paradise/master' into pr/RedWolfie/14277
This commit is contained in:
@@ -47144,7 +47144,7 @@
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/circuitboard/powermonitor,
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 3;
|
||||
pixel_y = -3
|
||||
},
|
||||
|
||||
@@ -31415,7 +31415,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/ruin/powered/snow_cabin)
|
||||
"aL" = (
|
||||
/obj/structure/displaycase/captain,
|
||||
/obj/mecha/working/ripley/mining,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/ruin/powered/snow_cabin)
|
||||
"aM" = (
|
||||
@@ -392,12 +392,6 @@
|
||||
/obj/structure/filingcabinet,
|
||||
/turf/simulated/floor/pod/dark,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
"UM" = (
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/pod/dark,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
"Wg" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/ruin/powered/snow_biodome)
|
||||
@@ -484,7 +478,7 @@ HP
|
||||
tl
|
||||
PK
|
||||
gz
|
||||
UM
|
||||
HP
|
||||
Wg
|
||||
ak
|
||||
ak
|
||||
|
||||
@@ -0,0 +1,614 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"c" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 1
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"d" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"e" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"g" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 4
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"h" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"l" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"m" = (
|
||||
/obj/effect/spawner/random_spawners/grille_often,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"n" = (
|
||||
/obj/effect/spawner/random_spawners/grille_maybe,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"o" = (
|
||||
/obj/random/tool,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"p" = (
|
||||
/obj/structure/girder/displaced,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"r" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 2;
|
||||
d2 = 8;
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"u" = (
|
||||
/obj/structure/door_assembly/door_assembly_sec,
|
||||
/obj/item/airlock_electronics,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"v" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"x" = (
|
||||
/obj/structure/disposalpipe/junction,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"y" = (
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"z" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"B" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"C" = (
|
||||
/obj/structure/disposalpipe/broken{
|
||||
dir = 1
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"D" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"E" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"F" = (
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"G" = (
|
||||
/obj/random/toolbox,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"I" = (
|
||||
/obj/structure/grille/broken,
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"J" = (
|
||||
/obj/structure/disposalpipe/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"K" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"N" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"O" = (
|
||||
/obj/machinery/power/apc/worn_out{
|
||||
pixel_y = -24
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"Q" = (
|
||||
/obj/effect/decal/cleanable/shreds{
|
||||
pixel_x = 4;
|
||||
pixel_y = 3
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"T" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"U" = (
|
||||
/obj/effect/spawner/random_barrier/wall_probably,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"V" = (
|
||||
/turf/simulated/wall,
|
||||
/area/space)
|
||||
"X" = (
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"Y" = (
|
||||
/obj/item/shard,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"Z" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
a
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
d
|
||||
d
|
||||
d
|
||||
r
|
||||
r
|
||||
d
|
||||
r
|
||||
a
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
d
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
d
|
||||
X
|
||||
m
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
Z
|
||||
X
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
g
|
||||
F
|
||||
X
|
||||
E
|
||||
I
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
F
|
||||
v
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
r
|
||||
J
|
||||
x
|
||||
C
|
||||
E
|
||||
v
|
||||
F
|
||||
X
|
||||
E
|
||||
X
|
||||
v
|
||||
g
|
||||
Z
|
||||
X
|
||||
X
|
||||
F
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
y
|
||||
E
|
||||
X
|
||||
E
|
||||
Y
|
||||
X
|
||||
n
|
||||
X
|
||||
h
|
||||
E
|
||||
F
|
||||
X
|
||||
v
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
B
|
||||
l
|
||||
p
|
||||
X
|
||||
X
|
||||
y
|
||||
p
|
||||
X
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
v
|
||||
X
|
||||
o
|
||||
X
|
||||
X
|
||||
Z
|
||||
l
|
||||
X
|
||||
E
|
||||
a
|
||||
X
|
||||
X
|
||||
V
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
Z
|
||||
Q
|
||||
v
|
||||
X
|
||||
y
|
||||
v
|
||||
D
|
||||
y
|
||||
U
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
n
|
||||
r
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
I
|
||||
v
|
||||
v
|
||||
X
|
||||
v
|
||||
t
|
||||
O
|
||||
V
|
||||
X
|
||||
X
|
||||
F
|
||||
E
|
||||
Z
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
J
|
||||
b
|
||||
c
|
||||
v
|
||||
G
|
||||
V
|
||||
X
|
||||
E
|
||||
e
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
V
|
||||
X
|
||||
Z
|
||||
X
|
||||
X
|
||||
X
|
||||
u
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
e
|
||||
Z
|
||||
r
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
v
|
||||
N
|
||||
E
|
||||
E
|
||||
K
|
||||
X
|
||||
v
|
||||
o
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
E
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
E
|
||||
J
|
||||
C
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
E
|
||||
X
|
||||
T
|
||||
X
|
||||
Z
|
||||
X
|
||||
n
|
||||
v
|
||||
X
|
||||
z
|
||||
n
|
||||
X
|
||||
Z
|
||||
X
|
||||
d
|
||||
a
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
F
|
||||
X
|
||||
X
|
||||
X
|
||||
p
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
r
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
v
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
r
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
a
|
||||
a
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
d
|
||||
r
|
||||
d
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
r
|
||||
a
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
@@ -0,0 +1,631 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space)
|
||||
"c" = (
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"d" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/space)
|
||||
"e" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"h" = (
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"j" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"l" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"m" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"n" = (
|
||||
/obj/item/stack/cable_coil/cut,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"o" = (
|
||||
/obj/machinery/door/airlock/command{
|
||||
max_integrity = 40
|
||||
},
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"p" = (
|
||||
/mob/living/simple_animal/hostile/carp,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"q" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"s" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/structure/door_assembly/door_assembly_com,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"u" = (
|
||||
/obj/item/clothing/head/bio_hood/virology,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"w" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"x" = (
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"y" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/door_assembly/door_assembly_vault{
|
||||
anchored = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/space)
|
||||
"z" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"A" = (
|
||||
/obj/structure/closet/crate,
|
||||
/obj/item/reagent_containers/glass/beaker/bluespace,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"B" = (
|
||||
/obj/item/shard{
|
||||
icon_state = "small"
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"C" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"D" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space)
|
||||
"E" = (
|
||||
/obj/item/reagent_containers/glass/beaker/large,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"F" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor,
|
||||
/area/space)
|
||||
"G" = (
|
||||
/obj/structure/safe,
|
||||
/obj/item/stack/sheet/mineral/bananium{
|
||||
amount = 5
|
||||
},
|
||||
/obj/item/stack/ore/bluespace_crystal/refined{
|
||||
amount = 3
|
||||
},
|
||||
/obj/item/dnainjector/comic,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"H" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/shard{
|
||||
icon_state = "medium"
|
||||
},
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"I" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"J" = (
|
||||
/mob/living/simple_animal/hostile/carp,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"L" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"M" = (
|
||||
/turf/simulated/floor,
|
||||
/area/space)
|
||||
"N" = (
|
||||
/obj/item/clothing/suit/bio_suit/virology,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"O" = (
|
||||
/obj/item/shard{
|
||||
icon_state = "small"
|
||||
},
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"P" = (
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"R" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/template_noop,
|
||||
/area/space)
|
||||
"S" = (
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"T" = (
|
||||
/turf/simulated/wall,
|
||||
/area/space)
|
||||
"U" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
"V" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"W" = (
|
||||
/obj/effect/landmark/burnturf,
|
||||
/turf/simulated/floor/plating/burnt,
|
||||
/area/space)
|
||||
"X" = (
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"Y" = (
|
||||
/obj/structure/girder/reinforced,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/space)
|
||||
"Z" = (
|
||||
/obj/machinery/computer/pandemic{
|
||||
circuit = /obj/effect/decal/cleanable/shreds
|
||||
},
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
d
|
||||
d
|
||||
d
|
||||
d
|
||||
d
|
||||
Y
|
||||
x
|
||||
S
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
d
|
||||
G
|
||||
A
|
||||
U
|
||||
F
|
||||
d
|
||||
z
|
||||
T
|
||||
T
|
||||
T
|
||||
T
|
||||
o
|
||||
T
|
||||
I
|
||||
p
|
||||
O
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
Y
|
||||
c
|
||||
U
|
||||
c
|
||||
U
|
||||
d
|
||||
X
|
||||
w
|
||||
M
|
||||
c
|
||||
U
|
||||
M
|
||||
T
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
a
|
||||
Y
|
||||
M
|
||||
F
|
||||
F
|
||||
q
|
||||
d
|
||||
z
|
||||
m
|
||||
F
|
||||
M
|
||||
F
|
||||
M
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
d
|
||||
d
|
||||
y
|
||||
d
|
||||
d
|
||||
Y
|
||||
X
|
||||
w
|
||||
X
|
||||
n
|
||||
X
|
||||
w
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
P
|
||||
J
|
||||
X
|
||||
T
|
||||
T
|
||||
T
|
||||
x
|
||||
T
|
||||
I
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
R
|
||||
X
|
||||
w
|
||||
X
|
||||
b
|
||||
x
|
||||
x
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
p
|
||||
s
|
||||
T
|
||||
m
|
||||
w
|
||||
T
|
||||
R
|
||||
X
|
||||
B
|
||||
X
|
||||
w
|
||||
X
|
||||
x
|
||||
z
|
||||
I
|
||||
s
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
s
|
||||
I
|
||||
T
|
||||
M
|
||||
F
|
||||
T
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
X
|
||||
x
|
||||
x
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
T
|
||||
c
|
||||
F
|
||||
T
|
||||
X
|
||||
X
|
||||
c
|
||||
F
|
||||
b
|
||||
j
|
||||
D
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
t
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
C
|
||||
I
|
||||
T
|
||||
X
|
||||
M
|
||||
N
|
||||
s
|
||||
I
|
||||
I
|
||||
L
|
||||
q
|
||||
q
|
||||
b
|
||||
T
|
||||
I
|
||||
s
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
l
|
||||
T
|
||||
T
|
||||
T
|
||||
I
|
||||
I
|
||||
u
|
||||
j
|
||||
W
|
||||
c
|
||||
U
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
I
|
||||
s
|
||||
p
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
p
|
||||
I
|
||||
I
|
||||
c
|
||||
H
|
||||
Z
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
V
|
||||
I
|
||||
I
|
||||
s
|
||||
V
|
||||
C
|
||||
I
|
||||
I
|
||||
s
|
||||
h
|
||||
T
|
||||
T
|
||||
T
|
||||
T
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
E
|
||||
I
|
||||
I
|
||||
V
|
||||
I
|
||||
O
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
e
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
e
|
||||
I
|
||||
V
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
h
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
a
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
C
|
||||
I
|
||||
I
|
||||
I
|
||||
I
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
@@ -0,0 +1,824 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"a" = (
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"c" = (
|
||||
/obj/item/trash/popcorn,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"d" = (
|
||||
/obj/effect/spawner/random_spawners/wall_rusted_maybe,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"e" = (
|
||||
/obj/item/poster/random_contraband,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"f" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"g" = (
|
||||
/obj/item/paperplane,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"h" = (
|
||||
/obj/item/trash/can,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"i" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/template_noop,
|
||||
/area/template_noop)
|
||||
"k" = (
|
||||
/obj/item/shard,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"l" = (
|
||||
/obj/item/stack/cable_coil{
|
||||
amount = 10
|
||||
},
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"m" = (
|
||||
/turf/simulated/wall,
|
||||
/area/template_noop)
|
||||
"n" = (
|
||||
/obj/item/stack/sheet/glass,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"p" = (
|
||||
/obj/random/plushie,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"q" = (
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"t" = (
|
||||
/obj/machinery/computer/arcade/battle,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/template_noop)
|
||||
"u" = (
|
||||
/obj/random/tool,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"v" = (
|
||||
/obj/item/trash/syndi_cakes,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"w" = (
|
||||
/obj/item/stack/tickets,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"x" = (
|
||||
/obj/structure/bookcase/random/fiction,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"y" = (
|
||||
/obj/item/storage/pill_bottle/random_meds/labelled,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"z" = (
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"A" = (
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"B" = (
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"D" = (
|
||||
/obj/item/paper,
|
||||
/obj/item/paper,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"F" = (
|
||||
/obj/random/tool,
|
||||
/turf/simulated/floor/plating/damaged,
|
||||
/area/template_noop)
|
||||
"G" = (
|
||||
/obj/item/poster/random_official,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"H" = (
|
||||
/obj/item/stack/sheet/wood,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"I" = (
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/rods,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"J" = (
|
||||
/obj/item/trash/pistachios,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"K" = (
|
||||
/obj/structure/lattice,
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"L" = (
|
||||
/obj/structure/girder,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"M" = (
|
||||
/obj/item/stack/sheet/metal,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"O" = (
|
||||
/obj/structure/girder/displaced,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"S" = (
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"U" = (
|
||||
/obj/item/stack/sheet/wood,
|
||||
/obj/item/stack/sheet/wood,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"V" = (
|
||||
/obj/item/circuitboard/arcade,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"W" = (
|
||||
/obj/item/stack/tickets,
|
||||
/obj/item/stack/tickets,
|
||||
/obj/item/stack/tickets,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
"Z" = (
|
||||
/obj/item/paper,
|
||||
/turf/space,
|
||||
/area/template_noop)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(2,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(3,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(4,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(5,1,1) = {"
|
||||
i
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(6,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
I
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
M
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(7,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
k
|
||||
A
|
||||
A
|
||||
O
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
m
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(8,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
H
|
||||
A
|
||||
G
|
||||
n
|
||||
m
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(9,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
m
|
||||
A
|
||||
w
|
||||
A
|
||||
M
|
||||
S
|
||||
A
|
||||
A
|
||||
d
|
||||
B
|
||||
M
|
||||
A
|
||||
O
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(10,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
Z
|
||||
A
|
||||
W
|
||||
B
|
||||
S
|
||||
h
|
||||
M
|
||||
L
|
||||
A
|
||||
c
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(11,1,1) = {"
|
||||
a
|
||||
i
|
||||
B
|
||||
w
|
||||
A
|
||||
S
|
||||
A
|
||||
F
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
Z
|
||||
A
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(12,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
H
|
||||
L
|
||||
S
|
||||
m
|
||||
m
|
||||
b
|
||||
A
|
||||
A
|
||||
Z
|
||||
w
|
||||
B
|
||||
A
|
||||
i
|
||||
a
|
||||
"}
|
||||
(13,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
B
|
||||
O
|
||||
A
|
||||
B
|
||||
A
|
||||
M
|
||||
A
|
||||
D
|
||||
K
|
||||
z
|
||||
S
|
||||
H
|
||||
B
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(14,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
n
|
||||
A
|
||||
y
|
||||
f
|
||||
B
|
||||
A
|
||||
z
|
||||
B
|
||||
A
|
||||
m
|
||||
t
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(15,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
z
|
||||
H
|
||||
A
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
q
|
||||
z
|
||||
z
|
||||
A
|
||||
A
|
||||
O
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(16,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
S
|
||||
U
|
||||
B
|
||||
B
|
||||
A
|
||||
A
|
||||
S
|
||||
A
|
||||
M
|
||||
B
|
||||
u
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(17,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
M
|
||||
H
|
||||
w
|
||||
Z
|
||||
B
|
||||
x
|
||||
S
|
||||
B
|
||||
S
|
||||
A
|
||||
k
|
||||
J
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(18,1,1) = {"
|
||||
a
|
||||
a
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
B
|
||||
z
|
||||
A
|
||||
O
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(19,1,1) = {"
|
||||
i
|
||||
a
|
||||
A
|
||||
A
|
||||
M
|
||||
z
|
||||
S
|
||||
w
|
||||
S
|
||||
M
|
||||
A
|
||||
m
|
||||
p
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(20,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
A
|
||||
O
|
||||
H
|
||||
v
|
||||
A
|
||||
V
|
||||
H
|
||||
A
|
||||
B
|
||||
L
|
||||
A
|
||||
M
|
||||
A
|
||||
w
|
||||
a
|
||||
a
|
||||
"}
|
||||
(21,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
e
|
||||
M
|
||||
A
|
||||
w
|
||||
Z
|
||||
w
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(22,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
M
|
||||
O
|
||||
m
|
||||
m
|
||||
L
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
q
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(23,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
B
|
||||
k
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
g
|
||||
n
|
||||
A
|
||||
O
|
||||
A
|
||||
A
|
||||
B
|
||||
B
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(24,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
M
|
||||
A
|
||||
A
|
||||
l
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(25,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
w
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(26,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
B
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
a
|
||||
a
|
||||
"}
|
||||
(27,1,1) = {"
|
||||
a
|
||||
a
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
B
|
||||
A
|
||||
w
|
||||
A
|
||||
B
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
a
|
||||
a
|
||||
"}
|
||||
(28,1,1) = {"
|
||||
a
|
||||
a
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
w
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
A
|
||||
a
|
||||
i
|
||||
"}
|
||||
(29,1,1) = {"
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
"}
|
||||
(30,1,1) = {"
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
i
|
||||
a
|
||||
a
|
||||
"}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,6 @@
|
||||
"an" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDNW";
|
||||
invisibility = 100;
|
||||
location = "SDNE"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
@@ -292,15 +291,13 @@
|
||||
"aU" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDSW";
|
||||
invisibility = 100;
|
||||
location = "SDNW"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/syndicate_depot/outer)
|
||||
"aV" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4;
|
||||
icon_state = "tube1"
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/syndicate_depot/outer)
|
||||
@@ -429,8 +426,7 @@
|
||||
/area/syndicate_depot/core)
|
||||
"bo" = (
|
||||
/obj/machinery/light{
|
||||
dir = 4;
|
||||
icon_state = "tube1"
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/spawner/random_spawners/syndicate/loot,
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -512,7 +508,6 @@
|
||||
id = "syndi_depot_rear";
|
||||
idle_power_usage = 0;
|
||||
name = "mysterious button";
|
||||
normaldoorcontrol = 0;
|
||||
pixel_x = 24;
|
||||
use_power = 0
|
||||
},
|
||||
@@ -663,8 +658,8 @@
|
||||
/obj/machinery/turretid/syndicate{
|
||||
name = "external turret controls";
|
||||
pixel_x = -32;
|
||||
pixel_y = 0;
|
||||
req_access = list(150)
|
||||
req_access = null;
|
||||
req_access_txt = "150"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
@@ -745,9 +740,8 @@
|
||||
/area/syndicate_depot/core)
|
||||
"ce" = (
|
||||
/obj/machinery/light/small{
|
||||
tag = "icon-bulb1 (EAST)";
|
||||
icon_state = "bulb1";
|
||||
dir = 4
|
||||
dir = 4;
|
||||
tag = "icon-bulb1 (EAST)"
|
||||
},
|
||||
/turf/simulated/floor/mineral/silver,
|
||||
/area/syndicate_depot/core)
|
||||
@@ -757,7 +751,6 @@
|
||||
id = "syndi_depot_rear";
|
||||
idle_power_usage = 0;
|
||||
name = "mysterious button";
|
||||
normaldoorcontrol = 0;
|
||||
use_power = 0
|
||||
},
|
||||
/obj/structure/sign/poster/contraband/syndicate_recruitment,
|
||||
@@ -774,8 +767,8 @@
|
||||
/area/syndicate_depot/core)
|
||||
"ci" = (
|
||||
/obj/structure/cable{
|
||||
icon_state = "0-2";
|
||||
d2 = 2
|
||||
d2 = 2;
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/obj/machinery/power/smes/upgraded{
|
||||
charge = 5e+006;
|
||||
@@ -845,7 +838,6 @@
|
||||
"cr" = (
|
||||
/obj/structure/sink{
|
||||
dir = 4;
|
||||
icon_state = "sink";
|
||||
pixel_x = 12
|
||||
},
|
||||
/turf/simulated/floor/mineral/silver,
|
||||
@@ -1154,7 +1146,6 @@
|
||||
"dc" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDSE";
|
||||
invisibility = 100;
|
||||
location = "SDSW"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
@@ -1179,7 +1170,6 @@
|
||||
"df" = (
|
||||
/obj/machinery/navbeacon/invisible{
|
||||
codes_txt = "patrol;next_patrol=SDNE";
|
||||
invisibility = 100;
|
||||
location = "SDSE"
|
||||
},
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
|
||||
@@ -35244,7 +35244,7 @@
|
||||
},
|
||||
/area/bridge)
|
||||
"bnW" = (
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 0;
|
||||
icon_state = "yellow"
|
||||
@@ -72578,7 +72578,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
@@ -75846,7 +75846,7 @@
|
||||
pixel_x = 32;
|
||||
pixel_y = 0
|
||||
},
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -77210,6 +77210,10 @@
|
||||
pixel_x = -22
|
||||
},
|
||||
/obj/item/stack/tape_roll,
|
||||
/obj/machinery/camera/motion{
|
||||
c_tag = "EVA Motion Sensor";
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,51 +137,56 @@
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(target_pressure),
|
||||
"max_rate" = MAX_OUTPUT_PRESSURE,
|
||||
"gas_unit" = "kPa",
|
||||
"step" = 10 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/passive_gate/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
if("max_rate")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/proc/toggle()
|
||||
if(powered())
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure))
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params)
|
||||
if(!istype(W, /obj/item/wrench))
|
||||
|
||||
@@ -192,51 +192,51 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 385, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(target_pressure),
|
||||
"max_rate" = MAX_OUTPUT_PRESSURE,
|
||||
"gas_unit" = "kPa",
|
||||
"step" = 10 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/pump/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure))
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("max_rate")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
target_pressure = clamp(text2num(params["rate"]), 0 , MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/power_change()
|
||||
var/old_stat = stat
|
||||
|
||||
@@ -188,51 +188,51 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 310, 115, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosPump", name, 310, 110, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["rate"] = round(transfer_rate)
|
||||
data["max_rate"] = round(MAX_TRANSFER_RATE)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"rate" = round(transfer_rate),
|
||||
"max_rate" = round(MAX_TRANSFER_RATE),
|
||||
"gas_unit" = "L/s",
|
||||
"step" = 1 // This is for the TGUI <NumberInput> step. It's here since multiple pumps share the same UI, but need different values.
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
|
||||
/obj/machinery/atmospherics/binary/volume_pump/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["rate"])
|
||||
var/rate = href_list["rate"]
|
||||
if(rate == "max")
|
||||
rate = MAX_TRANSFER_RATE
|
||||
. = TRUE
|
||||
else if(rate == "input")
|
||||
rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null
|
||||
if(!isnull(rate))
|
||||
. = TRUE
|
||||
else if(text2num(rate) != null)
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
transfer_rate = clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("max_rate")
|
||||
transfer_rate = MAX_TRANSFER_RATE
|
||||
. = TRUE
|
||||
|
||||
if("min_rate")
|
||||
transfer_rate = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_rate")
|
||||
transfer_rate = clamp(text2num(params["rate"]), 0 , MAX_TRANSFER_RATE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/binary/volume_pump/power_change()
|
||||
var/old_stat = stat
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Omni device port types
|
||||
//--------------------------------------------
|
||||
#define ATM_NONE 0
|
||||
#define ATM_INPUT 1
|
||||
#define ATM_OUTPUT 2
|
||||
|
||||
#define ATM_O2 3
|
||||
#define ATM_N2 4
|
||||
#define ATM_CO2 5
|
||||
#define ATM_P 6 //Plasma
|
||||
#define ATM_N2O 7
|
||||
|
||||
//--------------------------------------------
|
||||
// Omni port datum
|
||||
//
|
||||
// Used by omni devices to manage connections
|
||||
// to other atmospheric objects.
|
||||
//--------------------------------------------
|
||||
/datum/omni_port
|
||||
var/obj/machinery/atmospherics/omni/master
|
||||
var/dir
|
||||
var/update = 1
|
||||
var/mode = 0
|
||||
var/concentration = 0
|
||||
var/con_lock = 0
|
||||
var/transfer_moles = 0
|
||||
var/datum/gas_mixture/air
|
||||
var/obj/machinery/atmospherics/node
|
||||
var/datum/pipeline/parent
|
||||
|
||||
/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH)
|
||||
..()
|
||||
dir = direction
|
||||
if(istype(M))
|
||||
master = M
|
||||
air = new
|
||||
air.volume = 200
|
||||
|
||||
/datum/omni_port/proc/connect()
|
||||
if(node)
|
||||
return
|
||||
master.atmos_init()
|
||||
if(node)
|
||||
node.atmos_init()
|
||||
node.addMember(master)
|
||||
master.build_network()
|
||||
|
||||
/datum/omni_port/proc/disconnect()
|
||||
if(node)
|
||||
node.disconnect(master)
|
||||
node = null
|
||||
master.nullifyPipenet(parent)
|
||||
|
||||
//--------------------------------------------
|
||||
// Need to find somewhere else for these
|
||||
//--------------------------------------------
|
||||
|
||||
//returns a text string based on the direction flag input
|
||||
// if capitalize is true, it will return the string capitalized
|
||||
// otherwise it will return the direction string in lower case
|
||||
/proc/dir_name(var/dir, var/capitalize = 0)
|
||||
var/string = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
string = "North"
|
||||
if(SOUTH)
|
||||
string = "South"
|
||||
if(EAST)
|
||||
string = "East"
|
||||
if(WEST)
|
||||
string = "West"
|
||||
|
||||
if(!capitalize && string)
|
||||
string = lowertext(string)
|
||||
|
||||
return string
|
||||
|
||||
//returns a direction flag based on the string passed to it
|
||||
// case insensitive
|
||||
/proc/dir_flag(var/dir)
|
||||
dir = lowertext(dir)
|
||||
switch(dir)
|
||||
if("north")
|
||||
return NORTH
|
||||
if("south")
|
||||
return SOUTH
|
||||
if("east")
|
||||
return EAST
|
||||
if("west")
|
||||
return WEST
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas filter - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
name = "omni gas filter"
|
||||
icon_state = "map_filter"
|
||||
|
||||
var/list/o_filters = new()
|
||||
var/datum/omni_port/input
|
||||
var/datum/omni_port/output
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Destroy()
|
||||
input = null
|
||||
output = null
|
||||
o_filters.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(input == P)
|
||||
input = null
|
||||
if(o_filters.Find(P))
|
||||
o_filters -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
o_filters += P
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/error_check()
|
||||
if(!input || !output || !o_filters)
|
||||
return 1
|
||||
if(o_filters.len < 1 || o_filters.len > 2) //requires 1 or 2 o_filters ~otherwise why are you using a filter?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
if(!input || !output)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference
|
||||
var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug*
|
||||
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
if(output_pressure >= target_pressure)
|
||||
return 1
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
if(P.air.return_pressure() >= target_pressure)
|
||||
return 1
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
if(input_air.return_temperature() > 0)
|
||||
input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
if(input.transfer_moles > 0)
|
||||
var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles)
|
||||
|
||||
if(!removed)
|
||||
return 1
|
||||
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
filtered_out.temperature = removed.return_temperature()
|
||||
|
||||
switch(P.mode)
|
||||
if(ATM_O2)
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
removed.oxygen = 0
|
||||
if(ATM_N2)
|
||||
filtered_out.nitrogen = removed.nitrogen
|
||||
removed.nitrogen = 0
|
||||
if(ATM_CO2)
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
if(ATM_P)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
if(ATM_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
P.air.merge(filtered_out)
|
||||
P.parent.update = 1
|
||||
|
||||
output_air.merge(removed)
|
||||
output.parent.update = 1
|
||||
|
||||
input.transfer_moles = 0
|
||||
input.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
var/filter = 1
|
||||
var/f_type = null
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
filter = 0
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
filter = 0
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
f_type = mode_send_switch(P.mode)
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"filter" = filter, \
|
||||
"f_type" = f_type)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE)
|
||||
switch(mode)
|
||||
if(ATM_O2)
|
||||
return "Oxygen"
|
||||
if(ATM_N2)
|
||||
return "Nitrogen"
|
||||
if(ATM_CO2)
|
||||
return "Carbon Dioxide"
|
||||
if(ATM_P)
|
||||
return "Plasma" //*cough* Plasma *cough*
|
||||
if(ATM_N2O)
|
||||
return "Nitrous Oxide"
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
|
||||
if("switch_filter")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Plasma", "Nitrous Oxide")
|
||||
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode)
|
||||
switch(mode)
|
||||
if("Oxygen")
|
||||
return ATM_O2
|
||||
if("Nitrogen")
|
||||
return ATM_N2
|
||||
if("Carbon Dioxide")
|
||||
return ATM_CO2
|
||||
if("Plasma")
|
||||
return ATM_P
|
||||
if("Nitrous Oxide")
|
||||
return ATM_N2O
|
||||
if("in")
|
||||
return ATM_INPUT
|
||||
if("out")
|
||||
return ATM_OUTPUT
|
||||
if("None")
|
||||
return ATM_NONE
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode)
|
||||
//check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == dir)
|
||||
if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT)
|
||||
return
|
||||
|
||||
switch_mode(dir, mode)
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode)
|
||||
if(mode == null || !port)
|
||||
return
|
||||
var/datum/omni_port/target_port = null
|
||||
var/list/other_ports = new()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == port)
|
||||
target_port = P
|
||||
else
|
||||
other_ports += P
|
||||
|
||||
var/previous_mode = null
|
||||
if(target_port)
|
||||
previous_mode = target_port.mode
|
||||
target_port.mode = mode
|
||||
if(target_port.mode != previous_mode)
|
||||
handle_port_change(target_port)
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in other_ports)
|
||||
if(P.mode == mode)
|
||||
var/old_mode = P.mode
|
||||
P.mode = previous_mode
|
||||
if(P.mode != old_mode)
|
||||
handle_port_change(P)
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
@@ -1,291 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas mixer - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
name = "omni gas mixer"
|
||||
icon_state = "map_mixer"
|
||||
|
||||
var/list/inputs = new()
|
||||
var/datum/omni_port/output
|
||||
|
||||
//setup tags for initial concentration values (must be decimal)
|
||||
var/tag_north_con
|
||||
var/tag_south_con
|
||||
var/tag_east_con
|
||||
var/tag_west_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/New()
|
||||
..()
|
||||
if(mapper_set())
|
||||
var/con = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
if(tag_north_con && tag_north == 1)
|
||||
P.concentration = tag_north_con
|
||||
con += max(0, tag_north_con)
|
||||
if(SOUTH)
|
||||
if(tag_south_con && tag_south == 1)
|
||||
P.concentration = tag_south_con
|
||||
con += max(0, tag_south_con)
|
||||
if(EAST)
|
||||
if(tag_east_con && tag_east == 1)
|
||||
P.concentration = tag_east_con
|
||||
con += max(0, tag_east_con)
|
||||
if(WEST)
|
||||
if(tag_west_con && tag_west == 1)
|
||||
P.concentration = tag_west_con
|
||||
con += max(0, tag_west_con)
|
||||
|
||||
//mappers who are bad at maths will be punished (total concentration must be 100%)
|
||||
if(con != 1)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Destroy()
|
||||
inputs.Cut()
|
||||
output = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(inputs.Find(P))
|
||||
inputs -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
inputs += P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
|
||||
if(!mapper_set())
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.concentration = 1 / max(1, inputs.len)
|
||||
|
||||
if(output)
|
||||
output.air.volume *= 0.75 * inputs.len
|
||||
output.concentration = 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/mapper_set()
|
||||
return (tag_north_con || tag_south_con || tag_east_con || tag_west_con)
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/error_check()
|
||||
if(!output || !inputs)
|
||||
return 1
|
||||
if(inputs.len < 2 || inputs.len > 3) //requires 2 or 3 inputs ~otherwise why are you using a mixer?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
|
||||
if(output_pressure >= target_pressure * 0.999)
|
||||
//No need to mix if target is already full! - 0.1% margin of error so we minimize processing minor gas volumes
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.air.return_temperature() > 0)
|
||||
P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/ratio_check = null
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(!P.transfer_moles)
|
||||
return 1
|
||||
if(P.air.total_moles() < P.transfer_moles)
|
||||
ratio_check = 1
|
||||
continue
|
||||
|
||||
if(ratio_check)
|
||||
var/list/ratio_list = new()
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
ratio_list.Add(P.air.total_moles() / P.transfer_moles)
|
||||
|
||||
var/ratio = min(ratio_list)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.transfer_moles *= ratio
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.transfer_moles > 0)
|
||||
output_air.merge(P.air.remove(P.transfer_moles))
|
||||
P.parent.update = 1
|
||||
P.transfer_moles = 0
|
||||
|
||||
output.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"concentration" = P.concentration, \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"con_lock" = P.con_lock)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
|
||||
if("switch_con")
|
||||
change_concentration(dir_flag(href_list["dir"]))
|
||||
if("switch_conlock")
|
||||
con_lock(dir_flag(href_list["dir"]))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
|
||||
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
|
||||
switch(mode)
|
||||
if("in")
|
||||
mode = ATM_INPUT
|
||||
if("out")
|
||||
mode = ATM_OUTPUT
|
||||
else
|
||||
mode = ATM_NONE
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/old_mode = P.mode
|
||||
if(P.dir == port)
|
||||
switch(mode)
|
||||
if(ATM_INPUT)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
P.mode = mode
|
||||
if(ATM_OUTPUT)
|
||||
P.mode = mode
|
||||
if(ATM_NONE)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
if(P.mode == ATM_INPUT && inputs.len > 2)
|
||||
P.mode = mode
|
||||
else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT)
|
||||
P.mode = ATM_INPUT
|
||||
if(P.mode != old_mode)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
var/old_con = 0
|
||||
var/non_locked = 0
|
||||
var/remain_con = 1
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
old_con = P.concentration
|
||||
else if(!P.con_lock)
|
||||
non_locked++
|
||||
else
|
||||
remain_con -= P.concentration
|
||||
|
||||
//return if no adjustable ports
|
||||
if(non_locked < 1)
|
||||
return
|
||||
|
||||
var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100
|
||||
|
||||
//cap it between 0 and the max remaining concentration
|
||||
new_con = between(0, new_con, remain_con)
|
||||
|
||||
//new_con = min(remain_con, new_con)
|
||||
|
||||
//clamp remaining concentration so we don't go into negatives
|
||||
remain_con = max(0, remain_con - new_con)
|
||||
|
||||
//distribute remaining concentration between unlocked ports evenly
|
||||
remain_con /= max(1, non_locked)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.concentration = new_con
|
||||
else if(!P.con_lock)
|
||||
P.concentration = remain_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH)
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.con_lock = !P.con_lock
|
||||
@@ -1,302 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Base omni device
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni
|
||||
name = "omni device"
|
||||
icon = 'icons/atmos/omni_devices.dmi'
|
||||
icon_state = "base"
|
||||
use_power = IDLE_POWER_USE
|
||||
initialize_directions = 0
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/configuring = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/tag_north = ATM_NONE
|
||||
var/tag_south = ATM_NONE
|
||||
var/tag_east = ATM_NONE
|
||||
var/tag_west = ATM_NONE
|
||||
|
||||
var/overlays_on[5]
|
||||
var/overlays_off[5]
|
||||
var/overlays_error[2]
|
||||
var/underlays_current[4]
|
||||
|
||||
var/list/ports = new()
|
||||
|
||||
/obj/machinery/atmospherics/omni/New()
|
||||
..()
|
||||
icon_state = "base"
|
||||
|
||||
ports = new()
|
||||
for(var/d in GLOB.cardinal)
|
||||
var/datum/omni_port/new_port = new(src, d)
|
||||
switch(d)
|
||||
if(NORTH)
|
||||
new_port.mode = tag_north
|
||||
if(SOUTH)
|
||||
new_port.mode = tag_south
|
||||
if(EAST)
|
||||
new_port.mode = tag_east
|
||||
if(WEST)
|
||||
new_port.mode = tag_west
|
||||
if(new_port.mode > 0)
|
||||
initialize_directions |= d
|
||||
ports += new_port
|
||||
|
||||
build_icons()
|
||||
|
||||
/obj/machinery/atmospherics/omni/Destroy()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node)
|
||||
P.node.disconnect(src)
|
||||
P.node = null
|
||||
nullifyPipenet(P.parent)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/atmos_init()
|
||||
..()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node || P.mode == 0)
|
||||
continue
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, P.dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
P.node = target
|
||||
break
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_icon()
|
||||
..()
|
||||
|
||||
if(stat & NOPOWER)
|
||||
overlays = overlays_off
|
||||
on = 0
|
||||
else if(error_check())
|
||||
overlays = overlays_error
|
||||
on = 0
|
||||
else
|
||||
overlays = on ? (overlays_on) : (overlays_off)
|
||||
|
||||
underlays = underlays_current
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/error_check()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob, params)
|
||||
if(!istype(W, /obj/item/wrench))
|
||||
return ..()
|
||||
|
||||
if(can_unwrench)
|
||||
var/int_pressure = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
int_pressure += P.air.return_pressure()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='danger'>You cannot unwrench [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if(do_after(user, 40 * W.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/build_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
var/core_icon = null
|
||||
if(istype(src, /obj/machinery/atmospherics/omni/mixer))
|
||||
core_icon = "mixer"
|
||||
else if(istype(src, /obj/machinery/atmospherics/omni/filter))
|
||||
core_icon = "filter"
|
||||
else
|
||||
return
|
||||
|
||||
//directional icons are layers 1-4, with the core icon on layer 5
|
||||
if(core_icon)
|
||||
overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow")
|
||||
|
||||
overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error")
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_port_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
var/ref_layer = 0
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
ref_layer = 1
|
||||
if(SOUTH)
|
||||
ref_layer = 2
|
||||
if(EAST)
|
||||
ref_layer = 3
|
||||
if(WEST)
|
||||
ref_layer = 4
|
||||
|
||||
if(!ref_layer)
|
||||
continue
|
||||
|
||||
var/list/port_icons = select_port_icons(P)
|
||||
if(port_icons)
|
||||
if(P.node)
|
||||
underlays_current[ref_layer] = port_icons["pipe_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = port_icons["off_icon"]
|
||||
overlays_on[ref_layer] = port_icons["on_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = null
|
||||
overlays_on[ref_layer] = null
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/select_port_icons(var/datum/omni_port/P)
|
||||
if(!istype(P))
|
||||
return
|
||||
|
||||
if(P.mode > 0)
|
||||
var/ic_dir = dir_name(P.dir)
|
||||
var/ic_on = ic_dir
|
||||
var/ic_off = ic_dir
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
ic_on += "_in_glow"
|
||||
ic_off += "_in"
|
||||
if(ATM_OUTPUT)
|
||||
ic_on += "_out_glow"
|
||||
ic_off += "_out"
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
ic_on += "_filter"
|
||||
ic_off += "_out"
|
||||
|
||||
ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on)
|
||||
ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off)
|
||||
|
||||
var/pipe_state
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
|
||||
else
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
|
||||
|
||||
return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state)
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_underlays()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_ports()
|
||||
sort_ports()
|
||||
update_port_icons()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/sort_ports()
|
||||
return
|
||||
|
||||
// Pipenet procs
|
||||
/obj/machinery/atmospherics/omni/build_network(remove_deferral = FALSE)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!P.parent)
|
||||
P.parent = new /datum/pipeline()
|
||||
P.parent.build_pipeline(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
if(istype(P.node, /obj/machinery/atmospherics/pipe))
|
||||
qdel(P.parent)
|
||||
P.node = null
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/nullifyPipenet(datum/pipeline/P)
|
||||
..()
|
||||
if(!P)
|
||||
return
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
PO.parent.other_airs -= PO.air
|
||||
PO.parent = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenetAir(datum/pipeline/P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
return PO.air
|
||||
|
||||
/obj/machinery/atmospherics/omni/pipeline_expansion(datum/pipeline/P)
|
||||
if(P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(PO.parent == P)
|
||||
return list(PO.node)
|
||||
else
|
||||
var/list/nodes = list()
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
nodes += PO.node
|
||||
|
||||
return nodes
|
||||
|
||||
/obj/machinery/atmospherics/omni/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(A == PO.node)
|
||||
PO.parent = P
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenet(obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(A == P.node)
|
||||
return P.parent
|
||||
|
||||
/obj/machinery/atmospherics/omni/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(Old == P.parent)
|
||||
P.parent = New
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/omni/process_atmos()
|
||||
..()
|
||||
for(var/datum/omni_port/port in ports)
|
||||
if(!port.parent)
|
||||
return 0
|
||||
return 1
|
||||
@@ -128,66 +128,56 @@
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/process_atmos()
|
||||
..()
|
||||
if((stat & (NOPOWER|BROKEN)))
|
||||
return 0
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
if(!node)
|
||||
on = 0
|
||||
on = FALSE
|
||||
//broadcast_status() // from now air alarm/control computer should request update purposely --rastaf0
|
||||
if(!on)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(welded)
|
||||
if(air_contents.return_pressure() >= weld_burst_pressure && prob(5)) //the weld is on but the cover is welded shut, can it withstand the internal pressure?
|
||||
visible_message("<span class='danger'>The welded cover of [src] bursts open!</span>")
|
||||
for(var/mob/M in range(1, src))
|
||||
for(var/mob/living/M in range(1))
|
||||
unsafe_pressure_release(M, air_contents.return_pressure()) //let's send everyone flying
|
||||
welded = FALSE
|
||||
update_icon()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction) //internal -> external
|
||||
var/pressure_delta = 10000
|
||||
|
||||
if(pressure_checks&1)
|
||||
if(pressure_checks & 1)
|
||||
pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
|
||||
if(pressure_checks&2)
|
||||
if(pressure_checks & 2)
|
||||
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
|
||||
parent.update = 1
|
||||
if(pressure_delta > 0.5 && air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta * environment.volume / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
parent.update = TRUE
|
||||
|
||||
else //external -> internal
|
||||
var/pressure_delta = 10000
|
||||
if(pressure_checks&1)
|
||||
if(pressure_checks & 1)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&2)
|
||||
if(pressure_checks & 2)
|
||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(pressure_delta > 0.5 && environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if(isnull(removed)) //in space
|
||||
return
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
parent.update = TRUE
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if(isnull(removed)) //in space
|
||||
return
|
||||
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
|
||||
parent.update = 1
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//Radio remote control
|
||||
|
||||
@@ -386,11 +376,11 @@
|
||||
if(I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
if(!welded)
|
||||
welded = TRUE
|
||||
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
"<span class='notice'>You weld [src] shut!</span>")
|
||||
else
|
||||
welded = FALSE
|
||||
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
"<span class='notice'>You unweld [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -404,10 +404,10 @@
|
||||
if(I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
if(!welded)
|
||||
welded = TRUE
|
||||
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
|
||||
"<span class='notice'>You weld [src] shut!</span>")
|
||||
else
|
||||
welded = FALSE
|
||||
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
user.visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
|
||||
"<span class='notice'>You unweld [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
//var/list/underlays_intact[]
|
||||
//var/list/pipe_underlays_exposed[]
|
||||
//var/list/pipe_underlays_intact[]
|
||||
var/list/omni_icons[]
|
||||
|
||||
/datum/pipe_icon_manager/New()
|
||||
check_icons()
|
||||
@@ -53,8 +52,6 @@
|
||||
return manifold_icons[state + color]
|
||||
if("device")
|
||||
return device_icons[state]
|
||||
if("omni")
|
||||
return omni_icons[state]
|
||||
if("underlay")
|
||||
return underlays[state + dir + color]
|
||||
//if("underlay_intact")
|
||||
@@ -75,8 +72,6 @@
|
||||
gen_manifold_icons()
|
||||
if(!device_icons)
|
||||
gen_device_icons()
|
||||
if(!omni_icons)
|
||||
gen_omni_icons()
|
||||
//if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact)
|
||||
if(!underlays)
|
||||
gen_underlay_icons()
|
||||
@@ -150,18 +145,6 @@
|
||||
continue
|
||||
device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state)
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_omni_icons()
|
||||
if(!omni_icons)
|
||||
omni_icons = new()
|
||||
|
||||
var/icon/omni = new('icons/atmos/omni_devices.dmi')
|
||||
|
||||
for(var/state in omni.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state)
|
||||
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_underlay_icons()
|
||||
|
||||
if(!underlays)
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2
|
||||
|
||||
//used by airlocks and airlock wires.
|
||||
#define AICONTROLDISABLED_OFF 0 // Silicons can control the airlock normally.
|
||||
#define AICONTROLDISABLED_ON 1 // Silicons cannot control the airlock, but can hack the airlock.
|
||||
#define AICONTROLDISABLED_BYPASS 2 // Silicons can control the airlock because they succeeded on the hack
|
||||
#define AICONTROLDISABLED_PERMA 3 // Wire cutting an airlock on AICONTROLDISABLED_BYPASS toggles it between AICONTROLDISABLED_BYPASS and this.
|
||||
|
||||
//plastic flaps construction states
|
||||
#define PLASTIC_FLAPS_NORMAL 0
|
||||
#define PLASTIC_FLAPS_DETACHED 1
|
||||
|
||||
@@ -726,3 +726,7 @@
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
|
||||
///from monkey CtrlClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
|
||||
|
||||
///SSalarm signals
|
||||
#define COMSIG_TRIGGERED_ALARM "ssalarm_triggered"
|
||||
#define COMSIG_CANCELLED_ALARM "ssalarm_cancelled"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#define INSTRUMENT_MIN_OCTAVE 1
|
||||
#define INSTRUMENT_MAX_OCTAVE 9
|
||||
#define INSTRUMENT_MIN_KEY 0
|
||||
#define INSTRUMENT_MAX_KEY 127
|
||||
|
||||
/// Max number of playing notes per instrument.
|
||||
#define CHANNELS_PER_INSTRUMENT 128
|
||||
|
||||
/// Distance multiplier that makes us not be impacted by 3d sound as much. This is a multiplier so lower it is the closer we will pretend to be to people.
|
||||
#define INSTRUMENT_DISTANCE_FALLOFF_BUFF 0.2
|
||||
/// How many tiles instruments have no falloff for
|
||||
#define INSTRUMENT_DISTANCE_NO_FALLOFF 3
|
||||
|
||||
/// Maximum length a note should ever go for
|
||||
#define INSTRUMENT_MAX_TOTAL_SUSTAIN (5 SECONDS)
|
||||
|
||||
/// These are per decisecond.
|
||||
#define INSTRUMENT_EXP_FALLOFF_MIN 1.025 //100/(1.025^50) calculated for [INSTRUMENT_MIN_SUSTAIN_DROPOFF] to be 30.
|
||||
#define INSTRUMENT_EXP_FALLOFF_MAX 10
|
||||
|
||||
/// Minimum volume for when the sound is considered dead.
|
||||
#define INSTRUMENT_MIN_SUSTAIN_DROPOFF 0.1
|
||||
|
||||
#define SUSTAIN_LINEAR 1
|
||||
#define SUSTAIN_EXPONENTIAL 2
|
||||
|
||||
// /datum/instrument instrument_flags
|
||||
#define INSTRUMENT_LEGACY (1<<0) //Legacy instrument. Implies INSTRUMENT_DO_NOT_AUTOSAMPLE
|
||||
#define INSTRUMENT_DO_NOT_AUTOSAMPLE (1<<1) //Do not automatically sample
|
||||
@@ -92,3 +92,8 @@
|
||||
// Firelock states
|
||||
#define FD_OPEN 1
|
||||
#define FD_CLOSED 2
|
||||
|
||||
// Computer login types
|
||||
#define LOGIN_TYPE_NORMAL 1
|
||||
#define LOGIN_TYPE_AI 2
|
||||
#define LOGIN_TYPE_ROBOT 3
|
||||
|
||||
+60
-16
@@ -69,9 +69,6 @@
|
||||
#define ZONE_ACTIVE 1
|
||||
#define ZONE_SLEEPING 0
|
||||
|
||||
#define shuttle_time_in_station 1800 // 3 minutes in the station
|
||||
#define shuttle_time_to_arrive 6000 // 10 minutes to arrive
|
||||
|
||||
#define EVENT_LEVEL_MUNDANE 1
|
||||
#define EVENT_LEVEL_MODERATE 2
|
||||
#define EVENT_LEVEL_MAJOR 3
|
||||
@@ -245,28 +242,75 @@
|
||||
0.4,0.6,0.0,\
|
||||
0.2,0.2,0.6)
|
||||
|
||||
#define LIST_REPLACE_RENAME list("rebeccapurple" = "dark purple", "darkslategrey" = "dark grey", "darkolivegreen" = "dark green", "darkslateblue" = "dark blue",\
|
||||
"darkkhaki" = "khaki", "darkseagreen" = "light green", "midnightblue" = "blue", "lightgrey" = "light grey", "darkgrey" = "dark grey",\
|
||||
"steelblue" = "blue", "goldenrod" = "gold")
|
||||
/*
|
||||
Used for wire name appearances. Replaces the color name on the left with the one on the right.
|
||||
The color on the left is the one used as the actual color of the wire, but it doesn't look good when written.
|
||||
So, we need to replace the name to something that looks better.
|
||||
*/
|
||||
#define LIST_COLOR_RENAME \
|
||||
list( \
|
||||
"rebeccapurple" = "dark purple",\
|
||||
"darkslategrey" = "dark grey", \
|
||||
"darkolivegreen"= "dark green", \
|
||||
"darkslateblue" = "dark blue", \
|
||||
"darkkhaki" = "khaki", \
|
||||
"darkseagreen" = "light green",\
|
||||
"midnightblue" = "blue", \
|
||||
"lightgrey" = "light grey", \
|
||||
"darkgrey" = "dark grey", \
|
||||
"steelblue" = "blue", \
|
||||
"goldenrod" = "gold" \
|
||||
)
|
||||
|
||||
#define LIST_GREYSCALE_REPLACE list("red" = "lightgrey", "blue" = "grey", "green" = "grey", "orange" = "lightgrey", "brown" = "grey",\
|
||||
"gold" = "lightgrey", "cyan" = "lightgrey", "navy" = "grey", "purple" = "grey", "pink"= "lightgrey")
|
||||
/// Pure Black and white colorblindness. Every species except Vulpkanins and Tajarans will have this.
|
||||
#define GREYSCALE_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "grey", \
|
||||
"blue" = "grey", \
|
||||
"green" = "grey", \
|
||||
"orange" = "light grey", \
|
||||
"brown" = "grey", \
|
||||
"gold" = "light grey", \
|
||||
"cyan" = "silver", \
|
||||
"magenta" = "grey", \
|
||||
"purple" = "grey", \
|
||||
"pink" = "light grey" \
|
||||
)
|
||||
|
||||
#define LIST_VULP_REPLACE list("pink" = "beige", "orange" = "goldenrod", "gold" = "goldenrod", "red" = "darkolivegreen", "brown" = "darkolivegreen",\
|
||||
"green" = "darkslategrey", "cyan" = "steelblue", "purple" = "darkslategrey", "navy" = "midnightblue")
|
||||
|
||||
#define LIST_TAJ_REPLACE list("red" = "rebeccapurple", "brown" = "rebeccapurple", "purple" = "darkslateblue", "blue" = "darkslateblue",\
|
||||
"green" = "darkolivegreen", "orange" = "darkkhaki", "gold" = "darkkhaki", "cyan" = "darkseagreen", \
|
||||
"navy" = "midnightblue", "pink" = "lightgrey")
|
||||
/// Red colorblindness. Vulpkanins/Wolpins have this.
|
||||
#define PROTANOPIA_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "darkolivegreen", \
|
||||
"green" = "darkslategrey", \
|
||||
"orange" = "goldenrod", \
|
||||
"gold" = "goldenrod", \
|
||||
"brown" = "darkolivegreen", \
|
||||
"cyan" = "steelblue", \
|
||||
"magenta" = "blue", \
|
||||
"purple" = "darkslategrey", \
|
||||
"pink" = "beige" \
|
||||
)
|
||||
|
||||
/// Yellow-Blue colorblindness. Tajarans/Farwas have this.
|
||||
#define TRITANOPIA_COLOR_REPLACE \
|
||||
list( \
|
||||
"red" = "rebeccapurple", \
|
||||
"blue" = "darkslateblue", \
|
||||
"green" = "darkolivegreen", \
|
||||
"orange" = "darkkhaki", \
|
||||
"gold" = "darkkhaki", \
|
||||
"brown" = "rebeccapurple", \
|
||||
"cyan" = "darkseagreen", \
|
||||
"magenta" = "darkslateblue", \
|
||||
"purple" = "darkslateblue", \
|
||||
"pink" = "lightgrey" \
|
||||
)
|
||||
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null)))
|
||||
|
||||
// Macro to get the current elapsed round time, rather than total world runtime
|
||||
#define ROUND_TIME (SSticker.round_start_time ? (world.time - SSticker.round_start_time) : 0)
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#define PIPE_TVALVE 18
|
||||
#define PIPE_MANIFOLD4W 19
|
||||
#define PIPE_CAP 20
|
||||
#define PIPE_OMNI_MIXER 21
|
||||
#define PIPE_OMNI_FILTER 22
|
||||
#define PIPE_UNIVERSAL 23
|
||||
#define PIPE_SUPPLY_STRAIGHT 24
|
||||
#define PIPE_SUPPLY_BENT 25
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
|
||||
+3
-10
@@ -22,16 +22,9 @@
|
||||
|
||||
// these define the time taken for the shuttle to get to SS13
|
||||
// and the time before it leaves again
|
||||
#define SHUTTLE_PREPTIME 300 // 5 minutes = 300 seconds - after this time, the shuttle departs centcom and cannot be recalled
|
||||
#define SHUTTLE_LEAVETIME 180 // 3 minutes = 180 seconds - the duration for which the shuttle will wait at the station after arriving
|
||||
#define SHUTTLE_TRANSIT_DURATION 300 // 5 minutes = 300 seconds - how long it takes for the shuttle to get to the station
|
||||
#define SHUTTLE_TRANSIT_DURATION_RETURN 120 // 2 minutes = 120 seconds - for some reason it takes less time to come back, go figure.
|
||||
|
||||
//Ferry shuttle processing status
|
||||
#define IDLE_STATE 0
|
||||
#define WAIT_LAUNCH 1
|
||||
#define WAIT_ARRIVE 2
|
||||
#define WAIT_FINISH 3
|
||||
#define SHUTTLE_CALLTIME 6000 //10 minutes = 6000 deciseconds - time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
#define SHUTTLE_DOCKTIME 1800 //3 minutes = 1800 deciseconds - time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
#define SHUTTLE_ESCAPETIME 1200 //2 minutes = 1200 deciseconds - time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
|
||||
//shuttle mode defines
|
||||
#define SHUTTLE_IGNITING 0
|
||||
|
||||
@@ -45,11 +45,13 @@
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
#define INIT_ORDER_TITLE 100 // This **MUST** load first or people will se blank lobby screens
|
||||
#define INIT_ORDER_GARBAGE 19
|
||||
#define INIT_ORDER_DBCORE 18
|
||||
#define INIT_ORDER_BLACKBOX 17
|
||||
#define INIT_ORDER_SERVER_MAINT 16
|
||||
#define INIT_ORDER_INPUT 15
|
||||
#define INIT_ORDER_GARBAGE 21
|
||||
#define INIT_ORDER_DBCORE 20
|
||||
#define INIT_ORDER_BLACKBOX 19
|
||||
#define INIT_ORDER_SERVER_MAINT 18
|
||||
#define INIT_ORDER_INPUT 17
|
||||
#define INIT_ORDER_SOUNDS 16
|
||||
#define INIT_ORDER_INSTRUMENTS 15
|
||||
#define INIT_ORDER_RESEARCH 14
|
||||
#define INIT_ORDER_EVENTS 13
|
||||
#define INIT_ORDER_JOBS 12
|
||||
@@ -80,8 +82,7 @@
|
||||
#define INIT_ORDER_NANOMOB -23
|
||||
#define INIT_ORDER_SQUEAK -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
@@ -113,7 +114,6 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_NANOUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// TGUI defines
|
||||
#define TGUI_MODAL_INPUT_MAX_LENGTH 1024
|
||||
#define TGUI_MODAL_INPUT_MAX_LENGTH_NAME 64 // Names for generally anything don't go past 32, let alone 64.
|
||||
|
||||
#define TGUI_MODAL_OPEN 1
|
||||
#define TGUI_MODAL_DELEGATE 2
|
||||
#define TGUI_MODAL_ANSWER 3
|
||||
#define TGUI_MODAL_CLOSE 4
|
||||
@@ -0,0 +1,77 @@
|
||||
// Wire defines for all machines/items.
|
||||
|
||||
// Miscellaneous
|
||||
#define WIRE_DUD_PREFIX "__dud"
|
||||
|
||||
// General
|
||||
#define WIRE_IDSCAN "ID Scan"
|
||||
#define WIRE_MAIN_POWER1 "Primary Power"
|
||||
#define WIRE_MAIN_POWER2 "Secondary Power"
|
||||
#define WIRE_AI_CONTROL "AI Control"
|
||||
#define WIRE_ELECTRIFY "Electrification"
|
||||
#define WIRE_SAFETY "Safety"
|
||||
|
||||
// Vendors and smartfridges
|
||||
#define WIRE_THROW_ITEM "Item Throw"
|
||||
#define WIRE_CONTRABAND "Contraband"
|
||||
|
||||
// Airlock
|
||||
#define WIRE_DOOR_BOLTS "Door Bolts"
|
||||
#define WIRE_BACKUP_POWER1 "Primary Backup Power"
|
||||
#define WIRE_OPEN_DOOR "Door State"
|
||||
#define WIRE_SPEED "Door Timing"
|
||||
#define WIRE_BOLT_LIGHT "Bolt Lights"
|
||||
|
||||
// Air alarm
|
||||
#define WIRE_SYPHON "Siphon"
|
||||
#define WIRE_AALARM "Atmospherics Alarm"
|
||||
|
||||
// Camera
|
||||
#define WIRE_FOCUS "Focus"
|
||||
|
||||
// Mulebot
|
||||
#define WIRE_MOB_AVOIDANCE "Mob Avoidance"
|
||||
#define WIRE_LOADCHECK "Load Checking"
|
||||
#define WIRE_MOTOR1 "Primary Motor"
|
||||
#define WIRE_MOTOR2 "Secondary Motor"
|
||||
#define WIRE_REMOTE_RX "Signal Receiver"
|
||||
#define WIRE_REMOTE_TX "Signal Sender"
|
||||
#define WIRE_BEACON_RX "Beacon Receiver"
|
||||
|
||||
// Explosives, bombs
|
||||
#define WIRE_EXPLODE "Explode" // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut.
|
||||
#define WIRE_BOMB_UNBOLT "Unbolt" // Unbolts the bomb if cut, hint on pulsed.
|
||||
#define WIRE_BOMB_DELAY "Delay" // Raises the timer on pulse, does nothing on cut.
|
||||
#define WIRE_BOMB_PROCEED "Proceed" // Lowers the timer, explodes if cut while the bomb is active.
|
||||
#define WIRE_BOMB_ACTIVATE "Activate" // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut.
|
||||
|
||||
// Nuclear bomb
|
||||
#define WIRE_BOMB_LIGHT "Bomb Light"
|
||||
#define WIRE_BOMB_TIMING "Bomb Timing"
|
||||
#define WIRE_BOMB_SAFETY "Bomb Safety"
|
||||
|
||||
// Particle accelerator
|
||||
#define WIRE_PARTICLE_POWER "Power Toggle" // Toggles whether the PA is on or not.
|
||||
#define WIRE_PARTICLE_STRENGTH "Strength" // Determines the strength of the PA.
|
||||
#define WIRE_PARTICLE_INTERFACE "Interface" // Determines the interface showing up.
|
||||
#define WIRE_PARTICLE_POWER_LIMIT "Maximum Power" // Determines how strong the PA can be.
|
||||
|
||||
// Autolathe
|
||||
#define WIRE_AUTOLATHE_HACK "Hack"
|
||||
#define WIRE_AUTOLATHE_DISABLE "Disable"
|
||||
|
||||
// Radio
|
||||
#define WIRE_RADIO_SIGNAL "Signal"
|
||||
#define WIRE_RADIO_RECEIVER "Receiver"
|
||||
#define WIRE_RADIO_TRANSMIT "Transmitter"
|
||||
|
||||
// Cyborg
|
||||
#define WIRE_BORG_LOCKED "Lockdown"
|
||||
#define WIRE_BORG_CAMERA "Camera"
|
||||
#define WIRE_BORG_LAWCHECK "Law Check"
|
||||
|
||||
// Suit storage unit
|
||||
#define WIRE_SSU_UV "UV wire"
|
||||
|
||||
// Tesla coil
|
||||
#define WIRE_TESLACOIL_ZAP "Zap"
|
||||
+23
-5
@@ -5,11 +5,11 @@
|
||||
var/turf/T = get_turf(A)
|
||||
return T ? T.loc : null
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in world)
|
||||
if(A.name == N)
|
||||
return A
|
||||
return 0
|
||||
/proc/get_area_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
if(!A)
|
||||
return null
|
||||
return format_text ? format_text(A.name) : A.name
|
||||
|
||||
/proc/get_location_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
@@ -31,6 +31,24 @@
|
||||
areas |= T.loc
|
||||
return areas
|
||||
|
||||
/proc/get_open_turf_in_dir(atom/center, dir)
|
||||
var/turf/T = get_ranged_target_turf(center, dir, 1)
|
||||
if(T && !T.density)
|
||||
return T
|
||||
|
||||
/proc/get_adjacent_open_turfs(atom/center)
|
||||
. = list(get_open_turf_in_dir(center, NORTH),
|
||||
get_open_turf_in_dir(center, SOUTH),
|
||||
get_open_turf_in_dir(center, EAST),
|
||||
get_open_turf_in_dir(center, WEST))
|
||||
listclearnulls(.)
|
||||
|
||||
/proc/get_adjacent_open_areas(atom/center)
|
||||
. = list()
|
||||
var/list/adjacent_turfs = get_adjacent_open_turfs(center)
|
||||
for(var/I in adjacent_turfs)
|
||||
. |= get_area(I)
|
||||
|
||||
// Like view but bypasses luminosity check
|
||||
|
||||
/proc/hear(var/range, var/atom/source)
|
||||
|
||||
@@ -672,9 +672,6 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize(last_name)]"
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
|
||||
|
||||
@@ -615,5 +615,3 @@ proc/checkhtml(var/t)
|
||||
text = replacetext(text, "<td>", "\[cell\]")
|
||||
text = replacetext(text, "<img src = ntlogo.png>", "\[logo\]")
|
||||
return text
|
||||
|
||||
#define string2charlist(string) (splittext(string, regex("(\\x0A|.)")) - splittext(string, ""))
|
||||
|
||||
@@ -95,7 +95,7 @@ proc/isDay(var/month, var/day)
|
||||
/proc/seconds_to_time(var/seconds as num)
|
||||
var/numSeconds = seconds % 60
|
||||
var/numMinutes = (seconds - numSeconds) / 60
|
||||
return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds."
|
||||
return "[numMinutes] [numMinutes > 1 ? "minutes" : "minute"] and [numSeconds] seconds"
|
||||
|
||||
//Take a value in seconds and makes it display like a clock
|
||||
/proc/seconds_to_clock(var/seconds as num)
|
||||
|
||||
@@ -47,7 +47,10 @@ GLOBAL_LIST_EMPTY(ladders)
|
||||
GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing.
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
|
||||
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
|
||||
GLOBAL_LIST_EMPTY(explosive_walls)
|
||||
|
||||
GLOBAL_LIST_EMPTY(engine_beacon_list)
|
||||
|
||||
/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc.
|
||||
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
|
||||
|
||||
+74
-57
@@ -145,12 +145,10 @@
|
||||
/mob/living/silicon/ai/MiddleClickOn(var/atom/A)
|
||||
A.AIMiddleClick(src)
|
||||
|
||||
/*
|
||||
The following criminally helpful code is just the previous code cleaned up;
|
||||
I have no idea why it was in atoms.dm instead of respective files.
|
||||
*/
|
||||
|
||||
/atom/proc/AICtrlShiftClick(var/mob/user) // Examines
|
||||
// DEFAULT PROCS TO OVERRIDE
|
||||
|
||||
/atom/proc/AICtrlShiftClick(mob/user) // Examines
|
||||
if(user.client)
|
||||
user.examinate(src)
|
||||
return
|
||||
@@ -158,74 +156,93 @@
|
||||
/atom/proc/AIAltShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIAltShiftClick() // Sets/Unsets Emergency Access Override
|
||||
if(density)
|
||||
Topic(src, list("src" = UID(), "command"="emergency", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="emergency", "activate" = "0"), 1)
|
||||
return
|
||||
|
||||
/atom/proc/AIShiftClick(var/mob/user)
|
||||
/atom/proc/AIShiftClick(mob/living/user) // borgs use this too
|
||||
if(user.client)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
|
||||
if(density)
|
||||
Topic(src, list("src" = UID(), "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="open", "activate" = "0"), 1)
|
||||
/atom/proc/AICtrlClick(mob/living/silicon/ai/user)
|
||||
return
|
||||
|
||||
/atom/proc/AICtrlClick(var/mob/living/silicon/ai/user)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
|
||||
if(locked)
|
||||
Topic(src, list("src" = UID(), "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="bolts", "activate" = "1"), 1)
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
|
||||
Topic("breaker=1", list("breaker"="1"), 0) // 0 meaning no window (consistency! wait...)
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
|
||||
Topic(src, list("src" = UID(), "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!)
|
||||
|
||||
/atom/proc/AIAltClick(var/atom/A)
|
||||
/atom/proc/AIAltClick(atom/A)
|
||||
AltClick(A)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick() // Electrifies doors.
|
||||
if(!electrified_until)
|
||||
// permanent shock
|
||||
Topic(src, list("src" = UID(), "command"="electrify_permanently", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permanent shock
|
||||
Topic(src, list("src" = UID(), "command"="electrify_permanently", "activate" = "0"), 1)
|
||||
/atom/proc/AIMiddleClick(mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/TurfAdjacent(turf/T)
|
||||
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
|
||||
|
||||
|
||||
// APC
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick(mob/living/user) // turns off/on APCs.
|
||||
toggle_breaker(user)
|
||||
|
||||
|
||||
// TURRETCONTROL
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick(mob/living/silicon/ai/user) //turns off/on Turrets
|
||||
enabled = !enabled
|
||||
updateTurrets()
|
||||
|
||||
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
|
||||
Topic(src, list("src" = UID(), "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!)
|
||||
if(lethal_is_configurable)
|
||||
lethal = !lethal
|
||||
updateTurrets()
|
||||
|
||||
/atom/proc/AIMiddleClick()
|
||||
return
|
||||
// AIRLOCKS
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights.
|
||||
if(!src.lights)
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
/obj/machinery/door/airlock/AIAltShiftClick(mob/user) // Sets/Unsets Emergency Access Override
|
||||
emergency = !emergency
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/airlock/AIShiftClick(mob/user) // Opens and closes doors!
|
||||
if(welded)
|
||||
to_chat(user, "<span class='warning'>The airlock has been welded shut!</span>")
|
||||
if(locked)
|
||||
locked = !locked
|
||||
if(density)
|
||||
open()
|
||||
else
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "0"), 1)
|
||||
return
|
||||
close()
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick() //Turns liquid dispenser on or off
|
||||
/obj/machinery/door/airlock/AICtrlClick(mob/living/silicon/ai/user) // Bolts doors
|
||||
locked = !locked
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick(mob/living/silicon/ai/user) // Electrifies doors.
|
||||
if(wires.is_cut(WIRE_ELECTRIFY))
|
||||
to_chat(user, "<span class='warning'>The electrification wire is cut - Cannot electrify the door.</span>")
|
||||
if(isElectrified())
|
||||
electrify(0) // un-shock
|
||||
else
|
||||
electrify(-1) // permanent shock
|
||||
|
||||
|
||||
/obj/machinery/door/airlock/AIMiddleClick(mob/living/user) // Toggles door bolt lights.
|
||||
if(wires.is_cut(WIRE_BOLT_LIGHT))
|
||||
to_chat(user, "<span class='warning'>The bolt lights wire has been cut - The door bolt lights are permanently disabled.</span>")
|
||||
else if(lights)
|
||||
lights = FALSE
|
||||
to_chat(user, "<span class='notice'>The door bolt lights have been disabled.</span>")
|
||||
else if(!lights)
|
||||
lights = TRUE
|
||||
to_chat(user, "<span class='notice'>The door bolt lights have been enabled.</span>")
|
||||
update_icon()
|
||||
|
||||
// FIRE ALARMS
|
||||
|
||||
/obj/machinery/firealarm/AICtrlClick()
|
||||
if(enabled)
|
||||
reset()
|
||||
else
|
||||
alarm()
|
||||
|
||||
// AI-CONTROLLED SLIP GENERATOR IN AI CORE
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick(mob/living/silicon/ai/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
//
|
||||
// Override AdjacentQuick for AltClicking
|
||||
//
|
||||
|
||||
/mob/living/silicon/ai/TurfAdjacent(var/turf/T)
|
||||
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
|
||||
|
||||
@@ -170,6 +170,9 @@
|
||||
/obj/machinery/ai_slipper/BorgAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
/obj/machinery/firealarm/BorgCtrlClick()
|
||||
AICtrlClick()
|
||||
|
||||
/*
|
||||
As with AI, these are not used in click code,
|
||||
because the code for robots is specific, not generic.
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/obj/screen/ai/alerts/Click()
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_alarm_monitor()
|
||||
AI.ai_alerts()
|
||||
|
||||
/obj/screen/ai/announcement
|
||||
name = "Make Announcement"
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
|
||||
/obj/screen/ghost/respawn_pai/Click()
|
||||
var/mob/dead/observer/G = usr
|
||||
if(!GLOB.paiController.check_recruit(G))
|
||||
to_chat(G, "<span class='warning'>You are not eligible to become a pAI.</span>")
|
||||
return
|
||||
GLOB.paiController.recruitWindow(G)
|
||||
|
||||
/datum/hud/ghost
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
using.icon_state = mymob.a_intent
|
||||
static_inventory += using
|
||||
action_intent = using
|
||||
|
||||
|
||||
using = new /obj/screen/guardian/Manifest()
|
||||
using.screen_loc = ui_rhand
|
||||
static_inventory += using
|
||||
@@ -49,8 +49,8 @@
|
||||
/obj/screen/guardian/Manifest/Click()
|
||||
if(isguardian(usr))
|
||||
var/mob/living/simple_animal/hostile/guardian/G = usr
|
||||
G.Manifest()
|
||||
|
||||
if(G.loc == G.summoner)
|
||||
G.Manifest()
|
||||
|
||||
/obj/screen/guardian/Recall
|
||||
icon_state = "recall"
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
SUBSYSTEM_DEF(alarms)
|
||||
name = "Alarms"
|
||||
init_order = INIT_ORDER_ALARMS // 2
|
||||
offline_implications = "Alarms (Power, camera, fire, etc) will no longer be checked. No immediate action is needed."
|
||||
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
var/datum/alarm_handler/burglar/burglar_alarm = new()
|
||||
var/datum/alarm_handler/camera/camera_alarm = new()
|
||||
var/datum/alarm_handler/fire/fire_alarm = new()
|
||||
var/datum/alarm_handler/motion/motion_alarm = new()
|
||||
var/datum/alarm_handler/power/power_alarm = new()
|
||||
var/list/datum/alarm/all_handlers
|
||||
SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
var/list/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" = list())
|
||||
|
||||
/datum/controller/subsystem/alarms/Initialize(start_timeofday)
|
||||
all_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
return ..()
|
||||
/datum/controller/subsystem/alarm/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
|
||||
var/list/L = alarms[class]
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if(!(alarmsource.UID() in sources))
|
||||
sources += alarmsource.UID()
|
||||
return TRUE
|
||||
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
|
||||
SEND_SIGNAL(SSalarm, COMSIG_TRIGGERED_ALARM, class, A, O, alarmsource)
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/alarms/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
/datum/controller/subsystem/alarm/proc/cancelAlarm(class, area/A, obj/origin)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = FALSE
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
srcs -= origin.UID()
|
||||
if(!length(srcs))
|
||||
cleared = TRUE
|
||||
L -= I
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/active_alarms()
|
||||
var/list/all_alarms = new ()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
SEND_SIGNAL(SSalarm, COMSIG_CANCELLED_ALARM, class, A, origin, cleared)
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
offline_implications = "Chat messages will no longer be cleanly queued. No immediate action is needed."
|
||||
|
||||
var/list/payload = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
if(C)
|
||||
C << output(payload[C], "browseroutput:output")
|
||||
payload -= C
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, flag)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
stack_trace("to_chat called with invalid input type")
|
||||
return
|
||||
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
message += "<br>"
|
||||
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(islist(target))
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
@@ -0,0 +1,86 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
name = "Instruments"
|
||||
init_order = INIT_ORDER_INSTRUMENTS
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_BACKGROUND|SS_KEEP_TIMING
|
||||
offline_implications = "Instruments will no longer play. No immediate action is needed."
|
||||
|
||||
/// List of all instrument data, associative id = datum
|
||||
var/list/datum/instrument/instrument_data
|
||||
/// List of all song datums.
|
||||
var/list/datum/song/songs
|
||||
/// Max lines in songs
|
||||
var/musician_maxlines = 600
|
||||
/// Max characters per line in songs
|
||||
var/musician_maxlinechars = 300
|
||||
/// Deciseconds between hearchecks. Too high and instruments seem to lag when people are moving around in terms of who can hear it. Too low and the server lags from this.
|
||||
var/musician_hearcheck_mindelay = 5
|
||||
/// Maximum instrument channels total instruments are allowed to use. This is so you don't have instruments deadlocking all sound channels.
|
||||
var/max_instrument_channels = MAX_INSTRUMENT_CHANNELS
|
||||
/// Current number of channels allocated for instruments
|
||||
var/current_instrument_channels = 0
|
||||
/// Single cached list for synthesizer instrument ids, so you don't have to have a new list with every synthesizer.
|
||||
var/list/synthesizer_instrument_ids
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/Initialize()
|
||||
initialize_instrument_data()
|
||||
synthesizer_instrument_ids = get_allowed_instrument_ids()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Initializes all instrument datums
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data()
|
||||
instrument_data = list()
|
||||
for(var/path in subtypesof(/datum/instrument))
|
||||
var/datum/instrument/I = path
|
||||
if(initial(I.abstract_type) == path)
|
||||
continue
|
||||
I = new path
|
||||
I.Initialize()
|
||||
if(!I.id)
|
||||
qdel(I)
|
||||
continue
|
||||
else
|
||||
instrument_data[I.id] = I
|
||||
CHECK_TICK
|
||||
|
||||
/**
|
||||
* Reserves a sound channel for a given instrument datum
|
||||
*
|
||||
* Arguments:
|
||||
* * I - The instrument datum
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/reserve_instrument_channel(datum/instrument/I)
|
||||
if(current_instrument_channels > max_instrument_channels)
|
||||
return
|
||||
. = SSsounds.reserve_sound_channel(I)
|
||||
if(!isnull(.))
|
||||
current_instrument_channels++
|
||||
|
||||
/**
|
||||
* Called when a datum/song is created
|
||||
*
|
||||
* Arguments:
|
||||
* * S - The created datum/song
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S)
|
||||
LAZYADD(songs, S)
|
||||
|
||||
/**
|
||||
* Called when a datum/song is deleted
|
||||
*
|
||||
* Arguments:
|
||||
* * S - The deleted datum/song
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_del(datum/song/S)
|
||||
LAZYREMOVE(songs, S)
|
||||
|
||||
/**
|
||||
* Returns the instrument datum at the given ID or path
|
||||
*
|
||||
* Arguments:
|
||||
* * id_or_path - The ID or path of the instrument
|
||||
*/
|
||||
/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path)
|
||||
return instrument_data["[id_or_path]"]
|
||||
@@ -14,9 +14,9 @@ SUBSYSTEM_DEF(shuttle)
|
||||
//emergency shuttle stuff
|
||||
var/obj/docking_port/mobile/emergency/emergency
|
||||
var/obj/docking_port/mobile/emergency/backup/backup_shuttle
|
||||
var/emergencyCallTime = 6000 //time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
var/emergencyEscapeTime = 1200 //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
var/emergencyCallTime = SHUTTLE_CALLTIME //time taken for emergency shuttle to reach the station when called (in deciseconds)
|
||||
var/emergencyDockTime = SHUTTLE_DOCKTIME //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
|
||||
var/emergencyEscapeTime = SHUTTLE_ESCAPETIME //time taken for emergency shuttle to reach a safe distance after leaving station (in deciseconds)
|
||||
var/emergency_sec_level_time = 0 // time sec level was last raised to red or higher
|
||||
var/area/emergencyLastCallLoc
|
||||
var/emergencyNoEscape
|
||||
@@ -93,6 +93,11 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return S
|
||||
WARNING("couldn't find dock with id: [id]")
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/secondsToRefuel()
|
||||
var/elapsed = world.time - SSticker.round_start_time
|
||||
var/remaining = round((config.shuttle_refuel_delay - elapsed) / 10)
|
||||
return remaining > 0 ? remaining : 0
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
|
||||
if(!emergency)
|
||||
WARNING("requestEvac(): There is no emergency shuttle, but the shuttle was called. Using the backup shuttle instead.")
|
||||
@@ -107,7 +112,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return
|
||||
emergency = backup_shuttle
|
||||
|
||||
if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay)
|
||||
if(secondsToRefuel())
|
||||
to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.")
|
||||
return
|
||||
|
||||
@@ -131,7 +136,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
|
||||
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH)
|
||||
to_chat(user, "You must provide a reason.")
|
||||
to_chat(user, "Reason is too short. [CALL_SHUTTLE_REASON_LENGTH] character minimum.")
|
||||
return
|
||||
|
||||
var/area/signal_origin = get_area(user)
|
||||
@@ -192,7 +197,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/obj/machinery/computer/communications/C = thing
|
||||
if(C.stat & BROKEN)
|
||||
continue
|
||||
else if(istype(thing, /datum/computer_file/program/comm) || istype(thing, /obj/item/circuitboard/communications))
|
||||
else if(istype(thing, /obj/item/circuitboard/communications))
|
||||
continue
|
||||
|
||||
var/turf/T = get_turf(thing)
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#define DATUMLESS "NO_DATUM"
|
||||
|
||||
SUBSYSTEM_DEF(sounds)
|
||||
name = "Sounds"
|
||||
init_order = INIT_ORDER_SOUNDS
|
||||
flags = SS_NO_FIRE
|
||||
offline_implications = "Sounds may not play correctly. Shuttle call recommended."
|
||||
|
||||
var/using_channels_max = CHANNEL_HIGHEST_AVAILABLE // BYOND max channels
|
||||
/// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up.
|
||||
var/random_channels_min = 50
|
||||
// Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing.
|
||||
/// Assoc list, "[channel]" = either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
|
||||
var/list/using_channels
|
||||
/// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved.
|
||||
var/list/using_channels_by_datum
|
||||
// Special datastructure for fast channel management
|
||||
/// List of all channels as numbers
|
||||
var/list/channel_list
|
||||
/// Associative list of all reserved channels associated to their position. "[channel_number]" = index as number
|
||||
var/list/reserved_channels
|
||||
/// lower iteration position - Incremented and looped to get "random" sound channels for normal sounds. The channel at this index is returned when asking for a random channel.
|
||||
var/channel_random_low
|
||||
/// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel.
|
||||
var/channel_reserve_high
|
||||
|
||||
/datum/controller/subsystem/sounds/Initialize()
|
||||
setup_available_channels()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Sets up all available sound channels
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/setup_available_channels()
|
||||
channel_list = list()
|
||||
reserved_channels = list()
|
||||
using_channels = list()
|
||||
using_channels_by_datum = list()
|
||||
for(var/i in 1 to using_channels_max)
|
||||
channel_list += i
|
||||
channel_random_low = 1
|
||||
channel_reserve_high = length(channel_list)
|
||||
|
||||
/**
|
||||
* Removes a channel from using list
|
||||
*
|
||||
* Arguments:
|
||||
* * channel - The channel number
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
|
||||
var/text_channel = num2text(channel)
|
||||
var/using = using_channels[text_channel]
|
||||
using_channels -= text_channel
|
||||
if(!using) // datum channel
|
||||
using_channels_by_datum[using] -= channel
|
||||
if(!length(using_channels_by_datum[using]))
|
||||
using_channels_by_datum -= using
|
||||
free_channel(channel)
|
||||
|
||||
/**
|
||||
* Frees all the channels a datum is using
|
||||
*
|
||||
* Arguments:
|
||||
* * D - The datum
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D)
|
||||
var/list/L = using_channels_by_datum[D]
|
||||
if(!L)
|
||||
return
|
||||
for(var/channel in L)
|
||||
using_channels -= num2text(channel)
|
||||
free_channel(channel)
|
||||
using_channels_by_datum -= D
|
||||
|
||||
/**
|
||||
* Frees all datumless channels
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_datumless_channels()
|
||||
free_datum_channels(DATUMLESS)
|
||||
|
||||
/**
|
||||
* NO AUTOMATIC CLEANUP - If you use this, you better manually free it later!
|
||||
*
|
||||
* Returns an integer for channel
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless()
|
||||
. = reserve_channel()
|
||||
if(!.) // oh no..
|
||||
return FALSE
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = DATUMLESS
|
||||
LAZYADD(using_channels_by_datum[DATUMLESS], .)
|
||||
|
||||
/**
|
||||
* Reserves a channel for a datum. Automatic cleanup only when the datum is deleted.
|
||||
*
|
||||
* Returns an integer for channel
|
||||
* Arguments:
|
||||
* * D - The datum
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D)
|
||||
if(!D) // i don't like typechecks but someone will fuck it up
|
||||
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
|
||||
. = reserve_channel()
|
||||
if(!.)
|
||||
return FALSE
|
||||
var/text_channel = num2text(.)
|
||||
using_channels[text_channel] = D
|
||||
LAZYADD(using_channels_by_datum[D], .)
|
||||
|
||||
/**
|
||||
* Reserves a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/reserve_channel()
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(channel_reserve_high <= random_channels_min) // out of channels
|
||||
return
|
||||
var/channel = channel_list[channel_reserve_high]
|
||||
reserved_channels[num2text(channel)] = channel_reserve_high--
|
||||
return channel
|
||||
|
||||
/**
|
||||
* Frees a channel and updates the datastructure. Private proc.
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/free_channel(number)
|
||||
PRIVATE_PROC(TRUE)
|
||||
var/text_channel = num2text(number)
|
||||
var/index = reserved_channels[text_channel]
|
||||
if(!index)
|
||||
CRASH("Attempted to (internally) free a channel that wasn't reserved.")
|
||||
reserved_channels -= text_channel
|
||||
// push reserve index up, which makes it now on a channel that is reserved
|
||||
channel_reserve_high++
|
||||
// swap the reserved channel with the unreserved channel so the reserve index is now on an unoccupied channel and the freed channel is next to be used.
|
||||
channel_list.Swap(channel_reserve_high, index)
|
||||
// now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index
|
||||
// get it, and update position.
|
||||
var/text_reserved = num2text(channel_list[index])
|
||||
if(!reserved_channels[text_reserved]) // if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list!
|
||||
return
|
||||
reserved_channels[text_reserved] = index
|
||||
|
||||
/**
|
||||
* Random available channel, returns text
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel_text()
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = "[channel_list[channel_random_low++]]"
|
||||
|
||||
/**
|
||||
* Random available channel, returns number
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel()
|
||||
if(channel_random_low > channel_reserve_high)
|
||||
channel_random_low = 1
|
||||
. = channel_list[channel_random_low++]
|
||||
|
||||
/**
|
||||
* How many channels we have left
|
||||
*/
|
||||
/datum/controller/subsystem/sounds/proc/available_channels_left()
|
||||
return length(channel_list) - random_channels_min
|
||||
|
||||
#undef DATUMLESS
|
||||
@@ -20,7 +20,7 @@
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
|
||||
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
|
||||
"Cameras", "Garbage", "Event", "Nano", "Vote", "Fires",
|
||||
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
@@ -65,9 +65,6 @@
|
||||
if("Event")
|
||||
debug_variables(SSevents)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(SSalarms)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Nano")
|
||||
debug_variables(SSnanoui)
|
||||
feedback_add_details("admin_verb","DNano")
|
||||
|
||||
+3
-16
@@ -190,9 +190,6 @@
|
||||
/datum/action/item_action/toggle_mister
|
||||
name = "Toggle Mister"
|
||||
|
||||
/datum/action/item_action/toggle_headphones
|
||||
name = "Toggle Headphones"
|
||||
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
@@ -232,19 +229,6 @@
|
||||
button.name = name
|
||||
..()
|
||||
|
||||
/datum/action/item_action/synthswitch
|
||||
name = "Change Synthesizer Instrument"
|
||||
desc = "Change the type of instrument your synthesizer is playing as."
|
||||
|
||||
/datum/action/item_action/synthswitch/Trigger()
|
||||
if(istype(target, /obj/item/instrument/piano_synth))
|
||||
var/obj/item/instrument/piano_synth/synth = target
|
||||
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", "piano") as null|anything in synth.insTypes
|
||||
if(!synth.insTypes[chosen])
|
||||
return
|
||||
return synth.changeInstrument(chosen)
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
|
||||
@@ -257,6 +241,9 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/change_headphones_song
|
||||
name = "Change Headphones Song"
|
||||
|
||||
/datum/action/item_action/toggle
|
||||
|
||||
/datum/action/item_action/toggle/New(Target)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/component/spooky
|
||||
var/too_spooky = TRUE //will it spawn a new instrument?
|
||||
|
||||
/datum/component/spooky/Initialize()
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
|
||||
|
||||
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
|
||||
if(ishuman(user)) //this weapon wasn't meant for mortals.
|
||||
var/mob/living/carbon/human/U = user
|
||||
if(!istype(U.dna.species, /datum/species/skeleton))
|
||||
U.adjustStaminaLoss(35) //Extra Damage
|
||||
U.Jitter(35)
|
||||
U.stuttering = 20
|
||||
if(U.getStaminaLoss() > 95)
|
||||
to_chat(U, "<font color='red' size='4'><b>Your ears weren't meant for this spectral sound.</b></font>")
|
||||
spectral_change(U)
|
||||
return
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(istype(H.dna.species, /datum/species/skeleton))
|
||||
return //undeads are unaffected by the spook-pocalypse.
|
||||
C.Jitter(35)
|
||||
C.stuttering = 20
|
||||
if(!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman))
|
||||
C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
|
||||
to_chat(C, "<font color='red' size='4'><B>DOOT</B></font>")
|
||||
spectral_change(H)
|
||||
|
||||
else //the sound will spook monkeys.
|
||||
C.Jitter(15)
|
||||
C.stuttering = 20
|
||||
|
||||
/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
|
||||
if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman) && !istype(H.dna.species, /datum/species/skeleton)))
|
||||
H.Stun(20)
|
||||
H.set_species(/datum/species/skeleton)
|
||||
H.visible_message("<span class='warning'>[H] has given up on life as a mortal.</span>")
|
||||
var/T = get_turf(H)
|
||||
if(too_spooky)
|
||||
if(prob(30))
|
||||
new/obj/item/instrument/saxophone/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trumpet/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trombone/spectral(T)
|
||||
else
|
||||
to_chat(H, "<span class='boldwarning'>The spooky gods forgot to ship your instrument. Better luck next unlife.</span>")
|
||||
to_chat(H, "<span class='boldnotice'>You are the spooky skeleton!</span>")
|
||||
to_chat(H, "<span class='boldnotice'>A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.</span>")
|
||||
change_name(H) //time for a new name!
|
||||
|
||||
/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
|
||||
var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)
|
||||
if(!t)
|
||||
t = "spooky skeleton"
|
||||
H.real_name = t
|
||||
H.name = t
|
||||
@@ -71,7 +71,7 @@
|
||||
var/list/atoms_cache = output_atoms
|
||||
var/sound/S = sound(soundfile)
|
||||
if(direct)
|
||||
S.channel = open_sound_channel()
|
||||
S.channel = SSsounds.random_available_channel()
|
||||
S.volume = volume
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
|
||||
@@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable
|
||||
pipe_id = PIPE_CIRCULATOR
|
||||
pipe_icon = "circ"
|
||||
|
||||
/datum/pipes/atmospheric/omni_filter
|
||||
pipe_name = "omni filter"
|
||||
pipe_id = PIPE_OMNI_FILTER
|
||||
pipe_icon = "omni_filter"
|
||||
|
||||
/datum/pipes/atmospheric/omni_mixer
|
||||
pipe_name = "omni mixer"
|
||||
pipe_id = PIPE_OMNI_MIXER
|
||||
pipe_icon = "omni_mixer"
|
||||
|
||||
/datum/pipes/atmospheric/insulated
|
||||
pipe_name = "insulated pipe"
|
||||
pipe_id = PIPE_INSULATED_STRAIGHT
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
name = "Biodome Winter"
|
||||
id = "biodome-winter"
|
||||
description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \
|
||||
Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)."
|
||||
Includes the recently introduced I.C.E(tm)."
|
||||
suffix = "lavaland_biodome_winter.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome/clown
|
||||
|
||||
@@ -248,3 +248,29 @@
|
||||
allow_duplicates = FALSE // I dont even want to think about what happens if you have 2 shuttles with the same ID. Likely scary stuff.
|
||||
always_place = TRUE // Its designed to make exploring other space ruins more accessible
|
||||
cost = 0 // Force spawned so shouldnt have a cost
|
||||
|
||||
/datum/map_template/ruin/space/syndiecakesfactory
|
||||
id = "Syndiecakes Factory"
|
||||
suffix = "syndiecakesfactory.dmm"
|
||||
name = "Syndicakes Factory"
|
||||
description = "Syndicate used to get funds selling corgi cakes produced here. Was it hit by meteors or by a Nanotrasen comando?"
|
||||
allow_duplicates = FALSE
|
||||
cost = 2 //telecomms + multiple mobs
|
||||
|
||||
/datum/map_template/ruin/space/debris1
|
||||
id = "debris1"
|
||||
suffix = "debris1.dmm"
|
||||
name = "Debris field 1"
|
||||
description = "A bunch of metal chunks, wires and space waste"
|
||||
|
||||
/datum/map_template/ruin/space/debris2
|
||||
id = "debris2"
|
||||
suffix = "debris2.dmm"
|
||||
name = "Debris field 2"
|
||||
description = "A bunch of metal chunks, wires and space waste that used to be some kind of secure storage facility"
|
||||
|
||||
/datum/map_template/ruin/space/debris3
|
||||
id = "debris3"
|
||||
suffix = "debris3.dmm"
|
||||
name = "Debris field 3"
|
||||
description = "A bunch of metal chunks, wires and space waste. It used to be an arcade."
|
||||
|
||||
@@ -133,3 +133,8 @@
|
||||
suffix = "admin"
|
||||
name = "NTV Argos"
|
||||
description = "Default Admin ship. An older ship used for special operations."
|
||||
|
||||
/datum/map_template/shuttle/admin/armory
|
||||
suffix = "armory"
|
||||
name = "NRV Sparta"
|
||||
description = "Armory Shuttle, with plenty of guns to hand out and some general supplies."
|
||||
|
||||
@@ -6,44 +6,47 @@
|
||||
qdel(src)
|
||||
owner = new_owner
|
||||
|
||||
/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = FALSE, datum/topic_state/state = GLOB.ghost_state, datum/nanoui/master_ui = null)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/spawners_menu/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui_state/state = GLOB.tgui_observer_state, datum/tgui/master_ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "spawners_menu.tmpl", "Spawners Menu", 700, 600, master_ui, state = state)
|
||||
ui = new(user, src, ui_key, "SpawnersMenu", "Spawners Menu", 700, 600, master_ui, state = state)
|
||||
ui.open()
|
||||
|
||||
/datum/spawners_menu/ui_data(mob/user)
|
||||
/datum/spawners_menu/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["spawners"] = list()
|
||||
for(var/spawner in GLOB.mob_spawners)
|
||||
var/list/this = list()
|
||||
this["name"] = spawner
|
||||
this["desc"] = ""
|
||||
this["important_info"] = ""
|
||||
this["fluff"] = ""
|
||||
this["uids"] = list()
|
||||
for(var/spawner_obj in GLOB.mob_spawners[spawner])
|
||||
for(var/spawner_obj in GLOB.mob_spawners[spawner])//each spawner can contain multiple actual spawners, we use only one desc/info
|
||||
this["uids"] += "\ref[spawner_obj]"
|
||||
if(!this["desc"])
|
||||
if(!this["desc"]) //haven't set descriptions yet
|
||||
if(istype(spawner_obj, /obj/effect/mob_spawn))
|
||||
var/obj/effect/mob_spawn/MS = spawner_obj
|
||||
this["desc"] = MS.flavour_text
|
||||
this["desc"] = MS.description
|
||||
this["important_info"] = MS.important_info
|
||||
this["fluff"] = MS.flavour_text
|
||||
else
|
||||
var/obj/O = spawner_obj
|
||||
this["desc"] = O.desc
|
||||
this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner])
|
||||
data["spawners"] += list(this)
|
||||
|
||||
return data
|
||||
|
||||
/datum/spawners_menu/Topic(href, href_list)
|
||||
/datum/spawners_menu/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
var/spawners = replacetext(href_list["uid"], ",", ";")
|
||||
return
|
||||
var/spawners = replacetext(params["ID"], ",", ";")
|
||||
var/list/possible_spawners = params2list(spawners)
|
||||
var/obj/effect/mob_spawn/MS = locate(pick(possible_spawners))
|
||||
if(!MS || !istype(MS))
|
||||
log_runtime(EXCEPTION("A ghost tried to interact with an invalid spawner, or the spawner didn't exist."))
|
||||
return
|
||||
switch(href_list["action"])
|
||||
switch(action)
|
||||
if("jump")
|
||||
owner.forceMove(get_turf(MS))
|
||||
. = TRUE
|
||||
|
||||
@@ -736,6 +736,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 12 // normally 18
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/bulldog_XLmagsbag
|
||||
name = "Bulldog - 12g XL Magazine Duffel Bag"
|
||||
desc = "A duffel bag containing three 16 round drum magazines(Slug, Buckshot, Dragon's Breath)."
|
||||
reference = "12XLDB"
|
||||
item = /obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags
|
||||
cost = 12 // normally 18
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/smg
|
||||
name = "C-20r - .45 Magazine"
|
||||
desc = "An additional 20-round .45 magazine for use in the C-20r submachine gun. These bullets pack a lot of punch that can knock most targets down, but do limited overall damage."
|
||||
@@ -1725,8 +1733,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
U.purchase_log += "<BIG>[bicon(C)]</BIG>"
|
||||
for(var/item in bought_items)
|
||||
new item(C)
|
||||
U.purchase_log += "<BIG>[bicon(item)]</BIG>"
|
||||
var/obj/purchased = new item(C)
|
||||
U.purchase_log += "<BIG>[bicon(purchased)]</BIG>"
|
||||
log_game("[key_name(usr)] purchased a surplus crate with [jointext(itemlog, ", ")]")
|
||||
|
||||
/datum/uplink_item/bundles_TC/telecrystal
|
||||
|
||||
+76
-119
@@ -1,67 +1,29 @@
|
||||
// Wires for airlocks
|
||||
|
||||
/datum/wires/airlock/secure
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/airlock
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
wire_count = 12
|
||||
window_x = 410
|
||||
window_y = 570
|
||||
wire_count = 12 // 10 actual, 2 duds.
|
||||
proper_name = "Airlock"
|
||||
window_x = 400
|
||||
window_y = 101
|
||||
|
||||
#define AIRLOCK_WIRE_IDSCAN 1
|
||||
#define AIRLOCK_WIRE_MAIN_POWER1 2
|
||||
#define AIRLOCK_WIRE_DOOR_BOLTS 4
|
||||
#define AIRLOCK_WIRE_BACKUP_POWER1 8
|
||||
#define AIRLOCK_WIRE_OPEN_DOOR 16
|
||||
#define AIRLOCK_WIRE_AI_CONTROL 32
|
||||
#define AIRLOCK_WIRE_ELECTRIFY 64
|
||||
#define AIRLOCK_WIRE_SAFETY 128
|
||||
#define AIRLOCK_WIRE_SPEED 256
|
||||
#define AIRLOCK_WIRE_LIGHT 512
|
||||
/datum/wires/airlock/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_DOOR_BOLTS, WIRE_BACKUP_POWER1, WIRE_OPEN_DOOR,
|
||||
WIRE_AI_CONTROL, WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SPEED, WIRE_BOLT_LIGHT
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/airlock/GetWireName(index)
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
return "Door Bolts"
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
return "Primary Backup Power"
|
||||
|
||||
if(AIRLOCK_WIRE_OPEN_DOOR)
|
||||
return "Door State"
|
||||
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Door Safeties"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Door Timing"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Bolt Lights"
|
||||
|
||||
/datum/wires/airlock/CanUse(mob/living/L)
|
||||
/datum/wires/airlock/interactable(mob/user)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(iscarbon(L))
|
||||
if(A.Adjacent(L))
|
||||
if(A.isElectrified())
|
||||
if(A.shock(L, 100))
|
||||
return 0
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.isElectrified() && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/airlock/get_status()
|
||||
. = ..()
|
||||
@@ -70,21 +32,20 @@
|
||||
|
||||
. += "The door bolts [A.locked ? "have fallen!" : "look up."]"
|
||||
. += "The door bolt lights are [(A.lights && haspower) ? "on." : "off!"]"
|
||||
. += "The test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !A.emagged && haspower) ? "on" : "off"]."
|
||||
. += "The test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == AICONTROLDISABLED_OFF && !A.emagged && haspower) ? "on" : "off"]."
|
||||
. += "The 'Check Wiring' light is [(A.safe == 0 && haspower) ? "on" : "off"]."
|
||||
. += "The 'Check Timing Mechanism' light is [(A.normalspeed == 0 && haspower) ? "on" : "off"]."
|
||||
. += "The emergency lights are [(A.emergency && haspower) ? "on" : "off"]."
|
||||
|
||||
/datum/wires/airlock/UpdateCut(index, mended)
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
A.aiDisabledIdScanner = !mended
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.aiDisabledIdScanner = !mend
|
||||
if(WIRE_MAIN_POWER1)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user.
|
||||
A.loseMainPower()
|
||||
A.shock(usr, 50)
|
||||
@@ -92,9 +53,9 @@
|
||||
A.regainMainPower()
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
if(WIRE_BACKUP_POWER1)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user.
|
||||
A.loseBackupPower()
|
||||
A.shock(usr, 50)
|
||||
@@ -102,66 +63,66 @@
|
||||
A.regainBackupPower()
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
if(WIRE_DOOR_BOLTS)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present)
|
||||
A.lock(1)
|
||||
A.update_icon()
|
||||
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
if(WIRE_AI_CONTROL)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all.
|
||||
//aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
//aiControlDisabled: see explanation in code\__DEFINES\construction.dm#32
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_OFF)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_ON
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_PERMA)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_BYPASS
|
||||
else
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_ON)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_OFF
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_BYPASS)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_PERMA
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
if(!mended)
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(!mend)
|
||||
//Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted.
|
||||
A.electrify(-1)
|
||||
else
|
||||
A.electrify(0)
|
||||
return // Don't update the dialog.
|
||||
|
||||
if(AIRLOCK_WIRE_SAFETY)
|
||||
A.safe = mended
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = mend
|
||||
|
||||
if(AIRLOCK_WIRE_SPEED)
|
||||
A.autoclose = mended
|
||||
if(mended)
|
||||
if(WIRE_SPEED)
|
||||
A.autoclose = mend
|
||||
if(mend)
|
||||
if(!A.density)
|
||||
spawn(0)
|
||||
A.close()
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(AIRLOCK_WIRE_LIGHT)
|
||||
A.lights = mended
|
||||
if(WIRE_BOLT_LIGHT)
|
||||
A.lights = mend
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
/datum/wires/airlock/UpdatePulsed(index)
|
||||
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
//Sending a pulse through flashes the red light on the door (if the door has power).
|
||||
if(A.arePowerSystemsOn() && A.density)
|
||||
A.do_animate("deny")
|
||||
if(A.emergency)
|
||||
A.emergency = 0
|
||||
A.update_icon()
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
|
||||
if(WIRE_MAIN_POWER1)
|
||||
//Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter).
|
||||
A.loseMainPower()
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
|
||||
if(WIRE_DOOR_BOLTS)
|
||||
//one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not),
|
||||
//raises them if they are down (only if power's on)
|
||||
if(!A.locked)
|
||||
@@ -170,45 +131,41 @@
|
||||
else if(A.unlock())
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", hearing_distance = 1)
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
if(WIRE_BACKUP_POWER1)
|
||||
//two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter).
|
||||
A.loseBackupPower()
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
|
||||
spawn(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_OFF)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_ON
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_PERMA)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_BYPASS
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/ai_control_callback), 1 SECONDS)
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
//one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds.
|
||||
A.electrify(30)
|
||||
if(AIRLOCK_WIRE_OPEN_DOOR)
|
||||
|
||||
if(WIRE_OPEN_DOOR)
|
||||
//tries to open the door without ID
|
||||
//will succeed only if the ID wire is cut or the door requires no access and it's not emagged
|
||||
if(A.emagged) return
|
||||
if(!A.requiresID() || A.check_access(null))
|
||||
spawn(0)
|
||||
if(A.density)
|
||||
A.open()
|
||||
else
|
||||
A.close()
|
||||
if(AIRLOCK_WIRE_SAFETY)
|
||||
if(A.density)
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/open)
|
||||
else
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = !A.safe
|
||||
if(!A.density)
|
||||
spawn(0)
|
||||
A.close()
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(AIRLOCK_WIRE_SPEED)
|
||||
if(WIRE_SPEED)
|
||||
A.normalspeed = !A.normalspeed
|
||||
|
||||
if(AIRLOCK_WIRE_LIGHT)
|
||||
if(WIRE_BOLT_LIGHT)
|
||||
A.lights = !A.lights
|
||||
A.update_icon()
|
||||
|
||||
|
||||
+41
-69
@@ -2,35 +2,22 @@
|
||||
/datum/wires/alarm
|
||||
holder_type = /obj/machinery/alarm
|
||||
wire_count = 5
|
||||
window_x = 385
|
||||
window_y = 90
|
||||
proper_name = "Air alarm"
|
||||
|
||||
#define AALARM_WIRE_IDSCAN 1
|
||||
#define AALARM_WIRE_POWER 2
|
||||
#define AALARM_WIRE_SYPHON 4
|
||||
#define AALARM_WIRE_AI_CONTROL 8
|
||||
#define AALARM_WIRE_AALARM 16
|
||||
/datum/wires/alarm/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_IDSCAN , WIRE_MAIN_POWER1 , WIRE_SYPHON,
|
||||
WIRE_AI_CONTROL, WIRE_AALARM
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/alarm/GetWireName(index)
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
return "Power"
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
return "Syphon"
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
return "Atmospherics Alarm"
|
||||
|
||||
/datum/wires/alarm/CanUse(mob/living/L)
|
||||
/datum/wires/alarm/interactable(mob/user)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
if(A.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/alarm/get_status()
|
||||
. = ..()
|
||||
@@ -39,75 +26,60 @@
|
||||
. += "The Air Alarm is [(A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "offline." : "working properly!"]"
|
||||
. += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
|
||||
|
||||
/datum/wires/alarm/UpdateCut(index, mended)
|
||||
/datum/wires/alarm/on_cut(wire, mend)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
if(!mended)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
if(!mend)
|
||||
A.locked = 1
|
||||
// to_chat(world, "Idscan wire cut")
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = !mended
|
||||
A.shorted = !mend
|
||||
A.update_icon()
|
||||
// to_chat(world, "Power wire cut")
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
A.aidisabled = !mended
|
||||
// to_chat(world, "AI Control Wire Cut")
|
||||
if(WIRE_AI_CONTROL)
|
||||
A.aidisabled = !mend
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
if(!mended)
|
||||
if(WIRE_SYPHON)
|
||||
if(!mend)
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
A.apply_mode()
|
||||
// to_chat(world, "Syphon Wire Cut")
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(2, A))
|
||||
A.post_alert(2)
|
||||
if(WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_DANGER, A))
|
||||
A.post_alert(ATMOS_ALARM_DANGER)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
/datum/wires/alarm/UpdatePulsed(index)
|
||||
/datum/wires/alarm/on_pulse(wire)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.locked = !A.locked
|
||||
// to_chat(world, "Idscan wire pulsed")
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
// to_chat(world, "Power wire pulsed")
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
if(WIRE_MAIN_POWER1)
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
A.update_icon()
|
||||
addtimer(CALLBACK(A, /obj/machinery/alarm/.proc/unshort_callback), 120 SECONDS)
|
||||
|
||||
spawn(12000)
|
||||
if(A.shorted == 1)
|
||||
A.shorted = 0
|
||||
A.update_icon()
|
||||
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
// to_chat(world, "AI Control wire pulsed")
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
A.updateDialog()
|
||||
spawn(100)
|
||||
if(A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
addtimer(CALLBACK(A, /obj/machinery/alarm/.proc/enable_ai_control_callback), 10 SECONDS)
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
// to_chat(world, "Syphon wire pulsed")
|
||||
|
||||
if(WIRE_SYPHON)
|
||||
if(A.mode == 1) // AALARM_MODE_SCRUB
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
else
|
||||
A.mode = 1 // AALARM_MODE_SCRUB
|
||||
A.apply_mode()
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// to_chat(world, "Aalarm wire pulsed")
|
||||
if(A.alarm_area.atmosalert(0, A))
|
||||
A.post_alert(0)
|
||||
if(WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_NONE, A))
|
||||
A.post_alert(ATMOS_ALARM_NONE)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
+33
-58
@@ -1,25 +1,13 @@
|
||||
/datum/wires/apc
|
||||
holder_type = /obj/machinery/power/apc
|
||||
wire_count = 4
|
||||
proper_name = "APC"
|
||||
window_x = 355
|
||||
window_y = 97
|
||||
|
||||
#define APC_WIRE_IDSCAN 1
|
||||
#define APC_WIRE_MAIN_POWER1 2
|
||||
#define APC_WIRE_MAIN_POWER2 4
|
||||
#define APC_WIRE_AI_CONTROL 8
|
||||
|
||||
/datum/wires/apc/GetWireName(index)
|
||||
switch(index)
|
||||
if(APC_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(APC_WIRE_MAIN_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(APC_WIRE_MAIN_POWER2)
|
||||
return "Secondary Power"
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
/datum/wires/apc/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_AI_CONTROL)
|
||||
return ..()
|
||||
|
||||
/datum/wires/apc/get_status()
|
||||
. = ..()
|
||||
@@ -29,66 +17,53 @@
|
||||
. += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
|
||||
|
||||
|
||||
/datum/wires/apc/CanUse(mob/living/L)
|
||||
/datum/wires/apc/interactable(mob/user)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
if(A.panel_open && !A.opened)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/apc/UpdatePulsed(index)
|
||||
/datum/wires/apc/on_pulse(wire)
|
||||
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.locked = FALSE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/relock_callback), 30 SECONDS)
|
||||
|
||||
if(APC_WIRE_IDSCAN)
|
||||
A.locked = 0
|
||||
|
||||
spawn(300)
|
||||
if(A)
|
||||
A.locked = 1
|
||||
A.updateDialog()
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/check_main_power_callback), 120 SECONDS)
|
||||
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
|
||||
spawn(1200)
|
||||
if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
A.updateDialog()
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
|
||||
spawn(10)
|
||||
if(A && !IsIndexCut(APC_WIRE_AI_CONTROL))
|
||||
A.aidisabled = 0
|
||||
A.updateDialog()
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/check_ai_control_callback), 1 SECONDS)
|
||||
|
||||
..()
|
||||
|
||||
/datum/wires/apc/UpdateCut(index, mended)
|
||||
/datum/wires/apc/on_cut(wire, mend)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
|
||||
if(!mended)
|
||||
switch(wire)
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
if(!mend)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = 1
|
||||
A.shorted = TRUE
|
||||
|
||||
else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
else if(!is_cut(WIRE_MAIN_POWER1) && !is_cut(WIRE_MAIN_POWER2))
|
||||
A.shorted = FALSE
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
|
||||
if(!mended)
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!mend)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
else
|
||||
if(A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
if(A.aidisabled)
|
||||
A.aidisabled = FALSE
|
||||
..()
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
/datum/wires/autolathe
|
||||
holder_type = /obj/machinery/autolathe
|
||||
wire_count = 10
|
||||
proper_name = "Autolathe"
|
||||
window_x = 340
|
||||
window_y = 55
|
||||
|
||||
#define AUTOLATHE_HACK_WIRE 1
|
||||
#define AUTOLATHE_SHOCK_WIRE 2
|
||||
#define AUTOLATHE_DISABLE_WIRE 4
|
||||
|
||||
/datum/wires/autolathe/GetWireName(index)
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
return "Hack"
|
||||
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
return "Shock"
|
||||
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
return "Disable"
|
||||
/datum/wires/autolathe/New(atom/_holder)
|
||||
wires = list(WIRE_AUTOLATHE_HACK, WIRE_ELECTRIFY, WIRE_AUTOLATHE_DISABLE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/autolathe/get_status()
|
||||
. = ..()
|
||||
@@ -24,51 +16,38 @@
|
||||
. += "The green light is [A.shocked ? "off" : "on"]."
|
||||
. += "The blue light is [A.hacked ? "off" : "on"]."
|
||||
|
||||
/datum/wires/autolathe/CanUse()
|
||||
/datum/wires/autolathe/interactable(mob/user)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.shocked && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/autolathe/UpdateCut(index, mended)
|
||||
/datum/wires/autolathe/on_cut(wire, mend)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
A.adjust_hacked(!mended)
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
A.shocked = !mended
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
A.disabled = !mended
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.adjust_hacked(!mend)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !mend
|
||||
if(WIRE_AUTOLATHE_DISABLE)
|
||||
A.disabled = !mend
|
||||
..()
|
||||
|
||||
/datum/wires/autolathe/UpdatePulsed(index)
|
||||
if(IsIndexCut(index))
|
||||
/datum/wires/autolathe/on_pulse(wire)
|
||||
if(is_cut(wire))
|
||||
return
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.adjust_hacked(!A.hacked)
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.adjust_hacked(0)
|
||||
updateUIs()
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
A.shocked = !A.shocked
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.shocked = 0
|
||||
updateUIs()
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
A.disabled = !A.disabled
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.disabled = 0
|
||||
updateUIs()
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_hacked_callback), 5 SECONDS)
|
||||
|
||||
/datum/wires/autolathe/proc/updateUIs()
|
||||
SSnanoui.update_uis(src)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !A.shocked
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_electrified_callback), 5 SECONDS)
|
||||
|
||||
if(WIRE_AUTOLATHE_DISABLE)
|
||||
A.disabled = !A.disabled
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_disabled_callback), 5 SECONDS)
|
||||
|
||||
+20
-25
@@ -1,9 +1,15 @@
|
||||
// Wires for cameras.
|
||||
|
||||
/datum/wires/camera
|
||||
random = 0
|
||||
holder_type = /obj/machinery/camera
|
||||
wire_count = 2
|
||||
proper_name = "Camera"
|
||||
window_x = 350
|
||||
window_y = 95
|
||||
|
||||
/datum/wires/camera/New(atom/_holder)
|
||||
wires = list(WIRE_FOCUS, WIRE_MAIN_POWER1)
|
||||
return ..()
|
||||
|
||||
/datum/wires/camera/get_status()
|
||||
. = ..()
|
||||
@@ -11,51 +17,40 @@
|
||||
. += "The focus light is [(C.view_range == initial(C.view_range)) ? "on" : "off"]."
|
||||
. += "The power link light is [C.can_use() ? "on" : "off"]."
|
||||
|
||||
/datum/wires/camera/CanUse(mob/living/L)
|
||||
/datum/wires/camera/interactable(mob/user)
|
||||
var/obj/machinery/camera/C = holder
|
||||
if(!C.panel_open)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
#define CAMERA_WIRE_FOCUS 1
|
||||
#define CAMERA_WIRE_POWER 2
|
||||
|
||||
/datum/wires/camera/GetWireName(index)
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
return "Focus"
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
return "Power"
|
||||
|
||||
/datum/wires/camera/UpdateCut(index, mended)
|
||||
/datum/wires/camera/on_cut(wire, mend)
|
||||
var/obj/machinery/camera/C = holder
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
var/range = (mended ? initial(C.view_range) : C.short_range)
|
||||
switch(wire)
|
||||
if(WIRE_FOCUS)
|
||||
var/range = (mend ? initial(C.view_range) : C.short_range)
|
||||
C.setViewRange(range)
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
if(C.status && !mended || !C.status && mended)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
if(C.status && !mend || !C.status && mend)
|
||||
C.toggle_cam(usr, TRUE)
|
||||
C.obj_integrity = C.max_integrity //this is a pretty simplistic way to heal the camera, but there's no reason for this to be complex.
|
||||
..()
|
||||
|
||||
/datum/wires/camera/UpdatePulsed(index)
|
||||
/datum/wires/camera/on_pulse(wire)
|
||||
var/obj/machinery/camera/C = holder
|
||||
if(IsIndexCut(index))
|
||||
if(is_cut(wire))
|
||||
return
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
switch(wire)
|
||||
if(WIRE_FOCUS)
|
||||
var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range))
|
||||
C.setViewRange(new_range)
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
C.toggle_cam(null) // Deactivate the camera
|
||||
..()
|
||||
|
||||
/datum/wires/camera/proc/CanDeconstruct()
|
||||
if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS))
|
||||
if(is_cut(WIRE_MAIN_POWER1) && is_cut(WIRE_FOCUS))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
/datum/wires/explosive
|
||||
wire_count = 1
|
||||
proper_name = "Explosive"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
#define WIRE_EXPLODE 1
|
||||
|
||||
/datum/wires/explosive/GetWireName(index)
|
||||
switch(index)
|
||||
if(WIRE_EXPLODE)
|
||||
return "Explode"
|
||||
/datum/wires/explosive/New(atom/_holder)
|
||||
wires = list(WIRE_EXPLODE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/explosive/proc/explode()
|
||||
return
|
||||
|
||||
/datum/wires/explosive/UpdatePulsed(index)
|
||||
switch(index)
|
||||
/datum/wires/explosive/on_pulse(wire)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
explode()
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/UpdateCut(index, mended)
|
||||
switch(index)
|
||||
/datum/wires/explosive/on_cut(wire, mend)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
explode()
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/gibtonite
|
||||
holder_type = /obj/item/twohanded/required/gibtonite
|
||||
|
||||
/datum/wires/explosive/gibtonite/CanUse(mob/L)
|
||||
return 1
|
||||
/datum/wires/explosive/gibtonite/interactable(mob/user)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/gibtonite/UpdateCut(index, mended)
|
||||
/datum/wires/explosive/gibtonite/on_cut(wire, mend)
|
||||
return
|
||||
|
||||
/datum/wires/explosive/gibtonite/explode()
|
||||
|
||||
@@ -1,90 +1,35 @@
|
||||
/datum/wires/mulebot
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
holder_type = /mob/living/simple_animal/bot/mulebot
|
||||
wire_count = 10
|
||||
window_x = 410
|
||||
proper_name = "Mulebot"
|
||||
window_x = 370
|
||||
window_y = -12
|
||||
|
||||
#define MULEBOT_WIRE_POWER1 1 // power connections
|
||||
#define MULEBOT_WIRE_POWER2 2
|
||||
#define MULEBOT_WIRE_AVOIDANCE 4 // mob avoidance
|
||||
#define MULEBOT_WIRE_LOADCHECK 8 // load checking (non-crate)
|
||||
#define MULEBOT_WIRE_MOTOR1 16 // motor wires
|
||||
#define MULEBOT_WIRE_MOTOR2 32 //
|
||||
#define MULEBOT_WIRE_REMOTE_RX 64 // remote recv functions
|
||||
#define MULEBOT_WIRE_REMOTE_TX 128 // remote trans status
|
||||
#define MULEBOT_WIRE_BEACON_RX 256 // beacon ping recv
|
||||
/datum/wires/mulebot/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_MOB_AVOIDANCE,
|
||||
WIRE_LOADCHECK, WIRE_MOTOR1, WIRE_MOTOR2,
|
||||
WIRE_REMOTE_RX, WIRE_REMOTE_TX, WIRE_BEACON_RX
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/mulebot/GetWireName(index)
|
||||
switch(index)
|
||||
if(MULEBOT_WIRE_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(MULEBOT_WIRE_POWER2)
|
||||
return "Secondary Power"
|
||||
|
||||
if(MULEBOT_WIRE_AVOIDANCE)
|
||||
return "Mob Avoidance"
|
||||
|
||||
if(MULEBOT_WIRE_LOADCHECK)
|
||||
return "Load Checking"
|
||||
|
||||
if(MULEBOT_WIRE_MOTOR1)
|
||||
return "Primary Motor"
|
||||
|
||||
if(MULEBOT_WIRE_MOTOR2)
|
||||
return "Secondary Motor"
|
||||
|
||||
if(MULEBOT_WIRE_REMOTE_RX)
|
||||
return "Remote Signal Receiver"
|
||||
|
||||
if(MULEBOT_WIRE_REMOTE_TX)
|
||||
return "Remote Signal Sender"
|
||||
|
||||
if(MULEBOT_WIRE_BEACON_RX)
|
||||
return "Navigation Beacon Receiver"
|
||||
|
||||
/datum/wires/mulebot/CanUse(mob/living/L)
|
||||
/datum/wires/mulebot/interactable(mob/user)
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
if(M.open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/mulebot/UpdatePulsed(index)
|
||||
switch(index)
|
||||
if(MULEBOT_WIRE_POWER1, MULEBOT_WIRE_POWER2)
|
||||
/datum/wires/mulebot/on_pulse(wire)
|
||||
switch(wire)
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The charge light flickers.</span>")
|
||||
if(MULEBOT_WIRE_AVOIDANCE)
|
||||
if(WIRE_MOB_AVOIDANCE)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The external warning lights flash briefly.</span>")
|
||||
if(MULEBOT_WIRE_LOADCHECK)
|
||||
if(WIRE_LOADCHECK)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The load platform clunks.</span>")
|
||||
if(MULEBOT_WIRE_MOTOR1, MULEBOT_WIRE_MOTOR2)
|
||||
if(WIRE_MOTOR1, WIRE_MOTOR2)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The drive motor whines briefly.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] You hear a radio crackle.</span>")
|
||||
..()
|
||||
|
||||
// HELPER PROCS
|
||||
|
||||
/datum/wires/mulebot/proc/Motor1()
|
||||
return !(wires_status & MULEBOT_WIRE_MOTOR1)
|
||||
|
||||
/datum/wires/mulebot/proc/Motor2()
|
||||
return !(wires_status & MULEBOT_WIRE_MOTOR2)
|
||||
|
||||
/datum/wires/mulebot/proc/HasPower()
|
||||
return !(wires_status & MULEBOT_WIRE_POWER1) && !(wires_status & MULEBOT_WIRE_POWER2)
|
||||
|
||||
/datum/wires/mulebot/proc/LoadCheck()
|
||||
return !(wires_status & MULEBOT_WIRE_LOADCHECK)
|
||||
|
||||
/datum/wires/mulebot/proc/MobAvoid()
|
||||
return !(wires_status & MULEBOT_WIRE_AVOIDANCE)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteTX()
|
||||
return !(wires_status & MULEBOT_WIRE_REMOTE_TX)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteRX()
|
||||
return !(wires_status & MULEBOT_WIRE_REMOTE_RX)
|
||||
|
||||
/datum/wires/mulebot/proc/BeaconRX()
|
||||
return !(wires_status & MULEBOT_WIRE_BEACON_RX)
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
/datum/wires/nuclearbomb
|
||||
holder_type = /obj/machinery/nuclearbomb
|
||||
random = 1
|
||||
wire_count = 7
|
||||
randomize = TRUE
|
||||
wire_count = 7 // 3 actual, 4 duds.
|
||||
proper_name = "Nuclear bomb"
|
||||
window_x = 345
|
||||
window_y = 75
|
||||
|
||||
#define NUCLEARBOMB_WIRE_LIGHT 1
|
||||
#define NUCLEARBOMB_WIRE_TIMING 2
|
||||
#define NUCLEARBOMB_WIRE_SAFETY 4
|
||||
/datum/wires/nuclearbomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_LIGHT, WIRE_BOMB_TIMING, WIRE_BOMB_SAFETY)
|
||||
return ..()
|
||||
|
||||
/datum/wires/nuclearbomb/GetWireName(index)
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
return "Bomb Light"
|
||||
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
return "Bomb Timing"
|
||||
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
return "Bomb Safety"
|
||||
|
||||
/datum/wires/nuclearbomb/CanUse(mob/living/L)
|
||||
/datum/wires/nuclearbomb/interactable(mob/user)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
if(N.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/nuclearbomb/get_status()
|
||||
. = ..()
|
||||
@@ -31,52 +23,36 @@
|
||||
. += "The device is is [N.safety ? "quiet" : "whirring"]."
|
||||
. += "The lights are [N.lighthack ? "static" : "functional"]."
|
||||
|
||||
/datum/wires/nuclearbomb/UpdatePulsed(index)
|
||||
/datum/wires/nuclearbomb/on_pulse(wire)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
updateUIs()
|
||||
spawn(100)
|
||||
N.lighthack = !N.lighthack
|
||||
updateUIs()
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
addtimer(CALLBACK(N, /obj/machinery/nuclearbomb/.proc/reset_lighthack_callback), 10 SECONDS)
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
N.safety = !N.safety
|
||||
updateUIs()
|
||||
spawn(100)
|
||||
N.safety = !N.safety
|
||||
if(N.safety == 1)
|
||||
if(!N.is_syndicate)
|
||||
set_security_level(N.previous_level)
|
||||
N.visible_message("<span class='notice'>The [N] quiets down.</span>")
|
||||
if(!N.lighthack)
|
||||
if(N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
else
|
||||
N.visible_message("<span class='notice'>The [N] emits a quiet whirling noise!</span>")
|
||||
updateUIs()
|
||||
|
||||
/datum/wires/nuclearbomb/UpdateCut(index, mended)
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
N.safety = !N.safety
|
||||
addtimer(CALLBACK(N, /obj/machinery/nuclearbomb/.proc/reset_safety_callback), 10 SECONDS)
|
||||
|
||||
/datum/wires/nuclearbomb/on_cut(wire, mend)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(!N.lighthack)
|
||||
if(N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
N.timing = 0
|
||||
GLOB.bomb_set = 0
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
GLOB.bomb_set = FALSE
|
||||
|
||||
/datum/wires/nuclearbomb/proc/updateUIs()
|
||||
SSnanoui.update_uis(src)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
|
||||
@@ -1,67 +1,52 @@
|
||||
/datum/wires/particle_acc/control_box
|
||||
wire_count = 5
|
||||
holder_type = /obj/machinery/particle_accelerator/control_box
|
||||
proper_name = "Particle accelerator control"
|
||||
window_x = 361
|
||||
window_y = 22
|
||||
|
||||
#define PARTICLE_TOGGLE_WIRE 1 // Toggles whether the PA is on or not.
|
||||
#define PARTICLE_STRENGTH_WIRE 2 // Determines the strength of the PA.
|
||||
#define PARTICLE_INTERFACE_WIRE 4 // Determines the interface showing up.
|
||||
#define PARTICLE_LIMIT_POWER_WIRE 8 // Determines how strong the PA can be.
|
||||
/datum/wires/particle_acc/control_box/New(atom/_holder)
|
||||
wires = list(WIRE_PARTICLE_POWER, WIRE_PARTICLE_STRENGTH, WIRE_PARTICLE_INTERFACE, WIRE_PARTICLE_POWER_LIMIT)
|
||||
return ..()
|
||||
|
||||
/datum/wires/particle_acc/control_box/GetWireName(index)
|
||||
switch(index)
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
return "Power Toggle"
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
return "Strength"
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
return "Interface"
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
return "Maximum Power"
|
||||
|
||||
/datum/wires/particle_acc/control_box/CanUse(mob/living/L)
|
||||
/datum/wires/particle_acc/control_box/interactable(mob/user)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
if(C.construction_state == 2)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/particle_acc/control_box/UpdatePulsed(index)
|
||||
/datum/wires/particle_acc/control_box/on_pulse(wire)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(index)
|
||||
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
switch(wire)
|
||||
if(WIRE_PARTICLE_POWER)
|
||||
C.toggle_power()
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
if(WIRE_PARTICLE_STRENGTH)
|
||||
C.add_strength()
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
if(WIRE_PARTICLE_INTERFACE)
|
||||
C.interface_control = !C.interface_control
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
if(WIRE_PARTICLE_POWER_LIMIT)
|
||||
C.visible_message("[bicon(C)]<b>[C]</b> makes a large whirring noise.")
|
||||
..()
|
||||
|
||||
/datum/wires/particle_acc/control_box/UpdateCut(index, mended)
|
||||
/datum/wires/particle_acc/control_box/on_cut(wire, mend)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(index)
|
||||
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
if(C.active == !mended)
|
||||
switch(wire)
|
||||
if(WIRE_PARTICLE_POWER)
|
||||
if(C.active == !mend)
|
||||
C.toggle_power()
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
|
||||
for(var/i = 1; i < 3; i++)
|
||||
if(WIRE_PARTICLE_STRENGTH)
|
||||
for(var/i in 1 to 2)
|
||||
C.remove_strength()
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
C.interface_control = mended
|
||||
if(WIRE_PARTICLE_INTERFACE)
|
||||
C.interface_control = mend
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
C.strength_upper_limit = (mended ? 2 : 3)
|
||||
if(WIRE_PARTICLE_POWER_LIMIT)
|
||||
C.strength_upper_limit = (mend ? 2 : 3)
|
||||
if(C.strength_upper_limit < C.strength)
|
||||
C.remove_strength()
|
||||
..()
|
||||
|
||||
+27
-35
@@ -1,52 +1,44 @@
|
||||
/datum/wires/radio
|
||||
holder_type = /obj/item/radio
|
||||
wire_count = 3
|
||||
proper_name = "Radio"
|
||||
window_x = 330
|
||||
window_y = 37
|
||||
|
||||
#define RADIO_WIRE_SIGNAL 1
|
||||
#define RADIO_WIRE_RECEIVE 2
|
||||
#define RADIO_WIRE_TRANSMIT 4
|
||||
/datum/wires/radio/New(atom/_holder)
|
||||
wires = list(WIRE_RADIO_SIGNAL, WIRE_RADIO_RECEIVER, WIRE_RADIO_TRANSMIT)
|
||||
return ..()
|
||||
|
||||
/datum/wires/radio/GetWireName(index)
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
return "Signal"
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
return "Receiver"
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
return "Transmitter"
|
||||
|
||||
/datum/wires/radio/CanUse(mob/living/L)
|
||||
/datum/wires/radio/interactable(mob/user)
|
||||
var/obj/item/radio/R = holder
|
||||
if(R.b_stat)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/radio/UpdatePulsed(index)
|
||||
/datum/wires/radio/on_pulse(wire)
|
||||
var/obj/item/radio/R = holder
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
R.listening = !R.listening && !IsIndexCut(RADIO_WIRE_RECEIVE)
|
||||
R.broadcasting = R.listening && !IsIndexCut(RADIO_WIRE_TRANSMIT)
|
||||
switch(wire)
|
||||
if(WIRE_RADIO_SIGNAL)
|
||||
R.listening = !R.listening && !is_cut(WIRE_RADIO_RECEIVER)
|
||||
R.broadcasting = R.listening && !is_cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
R.listening = !R.listening && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_RECEIVER)
|
||||
R.listening = !R.listening && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
R.broadcasting = !R.broadcasting && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_TRANSMIT)
|
||||
R.broadcasting = !R.broadcasting && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
..()
|
||||
|
||||
/datum/wires/radio/UpdateCut(index, mended)
|
||||
/datum/wires/radio/on_cut(wire, mend)
|
||||
var/obj/item/radio/R = holder
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
R.listening = mended && !IsIndexCut(RADIO_WIRE_RECEIVE)
|
||||
R.broadcasting = mended && !IsIndexCut(RADIO_WIRE_TRANSMIT)
|
||||
switch(wire)
|
||||
if(WIRE_RADIO_SIGNAL)
|
||||
R.listening = mend && !is_cut(WIRE_RADIO_RECEIVER)
|
||||
R.broadcasting = mend && !is_cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
R.listening = mended && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_RECEIVER)
|
||||
R.listening = mend && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
R.broadcasting = mended && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_TRANSMIT)
|
||||
R.broadcasting = mend && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
..()
|
||||
|
||||
+29
-64
@@ -1,32 +1,14 @@
|
||||
/datum/wires/robot
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
holder_type = /mob/living/silicon/robot
|
||||
wire_count = 5
|
||||
window_x = 340
|
||||
window_y = 106
|
||||
proper_name = "Cyborg"
|
||||
|
||||
// /vg/ ordering
|
||||
|
||||
#define BORG_WIRE_MAIN_POWER 1 // The power wires do nothing whyyyyyyyyyyyyy
|
||||
#define BORG_WIRE_LOCKED_DOWN 2
|
||||
#define BORG_WIRE_CAMERA 4
|
||||
#define BORG_WIRE_AI_CONTROL 8 // Not used on MoMMIs
|
||||
#define BORG_WIRE_LAWCHECK 16 // Not used on MoMMIs
|
||||
|
||||
/datum/wires/robot/GetWireName(index)
|
||||
switch(index)
|
||||
if(BORG_WIRE_MAIN_POWER)
|
||||
return "Main Power"
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
return "Lockdown"
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
return "Camera"
|
||||
|
||||
if(BORG_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(BORG_WIRE_LAWCHECK)
|
||||
return "Law Check"
|
||||
/datum/wires/robot/New(atom/_holder)
|
||||
wires = list(WIRE_AI_CONTROL, WIRE_BORG_CAMERA, WIRE_BORG_LAWCHECK, WIRE_BORG_LOCKED)
|
||||
return ..()
|
||||
|
||||
/datum/wires/robot/get_status()
|
||||
. = ..()
|
||||
@@ -36,70 +18,53 @@
|
||||
. += "The Camera light is [(R.camera && R.camera.status == 1) ? "on" : "off"]."
|
||||
. += "The lockdown light is [R.lockcharge ? "on" : "off"]."
|
||||
|
||||
/datum/wires/robot/UpdateCut(index, mended)
|
||||
|
||||
/datum/wires/robot/on_cut(wire, mend)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(index)
|
||||
if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI
|
||||
if(!mended)
|
||||
if(R.lawupdate == 1)
|
||||
switch(wire)
|
||||
if(WIRE_BORG_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI
|
||||
if(!mend)
|
||||
if(R.lawupdate)
|
||||
to_chat(R, "LawSync protocol engaged.")
|
||||
R.lawsync()
|
||||
R.show_laws()
|
||||
else
|
||||
if(R.lawupdate == 0 && !R.emagged)
|
||||
R.lawupdate = 1
|
||||
if(!R.lawupdate && !R.emagged)
|
||||
R.lawupdate = TRUE
|
||||
|
||||
if(BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control
|
||||
if(!mended)
|
||||
if(WIRE_AI_CONTROL) //Cut the AI wire to reset AI control
|
||||
if(!mend)
|
||||
if(R.connected_ai)
|
||||
R.disconnect_from_ai()
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if(WIRE_BORG_CAMERA)
|
||||
if(!isnull(R.camera) && !R.scrambledcodes)
|
||||
R.camera.status = mended
|
||||
R.camera.status = mend
|
||||
R.camera.toggle_cam(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
|
||||
|
||||
if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh
|
||||
if(R.lawupdate)
|
||||
R.lawsync()
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
R.SetLockdown(!mended)
|
||||
if(WIRE_BORG_LOCKED)
|
||||
R.SetLockdown(!mend)
|
||||
..()
|
||||
|
||||
|
||||
/datum/wires/robot/UpdatePulsed(index)
|
||||
|
||||
/datum/wires/robot/on_pulse(wire)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(index)
|
||||
if(BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI
|
||||
switch(wire)
|
||||
if(WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI
|
||||
if(!R.emagged)
|
||||
R.connect_to_ai(select_active_ai())
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if(WIRE_BORG_CAMERA)
|
||||
if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes)
|
||||
R.camera.toggle_cam(usr, 0) // Kick anyone watching the Cyborg's camera, doesn't display you disconnecting the camera.
|
||||
R.visible_message("[R]'s camera lense focuses loudly.")
|
||||
to_chat(R, "Your camera lense focuses loudly.")
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
if(WIRE_BORG_LOCKED)
|
||||
R.SetLockdown(!R.lockcharge) // Toggle
|
||||
..()
|
||||
|
||||
/datum/wires/robot/CanUse(mob/living/L)
|
||||
/datum/wires/robot/interactable(mob/user)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
if(R.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/robot/proc/IsCameraCut()
|
||||
return wires_status & BORG_WIRE_CAMERA
|
||||
|
||||
/datum/wires/robot/proc/LockedCut()
|
||||
return wires_status & BORG_WIRE_LOCKED_DOWN
|
||||
|
||||
/datum/wires/robot/proc/CanLawCheck()
|
||||
return wires_status & BORG_WIRE_LAWCHECK
|
||||
|
||||
/datum/wires/robot/proc/AIHasControl()
|
||||
return wires_status & BORG_WIRE_AI_CONTROL
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
/datum/wires/smartfridge
|
||||
holder_type = /obj/machinery/smartfridge
|
||||
wire_count = 3
|
||||
proper_name = "Smartfridge"
|
||||
window_x = 340
|
||||
window_y = 103
|
||||
|
||||
/datum/wires/smartfridge/New(atom/_holder)
|
||||
wires = list(WIRE_ELECTRIFY, WIRE_IDSCAN, WIRE_THROW_ITEM)
|
||||
return ..()
|
||||
|
||||
/datum/wires/smartfridge/secure
|
||||
random = 1
|
||||
wire_count = 4
|
||||
randomize = TRUE
|
||||
wire_count = 4 // 3 actual, 1 dud.
|
||||
window_y = 97
|
||||
|
||||
#define SMARTFRIDGE_WIRE_ELECTRIFY 1
|
||||
#define SMARTFRIDGE_WIRE_THROW 2
|
||||
#define SMARTFRIDGE_WIRE_IDSCAN 4
|
||||
|
||||
/datum/wires/smartfridge/GetWireName(index)
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
return "Item Throw"
|
||||
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
/datum/wires/smartfridge/CanUse(mob/living/L)
|
||||
/datum/wires/smartfridge/interactable(mob/user)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
if(!issilicon(L))
|
||||
if(S.seconds_electrified)
|
||||
if(S.shock(L, 100))
|
||||
return 0
|
||||
if(iscarbon(user) && S.Adjacent(user) && S.seconds_electrified && S.shock(user, 100))
|
||||
return FALSE
|
||||
if(S.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/smartfridge/get_status()
|
||||
. = ..()
|
||||
@@ -38,27 +29,27 @@
|
||||
. += "The red light is [S.shoot_inventory ? "off" : "blinking"]."
|
||||
. += "A [S.scan_id ? "purple" : "yellow"] light is on."
|
||||
|
||||
/datum/wires/smartfridge/UpdatePulsed(index)
|
||||
/datum/wires/smartfridge/on_pulse(wire)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
S.shoot_inventory = !S.shoot_inventory
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
if(WIRE_ELECTRIFY)
|
||||
S.seconds_electrified = 30
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
if(WIRE_IDSCAN)
|
||||
S.scan_id = !S.scan_id
|
||||
..()
|
||||
|
||||
/datum/wires/smartfridge/UpdateCut(index, mended)
|
||||
/datum/wires/smartfridge/on_cut(wire, mend)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
S.shoot_inventory = !mended
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
S.shoot_inventory = !mend
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(mend)
|
||||
S.seconds_electrified = 0
|
||||
else
|
||||
S.seconds_electrified = -1
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
S.scan_id = 1
|
||||
if(WIRE_IDSCAN)
|
||||
S.scan_id = TRUE
|
||||
..()
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
/datum/wires/suitstorage
|
||||
holder_type = /obj/machinery/suit_storage_unit
|
||||
wire_count = 8
|
||||
proper_name = "Suit storage unit"
|
||||
window_x = 350
|
||||
window_y = 85
|
||||
|
||||
#define SSU_WIRE_ID 1
|
||||
#define SSU_WIRE_SHOCK 2
|
||||
#define SSU_WIRE_SAFETY 4
|
||||
#define SSU_WIRE_UV 8
|
||||
|
||||
|
||||
/datum/wires/suitstorage/GetWireName(index)
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
return "ID lock"
|
||||
if(SSU_WIRE_SHOCK)
|
||||
return "Shock wire"
|
||||
if(SSU_WIRE_SAFETY)
|
||||
return "Safety wire"
|
||||
if(SSU_WIRE_UV)
|
||||
return "UV wire"
|
||||
|
||||
/datum/wires/suitstorage/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SSU_UV)
|
||||
return ..()
|
||||
|
||||
/datum/wires/suitstorage/get_status()
|
||||
. = ..()
|
||||
@@ -28,42 +17,48 @@
|
||||
. += "The green light is [A.shocked ? "on" : "off"]."
|
||||
. += "The UV display shows [A.uv_super ? "15 nm" : "185 nm"]."
|
||||
|
||||
datum/wires/suitstorage/CanUse()
|
||||
datum/wires/suitstorage/interactable(mob/user)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.shocked)
|
||||
return A.shock(user, 100)
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/suitstorage/UpdateCut(index, mended)
|
||||
/datum/wires/suitstorage/on_cut(wire, mend)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
A.secure = mended
|
||||
if(SSU_WIRE_SAFETY)
|
||||
A.safeties = mended
|
||||
if(SSU_WIRE_SHOCK)
|
||||
A.shocked = !mended
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.secure = mend
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safeties = mend
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !mend
|
||||
A.shock(usr, 50)
|
||||
if(SSU_WIRE_UV)
|
||||
A.uv_super = !mended
|
||||
|
||||
if(WIRE_SSU_UV)
|
||||
A.uv_super = !mend
|
||||
..()
|
||||
|
||||
datum/wires/suitstorage/UpdatePulsed(index)
|
||||
datum/wires/suitstorage/on_pulse(wire)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
if(IsIndexCut(index))
|
||||
if(is_cut(wire))
|
||||
return
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.secure = !A.secure
|
||||
if(SSU_WIRE_SAFETY)
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safeties = !A.safeties
|
||||
if(SSU_WIRE_SHOCK)
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !A.shocked
|
||||
if(A.shocked)
|
||||
A.shock(usr, 100)
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.shocked = FALSE
|
||||
if(SSU_WIRE_UV)
|
||||
addtimer(CALLBACK(A, /obj/machinery/suit_storage_unit/.proc/check_electrified_callback), 5 SECONDS)
|
||||
|
||||
if(WIRE_SSU_UV)
|
||||
A.uv_super = !A.uv_super
|
||||
..()
|
||||
|
||||
@@ -1,47 +1,31 @@
|
||||
/datum/wires/syndicatebomb
|
||||
random = TRUE
|
||||
randomize = TRUE
|
||||
holder_type = /obj/machinery/syndicatebomb
|
||||
wire_count = 5
|
||||
proper_name = "Syndicate bomb"
|
||||
window_x = 320
|
||||
window_y = 22
|
||||
|
||||
#define BOMB_WIRE_BOOM 1 // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut
|
||||
#define BOMB_WIRE_UNBOLT 2 // Unbolts the bomb if cut, hint on pulsed
|
||||
#define BOMB_WIRE_DELAY 4 // Raises the timer on pulse, does nothing on cut
|
||||
#define BOMB_WIRE_PROCEED 8 // Lowers the timer, explodes if cut while the bomb is active
|
||||
#define BOMB_WIRE_ACTIVATE 16 // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut
|
||||
/datum/wires/syndicatebomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_DELAY, WIRE_EXPLODE, WIRE_BOMB_UNBOLT,WIRE_BOMB_PROCEED, WIRE_BOMB_ACTIVATE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/syndicatebomb/GetWireName(index)
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
return "Explode"
|
||||
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
return "Unbolt"
|
||||
|
||||
if(BOMB_WIRE_DELAY)
|
||||
return "Delay"
|
||||
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
return "Proceed"
|
||||
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
return "Activate"
|
||||
|
||||
/datum/wires/syndicatebomb/CanUse(mob/living/L)
|
||||
/datum/wires/syndicatebomb/interactable(mob/user)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
if(P.open_panel)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/syndicatebomb/UpdatePulsed(index)
|
||||
/datum/wires/syndicatebomb/on_pulse(wire)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
if(WIRE_BOMB_UNBOLT)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The bolts spin in place for a moment.</span>")
|
||||
if(BOMB_WIRE_DELAY)
|
||||
if(WIRE_BOMB_DELAY)
|
||||
if(B.delayedbig)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bomb has already been delayed.</span>")
|
||||
else
|
||||
@@ -49,7 +33,7 @@
|
||||
playsound(B, 'sound/machines/chime.ogg', 30, 1)
|
||||
B.detonation_timer += 300
|
||||
B.delayedbig = TRUE
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
if(WIRE_BOMB_PROCEED)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] The bomb buzzes ominously!</span>")
|
||||
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
|
||||
var/seconds = B.seconds_remaining()
|
||||
@@ -59,7 +43,7 @@
|
||||
B.detonation_timer -= 100
|
||||
else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy.
|
||||
B.detonation_timer = world.time + 100
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
if(WIRE_BOMB_ACTIVATE)
|
||||
if(!B.active && !B.defused)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] You hear the bomb start ticking!</span>")
|
||||
B.activate()
|
||||
@@ -72,11 +56,11 @@
|
||||
B.delayedlittle = TRUE
|
||||
..()
|
||||
|
||||
/datum/wires/syndicatebomb/UpdateCut(index, mended)
|
||||
/datum/wires/syndicatebomb/on_cut(wire, mend)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
if(mended)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(mend)
|
||||
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
|
||||
else
|
||||
if(B.active)
|
||||
@@ -84,17 +68,17 @@
|
||||
B.explode_now = TRUE
|
||||
else
|
||||
B.defused = TRUE
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
if(!mended && B.anchored)
|
||||
if(WIRE_BOMB_UNBOLT)
|
||||
if(!mend && B.anchored)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bolts lift out of the ground!</span>")
|
||||
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
|
||||
B.anchored = FALSE
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
if(!mended && B.active)
|
||||
if(WIRE_BOMB_PROCEED)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
if(!mended && B.active)
|
||||
if(WIRE_BOMB_ACTIVATE)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The timer stops! The bomb has been defused!</span>")
|
||||
B.defused = TRUE
|
||||
B.update_icon()
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/datum/wires/tesla_coil
|
||||
wire_count = 1
|
||||
holder_type = /obj/machinery/power/tesla_coil
|
||||
proper_name = "Tesla coil"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
#define TESLACOIL_WIRE_ZAP 1
|
||||
/datum/wires/tesla_coil/New(atom/_holder)
|
||||
wires = list(WIRE_TESLACOIL_ZAP)
|
||||
return ..()
|
||||
|
||||
/datum/wires/tesla_coil/GetWireName(index)
|
||||
switch(index)
|
||||
if(TESLACOIL_WIRE_ZAP)
|
||||
return "Zap"
|
||||
|
||||
/datum/wires/tesla_coil/CanUse(mob/living/L)
|
||||
/datum/wires/tesla_coil/interactable(mob/user)
|
||||
var/obj/machinery/power/tesla_coil/T = holder
|
||||
if(T && T.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/tesla_coil/UpdatePulsed(index)
|
||||
/datum/wires/tesla_coil/on_pulse(wire)
|
||||
var/obj/machinery/power/tesla_coil/T = holder
|
||||
switch(index)
|
||||
if(TESLACOIL_WIRE_ZAP)
|
||||
switch(wire)
|
||||
if(WIRE_TESLACOIL_ZAP)
|
||||
T.zap()
|
||||
..()
|
||||
|
||||
@@ -1,35 +1,21 @@
|
||||
/datum/wires/vending
|
||||
holder_type = /obj/machinery/vending
|
||||
wire_count = 4
|
||||
window_y = 112
|
||||
window_x = 350
|
||||
proper_name = "Vending machine"
|
||||
|
||||
#define VENDING_WIRE_THROW 1
|
||||
#define VENDING_WIRE_CONTRABAND 2
|
||||
#define VENDING_WIRE_ELECTRIFY 4
|
||||
#define VENDING_WIRE_IDSCAN 8
|
||||
/datum/wires/vending/New(atom/_holder)
|
||||
wires = list(WIRE_THROW_ITEM, WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_CONTRABAND)
|
||||
return ..()
|
||||
|
||||
/datum/wires/vending/GetWireName(index)
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
return "Item Throw"
|
||||
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
return "Contraband"
|
||||
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
/datum/wires/vending/CanUse(mob/living/L)
|
||||
/datum/wires/vending/interactable(mob/user)
|
||||
var/obj/machinery/vending/V = holder
|
||||
if(!istype(L, /mob/living/silicon))
|
||||
if(V.seconds_electrified)
|
||||
if(V.shock(L, 100))
|
||||
return 0
|
||||
if(!istype(user, /mob/living/silicon) && V.seconds_electrified && V.shock(user, 100))
|
||||
return FALSE
|
||||
if(V.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/vending/get_status()
|
||||
. = ..()
|
||||
@@ -39,31 +25,31 @@
|
||||
. += "The green light is [V.extended_inventory ? "on" : "off"]."
|
||||
. += "A [V.scan_id ? "purple" : "yellow"] light is on."
|
||||
|
||||
/datum/wires/vending/UpdatePulsed(index)
|
||||
/datum/wires/vending/on_pulse(wire)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
V.shoot_inventory = !V.shoot_inventory
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = !V.extended_inventory
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
if(WIRE_ELECTRIFY)
|
||||
V.seconds_electrified = 30
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = !V.scan_id
|
||||
..()
|
||||
|
||||
/datum/wires/vending/UpdateCut(index, mended)
|
||||
/datum/wires/vending/on_cut(wire, mend)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
V.shoot_inventory = !mended
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
V.shoot_inventory = !mend
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = FALSE
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(mend)
|
||||
V.seconds_electrified = 0
|
||||
else
|
||||
V.seconds_electrified = -1
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
V.scan_id = 1
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = TRUE
|
||||
..()
|
||||
|
||||
+395
-270
@@ -1,331 +1,456 @@
|
||||
// Wire datums. Created by Giacomand.
|
||||
// Was created to replace a horrible case of copy and pasted code with no care for maintability.
|
||||
// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires
|
||||
// Protolathe wires, APC wires and Camera wires!
|
||||
|
||||
#define MAX_FLAG 65535
|
||||
|
||||
GLOBAL_LIST_EMPTY(same_wires)
|
||||
// 12 colours, if you're adding more than 12 wires then add more colours here
|
||||
GLOBAL_LIST_INIT(wireColours, list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink"))
|
||||
|
||||
/datum/wires
|
||||
/// TRUE if the wires will be different every time a new wire datum is created.
|
||||
var/randomize = FALSE
|
||||
/// The atom the wires belong too. For example: an airlock.
|
||||
var/atom/holder
|
||||
/// The holder type; used to make sure that the holder is the correct type.
|
||||
var/holder_type
|
||||
/// The display name for the TGUI window. For example, given the var is "APC"...
|
||||
/// When the TGUI window is opened, "wires" will be appended to it's title, and it would become "APC wires".
|
||||
var/proper_name = "Unknown"
|
||||
/// The total number of wires that our holder atom has.
|
||||
var/wire_count = NONE
|
||||
/// A list of all wires. For a list of valid wires defines that can go here, see `code/__DEFINES/wires.dm`
|
||||
var/list/wires
|
||||
/// A list of all cut wires. The same values that can go into `wires` will get added and removed from this list.
|
||||
var/list/cut_wires
|
||||
/// An associative list with the wire color as the key, and the wire define as the value.
|
||||
var/list/colors
|
||||
/// An associative list of signalers attached to the wires. The wire color is the key, and the signaler object reference is the value.
|
||||
var/list/assemblies
|
||||
/// The width of the wire TGUI window.
|
||||
var/window_x = 300
|
||||
/// The height of the wire TGUI window. Will get longer as needed, based on the `wire_count`.
|
||||
var/window_y = 100
|
||||
|
||||
var/random = 0 // Will the wires be different for every single instance.
|
||||
var/atom/holder = null // The holder
|
||||
var/holder_type = null // The holder type; used to make sure that the holder is the correct type.
|
||||
var/wire_count = 0 // Max is 16
|
||||
var/wires_status = 0 // BITFLAG OF WIRES
|
||||
|
||||
var/list/wires = list()
|
||||
var/list/signallers = list()
|
||||
|
||||
var/table_options = " align='center'"
|
||||
var/row_options1 = " width='80px'"
|
||||
var/row_options2 = " width='260px'"
|
||||
var/window_x = 370
|
||||
var/window_y = 470
|
||||
|
||||
/datum/wires/New(atom/holder)
|
||||
/datum/wires/New(atom/_holder)
|
||||
..()
|
||||
src.holder = holder
|
||||
if(!istype(holder, holder_type))
|
||||
if(!istype(_holder, holder_type))
|
||||
CRASH("Our holder is null/the wrong type!")
|
||||
|
||||
// Generate new wires
|
||||
if(random)
|
||||
GenerateWires()
|
||||
// Get the same wires
|
||||
holder = _holder
|
||||
cut_wires = list()
|
||||
colors = list()
|
||||
assemblies = list()
|
||||
|
||||
// Add in the appropriate amount of dud wires.
|
||||
var/wire_len = length(wires)
|
||||
if(wire_len < wire_count) // If the amount of "real" wires is less than the total we're suppose to have...
|
||||
add_duds(wire_count - wire_len) // Add in the appropriate amount of duds to reach `wire_count`.
|
||||
|
||||
// If the randomize is true, we need to generate a new set of wires and ignore any wire color directories.
|
||||
if(randomize)
|
||||
randomize()
|
||||
return
|
||||
|
||||
if(!GLOB.wire_color_directory[holder_type])
|
||||
randomize()
|
||||
GLOB.wire_color_directory[holder_type] = colors
|
||||
else
|
||||
// We don't have any wires to copy yet, generate some and then copy it.
|
||||
if(!GLOB.same_wires[holder_type])
|
||||
GenerateWires()
|
||||
GLOB.same_wires[holder_type] = src.wires.Copy()
|
||||
else
|
||||
var/list/wires = GLOB.same_wires[holder_type]
|
||||
src.wires = wires // Reference the wires list.
|
||||
colors = GLOB.wire_color_directory[holder_type]
|
||||
|
||||
/datum/wires/Destroy()
|
||||
holder = null
|
||||
for(var/color in colors)
|
||||
detach_assembly(color)
|
||||
return ..()
|
||||
|
||||
/datum/wires/proc/GenerateWires()
|
||||
var/list/colours_to_pick = GLOB.wireColours.Copy() // Get a copy, not a reference.
|
||||
var/list/indexes_to_pick = list()
|
||||
//Generate our indexes
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
indexes_to_pick += i
|
||||
colours_to_pick.len = wire_count // Downsize it to our specifications.
|
||||
/**
|
||||
* Randomly generates a new set of wires. and corresponding colors from the given pool. Assigns the information as an associative list, to `colors`.
|
||||
*
|
||||
* In the `colors` list, the name of the color is the key, and the wire is the value.
|
||||
* For example: `colors["red"] = WIRE_ELECTRIFY`. This will look like `list("red" = WIRE_ELECTRIFY)` internally.
|
||||
*/
|
||||
datum/wires/proc/randomize()
|
||||
var/static/list/possible_colors = list("red", "blue", "green", "silver", "orange", "brown", "gold", "white", "cyan", "magenta", "purple", "pink")
|
||||
var/list/my_possible_colors = possible_colors.Copy()
|
||||
|
||||
while(colours_to_pick.len && indexes_to_pick.len)
|
||||
// Pick and remove a colour
|
||||
var/colour = pick_n_take(colours_to_pick)
|
||||
|
||||
// Pick and remove an index
|
||||
var/index = pick_n_take(indexes_to_pick)
|
||||
|
||||
src.wires[colour] = index
|
||||
//wires = shuffle(wires)
|
||||
|
||||
/datum/wires/proc/get_status()
|
||||
return list()
|
||||
for(var/wire in shuffle(wires))
|
||||
colors[pick_n_take(my_possible_colors)] = wire
|
||||
|
||||
/**
|
||||
* Proc called when the user attempts to interact with wires UI.
|
||||
*
|
||||
* Checks if the user exists, is a mob, the wires are attached to something (`holder`) and makes sure `interactable(user)` returns TRUE.
|
||||
* If all the checks succeed, open the TGUI interface for the user.
|
||||
*
|
||||
* Arugments:
|
||||
* * user - the mob trying to interact with the wires.
|
||||
*/
|
||||
/datum/wires/proc/Interact(mob/user)
|
||||
if(user && istype(user) && holder && CanUse(user))
|
||||
ui_interact(user)
|
||||
if(user && istype(user) && holder && interactable(user))
|
||||
tgui_interact(user)
|
||||
|
||||
/datum/wires/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/**
|
||||
* Base proc, intended to be overriden. Wire datum specific checks you want to run before the TGUI is shown to the user should go here.
|
||||
*/
|
||||
/datum/wires/proc/interactable(mob/user)
|
||||
return TRUE
|
||||
|
||||
/// Users will be interacting with our holder object and not the wire datum directly, therefore we need to return the holder.
|
||||
/datum/wires/tgui_host()
|
||||
return holder
|
||||
|
||||
/datum/wires/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "wires.tmpl", holder.name, window_x, window_y)
|
||||
ui = new(user, src, ui_key, "Wires", "[proper_name] wires", window_x, window_y + wire_count * 30, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/wires/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.physical_state)
|
||||
var/data[0]
|
||||
var/list/replace_colours = null
|
||||
/datum/wires/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/replace_colors
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(eyes && (COLOURBLIND in H.mutations))
|
||||
replace_colours = eyes.replace_colours
|
||||
if(eyes && (COLOURBLIND in H.mutations)) // Check if the human has colorblindness.
|
||||
replace_colors = eyes.replace_colours // Get the colorblind replacement colors list.
|
||||
|
||||
var/list/wires_list = list()
|
||||
|
||||
var/list/W[0]
|
||||
for(var/colour in wires)
|
||||
var/new_colour = colour
|
||||
var/colour_name = colour
|
||||
if(colour in replace_colours)
|
||||
new_colour = replace_colours[colour]
|
||||
if(new_colour in LIST_REPLACE_RENAME)
|
||||
colour_name = LIST_REPLACE_RENAME[new_colour]
|
||||
for(var/color in colors)
|
||||
var/replaced_color = color
|
||||
var/color_name = color
|
||||
|
||||
if(color in replace_colors) // If this color is one that needs to be replaced using the colorblindness list.
|
||||
replaced_color = replace_colors[color]
|
||||
if(replaced_color in LIST_COLOR_RENAME) // If its an ugly written color name like "darkolivegreen", rename it to something like "dark green".
|
||||
color_name = LIST_COLOR_RENAME[replaced_color]
|
||||
else
|
||||
colour_name = new_colour
|
||||
else
|
||||
new_colour = colour
|
||||
colour_name = new_colour
|
||||
W[++W.len] = list("colour_name" = capitalize(colour_name), "seen_colour" = capitalize(new_colour),"colour" = capitalize(colour), "cut" = IsColourCut(colour), "index" = can_see_wire_index(user) ? GetWireName(GetIndex(colour)) : null, "attached" = IsAttached(colour))
|
||||
color_name = replaced_color // Else just keep the normal color name
|
||||
|
||||
if(W.len > 0)
|
||||
data["wires"] = W
|
||||
wires_list += list(list(
|
||||
"seen_color" = replaced_color, // The color of the wire that the mob will see. This will be the same as `color` if the user is NOT colorblind.
|
||||
"color_name" = color_name, // The wire's name. This will be the same as `color` if the user is NOT colorblind.
|
||||
"color" = color, // The "real" color of the wire. No replacements.
|
||||
"wire" = can_see_wire_info(user) && !is_dud_color(color) ? get_wire(color) : null, // Wire define information like "Contraband" or "Door Bolts".
|
||||
"cut" = is_color_cut(color), // Whether the wire is cut or not. Used to display "cut" or "mend".
|
||||
"attached" = is_attached(color) // Whether or not a signaler is attached to this wire.
|
||||
))
|
||||
data["wires"] = wires_list
|
||||
|
||||
// Get the information shown at the bottom of wire TGUI window, such as "The red light is blinking", etc.
|
||||
// If the user is colorblind, we need to replace these colors as well.
|
||||
var/list/status = get_status()
|
||||
if(replace_colours)
|
||||
var/i
|
||||
for(i=1, i<=status.len, i++)
|
||||
for(var/colour in replace_colours)
|
||||
var/new_colour = replace_colours[colour]
|
||||
if(new_colour in LIST_REPLACE_RENAME)
|
||||
new_colour = LIST_REPLACE_RENAME[new_colour]
|
||||
if(findtext(status[i],colour))
|
||||
status[i] = replacetext(status[i],colour,new_colour)
|
||||
break
|
||||
data["status_len"] = status.len
|
||||
data["status"] = status
|
||||
|
||||
if(replace_colors)
|
||||
var/i
|
||||
for(i in 1 to length(status))
|
||||
for(var/color in replace_colors)
|
||||
var/new_color = replace_colors[color]
|
||||
if(new_color in LIST_COLOR_RENAME)
|
||||
new_color = LIST_COLOR_RENAME[new_color]
|
||||
if(findtext(status[i], color))
|
||||
status[i] = replacetext(status[i], color, new_color)
|
||||
break
|
||||
|
||||
data["status"] = status
|
||||
return data
|
||||
|
||||
/datum/wires/nano_host()
|
||||
return holder
|
||||
/datum/wires/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
/datum/wires/proc/can_see_wire_index(mob/user)
|
||||
var/mob/user = usr
|
||||
if(!interactable(user))
|
||||
return
|
||||
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
var/color = lowertext(params["wire"])
|
||||
holder.add_hiddenprint(user)
|
||||
|
||||
switch(action)
|
||||
// Toggles the cut/mend status.
|
||||
if("cut")
|
||||
if(!istype(I, /obj/item/wirecutters) && !user.can_admin_interact())
|
||||
to_chat(user, "<span class='error'>You need wirecutters!</span>")
|
||||
return
|
||||
|
||||
if(istype(I))
|
||||
playsound(holder, I.usesound, 20, 1)
|
||||
cut_color(color)
|
||||
return TRUE
|
||||
|
||||
// Pulse a wire.
|
||||
if("pulse")
|
||||
if(!istype(I, /obj/item/multitool) && !user.can_admin_interact())
|
||||
to_chat(user, "<span class='error'>You need a multitool!</span>")
|
||||
return
|
||||
|
||||
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
||||
pulse_color(color)
|
||||
|
||||
// If they pulse the electrify wire, call interactable() and try to shock them.
|
||||
if(get_wire(color) == WIRE_ELECTRIFY)
|
||||
interactable(user)
|
||||
|
||||
return TRUE
|
||||
|
||||
// Attach a signaler to a wire.
|
||||
if("attach")
|
||||
if(is_attached(color))
|
||||
var/obj/item/O = detach_assembly(color)
|
||||
if(O)
|
||||
user.put_in_hands(O)
|
||||
return TRUE
|
||||
|
||||
if(!istype(I, /obj/item/assembly/signaler))
|
||||
to_chat(user, "<span class='error'>You need a remote signaller!</span>")
|
||||
return
|
||||
|
||||
if(user.drop_item())
|
||||
attach_assembly(color, I)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[user.get_active_hand()] is stuck to your hand!</span>")
|
||||
|
||||
/**
|
||||
* Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc.
|
||||
*
|
||||
* If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the mob who is interacting with the wires.
|
||||
*/
|
||||
/datum/wires/proc/can_see_wire_info(mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return TRUE
|
||||
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
||||
var/obj/item/multitool/M = user.get_active_hand()
|
||||
if(M.shows_wire_information)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/wires/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
var/mob/L = usr
|
||||
if(CanUse(L) && href_list["action"])
|
||||
var/obj/item/I = L.get_active_hand()
|
||||
var/colour = lowertext(href_list["wire"])
|
||||
holder.add_hiddenprint(L)
|
||||
switch(href_list["action"])
|
||||
if("cut") // Toggles the cut/mend status
|
||||
if(istype(I, /obj/item/wirecutters) || L.can_admin_interact())
|
||||
if(istype(I))
|
||||
playsound(holder, I.usesound, 20, 1)
|
||||
CutWireColour(colour)
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need wirecutters!</span>")
|
||||
if("pulse")
|
||||
if(istype(I, /obj/item/multitool) || L.can_admin_interact())
|
||||
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
||||
PulseColour(colour)
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need a multitool!</span>")
|
||||
if("attach")
|
||||
if(IsAttached(colour))
|
||||
var/obj/item/O = Detach(colour)
|
||||
if(O)
|
||||
L.put_in_hands(O)
|
||||
else
|
||||
if(istype(I, /obj/item/assembly/signaler))
|
||||
if(L.drop_item())
|
||||
Attach(colour, I)
|
||||
else
|
||||
to_chat(L, "<span class='warning'>[L.get_active_hand()] is stuck to your hand!</span>")
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need a remote signaller!</span>")
|
||||
/**
|
||||
* Base proc, intended to be overwritten. Put wire information you'll see at the botton of the TGUI window here, such as "The red light is blinking".
|
||||
*/
|
||||
/datum/wires/proc/get_status()
|
||||
return list()
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
return 1
|
||||
/**
|
||||
* Clears the `colors` list, and randomizes it to a new set of color-to-wire relations.
|
||||
*/
|
||||
/datum/wires/proc/shuffle_wires()
|
||||
colors.Cut()
|
||||
randomize()
|
||||
|
||||
//
|
||||
// Overridable Procs
|
||||
//
|
||||
/**
|
||||
* Repairs all cut wires.
|
||||
*/
|
||||
/datum/wires/proc/repair()
|
||||
cut_wires.Cut()
|
||||
|
||||
// Called when wires cut/mended.
|
||||
/datum/wires/proc/UpdateCut(index, mended)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
/**
|
||||
* Adds in dud wires, which do nothing when cut/pulsed.
|
||||
*
|
||||
* Arguments:
|
||||
* * duds - the amount of dud wires to generate.
|
||||
*/
|
||||
/datum/wires/proc/add_duds(duds)
|
||||
while(duds)
|
||||
var/dud = WIRE_DUD_PREFIX + "[--duds]"
|
||||
if(dud in wires)
|
||||
continue
|
||||
wires += dud
|
||||
|
||||
// Called when wire pulsed. Add code here.
|
||||
/datum/wires/proc/UpdatePulsed(index)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
/**
|
||||
* Determines if the passed in wire is a dud or not. Returns TRUE if the wire is a dud, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/is_dud(wire)
|
||||
return findtext(wire, WIRE_DUD_PREFIX, 1, length(WIRE_DUD_PREFIX) + 1)
|
||||
|
||||
/datum/wires/proc/CanUse(mob/L)
|
||||
return 1
|
||||
/**
|
||||
* Returns TRUE if the wire that corresponds to the passed in color is a dud. FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_dud_color(color)
|
||||
return is_dud(get_wire(color))
|
||||
|
||||
/datum/wires/CanUseTopic(mob/user, datum/topic_state/state)
|
||||
if(!holder || !CanUse(user))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
/**
|
||||
* Gets the wire associated with the color passed in.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/get_wire(color)
|
||||
return colors[color]
|
||||
|
||||
// Example of use:
|
||||
/*
|
||||
/**
|
||||
* Determines if the passed in wire is cut or not. Returns TRUE if it's cut, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/is_cut(wire)
|
||||
return (wire in cut_wires)
|
||||
|
||||
#define NAME_WIRE_BOLTED 1
|
||||
#define NAME_WIRE_SHOCKED 2
|
||||
#define NAME_WIRE_SAFETY 4
|
||||
#define NAME_WIRE_POWER 8
|
||||
/**
|
||||
* Determines if the wire associated with the passed in color, is cut or not. Returns TRUE if it's cut, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_color_cut(color)
|
||||
return is_cut(get_wire(color))
|
||||
|
||||
/datum/wires/door/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(NAME_WIRE_BOLTED)
|
||||
if(!mended)
|
||||
A.bolt()
|
||||
if(NAME_WIRE_SHOCKED)
|
||||
A.shock()
|
||||
if(NAME_WIRE_SAFETY)
|
||||
A.safety()
|
||||
/**
|
||||
* Determines if all of the wires are cut. Returns TRUE they're all cut, FALSE otherwise.
|
||||
*/
|
||||
/datum/wires/proc/is_all_cut()
|
||||
return (length(cut_wires) == length(wires))
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Helper Procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/PulseColour(colour)
|
||||
PulseIndex(GetIndex(colour))
|
||||
|
||||
/datum/wires/proc/PulseIndex(index)
|
||||
if(IsIndexCut(index))
|
||||
return
|
||||
UpdatePulsed(index)
|
||||
|
||||
/datum/wires/proc/GetIndex(colour)
|
||||
if(wires[colour])
|
||||
var/index = wires[colour]
|
||||
return index
|
||||
/**
|
||||
* Cut or mend a wire. Calls `on_cut()`.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/cut(wire)
|
||||
if(is_cut(wire))
|
||||
cut_wires -= wire
|
||||
on_cut(wire, mend = TRUE)
|
||||
else
|
||||
CRASH("[colour] is not a key in wires.")
|
||||
cut_wires += wire
|
||||
on_cut(wire, mend = FALSE)
|
||||
|
||||
/datum/wires/proc/GetWireName(index)
|
||||
/**
|
||||
* Cut the wire which corresponds with the passed in color.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/cut_color(color)
|
||||
cut(get_wire(color))
|
||||
|
||||
/**
|
||||
* Cuts a random wire.
|
||||
*/
|
||||
/datum/wires/proc/cut_random()
|
||||
cut(wires[rand(1, length(wires))])
|
||||
|
||||
/**
|
||||
* Cuts all wires.
|
||||
*/
|
||||
/datum/wires/proc/cut_all()
|
||||
for(var/wire in wires)
|
||||
cut(wire)
|
||||
|
||||
/**
|
||||
* Proc called when any wire is cut.
|
||||
*
|
||||
* Base proc, intended to be overriden.
|
||||
* Place an behavior you want to happen when certain wires are cut, into this proc.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'.
|
||||
* * mend - TRUE if we're mending the wire. FALSE if we're cutting.
|
||||
*/
|
||||
/datum/wires/proc/on_cut(wire, mend = FALSE)
|
||||
return
|
||||
|
||||
//
|
||||
// Is Index/Colour Cut procs
|
||||
//
|
||||
/**
|
||||
* Pulses the given wire. Calls `on_pulse()`.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/pulse(wire)
|
||||
if(is_cut(wire))
|
||||
return
|
||||
on_pulse(wire)
|
||||
|
||||
/datum/wires/proc/IsColourCut(colour)
|
||||
var/index = GetIndex(colour)
|
||||
return IsIndexCut(index)
|
||||
/**
|
||||
* Pulses the wire associated with the given color.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/pulse_color(color)
|
||||
pulse(get_wire(color))
|
||||
|
||||
/datum/wires/proc/IsIndexCut(index)
|
||||
return (index & wires_status)
|
||||
/**
|
||||
* Proc called when any wire is pulsed.
|
||||
*
|
||||
* Base proc, intended to be overriden.
|
||||
* Place behavior you want to happen when certain wires are pulsed, into this proc.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'.
|
||||
*/
|
||||
/datum/wires/proc/on_pulse(wire)
|
||||
return
|
||||
|
||||
//
|
||||
// Signaller Procs
|
||||
//
|
||||
/**
|
||||
* Proc called when an attached signaler receives a signal.
|
||||
*
|
||||
* Searches through the `assemblies` list for the wire that the signaler is attached to. Pulses the wire when it's found.
|
||||
*
|
||||
* Arugments:
|
||||
* * S - the attached signaler receiving the signal.
|
||||
*/
|
||||
/datum/wires/proc/pulse_assembly(obj/item/assembly/signaler/S)
|
||||
for(var/color in assemblies)
|
||||
if(S == assemblies[color])
|
||||
pulse_color(color)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/IsAttached(colour)
|
||||
if(signallers[colour])
|
||||
return 1
|
||||
return 0
|
||||
/**
|
||||
* Proc called when a mob tries to attach a signaler to a wire.
|
||||
*
|
||||
* Makes sure that `S` is actually a signaler and that something is not already attached to the wire.
|
||||
* Adds the signaler to the `assemblies` list as a value, with the `color` as a the key.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
* * S - the signaler that a mob is trying to attach.
|
||||
*/
|
||||
/datum/wires/proc/attach_assembly(color, obj/item/assembly/signaler/S)
|
||||
if(S && istype(S) && !is_attached(color))
|
||||
assemblies[color] = S
|
||||
S.forceMove(holder)
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/GetAttached(colour)
|
||||
if(signallers[colour])
|
||||
return signallers[colour]
|
||||
/**
|
||||
* Proc called when a mob tries to detach a signaler from a wire.
|
||||
*
|
||||
* First checks if there is a signaler on the wire. If so, removes the signaler, and clears it from `assemblies` list.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/detach_assembly(color)
|
||||
var/obj/item/assembly/signaler/S = get_attached(color)
|
||||
if(S && istype(S))
|
||||
assemblies -= color
|
||||
S.connected = null
|
||||
S.forceMove(holder.drop_location())
|
||||
return S
|
||||
|
||||
/**
|
||||
* Gets the signaler attached to the given wire color, if there is one.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/get_attached(color)
|
||||
if(assemblies[color])
|
||||
return assemblies[color]
|
||||
return null
|
||||
|
||||
/datum/wires/proc/Attach(colour, obj/item/assembly/signaler/S)
|
||||
if(colour && S)
|
||||
if(!IsAttached(colour))
|
||||
signallers[colour] = S
|
||||
S.loc = holder
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/Detach(colour)
|
||||
if(colour)
|
||||
var/obj/item/assembly/signaler/S = GetAttached(colour)
|
||||
if(S)
|
||||
signallers -= colour
|
||||
S.connected = null
|
||||
S.loc = holder.loc
|
||||
return S
|
||||
|
||||
|
||||
/datum/wires/proc/Pulse(obj/item/assembly/signaler/S)
|
||||
|
||||
for(var/colour in signallers)
|
||||
if(S == signallers[colour])
|
||||
PulseColour(colour)
|
||||
break
|
||||
|
||||
|
||||
//
|
||||
// Cut Wire Colour/Index procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/CutWireColour(colour)
|
||||
var/index = GetIndex(colour)
|
||||
CutWireIndex(index)
|
||||
|
||||
/datum/wires/proc/CutWireIndex(index)
|
||||
if(IsIndexCut(index))
|
||||
wires_status &= ~index
|
||||
UpdateCut(index, 1)
|
||||
else
|
||||
wires_status |= index
|
||||
UpdateCut(index, 0)
|
||||
|
||||
/datum/wires/proc/RandomCut()
|
||||
var/r = rand(1, wires.len)
|
||||
CutWireIndex(r)
|
||||
|
||||
/datum/wires/proc/CutAll()
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
CutWireIndex(i)
|
||||
|
||||
/datum/wires/proc/IsAllCut()
|
||||
if(wires_status == (1 << wire_count) - 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//
|
||||
//Shuffle and Mend
|
||||
//
|
||||
|
||||
/datum/wires/proc/Shuffle()
|
||||
wires_status = 0
|
||||
GenerateWires()
|
||||
/**
|
||||
* Checks if the given wire has a signaler on it.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_attached(color)
|
||||
if(assemblies[color])
|
||||
return TRUE
|
||||
|
||||
@@ -50,10 +50,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/space/atmosalert()
|
||||
return
|
||||
|
||||
/area/space/fire_alert()
|
||||
/area/space/firealert(obj/source)
|
||||
return
|
||||
|
||||
/area/space/fire_reset()
|
||||
/area/space/firereset(obj/source)
|
||||
return
|
||||
|
||||
/area/space/readyalert()
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
/area/ai_monitored
|
||||
name = "AI Monitored Area"
|
||||
var/obj/machinery/camera/motioncamera = null
|
||||
var/list/motioncameras = list()
|
||||
var/list/motionTargets = list()
|
||||
|
||||
|
||||
/area/ai_monitored/LateInitialize()
|
||||
/area/ai_monitored/Initialize(mapload)
|
||||
. = ..()
|
||||
// locate and store the motioncamera
|
||||
for(var/obj/machinery/camera/M in src)
|
||||
if(M.isMotion())
|
||||
motioncamera = M
|
||||
M.area_motion = src
|
||||
break
|
||||
if(mapload)
|
||||
for(var/obj/machinery/camera/M in src)
|
||||
if(M.isMotion())
|
||||
motioncameras.Add(M)
|
||||
M.set_area_motion(src)
|
||||
|
||||
/area/ai_monitored/Entered(atom/movable/O)
|
||||
..()
|
||||
if(ismob(O) && motioncamera)
|
||||
motioncamera.newTarget(O)
|
||||
if(ismob(O) && length(motioncameras))
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.newTarget(O)
|
||||
return
|
||||
|
||||
/area/ai_monitored/Exited(atom/movable/O)
|
||||
if(ismob(O) && motioncamera)
|
||||
motioncamera.lostTarget(O)
|
||||
..()
|
||||
if(ismob(O) && length(motioncameras))
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.lostTargetRef(O.UID())
|
||||
return
|
||||
|
||||
|
||||
|
||||
+195
-63
@@ -57,6 +57,11 @@
|
||||
|
||||
var/list/ambientsounds = GENERIC_SOUNDS
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
|
||||
var/fast_despawn = FALSE
|
||||
var/can_get_auto_cryod = TRUE
|
||||
var/hide_attacklogs = FALSE // For areas such as thunderdome, lavaland syndiebase, etc which generate a lot of spammy attacklogs. Reduces log priority.
|
||||
@@ -125,35 +130,6 @@
|
||||
cameras += C
|
||||
return cameras
|
||||
|
||||
|
||||
/area/proc/atmosalert(danger_level, var/alarm_source, var/force = FALSE)
|
||||
if(report_alerts)
|
||||
if(danger_level == ATMOS_ALARM_NONE)
|
||||
SSalarms.atmosphere_alarm.clearAlarm(src, alarm_source)
|
||||
else
|
||||
SSalarms.atmosphere_alarm.triggerAlarm(src, alarm_source, severity = danger_level)
|
||||
|
||||
//Check all the alarms before lowering atmosalm. Raising is perfectly fine. If force = 1 we don't care.
|
||||
for(var/obj/machinery/alarm/AA in src)
|
||||
if(!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level && !force)
|
||||
danger_level = max(danger_level, AA.danger_level)
|
||||
|
||||
if(danger_level != atmosalm)
|
||||
if(danger_level < ATMOS_ALARM_WARNING && atmosalm >= ATMOS_ALARM_WARNING)
|
||||
//closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise
|
||||
air_doors_open()
|
||||
else if(danger_level >= ATMOS_ALARM_DANGER && atmosalm < ATMOS_ALARM_DANGER)
|
||||
air_doors_close()
|
||||
|
||||
atmosalm = danger_level
|
||||
for(var/obj/machinery/alarm/AA in src)
|
||||
AA.update_icon()
|
||||
|
||||
GLOB.air_alarm_repository.update_cache(src)
|
||||
return 1
|
||||
GLOB.air_alarm_repository.update_cache(src)
|
||||
return 0
|
||||
|
||||
/area/proc/air_doors_close()
|
||||
if(!air_doors_activated)
|
||||
air_doors_activated = TRUE
|
||||
@@ -179,44 +155,151 @@
|
||||
D.open()
|
||||
|
||||
|
||||
/area/proc/fire_alert()
|
||||
if(!fire)
|
||||
fire = 1 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_close()
|
||||
/area/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/area/proc/fire_reset()
|
||||
if(fire)
|
||||
fire = 0 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_open()
|
||||
/**
|
||||
* Generate a power alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/poweralert(state, obj/source)
|
||||
if(state != poweralm)
|
||||
poweralm = state
|
||||
if(istype(source)) //Only report power alarms on the z-level where the source is located.
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
if(state)
|
||||
C.network -= "Power Alarms"
|
||||
else
|
||||
C.network |= "Power Alarms"
|
||||
|
||||
return
|
||||
if(state)
|
||||
SSalarm.cancelAlarm("Power", src, source)
|
||||
else
|
||||
SSalarm.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
/area/proc/burglaralert(var/obj/trigger)
|
||||
if(always_unpowered == 1) //no burglar alarms in space/asteroid
|
||||
/**
|
||||
* Generate an atmospheric alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/atmosalert(danger_level, obj/source)
|
||||
if(danger_level != atmosalm)
|
||||
if(danger_level == ATMOS_ALARM_DANGER)
|
||||
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network |= "Atmosphere Alarms"
|
||||
|
||||
|
||||
SSalarm.triggerAlarm("Atmosphere", src, cameras, source)
|
||||
|
||||
else if(atmosalm == ATMOS_ALARM_DANGER)
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network -= "Atmosphere Alarms"
|
||||
|
||||
SSalarm.cancelAlarm("Atmosphere", src, source)
|
||||
|
||||
atmosalm = danger_level
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Try to close all the firedoors in the area
|
||||
*/
|
||||
/area/proc/ModifyFiredoors(opening)
|
||||
if(firedoors)
|
||||
firedoors_last_closed_on = world.time
|
||||
for(var/FD in firedoors)
|
||||
var/obj/machinery/door/firedoor/D = FD
|
||||
var/cont = !D.welded
|
||||
if(cont && opening) //don't open if adjacent area is on fire
|
||||
for(var/I in D.affecting_areas)
|
||||
var/area/A = I
|
||||
if(A.fire)
|
||||
cont = FALSE
|
||||
break
|
||||
if(cont && D.is_operational())
|
||||
if(D.operating)
|
||||
D.nextstate = opening ? FD_OPEN : FD_CLOSED
|
||||
else if(!(D.density ^ opening))
|
||||
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
|
||||
|
||||
/**
|
||||
* Generate a firealarm alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*
|
||||
* Also starts the area processing on SSobj
|
||||
*/
|
||||
/area/proc/firealert(obj/source)
|
||||
if(always_unpowered) //no fire alarms in space/asteroid
|
||||
return
|
||||
|
||||
//Trigger alarm effect
|
||||
set_fire_alarm_effect()
|
||||
if(!fire)
|
||||
set_fire_alarm_effect()
|
||||
ModifyFiredoors(FALSE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
|
||||
//Lockdown airlocks
|
||||
for(var/obj/machinery/door/airlock/A in src)
|
||||
spawn(0)
|
||||
A.close()
|
||||
if(A.density)
|
||||
A.lock()
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network |= "Fire Alarms"
|
||||
|
||||
SSalarms.burglar_alarm.triggerAlarm(src, trigger)
|
||||
spawn(600)
|
||||
SSalarms.burglar_alarm.clearAlarm(src, trigger)
|
||||
SSalarm.triggerAlarm("Fire", src, cameras, source)
|
||||
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = 1
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* Reset the firealarm alert for this area
|
||||
*
|
||||
* resets the alert sent to all ai players, alert consoles, drones and alarm monitor programs
|
||||
* in the world
|
||||
*
|
||||
* Also cycles the icons of all firealarms and deregisters the area from processing on SSOBJ
|
||||
*/
|
||||
/area/proc/firereset(obj/source)
|
||||
if(fire)
|
||||
unset_fire_alarm_effects()
|
||||
ModifyFiredoors(TRUE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network -= "Fire Alarms"
|
||||
|
||||
SSalarm.cancelAlarm("Fire", src, source)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* If 100 ticks has elapsed, toggle all the firedoors closed again
|
||||
*/
|
||||
/area/process()
|
||||
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
|
||||
ModifyFiredoors(FALSE)
|
||||
|
||||
/**
|
||||
* Close and lock a door passed into this proc
|
||||
*
|
||||
* Does this need to exist on area? probably not
|
||||
*/
|
||||
/area/proc/close_and_lock_door(obj/machinery/door/DOOR)
|
||||
set waitfor = FALSE
|
||||
DOOR.close()
|
||||
if(DOOR.density)
|
||||
DOOR.lock()
|
||||
|
||||
/area/proc/readyalert()
|
||||
if(!eject)
|
||||
@@ -240,13 +323,62 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
updateicon()
|
||||
|
||||
/**
|
||||
* Raise a burglar alert for this area
|
||||
*
|
||||
* Close and locks all doors in the area and alerts silicon mobs of a break in
|
||||
*
|
||||
* Alarm auto resets after 600 ticks
|
||||
*/
|
||||
/area/proc/burglaralert(obj/trigger)
|
||||
if(always_unpowered) //no burglar alarms in space/asteroid
|
||||
return
|
||||
|
||||
//Trigger alarm effect
|
||||
set_fire_alarm_effect()
|
||||
//Lockdown airlocks
|
||||
for(var/obj/machinery/door/DOOR in src)
|
||||
close_and_lock_door(DOOR)
|
||||
|
||||
if(SSalarm.triggerAlarm("Burglar", src, cameras, trigger))
|
||||
//Cancel silicon alert after 1 minute
|
||||
addtimer(CALLBACK(SSalarm, /datum/controller/subsystem/alarm.proc/cancelAlarm, "Burglar", src, trigger), 600)
|
||||
|
||||
/**
|
||||
* Trigger the fire alarm visual affects in an area
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/**
|
||||
* unset the fire alarm visual affects in an area
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/unset_fire_alarm_effects()
|
||||
fire = FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/area/proc/updateicon()
|
||||
if((fire || eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc.
|
||||
if(fire && !eject && !party)
|
||||
if((eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc.
|
||||
if(!eject && !party)
|
||||
icon_state = "red"
|
||||
else if(!fire && eject && !party)
|
||||
else if(eject && !party)
|
||||
icon_state = "red"
|
||||
else if(party && !fire && !eject)
|
||||
else if(party && !eject)
|
||||
icon_state = "party"
|
||||
else
|
||||
icon_state = "blue-red"
|
||||
|
||||
+343
-403
@@ -7,6 +7,11 @@
|
||||
|
||||
#define NEGATE_MUTATION_THRESHOLD 30 // Occupants with over ## percent radiation threshold will not gain mutations
|
||||
|
||||
#define PAGE_UI "ui"
|
||||
#define PAGE_SE "se"
|
||||
#define PAGE_BUFFER "buffer"
|
||||
#define PAGE_REJUVENATORS "rejuvenators"
|
||||
|
||||
//list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0),
|
||||
/datum/dna2/record
|
||||
var/datum/dna/dna = null
|
||||
@@ -161,6 +166,7 @@
|
||||
occupant = usr
|
||||
icon_state = "scanner_occupied"
|
||||
add_fingerprint(usr)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/dna_scannernew/MouseDrop_T(atom/movable/O, mob/user)
|
||||
if(!istype(O))
|
||||
@@ -214,6 +220,7 @@
|
||||
return
|
||||
|
||||
beaker = I
|
||||
SStgui.update_uis(src)
|
||||
I.forceMove(src)
|
||||
user.visible_message("[user] adds \a [I] to \the [src]!", "You add \a [I] to \the [src]!")
|
||||
return
|
||||
@@ -260,6 +267,7 @@
|
||||
M.forceMove(src)
|
||||
occupant = M
|
||||
icon_state = "scanner_occupied"
|
||||
SStgui.update_uis(src)
|
||||
|
||||
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
|
||||
if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \
|
||||
@@ -281,6 +289,7 @@
|
||||
occupant.forceMove(loc)
|
||||
occupant = null
|
||||
icon_state = "scanner_open"
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/dna_scannernew/force_eject_occupant()
|
||||
go_out(null, TRUE)
|
||||
@@ -296,6 +305,7 @@
|
||||
occupant = null
|
||||
updateUsrDialog()
|
||||
update_icon()
|
||||
SStgui.update_uis(src)
|
||||
|
||||
// Checks if occupants can be irradiated/mutated - prevents exploits where wearing full rad protection would still let you gain mutations
|
||||
/obj/machinery/dna_scannernew/proc/radiation_check()
|
||||
@@ -333,12 +343,11 @@
|
||||
var/injector_ready = FALSE //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
|
||||
var/obj/machinery/dna_scannernew/connected = null
|
||||
var/obj/item/disk/data/disk = null
|
||||
var/selected_menu_key = null
|
||||
var/selected_menu_key = PAGE_UI
|
||||
anchored = TRUE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 400
|
||||
var/waiting_for_user_input = 0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/disk/data)) //INSERT SOME diskS
|
||||
@@ -347,7 +356,7 @@
|
||||
I.forceMove(src)
|
||||
disk = I
|
||||
to_chat(user, "You insert [I].")
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src()
|
||||
SStgui.update_uis(src)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
@@ -399,35 +408,18 @@
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/**
|
||||
* The ui_interact proc is used to open and update Nano UIs
|
||||
* If ui_interact is not used then the UI will not update correctly
|
||||
* ui_interact is currently defined for /atom/movable
|
||||
*
|
||||
* @param user /mob The mob who is interacting with this ui
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
||||
/obj/machinery/computer/scan_consolenew/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(user == connected.occupant)
|
||||
return
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "dna_modifier.tmpl", "DNA Modifier Console", 660, 700)
|
||||
// open the new ui window
|
||||
ui = new(user, src, ui_key, "DNAModifier", name, 660, 700, master_ui, state)
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/ui_data(mob/user, datum/topic_state/state)
|
||||
/obj/machinery/computer/scan_consolenew/tgui_data(mob/user)
|
||||
var/data[0]
|
||||
data["selectedMenuKey"] = selected_menu_key
|
||||
data["locked"] = connected.locked
|
||||
@@ -501,9 +493,12 @@
|
||||
for(var/datum/reagent/R in connected.beaker.reagents.reagent_list)
|
||||
data["beakerVolume"] += R.volume
|
||||
|
||||
// Transfer modal information if there is one
|
||||
data["modal"] = tgui_modal_data(src)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/Topic(href, href_list)
|
||||
/obj/machinery/computer/scan_consolenew/tgui_act(action, params)
|
||||
if(..())
|
||||
return FALSE // don't update uis
|
||||
if(!istype(usr.loc, /turf))
|
||||
@@ -512,405 +507,350 @@
|
||||
return FALSE // don't update uis
|
||||
if(irradiating) // Make sure that it isn't already irradiating someone...
|
||||
return FALSE // don't update uis
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["selectMenuKey"])
|
||||
selected_menu_key = href_list["selectMenuKey"]
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["toggleLock"])
|
||||
if((connected && connected.occupant))
|
||||
connected.locked = !(connected.locked)
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["pulseRadiation"])
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
if(!connected.occupant)
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
var/radiation = (((radiation_intensity * 3) + radiation_duration * 3) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
if(connected.radiation_check())
|
||||
return TRUE
|
||||
|
||||
if(prob(95))
|
||||
if(prob(75))
|
||||
randmutb(connected.occupant)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
else
|
||||
if(prob(95))
|
||||
randmutg(connected.occupant)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["radiationDuration"])
|
||||
if(text2num(href_list["radiationDuration"]) > 0)
|
||||
if(radiation_duration < 20)
|
||||
radiation_duration += 2
|
||||
else
|
||||
if(radiation_duration > 2)
|
||||
radiation_duration -= 2
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["radiationIntensity"])
|
||||
if(text2num(href_list["radiationIntensity"]) > 0)
|
||||
if(radiation_intensity < 10)
|
||||
radiation_intensity++
|
||||
else
|
||||
if(radiation_intensity > 1)
|
||||
radiation_intensity--
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
if(href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) > 0)
|
||||
if(selected_ui_target < 15)
|
||||
selected_ui_target++
|
||||
selected_ui_target_hex = selected_ui_target
|
||||
switch(selected_ui_target)
|
||||
if(10)
|
||||
selected_ui_target_hex = "A"
|
||||
if(11)
|
||||
selected_ui_target_hex = "B"
|
||||
if(12)
|
||||
selected_ui_target_hex = "C"
|
||||
if(13)
|
||||
selected_ui_target_hex = "D"
|
||||
if(14)
|
||||
selected_ui_target_hex = "E"
|
||||
if(15)
|
||||
selected_ui_target_hex = "F"
|
||||
else
|
||||
selected_ui_target = 0
|
||||
selected_ui_target_hex = 0
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) < 1)
|
||||
if(selected_ui_target > 0)
|
||||
selected_ui_target--
|
||||
selected_ui_target_hex = selected_ui_target
|
||||
switch(selected_ui_target)
|
||||
if(10)
|
||||
selected_ui_target_hex = "A"
|
||||
if(11)
|
||||
selected_ui_target_hex = "B"
|
||||
if(12)
|
||||
selected_ui_target_hex = "C"
|
||||
if(13)
|
||||
selected_ui_target_hex = "D"
|
||||
if(14)
|
||||
selected_ui_target_hex = "E"
|
||||
else
|
||||
selected_ui_target = 15
|
||||
selected_ui_target_hex = "F"
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["selectUIBlock"] && href_list["selectUISubblock"]) // This chunk of code updates selected block / sub-block based on click
|
||||
var/select_block = text2num(href_list["selectUIBlock"])
|
||||
var/select_subblock = text2num(href_list["selectUISubblock"])
|
||||
if((select_block <= DNA_UI_LENGTH) && (select_block >= 1))
|
||||
selected_ui_block = select_block
|
||||
if((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1))
|
||||
selected_ui_subblock = select_subblock
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["pulseUIRadiation"])
|
||||
var/block = connected.occupant.dna.GetUISubBlock(selected_ui_block, selected_ui_subblock)
|
||||
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
if(!connected.occupant)
|
||||
return TRUE
|
||||
|
||||
if(prob((80 + (radiation_duration / 2))))
|
||||
var/radiation = (radiation_intensity + radiation_duration)
|
||||
connected.occupant.apply_effect(radiation,IRRADIATE,0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return TRUE
|
||||
|
||||
block = miniscrambletarget(num2text(selected_ui_target), radiation_intensity, radiation_duration)
|
||||
connected.occupant.dna.SetUISubBlock(selected_ui_block, selected_ui_subblock, block)
|
||||
connected.occupant.UpdateAppearance()
|
||||
else
|
||||
var/radiation = ((radiation_intensity * 2) + radiation_duration)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
if(connected.radiation_check())
|
||||
return TRUE
|
||||
|
||||
if(prob(20 + radiation_intensity))
|
||||
randmutb(connected.occupant)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
connected.occupant.UpdateAppearance()
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
if(href_list["injectRejuvenators"])
|
||||
if(!connected.occupant)
|
||||
return FALSE
|
||||
var/inject_amount = round(text2num(href_list["injectRejuvenators"]), 5) // round to nearest 5
|
||||
if(inject_amount < 0) // Since the user can actually type the commands himself, some sanity checking
|
||||
inject_amount = 0
|
||||
if(inject_amount > 50)
|
||||
inject_amount = 50
|
||||
connected.beaker.reagents.trans_to(connected.occupant, inject_amount)
|
||||
connected.beaker.reagents.reaction(connected.occupant)
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
if(href_list["selectSEBlock"] && href_list["selectSESubblock"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes)
|
||||
var/select_block = text2num(href_list["selectSEBlock"])
|
||||
var/select_subblock = text2num(href_list["selectSESubblock"])
|
||||
if((select_block <= DNA_SE_LENGTH) && (select_block >= 1))
|
||||
selected_se_block = select_block
|
||||
if((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1))
|
||||
selected_se_subblock = select_subblock
|
||||
//testing("User selected block [selected_se_block] (sent [select_block]), subblock [selected_se_subblock] (sent [select_block]).")
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["pulseSERadiation"])
|
||||
var/block = connected.occupant.dna.GetSESubBlock(selected_se_block, selected_se_subblock)
|
||||
//var/original_block=block
|
||||
//testing("Irradiating SE block [selected_se_block]:[selected_se_subblock] ([block])...")
|
||||
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
if(connected.occupant)
|
||||
if(prob((80 + ((radiation_duration / 2) + (connected.precision_coeff ** 3)))))
|
||||
var/radiation = ((radiation_intensity + radiation_duration) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return 1
|
||||
|
||||
var/real_SE_block=selected_se_block
|
||||
block = miniscramble(block, radiation_intensity, radiation_duration)
|
||||
if(prob(20))
|
||||
if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2)
|
||||
real_SE_block++
|
||||
else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH)
|
||||
real_SE_block--
|
||||
|
||||
//testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!")
|
||||
connected.occupant.dna.SetSESubBlock(real_SE_block, selected_se_subblock, block)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
var/radiation = (((radiation_intensity * 2) + radiation_duration) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return 1
|
||||
|
||||
if(prob(80 - radiation_duration))
|
||||
//testing("Random bad mut!")
|
||||
randmutb(connected.occupant)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
//testing("Random identity mut!")
|
||||
connected.occupant.UpdateAppearance()
|
||||
return TRUE // return 1 forces an update to all Nano uis attached to src
|
||||
|
||||
if(href_list["ejectBeaker"])
|
||||
if(connected.beaker)
|
||||
var/obj/item/reagent_containers/glass/B = connected.beaker
|
||||
B.forceMove(connected.loc)
|
||||
connected.beaker = null
|
||||
if(tgui_act_modal(action, params))
|
||||
return TRUE
|
||||
|
||||
if(href_list["ejectOccupant"])
|
||||
connected.eject_occupant(usr)
|
||||
return TRUE
|
||||
|
||||
// Transfer Buffer Management
|
||||
if(href_list["bufferOption"])
|
||||
var/bufferOption = href_list["bufferOption"]
|
||||
|
||||
// These bufferOptions do not require a bufferId
|
||||
if(bufferOption == "wipeDisk")
|
||||
if((isnull(disk)) || (disk.read_only))
|
||||
//temphtml = "Invalid disk. Please try again."
|
||||
return FALSE
|
||||
|
||||
disk.buf = null
|
||||
//temphtml = "Data saved."
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "ejectDisk")
|
||||
if(!disk)
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("selectMenuKey")
|
||||
var/key = params["key"]
|
||||
if(!(key in list(PAGE_UI, PAGE_SE, PAGE_BUFFER, PAGE_REJUVENATORS)))
|
||||
return
|
||||
disk.forceMove(get_turf(src))
|
||||
disk = null
|
||||
return TRUE
|
||||
|
||||
// All bufferOptions from here on require a bufferId
|
||||
if(!href_list["bufferId"])
|
||||
return FALSE
|
||||
|
||||
var/bufferId = text2num(href_list["bufferId"])
|
||||
|
||||
if(bufferId < 1 || bufferId > 3)
|
||||
return FALSE // Not a valid buffer id
|
||||
|
||||
if(bufferOption == "saveUI")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_UI // DNA2_BUF_UE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name=connected.occupant.name
|
||||
databuf.name = "Unique Identifier"
|
||||
buffers[bufferId] = databuf
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "saveUIAndUE")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_UI|DNA2_BUF_UE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name=connected.occupant.dna.real_name
|
||||
databuf.name = "Unique Identifier + Unique Enzymes"
|
||||
buffers[bufferId] = databuf
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "saveSE")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_SE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name = connected.occupant.dna.real_name
|
||||
databuf.name = "Structural Enzymes"
|
||||
buffers[bufferId] = databuf
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "clear")
|
||||
buffers[bufferId] = new /datum/dna2/record()
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "changeLabel")
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null)
|
||||
buf.name = text
|
||||
buffers[bufferId] = buf
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "transfer")
|
||||
if(!connected.occupant || (NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna)
|
||||
return TRUE
|
||||
|
||||
irradiating = 2
|
||||
selected_menu_key = key
|
||||
if("toggleLock")
|
||||
if(connected && connected.occupant)
|
||||
connected.locked = !(connected.locked)
|
||||
if("pulseRadiation")
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
sleep(2 SECONDS)
|
||||
SStgui.update_uis(src)
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
var/radiation = (rand(20,50) / connected.damage_coeff)
|
||||
if(!connected.occupant)
|
||||
return
|
||||
|
||||
var/radiation = (((radiation_intensity * 3) + radiation_duration * 3) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return TRUE
|
||||
return
|
||||
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
|
||||
if((buf.types & DNA2_BUF_UI))
|
||||
if((buf.types & DNA2_BUF_UE))
|
||||
connected.occupant.real_name = buf.dna.real_name
|
||||
connected.occupant.name = buf.dna.real_name
|
||||
connected.occupant.UpdateAppearance(buf.dna.UI.Copy())
|
||||
else if(buf.types & DNA2_BUF_SE)
|
||||
connected.occupant.dna.SE = buf.dna.SE.Copy()
|
||||
connected.occupant.dna.UpdateSE()
|
||||
domutcheck(connected.occupant, connected)
|
||||
return TRUE
|
||||
|
||||
if(bufferOption == "createInjector")
|
||||
if(injector_ready && !waiting_for_user_input)
|
||||
|
||||
var/success = 1
|
||||
var/obj/item/dnainjector/I = new /obj/item/dnainjector
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
buf = buf.copy()
|
||||
if(href_list["createBlockInjector"])
|
||||
waiting_for_user_input=1
|
||||
var/list/selectedbuf
|
||||
if(buf.types & DNA2_BUF_SE)
|
||||
selectedbuf=buf.dna.SE
|
||||
else
|
||||
selectedbuf=buf.dna.UI
|
||||
var/blk = input(usr,"Select Block","Block") as null|anything in all_dna_blocks(selectedbuf)
|
||||
success = setInjectorBlock(I,blk,buf)
|
||||
if(prob(95))
|
||||
if(prob(75))
|
||||
randmutb(connected.occupant)
|
||||
else
|
||||
I.buf = buf
|
||||
waiting_for_user_input = 0
|
||||
if(success)
|
||||
I.forceMove(loc)
|
||||
I.name += " ([buf.name])"
|
||||
if(connected)
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
injector_ready = FALSE
|
||||
spawn(300)
|
||||
injector_ready = TRUE
|
||||
return TRUE
|
||||
randmuti(connected.occupant)
|
||||
else
|
||||
if(prob(95))
|
||||
randmutg(connected.occupant)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
if("radiationDuration")
|
||||
radiation_duration = clamp(text2num(params["value"]), 1, 20)
|
||||
if("radiationIntensity")
|
||||
radiation_intensity = clamp(text2num(params["value"]), 1, 10)
|
||||
////////////////////////////////////////////////////////
|
||||
if("changeUITarget")
|
||||
selected_ui_target = clamp(text2num(params["value"]), 1, 15)
|
||||
selected_ui_target_hex = num2text(selected_ui_target, 1, 16)
|
||||
if("selectUIBlock") // This chunk of code updates selected block / sub-block based on click
|
||||
var/select_block = text2num(params["block"])
|
||||
var/select_subblock = text2num(params["subblock"])
|
||||
if(!select_block || !select_subblock)
|
||||
return
|
||||
|
||||
if(bufferOption == "loadDisk")
|
||||
if((isnull(disk)) || (!disk.buf))
|
||||
//temphtml = "Invalid disk. Please try again."
|
||||
return FALSE
|
||||
selected_ui_block = clamp(select_block, 1, DNA_UI_LENGTH)
|
||||
selected_ui_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE)
|
||||
if("pulseUIRadiation")
|
||||
var/block = connected.occupant.dna.GetUISubBlock(selected_ui_block, selected_ui_subblock)
|
||||
|
||||
buffers[bufferId] = disk.buf.copy()
|
||||
//temphtml = "Data loaded."
|
||||
return TRUE
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
|
||||
if(bufferOption == "saveDisk")
|
||||
if((isnull(disk)) || (disk.read_only))
|
||||
//temphtml = "Invalid disk. Please try again."
|
||||
return FALSE
|
||||
SStgui.update_uis(src)
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
disk.buf = buf.copy()
|
||||
disk.name = "data disk - '[buf.dna.real_name]'"
|
||||
//temphtml = "Data saved."
|
||||
return TRUE
|
||||
if(!connected.occupant)
|
||||
return
|
||||
|
||||
if(prob((80 + (radiation_duration / 2))))
|
||||
var/radiation = (radiation_intensity + radiation_duration)
|
||||
connected.occupant.apply_effect(radiation,IRRADIATE,0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return
|
||||
|
||||
block = miniscrambletarget(num2text(selected_ui_target), radiation_intensity, radiation_duration)
|
||||
connected.occupant.dna.SetUISubBlock(selected_ui_block, selected_ui_subblock, block)
|
||||
connected.occupant.UpdateAppearance()
|
||||
else
|
||||
var/radiation = ((radiation_intensity * 2) + radiation_duration)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
if(connected.radiation_check())
|
||||
return
|
||||
|
||||
if(prob(20 + radiation_intensity))
|
||||
randmutb(connected.occupant)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
connected.occupant.UpdateAppearance()
|
||||
////////////////////////////////////////////////////////
|
||||
if("injectRejuvenators")
|
||||
if(!connected.occupant || !connected.beaker)
|
||||
return
|
||||
var/inject_amount = clamp(round(text2num(params["amount"]), 5), 0, 50) // round to nearest 5 and clamp to 0-50
|
||||
if(!inject_amount)
|
||||
return
|
||||
connected.beaker.reagents.trans_to(connected.occupant, inject_amount)
|
||||
connected.beaker.reagents.reaction(connected.occupant)
|
||||
////////////////////////////////////////////////////////
|
||||
if("selectSEBlock") // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes)
|
||||
var/select_block = text2num(params["block"])
|
||||
var/select_subblock = text2num(params["subblock"])
|
||||
if(!select_block || !select_subblock)
|
||||
return
|
||||
|
||||
selected_se_block = clamp(select_block, 1, DNA_SE_LENGTH)
|
||||
selected_se_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE)
|
||||
if("pulseSERadiation")
|
||||
var/block = connected.occupant.dna.GetSESubBlock(selected_se_block, selected_se_subblock)
|
||||
//var/original_block=block
|
||||
//testing("Irradiating SE block [selected_se_block]:[selected_se_subblock] ([block])...")
|
||||
|
||||
irradiating = radiation_duration
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
|
||||
SStgui.update_uis(src)
|
||||
sleep(10 * radiation_duration) // sleep for radiation_duration seconds
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
if(connected.occupant)
|
||||
if(prob((80 + ((radiation_duration / 2) + (connected.precision_coeff ** 3)))))
|
||||
var/radiation = ((radiation_intensity + radiation_duration) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return 1
|
||||
|
||||
var/real_SE_block=selected_se_block
|
||||
block = miniscramble(block, radiation_intensity, radiation_duration)
|
||||
if(prob(20))
|
||||
if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2)
|
||||
real_SE_block++
|
||||
else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH)
|
||||
real_SE_block--
|
||||
|
||||
//testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!")
|
||||
connected.occupant.dna.SetSESubBlock(real_SE_block, selected_se_subblock, block)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
var/radiation = (((radiation_intensity * 2) + radiation_duration) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return
|
||||
|
||||
if(prob(80 - radiation_duration))
|
||||
//testing("Random bad mut!")
|
||||
randmutb(connected.occupant)
|
||||
domutcheck(connected.occupant, connected)
|
||||
else
|
||||
randmuti(connected.occupant)
|
||||
//testing("Random identity mut!")
|
||||
connected.occupant.UpdateAppearance()
|
||||
if("ejectBeaker")
|
||||
if(connected.beaker)
|
||||
var/obj/item/reagent_containers/glass/B = connected.beaker
|
||||
B.forceMove(connected.loc)
|
||||
connected.beaker = null
|
||||
if("ejectOccupant")
|
||||
connected.eject_occupant()
|
||||
// Transfer Buffer Management
|
||||
if("bufferOption")
|
||||
var/bufferOption = params["option"]
|
||||
var/bufferId = text2num(params["id"])
|
||||
if(bufferId < 1 || bufferId > 3) // Not a valid buffer id
|
||||
return
|
||||
|
||||
var/datum/dna2/record/buffer = buffers[bufferId]
|
||||
switch(bufferOption)
|
||||
if("saveUI")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_UI // DNA2_BUF_UE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name=connected.occupant.name
|
||||
databuf.name = "Unique Identifier"
|
||||
buffers[bufferId] = databuf
|
||||
if("saveUIAndUE")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_UI|DNA2_BUF_UE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name=connected.occupant.dna.real_name
|
||||
databuf.name = "Unique Identifier + Unique Enzymes"
|
||||
buffers[bufferId] = databuf
|
||||
if("saveSE")
|
||||
if(connected.occupant && connected.occupant.dna)
|
||||
var/datum/dna2/record/databuf = new
|
||||
databuf.types = DNA2_BUF_SE
|
||||
databuf.dna = connected.occupant.dna.Clone()
|
||||
if(ishuman(connected.occupant))
|
||||
databuf.dna.real_name = connected.occupant.dna.real_name
|
||||
databuf.name = "Structural Enzymes"
|
||||
buffers[bufferId] = databuf
|
||||
if("clear")
|
||||
buffers[bufferId] = new /datum/dna2/record()
|
||||
if("changeLabel")
|
||||
tgui_modal_input(src, "changeBufferLabel", "Please enter the new buffer label:", null, list("id" = bufferId), buffer.name, TGUI_MODAL_INPUT_MAX_LENGTH_NAME)
|
||||
if("transfer")
|
||||
if(!connected.occupant || (NOCLONE in connected.occupant.mutations && connected.scan_level < 3) || !connected.occupant.dna)
|
||||
return
|
||||
|
||||
irradiating = 2
|
||||
var/lock_state = connected.locked
|
||||
connected.locked = TRUE //lock it
|
||||
|
||||
SStgui.update_uis(src)
|
||||
sleep(2 SECONDS)
|
||||
|
||||
irradiating = 0
|
||||
connected.locked = lock_state
|
||||
|
||||
var/radiation = (rand(20,50) / connected.damage_coeff)
|
||||
connected.occupant.apply_effect(radiation, IRRADIATE, 0)
|
||||
|
||||
if(connected.radiation_check())
|
||||
return
|
||||
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
|
||||
if((buf.types & DNA2_BUF_UI))
|
||||
if((buf.types & DNA2_BUF_UE))
|
||||
connected.occupant.real_name = buf.dna.real_name
|
||||
connected.occupant.name = buf.dna.real_name
|
||||
connected.occupant.UpdateAppearance(buf.dna.UI.Copy())
|
||||
else if(buf.types & DNA2_BUF_SE)
|
||||
connected.occupant.dna.SE = buf.dna.SE.Copy()
|
||||
connected.occupant.dna.UpdateSE()
|
||||
domutcheck(connected.occupant, connected)
|
||||
if("createInjector")
|
||||
if(!injector_ready)
|
||||
return
|
||||
if(text2num(params["block"]) > 0)
|
||||
var/list/choices = all_dna_blocks((buffer.types & DNA2_BUF_SE) ? buffer.dna.SE : buffer.dna.UI)
|
||||
tgui_modal_choice(src, "createInjectorBlock", "Please select the block to create an injector from:", null, list("id" = bufferId), null, choices)
|
||||
else
|
||||
create_injector(bufferId, TRUE)
|
||||
if("loadDisk")
|
||||
if(isnull(disk) || disk.read_only)
|
||||
return
|
||||
buffers[bufferId] = disk.buf.copy()
|
||||
if("saveDisk")
|
||||
if(isnull(disk) || disk.read_only)
|
||||
return
|
||||
var/datum/dna2/record/buf = buffers[bufferId]
|
||||
disk.buf = buf.copy()
|
||||
disk.name = "data disk - '[buf.dna.real_name]'"
|
||||
if("wipeDisk")
|
||||
if(isnull(disk) || disk.read_only)
|
||||
return
|
||||
disk.buf = null
|
||||
if("ejectDisk")
|
||||
if(!disk)
|
||||
return
|
||||
disk.forceMove(get_turf(src))
|
||||
disk = null
|
||||
|
||||
/**
|
||||
* Creates a blank injector with the name of the buffer at the given buffer_id
|
||||
*
|
||||
* Arguments:
|
||||
* * buffer_id - The ID of the buffer
|
||||
* * copy_buffer - Whether the injector should copy the buffer contents
|
||||
*/
|
||||
/obj/machinery/computer/scan_consolenew/proc/create_injector(buffer_id, copy_buffer = FALSE)
|
||||
if(buffer_id < 1 || buffer_id > length(buffers))
|
||||
return
|
||||
|
||||
// Cooldown
|
||||
injector_ready = FALSE
|
||||
addtimer(CALLBACK(src, .proc/injector_cooldown_finish), 30 SECONDS)
|
||||
|
||||
// Create it
|
||||
var/datum/dna2/record/buf = buffers[buffer_id]
|
||||
var/obj/item/dnainjector/I = new()
|
||||
I.forceMove(loc)
|
||||
I.name += " ([buf.name])"
|
||||
if(copy_buffer)
|
||||
I.buf = buf.copy()
|
||||
if(connected)
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
return I
|
||||
|
||||
/**
|
||||
* Called when the injector creation cooldown finishes
|
||||
*/
|
||||
/obj/machinery/computer/scan_consolenew/proc/injector_cooldown_finish()
|
||||
injector_ready = TRUE
|
||||
|
||||
/**
|
||||
* Called in tgui_act() to process modal actions
|
||||
*
|
||||
* Arguments:
|
||||
* * action - The action passed by tgui
|
||||
* * params - The params passed by tgui
|
||||
*/
|
||||
/obj/machinery/computer/scan_consolenew/proc/tgui_act_modal(action, params)
|
||||
. = TRUE
|
||||
var/id = params["id"] // The modal's ID
|
||||
var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"]
|
||||
switch(tgui_modal_act(src, action, params))
|
||||
if(TGUI_MODAL_ANSWER)
|
||||
var/answer = params["answer"]
|
||||
switch(id)
|
||||
if("createInjectorBlock")
|
||||
var/buffer_id = text2num(arguments["id"])
|
||||
if(buffer_id < 1 || buffer_id > length(buffers))
|
||||
return
|
||||
var/datum/dna2/record/buf = buffers[buffer_id]
|
||||
var/obj/item/dnainjector/I = create_injector(buffer_id)
|
||||
setInjectorBlock(I, answer, buf.copy())
|
||||
if("changeBufferLabel")
|
||||
var/buffer_id = text2num(arguments["id"])
|
||||
if(buffer_id < 1 || buffer_id > length(buffers))
|
||||
return
|
||||
var/datum/dna2/record/buf = buffers[buffer_id]
|
||||
buf.name = answer
|
||||
buffers[buffer_id] = buf
|
||||
else
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
#undef PAGE_UI
|
||||
#undef PAGE_SE
|
||||
#undef PAGE_BUFFER
|
||||
#undef PAGE_REJUVENATORS
|
||||
|
||||
/////////////////////////// DNA MACHINES
|
||||
|
||||
@@ -249,14 +249,13 @@
|
||||
block = GLOB.wingdingsblock
|
||||
|
||||
/datum/dna/gene/disability/wingdings/OnSay(mob/M, message)
|
||||
var/list/chars = string2charlist(message)
|
||||
var/garbled_message = ""
|
||||
for(var/C in chars)
|
||||
if(C in GLOB.alphabet_uppercase)
|
||||
for(var/i in 1 to length(message))
|
||||
if(message[i] in GLOB.alphabet_uppercase)
|
||||
garbled_message += pick(GLOB.alphabet_uppercase)
|
||||
else if(C in GLOB.alphabet)
|
||||
else if(message[i] in GLOB.alphabet)
|
||||
garbled_message += pick(GLOB.alphabet)
|
||||
else
|
||||
garbled_message += C
|
||||
garbled_message += message[i]
|
||||
message = garbled_message
|
||||
return message
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
intercepttext += "<BR>Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.<BR>"
|
||||
intercepttext += "Message ends."
|
||||
if(2)
|
||||
var/nukecode = "[rand(10000, 99999)]"
|
||||
var/nukecode = rand(10000, 99999)
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
if(bomb && bomb.r_code)
|
||||
if(is_station_level(bomb.z))
|
||||
@@ -40,7 +40,7 @@
|
||||
aiPlayer.set_zeroth_law(law)
|
||||
to_chat(aiPlayer, "Laws Updated: [law]")
|
||||
|
||||
print_command_report(intercepttext, interceptname)
|
||||
print_command_report(intercepttext, interceptname, FALSE)
|
||||
GLOB.event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg', from = "[command_name()] Update")
|
||||
|
||||
/datum/station_state
|
||||
|
||||
@@ -370,16 +370,11 @@ GLOBAL_LIST_EMPTY(sting_paths)
|
||||
mind.changeling.purchasedpowers += path
|
||||
path.on_purchase(src)
|
||||
else //for respec
|
||||
var/datum/action/changeling/hivemind_upload/S1 = new
|
||||
var/datum/action/changeling/hivemind_pick/S1 = new
|
||||
if(!mind.changeling.has_sting(S1))
|
||||
mind.changeling.purchasedpowers+=S1
|
||||
S1.Grant(src)
|
||||
|
||||
var/datum/action/changeling/hivemind_download/S2 = new
|
||||
if(!mind.changeling.has_sting(S2))
|
||||
mind.changeling.purchasedpowers+=S2
|
||||
S2.Grant(src)
|
||||
|
||||
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
|
||||
mind.changeling.absorbed_dna |= C.dna.Clone()
|
||||
mind.changeling.trim_dna()
|
||||
|
||||
@@ -12,27 +12,36 @@
|
||||
var/datum/changeling/changeling=user.mind.changeling
|
||||
changeling.changeling_speak = 1
|
||||
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
|
||||
var/datum/action/changeling/hivemind_upload/S1 = new
|
||||
var/datum/action/changeling/hivemind_pick/S1 = new
|
||||
if(!changeling.has_sting(S1))
|
||||
changeling.purchasedpowers+=S1
|
||||
S1.Grant(user)
|
||||
var/datum/action/changeling/hivemind_download/S2 = new
|
||||
if(!changeling.has_sting(S2))
|
||||
S2.Grant(user)
|
||||
changeling.purchasedpowers+=S2
|
||||
return
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
|
||||
/datum/action/changeling/hivemind_upload
|
||||
/datum/action/changeling/hivemind_pick
|
||||
name = "Hive Channel DNA"
|
||||
desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it. Costs 10 chemicals."
|
||||
button_icon_state = "hivemind_channel"
|
||||
desc = "Allows us to upload or absorb DNA in the airwaves. Does not count towards absorb objectives. Costs 10 chemicals."
|
||||
button_icon_state = "hive_absorb"
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/datum/action/changeling/hivemind_upload/sting_action(var/mob/user)
|
||||
/datum/action/changeling/hivemind_pick/sting_action(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/channel_pick = alert("Upload or Absorb DNA?", "Channel Select", "Upload", "Absorb")
|
||||
|
||||
if(channel_pick == "Upload")
|
||||
dna_upload(user)
|
||||
if(channel_pick == "Absorb")
|
||||
if(changeling.using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it.
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
else
|
||||
dna_absorb(user)
|
||||
|
||||
/datum/action/changeling/proc/dna_upload(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/list/names = list()
|
||||
for(var/datum/dna/DNA in (changeling.absorbed_dna+changeling.protected_dna))
|
||||
@@ -56,23 +65,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
feedback_add_details("changeling_powers","HU")
|
||||
return 1
|
||||
|
||||
/datum/action/changeling/hivemind_download
|
||||
name = "Hive Absorb DNA"
|
||||
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives. Costs 10 chemicals."
|
||||
button_icon_state = "hive_absorb"
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/datum/action/changeling/hivemind_download/can_sting(var/mob/living/carbon/user)
|
||||
if(!..())
|
||||
return
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
if(changeling.using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it.
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/datum/action/changeling/hivemind_download/sting_action(var/mob/user)
|
||||
/datum/action/changeling/proc/dna_absorb(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/list/names = list()
|
||||
for(var/datum/dna/DNA in GLOB.hivemind_bank)
|
||||
|
||||
@@ -177,26 +177,37 @@
|
||||
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/special_overlays()
|
||||
return mutable_appearance('icons/effects/cult_effects.dmi', shield_state, MOB_LAYER + 0.01)
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/berserker
|
||||
/obj/item/clothing/suit/hooded/cultrobes/flagellant_robe
|
||||
name = "flagellant's robes"
|
||||
desc = "Blood-soaked robes infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage."
|
||||
icon_state = "hardsuit-berserker"
|
||||
item_state = "hardsuit-berserker"
|
||||
icon_state = "flagellantrobe"
|
||||
item_state = "flagellantrobe"
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
allowed = list(/obj/item/tome,/obj/item/melee/cultblade)
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
armor = list("melee" = -45, "bullet" = -45, "laser" = -45,"energy" = -45, "bomb" = -45, "bio" = -45, "rad" = -45, "fire" = 0, "acid" = 0)
|
||||
slowdown = -1
|
||||
hoodtype = /obj/item/clothing/head/hooded/berserkerhood
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/suit.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/suit.dmi'
|
||||
)
|
||||
hoodtype = /obj/item/clothing/head/hooded/flagellant_hood
|
||||
|
||||
|
||||
/obj/item/clothing/head/hooded/berserkerhood
|
||||
/obj/item/clothing/head/hooded/flagellant_hood
|
||||
name = "flagellant's robes"
|
||||
desc = "Blood-soaked garb infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage."
|
||||
icon_state = "culthood"
|
||||
icon_state = "flagellanthood"
|
||||
item_state = "flagellanthood"
|
||||
flags_inv = HIDEFACE
|
||||
flags_cover = HEADCOVERSEYES
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/head.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/head.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/head.dmi'
|
||||
)
|
||||
|
||||
/obj/item/whetstone/cult
|
||||
name = "eldritch whetstone"
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
selection_prompt = "You study the schematics etched on the forge..."
|
||||
selection_title = "Forge"
|
||||
creation_message = "<span class='cultitalic'>You work the forge as dark knowledge guides your hands, creating %ITEM%!</span>"
|
||||
choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/berserker, \
|
||||
choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/flagellant_robe, \
|
||||
"Cultist Hardsuit" = /obj/item/storage/box/cult)
|
||||
|
||||
/obj/structure/cult/functional/forge/New()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/paper/talisman
|
||||
icon = 'icons/obj/paper.dmi'
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paper_talisman"
|
||||
var/cultist_name = "talisman"
|
||||
var/cultist_desc = "A basic talisman. It serves no purpose."
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
|
||||
. = ..()
|
||||
owner = owner_mind
|
||||
flavour_text = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, [owner.p_they()] can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
|
||||
description = "Be someone's loyal friend/slave. If they die, you die as well." //best I could think of in the moment, not sure how this role plays in practise, have never seen it.
|
||||
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, [owner.p_they()] can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
|
||||
var/area/A = get_area(src)
|
||||
if(!mapload && A)
|
||||
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = TRUE)
|
||||
|
||||
@@ -507,7 +507,7 @@ proc/display_roundstart_logout_report()
|
||||
message_text += G.get_report()
|
||||
message_text += "<hr>"
|
||||
|
||||
print_command_report(message_text, "[command_name()] Orders")
|
||||
print_command_report(message_text, "[command_name()] Orders", FALSE)
|
||||
|
||||
/datum/game_mode/proc/declare_station_goal_completion()
|
||||
for(var/V in station_goals)
|
||||
|
||||
@@ -616,7 +616,7 @@
|
||||
active = FALSE
|
||||
return
|
||||
var/turf/T = get_turf(owner_AI.eyeobj)
|
||||
new /obj/machinery/transformer/conveyor(T)
|
||||
new /obj/machinery/transformer(T, owner_AI)
|
||||
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
|
||||
owner_AI.can_shunt = FALSE
|
||||
to_chat(owner, "<span class='warning'>You are no longer able to shunt your core to APCs.</span>")
|
||||
@@ -781,3 +781,17 @@
|
||||
if(AI.eyeobj)
|
||||
AI.eyeobj.relay_speech = TRUE
|
||||
|
||||
/datum/AI_Module/large/cameracrack
|
||||
module_name = "Core Camera Cracker"
|
||||
mod_pick_name = "cameracrack"
|
||||
description = "By shortcirucuting the camera network chip, it overheats, preventing the camera console from using your internal camera."
|
||||
cost = 10
|
||||
one_purchase = TRUE
|
||||
upgrade = TRUE
|
||||
unlock_text = "<span class='notice'>Network chip short circuited. Internal camera disconected from network. Minimal damage to other internal components.</span>"
|
||||
unlock_sound = 'sound/items/wirecutter.ogg'
|
||||
|
||||
/datum/AI_Module/large/cameracrack/upgrade(mob/living/silicon/ai/AI)
|
||||
if(AI.builtInCamera)
|
||||
QDEL_NULL(AI.builtInCamera)
|
||||
|
||||
|
||||
@@ -19,15 +19,13 @@
|
||||
mob_name = "a swarmer"
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
flavour_text = {"
|
||||
<b>You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate.</b>
|
||||
<b>Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful.</b>
|
||||
<b>Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.</b>
|
||||
<b>Objectives:</b>
|
||||
important_info = "Follow your objectives, do not make the station inhospitable or try and kill crew."
|
||||
flavour_text = "You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate."
|
||||
description = {" Your goal is to create more of yourself by consuming the station. Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. Ctrl-Clicking on a mob will attempt to remove it from the area and place it in a safe environment for storage.
|
||||
Objectives:
|
||||
1. Consume resources and replicate until there are no more resources left.
|
||||
2. Ensure that this location is fit for invasion at a later date; do not perform actions that would render it dangerous or inhospitable.
|
||||
3. Biological resources will be harvested at a later date; do not harm them.
|
||||
"}
|
||||
3. Biological resources will be harvested at a later date; do not harm them."}
|
||||
|
||||
/obj/effect/mob_spawn/swarmer/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/swarmer_report = "<font size=3><b>[command_name()] High-Priority Update</b></span>"
|
||||
swarmer_report += "<br><br>Our long-range sensors have detected an odd signal emanating from your station's gateway. We recommend immediate investigation of your gateway, as something may have come \
|
||||
through."
|
||||
print_command_report(swarmer_report, "Classified [command_name()] Update")
|
||||
print_command_report(swarmer_report, "Classified [command_name()] Update", FALSE)
|
||||
GLOB.event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
|
||||
|
||||
/datum/event/spawn_swarmer/start()
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
if("Protector")
|
||||
pickedtype = /mob/living/simple_animal/hostile/guardian/protector
|
||||
|
||||
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user)
|
||||
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user, user)
|
||||
G.summoner = user
|
||||
G.summoned = TRUE
|
||||
G.key = key
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
layer = LYING_MOB_LAYER
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/beam
|
||||
melee_damage_lower = 7
|
||||
melee_damage_upper = 7
|
||||
melee_damage_lower = 12
|
||||
melee_damage_upper = 12
|
||||
attacktext = "shocks"
|
||||
melee_damage_type = BURN
|
||||
attack_sound = 'sound/machines/defib_zap.ogg'
|
||||
damage_transfer = 0.7
|
||||
damage_transfer = 0.6
|
||||
range = 7
|
||||
playstyle_string = "As a <b>Lightning</b> type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them."
|
||||
magic_fluff_string = "..And draw the Tesla, a shocking, lethal source of power."
|
||||
@@ -18,6 +18,17 @@
|
||||
var/list/enemychains = list()
|
||||
var/successfulshocks = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/beam/New(loc, mob/living/user)
|
||||
. = ..()
|
||||
if(!user)
|
||||
return
|
||||
summoner = user
|
||||
if(!(NO_SHOCK in summoner.mutations))
|
||||
summoner.mutations.Add(NO_SHOCK)
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/beam/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
|
||||
return FALSE //You are lightning, you should not be hurt by such things.
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/beam/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && isliving(target) && target != src && target != summoner)
|
||||
@@ -106,3 +117,8 @@
|
||||
)
|
||||
L.adjustFireLoss(1.2) //adds up very rapidly
|
||||
. = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/beam/death(gibbed)
|
||||
if(summoner && (NO_SHOCK in summoner.mutations))
|
||||
summoner.mutations.Remove(NO_SHOCK)
|
||||
return ..()
|
||||
|
||||
@@ -103,7 +103,7 @@ proc/issyndicate(mob/living/M as mob)
|
||||
|
||||
var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb")
|
||||
|
||||
var/nuke_code = "[rand(10000, 99999)]"
|
||||
var/nuke_code = rand(10000, 99999)
|
||||
var/leader_selected = 0
|
||||
var/agent_number = 1
|
||||
var/spawnpos = 1
|
||||
|
||||
@@ -14,59 +14,59 @@ GLOBAL_VAR(bomb_set)
|
||||
icon_state = "nuclearbomb0"
|
||||
density = 1
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/deployable = 0
|
||||
var/extended = 0
|
||||
var/lighthack = 0
|
||||
var/extended = FALSE
|
||||
var/lighthack = FALSE
|
||||
var/timeleft = 120
|
||||
var/timing = 0
|
||||
var/timing = FALSE
|
||||
var/exploded = FALSE
|
||||
var/r_code = "ADMIN"
|
||||
var/code = ""
|
||||
var/yes_code = 0
|
||||
var/safety = 1
|
||||
var/code
|
||||
var/yes_code = FALSE
|
||||
var/safety = TRUE
|
||||
var/obj/item/disk/nuclear/auth = null
|
||||
var/removal_stage = NUKE_INTACT
|
||||
var/lastentered
|
||||
var/is_syndicate = 0
|
||||
var/is_syndicate = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
var/previous_level = ""
|
||||
var/datum/wires/nuclearbomb/wires = null
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate
|
||||
is_syndicate = 1
|
||||
is_syndicate = TRUE
|
||||
|
||||
/obj/machinery/nuclearbomb/New()
|
||||
..()
|
||||
r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
|
||||
r_code = rand(10000, 99999.0) // Creates a random code upon object spawn.
|
||||
wires = new/datum/wires/nuclearbomb(src)
|
||||
previous_level = get_security_level()
|
||||
GLOB.poi_list |= src
|
||||
|
||||
/obj/machinery/nuclearbomb/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
GLOB.poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/process()
|
||||
if(timing)
|
||||
GLOB.bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
|
||||
GLOB.bomb_set = TRUE // So long as there is one nuke timing, it means one nuke is armed.
|
||||
timeleft = max(timeleft - 2, 0) // 2 seconds per process()
|
||||
if(timeleft <= 0)
|
||||
INVOKE_ASYNC(src, .proc/explode)
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/attackby(obj/item/O as obj, mob/user as mob, params)
|
||||
if(istype(O, /obj/item/disk/nuclear))
|
||||
if(extended)
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='notice'>\The [O] is stuck to your hand!</span>")
|
||||
to_chat(user, "<span class='notice'>[O] is stuck to your hand!</span>")
|
||||
return
|
||||
O.forceMove(src)
|
||||
auth = O
|
||||
add_fingerprint(user)
|
||||
return attack_hand(user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need to deploy \the [src] first. Right click on the sprite, select 'Make Deployable' then click on \the [src] with an empty hand.</span>")
|
||||
to_chat(user, "<span class='notice'>You need to deploy [src] first.</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -170,181 +170,157 @@ GLOBAL_VAR(bomb_set)
|
||||
removal_stage = NUKE_SEALANT_OPEN
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
|
||||
if(extended)
|
||||
attack_hand(user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
|
||||
if(extended)
|
||||
if(panel_open)
|
||||
wires.Interact(user)
|
||||
else
|
||||
ui_interact(user)
|
||||
else if(deployable)
|
||||
if(removal_stage != NUKE_MOBILE)
|
||||
anchored = 1
|
||||
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring!</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
|
||||
if(!lighthack)
|
||||
flick("nuclearbombc", src)
|
||||
icon_state = "nuclearbomb1"
|
||||
extended = 1
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "nuclear_bomb.tmpl", "Nuke Control Panel", 450, 550, state = GLOB.physical_state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
data["is_syndicate"] = is_syndicate
|
||||
data["hacking"] = 0
|
||||
data["auth"] = is_auth(user)
|
||||
if(is_auth(user))
|
||||
if(yes_code)
|
||||
data["authstatus"] = timing ? "Functional/Set" : "Functional"
|
||||
else
|
||||
data["authstatus"] = "Auth. S2"
|
||||
if(panel_open)
|
||||
wires.Interact(user)
|
||||
else
|
||||
if(timing)
|
||||
data["authstatus"] = "Set"
|
||||
else
|
||||
data["authstatus"] = "Auth. S1"
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/nuclearbomb/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NuclearBomb", name, 450, 300, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/nuclearbomb/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["extended"] = extended
|
||||
data["authdisk"] = is_auth(user)
|
||||
data["diskname"] = auth ? auth.name : FALSE
|
||||
data["authcode"] = yes_code
|
||||
data["authfull"] = data["authdisk"] && data["authcode"]
|
||||
data["safe"] = safety ? "Safe" : "Engaged"
|
||||
data["time"] = timeleft
|
||||
data["timer"] = timing
|
||||
data["safety"] = safety
|
||||
data["anchored"] = anchored
|
||||
data["yescode"] = yes_code
|
||||
data["message"] = "AUTH"
|
||||
if(is_auth(user))
|
||||
data["message"] = code
|
||||
if(yes_code)
|
||||
data["message"] = "*****"
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/nuclearbomb/verb/make_deployable()
|
||||
set category = "Object"
|
||||
set name = "Make Deployable"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
return
|
||||
|
||||
if(deployable)
|
||||
to_chat(usr, "<span class='warning'>You close several panels to make [src] undeployable.</span>")
|
||||
deployable = 0
|
||||
data["codemsg"] = "CLEAR CODE"
|
||||
else if(code)
|
||||
data["codemsg"] = "RE-ENTER CODE"
|
||||
else
|
||||
data["codemsg"] = "ENTER CODE"
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You adjust some panels to make [src] deployable.</span>")
|
||||
deployable = 1
|
||||
return
|
||||
data["codemsg"] = "-----"
|
||||
return data
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/is_auth(var/mob/user)
|
||||
if(auth)
|
||||
return 1
|
||||
return TRUE
|
||||
else if(user.can_admin_interact())
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/nuclearbomb/Topic(href, href_list)
|
||||
/obj/machinery/nuclearbomb/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["auth"])
|
||||
if(auth)
|
||||
auth.loc = loc
|
||||
yes_code = 0
|
||||
auth = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/disk/nuclear))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
auth = I
|
||||
if(is_auth(usr))
|
||||
if(href_list["type"])
|
||||
if(href_list["type"] == "E")
|
||||
return
|
||||
. = TRUE
|
||||
if(exploded)
|
||||
return
|
||||
switch(action)
|
||||
if("deploy")
|
||||
if(removal_stage != NUKE_MOBILE)
|
||||
anchored = TRUE
|
||||
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring!</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
|
||||
if(!lighthack)
|
||||
flick("nuclearbombc", src)
|
||||
icon_state = "nuclearbomb1"
|
||||
extended = TRUE
|
||||
return
|
||||
if("auth")
|
||||
if(auth)
|
||||
if(!usr.get_active_hand() && Adjacent(usr))
|
||||
usr.put_in_hands(auth)
|
||||
else
|
||||
auth.forceMove(get_turf(src))
|
||||
yes_code = FALSE
|
||||
auth = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/disk/nuclear))
|
||||
usr.drop_item()
|
||||
I.forceMove(src)
|
||||
auth = I
|
||||
return
|
||||
if(!is_auth(usr)) // All requests below here require NAD inserted.
|
||||
return FALSE
|
||||
switch(action)
|
||||
if("code")
|
||||
if(yes_code) // Clear code
|
||||
code = null
|
||||
yes_code = FALSE
|
||||
return
|
||||
// If no code set, enter new one
|
||||
var/tempcode = input(usr, "Code", "Input Code", null) as num|null
|
||||
if(tempcode)
|
||||
code = min(max(round(tempcode), 0), 999999)
|
||||
if(code == r_code)
|
||||
yes_code = 1
|
||||
yes_code = TRUE
|
||||
code = null
|
||||
else
|
||||
code = "ERROR"
|
||||
return
|
||||
|
||||
if(!yes_code) // All requests below here require both NAD inserted AND code correct
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("toggle_anchor")
|
||||
if(removal_stage == NUKE_MOBILE)
|
||||
anchored = FALSE
|
||||
visible_message("<span class='warning'>[src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
|
||||
else if(isinspace())
|
||||
to_chat(usr, "<span class='warning'>There is nothing to anchor to!</span>")
|
||||
return FALSE
|
||||
else
|
||||
if(href_list["type"] == "R")
|
||||
yes_code = 0
|
||||
code = null
|
||||
else
|
||||
lastentered = text("[]", href_list["type"])
|
||||
if(text2num(lastentered) == null)
|
||||
var/turf/LOC = get_turf(usr)
|
||||
message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: <a href='?_src_=vars;Vars=[UID()]'>[lastentered]</a>! ([LOC ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[LOC.x];Y=[LOC.y];Z=[LOC.z]'>JMP</a>" : "null"])", 0)
|
||||
log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!")
|
||||
else
|
||||
code += lastentered
|
||||
if(length(code) > 5)
|
||||
code = "ERROR"
|
||||
if(yes_code)
|
||||
if(href_list["time"])
|
||||
var/time = text2num(href_list["time"])
|
||||
timeleft += time
|
||||
timeleft = min(max(round(src.timeleft), 120), 600)
|
||||
if(href_list["timer"])
|
||||
if(timing == -1.0)
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
if(safety)
|
||||
to_chat(usr, "<span class='warning'>The safety is still on.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
timing = !(timing)
|
||||
if(timing)
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb2"
|
||||
if(!safety)
|
||||
message_admins("[key_name_admin(usr)] engaged a nuclear bomb (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
if(!is_syndicate)
|
||||
set_security_level("delta")
|
||||
GLOB.bomb_set = 1 //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N
|
||||
else
|
||||
GLOB.bomb_set = 0
|
||||
anchored = !(anchored)
|
||||
if(anchored)
|
||||
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>The anchoring bolts slide back into the depths of [src].</span>")
|
||||
return
|
||||
if("set_time")
|
||||
var/time = input(usr, "Detonation time (seconds, min 120, max 600)", "Input Time", 120) as num|null
|
||||
if(time)
|
||||
timeleft = min(max(round(time), 120), 600)
|
||||
if("toggle_safety")
|
||||
safety = !(safety)
|
||||
if(safety)
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
timing = FALSE
|
||||
GLOB.bomb_set = FALSE
|
||||
if("toggle_armed")
|
||||
if(safety)
|
||||
to_chat(usr, "<span class='notice'>The safety is still on.</span>")
|
||||
return
|
||||
timing = !(timing)
|
||||
if(timing)
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb2"
|
||||
if(!safety)
|
||||
message_admins("[key_name_admin(usr)] engaged a nuclear bomb [ADMIN_JMP(src)]")
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
GLOB.bomb_set = 0
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb1"
|
||||
if(href_list["safety"])
|
||||
safety = !(safety)
|
||||
if(safety)
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
timing = 0
|
||||
GLOB.bomb_set = 0
|
||||
if(href_list["anchor"])
|
||||
if(removal_stage == NUKE_MOBILE)
|
||||
anchored = 0
|
||||
visible_message("<span class='warning'>\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
if(!isinspace())
|
||||
anchored = !(anchored)
|
||||
if(anchored)
|
||||
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>The anchoring bolts slide back into the depths of [src].</span>")
|
||||
set_security_level("delta")
|
||||
GLOB.bomb_set = TRUE // There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>There is nothing to anchor to!</span>")
|
||||
GLOB.bomb_set = TRUE
|
||||
else
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
GLOB.bomb_set = FALSE
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb1"
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/obj/machinery/nuclearbomb/blob_act(obj/structure/blob/B)
|
||||
if(timing == -1.0)
|
||||
if(exploded)
|
||||
return
|
||||
if(timing) //boom
|
||||
INVOKE_ASYNC(src, .proc/explode)
|
||||
@@ -359,11 +335,11 @@ GLOBAL_VAR(bomb_set)
|
||||
#define NUKERANGE 80
|
||||
/obj/machinery/nuclearbomb/proc/explode()
|
||||
if(safety)
|
||||
timing = 0
|
||||
timing = FALSE
|
||||
return
|
||||
timing = -1.0
|
||||
yes_code = 0
|
||||
safety = 1
|
||||
exploded = TRUE
|
||||
yes_code = FALSE
|
||||
safety = TRUE
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb3"
|
||||
playsound(src,'sound/machines/alarm.ogg',100,0,5)
|
||||
@@ -407,6 +383,20 @@ GLOBAL_VAR(bomb_set)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/reset_lighthack_callback()
|
||||
lighthack = !lighthack
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/reset_safety_callback()
|
||||
safety = !safety
|
||||
if(safety == 1)
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
visible_message("<span class='notice'>The [src] quiets down.</span>")
|
||||
if(!lighthack)
|
||||
if(icon_state == "nuclearbomb2")
|
||||
icon_state = "nuclearbomb1"
|
||||
else
|
||||
visible_message("<span class='notice'>The [src] emits a quiet whirling noise!</span>")
|
||||
|
||||
//==========DAT FUKKEN DISK===============
|
||||
/obj/item/disk/nuclear
|
||||
|
||||
@@ -279,6 +279,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
var/blood = 0
|
||||
var/old_bloodtotal = 0 //used to see if we increased our blood total
|
||||
var/old_bloodusable = 0 //used to see if we increased our blood usable
|
||||
var/blood_volume_warning = 9999 //Blood volume threshold for warnings
|
||||
if(owner.is_muzzled())
|
||||
to_chat(owner, "<span class='warning'>[owner.wear_mask] prevents you from biting [H]!</span>")
|
||||
draining = null
|
||||
@@ -291,13 +292,10 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
H.LAssailant = owner
|
||||
while(do_mob(owner, H, 50))
|
||||
if(!(owner.mind in SSticker.mode.vampires))
|
||||
to_chat(owner, "<span class='warning'>Your fangs have disappeared!</span>")
|
||||
to_chat(owner, "<span class='userdanger'>Your fangs have disappeared!</span>")
|
||||
return
|
||||
old_bloodtotal = bloodtotal
|
||||
old_bloodusable = bloodusable
|
||||
if(!H.blood_volume)
|
||||
to_chat(owner, "<span class='warning'>They've got no blood left to give.</span>")
|
||||
break
|
||||
if(H.stat < DEAD)
|
||||
if(H.ckey || H.player_ghosted) //Requires ckey regardless if monkey or humanoid, or the body has been ghosted before it died
|
||||
blood = min(20, H.blood_volume) // if they have less than 20 blood, give them the remnant else they get 20 blood
|
||||
@@ -312,6 +310,17 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
to_chat(owner, "<span class='notice'><b>You have accumulated [bloodtotal] [bloodtotal > 1 ? "units" : "unit"] of blood[bloodusable != old_bloodusable ? ", and have [bloodusable] left to use" : ""].</b></span>")
|
||||
check_vampire_upgrade()
|
||||
H.blood_volume = max(H.blood_volume - 25, 0)
|
||||
//Blood level warnings (Code 'borrowed' from Fulp)
|
||||
if(H.blood_volume)
|
||||
if(H.blood_volume <= BLOOD_VOLUME_BAD && blood_volume_warning > BLOOD_VOLUME_BAD)
|
||||
to_chat(owner, "<span class='danger'>Your victim's blood volume is dangerously low.</span>")
|
||||
else if(H.blood_volume <= BLOOD_VOLUME_OKAY && blood_volume_warning > BLOOD_VOLUME_OKAY)
|
||||
to_chat(owner, "<span class='warning'>Your victim's blood is at an unsafe level.</span>")
|
||||
blood_volume_warning = H.blood_volume //Set to blood volume, so that you only get the message once
|
||||
else
|
||||
to_chat(owner, "<span class='warning'>You have bled your victim dry!</span>")
|
||||
break
|
||||
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/V = owner
|
||||
if(!H.ckey && !H.player_ghosted)//Only runs if there is no ckey and the body has not being ghosted while alive
|
||||
|
||||
@@ -510,3 +510,26 @@ proc/get_all_job_icons() //For all existing HUD icons
|
||||
return rankName
|
||||
|
||||
return "Unknown" //Return unknown if none of the above apply
|
||||
|
||||
proc/get_accesslist_static_data(num_min_region = REGION_GENERAL, num_max_region = REGION_COMMAND)
|
||||
var/list/retval
|
||||
for(var/i in num_min_region to num_max_region)
|
||||
var/list/accesses = list()
|
||||
var/list/available_accesses
|
||||
if(i == REGION_CENTCOMM) // Override necessary, because get_region_accesses(REGION_CENTCOM) returns BOTH CC and crew accesses.
|
||||
available_accesses = get_all_centcom_access()
|
||||
else
|
||||
available_accesses = get_region_accesses(i)
|
||||
for(var/access in available_accesses)
|
||||
var/access_desc = (i == REGION_CENTCOMM) ? get_centcom_access_desc(access) : get_access_desc(access)
|
||||
if (access_desc)
|
||||
accesses += list(list(
|
||||
"desc" = replacetext(access_desc, " ", " "),
|
||||
"ref" = access,
|
||||
))
|
||||
retval += list(list(
|
||||
"name" = get_region_accesses_name(i),
|
||||
"regid" = i,
|
||||
"accesses" = accesses
|
||||
))
|
||||
return retval
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
ACCESS_HEADS, ACCESS_CONSTRUCTION, ACCESS_SEC_DOORS,
|
||||
ACCESS_CE, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_MINISAT, ACCESS_MECHANIC, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_ENGINEERING
|
||||
outfit = /datum/outfit/job/chief_engineer
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE,
|
||||
ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_PSYCHIATRIST, ACCESS_MAINT_TUNNELS, ACCESS_PARAMEDIC, ACCESS_MINERAL_STOREROOM)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_MEDICAL
|
||||
outfit = /datum/outfit/job/cmo
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
ACCESS_RESEARCH, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_AI_UPLOAD,
|
||||
ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_GATEWAY, ACCESS_XENOARCH, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM, ACCESS_NETWORK)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_SCIENCE
|
||||
// All science-y guys get bonuses for maxing out their tech.
|
||||
required_objectives = list(
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
|
||||
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_PILOT, ACCESS_WEAPONS)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_SECURITY
|
||||
disabilities_allowed = 0
|
||||
outfit = /datum/outfit/job/hos
|
||||
@@ -64,7 +64,7 @@
|
||||
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS)
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 600
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type = EXP_TYPE_SECURITY
|
||||
outfit = /datum/outfit/job/warden
|
||||
|
||||
/datum/outfit/job/warden
|
||||
|
||||
@@ -13,7 +13,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca
|
||||
access = list() //See get_access()
|
||||
minimal_access = list() //See get_access()
|
||||
minimal_player_age = 30
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_COMMAND
|
||||
disabilities_allowed = 0
|
||||
outfit = /datum/outfit/job/captain
|
||||
@@ -67,7 +67,7 @@ GLOBAL_DATUM_INIT(captain_announcement, /datum/announcement/minor, new(do_newsca
|
||||
req_admin_notify = 1
|
||||
is_command = 1
|
||||
minimal_player_age = 21
|
||||
exp_requirements = 300
|
||||
exp_requirements = 1200
|
||||
exp_type = EXP_TYPE_COMMAND
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_FORENSICS_LOCKERS,
|
||||
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user