From 5a72fb8bc11f5d990c91212d6fb110083bb08a80 Mon Sep 17 00:00:00 2001 From: LordMidas <55047920+LordMidas@users.noreply.github.com> Date: Tue, 4 Mar 2025 21:39:07 +0000 Subject: [PATCH 1/2] feat: add function to get actors adjacent to a tile --- .../tactical/tactical_entity_manager.nut | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/msu/hooks/entity/tactical/tactical_entity_manager.nut b/msu/hooks/entity/tactical/tactical_entity_manager.nut index c39a206d..e54e40b0 100644 --- a/msu/hooks/entity/tactical/tactical_entity_manager.nut +++ b/msu/hooks/entity/tactical/tactical_entity_manager.nut @@ -35,6 +35,27 @@ } return ret; } + + q.getAdjacentActors <- function( _tile ) + { + if (_tile.ID == 0) + { + ::logError("The ID of _tile is 0 which means that the actor this tile was fetched from is not placed on map."); + throw ::MSU.Exception.InvalidValue(_tile); + } + + local ret = []; + for (local i = 0; i < 6; i++) + { + if (!_tile.hasNextTile(i)) + continue; + + local nextTile = _tile.getNextTile(i); + if (nextTile.IsOccupiedByActor) + ret.push(nextTile.getEntity()); + } + return ret; + } q.getAlliedActors <- function( _faction, _tile = null, _distance = null, _atDistance = false ) { From ca306cf4397378ccdb7f8eeb7188df632e9d80be Mon Sep 17 00:00:00 2001 From: LordMidas <55047920+LordMidas@users.noreply.github.com> Date: Tue, 4 Mar 2025 21:40:17 +0000 Subject: [PATCH 2/2] perf: optimize getActors functions for the case of 1 distance Instead of iterating over all the actors on the battlefield, we only iterate over the adjacent 6 tiles. Getting adjacent actors is a very widely used thing in mods and occurs inside often repeating functions e.g. onUpdate so it is good to optimize it. --- .../tactical/tactical_entity_manager.nut | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/msu/hooks/entity/tactical/tactical_entity_manager.nut b/msu/hooks/entity/tactical/tactical_entity_manager.nut index e54e40b0..be90f425 100644 --- a/msu/hooks/entity/tactical/tactical_entity_manager.nut +++ b/msu/hooks/entity/tactical/tactical_entity_manager.nut @@ -65,6 +65,14 @@ throw ::MSU.Exception.InvalidValue(_tile); } + if (_distance == 1) + { + local ret = this.getAdjacentActors(_tile); + if (!_atDistance && _tile.IsOccupiedByActor) + ret.push(_tile.getEntity()); + return ret.filter(@(_, _a) _a.isAlliedWith(_faction)); + } + return this.getActorsByFunction(function(_actor) { if (!_actor.isAlliedWith(_faction)) return false; if (_tile != null) @@ -85,6 +93,14 @@ throw ::MSU.Exception.InvalidValue(_tile); } + if (_distance == 1) + { + local ret = this.getAdjacentActors(_tile); + if (!_atDistance && _tile.IsOccupiedByActor) + ret.push(_tile.getEntity()); + return ret.filter(@(_, _a) !_a.isAlliedWith(_faction)); + } + return this.getActorsByFunction(function(_actor) { if (_actor.isAlliedWith(_faction)) return false; if (_tile != null) @@ -108,6 +124,14 @@ ::logError("The ID of _tile is 0 which means that the actor this tile was fetched from is not placed on map."); throw ::MSU.Exception.InvalidValue(_tile); } + + if (_distance == 1) + { + local ret = this.getAdjacentActors(_tile); + if (!_atDistance && _tile.IsOccupiedByActor) + ret.push(_tile.getEntity()); + return ret.filter(@(_, _a) _a.getFaction() == _faction); + } local actors = this.getInstancesOfFaction(_faction); local ret = []; @@ -129,6 +153,14 @@ throw ::MSU.Exception.InvalidValue(_tile); } + if (_distance == 1) + { + local ret = this.getAdjacentActors(_tile); + if (!_atDistance && _tile.IsOccupiedByActor) + ret.push(_tile.getEntity()); + return ret.filter(@(_, _a) _a.isAlliedWith(_faction) && _a.getFaction() != _faction); + } + return this.getActorsByFunction(function(_actor) { if (!_actor.isAlliedWith(_faction) || _actor.getFaction() == _faction) return false; if (_tile != null)