Files
Paradise/code/datums/proximity/advanced_proximity_monitor.dm
PollardTheDragon 24845b238a The Divine Flock - DaedalusDock Flockmind Port (#31984)
* Initial commit - FLOCKMIND - Probably has like a billion things to fix

* Do after conversions

* Config

* Moved the files, icon fixes

* Tick everything, language work, event, spawn landmark, role prefs, beginning mob port

* Spans and some other fixes. Also the tickening

* More tickening

* More fixes. Lots of fixes.

* More Fixes

* A whole lot more. Also flock TGUI.

* Fixes fixes fixes fixes fixes

* FIXES

* More fixes - PR ready, still needs a fuckton of testing

* Fixes

* fix incomplete upstream merge

* fix FlockPanel + sort button name

* TGUI review

* Fixes tealprint list

* Fixes

* More fixes

* Incapacitator Fix

* Filenames

* Linters

* Interceptor range buff

* Reagent counts

* Linters

* Fabricator vendor fix

* Keybinds and HUD - Flockdrones, Fixes Vendor Conversion, Cube Materials

* Reworks reagent, adds flock grilles, fixes compute node overlays

* Intent-based flockdrone parts

* Intent based drone parts

* Radial control panel for controlling drones manually, phasing through windows/grilles

* Movement fixes

* Radio talk power, stare fix

* Flock health HUD

* Fixes flock lights, linters

* Unit tests

* Adds countdown to relay

* Relay improvements

* Small fix

* Logic Schmogic

* Relay overlay and looping sound effect

* Ignore air when converting turfs

* Cage fixes and improvements

* Improved flock bolt

* Turret conversions

* Flock bolts taze simple or basic mobs

* Sentience type

* Fixe

* Linter

* tgui review stage 2

* Concentrated Repair Burst

* Improves radio detection

* Removes extra space

* Adds healing visual effect

* Cube tech levels

* Ghooost

* Excess

* Flock doors, chairs, lattices. Centralizes conversion code.  Crafting with Gnesis

* Update code/modules/antagonists/flockmind/ai_behaviors/flock_wander.dm

Co-authored-by: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>

* Fixes the fix

* Astar movement detection

* Fix, extraneous code, language stuff

* Language fixes and wander fix

* Fixes

* Another fix

* Lints

* Another linter

* Language improvement

* More language improvements

* Time requirement and appearing in orbit menu as an antag

* Cube glow

* TGUI

* Minicache

* Linters

* Grammar

* Material ID fix

* Lid fix

* Reagent turf reaction

* Reagent fix

* Butcher results

* Conversion rates

* Flock stare fix

* Fixes stare behavior

* Staring

* Flock mob blood

* Flock mobs gibs and blood. Also some runtime fixes

* Flock mobs now resist out of grabs, buckles, lockers, and more

* Fixes flock orbit, fixes a runtime I think,

* Target mechs, damage mechs, other bug fixes

* Cage fix

* Cage resist change

* Some mind changes, gatecrash buff

* Drones now shoot mechs, stare improvement

* Cut down on spam a little

* Nest fix

* No more resist spam

* Fixed drone death control

* Resist statement

* Makes the relay alarm scarier

* Fixes dead flock camera mobs having no ghost sprite, something with ghosting

* Enhanced flockphasing

* Improved flockmob pathing

* Added required turf restriction to relay

* Increased needed bandwidth for relay construction

* Nerfed drone substrate rate

* Added new status tab items for relay progress

* Another relay cost adjustment

* Improves drone AI responsiveness

* Computer frames now become flock computers

* Improves target finding for conversion, building, and replicating

* Reduced flock event pop requirements

* Adjusts flock protection on structures. Adjusts overlays.

* Relay unlock tweak

* Fixwes flock being able to gib mech'd AIs with one button

* Map conflict

* Flock can no longer be outed by merely existing

* Fied bug causing drones to shoot themselves

* Prevents mobs from attacking while in a cage

* Converter tool can now open closets and crates.

* Adds descriptions to flockdrone tools.

* More informatic blurbs

* Adds xenobiology organs

* Organ lint

* TGUI merge

* bundle and mm

---------

Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Co-authored-by: Toastical <20125180+Toastical@users.noreply.github.com>
Co-authored-by: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
2026-07-08 21:31:28 +00:00

188 lines
6.9 KiB
Plaintext

#define FIELD_TURFS_KEY "field_turfs"
#define EDGE_TURFS_KEY "edge_turfs"
/**
* Movable and easily code-modified fields! Allows for custom AOE effects that affect movement
* and anything inside of them, and can do custom turf effects!
* Supports automatic recalculation/reset on movement.
*
* "What do I gain from using advanced over standard prox monitors?"
* - You can set different effects on edge vs field entrance
* - You can set effects when the proximity monitor starts and stops tracking a turf
*/
/datum/proximity_monitor/advanced
/// If TRUE, edge turfs will be included as "in the field" for effects
/// Can be used in certain situations where you may have effects that trigger only at the edge,
/// while also wanting the field effect to trigger at edge turfs as well
var/edge_is_a_field = FALSE
/// If TRUE, view() will be used over range(). If this is used, edge turfs will not exist!
var/use_view = FALSE
/// All turfs on the inside of the proximity monitor - range - 1 turfs
var/list/turf/field_turfs = list()
/// All turfs on the very last tile of the proximity monitor's radius
var/list/turf/edge_turfs = list()
/datum/proximity_monitor/advanced/Destroy()
cleanup_field()
return ..()
/datum/proximity_monitor/advanced/proc/cleanup_field()
for(var/turf/turf as anything in edge_turfs)
cleanup_edge_turf(turf)
cleanup_effects(turf)
edge_turfs = list()
for(var/turf/turf as anything in field_turfs)
cleanup_field_turf(turf)
cleanup_effects(turf)
field_turfs = list()
//Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
/datum/proximity_monitor/advanced/proc/recalculate_field(full_recalc = FALSE)
var/list/new_turfs = update_new_turfs()
var/list/old_field_turfs = field_turfs
var/list/old_edge_turfs = edge_turfs
field_turfs = new_turfs[FIELD_TURFS_KEY]
edge_turfs = new_turfs[EDGE_TURFS_KEY]
if(full_recalc)
field_turfs = list()
edge_turfs = list()
for(var/turf/old_turf as anything in old_field_turfs - field_turfs)
if(QDELETED(src))
return
cleanup_field_turf(old_turf)
cleanup_effects(old_turf)
for(var/turf/old_turf as anything in old_edge_turfs - edge_turfs)
if(QDELETED(src))
return
cleanup_edge_turf(old_turf)
cleanup_effects(old_turf)
if(full_recalc)
old_field_turfs = list()
old_edge_turfs = list()
field_turfs = new_turfs[FIELD_TURFS_KEY]
edge_turfs = new_turfs[EDGE_TURFS_KEY]
for(var/turf/new_turf as anything in field_turfs - old_field_turfs)
if(QDELETED(src))
return
setup_field_turf(new_turf)
for(var/turf/new_turf as anything in edge_turfs - old_edge_turfs)
if(QDELETED(src))
return
setup_edge_turf(new_turf)
/datum/proximity_monitor/advanced/on_initialized(turf/location, atom/created, init_flags)
. = ..()
on_entered(location, created, null)
/datum/proximity_monitor/advanced/on_entered(turf/source, atom/movable/entered, turf/old_loc)
. = ..()
if(get_dist(source, host) == current_range)
field_edge_crossed(entered, old_loc, source)
else
field_turf_crossed(entered, old_loc, source)
/datum/proximity_monitor/advanced/on_moved(atom/movable/movable, atom/old_loc)
. = ..()
if(ignore_if_not_on_turf)
//Early return if it's not the host that has moved.
if(movable != host)
return
//Cleanup the field if the host was on a turf but isn't anymore.
if(!isturf(host.loc))
if(isturf(old_loc))
cleanup_field()
return
recalculate_field(full_recalc = FALSE)
/datum/proximity_monitor/advanced/on_uncrossed(turf/source, atom/movable/gone, direction)
if(get_dist(source, host) == current_range)
field_edge_uncrossed(gone, source, get_turf(gone))
else
field_turf_uncrossed(gone, source, get_turf(gone))
/// Called when a turf in the field of the monitor is linked
/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/target)
return
/// Called when a turf in the field of the monitor is unlinked
/// Do NOT call this manually, requires management of the field_turfs list
/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/target)
PRIVATE_PROC(TRUE)
return
/// A holder proc for cleaning up various effects.
/datum/proximity_monitor/advanced/proc/cleanup_effects(turf/target)
return
/// Called when a turf in the edge of the monitor is linked
/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/target)
if(edge_is_a_field) // If the edge is considered a field, set it up like one
setup_field_turf(target)
/// Called when a turf in the edge of the monitor is unlinked
/// Do NOT call this manually, requires management of the edge_turfs list
/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/target)
if(edge_is_a_field) // If the edge is considered a field, clean it up like one
cleanup_field_turf(target)
/datum/proximity_monitor/advanced/proc/update_new_turfs()
if(ignore_if_not_on_turf && !isturf(host.loc))
return list(FIELD_TURFS_KEY = list(), EDGE_TURFS_KEY = list())
if(use_view)
var/list/turfs = list()
for(var/turf/T as turf in view(current_range, host))
turfs += T
return list(FIELD_TURFS_KEY = turfs, EDGE_TURFS_KEY = list())
var/list/local_field_turfs = list()
var/list/local_edge_turfs = list()
var/turf/center = get_turf(host)
if(current_range > 0)
local_field_turfs += RANGE_TURFS(current_range - 1, center)
if(current_range > 1)
local_edge_turfs = RANGE_TURFS(current_range, center) - local_field_turfs
return list(FIELD_TURFS_KEY = local_field_turfs, EDGE_TURFS_KEY = local_edge_turfs)
//Gets edge direction/corner, only works with square radius/WDH fields!
/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null)
var/turf/checking_from = get_turf(host)
if(istype(center_override))
checking_from = center_override
if(!(T in edge_turfs))
return
if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range))))
return get_dir(checking_from, T)
if(T.x == (checking_from.x + current_range))
return EAST
if(T.x == (checking_from.x - current_range))
return WEST
if(T.y == (checking_from.y - current_range))
return SOUTH
if(T.y == (checking_from.y + current_range))
return NORTH
/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/movable, turf/old_location, turf/new_location)
return
/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/movable, turf/old_location, turf/new_location)
return
/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/movable, turf/old_location, turf/new_location)
if(edge_is_a_field) // If the edge is considered a field, pass crossed to that
field_turf_crossed(movable, old_location, new_location)
/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/movable, turf/old_location, turf/new_location)
if(edge_is_a_field) // If the edge is considered a field, pass uncrossed to that
field_turf_uncrossed(movable, old_location, new_location)
#undef FIELD_TURFS_KEY
#undef EDGE_TURFS_KEY