mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-14 03:32:00 +00:00
* Reworks targeting behavior to fall back onto proximity monitors. Refactors ai cooldowns a bit (#82640) ## About The Pull Request Nother bit ripped out of #79498 [Implements a get_cooldown() proc to get around dumb manual overrides and empower me to optimize the findtarget logic](7047d294dd) [Adds modify_cooldown, uses it to optimize find_potential_targets further](4ebc8cedce) No sense running the behavior if we're just waiting on its output, so let's run it once a minute just in case, then push an update instantly if we find something [Optimizes connect_range and promxity_monitors](bcf7d7c5b3) We know what turfs exist before and after a move We can use this information to prevent trying to update turfs we don't care about. This is important because post these changes mobs with fields will be moving a lot more, so it's gotta be cheap [Implements a special kind of field to handle ai targeting](80b63b3445) If we run targeting and don't like, find anything, we should setup a field that listens for things coming near us and then handle those things as we find them. This incurs a slight startup cost but saves so much time on the churn of constant costs Note: We should also work to figure out a way to avoid waking ais if none is near them/they aren't doing anything interesting We don't need to do that immediately this acts as somewhat of a stopgap (and would be good regardless) but it is worth keeping in mind) ## IMPORTANT I am unsure whether this is worth it anymore since #82539 was merged. As I say it was done as a stopgap because ais didn't know how to idle. If not I'll rip er out and we'll keep the other refactoring/optimizations. ## Why It's Good For The Game Cleaner basic ai code, maybe? faster basic ai code, for sure faster proximity monitors (significantly) * ai controllers use cell trackers to know when to idle (#82691) ## About The Pull Request this makes ai controllers use cell trackers and signals to determine when to idle ## Why It's Good For The Game might be better than looping over all clients for every controller ## Changelog 🆑 code: The way mobs idle has been refactored, please report any issues with non-reactive mobs /🆑 * makes slimes not idle (#82742) ## About The Pull Request slimes should still be able to do their everyday routine without needing to be watched over ## Why It's Good For The Game makes xenobiologist's lives easier ## Changelog 🆑 qol: slimes will stay active without needing any one to watch over /🆑 --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
115 lines
4.4 KiB
Plaintext
115 lines
4.4 KiB
Plaintext
/**
|
|
* This component behaves similar to connect_loc_behalf but for all turfs in range, hooking into a signal on each of them.
|
|
* Just like connect_loc_behalf, It can react to that signal on behalf of a seperate listener.
|
|
* Good for components, though it carries some overhead. Can't be an element as that may lead to bugs.
|
|
*/
|
|
/datum/component/connect_range
|
|
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
|
|
|
/// An assoc list of signal -> procpath to register to the loc this object is on.
|
|
var/list/connections
|
|
/// The turfs currently connected to this component
|
|
var/list/turfs = list()
|
|
/**
|
|
* The atom the component is tracking. The component will delete itself if the tracked is deleted.
|
|
* Signals will also be updated whenever it moves (if it's a movable).
|
|
*/
|
|
var/atom/tracked
|
|
|
|
/// The component will hook into signals only on turfs not farther from tracked than this.
|
|
var/range
|
|
/// Whether the component works when the movable isn't directly located on a turf.
|
|
var/works_in_containers
|
|
|
|
/datum/component/connect_range/Initialize(atom/tracked, list/connections, range, works_in_containers = TRUE)
|
|
if(!isatom(tracked) || isarea(tracked) || range < 0)
|
|
return COMPONENT_INCOMPATIBLE
|
|
src.connections = connections
|
|
src.range = range
|
|
set_tracked(tracked)
|
|
src.works_in_containers = works_in_containers
|
|
|
|
/datum/component/connect_range/Destroy()
|
|
set_tracked(null)
|
|
return ..()
|
|
|
|
/datum/component/connect_range/InheritComponent(datum/component/component, original, atom/tracked, list/connections, range, works_in_containers)
|
|
// Not equivalent. Checks if they are not the same list via shallow comparison.
|
|
if(!compare_list(src.connections, connections))
|
|
stack_trace("connect_range component attached to [parent] tried to inherit another connect_range component with different connections")
|
|
return
|
|
if(src.tracked != tracked)
|
|
set_tracked(tracked)
|
|
if(src.range == range && src.works_in_containers == works_in_containers)
|
|
return
|
|
//Unregister the signals with the old settings.
|
|
unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs)
|
|
src.range = range
|
|
src.works_in_containers = works_in_containers
|
|
//Re-register the signals with the new settings.
|
|
update_signals(src.tracked)
|
|
|
|
/datum/component/connect_range/proc/set_tracked(atom/new_tracked)
|
|
if(tracked) //Unregister the signals from the old tracked and its surroundings
|
|
unregister_signals(isturf(tracked) ? tracked : tracked.loc, turfs)
|
|
UnregisterSignal(tracked, list(
|
|
COMSIG_MOVABLE_MOVED,
|
|
COMSIG_QDELETING,
|
|
))
|
|
tracked = new_tracked
|
|
if(!tracked)
|
|
return
|
|
//Register signals on the new tracked atom and its surroundings.
|
|
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
|
RegisterSignal(tracked, COMSIG_QDELETING, PROC_REF(handle_tracked_qdel))
|
|
update_signals(tracked)
|
|
|
|
/datum/component/connect_range/proc/handle_tracked_qdel()
|
|
SIGNAL_HANDLER
|
|
qdel(src)
|
|
|
|
/datum/component/connect_range/proc/update_signals(atom/target, atom/old_loc)
|
|
var/turf/current_turf = get_turf(target)
|
|
if(isnull(current_turf))
|
|
unregister_signals(old_loc, turfs)
|
|
turfs = list()
|
|
return
|
|
|
|
if(ismovable(target.loc))
|
|
if(!works_in_containers)
|
|
unregister_signals(old_loc, turfs)
|
|
turfs = list()
|
|
return
|
|
//Keep track of possible movement of all movables the target is in.
|
|
for(var/atom/movable/container as anything in get_nested_locs(target))
|
|
RegisterSignal(container, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
|
|
|
|
//Only register/unregister turf signals if it's moved to a new turf.
|
|
if(current_turf == get_turf(old_loc))
|
|
unregister_signals(old_loc, null)
|
|
return
|
|
var/list/old_turfs = turfs
|
|
turfs = RANGE_TURFS(range, current_turf)
|
|
unregister_signals(old_loc, old_turfs - turfs)
|
|
for(var/turf/target_turf as anything in turfs - old_turfs)
|
|
for(var/signal in connections)
|
|
parent.RegisterSignal(target_turf, signal, connections[signal])
|
|
|
|
/datum/component/connect_range/proc/unregister_signals(atom/location, list/remove_from)
|
|
//The location is null or is a container and the component shouldn't have register signals on it
|
|
if(isnull(location) || (!works_in_containers && !isturf(location)))
|
|
return
|
|
|
|
if(ismovable(location))
|
|
for(var/atom/movable/target as anything in (get_nested_locs(location) + location))
|
|
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
|
|
|
|
if(!length(remove_from))
|
|
return
|
|
for(var/turf/target_turf as anything in remove_from)
|
|
parent.UnregisterSignal(target_turf, connections)
|
|
|
|
/datum/component/connect_range/proc/on_moved(atom/movable/movable, atom/old_loc)
|
|
SIGNAL_HANDLER
|
|
update_signals(movable, old_loc)
|