mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-21 22:47:02 +01:00
requires #6644 Entirely replaces how (most) belts perform insertion checks. This pretty much allows belts to hold most things. Armor vests are next. Trashbags will also use the systems we use on main. Closes #7256 and #7435 --------- Co-authored-by: silicons <silicons@silicons.dev>
167 lines
5.0 KiB
Plaintext
167 lines
5.0 KiB
Plaintext
#define OVERLAY_CACHE_LEN 50
|
|
|
|
/obj/item/t_scanner
|
|
name = "\improper T-ray scanner"
|
|
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
|
icon = 'icons/obj/device.dmi'
|
|
icon_state = "t-ray0"
|
|
item_state = "t-ray"
|
|
slot_flags = SLOT_BELT
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
materials_base = list(MAT_STEEL = 150)
|
|
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
|
|
suit_storage_class = SUIT_STORAGE_CLASS_SOFTWEAR | SUIT_STORAGE_CLASS_HARDWEAR
|
|
belt_storage_class = BELT_CLASS_SMALL
|
|
|
|
var/scan_range = 1
|
|
|
|
var/on = 0
|
|
var/list/active_scanned = list() //assoc list of objects being scanned, mapped to their overlay
|
|
var/client/user_client //since making sure overlays are properly added and removed is pretty important, so we track the current user explicitly
|
|
var/flicker = 0
|
|
|
|
var/global/list/overlay_cache = list() //cache recent overlays
|
|
|
|
/obj/item/t_scanner/update_icon()
|
|
. = ..()
|
|
icon_state = "t-ray[on]"
|
|
|
|
/obj/item/t_scanner/AltClick()
|
|
set_active(!on)
|
|
|
|
/obj/item/t_scanner/attack_self(mob/user, datum/event_args/actor/actor)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
set_active(!on)
|
|
|
|
/obj/item/t_scanner/proc/set_active(var/active)
|
|
on = active
|
|
if(on)
|
|
START_PROCESSING(SSobj, src)
|
|
flicker = 0
|
|
else
|
|
STOP_PROCESSING(SSobj, src)
|
|
set_user_client(null)
|
|
update_icon()
|
|
|
|
//If reset is set, then assume the client has none of our overlays, otherwise we only send new overlays.
|
|
/obj/item/t_scanner/process(delta_time)
|
|
if(!on) return
|
|
|
|
//handle clients changing
|
|
var/client/loc_client = null
|
|
if(ismob(src.loc))
|
|
var/mob/M = src.loc
|
|
loc_client = M.client
|
|
set_user_client(loc_client)
|
|
|
|
//no sense processing if no-one is going to see it.
|
|
if(!user_client) return
|
|
|
|
//get all objects in scan range
|
|
var/list/scanned = get_scanned_objects(scan_range)
|
|
var/list/update_add = scanned - active_scanned
|
|
var/list/update_remove = active_scanned - scanned
|
|
|
|
//Add new overlays
|
|
for(var/obj/O in update_add)
|
|
var/image/overlay = get_overlay(O)
|
|
active_scanned[O] = overlay
|
|
user_client.images += overlay
|
|
|
|
//Remove stale overlays
|
|
for(var/obj/O in update_remove)
|
|
user_client.images -= active_scanned[O]
|
|
active_scanned -= O
|
|
|
|
//Flicker effect
|
|
for(var/obj/O in active_scanned)
|
|
var/image/overlay = active_scanned[O]
|
|
if(flicker)
|
|
overlay.alpha = 0
|
|
else
|
|
overlay.alpha = 128
|
|
flicker = !flicker
|
|
|
|
//creates a new overlay for a scanned object
|
|
/obj/item/t_scanner/proc/get_overlay(obj/scanned)
|
|
//Use a cache so we don't create a whole bunch of new images just because someone's walking back and forth in a room.
|
|
//Also means that images are reused if multiple people are using t-rays to look at the same objects.
|
|
if(scanned in overlay_cache)
|
|
. = overlay_cache[scanned]
|
|
else
|
|
var/image/I = image(loc = scanned, icon = scanned.icon, icon_state = scanned.icon_state, layer = ABOVE_LIGHTING_LAYER_MAIN)
|
|
I.plane = ABOVE_LIGHTING_PLANE
|
|
|
|
//Pipes are special
|
|
if(istype(scanned, /obj/machinery/atmospherics/pipe))
|
|
var/obj/machinery/atmospherics/pipe/P = scanned
|
|
I.color = P.pipe_color
|
|
I.copy_overlays(P)
|
|
|
|
I.alpha = 128
|
|
I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
. = I
|
|
|
|
// Add it to cache, cutting old entries if the list is too long
|
|
overlay_cache[scanned] = .
|
|
if(overlay_cache.len > OVERLAY_CACHE_LEN)
|
|
overlay_cache.Cut(1, overlay_cache.len-OVERLAY_CACHE_LEN-1)
|
|
|
|
/obj/item/t_scanner/proc/get_scanned_objects(var/scan_dist)
|
|
. = list()
|
|
|
|
var/turf/center = get_turf(src.loc)
|
|
if(!center)
|
|
return
|
|
|
|
// the reason we don't just obj in range is because some things
|
|
// will INVISIBILITY_ABSTRACt while hiding underfloor,
|
|
// so normal range won't pick it up
|
|
for(var/turf/T in range(scan_range, center))
|
|
if(!T.hides_underfloor_objects())
|
|
continue
|
|
|
|
for(var/obj/O in T.contents)
|
|
if(!O.is_hidden_underfloor())
|
|
continue
|
|
if(!O.invisibility)
|
|
continue //if it's already visible don't need an overlay for it
|
|
. += O
|
|
|
|
/obj/item/t_scanner/proc/set_user_client(var/client/new_client)
|
|
if(new_client == user_client)
|
|
return
|
|
if(user_client)
|
|
for(var/scanned in active_scanned)
|
|
user_client.images -= active_scanned[scanned]
|
|
if(new_client)
|
|
for(var/scanned in active_scanned)
|
|
new_client.images += active_scanned[scanned]
|
|
else
|
|
active_scanned.Cut()
|
|
|
|
user_client = new_client
|
|
|
|
/obj/item/t_scanner/dropped(mob/user, atom_flags, atom/newLoc)
|
|
. = ..()
|
|
set_user_client(null)
|
|
|
|
/obj/item/t_scanner/upgraded
|
|
name = "Upgraded T-ray Scanner"
|
|
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
|
materials_base = list(MAT_STEEL = 500, PHORON = 150)
|
|
origin_tech = list(TECH_MAGNET = 4, TECH_ENGINEERING = 5)
|
|
scan_range = 3
|
|
|
|
/obj/item/t_scanner/advanced
|
|
name = "Advanced T-ray Scanner"
|
|
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
|
materials_base = list(MAT_STEEL = 1500, PHORON = 200, SILVER = 250)
|
|
origin_tech = list(TECH_MAGNET = 7, TECH_ENGINEERING = 7, TECH_MATERIAL = 6)
|
|
scan_range = 7
|
|
|
|
|
|
#undef OVERLAY_CACHE_LEN
|