mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Proximity sensing refactor (#26260)
* New proximity monitor datum * Replace the old systems * Fixes #26254 * Ports a New and spawn to Initialize * Switch to Moved * Remove unused var * Speedup and fixes * More speed * qdel in movable * Uneeded now * Fix * Use the faster RANGE_TURFS
This commit is contained in:
committed by
duncathan salt
parent
7dcfe586ea
commit
4f14ca7a49
@@ -1137,46 +1137,6 @@ B --><-- A
|
||||
if(location == src)
|
||||
return 1
|
||||
|
||||
/proc/add_to_proximity_list(atom/A, range)
|
||||
var/turf/T = get_turf(A)
|
||||
if(!T || !A.loc)
|
||||
throw EXCEPTION("Someone adding a prox sensor in nullspace")
|
||||
var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z))
|
||||
for(var/B in L)
|
||||
var/turf/C = B
|
||||
LAZYINITLIST(C.proximity_checkers)
|
||||
C.proximity_checkers[A] = TRUE
|
||||
return L
|
||||
|
||||
/proc/remove_from_proximity_list(atom/A, range, oldloc = null)
|
||||
var/turf/T = get_turf(oldloc ? oldloc : A)
|
||||
var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z))
|
||||
for(var/B in L)
|
||||
var/turf/C = B
|
||||
if (!C.proximity_checkers)
|
||||
continue
|
||||
C.proximity_checkers.Remove(A)
|
||||
|
||||
/proc/shift_proximity(atom/checker, atom/A, range, atom/B, newrange)
|
||||
var/turf/T = get_turf(A)
|
||||
var/turf/Q = get_turf(B)
|
||||
if(T == Q && range == newrange)
|
||||
return 0
|
||||
var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z))
|
||||
var/list/M = block(locate(Q.x - newrange, Q.y - newrange, Q.z), locate(Q.x + newrange, Q.y + newrange, Q.z))
|
||||
var/list/N = L - M
|
||||
var/list/O = M - L
|
||||
for(var/C in N)
|
||||
var/turf/D = C
|
||||
if (!D.proximity_checkers)
|
||||
continue
|
||||
D.proximity_checkers.Remove(checker)
|
||||
for(var/E in O)
|
||||
var/turf/F = E
|
||||
LAZYINITLIST(F.proximity_checkers)
|
||||
F.proximity_checkers[checker] = TRUE
|
||||
return 1
|
||||
|
||||
/proc/flick_overlay_static(image/I, atom/A, duration)
|
||||
set waitfor = 0
|
||||
if(!A || !I)
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
|
||||
@@ -121,6 +121,10 @@
|
||||
|
||||
if(flags & CLEAN_ON_MOVE)
|
||||
clean_on_move()
|
||||
|
||||
var/datum/proximity_monitor/pc = proximity_monitor
|
||||
if(pc)
|
||||
pc.HandleMove()
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/clean_on_move()
|
||||
@@ -171,6 +175,8 @@
|
||||
|
||||
if(stationloving && force)
|
||||
STOP_PROCESSING(SSinbounds, src)
|
||||
|
||||
QDEL_NULL(proximity_monitor)
|
||||
|
||||
. = ..()
|
||||
if(loc)
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
assembly.state = 4
|
||||
GLOB.cameranet.cameras += src
|
||||
GLOB.cameranet.addCamera(src)
|
||||
add_to_proximity_list(src, 1) //1 was default of everything
|
||||
proximity_monitor = new(src, 1)
|
||||
|
||||
/* // Use this to look for cameras that have the same c_tag.
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
var/list/tempnetwork = C.network&src.network
|
||||
@@ -59,13 +60,8 @@
|
||||
if(mapload && z == 1 && prob(3) && !start_active)
|
||||
toggle_cam()
|
||||
|
||||
/obj/machinery/camera/Move()
|
||||
remove_from_proximity_list(src, 1)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
toggle_cam(null, 0) //kick anyone viewing out
|
||||
remove_from_proximity_list(src, 1)
|
||||
if(assembly)
|
||||
qdel(assembly)
|
||||
assembly = null
|
||||
|
||||
@@ -154,6 +154,10 @@
|
||||
new /obj/item/stack/sheet/metal (loc, 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/flasher/portable/Initialize()
|
||||
. = ..()
|
||||
proximity_monitor = new(src, 0)
|
||||
|
||||
/obj/machinery/flasher/portable/HasProximity(atom/movable/AM)
|
||||
if (last_flash && world.time < last_flash + 150)
|
||||
return
|
||||
@@ -172,25 +176,17 @@
|
||||
add_overlay("[base_state]-s")
|
||||
anchored = 1
|
||||
power_change()
|
||||
add_to_proximity_list(src, range)
|
||||
proximity_monitor.SetRange(range)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] can now be moved.</span>")
|
||||
cut_overlays()
|
||||
anchored = 0
|
||||
power_change()
|
||||
remove_from_proximity_list(src, range)
|
||||
proximity_monitor.SetRange(0)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/flasher/portable/Destroy()
|
||||
remove_from_proximity_list(src, range)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/flasher/portable/Moved(oldloc)
|
||||
remove_from_proximity_list(oldloc, range)
|
||||
return ..()
|
||||
|
||||
/obj/item/wallframe/flasher
|
||||
name = "mounted flash frame"
|
||||
desc = "Used for building wall-mounted flashers."
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
/obj/effect/blob_act()
|
||||
return
|
||||
|
||||
/obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
return 0
|
||||
|
||||
/obj/effect/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/obj/effect/ex_act(severity, target)
|
||||
if(target == src)
|
||||
qdel(src)
|
||||
@@ -37,12 +43,15 @@
|
||||
if(prob(25))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
return 0
|
||||
|
||||
/obj/effect/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/obj/effect/singularity_act()
|
||||
qdel(src)
|
||||
return 0
|
||||
return 0
|
||||
|
||||
/obj/effect/abstract/ex_act(severity, target)
|
||||
return
|
||||
|
||||
/obj/effect/abstract/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/abstract/singularity_act()
|
||||
return
|
||||
97
code/game/objects/effects/proximity.dm
Normal file
97
code/game/objects/effects/proximity.dm
Normal file
@@ -0,0 +1,97 @@
|
||||
/datum/proximity_monitor
|
||||
var/atom/host //the atom we are tracking
|
||||
var/atom/last_host_loc
|
||||
var/list/checkers //list of /obj/effect/abstract/proximity_checkers
|
||||
var/current_range
|
||||
var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf
|
||||
|
||||
/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
|
||||
host = _host
|
||||
last_host_loc = _host.loc
|
||||
ignore_if_not_on_turf = _ignore_if_not_on_turf
|
||||
SetRange(range)
|
||||
|
||||
/datum/proximity_monitor/Destroy()
|
||||
host = null
|
||||
QDEL_LIST(checkers)
|
||||
return ..()
|
||||
|
||||
/datum/proximity_monitor/proc/HandleMove()
|
||||
var/atom/_host = host
|
||||
var/atom/new_host_loc = _host.loc
|
||||
if(last_host_loc != new_host_loc)
|
||||
last_host_loc = new_host_loc //hopefully this won't cause GC issues with containers
|
||||
var/curr_range = current_range
|
||||
SetRange(curr_range, TRUE)
|
||||
if(curr_range)
|
||||
testing("HasProx: [host] -> [host]")
|
||||
_host.HasProximity(host) //if we are processing, we're guaranteed to be a movable
|
||||
|
||||
/datum/proximity_monitor/proc/SetRange(range, force_rebuild = FALSE)
|
||||
if(!force_rebuild && range == current_range)
|
||||
return FALSE
|
||||
. = TRUE
|
||||
|
||||
current_range = range
|
||||
|
||||
var/list/old_checkers = checkers
|
||||
var/old_checkers_len = LAZYLEN(old_checkers)
|
||||
|
||||
var/atom/host_loc = host.loc
|
||||
|
||||
var/atom/loc_to_use = ignore_if_not_on_turf ? host_loc : get_turf(host)
|
||||
if(!isturf(loc_to_use)) //only check the host's loc
|
||||
if(range)
|
||||
var/obj/effect/abstract/proximity_checker/pc
|
||||
if(old_checkers_len)
|
||||
pc = old_checkers[old_checkers_len]
|
||||
--old_checkers.len
|
||||
else
|
||||
pc = new(host_loc, src)
|
||||
|
||||
checkers = list(pc) //only check the host's loc
|
||||
return
|
||||
|
||||
var/list/turfs = RANGE_TURFS(range, loc_to_use)
|
||||
var/old_checkers_used = min(turfs.len, old_checkers_len)
|
||||
|
||||
//reuse what we can
|
||||
for(var/I in 1 to old_checkers_len)
|
||||
if(I <= old_checkers_used)
|
||||
var/obj/effect/abstract/proximity_checker/pc = old_checkers[I]
|
||||
pc.loc = turfs[I]
|
||||
else
|
||||
qdel(old_checkers[I]) //delete the leftovers
|
||||
|
||||
LAZYCLEARLIST(old_checkers)
|
||||
|
||||
//create what we lack
|
||||
var/list/checkers_local = list()
|
||||
for(var/I in (old_checkers_used + 1) to turfs.len)
|
||||
checkers_local += new /obj/effect/abstract/proximity_checker(turfs[I], src)
|
||||
|
||||
checkers = checkers_local
|
||||
|
||||
/obj/effect/abstract/proximity_checker
|
||||
var/datum/proximity_monitor/monitor
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Initialize(mapload, datum/proximity_monitor/_monitor)
|
||||
. = ..()
|
||||
if(_monitor)
|
||||
monitor = _monitor
|
||||
else
|
||||
stack_trace("proximity_checker created without proximity_monitor")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Destroy()
|
||||
monitor = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
|
||||
set waitfor = FALSE
|
||||
var/datum/proximity_monitor/M = monitor
|
||||
if(!M.current_range)
|
||||
return
|
||||
var/atom/H = M.host
|
||||
testing("HasProx: [H] -> [AM]")
|
||||
H.HasProximity(AM)
|
||||
@@ -227,7 +227,6 @@
|
||||
layer = MOB_LAYER
|
||||
var/obj/item/clothing/mask/facehugger/child
|
||||
|
||||
|
||||
/obj/structure/alien/egg/Initialize(mapload)
|
||||
..()
|
||||
update_icon()
|
||||
@@ -235,15 +234,10 @@
|
||||
child = new(src)
|
||||
if(status == GROWING)
|
||||
addtimer(CALLBACK(src, .proc/Grow), rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
|
||||
if(status == GROWN)
|
||||
add_to_proximity_list(src, 1)
|
||||
proximity_monitor = new(src, status == GROWN ? 1 : 0)
|
||||
if(status == BURST)
|
||||
obj_integrity = integrity_failure
|
||||
|
||||
/obj/structure/alien/egg/Destroy()
|
||||
remove_from_proximity_list(src, 1)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/alien/egg/update_icon()
|
||||
..()
|
||||
switch(status)
|
||||
@@ -283,12 +277,12 @@
|
||||
/obj/structure/alien/egg/proc/Grow()
|
||||
status = GROWN
|
||||
update_icon()
|
||||
add_to_proximity_list(src, 1)
|
||||
proximity_monitor.SetRange(1)
|
||||
|
||||
//drops and kills the hugger if any is remaining
|
||||
/obj/structure/alien/egg/proc/Burst(kill = TRUE)
|
||||
if(status == GROWN || status == GROWING)
|
||||
remove_from_proximity_list(src, 1)
|
||||
proximity_monitor.SetRange(0)
|
||||
status = BURST
|
||||
update_icon()
|
||||
flick("egg_opening", src)
|
||||
@@ -307,12 +301,6 @@
|
||||
child.Attach(M)
|
||||
break
|
||||
|
||||
/obj/structure/alien/egg/Moved(oldloc)
|
||||
remove_from_proximity_list(oldloc, 1)
|
||||
if(status == GROWN)
|
||||
add_to_proximity_list(src, 1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/alien/egg/obj_break(damage_flag)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
if(status != BURST)
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
flags = CAN_BE_DIRTY
|
||||
|
||||
var/list/proximity_checkers
|
||||
|
||||
var/image/obscured //camerachunks
|
||||
|
||||
var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes
|
||||
@@ -156,10 +154,6 @@
|
||||
return 1 //Nothing found to block so return success!
|
||||
|
||||
/turf/Entered(atom/movable/AM)
|
||||
for(var/A in proximity_checkers)
|
||||
var/atom/B = A
|
||||
B.HasProximity(AM)
|
||||
|
||||
if(explosion_level && AM.ex_check(explosion_id))
|
||||
AM.ex_act(explosion_level)
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
var/timing = 0
|
||||
var/time = 10
|
||||
var/sensitivity = 1
|
||||
var/atom/oldloc
|
||||
var/list/turfs_around = list()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/proc/toggle_scan()
|
||||
|
||||
@@ -19,22 +17,15 @@
|
||||
/obj/item/device/assembly/prox_sensor/proc/sense()
|
||||
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
oldloc = loc
|
||||
/obj/item/device/assembly/prox_sensor/Initialize()
|
||||
. = ..()
|
||||
proximity_monitor = new(src, 0)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/describe()
|
||||
if(timing)
|
||||
return "<span class='notice'>The proximity sensor is arming.</span>"
|
||||
return "The proximity sensor is [scanning?"armed":"disarmed"]."
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/on_attach(datum/wires/w)
|
||||
handle_move(w.holder)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/on_detach(datum/wires/w)
|
||||
handle_move(w.holder.loc)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/activate()
|
||||
if(!..())
|
||||
return 0//Cooldown check
|
||||
@@ -42,12 +33,15 @@
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/toggle_secure()
|
||||
secured = !secured
|
||||
if(!secured)
|
||||
scanning = 0
|
||||
if(scanning)
|
||||
toggle_scan()
|
||||
proximity_monitor.host = src
|
||||
timing = 0
|
||||
else
|
||||
proximity_monitor.host = loc
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
@@ -73,36 +67,19 @@
|
||||
timing = 0
|
||||
toggle_scan(1)
|
||||
time = initial(time)
|
||||
handle_move(loc)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/dropped()
|
||||
..()
|
||||
if(scanning)
|
||||
INVOKE_ASYNC(src, .proc/sense)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/Destroy()
|
||||
if(scanning)
|
||||
remove_from_proximity_list(src, sensitivity, oldloc)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/toggle_scan(scan)
|
||||
if(!secured)
|
||||
return 0
|
||||
scanning = scan
|
||||
if(scanning)
|
||||
add_to_proximity_list(src, sensitivity)
|
||||
else
|
||||
remove_from_proximity_list(src, sensitivity)
|
||||
oldloc = get_turf(loc)
|
||||
proximity_monitor.SetRange(scanning ? sensitivity : 0)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/proc/sensitivity_change(value)
|
||||
var/sense = min(max(sensitivity + value, 0), 5)
|
||||
if(scanning)
|
||||
if(shift_proximity(src, oldloc, sensitivity, loc, sense))
|
||||
sense()
|
||||
oldloc = loc
|
||||
sensitivity = sense
|
||||
if(scanning && proximity_monitor.SetRange(sense))
|
||||
sense()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/update_icon()
|
||||
cut_overlays()
|
||||
@@ -117,17 +94,6 @@
|
||||
holder.update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/proc/handle_move(atom/newloc)
|
||||
if(scanning)
|
||||
if(shift_proximity(src, oldloc, sensitivity, newloc, sensitivity) || newloc != oldloc)
|
||||
sense()
|
||||
oldloc = newloc
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/Moved()
|
||||
..()
|
||||
handle_move(loc)
|
||||
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy
|
||||
if(is_secured(user))
|
||||
var/second = time % 60
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
var/machinedir = SOUTHEAST
|
||||
speed_process = 1
|
||||
|
||||
/obj/machinery/mineral/stacking_unit_console/New()
|
||||
..()
|
||||
spawn(7)
|
||||
src.machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
|
||||
if (machine)
|
||||
machine.CONSOLE = src
|
||||
else
|
||||
qdel(src)
|
||||
/obj/machinery/mineral/stacking_unit_console/Initialize()
|
||||
. = ..()
|
||||
machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
|
||||
if (machine)
|
||||
machine.CONSOLE = src
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/mineral/stacking_unit_console/attack_hand(mob/user)
|
||||
|
||||
@@ -71,6 +70,14 @@
|
||||
input_dir = EAST
|
||||
output_dir = WEST
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/Initialize()
|
||||
. = ..()
|
||||
proximity_monitor = new(src, 1)
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/HasProximity(atom/movable/AM)
|
||||
if(istype(AM, /obj/item/stack/sheet) && AM.loc == get_step(src, input_dir))
|
||||
process_sheet(AM)
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/proc/process_sheet(obj/item/stack/sheet/inp)
|
||||
if(!(inp.type in stack_list)) //It's the first of this sheet added
|
||||
var/obj/item/stack/sheet/s = new inp.type(src,0)
|
||||
@@ -83,10 +90,4 @@
|
||||
var/obj/item/stack/sheet/out = new inp.type()
|
||||
out.amount = stack_amt
|
||||
unload_mineral(out)
|
||||
storage.amount -= stack_amt
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/process()
|
||||
var/turf/T = get_step(src, input_dir)
|
||||
if(T)
|
||||
for(var/obj/item/stack/sheet/S in T)
|
||||
process_sheet(S)
|
||||
storage.amount -= stack_amt
|
||||
@@ -656,6 +656,7 @@
|
||||
#include "code\game\objects\effects\mines.dm"
|
||||
#include "code\game\objects\effects\misc.dm"
|
||||
#include "code\game\objects\effects\overlays.dm"
|
||||
#include "code\game\objects\effects\proximity.dm"
|
||||
#include "code\game\objects\effects\portals.dm"
|
||||
#include "code\game\objects\effects\spiders.dm"
|
||||
#include "code\game\objects\effects\step_triggers.dm"
|
||||
|
||||
Reference in New Issue
Block a user