mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
fixes merge conflict, updates to master
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
|
||||
},
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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
|
||||
+60
-13
@@ -242,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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]"]
|
||||
@@ -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]
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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."
|
||||
|
||||
+62
-106
@@ -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 test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !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,16 +63,16 @@
|
||||
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)
|
||||
@@ -124,44 +85,44 @@
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
|
||||
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,40 @@
|
||||
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(WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/ai_control_callback), 1 SECONDS)
|
||||
|
||||
spawn(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ GLOBAL_VAR(bomb_set)
|
||||
GLOB.poi_list |= src
|
||||
|
||||
/obj/machinery/nuclearbomb/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
GLOB.poi_list.Remove(src)
|
||||
return ..()
|
||||
@@ -407,6 +408,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
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
first_run()
|
||||
|
||||
/obj/machinery/alarm/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
GLOB.air_alarms -= src
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src, frequency)
|
||||
@@ -314,7 +315,7 @@
|
||||
temperature_dangerlevel
|
||||
)
|
||||
|
||||
if(old_danger_level!=danger_level)
|
||||
if(old_danger_level != danger_level)
|
||||
apply_danger_level()
|
||||
|
||||
if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05)
|
||||
@@ -534,28 +535,35 @@
|
||||
"checks"= 0,
|
||||
))
|
||||
|
||||
/obj/machinery/alarm/proc/apply_danger_level(var/new_danger_level)
|
||||
if(report_danger_level && alarm_area.atmosalert(new_danger_level, src))
|
||||
post_alert(new_danger_level)
|
||||
/obj/machinery/alarm/proc/apply_danger_level()
|
||||
var/new_area_danger_level = ATMOS_ALARM_NONE
|
||||
for(var/obj/machinery/alarm/AA in alarm_area)
|
||||
if(!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted)
|
||||
new_area_danger_level = max(new_area_danger_level, AA.danger_level)
|
||||
if(alarm_area.atmosalert(new_area_danger_level, src)) //if area was in normal state or if area was in alert state
|
||||
post_alert(new_area_danger_level)
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/alarm/proc/post_alert(alert_level)
|
||||
if(!report_danger_level)
|
||||
return
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/alert_signal = new
|
||||
alert_signal.source = src
|
||||
alert_signal.transmission_method = 1
|
||||
alert_signal.data["zone"] = alarm_area.name
|
||||
alert_signal.data["zone"] = get_area_name(src, TRUE)
|
||||
alert_signal.data["type"] = "Atmospheric"
|
||||
|
||||
if(alert_level==2)
|
||||
if(alert_level == ATMOS_ALARM_DANGER)
|
||||
alert_signal.data["alert"] = "severe"
|
||||
else if(alert_level==1)
|
||||
else if(alert_level == ATMOS_ALARM_WARNING)
|
||||
alert_signal.data["alert"] = "minor"
|
||||
else if(alert_level==0)
|
||||
else if(alert_level == ATMOS_ALARM_NONE)
|
||||
alert_signal.data["alert"] = "clear"
|
||||
|
||||
frequency.post_signal(src, alert_signal)
|
||||
@@ -889,14 +897,14 @@
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_DANGER, src))
|
||||
apply_danger_level(ATMOS_ALARM_DANGER)
|
||||
post_alert(ATMOS_ALARM_DANGER)
|
||||
alarmActivated = 1
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_NONE, src, TRUE))
|
||||
apply_danger_level(ATMOS_ALARM_NONE)
|
||||
post_alert(ATMOS_ALARM_NONE)
|
||||
alarmActivated = 0
|
||||
update_icon()
|
||||
return 1
|
||||
@@ -951,7 +959,7 @@
|
||||
to_chat(user, "It does nothing")
|
||||
return
|
||||
else
|
||||
if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] the Air Alarm interface.</span>")
|
||||
updateUsrDialog()
|
||||
@@ -1030,7 +1038,7 @@
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(wires.wires_status == 31) // all wires cut
|
||||
if(wires.is_all_cut()) // all wires cut
|
||||
var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil(user.drop_location())
|
||||
new_coil.amount = 5
|
||||
buildstage = AIR_ALARM_BUILDING
|
||||
@@ -1076,6 +1084,15 @@
|
||||
if(buildstage < 1)
|
||||
. += "The circuit is missing."
|
||||
|
||||
/obj/machinery/alarm/proc/unshort_callback()
|
||||
if(shorted)
|
||||
shorted = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/alarm/proc/enable_ai_control_callback()
|
||||
if(aidisabled)
|
||||
aidisabled = FALSE
|
||||
|
||||
/obj/machinery/alarm/all_access
|
||||
name = "all-access air alarm"
|
||||
desc = "This particular atmos control unit appears to have no access restrictions."
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/autolathe/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
@@ -467,3 +468,15 @@
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if("hacked" in D.category)
|
||||
files.known_designs -= D.id
|
||||
|
||||
/obj/machinery/autolathe/proc/check_hacked_callback()
|
||||
if(!wires.is_cut(WIRE_AUTOLATHE_HACK))
|
||||
adjust_hacked(FALSE)
|
||||
|
||||
/obj/machinery/autolathe/proc/check_electrified_callback()
|
||||
if(!wires.is_cut(WIRE_ELECTRIFY))
|
||||
shocked = FALSE
|
||||
|
||||
/obj/machinery/autolathe/proc/check_disabled_callback()
|
||||
if(!wires.is_cut(WIRE_AUTOLATHE_DISABLE))
|
||||
disabled = FALSE
|
||||
|
||||
@@ -28,13 +28,14 @@
|
||||
var/view_range = 7
|
||||
var/short_range = 2
|
||||
|
||||
var/alarm_on = FALSE
|
||||
var/busy = FALSE
|
||||
var/emped = FALSE //Number of consecutive EMP's on this camera
|
||||
|
||||
var/in_use_lights = 0 // TO BE IMPLEMENTED
|
||||
var/toggle_sound = 'sound/items/wirecutter.ogg'
|
||||
|
||||
/obj/machinery/camera/Initialize()
|
||||
/obj/machinery/camera/Initialize(mapload)
|
||||
. = ..()
|
||||
wires = new(src)
|
||||
assembly = new(src)
|
||||
@@ -44,11 +45,17 @@
|
||||
|
||||
GLOB.cameranet.cameras += src
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if(isturf(loc))
|
||||
LAZYADD(myArea.cameras, UID())
|
||||
if(is_station_level(z) && prob(3) && !start_active)
|
||||
toggle_cam(null, FALSE)
|
||||
wires.CutAll()
|
||||
wires.cut_all()
|
||||
|
||||
/obj/machinery/camera/proc/set_area_motion(area/A)
|
||||
area_motion = A
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
toggle_cam(null, FALSE) //kick anyone viewing out
|
||||
QDEL_NULL(assembly)
|
||||
if(istype(bug))
|
||||
@@ -59,10 +66,14 @@
|
||||
QDEL_NULL(wires)
|
||||
GLOB.cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
|
||||
GLOB.cameranet.cameras -= src
|
||||
if(isarea(myArea))
|
||||
LAZYREMOVE(myArea.cameras, UID())
|
||||
var/area/ai_monitored/A = get_area(src)
|
||||
if(istype(A))
|
||||
A.motioncamera = null
|
||||
A.motioncameras -= src
|
||||
area_motion = null
|
||||
cancelCameraAlarm()
|
||||
cancelAlarm()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
@@ -252,7 +263,7 @@
|
||||
if(status && !(flags & NODECONSTRUCT))
|
||||
triggerCameraAlarm()
|
||||
toggle_cam(null, FALSE)
|
||||
wires.CutAll()
|
||||
wires.cut_all()
|
||||
|
||||
/obj/machinery/camera/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
@@ -282,9 +293,16 @@
|
||||
status = !status
|
||||
if(can_use())
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if(isturf(loc))
|
||||
myArea = get_area(src)
|
||||
LAZYADD(myArea.cameras, UID())
|
||||
else
|
||||
myArea = null
|
||||
else
|
||||
set_light(0)
|
||||
GLOB.cameranet.removeCamera(src)
|
||||
if(isarea(myArea))
|
||||
LAZYREMOVE(myArea.cameras, UID())
|
||||
GLOB.cameranet.updateChunk(x, y, z)
|
||||
var/change_msg = "deactivates"
|
||||
if(status)
|
||||
@@ -313,12 +331,12 @@
|
||||
to_chat(O, "The screen bursts into static.")
|
||||
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm()
|
||||
if(is_station_contact(z))
|
||||
SSalarms.camera_alarm.triggerAlarm(loc, src)
|
||||
alarm_on = TRUE
|
||||
SSalarm.triggerAlarm("Camera", get_area(src), list(UID()), src)
|
||||
|
||||
/obj/machinery/camera/proc/cancelCameraAlarm()
|
||||
if(is_station_contact(z))
|
||||
SSalarms.camera_alarm.clearAlarm(loc, src)
|
||||
alarm_on = FALSE
|
||||
SSalarm.cancelAlarm("Camera", get_area(src), src)
|
||||
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
@@ -414,8 +432,8 @@
|
||||
/obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets.
|
||||
var/turf/prev_turf
|
||||
|
||||
/obj/machinery/camera/portable/New()
|
||||
..()
|
||||
/obj/machinery/camera/portable/Initialize(mapload)
|
||||
. = ..()
|
||||
assembly.state = 0 //These cameras are portable, and so shall be in the portable state if removed.
|
||||
assembly.anchored = 0
|
||||
assembly.update_icon()
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/obj/machinery/camera
|
||||
|
||||
var/list/motionTargets = list()
|
||||
var/list/localMotionTargets = list()
|
||||
var/detectTime = 0
|
||||
var/area/ai_monitored/area_motion = null
|
||||
var/alarm_delay = 100
|
||||
|
||||
var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm()
|
||||
|
||||
/obj/machinery/camera/process()
|
||||
// motion camera event loop
|
||||
if(stat & (EMPED|NOPOWER))
|
||||
return
|
||||
if(!isMotion())
|
||||
. = PROCESS_KILL
|
||||
return
|
||||
if(stat & (EMPED|NOPOWER))
|
||||
return
|
||||
if(detectTime > 0)
|
||||
var/elapsed = world.time - detectTime
|
||||
if(elapsed > alarm_delay)
|
||||
triggerAlarm()
|
||||
else if(detectTime == -1)
|
||||
for(var/mob/target in motionTargets)
|
||||
if(target.stat == 2) lostTarget(target)
|
||||
// If not detecting with motion camera...
|
||||
if(!area_motion)
|
||||
// See if the camera is still in range
|
||||
if(!in_range(src, target))
|
||||
// If they aren't in range, lose the target.
|
||||
lostTarget(target)
|
||||
for(var/thing in getTargetList())
|
||||
var/mob/target = locateUID(thing)
|
||||
if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target)))
|
||||
//If not part of a monitored area and the camera is not in range or the target is dead
|
||||
lostTargetRef(thing)
|
||||
|
||||
/obj/machinery/camera/proc/newTarget(var/mob/target)
|
||||
if(istype(target, /mob/living/silicon/ai)) return 0
|
||||
/obj/machinery/camera/proc/getTargetList()
|
||||
if(area_motion)
|
||||
return area_motion.motionTargets
|
||||
return localMotionTargets
|
||||
|
||||
/obj/machinery/camera/proc/newTarget(mob/target)
|
||||
if(isAI(target))
|
||||
return FALSE
|
||||
if(detectTime == 0)
|
||||
detectTime = world.time // start the clock
|
||||
if(!(target in motionTargets))
|
||||
motionTargets += target
|
||||
return 1
|
||||
var/list/targets = getTargetList()
|
||||
targets |= target.UID()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/proc/lostTarget(var/mob/target)
|
||||
if(target in motionTargets)
|
||||
motionTargets -= target
|
||||
if(motionTargets.len == 0)
|
||||
/obj/machinery/camera/proc/lostTargetRef(uid)
|
||||
var/list/targets = getTargetList()
|
||||
targets -= uid
|
||||
if(length(targets))
|
||||
cancelAlarm()
|
||||
|
||||
/obj/machinery/camera/proc/cancelAlarm()
|
||||
if(!status || (stat & NOPOWER))
|
||||
return FALSE
|
||||
if(detectTime == -1 && is_station_contact(z))
|
||||
SSalarms.motion_alarm.clearAlarm(loc, src)
|
||||
if(detectTime == -1)
|
||||
if(status)
|
||||
SSalarm.cancelAlarm("Motion", get_area(src), src)
|
||||
detectTime = 0
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/proc/triggerAlarm()
|
||||
if(!status || (stat & NOPOWER))
|
||||
if(!detectTime)
|
||||
return FALSE
|
||||
if(!detectTime || !is_station_contact(z))
|
||||
return FALSE
|
||||
SSalarms.motion_alarm.triggerAlarm(loc, src)
|
||||
if(status)
|
||||
SSalarm.triggerAlarm("Motion", get_area(src), list(UID()), src)
|
||||
visible_message("<span class='warning'>A red light flashes on the [src]!</span>")
|
||||
detectTime = -1
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// EMP
|
||||
|
||||
/obj/machinery/camera/emp_proof/Initialize()
|
||||
/obj/machinery/camera/emp_proof/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeEmpProof()
|
||||
|
||||
@@ -11,19 +11,23 @@
|
||||
/obj/machinery/camera/xray
|
||||
icon_state = "xraycam" // Thanks to Krutchen for the icons.
|
||||
|
||||
/obj/machinery/camera/xray/Initialize()
|
||||
/obj/machinery/camera/xray/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeXRay()
|
||||
|
||||
// MOTION
|
||||
/obj/machinery/camera/motion
|
||||
name = "motion-sensitive security camera"
|
||||
|
||||
/obj/machinery/camera/motion/Initialize()
|
||||
/obj/machinery/camera/motion/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeMotion()
|
||||
|
||||
// ALL UPGRADES
|
||||
/obj/machinery/camera/all
|
||||
icon_state = "xraycamera" //mapping icon.
|
||||
|
||||
/obj/machinery/camera/all/Initialize()
|
||||
/obj/machinery/camera/all/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeEmpProof()
|
||||
upgradeXRay()
|
||||
@@ -78,6 +82,10 @@
|
||||
|
||||
// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
|
||||
/obj/machinery/camera/proc/upgradeMotion()
|
||||
if(isMotion())
|
||||
return
|
||||
if(name == initial(name))
|
||||
name = "motion-sensitive security camera"
|
||||
assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly))
|
||||
setPowerUsage()
|
||||
// Add it to machines that process
|
||||
|
||||
@@ -1,84 +1,90 @@
|
||||
GLOBAL_LIST_EMPTY(priority_air_alarms)
|
||||
GLOBAL_LIST_EMPTY(minor_air_alarms)
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert
|
||||
name = "atmospheric alert computer"
|
||||
desc = "Used to access the station's atmospheric sensors."
|
||||
circuit = /obj/item/circuitboard/atmos_alert
|
||||
var/ui_x = 350
|
||||
var/ui_y = 300
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
var/list/priority_alarms = list()
|
||||
var/list/minor_alarms = list()
|
||||
var/receive_frequency = ATMOS_FIRE_FREQ
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/computer/atmos_alert/New()
|
||||
..()
|
||||
SSalarms.atmosphere_alarm.register(src, /obj/machinery/computer/station_alert/.proc/update_icon)
|
||||
/obj/machinery/computer/atmos_alert/Initialize(mapload)
|
||||
. = ..()
|
||||
set_frequency(receive_frequency)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Destroy()
|
||||
SSalarms.atmosphere_alarm.unregister(src)
|
||||
return ..()
|
||||
SSradio.remove_object(src, receive_frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/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)
|
||||
/obj/machinery/computer/atmos_alert/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)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500)
|
||||
ui = new(user, src, ui_key, "AtmosAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
var/major_alarms[0]
|
||||
var/minor_alarms[0]
|
||||
/obj/machinery/computer/atmos_alert/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
for(var/datum/alarm/alarm in SSalarms.atmosphere_alarm.major_alarms())
|
||||
major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
for(var/datum/alarm/alarm in SSalarms.atmosphere_alarm.minor_alarms())
|
||||
minor_alarms[++minor_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
data["priority_alarms"] = major_alarms
|
||||
data["minor_alarms"] = minor_alarms
|
||||
data["priority"] = list()
|
||||
for(var/zone in priority_alarms)
|
||||
data["priority"] |= zone
|
||||
data["minor"] = list()
|
||||
for(var/zone in minor_alarms)
|
||||
data["minor"] |= zone
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/atmos_alert/update_icon()
|
||||
var/list/alarms = SSalarms.atmosphere_alarm.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
alarms = SSalarms.atmosphere_alarm.minor_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:1"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Topic(href, href_list)
|
||||
/obj/machinery/computer/atmos_alert/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
switch(action)
|
||||
if("clear")
|
||||
var/zone = params["zone"]
|
||||
if(zone in priority_alarms)
|
||||
to_chat(usr, "<span class='notice'>Priority alarm for [zone] cleared.</span>")
|
||||
priority_alarms -= zone
|
||||
. = TRUE
|
||||
if(zone in minor_alarms)
|
||||
to_chat(usr, "<span class='notice'>Minor alarm for [zone] cleared.</span>")
|
||||
minor_alarms -= zone
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
if(href_list["clear_alarm"])
|
||||
var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in SSalarms.atmosphere_alarm.alarms
|
||||
if(alarm)
|
||||
for(var/datum/alarm_source/alarm_source in alarm.sources)
|
||||
var/obj/machinery/alarm/air_alarm = alarm_source.source
|
||||
if(istype(air_alarm))
|
||||
var/list/new_ref = list("atmos_reset" = 1)
|
||||
air_alarm.Topic(href, new_ref, state = GLOB.air_alarm_topic)
|
||||
update_icon()
|
||||
return 1
|
||||
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, receive_frequency)
|
||||
receive_frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA)
|
||||
|
||||
GLOBAL_DATUM_INIT(air_alarm_topic, /datum/topic_state/air_alarm_topic, new)
|
||||
/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
|
||||
if(!signal)
|
||||
return
|
||||
|
||||
/datum/topic_state/air_alarm_topic/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = 1
|
||||
var/zone = signal.data["zone"]
|
||||
var/severity = signal.data["alert"]
|
||||
|
||||
return extra_href
|
||||
if(!zone || !severity)
|
||||
return
|
||||
|
||||
/datum/topic_state/air_alarm_topic/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_INTERACTIVE
|
||||
minor_alarms -= zone
|
||||
priority_alarms -= zone
|
||||
if(severity == "severe")
|
||||
priority_alarms += zone
|
||||
else if(severity == "minor")
|
||||
minor_alarms += zone
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/update_icon()
|
||||
if(length(priority_alarms))
|
||||
icon_screen = "alert:2"
|
||||
else if(length(minor_alarms))
|
||||
icon_screen = "alert:1"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
..()
|
||||
|
||||
@@ -165,12 +165,9 @@
|
||||
/obj/item/circuitboard/stationalert_engineering
|
||||
name = "Circuit Board (Station Alert Console (Engineering))"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/circuitboard/stationalert_security
|
||||
name = "Circuit Board (Station Alert Console (Security))"
|
||||
/obj/item/circuitboard/stationalert
|
||||
name = "Circuit Board (Station Alert Console)"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/circuitboard/stationalert_all
|
||||
name = "Circuit Board (Station Alert Console (All))"
|
||||
build_path = /obj/machinery/computer/station_alert/all
|
||||
/obj/item/circuitboard/atmos_alert
|
||||
name = "Circuit Board (Atmospheric Alert Computer)"
|
||||
build_path = /obj/machinery/computer/atmos_alert
|
||||
@@ -236,7 +233,10 @@
|
||||
/obj/item/circuitboard/brigcells
|
||||
name = "Circuit board (Brig Cell Control)"
|
||||
build_path = /obj/machinery/computer/brigcells
|
||||
|
||||
/obj/item/circuitboard/sm_monitor
|
||||
name = "Circuit board (Supermatter Monitoring Console)"
|
||||
build_path = /obj/machinery/computer/sm_monitor
|
||||
origin_tech = "programming=2;powerstorage=2"
|
||||
|
||||
// RD console circuits, so that {de,re}constructing one of the special consoles doesn't ruin everything forever
|
||||
/obj/item/circuitboard/rdconsole
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/obj/machinery/computer/sm_monitor
|
||||
name = "supermatter monitoring console"
|
||||
desc = "Used to monitor supermatter shards."
|
||||
icon_keyboard = "power_key"
|
||||
icon_screen = "smmon_0"
|
||||
circuit = /obj/item/circuitboard/sm_monitor
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
/// Cache-list of all supermatter shards
|
||||
var/list/supermatters
|
||||
/// Last status of the active supermatter for caching purposes
|
||||
var/last_status
|
||||
/// Reference to the active shard
|
||||
var/obj/machinery/power/supermatter_shard/active
|
||||
|
||||
/obj/machinery/computer/sm_monitor/Destroy()
|
||||
active = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/sm_monitor/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/sm_monitor/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/sm_monitor/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)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SupermatterMonitor", name, 600, 325, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/sm_monitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(istype(active))
|
||||
var/turf/T = get_turf(active)
|
||||
// If we somehow delam during this proc, handle it somewhat
|
||||
if(!T)
|
||||
active = null
|
||||
refresh()
|
||||
return
|
||||
var/datum/gas_mixture/air = T.return_air()
|
||||
if(!air)
|
||||
active = null
|
||||
return
|
||||
|
||||
data["active"] = TRUE
|
||||
data["SM_integrity"] = active.get_integrity()
|
||||
data["SM_power"] = active.power
|
||||
data["SM_ambienttemp"] = air.temperature
|
||||
data["SM_ambientpressure"] = air.return_pressure()
|
||||
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
|
||||
var/other_moles = air.total_trace_moles()
|
||||
var/TM = air.total_moles()
|
||||
if(TM)
|
||||
data["SM_gas_O2"] = round(100*air.oxygen/TM, 0.01)
|
||||
data["SM_gas_CO2"] = round(100*air.carbon_dioxide/TM, 0.01)
|
||||
data["SM_gas_N2"] = round(100*air.nitrogen/TM, 0.01)
|
||||
data["SM_gas_PL"] = round(100*air.toxins/TM, 0.01)
|
||||
if(other_moles)
|
||||
data["SM_gas_OTHER"] = round(100 * other_moles / TM, 0.01)
|
||||
else
|
||||
data["SM_gas_OTHER"] = 0
|
||||
else
|
||||
data["SM_gas_O2"] = 0
|
||||
data["SM_gas_CO2"] = 0
|
||||
data["SM_gas_N2"] = 0
|
||||
data["SM_gas_PH"] = 0
|
||||
data["SM_gas_OTHER"] = 0
|
||||
else
|
||||
var/list/SMS = list()
|
||||
for(var/I in supermatters)
|
||||
var/obj/machinery/power/supermatter_shard/S = I
|
||||
var/area/A = get_area(S)
|
||||
if(!A)
|
||||
continue
|
||||
|
||||
SMS.Add(list(list(
|
||||
"area_name" = A.name,
|
||||
"integrity" = S.get_integrity(),
|
||||
"uid" = S.UID()
|
||||
)))
|
||||
|
||||
data["active"] = FALSE
|
||||
data["supermatters"] = SMS
|
||||
|
||||
return data
|
||||
|
||||
/**
|
||||
* Supermatter List Refresher
|
||||
*
|
||||
* This proc loops through the list of supermatters in the atmos SS and adds them to this console's cache list
|
||||
*/
|
||||
/obj/machinery/computer/sm_monitor/proc/refresh()
|
||||
supermatters = list()
|
||||
var/turf/T = get_turf(tgui_host()) // Get the TGUI host incase this ever turned into a supermatter monitoring module for AIs to use or something
|
||||
if(!T)
|
||||
return
|
||||
for(var/obj/machinery/power/supermatter_shard/S in SSair.atmos_machinery)
|
||||
// Delaminating, not within coverage, not on a tile.
|
||||
if(!(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T) || !istype(S.loc, /turf/simulated/)))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
|
||||
if(!(active in supermatters))
|
||||
active = null
|
||||
|
||||
/obj/machinery/computer/sm_monitor/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
|
||||
if(active)
|
||||
var/new_status = active.get_status()
|
||||
if(last_status != new_status)
|
||||
last_status = new_status
|
||||
if(last_status == SUPERMATTER_ERROR)
|
||||
last_status = SUPERMATTER_INACTIVE
|
||||
icon_screen = "smmon_[last_status]"
|
||||
update_icon()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/sm_monitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
|
||||
switch(action)
|
||||
if("refresh")
|
||||
refresh()
|
||||
|
||||
if("view")
|
||||
var/newuid = params["view"]
|
||||
for(var/obj/machinery/power/supermatter_shard/S in supermatters)
|
||||
if(S.UID() == newuid)
|
||||
active = S
|
||||
break
|
||||
|
||||
if("back")
|
||||
active = null
|
||||
|
||||
@@ -6,48 +6,91 @@
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
circuit = /obj/item/circuitboard/stationalert_engineering
|
||||
var/datum/nano_module/alarm_monitor/alarm_monitor
|
||||
var/monitor_type = /datum/nano_module/alarm_monitor/engineering
|
||||
var/ui_x = 325
|
||||
var/ui_y = 500
|
||||
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
|
||||
|
||||
/obj/machinery/computer/station_alert/security
|
||||
monitor_type = /datum/nano_module/alarm_monitor/security
|
||||
circuit = /obj/item/circuitboard/stationalert_security
|
||||
|
||||
/obj/machinery/computer/station_alert/all
|
||||
monitor_type = /datum/nano_module/alarm_monitor/all
|
||||
circuit = /obj/item/circuitboard/stationalert_all
|
||||
|
||||
/obj/machinery/computer/station_alert/New()
|
||||
..()
|
||||
alarm_monitor = new monitor_type(src)
|
||||
alarm_monitor.register(src, /obj/machinery/computer/station_alert/.proc/update_icon)
|
||||
/obj/machinery/computer/station_alert/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.alert_consoles += src
|
||||
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered)
|
||||
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled)
|
||||
|
||||
/obj/machinery/computer/station_alert/Destroy()
|
||||
alarm_monitor.unregister(src)
|
||||
QDEL_NULL(alarm_monitor)
|
||||
GLOB.alert_consoles -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/interact(mob/user)
|
||||
alarm_monitor.ui_interact(user)
|
||||
/obj/machinery/computer/station_alert/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)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "StationAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/station_alert/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["alarms"] = list()
|
||||
for(var/class in SSalarm.alarms)
|
||||
if(!(class in alarms_listend_for))
|
||||
continue
|
||||
data["alarms"][class] = list()
|
||||
for(var/area in SSalarm.alarms[class])
|
||||
for(var/thing in SSalarm.alarms[class][area][3])
|
||||
var/atom/A = locateUID(thing)
|
||||
if(atoms_share_level(A, src))
|
||||
data["alarms"][class] += area
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/station_alert/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(alarmsource.z != z)
|
||||
return
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/station_alert/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
|
||||
if(!(class in alarms_listend_for))
|
||||
return
|
||||
if(origin.z != z)
|
||||
return
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/station_alert/update_icon()
|
||||
if(alarm_monitor)
|
||||
var/list/alarms = alarm_monitor.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
var/active_alarms = FALSE
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
if(length(L))
|
||||
active_alarms = TRUE
|
||||
if(active_alarms)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
|
||||
..()
|
||||
|
||||
@@ -142,6 +142,7 @@ About the new airlock wires panel:
|
||||
break
|
||||
|
||||
/obj/machinery/door/airlock/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(electronics)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(note)
|
||||
@@ -188,10 +189,6 @@ About the new airlock wires panel:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/door/airlock/proc/isWireCut(wireIndex)
|
||||
// You can find the wires in the datum folder.
|
||||
return wires.IsIndexCut(wireIndex)
|
||||
|
||||
/obj/machinery/door/airlock/proc/canAIControl()
|
||||
return ((aiControlDisabled!=1) && (!isAllPowerLoss()))
|
||||
|
||||
@@ -204,27 +201,21 @@ About the new airlock wires panel:
|
||||
return (main_power_lost_until==0 || backup_power_lost_until==0)
|
||||
|
||||
/obj/machinery/door/airlock/requiresID()
|
||||
return !(isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner)
|
||||
return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner)
|
||||
|
||||
/obj/machinery/door/airlock/proc/isAllPowerLoss()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 1
|
||||
if(mainPowerCablesCut() && backupPowerCablesCut())
|
||||
if(wires.is_cut(WIRE_MAIN_POWER1) && wires.is_cut(WIRE_BACKUP_POWER1))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/door/airlock/proc/mainPowerCablesCut()
|
||||
return isWireCut(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
|
||||
/obj/machinery/door/airlock/proc/backupPowerCablesCut()
|
||||
return isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
|
||||
/obj/machinery/door/airlock/proc/loseMainPower()
|
||||
main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + 60 SECONDS
|
||||
main_power_lost_until = wires.is_cut(WIRE_MAIN_POWER1) ? -1 : world.time + 60 SECONDS
|
||||
if(main_power_lost_until > 0)
|
||||
main_power_timer = addtimer(CALLBACK(src, .proc/regainMainPower), 60 SECONDS, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
// If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running
|
||||
if(backup_power_lost_until == -1 && !backupPowerCablesCut())
|
||||
if(backup_power_lost_until == -1 && !wires.is_cut(WIRE_BACKUP_POWER1))
|
||||
backup_power_lost_until = world.time + 10 SECONDS
|
||||
backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), 10 SECONDS, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
// Disable electricity if required
|
||||
@@ -232,7 +223,7 @@ About the new airlock wires panel:
|
||||
electrify(0)
|
||||
|
||||
/obj/machinery/door/airlock/proc/loseBackupPower()
|
||||
backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + 60 SECONDS
|
||||
backup_power_lost_until = wires.is_cut(WIRE_BACKUP_POWER1) ? -1 : world.time + 60 SECONDS
|
||||
if(backup_power_lost_until > 0)
|
||||
backup_power_timer = addtimer(CALLBACK(src, .proc/regainBackupPower), 60 SECONDS, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
|
||||
@@ -243,7 +234,7 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/proc/regainMainPower()
|
||||
main_power_timer = null
|
||||
|
||||
if(!mainPowerCablesCut())
|
||||
if(!wires.is_cut(WIRE_MAIN_POWER1))
|
||||
main_power_lost_until = 0
|
||||
// If backup power is currently active then disable, otherwise let it count down and disable itself later
|
||||
if(!backup_power_lost_until)
|
||||
@@ -253,7 +244,7 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/proc/regainBackupPower()
|
||||
backup_power_timer = null
|
||||
|
||||
if(!backupPowerCablesCut())
|
||||
if(!wires.is_cut(WIRE_BACKUP_POWER1))
|
||||
// Restore backup power only if main power is offline, otherwise permanently disable
|
||||
backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0
|
||||
update_icon()
|
||||
@@ -264,7 +255,7 @@ About the new airlock wires panel:
|
||||
electrified_timer = null
|
||||
|
||||
var/message = ""
|
||||
if(isWireCut(AIRLOCK_WIRE_ELECTRIFY) && arePowerSystemsOn())
|
||||
if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn())
|
||||
message = text("The electrification wire is cut - Door permanently electrified.")
|
||||
electrified_until = -1
|
||||
else if(duration && !arePowerSystemsOn())
|
||||
@@ -763,7 +754,7 @@ About the new airlock wires panel:
|
||||
var/activate = text2num(href_list["activate"])
|
||||
switch(href_list["command"])
|
||||
if("idscan")
|
||||
if(isWireCut(AIRLOCK_WIRE_IDSCAN))
|
||||
if(wires.is_cut(WIRE_IDSCAN))
|
||||
to_chat(usr, "The IdScan wire has been cut - IdScan feature permanently disabled.")
|
||||
else if(activate && aiDisabledIdScanner)
|
||||
aiDisabledIdScanner = 0
|
||||
@@ -780,14 +771,14 @@ About the new airlock wires panel:
|
||||
loseBackupPower()
|
||||
update_icon()
|
||||
if("bolts")
|
||||
if(isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
|
||||
if(wires.is_cut(WIRE_DOOR_BOLTS))
|
||||
to_chat(usr, "The door bolt control wire has been cut - Door bolts permanently dropped.")
|
||||
else if(activate && lock())
|
||||
to_chat(usr, "The door bolts have been dropped.")
|
||||
else if(!activate && unlock())
|
||||
to_chat(usr, "The door bolts have been raised.")
|
||||
if("electrify_temporary")
|
||||
if(activate && isWireCut(AIRLOCK_WIRE_ELECTRIFY))
|
||||
if(activate && wires.is_cut(WIRE_ELECTRIFY))
|
||||
to_chat(usr, text("The electrification wire is cut - Door permanently electrified."))
|
||||
else if(!activate && electrified_until != 0)
|
||||
to_chat(usr, "The door is now un-electrified.")
|
||||
@@ -799,7 +790,7 @@ About the new airlock wires panel:
|
||||
to_chat(usr, "The door is now electrified for thirty seconds.")
|
||||
electrify(30)
|
||||
if("electrify_permanently")
|
||||
if(isWireCut(AIRLOCK_WIRE_ELECTRIFY))
|
||||
if(wires.is_cut(WIRE_ELECTRIFY))
|
||||
to_chat(usr, text("The electrification wire is cut - Cannot electrify the door."))
|
||||
else if(!activate && electrified_until != 0)
|
||||
to_chat(usr, "The door is now un-electrified.")
|
||||
@@ -821,7 +812,7 @@ About the new airlock wires panel:
|
||||
close()
|
||||
if("safeties")
|
||||
// Safeties! We don't need no stinking safeties!
|
||||
if(isWireCut(AIRLOCK_WIRE_SAFETY))
|
||||
if(wires.is_cut(WIRE_SAFETY))
|
||||
to_chat(usr, text("The safety wire is cut - Cannot secure the door."))
|
||||
else if(activate && safe)
|
||||
safe = 0
|
||||
@@ -829,7 +820,7 @@ About the new airlock wires panel:
|
||||
safe = 1
|
||||
if("timing")
|
||||
// Door speed control
|
||||
if(isWireCut(AIRLOCK_WIRE_SPEED))
|
||||
if(wires.is_cut(WIRE_SPEED))
|
||||
to_chat(usr, text("The timing wire is cut - Cannot alter timing."))
|
||||
else if(activate && normalspeed)
|
||||
normalspeed = 0
|
||||
@@ -837,7 +828,7 @@ About the new airlock wires panel:
|
||||
normalspeed = 1
|
||||
if("lights")
|
||||
// Bolt lights
|
||||
if(isWireCut(AIRLOCK_WIRE_LIGHT))
|
||||
if(wires.is_cut(WIRE_BOLT_LIGHT))
|
||||
to_chat(usr, "The bolt lights wire has been cut - The door bolt lights are permanently disabled.")
|
||||
else if(!activate && lights)
|
||||
lights = 0
|
||||
@@ -1126,7 +1117,7 @@ About the new airlock wires panel:
|
||||
if(operating || welded || locked || emagged)
|
||||
return 0
|
||||
if(!forced)
|
||||
if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
|
||||
if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR))
|
||||
return 0
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
if(forced)
|
||||
@@ -1163,7 +1154,7 @@ About the new airlock wires panel:
|
||||
if(!forced)
|
||||
//despite the name, this wire is for general door control.
|
||||
//Bolts are already covered by the check for locked, above
|
||||
if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
|
||||
if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR))
|
||||
return
|
||||
if(safe)
|
||||
for(var/turf/turf in locs)
|
||||
@@ -1219,7 +1210,7 @@ About the new airlock wires panel:
|
||||
return
|
||||
|
||||
if(!forced)
|
||||
if(operating || !arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
|
||||
if(operating || !arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS))
|
||||
return
|
||||
|
||||
locked = 0
|
||||
@@ -1314,7 +1305,7 @@ About the new airlock wires panel:
|
||||
stat |= BROKEN
|
||||
if(!panel_open)
|
||||
panel_open = TRUE
|
||||
wires.CutAll()
|
||||
wires.cut_all()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/airlock/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
@@ -1407,6 +1398,12 @@ About the new airlock wires panel:
|
||||
A.name = name
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/door/airlock/proc/ai_control_callback()
|
||||
if(aiControlDisabled == 1)
|
||||
aiControlDisabled = 0
|
||||
else if(aiControlDisabled == 2)
|
||||
aiControlDisabled = -1
|
||||
|
||||
#undef AIRLOCK_CLOSED
|
||||
#undef AIRLOCK_CLOSING
|
||||
#undef AIRLOCK_OPEN
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
var/nextstate = null
|
||||
var/boltslocked = TRUE
|
||||
var/active_alarm = FALSE
|
||||
var/list/affecting_areas
|
||||
|
||||
/obj/machinery/door/firedoor/Initialize(mapload)
|
||||
. = ..()
|
||||
CalculateAffectingAreas()
|
||||
|
||||
/obj/machinery/door/firedoor/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -40,11 +45,31 @@
|
||||
else
|
||||
. += "<span class='notice'>The bolt locks have been <i>unscrewed</i>, but the bolts themselves are still <b>wrenched</b> to the floor.</span>"
|
||||
|
||||
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
|
||||
remove_from_areas()
|
||||
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYADD(A.firedoors, src)
|
||||
|
||||
/obj/machinery/door/firedoor/closed
|
||||
icon_state = "door_closed"
|
||||
opacity = TRUE
|
||||
density = TRUE
|
||||
|
||||
//see also turf/AfterChange for adjacency shennanigans
|
||||
|
||||
/obj/machinery/door/firedoor/proc/remove_from_areas()
|
||||
if(affecting_areas)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYREMOVE(A.firedoors, src)
|
||||
|
||||
/obj/machinery/door/firedoor/Destroy()
|
||||
remove_from_areas()
|
||||
affecting_areas.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/Bumped(atom/AM)
|
||||
if(panel_open || operating)
|
||||
return
|
||||
|
||||
@@ -25,6 +25,11 @@ FIRE ALARM
|
||||
active_power_usage = 6
|
||||
power_channel = ENVIRON
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
light_power = 0
|
||||
light_range = 7
|
||||
light_color = "#ff3232"
|
||||
|
||||
var/last_process = 0
|
||||
var/wiresexposed = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
@@ -191,6 +196,7 @@ FIRE ALARM
|
||||
/obj/machinery/firealarm/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT) && buildstage != 0) //can't break the electronics if there isn't any inside.
|
||||
stat |= BROKEN
|
||||
LAZYREMOVE(myArea.firealarms, src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/deconstruct(disassembled = TRUE)
|
||||
@@ -203,6 +209,14 @@ FIRE ALARM
|
||||
new /obj/item/stack/cable_coil(loc, 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/firealarm/proc/update_fire_light(fire)
|
||||
if(fire == !!light_power)
|
||||
return // do nothing if we're already active
|
||||
if(fire)
|
||||
set_light(l_power = 0.8)
|
||||
else
|
||||
set_light(l_power = 0)
|
||||
|
||||
/obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
@@ -286,26 +300,16 @@ FIRE ALARM
|
||||
time = min(max(round(time), 0), 120)
|
||||
|
||||
/obj/machinery/firealarm/proc/reset()
|
||||
if(!working)
|
||||
if(!working || !report_fire_alarms)
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
A.fire_reset()
|
||||
A.firereset(src)
|
||||
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
if(is_station_contact(z) && FA.report_fire_alarms)
|
||||
SSalarms.fire_alarm.clearAlarm(loc, FA)
|
||||
|
||||
/obj/machinery/firealarm/proc/alarm(var/duration = 0)
|
||||
if(!working)
|
||||
/obj/machinery/firealarm/proc/alarm()
|
||||
if(!working || !report_fire_alarms)
|
||||
return
|
||||
|
||||
var/area/A = get_area(src)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
if(is_station_contact(z) && FA.report_fire_alarms)
|
||||
SSalarms.fire_alarm.triggerAlarm(loc, FA, duration)
|
||||
else
|
||||
A.fire_alert() // Manually trigger alarms if the alarm isn't reported
|
||||
|
||||
A.firealert(src) // Manually trigger alarms if the alarm isn't reported
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/New(location, direction, building)
|
||||
@@ -323,8 +327,14 @@ FIRE ALARM
|
||||
else
|
||||
overlays += image('icons/obj/monitors.dmi', "overlay_green")
|
||||
|
||||
myArea = get_area(src)
|
||||
LAZYADD(myArea.firealarms, src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/Destroy()
|
||||
LAZYREMOVE(myArea.firealarms, src)
|
||||
return ..()
|
||||
|
||||
/*
|
||||
FIRE ALARM CIRCUIT
|
||||
Just a object used in constructing fire alarms
|
||||
|
||||
@@ -12,29 +12,26 @@
|
||||
var/resultlvl = null
|
||||
|
||||
/obj/machinery/slot_machine/attack_hand(mob/user as mob)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/slot_machine/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SlotMachine", name, 350, 200, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/slot_machine/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
// Get account
|
||||
account = user.get_worn_id_account()
|
||||
if(!account)
|
||||
if(istype(user.get_active_hand(), /obj/item/card/id))
|
||||
account = get_card_account(user.get_active_hand())
|
||||
else
|
||||
account = null
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/slot_machine/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
default_unfasten_wrench(user, I)
|
||||
|
||||
/obj/machinery/slot_machine/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, "slotmachine.tmpl", name, 350, 200)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/slot_machine/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
// Send data
|
||||
data["working"] = working
|
||||
data["money"] = account ? account.money : null
|
||||
data["plays"] = plays
|
||||
@@ -42,22 +39,23 @@
|
||||
data["resultlvl"] = resultlvl
|
||||
return data
|
||||
|
||||
/obj/machinery/slot_machine/Topic(href, href_list)
|
||||
/obj/machinery/slot_machine/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["ops"])
|
||||
if(text2num(href_list["ops"])) // Play
|
||||
if(working)
|
||||
return
|
||||
if(!account || account.money < 10)
|
||||
return
|
||||
if(!account.charge(10, null, "Bet", "Slot Machine", "Slot Machine"))
|
||||
return
|
||||
plays++
|
||||
working = 1
|
||||
icon_state = "slots-on"
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
addtimer(CALLBACK(src, .proc/spin_slots, usr.name), 25)
|
||||
if(action == "spin")
|
||||
if(working)
|
||||
return
|
||||
if(!account || account.money < 10)
|
||||
return
|
||||
if(!account.charge(10, null, "Bet", "Slot Machine", "Slot Machine"))
|
||||
return
|
||||
plays++
|
||||
working = TRUE
|
||||
icon_state = "slots-on"
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
addtimer(CALLBACK(src, .proc/spin_slots, usr.name), 25)
|
||||
|
||||
/obj/machinery/slot_machine/proc/spin_slots(userName)
|
||||
switch(rand(1,4050))
|
||||
@@ -65,44 +63,45 @@
|
||||
atom_say("JACKPOT! [userName] has won a MILLION CREDITS!")
|
||||
GLOB.event_announcement.Announce("Congratulations to [userName] on winning the Jackpot of ONE MILLION CREDITS!", "Jackpot Winner")
|
||||
result = "JACKPOT! You win one million credits!"
|
||||
resultlvl = "highlight"
|
||||
resultlvl = "teal"
|
||||
win_money(1000000, 'sound/goonstation/misc/airraid_loop.ogg')
|
||||
if(2 to 5) // .07%
|
||||
atom_say("Big Winner! [userName] has won a hundred thousand credits!")
|
||||
GLOB.event_announcement.Announce("Congratulations to [userName] on winning a hundred thousand credits!", "Big Winner")
|
||||
result = "Big Winner! You win a hundred thousand credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(100000, 'sound/goonstation/misc/klaxon.ogg')
|
||||
if(6 to 50) // 1.08%
|
||||
atom_say("Big Winner! [userName] has won ten thousand credits!")
|
||||
result = "You win ten thousand credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(10000, 'sound/goonstation/misc/klaxon.ogg')
|
||||
if(51 to 100) // 1.21%
|
||||
atom_say("Winner! [userName] has won a thousand credits!")
|
||||
result = "You win a thousand credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(1000, 'sound/goonstation/misc/bell.ogg')
|
||||
if(101 to 200) // 2.44%
|
||||
atom_say("Winner! [userName] has won a hundred credits!")
|
||||
result = "You win a hundred credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(100, 'sound/goonstation/misc/bell.ogg')
|
||||
if(201 to 300) // 2.44%
|
||||
atom_say("Winner! [userName] has won fifty credits!")
|
||||
result = "You win fifty credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(50)
|
||||
if(301 to 1000) // 17.26%
|
||||
atom_say("Winner! [userName] has won ten credits!")
|
||||
result = "You win ten credits!"
|
||||
resultlvl = "good"
|
||||
resultlvl = "green"
|
||||
win_money(10)
|
||||
else // 75.31%
|
||||
result = "<span class='warning'>No luck!</span>"
|
||||
resultlvl = "average"
|
||||
working = 0
|
||||
result = "No luck!"
|
||||
resultlvl = "orange"
|
||||
working = FALSE
|
||||
icon_state = "slots-off"
|
||||
SStgui.update_uis(src) // Push a UI update
|
||||
|
||||
/obj/machinery/slot_machine/proc/win_money(amt, sound='sound/machines/ping.ogg')
|
||||
if(sound)
|
||||
@@ -110,3 +109,9 @@
|
||||
if(!account)
|
||||
return
|
||||
account.credit(amt, "Slot Winnings", "Slot Machine", account.owner_name)
|
||||
|
||||
/obj/machinery/slot_machine/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
default_unfasten_wrench(user, I)
|
||||
|
||||
@@ -255,6 +255,7 @@
|
||||
occupant_typecache = typecacheof(occupant_typecache)
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(suit)
|
||||
QDEL_NULL(helmet)
|
||||
QDEL_NULL(mask)
|
||||
@@ -802,3 +803,7 @@
|
||||
|
||||
/obj/machinery/suit_storage_unit/attack_ai(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/check_electrified_callback()
|
||||
if(!wires.is_cut(WIRE_ELECTRIFY))
|
||||
shocked = FALSE
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/syndicatebomb/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(countdown)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
@@ -174,7 +175,7 @@
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(open_panel && wires.IsAllCut())
|
||||
if(open_panel && wires.is_all_cut())
|
||||
if(payload)
|
||||
to_chat(user, "<span class='notice'>You carefully pry out [payload].</span>")
|
||||
payload.loc = user.loc
|
||||
@@ -188,7 +189,7 @@
|
||||
|
||||
/obj/machinery/syndicatebomb/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(payload || !wires.IsAllCut() || !open_panel)
|
||||
if(payload || !wires.is_all_cut() || !open_panel)
|
||||
return
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
@@ -264,9 +265,6 @@
|
||||
investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB)
|
||||
payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!"
|
||||
|
||||
/obj/machinery/syndicatebomb/proc/isWireCut(var/index)
|
||||
return wires.IsIndexCut(index)
|
||||
|
||||
///Bomb Subtypes///
|
||||
|
||||
/obj/machinery/syndicatebomb/training
|
||||
@@ -297,7 +295,7 @@
|
||||
|
||||
/obj/machinery/syndicatebomb/empty/New()
|
||||
..()
|
||||
wires.CutAll()
|
||||
wires.cut_all()
|
||||
|
||||
/obj/machinery/syndicatebomb/self_destruct
|
||||
name = "self destruct device"
|
||||
@@ -368,7 +366,7 @@
|
||||
var/obj/machinery/syndicatebomb/holder = loc
|
||||
if(istype(holder))
|
||||
if(holder.wires)
|
||||
holder.wires.Shuffle()
|
||||
holder.wires.shuffle_wires()
|
||||
holder.defused = 0
|
||||
holder.open_panel = 0
|
||||
holder.delayedbig = FALSE
|
||||
|
||||
+102
-133
@@ -6,17 +6,45 @@
|
||||
layer = MOB_LAYER+1 // Overhead
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/transform_dead = 0
|
||||
var/transform_standing = 0
|
||||
var/cooldown_duration = 600 // 1 minute
|
||||
var/cooldown = 0
|
||||
var/robot_cell_charge = 5000
|
||||
/// TRUE if the factory can transform dead mobs.
|
||||
var/transform_dead = TRUE
|
||||
/// TRUE if the mob can be standing and still be transformed.
|
||||
var/transform_standing = TRUE
|
||||
/// Cooldown between each transformation, in deciseconds.
|
||||
var/cooldown_duration = 1 MINUTES
|
||||
/// If the factory is currently on cooldown from its last transformation.
|
||||
var/is_on_cooldown = FALSE
|
||||
/// The type of cell that newly created borgs get.
|
||||
var/robot_cell_type = /obj/item/stock_parts/cell/high/plus
|
||||
/// The direction that mobs must moving in to get transformed.
|
||||
var/acceptdir = EAST
|
||||
/// The AI who placed this factory.
|
||||
var/mob/living/silicon/ai/masterAI
|
||||
|
||||
/obj/machinery/transformer/New()
|
||||
// On us
|
||||
..()
|
||||
new /obj/machinery/conveyor/auto(loc, WEST)
|
||||
/obj/machinery/transformer/Initialize(mapload, mob/living/silicon/ai/_ai = null)
|
||||
. = ..()
|
||||
if(_ai)
|
||||
masterAI = _ai
|
||||
initialize_belts()
|
||||
|
||||
/// Used to create all of the belts the transformer will be using. All belts should be pushing `WEST`.
|
||||
/obj/machinery/transformer/proc/initialize_belts()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
|
||||
// Belt under the factory.
|
||||
new /obj/machinery/conveyor/auto(T, WEST)
|
||||
|
||||
// Get the turf 1 tile to the EAST.
|
||||
var/turf/east = locate(T.x + 1, T.y, T.z)
|
||||
if(istype(east, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(east, WEST)
|
||||
|
||||
// Get the turf 1 tile to the WEST.
|
||||
var/turf/west = locate(T.x - 1, T.y, T.z)
|
||||
if(istype(west, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(west, WEST)
|
||||
|
||||
/obj/machinery/transformer/power_change()
|
||||
..()
|
||||
@@ -24,7 +52,7 @@
|
||||
|
||||
/obj/machinery/transformer/update_icon()
|
||||
..()
|
||||
if(stat & (BROKEN|NOPOWER) || cooldown == 1)
|
||||
if(is_on_cooldown || stat & (BROKEN|NOPOWER))
|
||||
icon_state = "separator-AO0"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
@@ -35,120 +63,76 @@
|
||||
C.setDir(newdir)
|
||||
acceptdir = turn(newdir, 180)
|
||||
|
||||
/obj/machinery/transformer/Bumped(var/atom/movable/AM)
|
||||
/// Resets `is_on_cooldown` to `FALSE` and updates our icon. Used in a callback after the transformer does a transformation.
|
||||
/obj/machinery/transformer/proc/reset_cooldown()
|
||||
is_on_cooldown = FALSE
|
||||
update_icon()
|
||||
|
||||
if(cooldown == 1)
|
||||
/obj/machinery/transformer/Bumped(atom/movable/AM)
|
||||
// They have to be human to be transformed.
|
||||
if(is_on_cooldown || !ishuman(AM))
|
||||
return
|
||||
|
||||
// Crossed didn't like people lying down.
|
||||
if(ishuman(AM))
|
||||
// Only humans can enter from the west side, while lying down.
|
||||
var/move_dir = get_dir(loc, AM.loc)
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if((transform_standing || H.lying) && move_dir == acceptdir)// || move_dir == WEST)
|
||||
AM.loc = src.loc
|
||||
do_transform(AM)
|
||||
var/mob/living/carbon/human/H = AM
|
||||
var/move_dir = get_dir(loc, H.loc)
|
||||
|
||||
/obj/machinery/transformer/proc/do_transform(var/mob/living/carbon/human/H)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(cooldown == 1)
|
||||
if((transform_standing || H.lying) && move_dir == acceptdir)
|
||||
H.forceMove(drop_location())
|
||||
do_transform(H)
|
||||
|
||||
/// Transforms a human mob into a cyborg, connects them to the malf AI which placed the factory.
|
||||
/obj/machinery/transformer/proc/do_transform(mob/living/carbon/human/H)
|
||||
if(is_on_cooldown || stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
if(!transform_dead && H.stat == DEAD)
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
|
||||
H.emote("scream") // It is painful
|
||||
H.adjustBruteLoss(max(0, 80 - H.getBruteLoss())) // Hurt the human, don't try to kill them though.
|
||||
|
||||
// Sleep for a couple of ticks to allow the human to see the pain
|
||||
sleep(5)
|
||||
|
||||
playsound(loc, 'sound/items/welder.ogg', 50, 1)
|
||||
use_power(5000) // Use a lot of power.
|
||||
var/mob/living/silicon/robot/R = H.Robotize(1) // Delete the items or they'll all pile up in a single tile and lag
|
||||
|
||||
R.cell.maxcharge = robot_cell_charge
|
||||
R.cell.charge = robot_cell_charge
|
||||
|
||||
// So he can't jump out the gate right away.
|
||||
R.lockcharge = !R.lockcharge
|
||||
spawn(50)
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
sleep(30)
|
||||
if(R)
|
||||
R.lockcharge = !R.lockcharge
|
||||
R.notify_ai(1)
|
||||
|
||||
// Activate the cooldown
|
||||
cooldown = 1
|
||||
is_on_cooldown = TRUE
|
||||
update_icon()
|
||||
spawn(cooldown_duration)
|
||||
cooldown = 0
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/transformer/conveyor/New()
|
||||
..()
|
||||
var/turf/T = loc
|
||||
if(T)
|
||||
// Spawn Conveyour Belts
|
||||
|
||||
//East
|
||||
var/turf/east = locate(T.x + 1, T.y, T.z)
|
||||
if(istype(east, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(east, WEST)
|
||||
|
||||
// West
|
||||
var/turf/west = locate(T.x - 1, T.y, T.z)
|
||||
if(istype(west, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(west, WEST)
|
||||
addtimer(CALLBACK(src, .proc/reset_cooldown), cooldown_duration)
|
||||
addtimer(CALLBACK(null, .proc/playsound, loc, 'sound/machines/ping.ogg', 50, 0), 3 SECONDS)
|
||||
|
||||
H.emote("scream")
|
||||
if(!masterAI) // If the factory was placed via admin spawning or other means, it wont have an owner_AI.
|
||||
H.Robotize(robot_cell_type)
|
||||
return
|
||||
|
||||
var/mob/living/silicon/robot/R = H.Robotize(robot_cell_type, FALSE, masterAI)
|
||||
if(R.mind && !R.client && !R.grab_ghost()) // Make sure this is an actual player first and not just a humanized monkey or something.
|
||||
message_admins("[key_name_admin(R)] was just transformed by a borg factory, but they were SSD. Polling ghosts for a replacement.")
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a malfunctioning cyborg?", ROLE_TRAITOR, poll_time = 15 SECONDS)
|
||||
if(!length(candidates))
|
||||
return
|
||||
var/mob/dead/observer/O = pick(candidates)
|
||||
R.key= O.key
|
||||
|
||||
/obj/machinery/transformer/mime
|
||||
name = "Mimetech Greyscaler"
|
||||
desc = "Turns anything placed inside black and white."
|
||||
|
||||
|
||||
/obj/machinery/transformer/mime/conveyor/New()
|
||||
..()
|
||||
var/turf/T = loc
|
||||
if(T)
|
||||
// Spawn Conveyour Belts
|
||||
|
||||
//East
|
||||
var/turf/east = locate(T.x + 1, T.y, T.z)
|
||||
if(istype(east, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(east, WEST)
|
||||
|
||||
// West
|
||||
var/turf/west = locate(T.x - 1, T.y, T.z)
|
||||
if(istype(west, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(west, WEST)
|
||||
|
||||
/obj/machinery/transformer/mime/Bumped(var/atom/movable/AM)
|
||||
|
||||
if(cooldown == 1)
|
||||
/obj/machinery/transformer/mime/Bumped(atom/movable/AM)
|
||||
if(is_on_cooldown)
|
||||
return
|
||||
|
||||
// Crossed didn't like people lying down.
|
||||
if(isatom(AM))
|
||||
AM.loc = src.loc
|
||||
if(istype(AM))
|
||||
AM.forceMove(drop_location())
|
||||
do_transform_mime(AM)
|
||||
else
|
||||
to_chat(AM, "Only items can be greyscaled.")
|
||||
return
|
||||
|
||||
/obj/machinery/transformer/proc/do_transform_mime(var/obj/item/I)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(cooldown == 1)
|
||||
/obj/machinery/transformer/proc/do_transform_mime(obj/item/I)
|
||||
if(is_on_cooldown || stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
|
||||
// Sleep for a couple of ticks to allow the human to see the pain
|
||||
sleep(5)
|
||||
playsound(loc, 'sound/items/welder.ogg', 50, 1)
|
||||
use_power(5000) // Use a lot of power.
|
||||
|
||||
var/icon/newicon = new(I.icon, I.icon_state)
|
||||
@@ -156,42 +140,27 @@
|
||||
I.icon = newicon
|
||||
|
||||
// Activate the cooldown
|
||||
cooldown = 1
|
||||
is_on_cooldown = TRUE
|
||||
update_icon()
|
||||
spawn(cooldown_duration)
|
||||
cooldown = 0
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, .proc/reset_cooldown), cooldown_duration)
|
||||
|
||||
/obj/machinery/transformer/xray
|
||||
name = "Automatic X-Ray 5000"
|
||||
desc = "A large metalic machine with an entrance and an exit. A sign on the side reads, 'backpack go in, backpack come out', 'human go in, irradiated human come out'."
|
||||
acceptdir = WEST
|
||||
|
||||
/obj/machinery/transformer/xray/Initialize(mapload)
|
||||
. = ..()
|
||||
// On us
|
||||
new /obj/machinery/conveyor/auto(loc, EAST)
|
||||
|
||||
/obj/machinery/transformer/xray/conveyor/New()
|
||||
..()
|
||||
var/turf/T = loc
|
||||
/obj/machinery/transformer/xray/initialize_belts()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
// Spawn Conveyour Belts
|
||||
// This handles the belt under the transformer and 1 tile to the left and right.
|
||||
. = ..()
|
||||
|
||||
//East
|
||||
var/turf/east = locate(T.x + 1, T.y, T.z)
|
||||
if(istype(east, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(east, EAST)
|
||||
//East2
|
||||
// Get the turf 2 tiles to the EAST.
|
||||
var/turf/east2 = locate(T.x + 2, T.y, T.z)
|
||||
if(istype(east2, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(east2, EAST)
|
||||
|
||||
// West
|
||||
var/turf/west = locate(T.x - 1, T.y, T.z)
|
||||
if(istype(west, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(west, EAST)
|
||||
|
||||
// West2
|
||||
// Get the turf 2 tiles to the WEST.
|
||||
var/turf/west2 = locate(T.x - 2, T.y, T.z)
|
||||
if(istype(west2, /turf/simulated/floor))
|
||||
new /obj/machinery/conveyor/auto(west2, EAST)
|
||||
@@ -207,30 +176,30 @@
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/transformer/xray/Bumped(var/atom/movable/AM)
|
||||
|
||||
if(cooldown == 1)
|
||||
/obj/machinery/transformer/xray/Bumped(atom/movable/AM)
|
||||
if(is_on_cooldown)
|
||||
return
|
||||
|
||||
// Crossed didn't like people lying down.
|
||||
if(ishuman(AM))
|
||||
// Only humans can enter from the west side, while lying down.
|
||||
var/move_dir = get_dir(loc, AM.loc)
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(H.lying && move_dir == WEST)// || move_dir == WEST)
|
||||
AM.loc = src.loc
|
||||
irradiate(AM)
|
||||
var/move_dir = get_dir(loc, H.loc)
|
||||
|
||||
else if(isatom(AM))
|
||||
AM.loc = src.loc
|
||||
if(H.lying && move_dir == acceptdir)
|
||||
H.forceMove(drop_location())
|
||||
irradiate(H)
|
||||
|
||||
else if(istype(AM))
|
||||
AM.forceMove(drop_location())
|
||||
scan(AM)
|
||||
|
||||
/obj/machinery/transformer/xray/proc/irradiate(var/mob/living/carbon/human/H)
|
||||
/obj/machinery/transformer/xray/proc/irradiate(mob/living/carbon/human/H)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
flick("separator-AO0",src)
|
||||
playsound(src.loc, 'sound/effects/alert.ogg', 50, 0)
|
||||
playsound(loc, 'sound/effects/alert.ogg', 50, 0)
|
||||
sleep(5)
|
||||
H.apply_effect((rand(150,200)),IRRADIATE,0)
|
||||
if(prob(5))
|
||||
@@ -242,15 +211,15 @@
|
||||
domutcheck(H,null,1)
|
||||
|
||||
|
||||
/obj/machinery/transformer/xray/proc/scan(var/obj/item/I)
|
||||
/obj/machinery/transformer/xray/proc/scan(obj/item/I)
|
||||
if(scan_rec(I))
|
||||
playsound(src.loc, 'sound/effects/alert.ogg', 50, 0)
|
||||
playsound(loc, 'sound/effects/alert.ogg', 50, 0)
|
||||
flick("separator-AO0",src)
|
||||
else
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
sleep(30)
|
||||
|
||||
/obj/machinery/transformer/xray/proc/scan_rec(var/obj/item/I)
|
||||
/obj/machinery/transformer/xray/proc/scan_rec(obj/item/I)
|
||||
if(istype(I, /obj/item/gun))
|
||||
return TRUE
|
||||
if(istype(I, /obj/item/transfer_valve))
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
power_change()
|
||||
|
||||
/obj/machinery/vending/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(coin)
|
||||
QDEL_NULL(inserted_item)
|
||||
@@ -1371,7 +1372,6 @@
|
||||
/obj/item/clothing/glasses/gglasses = 1,
|
||||
/obj/item/clothing/shoes/jackboots = 1,
|
||||
/obj/item/clothing/under/schoolgirl = 1,
|
||||
/obj/item/clothing/head/kitty = 1,
|
||||
/obj/item/clothing/under/blackskirt = 1,
|
||||
/obj/item/clothing/suit/toggle/owlwings = 1,
|
||||
/obj/item/clothing/under/owl = 1,
|
||||
|
||||
@@ -331,6 +331,8 @@
|
||||
else
|
||||
occupant.clear_alert("mechaport")
|
||||
if(leg_overload_mode)
|
||||
log_message("Leg Overload damage.")
|
||||
take_damage(1, BRUTE, FALSE, FALSE)
|
||||
if(obj_integrity < max_integrity - max_integrity / 3)
|
||||
leg_overload_mode = FALSE
|
||||
step_in = initial(step_in)
|
||||
@@ -502,7 +504,7 @@
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
else
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT))
|
||||
if(. >= 5 || prob(33))
|
||||
if((. >= 5 || prob(33)) && !(. == 1 && leg_overload_mode)) //If it takes 1 damage and leg_overload_mode is true, do not say TAKING DAMAGE! to the user several times a second.
|
||||
occupant_message("<span class='userdanger'>Taking damage!</span>")
|
||||
log_message("Took [damage_amount] points of damage. Damage type: [damage_type]")
|
||||
|
||||
|
||||
@@ -221,6 +221,12 @@
|
||||
A.contents += thing
|
||||
thing.change_area(old_area, A)
|
||||
|
||||
var/area/oldA = get_area(get_turf(usr))
|
||||
var/list/firedoors = oldA.firedoors
|
||||
for(var/door in firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = door
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
interact()
|
||||
area_created = TRUE
|
||||
return area_created
|
||||
@@ -236,6 +242,10 @@
|
||||
return
|
||||
set_area_machinery_title(A,str,prevname)
|
||||
A.name = str
|
||||
if(A.firedoors)
|
||||
for(var/D in A.firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = D
|
||||
FD.CalculateAffectingAreas()
|
||||
to_chat(usr, "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>")
|
||||
interact()
|
||||
return 1
|
||||
|
||||
@@ -186,10 +186,10 @@
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
for(var/i, i<= 5, i++)
|
||||
wires.UpdateCut(i,1)
|
||||
wires.on_cut(i, 1)
|
||||
|
||||
/obj/item/radio/intercom/wirecutter_act(mob/user, obj/item/I)
|
||||
if(!(buildstage == 3 && b_stat && wires.IsAllCut()))
|
||||
if(!(buildstage == 3 && b_stat && wires.is_all_cut()))
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
@@ -270,4 +270,4 @@
|
||||
|
||||
/obj/item/radio/intercom/locked/prison/New()
|
||||
..()
|
||||
wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
|
||||
wires.cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
@@ -76,6 +76,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
GLOB.global_radios |= src
|
||||
|
||||
/obj/item/radio/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src, frequency)
|
||||
@@ -127,8 +128,8 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
|
||||
data["mic_cut"] = (wires.IsIndexCut(RADIO_WIRE_TRANSMIT) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
data["spk_cut"] = (wires.IsIndexCut(RADIO_WIRE_RECEIVE) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
data["mic_cut"] = (wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
data["spk_cut"] = (wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
|
||||
var/list/chanlist = list_channels(user)
|
||||
if(islist(chanlist) && chanlist.len)
|
||||
@@ -184,10 +185,10 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
return can_admin_interact()
|
||||
|
||||
/obj/item/radio/proc/ToggleBroadcast()
|
||||
broadcasting = !broadcasting && !(wires.IsIndexCut(RADIO_WIRE_TRANSMIT) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
broadcasting = !broadcasting && !(wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
|
||||
/obj/item/radio/proc/ToggleReception()
|
||||
listening = !listening && !(wires.IsIndexCut(RADIO_WIRE_RECEIVE) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
listening = !listening && !(wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
|
||||
/obj/item/radio/Topic(href, href_list)
|
||||
if(..())
|
||||
@@ -334,7 +335,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
|
||||
// Uncommenting this. To the above comment:
|
||||
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
|
||||
if(wires.IsIndexCut(RADIO_WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
if(wires.is_cut(WIRE_RADIO_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
return 0
|
||||
|
||||
if(!M.IsVocal())
|
||||
@@ -515,7 +516,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
var/is_listening = TRUE
|
||||
if(!on)
|
||||
is_listening = FALSE
|
||||
if(!wires || wires.IsIndexCut(RADIO_WIRE_RECEIVE))
|
||||
if(!wires || wires.is_cut(WIRE_RADIO_RECEIVER))
|
||||
is_listening = FALSE
|
||||
if(!listening)
|
||||
is_listening = FALSE
|
||||
|
||||
@@ -72,8 +72,7 @@ REAGENT SCANNER
|
||||
var/turf/U = O.loc
|
||||
if(U && U.intact)
|
||||
O.invisibility = 101
|
||||
if(O)
|
||||
O.alpha = 255
|
||||
O.alpha = 255
|
||||
for(var/mob/living/M in T.contents)
|
||||
var/oldalpha = M.alpha
|
||||
if(M.alpha < 255 && istype(M))
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
|
||||
investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
|
||||
burn()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -267,8 +268,16 @@
|
||||
|
||||
/obj/item/flag/chameleon/burn()
|
||||
if(boobytrap)
|
||||
boobytrap.prime()
|
||||
..()
|
||||
fire_act()
|
||||
addtimer(CALLBACK(src, .proc/prime_boobytrap), boobytrap.det_time)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/flag/chameleon/proc/prime_boobytrap()
|
||||
boobytrap.forceMove(get_turf(loc))
|
||||
boobytrap.prime()
|
||||
boobytrap = null
|
||||
burn()
|
||||
|
||||
/obj/item/flag/chameleon/updateFlagIcon()
|
||||
icon_state = updated_icon_state
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
playsound(src.loc, 'sound/weapons/cablecuff.ogg', 15, 1, -1)
|
||||
|
||||
M.visible_message("<span class='danger'>[U] comes from behind and begins garroting [M] with the [src]!</span>", \
|
||||
"<span class='userdanger'>[U]\ begins garroting you with the [src]![improvised ? "" : " You are unable to speak!"]</span>", \
|
||||
"<span class='userdanger'>[U] begins garroting you with the [src]![improvised ? "" : " You are unable to speak!"]</span>", \
|
||||
"You hear struggling and wire strain against flesh!")
|
||||
|
||||
return
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/item/grenade/smokebomb/prime()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
src.smoke.set_up(10, 0, usr.loc)
|
||||
smoke.set_up(10, 0)
|
||||
spawn(0)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
|
||||
@@ -372,6 +372,15 @@
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/dragon(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags
|
||||
desc = "A large duffelbag, containing three types of extended drum magazines."
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags/New()
|
||||
..()
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg/dragon(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/mining_conscript/
|
||||
name = "mining conscription kit"
|
||||
desc = "A kit containing everything a crewmember needs to support a shaft miner in the field."
|
||||
|
||||
@@ -380,12 +380,13 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
materials = list(MAT_METAL=3000)
|
||||
cant_hold = list(/obj/item/disk/nuclear) // Prevents some cheesing
|
||||
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
|
||||
..()
|
||||
// Drop all the things. All of them.
|
||||
var/list/obj/item/oldContents = contents.Copy()
|
||||
quick_empty()
|
||||
drop_inventory(user)
|
||||
|
||||
// Make each item scatter a bit
|
||||
for(var/obj/item/I in oldContents)
|
||||
|
||||
@@ -438,8 +438,11 @@
|
||||
if((!ishuman(usr) && (src.loc != usr)) || usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
drop_inventory(usr)
|
||||
|
||||
/obj/item/storage/proc/drop_inventory(user)
|
||||
var/turf/T = get_turf(src)
|
||||
hide_from(usr)
|
||||
hide_from(user)
|
||||
for(var/obj/item/I in contents)
|
||||
remove_from_storage(I, T)
|
||||
CHECK_TICK
|
||||
@@ -499,10 +502,9 @@
|
||||
|
||||
/obj/item/storage/attack_self(mob/user)
|
||||
|
||||
//Clicking on itself will empty it, if it has the verb to do that.
|
||||
if(user.is_in_active_hand(src))
|
||||
if(verbs.Find(/obj/item/storage/verb/quick_empty))
|
||||
quick_empty()
|
||||
//Clicking on itself will empty it, if allow_quick_empty is TRUE
|
||||
if(allow_quick_empty && user.is_in_active_hand(src))
|
||||
drop_inventory(user)
|
||||
|
||||
//Returns the storage depth of an atom. This is the number of storage items the atom is contained in before reaching toplevel (the area).
|
||||
//Returns -1 if the atom was not found on container.
|
||||
|
||||
@@ -43,35 +43,31 @@
|
||||
/obj/item/tank/proc/toggle_internals(mob/user, silent = FALSE)
|
||||
var/mob/living/carbon/C = user
|
||||
if(!istype(C))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(C.internal == src)
|
||||
to_chat(C, "<span class='notice'>You close \the [src] valve.</span>")
|
||||
C.internal = null
|
||||
else
|
||||
var/can_open_valve = 0
|
||||
if(C.get_organ_slot("breathing_tube"))
|
||||
can_open_valve = 1
|
||||
else if(C.wear_mask && C.wear_mask.flags & AIRTIGHT)
|
||||
can_open_valve = 1
|
||||
else if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.head && H.head.flags & AIRTIGHT)
|
||||
can_open_valve = 1
|
||||
if(!C.get_organ_slot("breathing_tube")) // Breathing tubes can always use internals, if they have one, skip ahead and turn internals on/off
|
||||
if(!C.wear_mask) // Do we have a mask equipped?
|
||||
return FALSE
|
||||
|
||||
if(can_open_valve)
|
||||
var/obj/item/clothing/mask/M = C.wear_mask
|
||||
// If the "mask" isn't actually a mask OR That mask isn't internals compatible AND Their headgear isn't internals compatible
|
||||
if(!istype(M) || (!(initial(M.flags) & AIRTIGHT) && !(C.head.flags & AIRTIGHT)))
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='warning'>You are not wearing a suitable mask or helmet.</span>")
|
||||
return FALSE
|
||||
if(M.mask_adjusted) // If the mask is equipped but pushed down
|
||||
M.adjustmask(C) // Adjust it back
|
||||
|
||||
if(!silent)
|
||||
if(C.internal)
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You switch your internals to [src].</span>")
|
||||
to_chat(C, "<span class='notice'>You switch your internals to [src].</span>")
|
||||
else
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You open \the [src] valve.</span>")
|
||||
C.internal = src
|
||||
else
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You are not wearing a suitable mask or helmet.</span>")
|
||||
return 0
|
||||
|
||||
to_chat(C, "<span class='notice'>You open \the [src] valve.</span>")
|
||||
C.internal = src
|
||||
C.update_action_buttons_icon()
|
||||
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
new /obj/item/clothing/suit/storage/labcoat(src)
|
||||
new /obj/item/radio/headset/headset_sci(src)
|
||||
new /obj/item/radio/headset/headset_sci(src)
|
||||
new /obj/item/reagent_containers/food/drinks/oilcan(src)
|
||||
new /obj/item/reagent_containers/food/drinks/oilcan(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/RD
|
||||
name = "research director's locker"
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
|
||||
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
var/tempo = 5 // delay between notes
|
||||
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeat = 10 // maximum times we can repeat
|
||||
|
||||
var/instrumentDir = "piano" // the folder with the sounds
|
||||
var/instrumentExt = "ogg" // the file extension
|
||||
var/obj/instrumentObj = null // the associated obj playing the sound
|
||||
|
||||
/datum/song/New(dir, obj, ext = "ogg")
|
||||
tempo = sanitize_tempo(tempo)
|
||||
instrumentDir = dir
|
||||
instrumentObj = obj
|
||||
instrumentExt = ext
|
||||
|
||||
/datum/song/Destroy()
|
||||
instrumentObj = null
|
||||
return ..()
|
||||
|
||||
// note is a number from 1-7 for A-G
|
||||
// acc is either "b", "n", or "#"
|
||||
// oct is 1-8 (or 9 for C)
|
||||
/datum/song/proc/playnote(note, acc as text, oct)
|
||||
// handle accidental -> B<>C of E<>F
|
||||
if(acc == "b" && (note == 3 || note == 6)) // C or F
|
||||
if(note == 3)
|
||||
oct--
|
||||
note--
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 2 || note == 5)) // B or E
|
||||
if(note == 2)
|
||||
oct++
|
||||
note++
|
||||
acc = "n"
|
||||
else if(acc == "#" && (note == 7)) //G#
|
||||
note = 1
|
||||
acc = "b"
|
||||
else if(acc == "#") // mass convert all sharps to flats, octave jump already handled
|
||||
acc = "b"
|
||||
note++
|
||||
|
||||
// check octave, C is allowed to go to 9
|
||||
if(oct < 1 || (note == 3 ? oct > 9 : oct > 8))
|
||||
return
|
||||
|
||||
// now generate name
|
||||
var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]"
|
||||
soundfile = file(soundfile)
|
||||
// make sure the note exists
|
||||
if(!fexists(soundfile))
|
||||
return
|
||||
// and play
|
||||
var/turf/source = get_turf(instrumentObj)
|
||||
var/sound/music_played = sound(soundfile)
|
||||
for(var/A in hearers(15, source))
|
||||
var/mob/M = A
|
||||
if(!M.client || !(M.client.prefs.sound & SOUND_INSTRUMENTS))
|
||||
continue
|
||||
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
|
||||
|
||||
/datum/song/proc/shouldStopPlaying(mob/user)
|
||||
if(instrumentObj)
|
||||
//if(!user.canUseTopic(instrumentObj))
|
||||
//return 1
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
else
|
||||
return 1
|
||||
|
||||
/datum/song/proc/playsong(mob/user)
|
||||
while(repeat >= 0)
|
||||
var/cur_oct[7]
|
||||
var/cur_acc[7]
|
||||
for(var/i = 1 to 7)
|
||||
cur_oct[i] = 3
|
||||
cur_acc[i] = "n"
|
||||
|
||||
for(var/line in lines)
|
||||
for(var/beat in splittext(lowertext(line), ","))
|
||||
var/list/notes = splittext(beat, "/")
|
||||
for(var/note in splittext(notes[1], "-"))
|
||||
if(!playing || shouldStopPlaying(user)) //If the instrument is playing, or special case
|
||||
playing = 0
|
||||
return
|
||||
if(length(note) == 0)
|
||||
continue
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to length(note))
|
||||
var/ni = copytext(note,i,i+1)
|
||||
if(!text2num(ni))
|
||||
if(ni == "#" || ni == "b" || ni == "n")
|
||||
cur_acc[cur_note] = ni
|
||||
else if(ni == "s")
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = text2num(ni)
|
||||
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(sanitize_tempo(tempo / text2num(notes[2])))
|
||||
else
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
playing = 0
|
||||
repeat = 0
|
||||
|
||||
/datum/song/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!instrumentObj)
|
||||
return
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, instrumentObj, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, instrumentObj, ui_key, "song.tmpl", instrumentObj.name, 700, 500)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/song/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
data["lines"] = lines
|
||||
data["tempo"] = tempo
|
||||
|
||||
data["playing"] = playing
|
||||
data["help"] = help
|
||||
data["repeat"] = repeat
|
||||
data["maxRepeat"] = max_repeat
|
||||
data["minTempo"] = world.tick_lag
|
||||
data["maxTempo"] = 600
|
||||
|
||||
return data
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!in_range(instrumentObj, usr) || (issilicon(usr) && instrumentObj.loc != usr) || !isliving(usr) || usr.incapacitated())
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return 1
|
||||
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
playing = 0
|
||||
lines = new()
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
name = ""
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["import"])
|
||||
playing = 0
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
|
||||
if(length(t) >= 12000)
|
||||
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
|
||||
if(cont == "no")
|
||||
break
|
||||
while(length(t) > 12000)
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
lines = splittext(t, "\n")
|
||||
if(lines.len == 0)
|
||||
return 1
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
|
||||
lines.Cut(1,2)
|
||||
else
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
if(lines.len > 200)
|
||||
to_chat(usr, "Too many lines!")
|
||||
lines.Cut(201)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(length(l) > 200)
|
||||
to_chat(usr, "Line [linenum] too long!")
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["help"])
|
||||
help = !help
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
|
||||
if(playing)
|
||||
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
|
||||
repeat += round(text2num(href_list["repeat"]))
|
||||
if(repeat < 0)
|
||||
repeat = 0
|
||||
if(repeat > max_repeat)
|
||||
repeat = max_repeat
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["tempo"])
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]) * world.tick_lag)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["play"])
|
||||
if(playing)
|
||||
return
|
||||
playing = 1
|
||||
spawn()
|
||||
playsong(usr)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["insertline"])
|
||||
var/num = round(text2num(href_list["insertline"]))
|
||||
if(num < 1 || num > lines.len + 1)
|
||||
return
|
||||
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lines.len > 200)
|
||||
return
|
||||
if(length(newline) > 200)
|
||||
newline = copytext(newline, 1, 200)
|
||||
|
||||
lines.Insert(num, newline)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num + 1)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]))
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(length(content) > 200)
|
||||
content = copytext(content, 1, 200)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/datum/song/proc/sanitize_tempo(new_tempo)
|
||||
new_tempo = abs(new_tempo)
|
||||
return max(round(new_tempo, world.tick_lag), world.tick_lag)
|
||||
|
||||
// subclass for handheld instruments, like violin
|
||||
/datum/song/handheld
|
||||
|
||||
/datum/song/handheld/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !isliving(instrumentObj.loc)
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
|
||||
|
||||
/obj/structure/piano/New()
|
||||
..()
|
||||
song = new("piano", src)
|
||||
|
||||
if(prob(50))
|
||||
name = "space minimoog"
|
||||
desc = "This is a minimoog, like a space piano, but more spacey!"
|
||||
icon_state = "minimoog"
|
||||
else
|
||||
name = "space piano"
|
||||
desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
|
||||
icon_state = "piano"
|
||||
|
||||
/obj/structure/piano/Destroy()
|
||||
QDEL_NULL(song)
|
||||
return ..()
|
||||
|
||||
/obj/structure/piano/Initialize()
|
||||
if(song)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
..()
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/piano/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!isliving(user) || user.incapacitated() || !anchored)
|
||||
return
|
||||
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/structure/piano/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
return song.ui_data(user, ui_key, state)
|
||||
|
||||
/obj/structure/piano/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
|
||||
/obj/structure/piano/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(!anchored && !isinspace())
|
||||
WRENCH_ANCHOR_MESSAGE
|
||||
if(!I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
return
|
||||
user.visible_message( \
|
||||
"[user] tightens [src]'s casters.", \
|
||||
"<span class='notice'> You have tightened [src]'s casters. Now it can be played again.</span>", \
|
||||
"You hear ratchet.")
|
||||
anchored = TRUE
|
||||
else if(anchored)
|
||||
to_chat(user, "<span class='notice'> You begin to loosen [src]'s casters...</span>")
|
||||
if(!I.use_tool(src, user, 40, volume = I.tool_volume))
|
||||
return
|
||||
user.visible_message( \
|
||||
"[user] loosens [src]'s casters.", \
|
||||
"<span class='notice'> You have loosened [src]. Now it can be pulled somewhere else.</span>", \
|
||||
"You hear ratchet.")
|
||||
anchored = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be bolted to the floor!</span>")
|
||||
@@ -292,12 +292,12 @@
|
||||
|
||||
/obj/structure/sign/directions/engineering
|
||||
name = "\improper Engineering Department"
|
||||
desc = "A direction sign, pointing out which way the Engineering department is."
|
||||
desc = "A direction sign, pointing out which way the Engineering Department is."
|
||||
icon_state = "direction_eng"
|
||||
|
||||
/obj/structure/sign/directions/security
|
||||
name = "\improper Security Department"
|
||||
desc = "A direction sign, pointing out which way the Security department is."
|
||||
desc = "A direction sign, pointing out which way the Security Department is."
|
||||
icon_state = "direction_sec"
|
||||
|
||||
/obj/structure/sign/directions/medical
|
||||
@@ -307,12 +307,12 @@
|
||||
|
||||
/obj/structure/sign/directions/evac
|
||||
name = "\improper Escape Arm"
|
||||
desc = "A direction sign, pointing out which way escape shuttle dock is."
|
||||
desc = "A direction sign, pointing out which way Escape Shuttle Dock is."
|
||||
icon_state = "direction_evac"
|
||||
|
||||
/obj/structure/sign/directions/cargo
|
||||
name = "\improper Cargo Department"
|
||||
desc = "A direction sign, pointing out which way the Cargo department is."
|
||||
desc = "A direction sign, pointing out which way the Cargo Department is."
|
||||
icon_state = "direction_supply"
|
||||
|
||||
/obj/structure/sign/explosives
|
||||
|
||||
+13
-12
@@ -4,12 +4,13 @@
|
||||
return
|
||||
|
||||
var/turf/turf_source = get_turf(source)
|
||||
|
||||
if(!turf_source)
|
||||
return
|
||||
if(!SSsounds.channel_list) // Not ready yet
|
||||
return
|
||||
|
||||
//allocate a channel if necessary now so its the same for everyone
|
||||
channel = channel || open_sound_channel()
|
||||
channel = channel || SSsounds.random_available_channel()
|
||||
|
||||
// Looping through the player list has the added bonus of working for mobs inside containers
|
||||
var/sound/S = sound(get_sfx(soundin))
|
||||
@@ -33,7 +34,7 @@
|
||||
if(distance <= maxdistance)
|
||||
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
|
||||
|
||||
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S)
|
||||
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S, distance_multiplier = 1)
|
||||
if(!client || !can_hear())
|
||||
return
|
||||
|
||||
@@ -41,7 +42,7 @@
|
||||
S = sound(get_sfx(soundin))
|
||||
|
||||
S.wait = 0 //No queue
|
||||
S.channel = channel || open_sound_channel()
|
||||
S.channel = channel || SSsounds.random_available_channel()
|
||||
S.volume = vol
|
||||
|
||||
if(vary)
|
||||
@@ -55,6 +56,7 @@
|
||||
|
||||
//sound volume falloff with distance
|
||||
var/distance = get_dist(T, turf_source)
|
||||
distance *= distance_multiplier
|
||||
|
||||
S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff.
|
||||
|
||||
@@ -81,9 +83,9 @@
|
||||
return //No sound
|
||||
|
||||
var/dx = turf_source.x - T.x // Hearing from the right/left
|
||||
S.x = dx
|
||||
S.x = dx * distance_multiplier
|
||||
var/dz = turf_source.y - T.y // Hearing from infront/behind
|
||||
S.z = dz
|
||||
S.z = dz * distance_multiplier
|
||||
// The y value is for above your head, but there is no ceiling in 2d spessmens.
|
||||
S.y = 1
|
||||
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
|
||||
@@ -98,15 +100,14 @@
|
||||
var/mob/M = m
|
||||
M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S)
|
||||
|
||||
/proc/open_sound_channel()
|
||||
var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used
|
||||
. = ++next_channel
|
||||
if(next_channel > CHANNEL_HIGHEST_AVAILABLE)
|
||||
next_channel = 1
|
||||
|
||||
/mob/proc/stop_sound_channel(chan)
|
||||
SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
|
||||
|
||||
/mob/proc/set_sound_channel_volume(channel, volume)
|
||||
var/sound/S = sound(null, FALSE, FALSE, channel, volume)
|
||||
S.status = SOUND_UPDATE
|
||||
SEND_SOUND(src, S)
|
||||
|
||||
/client/proc/playtitlemusic()
|
||||
if(!SSticker || !SSticker.login_music || config.disable_lobby_music)
|
||||
return
|
||||
|
||||
@@ -263,6 +263,13 @@
|
||||
if(SSair && !ignore_air)
|
||||
SSair.add_to_active(src)
|
||||
|
||||
//update firedoor adjacency
|
||||
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
|
||||
for(var/I in turfs_to_check)
|
||||
var/turf/T = I
|
||||
for(var/obj/machinery/door/firedoor/FD in T)
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
if(!keep_cabling && !can_have_cabling())
|
||||
for(var/obj/structure/cable/C in contents)
|
||||
qdel(C)
|
||||
|
||||
@@ -340,6 +340,8 @@ GLOBAL_VAR_INIT(world_topic_spam_protect_time, world.timeofday)
|
||||
#endif
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
var/secs_before_auto_reconnect = 10 // TODO: make it higher if server is due for an update @AffectedArc07
|
||||
C << output(list2params(list(secs_before_auto_reconnect)), "browseroutput:reboot")
|
||||
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
#define ALARM_RESET_DELAY 100 // How long will the alarm/trigger remain active once origin/source has been found to be gone?
|
||||
|
||||
/datum/alarm_source
|
||||
var/source = null // The source trigger
|
||||
var/source_name = "" // The name of the source should it be lost (for example a destroyed camera)
|
||||
var/duration = 0 // How long this source will be alarming, 0 for indefinetely.
|
||||
var/severity = 1 // How severe the alarm from this source is.
|
||||
var/start_time = 0 // When this source began alarming.
|
||||
var/end_time = 0 // Use to set when this trigger should clear, in case the source is lost.
|
||||
|
||||
/datum/alarm_source/New(var/atom/source)
|
||||
src.source = source
|
||||
start_time = world.time
|
||||
source_name = source.get_source_name()
|
||||
|
||||
/datum/alarm
|
||||
var/atom/origin //Used to identify the alarm area.
|
||||
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
|
||||
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
|
||||
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
|
||||
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
|
||||
var/area/last_name //The last acquired name, used should origin be lost
|
||||
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
|
||||
var/end_time //Used to set when this alarm should clear, in case the origin is lost.
|
||||
|
||||
/datum/alarm/New(var/atom/origin, var/atom/source, var/duration, var/severity)
|
||||
src.origin = origin
|
||||
|
||||
cameras() // Sets up both cameras and last alarm area.
|
||||
set_source_data(source, duration, severity)
|
||||
|
||||
/datum/alarm/process()
|
||||
// Has origin gone missing?
|
||||
if(!origin && !end_time)
|
||||
end_time = world.time + ALARM_RESET_DELAY
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
// Has the alarm passed its best before date?
|
||||
if((AS.end_time && world.time > AS.end_time) || (AS.duration && world.time > (AS.start_time + AS.duration)))
|
||||
sources -= AS
|
||||
// Has the source gone missing? Then reset the normal duration and set end_time
|
||||
if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinetely.
|
||||
AS.duration = 0
|
||||
AS.end_time = world.time + ALARM_RESET_DELAY
|
||||
|
||||
/datum/alarm/proc/set_source_data(var/atom/source, var/duration, var/severity)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
if(!AS)
|
||||
AS = new/datum/alarm_source(source)
|
||||
sources += AS
|
||||
sources_assoc[source] = AS
|
||||
// Currently only non-0 durations can be altered (normal alarms VS EMP blasts)
|
||||
if(AS.duration)
|
||||
duration = duration SECONDS
|
||||
AS.duration = duration
|
||||
AS.severity = severity
|
||||
|
||||
/datum/alarm/proc/clear(var/source)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
sources -= AS
|
||||
sources_assoc -= source
|
||||
|
||||
/datum/alarm/proc/alarm_area()
|
||||
if(!origin)
|
||||
return last_area
|
||||
|
||||
last_area = origin.get_alarm_area()
|
||||
return last_area
|
||||
|
||||
/datum/alarm/proc/alarm_name()
|
||||
if(!origin)
|
||||
return last_name
|
||||
|
||||
last_name = origin.get_alarm_name()
|
||||
return last_name
|
||||
|
||||
/datum/alarm/proc/cameras()
|
||||
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
||||
if(cameras && (last_camera_area != alarm_area()))
|
||||
cameras = null
|
||||
|
||||
// The list of cameras is also reset by /proc/invalidateCameraCache()
|
||||
if(!cameras)
|
||||
cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras()
|
||||
|
||||
last_camera_area = last_area
|
||||
return cameras
|
||||
|
||||
/datum/alarm/proc/max_severity()
|
||||
var/max_severity = 0
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
max_severity = max(AS.severity, max_severity)
|
||||
|
||||
return max_severity
|
||||
|
||||
/******************
|
||||
* Assisting procs *
|
||||
******************/
|
||||
/atom/proc/get_alarm_area()
|
||||
var/area/A = get_area(src)
|
||||
return A
|
||||
|
||||
/area/get_alarm_area()
|
||||
return src
|
||||
|
||||
/atom/proc/get_alarm_name()
|
||||
var/area/A = get_area(src)
|
||||
return A.name
|
||||
|
||||
/area/get_alarm_name()
|
||||
return name
|
||||
|
||||
/mob/get_alarm_name()
|
||||
return name
|
||||
|
||||
/atom/proc/get_source_name()
|
||||
return name
|
||||
|
||||
/obj/machinery/camera/get_source_name()
|
||||
return c_tag
|
||||
|
||||
/atom/proc/get_alarm_cameras()
|
||||
var/area/A = get_area(src)
|
||||
return A.get_cameras()
|
||||
|
||||
/area/get_alarm_cameras()
|
||||
return get_cameras()
|
||||
|
||||
/mob/living/silicon/robot/get_alarm_cameras()
|
||||
var/list/cameras = ..()
|
||||
if(camera)
|
||||
cameras += camera
|
||||
|
||||
return cameras
|
||||
|
||||
/mob/living/silicon/robot/syndicate/get_alarm_cameras()
|
||||
return list()
|
||||
@@ -1,103 +0,0 @@
|
||||
#define ALARM_RAISED 1
|
||||
#define ALARM_CLEARED 0
|
||||
|
||||
/datum/alarm_handler
|
||||
var/category = ""
|
||||
var/list/datum/alarm/alarms = new // All alarms, to handle cases when an origin has been deleted with one or more active alarms
|
||||
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin.
|
||||
var/list/listeners = new // A list of all objects interested in alarm changes.
|
||||
|
||||
/datum/alarm_handler/process()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
A.process()
|
||||
check_alarm_cleared(A)
|
||||
|
||||
/datum/alarm_handler/proc/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
var/new_alarm
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
new_alarm = 0
|
||||
//see if there is already an alarm of this origin
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.set_source_data(source, duration, severity)
|
||||
else
|
||||
existing = new/datum/alarm(origin, source, duration, severity)
|
||||
new_alarm = 1
|
||||
|
||||
alarms |= existing
|
||||
alarms_assoc[origin] = existing
|
||||
if(new_alarm)
|
||||
alarms = dd_sortedObjectList(alarms)
|
||||
on_alarm_change(existing, ALARM_RAISED)
|
||||
|
||||
return new_alarm
|
||||
|
||||
/datum/alarm_handler/proc/clearAlarm(var/atom/origin, var/source)
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.clear(source)
|
||||
return check_alarm_cleared(existing)
|
||||
|
||||
/datum/alarm_handler/proc/has_major_alarms()
|
||||
if(alarms && alarms.len)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/alarm_handler/proc/major_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/minor_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/check_alarm_cleared(var/datum/alarm/alarm)
|
||||
if((alarm.end_time && world.time > alarm.end_time) || !alarm.sources.len)
|
||||
alarms -= alarm
|
||||
alarms_assoc -= alarm.origin
|
||||
on_alarm_change(alarm, ALARM_CLEARED)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/alarm_handler/proc/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
for(var/obj/machinery/camera/C in alarm.cameras())
|
||||
if(was_raised)
|
||||
C.network.Add(category)
|
||||
else
|
||||
C.network.Remove(category)
|
||||
notify_listeners(alarm, was_raised)
|
||||
|
||||
/datum/alarm_handler/proc/get_alarm_severity_for_origin(var/atom/origin)
|
||||
if(!origin)
|
||||
return
|
||||
|
||||
origin = origin.get_alarm_origin()
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(!existing)
|
||||
return
|
||||
|
||||
return existing.max_severity()
|
||||
|
||||
/atom/proc/get_alarm_origin()
|
||||
return src
|
||||
|
||||
/turf/get_alarm_origin()
|
||||
var/area/area = get_area(src)
|
||||
return area // Very important to get area.master, as dynamic lightning can and will split areas.
|
||||
|
||||
/datum/alarm_handler/proc/register(var/object, var/procName)
|
||||
listeners[object] = procName
|
||||
|
||||
/datum/alarm_handler/proc/unregister(var/object)
|
||||
listeners -= object
|
||||
|
||||
/datum/alarm_handler/proc/notify_listeners(var/alarm, var/was_raised)
|
||||
for(var/listener in listeners)
|
||||
call(listener, listeners[listener])(src, alarm, was_raised)
|
||||
@@ -1,19 +0,0 @@
|
||||
/datum/alarm_handler/atmosphere
|
||||
category = "Atmosphere Alarms"
|
||||
|
||||
/datum/alarm_handler/atmosphere/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
..()
|
||||
|
||||
/datum/alarm_handler/atmosphere/major_alarms()
|
||||
var/list/major_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() > 1)
|
||||
major_alarms.Add(A)
|
||||
return major_alarms
|
||||
|
||||
/datum/alarm_handler/atmosphere/minor_alarms()
|
||||
var/list/minor_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() == 1)
|
||||
minor_alarms.Add(A)
|
||||
return minor_alarms
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/burglar
|
||||
category = "Burglar Alarms"
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/camera
|
||||
category = "Camera Alarms"
|
||||
@@ -1,11 +0,0 @@
|
||||
/datum/alarm_handler/fire
|
||||
category = "Fire Alarms"
|
||||
|
||||
/datum/alarm_handler/fire/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
if(was_raised)
|
||||
A.fire_alert()
|
||||
else
|
||||
A.fire_reset()
|
||||
..()
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/motion
|
||||
category = "Motion Alarms"
|
||||
@@ -1,10 +0,0 @@
|
||||
/datum/alarm_handler/power
|
||||
category = "Power Alarms"
|
||||
|
||||
/datum/alarm_handler/power/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
A.power_alert(was_raised)
|
||||
..()
|
||||
|
||||
/area/proc/power_alert(var/alarming)
|
||||
@@ -1,3 +1,9 @@
|
||||
#define WIRE_RECEIVE (1<<0) //Allows pulse(0) to call Activate()
|
||||
#define WIRE_PULSE (1<<1) //Allows pulse(0) to act on the holder
|
||||
#define WIRE_PULSE_SPECIAL (1<<2) //Allows pulse(0) to act on the holders special assembly
|
||||
#define WIRE_RADIO_RECEIVE (1<<3) //Allows pulse(1) to call Activate()
|
||||
#define WIRE_RADIO_PULSE (1<<4) //Allows pulse(1) to send a radio message
|
||||
|
||||
/obj/item/assembly
|
||||
name = "assembly"
|
||||
desc = "A small electronic device that should never exist."
|
||||
@@ -22,21 +28,12 @@
|
||||
var/wires = WIRE_RECEIVE | WIRE_PULSE
|
||||
var/datum/wires/connected = null // currently only used by timer/signaler
|
||||
|
||||
var/const/WIRE_RECEIVE = 1 //Allows Pulsed(0) to call Activate()
|
||||
var/const/WIRE_PULSE = 2 //Allows Pulse(0) to act on the holder
|
||||
var/const/WIRE_PULSE_SPECIAL = 4 //Allows Pulse(0) to act on the holders special assembly
|
||||
var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate()
|
||||
var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message
|
||||
|
||||
/obj/item/assembly/proc/activate() //What the device does when turned on
|
||||
return
|
||||
|
||||
/obj/item/assembly/proc/pulsed(radio = FALSE) //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
|
||||
return
|
||||
|
||||
/obj/item/assembly/proc/pulse(radio = FALSE) //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
|
||||
return
|
||||
|
||||
/obj/item/assembly/proc/toggle_secure() //Code that has to happen when the assembly is un\secured goes here
|
||||
return
|
||||
|
||||
@@ -79,7 +76,11 @@
|
||||
activate()
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/pulse(radio = FALSE)
|
||||
//Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
|
||||
/obj/item/assembly/proc/pulse(radio = FALSE)
|
||||
if(connected && wires)
|
||||
connected.pulse_assembly(src)
|
||||
return TRUE
|
||||
if(holder && (wires & WIRE_PULSE))
|
||||
holder.process_activation(src, 1, 0)
|
||||
if(holder && (wires & WIRE_PULSE_SPECIAL))
|
||||
|
||||
@@ -128,12 +128,6 @@
|
||||
if(usr)
|
||||
GLOB.lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
|
||||
|
||||
/obj/item/assembly/signaler/pulse(var/radio = FALSE)
|
||||
if(connected && wires)
|
||||
connected.Pulse(src)
|
||||
else
|
||||
return ..(radio)
|
||||
|
||||
/obj/item/assembly/signaler/receive_signal(datum/signal/signal)
|
||||
if(!receiving || !signal)
|
||||
return FALSE
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user