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>
This commit is contained in:
PollardTheDragon
2026-07-08 17:31:28 -04:00
committed by GitHub
parent ab05a4ee3a
commit 24845b238a
228 changed files with 9724 additions and 49 deletions
+2
View File
@@ -10,6 +10,7 @@ SUBSYSTEM_DEF(mobs)
var/list/currentrun = list()
var/static/list/clients_by_zlevel[][]
var/static/list/dead_players_by_zlevel[][] = list(list()) // Needs to support zlevel 1 here, MaxZChanged only happens when CC is created and new_players can login before that.
var/static/list/flock_cameras_by_zlevel[][]= list(list())
var/static/list/cubemonkeys = list()
/// The amount of Xenobiology mobs (and their offspring) that exist in the world. Used for mob capping. Excludes Slimes
var/xenobiology_mobs = 0
@@ -26,6 +27,7 @@ SUBSYSTEM_DEF(mobs)
/datum/controller/subsystem/mobs/Initialize()
clients_by_zlevel = new /list(world.maxz, 0)
dead_players_by_zlevel = new /list(world.maxz, 0)
flock_cameras_by_zlevel = new /list(world.maxz, 0)
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
@@ -407,6 +407,219 @@
return MOVELOOP_FAILURE
/**
* Used for following A* defined paths.
*
* Returns TRUE if the loop sucessfully started, or FALSE if it failed
*
* Arguments:
* moving - The atom we want to move
* chasing - The atom we want to move towards
* delay - How many deci-seconds to wait between fires. Defaults to the lowest value, 0.1
* repath_delay - How often we're allowed to recalculate our path
* max_path_length - The maximum number of steps we can take in a given path to search (default: 30, 0 = infinite)
* miminum_distance - Minimum distance to the target before path returns, could be used to get near a target, but not right to it - for an AI mob with a gun, for example
* id - An ID card representing what access we have and what doors we can open
* simulated_only - Whether we consider turfs without atmos simulation (AKA do we want to ignore space)
* avoid - If we want to avoid a specific turf, like if we're a mulebot who already got blocked by some turf
* skip_first - Whether or not to delete the first item in the path. This would be done because the first item is the starting tile, which can break things
* timeout - Time in deci-seconds until the moveloop self expires. Defaults to infinity
* subsystem - The movement subsystem to use. Defaults to SSmovement. Only one loop can exist for any one subsystem
* priority - Defines how different move loops override each other. Lower numbers beat higher numbers, equal defaults to what currently exists. Defaults to MOVEMENT_DEFAULT_PRIORITY
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/move_manager/proc/astar_move(
moving,
chasing,
delay,
timeout,
repath_delay,
max_path_length,
minimum_distance,
list/access,
simulated_only,
turf/avoid,
skip_first,
subsystem,
priority,
flags,
datum/extra_info,
initial_path,
use_diagonals,
datum/callback/heuristic,
)
return add_to_loop(
moving,
subsystem,
/datum/move_loop/has_target/astar,
priority,
flags,
extra_info,
delay,
timeout,
chasing,
repath_delay,
max_path_length,
minimum_distance,
access,
simulated_only,
avoid,
skip_first,
initial_path,
use_diagonals,
heuristic,
)
/datum/move_loop/has_target/astar
///How often we're allowed to recalculate our path
var/repath_delay
///Max amount of steps to search
var/max_path_length
///Minimum distance to the target before path returns
var/minimum_distance
///A list representing what access we have and what doors we can open.
var/list/access
///Whether we consider turfs without atmos simulation (AKA do we want to ignore space)
var/simulated_only
///A perticular turf to avoid
var/turf/avoid
///Should we skip the first step? This is the tile we're currently on, which breaks some things
var/skip_first
///A list for the path we're currently following
var/list/movement_path
/// Should we use diagonals, or use only cardinals?
var/use_diagonals
///Cooldown for repathing, prevents spam
COOLDOWN_DECLARE(repath_cooldown)
///Bool used to determine if we're already making a path in AStar. this prevents us from re-pathing while we're already busy.
var/is_pathing = FALSE
///Callback to invoke once we make a path
var/datum/callback/on_finish_callback
///AStar heuristic function
var/datum/callback/heuristic
/datum/move_loop/has_target/astar/New(datum/movement_packet/owner, datum/controller/subsystem/movement/controller, atom/moving, priority, flags, datum/extra_info)
. = ..()
on_finish_callback = CALLBACK(src, PROC_REF(on_finish_pathing))
/datum/move_loop/has_target/astar/setup(delay, timeout, atom/chasing, repath_delay, max_path_length, minimum_distance, list/access, simulated_only, turf/avoid, skip_first, list/initial_path, use_diagonals, datum/callback/heuristic)
. = ..()
if(!.)
return
src.repath_delay = repath_delay
src.max_path_length = max_path_length
src.minimum_distance = minimum_distance
src.access = access
src.simulated_only = simulated_only
src.avoid = avoid
src.skip_first = skip_first
src.use_diagonals = use_diagonals
src.heuristic = heuristic
movement_path = initial_path?.Copy()
/datum/move_loop/has_target/astar/compare_loops(
datum/move_loop/loop_type,
priority,
flags,
extra_info,
delay,
timeout,
atom/chasing,
repath_delay,
max_path_length,
minimum_distance,
obj/item/card/id/id,
simulated_only,
turf/avoid,
skip_first,
initial_path,
use_diagonals,
datum/callback/heuristic,
)
if(..() && \
repath_delay == src.repath_delay && \
max_path_length == src.max_path_length && \
minimum_distance == src.minimum_distance && \
access ~= src.access && \
simulated_only == src.simulated_only && \
avoid == src.avoid && \
use_diagonals == src.use_diagonals && \
heuristic == src.heuristic)
return TRUE
return FALSE
/datum/move_loop/has_target/astar/loop_started()
. = ..()
if(!movement_path)
INVOKE_ASYNC(src, PROC_REF(recalculate_path))
/datum/move_loop/has_target/astar/loop_stopped()
. = ..()
movement_path = null
/datum/move_loop/has_target/astar/Destroy()
avoid = null
return ..()
///Tries to calculate a new path for this moveloop.
/datum/move_loop/has_target/astar/proc/recalculate_path()
if(!COOLDOWN_FINISHED(src, repath_cooldown))
return
COOLDOWN_START(src, repath_cooldown, repath_delay)
var/path_ok = SSpathfinder.astar_pathfind(
moving,
target,
max_path_length,
minimum_distance,
access,
simulated_only,
avoid,
skip_first,
use_diagonals = use_diagonals,
on_finish = on_finish_callback,
heuristic = heuristic
)
if(path_ok)
is_pathing = TRUE
SEND_SIGNAL(src, COMSIG_MOVELOOP_ASTAR_REPATH)
///Called when a path has finished being created
/datum/move_loop/has_target/astar/proc/on_finish_pathing(list/path)
movement_path = path
is_pathing = FALSE
/datum/move_loop/has_target/astar/move()
if(!length(movement_path))
if(is_pathing)
return MOVELOOP_NOT_READY
else
INVOKE_ASYNC(src, PROC_REF(recalculate_path))
return MOVELOOP_FAILURE
var/turf/next_step = movement_path[1]
var/atom/old_loc = moving.loc
//KAPU NOTE: WE DO NOT HAVE THIS
//moving.Move(next_step, get_dir(moving, next_step), FALSE, !(flags & MOVEMENT_LOOP_NO_DIR_UPDATE))
var/movement_dir = get_dir(moving, next_step)
moving.Move(next_step, movement_dir)
. = (old_loc != moving?.loc) ? MOVELOOP_SUCCESS : MOVELOOP_FAILURE
// this check if we're on exactly the next tile may be overly brittle for dense objects who may get bumped slightly
// to the side while moving but could maybe still follow their path without needing a whole new path
if(get_turf(moving) == next_step)
if(length(movement_path))
movement_path.Cut(1,2)
else
INVOKE_ASYNC(src, PROC_REF(recalculate_path))
return MOVELOOP_FAILURE
///Base class of move_to and move_away, deals with the distance and target aspect of things
/datum/move_loop/has_target/dist_bound
var/distance = 0
@@ -213,3 +213,74 @@ SUBSYSTEM_DEF(pathfinder)
active_pathing += path
return TRUE
return FALSE
/datum/controller/subsystem/pathfinder/proc/astar_pathfind(
atom/movable/invoker,
atom/end,
max_steps = 30,
mintargetdist,
list/access,
simulated_only = TRUE,
turf/exclude,
skip_first = TRUE,
use_diagonals = TRUE,
datum/callback/on_finish,
datum/callback/heuristic,
)
var/datum/pathfind/astar/path = new(
invoker,
end,
access,
max_steps,
mintargetdist,
simulated_only,
exclude,
skip_first,
use_diagonals,
on_finish,
heuristic,
)
if(path.start())
active_pathing += path
return TRUE
return FALSE
/datum/controller/subsystem/pathfinder/proc/astar_pathfind_now(
atom/movable/invoker,
atom/end,
max_steps = 14,
mintargetdist,
list/access,
simulated_only = TRUE,
turf/exclude,
skip_first = TRUE,
use_diagonals = TRUE,
datum/callback/heuristic,
)
var/datum/pathfind/astar/path = new(
invoker,
end,
access,
max_steps,
mintargetdist,
simulated_only,
exclude,
skip_first,
use_diagonals,
null,
heuristic,
)
if(!path.start())
return FALSE
if(!path.search_step(FALSE))
path.early_exit()
return FALSE
path.finished()
return path.path