mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-21 19:17:50 +01:00
Camera Update+Camera Bugs
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
#define VANILLA_BUG 0
|
||||
#define UNIVERSAL_BUG 1
|
||||
#define NETWORK_BUG 2
|
||||
#define SABOTAGE_BUG 3
|
||||
#define ADVANCED_BUG 4
|
||||
#define ADMIN_BUG 5
|
||||
|
||||
#define BUGMODE_LIST 0
|
||||
#define BUGMODE_MONITOR 1
|
||||
#define BUGMODE_TRACK 2
|
||||
|
||||
|
||||
|
||||
/obj/item/device/camera_bug
|
||||
name = "camera bug"
|
||||
desc = "For illicit snooping through the camera network."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "camera_bug"
|
||||
w_class = 1.0
|
||||
item_state = "camera_bug"
|
||||
icon_override = 'icons/mob/in-hand/tools.dmi'
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
|
||||
var/obj/machinery/camera/current = null
|
||||
var/obj/item/expansion = null
|
||||
var/bugtype = VANILLA_BUG
|
||||
|
||||
var/last_net_update = 0
|
||||
var/last_bugtype = VANILLA_BUG
|
||||
var/list/bugged_cameras = list()
|
||||
var/skip_bugcheck = 0
|
||||
|
||||
var/track_mode = BUGMODE_LIST
|
||||
var/last_tracked = 0
|
||||
var/refresh_interval = 50
|
||||
|
||||
var/tracked_name = null
|
||||
var/atom/tracking = null
|
||||
|
||||
var/last_found = null
|
||||
var/last_seen = null
|
||||
|
||||
/obj/item/device/camera_bug/New()
|
||||
..()
|
||||
processing_objects += src
|
||||
|
||||
/obj/item/device/camera_bug/Destroy()
|
||||
if(expansion)
|
||||
qdel(expansion)
|
||||
expansion = null
|
||||
del(src)
|
||||
/* Easier to just call del() than this nonsense
|
||||
get_cameras()
|
||||
for(var/cam_tag in bugged_cameras)
|
||||
var/obj/machinery/camera/camera = bugged_cameras[cam_tag]
|
||||
if(camera.bug == src)
|
||||
camera.bug = null
|
||||
bugged_cameras = list()
|
||||
if(tracking)
|
||||
tracking = null
|
||||
..()
|
||||
*/
|
||||
|
||||
/obj/item/device/camera_bug/interact(var/mob/user = usr)
|
||||
var/datum/browser/popup = new(user, "camerabug","Camera Bug",nref=src)
|
||||
popup.set_content(menu(get_cameras()))
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/camera_bug/attack_self(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/camera_bug/check_eye(var/mob/user as mob)
|
||||
if (user.stat || loc != user || !user.canmove || user.eye_blind || !current)
|
||||
user.reset_view(null)
|
||||
user.unset_machine()
|
||||
return null
|
||||
|
||||
var/turf/T = get_turf(user.loc)
|
||||
if(T.z != current.z || (!skip_bugcheck && current.bug != src) || !current.can_use())
|
||||
user << "<span class='danger'>[src] has lost the signal.</span>"
|
||||
current = null
|
||||
user.reset_view(null)
|
||||
user.unset_machine()
|
||||
return null
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/device/camera_bug/proc/get_cameras()
|
||||
if(bugtype != last_bugtype || ( (bugtype in list(UNIVERSAL_BUG,NETWORK_BUG,ADMIN_BUG)) && world.time > (last_net_update + 100)))
|
||||
bugged_cameras = list()
|
||||
last_bugtype = bugtype
|
||||
for(var/obj/machinery/camera/camera in cameranet.cameras)
|
||||
if(camera.stat || !camera.can_use())
|
||||
continue
|
||||
switch(bugtype)
|
||||
if(VANILLA_BUG,SABOTAGE_BUG,ADVANCED_BUG)
|
||||
if(camera.bug == src)
|
||||
bugged_cameras[camera.c_tag] = camera
|
||||
if(UNIVERSAL_BUG)
|
||||
if(camera.bug)
|
||||
bugged_cameras[camera.c_tag] = camera
|
||||
if(NETWORK_BUG,ADMIN_BUG)
|
||||
if(length(list("SS13","MINE")&camera.network))
|
||||
bugged_cameras[camera.c_tag] = camera
|
||||
sortList(bugged_cameras)
|
||||
return bugged_cameras
|
||||
|
||||
|
||||
/obj/item/device/camera_bug/proc/menu(var/list/cameras)
|
||||
if(!cameras || !cameras.len)
|
||||
return "No bugged cameras found."
|
||||
|
||||
var/html
|
||||
switch(track_mode)
|
||||
if(BUGMODE_LIST)
|
||||
html = "<h3>Select a camera:</h3> <a href='?src=\ref[src];view'>\[Cancel camera view\]</a><hr><table>"
|
||||
for(var/entry in cameras)
|
||||
var/obj/machinery/camera/C = cameras[entry]
|
||||
var/functions = ""
|
||||
switch(bugtype)
|
||||
if(SABOTAGE_BUG)
|
||||
functions = " - <a href='?src=\ref[src];emp=\ref[C]'>\[Disable\]</a>"
|
||||
if(ADVANCED_BUG)
|
||||
functions = " - <a href='?src=\ref[src];monitor=\ref[C]'>\[Monitor\]</a>"
|
||||
if(ADMIN_BUG)
|
||||
if(C.bug == src)
|
||||
functions = " - <a href='?src=\ref[src];monitor=\ref[C]'>\[Monitor\]</a> <a href='?src=\ref[src];emp=\ref[C]'>\[Disable\]</a>"
|
||||
else
|
||||
functions = " - <a href='?src=\ref[src];monitor=\ref[C]'>\[Monitor\]</a>"
|
||||
html += "<tr><td><a href='?src=\ref[src];view=\ref[C]'>[entry]</a></td><td>[functions]</td></tr>"
|
||||
|
||||
if(BUGMODE_MONITOR)
|
||||
if(current)
|
||||
html = "Analyzing Camera '[current.c_tag]' <a href='?\ref[src];mode=0'>\[Select Camera\]</a><br>"
|
||||
html += camera_report()
|
||||
else
|
||||
track_mode = BUGMODE_LIST
|
||||
return .(cameras)
|
||||
if(BUGMODE_TRACK)
|
||||
if(tracking)
|
||||
html = "Tracking '[tracked_name]' <a href='?\ref[src];mode=0'>\[Cancel Tracking\]</a> <a href='?src=\ref[src];view'>\[Cancel camera view\]</a><br>"
|
||||
if(last_found)
|
||||
var/time_diff = round((world.time - last_seen) / 150)
|
||||
var/obj/machinery/camera/C = bugged_cameras[last_found]
|
||||
var/outstring
|
||||
if(C)
|
||||
outstring = "<a href='?\ref[src];view=\ref[C]'>[last_found]</a>"
|
||||
else
|
||||
outstring = last_found
|
||||
if(!time_diff)
|
||||
html += "Last seen near [outstring] (now)<br>"
|
||||
else
|
||||
// 15 second intervals ~ 1/4 minute
|
||||
var/m = round(time_diff/4)
|
||||
var/s = (time_diff - 4*m) * 15
|
||||
if(!s) s = "00"
|
||||
html += "Last seen near [outstring] ([m]:[s] minute\s ago)<br>"
|
||||
else
|
||||
html += "Not yet seen."
|
||||
else
|
||||
track_mode = BUGMODE_LIST
|
||||
return .(cameras)
|
||||
return html
|
||||
|
||||
/obj/item/device/camera_bug/proc/camera_report()
|
||||
// this should only be called if current exists
|
||||
var/dat = ""
|
||||
if(current && current.can_use())
|
||||
var/list/seen = current.can_see()
|
||||
var/list/names = list()
|
||||
for(var/obj/machinery/singularity/S in seen) // god help you if you see more than one
|
||||
if(S.name in names)
|
||||
names[S.name]++
|
||||
dat += "[S.name] ([names[S.name]])"
|
||||
else
|
||||
names[S.name] = 1
|
||||
dat += "[S.name]"
|
||||
var/stage = round(S.current_size / 2)+1
|
||||
dat += " (Stage [stage])"
|
||||
dat += " <a href='?\ref[src];track=\ref[S]'>\[Track\]</a><br>"
|
||||
|
||||
for(var/obj/mecha/M in seen)
|
||||
if(M.name in names)
|
||||
names[M.name]++
|
||||
dat += "[M.name] ([names[M.name]])"
|
||||
else
|
||||
names[M.name] = 1
|
||||
dat += "[M.name]"
|
||||
dat += " <a href='?\ref[src];track=\ref[M]'>\[Track\]</a><br>"
|
||||
|
||||
|
||||
for(var/mob/living/M in seen)
|
||||
if(M.name in names)
|
||||
names[M.name]++
|
||||
dat += "[M.name] ([names[M.name]])"
|
||||
else
|
||||
names[M.name] = 1
|
||||
dat += "[M.name]"
|
||||
if(M.buckled && !M.lying)
|
||||
dat += " (Sitting)"
|
||||
if(M.lying)
|
||||
dat += " (Laying down)"
|
||||
dat += " <a href='?\ref[src];track=\ref[M]'>\[Track\]</a><br>"
|
||||
if(length(dat) == 0)
|
||||
dat += "No motion detected."
|
||||
return dat
|
||||
else
|
||||
return "Camera Offline<br>"
|
||||
|
||||
/obj/item/device/camera_bug/Topic(var/href,var/list/href_list)
|
||||
if(usr != loc)
|
||||
usr.unset_machine()
|
||||
usr.reset_view(null)
|
||||
usr << browse(null, "window=camerabug")
|
||||
return
|
||||
usr.set_machine(src)
|
||||
if("mode" in href_list)
|
||||
track_mode = text2num(href_list["mode"])
|
||||
if("monitor" in href_list)
|
||||
var/obj/machinery/camera/C = locate(href_list["monitor"])
|
||||
if(C)
|
||||
track_mode = BUGMODE_MONITOR
|
||||
current = C
|
||||
usr.reset_view(null)
|
||||
interact()
|
||||
if("track" in href_list)
|
||||
var/atom/A = locate(href_list["track"])
|
||||
if(A)
|
||||
tracking = A
|
||||
tracked_name = A.name
|
||||
last_found = current.c_tag
|
||||
last_seen = world.time
|
||||
track_mode = BUGMODE_TRACK
|
||||
if("emp" in href_list)
|
||||
var/obj/machinery/camera/C = locate(href_list["emp"])
|
||||
if(istype(C) && C.bug == src)
|
||||
C.emp_act(1)
|
||||
C.bug = null
|
||||
bugged_cameras -= C.c_tag
|
||||
interact()
|
||||
return
|
||||
if("close" in href_list)
|
||||
usr.reset_view(null)
|
||||
usr.unset_machine()
|
||||
current = null
|
||||
return // I do not <- I do not remember what I was going to write in this comment -Sayu, sometime later
|
||||
if("view" in href_list)
|
||||
var/obj/machinery/camera/C = locate(href_list["view"])
|
||||
if(istype(C))
|
||||
if(!C.can_use())
|
||||
usr << "<span class='danger'>Something's wrong with that camera. You can't get a feed.</span>"
|
||||
return
|
||||
var/turf/T = get_turf(loc)
|
||||
if(!T || C.z != T.z)
|
||||
usr << "<span class='danger'>You can't get a signal.</span>"
|
||||
return
|
||||
current = C
|
||||
spawn(6)
|
||||
if(src.check_eye(usr))
|
||||
usr.reset_view(C)
|
||||
interact()
|
||||
else
|
||||
usr.unset_machine()
|
||||
usr.reset_view(null)
|
||||
usr << browse(null, "window=camerabug")
|
||||
return
|
||||
else
|
||||
usr.unset_machine()
|
||||
usr.reset_view(null)
|
||||
|
||||
interact()
|
||||
|
||||
/obj/item/device/camera_bug/process()
|
||||
if(track_mode == BUGMODE_LIST || (world.time < (last_tracked + refresh_interval)))
|
||||
return
|
||||
last_tracked = world.time
|
||||
if(track_mode == BUGMODE_TRACK ) // search for user
|
||||
// Note that it will be tricked if your name appears to change.
|
||||
// This is not optimal but it is better than tracking you relentlessly despite everything.
|
||||
if(!tracking)
|
||||
src.updateSelfDialog()
|
||||
return
|
||||
|
||||
if(tracking.name != tracked_name) // Hiding their identity, tricksy
|
||||
var/mob/M = tracking
|
||||
if(istype(M))
|
||||
if(!(tracked_name == "Unknown" && findtext(tracking.name,"Unknown"))) // we saw then disguised before
|
||||
if(!(tracked_name == M.real_name && findtext(tracking.name,M.real_name))) // or they're still ID'd
|
||||
src.updateSelfDialog()//But if it's neither of those cases
|
||||
return // you won't find em on the cameras
|
||||
else
|
||||
src.updateSelfDialog()
|
||||
return
|
||||
|
||||
var/list/tracking_cams = list()
|
||||
var/list/b_cams = get_cameras()
|
||||
for(var/entry in b_cams)
|
||||
tracking_cams += b_cams[entry]
|
||||
var/list/target_region = view(tracking)
|
||||
|
||||
for(var/obj/machinery/camera/C in (target_region & tracking_cams))
|
||||
if(!can_see(C,tracking)) // target may have xray, that doesn't make them visible to cameras
|
||||
continue
|
||||
if(C.can_use())
|
||||
last_found = C.c_tag
|
||||
last_seen = world.time
|
||||
break
|
||||
src.updateSelfDialog()
|
||||
|
||||
/obj/item/device/camera_bug/attackby(var/obj/item/W as obj,var/mob/living/user as mob, params)
|
||||
if(istype(W,/obj/item/weapon/screwdriver) && expansion)
|
||||
expansion.loc = get_turf(loc)
|
||||
user << "You unscrew [expansion]."
|
||||
user.put_in_inactive_hand(expansion)
|
||||
expansion = null
|
||||
bugtype = VANILLA_BUG
|
||||
skip_bugcheck = 0
|
||||
track_mode = BUGMODE_LIST
|
||||
tracking = null
|
||||
return
|
||||
|
||||
if(expansion || !W)
|
||||
return ..(W,user)
|
||||
|
||||
// I am not sure that this list is or should be final
|
||||
// really I do not know what to do here.
|
||||
var/static/list/expandables = list(
|
||||
/obj/item/weapon/research = ADMIN_BUG, // could have been anything spawn-only
|
||||
|
||||
// these are all so hackish I am sorry
|
||||
|
||||
/obj/item/device/analyzer = UNIVERSAL_BUG,
|
||||
/obj/item/weapon/stock_parts/subspace/analyzer = UNIVERSAL_BUG,
|
||||
|
||||
/obj/item/device/assembly/igniter = SABOTAGE_BUG,
|
||||
/obj/item/device/assembly/infra = SABOTAGE_BUG, // ir blaster to disable camera
|
||||
/obj/item/weapon/stock_parts/subspace/amplifier = SABOTAGE_BUG,
|
||||
|
||||
/obj/item/device/radio = NETWORK_BUG,
|
||||
/obj/item/device/assembly/signaler = NETWORK_BUG,
|
||||
/obj/item/weapon/stock_parts/subspace/transmitter = NETWORK_BUG,
|
||||
|
||||
/obj/item/device/detective_scanner = ADVANCED_BUG,
|
||||
/obj/item/device/paicard = ADVANCED_BUG,
|
||||
/obj/item/weapon/stock_parts/scanning_module = ADVANCED_BUG
|
||||
)
|
||||
|
||||
for(var/entry in expandables)
|
||||
if(istype(W,entry))
|
||||
bugtype = expandables[entry]
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
expansion = W
|
||||
user << "You add [W] to [src]."
|
||||
get_cameras() // the tracking code will want to know the new camera list
|
||||
if(bugtype in list(UNIVERSAL_BUG,NETWORK_BUG,ADMIN_BUG))
|
||||
skip_bugcheck = 1
|
||||
return
|
||||
|
||||
#undef VANILLA_BUG
|
||||
#undef UNIVERSAL_BUG
|
||||
#undef NETWORK_BUG
|
||||
#undef SABOTAGE_BUG
|
||||
#undef ADVANCED_BUG
|
||||
#undef ADMIN_BUG
|
||||
|
||||
#undef BUGMODE_LIST
|
||||
#undef BUGMODE_MONITOR
|
||||
#undef BUGMODE_TRACK
|
||||
@@ -1,47 +0,0 @@
|
||||
/obj/item/device/handtv
|
||||
name = "handheld tv"
|
||||
desc = "A handheld tv meant for remote viewing."
|
||||
icon_state = "handtv"
|
||||
w_class = 1
|
||||
var/obj/machinery/camera/current = null
|
||||
|
||||
/obj/item/device/handtv/attack_self(mob/usr as mob)
|
||||
var/list/cameras = new/list()
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if (C.hasbug && C.status)
|
||||
cameras.Add(C)
|
||||
if (length(cameras) == 0)
|
||||
usr << "\red No bugged functioning cameras found."
|
||||
return
|
||||
|
||||
var/list/friendly_cameras = new/list()
|
||||
|
||||
for (var/obj/machinery/camera/C in cameras)
|
||||
friendly_cameras.Add(C.c_tag)
|
||||
|
||||
var/target = input("Select the camera to observe", null) as null|anything in friendly_cameras
|
||||
if (!target)
|
||||
usr.unset_machine()
|
||||
usr.reset_view(usr)
|
||||
src.in_use = 0
|
||||
return
|
||||
for (var/obj/machinery/camera/C in cameras)
|
||||
if (C.c_tag == target)
|
||||
target = C
|
||||
break
|
||||
if (usr.stat == 2) return
|
||||
if(target)
|
||||
usr.client.eye = target
|
||||
usr.set_machine(src)
|
||||
src.current = target
|
||||
src.in_use = 1
|
||||
else
|
||||
usr.unset_machine()
|
||||
src.in_use = 0
|
||||
return
|
||||
|
||||
/obj/item/device/handtv/check_eye(var/mob/usr as mob)
|
||||
if ( src.loc != usr || usr.get_active_hand() != src|| !usr.canmove || usr.blinded || !current || !current.status )
|
||||
return null
|
||||
usr.reset_view(current)
|
||||
return 1
|
||||
@@ -41,22 +41,6 @@
|
||||
|
||||
autoignition_temperature = 530 // Kelvin
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/surveillance
|
||||
name = "\improper DromedaryCo packet"
|
||||
desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\""
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "Dpacket"
|
||||
item_state = "Dpacket"
|
||||
w_class = 1
|
||||
foldable = null
|
||||
New()
|
||||
..()
|
||||
contents = list()
|
||||
sleep(1)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/device/camera_bug(src)
|
||||
|
||||
/obj/item/weapon/storage/box/survival
|
||||
New()
|
||||
..()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
new /obj/item/weapon/card/id/syndicate(src)
|
||||
new /obj/item/weapon/card/id/syndicate(src)
|
||||
new /obj/item/clothing/shoes/syndigaloshes(src)
|
||||
new /obj/item/device/camera_bug(src)
|
||||
return
|
||||
|
||||
if("stealth")
|
||||
@@ -134,15 +135,6 @@
|
||||
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/surveillance
|
||||
name = "box (S)"
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/surveillance/New()
|
||||
..()
|
||||
new /obj/item/device/handtv(src)
|
||||
new /obj/item/weapon/storage/box/surveillance(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/conversion
|
||||
name = "box (CK)"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user