forked from ss220club/BandaStation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcamera.dm
215 lines (178 loc) · 7.19 KB
/
camera.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#define DEFAULT_MAP_SIZE 15
/obj/machinery/computer/security
name = "security camera console"
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "security_key"
circuit = /obj/item/circuitboard/computer/security
light_color = COLOR_SOFT_RED
var/list/network = list(CAMERANET_NETWORK_SS13)
var/obj/machinery/camera/active_camera
/// The turf where the camera was last updated.
var/turf/last_camera_turf
var/list/concurrent_users = list()
// Stuff needed to render the map
var/atom/movable/screen/map_view/cam_screen
/// All the plane masters that need to be applied.
var/atom/movable/screen/background/cam_background
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT
/obj/machinery/computer/security/Initialize(mapload)
. = ..()
// Map name has to start and end with an A-Z character,
// and definitely NOT with a square bracket or even a number.
// I wasted 6 hours on this. :agony:
var/map_name = "camera_console_[REF(src)]_map"
// Convert networks to lowercase
for(var/i in network)
network -= i
network += LOWER_TEXT(i)
// Initialize map objects
cam_screen = new
cam_screen.generate_view(map_name)
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
/obj/machinery/computer/security/Destroy()
QDEL_NULL(cam_screen)
QDEL_NULL(cam_background)
return ..()
/obj/machinery/computer/security/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
for(var/i in network)
network -= i
network += "[port.shuttle_id]_[i]"
/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui)
. = ..()
if(!user.client) //prevents errors by trying to pass clients that don't exist.
return
// Update UI
ui = SStgui.try_update_ui(user, src, ui)
// Update the camera, showing static if necessary and updating data if the location has moved.
update_active_camera_screen()
if(!ui)
var/user_ref = REF(user)
var/is_living = isliving(user)
// Ghosts shouldn't count towards concurrent users, which produces
// an audible terminal_on click.
if(is_living)
concurrent_users += user_ref
// Turn on the console
if(length(concurrent_users) == 1 && is_living)
playsound(src, 'sound/machines/terminal/terminal_on.ogg', 25, FALSE)
use_energy(active_power_usage)
// Register map objects
cam_screen.display_to(user)
user.client.register_map_obj(cam_background)
// Open UI
ui = new(user, src, "CameraConsole220", name) // BANDASTATION EDIT: UI changed from CameraConsole to CameraConsole220
ui.open()
/obj/machinery/computer/security/ui_status(mob/user, datum/ui_state/state)
. = ..()
if(. == UI_DISABLED)
return UI_CLOSE
return .
/obj/machinery/computer/security/ui_data()
var/list/data = list()
data["activeCamera"] = null
if(active_camera)
data["activeCamera"] = list(
name = active_camera.c_tag,
ref = REF(active_camera),
status = active_camera.camera_enabled,
)
return data
/obj/machinery/computer/security/ui_static_data()
var/list/data = list()
data["network"] = network
data["mapRef"] = cam_screen.assigned_map
data["cameras"] = GLOB.cameranet.get_available_cameras_data(network)
return data
/obj/machinery/computer/security/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
if(action == "switch_camera")
var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras
active_camera = selected_camera
if(isnull(active_camera))
return TRUE
update_active_camera_screen()
return TRUE
/obj/machinery/computer/security/proc/update_active_camera_screen()
// Show static if can't use the camera
if(!active_camera?.can_use())
show_camera_static()
return
var/list/visible_turfs = list()
// Get the camera's turf to correctly gather what's visible from its turf, in case it's located in a moving object (borgs / mechs)
var/new_cam_turf = get_turf(active_camera)
// If we're not forcing an update for some reason and the cameras are in the same location,
// we don't need to update anything.
// Most security cameras will end here as they're not moving.
if(last_camera_turf == new_cam_turf)
return
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs.
last_camera_turf = new_cam_turf
//Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present
var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf)
for(var/turf/visible_turf in visible_things)
visible_turfs += visible_turf
//Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/obj/machinery/computer/security/ui_close(mob/user)
. = ..()
var/user_ref = REF(user)
var/is_living = isliving(user)
// Living creature or not, we remove you anyway.
concurrent_users -= user_ref
// Unregister map objects
cam_screen.hide_from(user)
// Turn off the console
if(length(concurrent_users) == 0 && is_living)
active_camera = null
last_camera_turf = null
playsound(src, 'sound/machines/terminal/terminal_off.ogg', 25, FALSE)
/obj/machinery/computer/security/proc/show_camera_static()
cam_screen.vis_contents.Cut()
cam_background.icon_state = "scanline2"
cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE)
// SECURITY MONITORS
/obj/machinery/computer/security/wooden_tv
name = "security camera monitor"
desc = "An old TV hooked into the station's camera network."
icon_state = "television"
icon_keyboard = null
icon_screen = "detective_tv"
pass_flags = PASSTABLE
/obj/machinery/computer/security/mining
name = "outpost camera console"
desc = "Used to access the various cameras on the outpost."
icon_screen = "mining"
icon_keyboard = "mining_key"
network = list(CAMERANET_NETWORK_MINE, CAMERANET_NETWORK_AUXBASE)
circuit = /obj/item/circuitboard/computer/mining
/obj/machinery/computer/security/research
name = "research camera console"
desc = "Used to access the various cameras in science."
network = list(CAMERANET_NETWORK_RD)
circuit = /obj/item/circuitboard/computer/research
/obj/machinery/computer/security/hos
name = "\improper Head of Security's camera console"
desc = "A custom security console with added access to the labor camp network."
network = list(CAMERANET_NETWORK_SS13, CAMERANET_NETWORK_LABOR)
circuit = null
/obj/machinery/computer/security/labor
name = "labor camp monitoring"
desc = "Used to access the various cameras on the labor camp."
network = list(CAMERANET_NETWORK_LABOR)
circuit = null
/obj/machinery/computer/security/qm
name = "\improper Quartermaster's camera console"
desc = "A console with access to the mining, auxiliary base and vault camera networks."
network = list(CAMERANET_NETWORK_MINE, CAMERANET_NETWORK_AUXBASE, CAMERANET_NETWORK_VAULT)
circuit = null
#undef DEFAULT_MAP_SIZE