Files
BatrachophrenoandGitHub 8111a8489b Restore many missing inhand sprites for items, add/port others (#21831)
Many, many, many items have inhand sprites in their .dmis but for
whatever reasons do not display them in-game. This PR:

1. Updates many item definitions to point to their already-existing
inhands correctly. This consists largely of held tools, but also gas
tanks and jetpacks mounted in the suit storage slot.

2. Adds a few codersprites made by me for objects with either missing
inhands or poorly matching mishands (IE, the tape recorder, which has a
black case, reused the white inhand sprites of the health analyzer). The
new sprites are modified or recolored variations of other inhand sprites
from our repo, except for circuitboards which are new.
<img width="444" height="400" alt="image"
src="https://github.com/user-attachments/assets/7f107b9a-fe24-4e31-8f16-4d34768ee117"
/>


3. Adds inhand sprites for Inflatables and Inflatable Boxes made by
Tomixcomics.
<img width="424" height="101" alt="image"
src="https://github.com/user-attachments/assets/434107c4-8577-49a2-a58e-d6b014c03933"
/>

4. Ports inhand sprites for the Hydraulic Rescue Tool from tg's Jaws of
Life.
<img width="224" height="94" alt="Screenshot 2026-02-07 172931"
src="https://github.com/user-attachments/assets/070c7956-f6a8-4fb5-870f-10c64afcc8b3"
/>

5. Some additional cleanup while in the area. The 'analyzer' has been
renamed the 'gas analyzer' to be consistent with the other analyzer
objects, standardized icon_state naming conventions where I saw
oddballs, updated code docs to use DMDocs when in the area, etc.

### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:

| Path | Original Author | License |
| --- | --- | --- |
| icons/obj/item/hydraulic_rescue_tool.dmi | [SomeAngryMiner (bee
station)](https://github.com/BeeStation/BeeStation-Hornet/pull/2487),
[maxymax
(/tg/station)](https://github.com/tgstation/tgstation/pull/58616) |
CC-BY-SA |
| icons/obj/item/inflatables.dmi |
[Tomixcomics](https://github.com/tomixcomics) | CC-BY-SA |
2026-02-17 17:51:22 +00:00

307 lines
8.8 KiB
Plaintext

/obj/machinery/computer/security
name = "security camera monitor"
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "yellow_key"
icon_keyboard_emis = "yellow_key_mask"
light_color = LIGHT_COLOR_YELLOW
var/current_network = null
var/obj/machinery/camera/current_camera = null
var/last_pic = 1.0
var/list/console_networks
var/mapping = 0
var/cache_id = 0
/// A currently active program running on the computer.
var/datum/computer_file/program/camera_monitor/camera_monitor_program
circuit = /obj/item/circuitboard/security
/obj/machinery/computer/security/Initialize()
if(!console_networks)
console_networks = SSatlas.current_map.station_networks.Copy()
. = ..()
if(console_networks.len)
current_network = console_networks[1]
// Create a new camera_monitor program that can run independently of a modular computer.
camera_monitor_program = new("Compless")
// Make sure that camera_monitor knows its been generated from a dedicated console; this will define its network access.
camera_monitor_program.monitored_networks = console_networks
/obj/machinery/computer/security/Destroy()
if(camera_monitor_program)
camera_monitor_program = null
. = ..()
/obj/machinery/computer/security/attack_ai(var/mob/user as mob)
if(!ai_can_interact(user))
return
return attack_hand(user)
/obj/machinery/computer/security/check_eye(var/mob/user as mob)
if (user.stat || user.blinded || !operable())
return -1
if(!current_camera)
return 0
var/viewflag = current_camera.check_eye(user)
if ( viewflag < 0 ) //camera doesn't work
reset_current()
return viewflag
/obj/machinery/computer/security/grants_equipment_vision(var/mob/user as mob)
if(user.stat || user.blinded || !operable())
return FALSE
if(!current_camera)
return FALSE
var/viewflag = current_camera.check_eye(user)
if (viewflag < 0) //camera doesn't work
return FALSE
return TRUE
/obj/machinery/computer/security/proc/can_access_network(var/mob/user, var/network_access)
// No access passed, or 0 which is considered no access requirement. Allow it.
if(!network_access)
return TRUE
return (check_camera_access(user, ACCESS_SECURITY) && GLOB.security_level >= SEC_LEVEL_BLUE) || check_camera_access(user, network_access)
/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
if(camera_monitor_program)
ui = new(user, src, camera_monitor_program.tgui_id, camera_monitor_program.filedesc)
ui.autoupdate = camera_monitor_program.ui_auto_update
else
to_chat(usr, "Something has gone wrong; please report the circumstances in which you received this message to the GitHub issues tracker.")
return
ui.open()
/obj/machinery/computer/security/ui_data(mob/user)
var/list/data = list()
if(camera_monitor_program)
data += camera_monitor_program.ui_data(user)
return data
/obj/machinery/computer/security/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
if(camera_monitor_program)
. = camera_monitor_program.ui_act(action, params, ui, state)
/obj/machinery/computer/security/attack_hand(var/mob/user as mob)
if (!(src.z in GetConnectedZlevels(starting_z_level)))
to_chat(user, "Unable to establish a connection.")
return
if(stat & (NOPOWER|BROKEN)) return
if(!isAI(user))
user.set_machine(src)
user.reset_view(current_camera)
ui_interact(user)
/obj/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C)
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
if(isAI(user))
var/mob/living/silicon/ai/A = user
// Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise.
if(!A.is_in_chassis())
return 0
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
return 1
if (user.stat || user.blinded || !operable())
return 0
set_current(C)
if (!(C.z in GetConnectedZlevels(starting_z_level)))
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
return FALSE
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.reset_view(current_camera)
else
user.reset_view(current_camera)
check_eye(user)
return 1
/obj/machinery/computer/security/proc/check_camera_access(var/mob/user, var/access)
if(!access)
return 1
if(!istype(user))
return 0
var/obj/item/card/id/I = user.GetIdCard()
if(!I)
return 0
if(access in I.access)
return 1
return 0
//Camera control: moving.
/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A)
if(user.machine != src)
return
var/obj/machinery/camera/jump_to
if(istype(A,/obj/machinery/camera))
jump_to = A
else if(ismob(A))
if(ishuman(A))
var/mob/living/carbon/human/H = A
jump_to = locate() in H.head
else if(isrobot(A))
var/mob/living/silicon/robot/R = A
jump_to = R.camera
else if(isobj(A))
jump_to = locate() in A
else if(isturf(A))
var/best_dist = INFINITY
var/check_area = get_area(A)
if (!check_area)
return
for(var/cc in SSmachinery.all_cameras)
var/obj/machinery/camera/camera = cc
if(!camera.loc)
continue
if (camera.loc.loc != check_area)
continue
if(!camera.can_use())
continue
if(!can_access_camera(camera))
continue
var/dist = get_dist(camera,A)
if(dist < best_dist)
best_dist = dist
jump_to = camera
if(isnull(jump_to))
return
if(can_access_camera(jump_to))
switch_to_camera(user,jump_to)
/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C)
var/list/shared_networks = src.console_networks & C.network
if(shared_networks.len)
return 1
return 0
/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C)
if(current_camera == C)
return
if(current_camera)
reset_current()
src.current_camera = C
if(current_camera)
update_use_power(POWER_USE_ACTIVE)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_initiated()
/obj/machinery/computer/security/proc/reset_current()
if(current_camera)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_cancelled()
current_camera = null
update_use_power(POWER_USE_IDLE)
/obj/machinery/computer/security/telescreen
name = "Telescreen"
desc = "Used for watching an empty arena."
icon = 'icons/obj/computer.dmi'
icon_state = "wallframe"
icon_screen = null
light_range_on = 0
console_networks = list(NETWORK_THUNDER)
density = 0
circuit = null
is_holographic = FALSE
/obj/machinery/computer/security/telescreen/entertainment
name = "entertainment monitor"
desc = "Damn, why do they never have anything interesting on these things?"
icon_screen = "entertainment"
light_color = "#FFEEDB"
light_range_on = 2
circuit = null
/obj/machinery/computer/security/wooden_tv
name = "security camera monitor"
desc = "An old TV hooked into the stations camera network."
icon = 'icons/obj/computer.dmi'
icon_state = "television"
icon_screen = "detective_tv"
circuit = null
light_color = "#3848B3"
light_power_on = 0.5
/obj/machinery/computer/security/mining
name = "outpost camera monitor"
desc = "Used to access the various cameras on the outpost."
icon_screen = "miningcameras"
icon_keyboard = "purple_key"
icon_keyboard_emis = "purple_key_mask"
light_color = LIGHT_COLOR_PURPLE
console_networks = list("MINE")
circuit = /obj/item/circuitboard/security/mining
/obj/machinery/computer/security/engineering
name = "engineering camera monitor"
desc = "Used to monitor fires and breaches."
icon_screen = "engineeringcameras"
icon_keyboard = "yellow_key"
icon_keyboard_emis = "yellow_key_mask"
light_color = LIGHT_COLOR_YELLOW
circuit = /obj/item/circuitboard/security/engineering
/obj/machinery/computer/security/engineering/terminal
name = "engineering camera monitor"
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
icon_screen = "engines"
icon_keyboard = "power_key"
icon_keyboard_emis = "power_key_mask"
is_connected = TRUE
has_off_keyboards = TRUE
can_pass_under = FALSE
light_power_on = 1
/obj/machinery/computer/security/engineering/Initialize()
if(!console_networks)
console_networks = GLOB.engineering_networks.Copy()
. = ..()
/obj/machinery/computer/security/nuclear
name = "head mounted camera monitor"
desc = "Used to access the built-in cameras in helmets."
icon_screen = "syndicam"
icon_keyboard = "red_key"
icon_keyboard_emis = "red_key_mask"
light_color = LIGHT_COLOR_RED
console_networks = list(NETWORK_MERCENARY)
circuit = null
/obj/machinery/computer/security/nuclear/Initialize()
. = ..()
req_access = list(150)
/obj/machinery/computer/security/terminal
name = "camera monitor terminal"
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
icon_screen = "cameras"
icon_keyboard = "security_key"
icon_keyboard_emis = "security_key_mask"
is_connected = TRUE
has_off_keyboards = TRUE
can_pass_under = FALSE
light_power_on = 1