This commit is contained in:
Frank 2020-11-06 00:29:42 +01:00
parent cef0e444c9
commit f3d9b9c5be
3 changed files with 158 additions and 13 deletions

View File

@ -33,6 +33,7 @@
-- @field #boolean adinfinitum Resume route at first waypoint when final waypoint is reached.
-- @field #boolean formationPerma Formation that is used permanently and overrules waypoint formations.
-- @field #boolean isMobile If true, group is mobile.
-- @field #ARMYGROUP.Target engage Engage target.
-- @extends Ops.OpsGroup#OPSGROUP
--- *Your soul may belong to Jesus, but your ass belongs to the marines.* -- Eugene B. Sledge
@ -49,6 +50,7 @@
ARMYGROUP = {
ClassName = "ARMYGROUP",
formationPerma = nil,
engage = {},
}
--- Army group element.
@ -61,6 +63,11 @@ ARMYGROUP = {
-- @field #number width Width of element in meters.
-- @field #number height Height of element in meters.
--- Target
-- @type ARMYGROUP.Target
-- @field Ops.Target#TARGET Target The target.
-- @field Core.Point#COORDINATE Coordinate Last known coordinate of the target.
--- Army Group version.
-- @field #string version
ARMYGROUP.version="0.3.0"
@ -103,6 +110,13 @@ function ARMYGROUP:New(Group)
self:AddTransition("*", "Detour", "OnDetour") -- Make a detour to a coordinate and resume route afterwards.
self:AddTransition("OnDetour", "DetourReached", "Cruising") -- Group reached the detour coordinate.
self:AddTransition("*", "Retreat", "Retreating") --
self:AddTransition("Retreating", "Retreated", "Holding") --
self:AddTransition("Cruising", "EngageTarget", "Engaging") -- Engage a target
self:AddTransition("Holding", "EngageTarget", "Engaging") -- Engage a target
self:AddTransition("Engaging", "Disengage", "Cruising") -- Engage a target
self:AddTransition("*", "Rearm", "Rearm") -- Group is send to a coordinate and waits until ammo is refilled.
self:AddTransition("Rearm", "Rearming", "Rearming") -- Group has arrived at the rearming coodinate and is waiting to be fully rearmed.
@ -311,6 +325,11 @@ function ARMYGROUP:onafterStatus(From, Event, To)
-- Check if group got stuck.
self:_CheckStuck()
-- Update engagement.
if self:IsEngaging() then
self:_UpdateEngageTarget()
end
if self.verbose>=1 then
-- Get number of tasks and missions.
@ -321,11 +340,12 @@ function ARMYGROUP:onafterStatus(From, Event, To)
local alarm=self:GetAlarmstate()
local speed=UTILS.MpsToKnots(self.velocity)
local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed())
local formation=self.option.Formation or "unknown"
local formation=self.option.Formation or "unknown"
local ammo=self:GetAmmoTot()
-- Info text.
local text=string.format("%s [ROE-AS=%d-%d T/M=%d/%d]: Wp=%d/%d-->%d (final %s), Speed=%.1f (%d), Heading=%03d",
fsmstate, roe, alarm, nTaskTot, nMissions, self.currentwp, #self.waypoints, self:GetWaypointIndexNext(), tostring(self.passedfinalwp), speed, speedEx, self.heading)
local text=string.format("%s [ROE-AS=%d-%d T/M=%d/%d]: Wp=%d/%d-->%d (final %s), Speed=%.1f (%d), Heading=%03d, Ammo=%d",
fsmstate, roe, alarm, nTaskTot, nMissions, self.currentwp, #self.waypoints, self:GetWaypointIndexNext(), tostring(self.passedfinalwp), speed, speedEx, self.heading, ammo.Total)
self:I(self.lid..text)
end
@ -506,7 +526,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
end
end
if not self.passedfinalwp then
if self:IsEngaging() or not self.passedfinalwp then
-- Debug info.
self:T(self.lid..string.format("Updateing route: WP %d-->%d (%d/%d), Speed=%.1f knots, Formation=%s",
@ -632,6 +652,85 @@ function ARMYGROUP:onafterRearming(From, Event, To)
end
--- On after "EngageTarget" event.
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Group#GROUP Group the group to be engaged.
function ARMYGROUP:onafterEngageTarget(From, Event, To, Target)
if Target:IsInstanceOf("TARGET") then
self.engage.Target=Target
else
self.engage.Target=TARGET:New(Target)
end
env.info("FF Engage Target "..self.engage.Target:GetName())
self.engage.Coordinate=UTILS.DeepCopy(self.engage.Target:GetCoordinate())
self:SwitchAlarmstate(ENUMS.AlarmState.Auto)
self:SwitchROE(ENUMS.ROE.WeaponFree)
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
-- Add waypoint after current.
self.engage.Waypoint=self:AddWaypoint(self.engage.Coordinate, nil, uid, Formation, true)
-- Set if we want to resume route after reaching the detour waypoint.
self.engage.Waypoint.detour=1
end
--- On after "EngageTarget" event.
-- @param #ARMYGROUP self
function ARMYGROUP:_UpdateEngageTarget()
if self.engage.Target and self.engage.Target:IsAlive() then
env.info("FF Update Engage Target "..self.engage.Target:GetName())
local vec3=self.engage.Target:GetCoordinate():GetVec3()
local dist=UTILS.VecDist2D(vec3, self.engage.Coordinate:GetVec3())
if dist>100 then
env.info("FF Update Engage Target Moved "..self.engage.Target:GetName())
self.engage.Coordinate:UpdateFromVec3(vec3)
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
-- Remove current waypoint
self:RemoveWaypointByID(self.engage.Waypoint.uid)
-- Add waypoint after current.
self.engage.Waypoint=self:AddWaypoint(self.engage.Coordinate, nil, uid, Formation, true)
-- Set if we want to resume route after reaching the detour waypoint.
self.engage.Waypoint.detour=0
end
else
self:Disengage()
end
end
--- On after "Disengage" event.
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARMYGROUP:onafterDisengage(From, Event, To)
self:_CheckGroupDone(1)
end
--- On after "Rearmed" event.
-- @param #ARMYGROUP self
-- @param #string From From state.

View File

@ -1245,6 +1245,13 @@ function OPSGROUP:IsLasing()
return self.spot.On
end
--- Check if the group has currently switched a LASER on.
-- @param #OPSGROUP self
-- @return #boolean If true, LASER of the group is on.
function OPSGROUP:IsEngaging()
return self:is("Engaging")
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Waypoint Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -3909,6 +3916,11 @@ function OPSGROUP:_CheckGroupDone(delay)
self:ScheduleOnce(delay, self._CheckGroupDone, self)
else
if self:IsEngaging() then
self:UpdateRoute()
return
end
-- Get current waypoint.
local waypoint=self:GetWaypoint(self.currentwp)
@ -4120,8 +4132,13 @@ function OPSGROUP:_CheckAmmoStatus()
if ammo.Missiles==0 and self.ammo.Missiles>0 and not self.outofMissiles then
self.outofMissiles=true
self:OutOfMissiles()
end
end
-- Check if group is engaging.
if self:IsEngaging() and ammo.Total==0 then
self:Disengage()
end
end
end
@ -4265,6 +4282,9 @@ function OPSGROUP:InitWaypoints()
-- Coordinate of the waypoint.
local coordinate=COORDINATE:New(wp.x, wp.alt, wp.y)
-- Strange!
wp.speed=wp.speed or 0
-- Speed at the waypoint.
local speedknots=UTILS.MpsToKnots(wp.speed)
@ -4423,6 +4443,10 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid)
-- Trigger Rearming event.
opsgroup:Rearming()
elseif opsgroup:IsEngaging() then
-- Nothing to do really.
else
-- Trigger DetourReached event.

View File

@ -244,6 +244,19 @@ function TARGET:AddObject(Object)
end
--- Check if TARGET is alive.
-- @param #TARGET self
-- @param #boolean If true, target is alive.
function TARGET:IsAlive()
return self:Is("Alive")
end
--- Check if TARGET is dead.
-- @param #TARGET self
-- @param #boolean If true, target is dead.
function TARGET:IsDead()
return self:Is("Dead")
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status
@ -302,7 +315,7 @@ function TARGET:onafterStatus(From, Event, To)
end
-- Log output verbose=1.
if self.verbose>=1 then
if self.verbose>=0 then
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.Ntargets0, self:GetLife(), self:GetLife0(), self:GetDamage())
if damaged then
text=text.." Damaged!"
@ -311,7 +324,7 @@ function TARGET:onafterStatus(From, Event, To)
end
-- Log output verbose=2.
if self.verbose>=2 then
if self.verbose>=0 then
local text="Target:"
for i,_target in pairs(self.targets) do
local target=_target --#TARGET.Object
@ -349,7 +362,8 @@ end
-- @param #TARGET.Object Target Target object.
function TARGET:onafterObjectDestroyed(From, Event, To, Target)
self:T(self.lid..string.format("Object %s destroyed", Target.Name))
-- Debug message.
self:I(self.lid..string.format("Object %s destroyed", Target.Name))
-- Set target status.
Target.Status=TARGET.ObjectStatus.DEAD
@ -405,16 +419,20 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
if EventData and EventData.IniUnitName then
-- Debug info.
--self:T3(self.lid..string.format("EVENT: Unit %s dead or lost!", EventData.IniUnitName))
self:I(self.lid..string.format("EVENT: Unit %s dead or lost!", EventData.IniUnitName))
-- Get target.
local target=self:GetTargetByName(EventData.IniUnitName)
if not target then
target=self:GetTargetByName(EventData.IniGroupName)
end
-- Check if this is one of ours.
if target and target.Status==TARGET.ObjectStatus.ALIVE then
-- Debug message.
self:T3(self.lid..string.format("EVENT: target unit %s dead or lost ==> destroyed", target.Name))
self:I(self.lid..string.format("EVENT: target unit %s dead or lost ==> destroyed", target.Name))
-- Trigger object destroyed event.
self:ObjectDestroyed(target)
@ -684,7 +702,11 @@ function TARGET:GetTargetVec3(Target)
if object and object:IsAlive() then
return object:GetVec3()
return object:GetVec3()
else
return nil
end
@ -1007,7 +1029,7 @@ function TARGET:CountTargets()
-- No target we can check!
else
self:E(self.lid.."ERROR unknown target type")
self:E(self.lid.."ERROR: Unknown target type! Cannot count targets")
end
end