#ARMYGROUP - Added Huntingpatrolcode by Celludriel

This commit is contained in:
Applevangelist
2026-03-08 15:38:03 +01:00
parent 85a4e4bd35
commit f93bf6f0e7
+208 -1
View File
@@ -68,7 +68,7 @@ ARMYGROUP = {
--- Army Group version.
-- @field #string version
ARMYGROUP.version="1.0.3"
ARMYGROUP.version="1.0.4"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -2332,6 +2332,213 @@ function ARMYGROUP:onafterUnsuppressed(From, Event, To)
end
----------------------------------------------------------------
-- HuntingPatrol.lua
--
-- Adds simple "hunting patrol" behavior on top of ARMYGROUP:
--
-- * Group patrols normally using its existing waypoints
-- * While combat-ready, periodically scans a zone for enemies
-- * When an enemy is found, lock it and call EngageTarget()
-- * Stay on that target until it dies
-- * When target is dead, Disengage() and let ARMYGROUP resume patrol
----------------------------------------------------------------
--- Module table
ARMYGROUP.HuntingPatrol = {}
----------------------------------------------------------------
-- ARMYGROUP extension state
----------------------------------------------------------------
-- We store a few extra fields on ARMYGROUP:
-- hp_zone : ZONE object to hunt inside
-- hp_speed : speed in knots when engaging
-- hp_formation : formation string when engaging
-- hp_target : currently locked UNIT (or nil)
-- hp_timer : TIMER object for periodic updates
-- hp_interval : scan interval in seconds
----------------------------------------------------------------
--- Enable hunting patrol behavior for this ARMYGROUP.
-- @param #ARMYGROUP self
-- @param Core.Zone#ZONE_BASE Zone The zone to hunt inside.
-- @param #number Speed Speed in knots when engaging.
-- @param #string Formation Formation used during engagement (optional).
-- @param #number Interval Scan interval in seconds (optional, default 5).
-- @return #ARMYGROUP self
function ARMYGROUP:EnableHuntingPatrol(Zone, Speed, Formation, Interval)
self.hp_zone = Zone
self.hp_speed = tonumber(Speed) or 20
self.hp_formation = Formation or nil
-- Force numeric, safe interval
local intervalNum = tonumber(Interval)
if not intervalNum or intervalNum <= 0 then
intervalNum = 5
end
self.hp_interval = intervalNum
self.hp_target = nil
if self.hp_timer then
self.hp_timer:Stop()
self.hp_timer = nil
end
self.hp_timer = TIMER:New(self._HuntingPatrolUpdate, self):Start(1, self.hp_interval)
self:T(self.lid .. "HuntingPatrol: enabled. Interval=" .. tostring(self.hp_interval))
return self
end
--- Disable hunting patrol behavior.
-- @param #ARMYGROUP self
-- @return #ARMYGROUP self
function ARMYGROUP:DisableHuntingPatrol()
if self.hp_timer then
self.hp_timer:Stop()
self.hp_timer = nil
end
if self.HuntingEnemySet then
self.HuntingEnemySet:FilterStop()
self.HuntingEnemySet = nil
end
self.hp_target = nil
self:T(self.lid .. "HuntingPatrol: disabled.")
return self
end
----------------------------------------------------------------
-- Internal: periodic update
----------------------------------------------------------------
-- This is called by the TIMER created in EnableHuntingPatrol().
-- It:
--
-- - checks if group is alive & combat-ready
-- - if a target is locked, checks if it is still alive
-- - if no target, scans the zone for enemies and locks one
-- - uses ARMYGROUP:EngageTarget() / Disengage()
--
----------------------------------------------------------------
-- @param #ARMYGROUP self
-- @return #ARMYGROUP self
function ARMYGROUP:_HuntingPatrolUpdate()
-- If group is dead, stop.
if not self:IsAlive() then
self:DisableHuntingPatrol()
return
end
-- Only run during PATROLZONE missions
local mission = self:GetMissionCurrent()
if not mission or mission.type ~= AUFTRAG.Type.PATROLZONE then
return
end
-- Only act when combat-ready
if not self:IsCombatReady() then
return
end
-- If we have a locked target, keep or drop it
if self.hp_target then
if not self.hp_target:IsAlive() then
self.hp_target = nil
self:Disengage()
end
return
end
-- No target → scan for new enemies
local enemy = self:_HuntingPatrolFindEnemyInZone(self.hp_zone)
if enemy then
self.hp_target = enemy
self:EngageTarget(enemy, self.hp_speed, self.hp_formation)
end
end
----------------------------------------------------------------
-- Internal: find one enemy ground unit inside a zone
----------------------------------------------------------------
-- Very simple: build a SET_UNIT, filter by coalition and zone,
-- and pick the closest unit to this ARMYGROUP.
----------------------------------------------------------------
-- @param #ARMYGROUP self
-- @param Core.Zone#ZONE Zone The zont to look at
-- @return Wrapper.Unit#UNIT Enemy The nearest enemy UNIT in zone
function ARMYGROUP:_HuntingPatrolFindEnemyInZone(Zone)
if not Zone then return nil end
-- Determine our coalition.
local myCoalition = self:GetCoalition()
if not self.HuntingEnemySet then
self.HuntingEnemySet = SET_UNIT:New()
:FilterActive(true)
:FilterCategories("ground")
:FilterStart()
end
local enemies = {}
self.HuntingEnemySet:ForEachUnitCompletelyInZone(Zone, function(unit)
if unit:GetCoalition() ~= myCoalition and unit:IsAlive() then
table.insert(enemies, unit)
end
end)
if #enemies == 0 then
return nil
end
-- Pick the closest enemy.
local myCoord = self:GetCoordinate()
table.sort(enemies, function(a, b)
return myCoord:Get2DDistance(a:GetCoordinate()) <
myCoord:Get2DDistance(b:GetCoordinate())
end)
return enemies[1]
end
----------------------------------------------------------------
-- Optional helper: convenience wrapper for your campaign code
----------------------------------------------------------------
-- Example usage in your ArmyManagement:
--
-- local group = GROUP:FindByName("MyDefenseGroup")
-- local army = ARMYGROUP:New(group)
-- army:SetPatrolAdInfinitum(true)
-- army:EnableHuntingPatrol(myZone, 20, "Off Road", 5)
--
-- ARMYGROUP will:
--
-- * patrol its waypoints forever
-- * periodically scan myZone
-- * when an enemy appears, EngageTarget()
-- * when target dies, Disengage() and resume patrol
--
----------------------------------------------------------------
-- @param Wrapper.Group#GROUP group The GROUP object to be made into an ARMYGROUP and send hunting.
-- @param Core.Zone#ZONE zone The zone object where to search for enemies.
-- @param #number speed Speed in knots when engaging.
-- @param #string formation Formation used during engagement (optional).
-- @param #number interval Scan interval in seconds (optional, default 5).
-- @return #ARMYGROUP ArmyGroup The new ArmyGroup.
function ARMYGROUP.EnableHuntingPatrolForGroup(group, zone, speed, formation, interval)
local army = ARMYGROUP:New(group)
army:SetPatrolAdInfinitum(true)
army:EnableHuntingPatrol(zone, speed, formation, interval)
return army
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------