From 64068fc614f687ea6dccf7586a7a497b79556000 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 16 Apr 2017 17:15:29 -0500 Subject: [PATCH] Proximity sensing refactor (#425) --- code/__HELPERS/unsorted.dm | 40 ---------- code/game/atoms.dm | 2 + code/game/atoms_movable.dm | 6 ++ code/game/machinery/camera/camera.dm | 8 +- code/game/machinery/flasher.dm | 16 ++-- code/game/objects/effects/effects.dm | 23 ++++-- code/game/objects/effects/proximity.dm | 97 +++++++++++++++++++++++++ code/game/objects/structures/aliens.dm | 18 +---- code/game/turfs/turf.dm | 6 -- code/modules/assembly/proximity.dm | 56 +++----------- code/modules/mining/machine_stacking.dm | 31 ++++---- tgstation.dme | 1 + 12 files changed, 160 insertions(+), 144 deletions(-) create mode 100644 code/game/objects/effects/proximity.dm diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 73b4c33620..f57e801658 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -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) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 8de954c5b6..6dc215bbcc 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -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() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index fbfe6b5834..61942a9c58 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -120,6 +120,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() @@ -170,6 +174,8 @@ if(stationloving && force) STOP_PROCESSING(SSinbounds, src) + + QDEL_NULL(proximity_monitor) . = ..() if(loc) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 592a7b6967..080f85e977 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -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 diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index c26094e2bd..6904067e2a 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -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, "[src] can now be moved.") 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." diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 6646735613..365d7f1c26 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -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 \ No newline at end of file + return 0 + +/obj/effect/abstract/ex_act(severity, target) + return + +/obj/effect/abstract/singularity_pull() + return + +/obj/effect/abstract/singularity_act() + return \ No newline at end of file diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm new file mode 100644 index 0000000000..8fabe3fce0 --- /dev/null +++ b/code/game/objects/effects/proximity.dm @@ -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) \ No newline at end of file diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index cd5a72d308..d46136a9ae 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -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) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b6ed50c576..10eefc4b14 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -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) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 8375fa3e56..1856313b36 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -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 "The proximity sensor is arming." 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 diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index c148f83d17..e7b0c12aac 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -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) @@ -70,6 +69,14 @@ var/stack_amt = 50; //ammount to stack before releassing 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 @@ -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 \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index fc5dbae6f4..97e665b378 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -686,6 +686,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"