Ops Fixes

This commit is contained in:
Frank 2020-08-05 00:39:48 +02:00
parent 76e75505e5
commit e6f7493ddd
6 changed files with 87 additions and 100 deletions

View File

@ -1890,31 +1890,46 @@ function AUFTRAG:Evaluate()
-- Target damage in %.
local targetdamage=self:GetTargetDamage()
-- Own damage in %.
local owndamage=self.Ncasualties/self.Nelements*100
-- Current number of mission targets.
local Ntargets=self:CountMissionTargets()
-- Number of current targets is still >0 ==> Not everything was destroyed.
if self.type==AUFTRAG.Type.TROOPTRANSPORT then
if self.Ntargets>0 and Ntargets<self.Ntargets then
failed=true
end
if self.Ntargets>0 then
---
-- Mission had targets
---
-- Number of current targets is still >0 ==> Not everything was destroyed.
if self.type==AUFTRAG.Type.TROOPTRANSPORT then
if Ntargets<self.Ntargets then
failed=true
end
else
if Ntargets>0 then
failed=true
end
end
else
---
-- Mission had NO targets
---
-- No targets and everybody died ==> mission failed. Well, unless success condition is true.
if self.Nelements==self.Ncasualties then
failed=true
end
if self.Ntargets>0 and Ntargets>0 then
failed=true
end
-- No targets and everybody died ==> mission failed. Well, unless success condition is true.
if self.Ntargets==0 and self.Nelements==self.Ncasualties then
failed=true
end
end
--TODO: all assets dead? Is this a FAILED criterion even if all targets have been destroyed? What if there are no initial targets (e.g. when ORBIT, PATROL, RECON missions).
if failureCondition then
failed=true
@ -1924,14 +1939,19 @@ function AUFTRAG:Evaluate()
-- Debug text.
local text=string.format("Evaluating mission:\n")
text=text..string.format("Units assigned = %d\n", self.Nelements)
text=text..string.format("Own casualties = %d\n", self.Ncasualties)
text=text..string.format("Own losses = %.1f %%\n", self.Ncasualties/self.Nelements*100)
text=text..string.format("Targets = %d/%d\n", self.Ntargets, Ntargets)
text=text..string.format("Damage = %.1f %%\n", targetdamage)
text=text..string.format("Own casualties = %d/%d\n", self.Ncasualties, self.Nelements)
text=text..string.format("Own losses = %.1f %%\n", owndamage)
text=text..string.format("--------------------------\n")
text=text..string.format("Targets left = %d/%d\n", Ntargets, self.Ntargets)
text=text..string.format("Enemy losses = %.1f %%\n", targetdamage)
text=text..string.format("--------------------------\n")
--text=text..string.format("Loss ratio = %.1f %%\n", targetdamage)
--text=text..string.format("--------------------------\n")
text=text..string.format("Success Cond = %s\n", tostring(successCondition))
text=text..string.format("Failure Cond = %s\n", tostring(failureCondition))
text=text..string.format("Failed = %s", tostring(failed))
text=text..string.format("--------------------------\n")
text=text..string.format("Final Success = %s\n", tostring(not failed))
text=text..string.format("=========================")
self:I(self.lid..text)
if failed then

View File

@ -817,7 +817,7 @@ function FLIGHTGROUP:onafterStatus(From, Event, To)
---
-- Task queue.
if #self.taskqueue>0 and self.verbose>1 then
if self.verbose>1 and #self.taskqueue>0 then
local text=string.format("Tasks #%d", #self.taskqueue)
for i,_task in pairs(self.taskqueue) do
local task=_task --Ops.OpsGroup#OPSGROUP.Task
@ -1088,7 +1088,7 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData)
if element.unit and element.unit:IsAlive() then
local airbase=self:GetClosestAirbase() --element.unit:GetCoordinate():GetClosestAirbase()
local airbase=self:GetClosestAirbase()
local parking=self:GetParkingSpot(element, 10, airbase)
if airbase and parking then
@ -1096,18 +1096,13 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData)
self:T3(self.lid..string.format("EVENT: Element %s shut down engines ==> arrived", element.name))
else
self:T3(self.lid..string.format("EVENT: Element %s shut down engines but is not parking. Is it dead?", element.name))
--self:ElementDead(element)
end
else
--self:I(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name))
end
else
-- element is nil
end
end -- element nil?
end
@ -1154,8 +1149,7 @@ function FLIGHTGROUP:OnEventUnitLost(EventData)
local element=self:GetElementByName(unitname)
if element then
self:I(self.lid..string.format("EVENT: Element %s unit lost ==> destroyed", element.name))
--self:ElementDead(element)
self:T3(self.lid..string.format("EVENT: Element %s unit lost ==> destroyed", element.name))
self:ElementDestroyed(element)
end
@ -1178,7 +1172,7 @@ function FLIGHTGROUP:OnEventRemoveUnit(EventData)
local element=self:GetElementByName(unitname)
if element then
self:I(self.lid..string.format("EVENT: Element %s removed ==> dead", element.name))
self:T3(self.lid..string.format("EVENT: Element %s removed ==> dead", element.name))
self:ElementDead(element)
end
@ -1406,7 +1400,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterSpawned(From, Event, To)
self:I(self.lid..string.format("Flight spawned!"))
self:T(self.lid..string.format("Flight spawned"))
if self.ai then
@ -1543,7 +1537,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterAirborne(From, Event, To)
self:I(self.lid..string.format("Flight airborne"))
self:T(self.lid..string.format("Flight airborne"))
if self.ai then
self:_CheckGroupDone(1)
@ -1608,7 +1602,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterDead(From, Event, To)
self:I(self.lid..string.format("Flight dead!"))
self:T(self.lid..string.format("Flight dead!"))
-- Delete waypoints so they are re-initialized at the next spawn.
self.waypoints=nil
@ -1655,8 +1649,8 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
self:E(self.lid.."Update route denied. Group is DEAD!")
allowed=false
else
-- Not airborne yet. Try again in 1 sec.
self:I(self.lid.."FF update route denied ==> checking back in 5 sec")
-- Not airborne yet. Try again in 5 sec.
self:T(self.lid.."Update route denied ==> checking back in 5 sec")
trepeat=-5
allowed=false
end
@ -1673,7 +1667,7 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
local N=n or self.currentwp+1
if not N or N<1 then
self:E(self.lid.."FF update route denied because N=nil or N<1")
self:E(self.lid.."Update route denied because N=nil or N<1")
trepeat=-5
allowed=false
end
@ -1734,7 +1728,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Debug info.
local hb=self.homebase and self.homebase:GetName() or "unknown"
local db=self.destbase and self.destbase:GetName() or "unknown"
self:I(self.lid..string.format("Updating route for WP #%d-%d homebase=%s destination=%s", n, #wp, hb, db))
self:T(self.lid..string.format("Updating route for WP #%d-%d homebase=%s destination=%s", n, #wp, hb, db))
if #wp>1 then
@ -2207,7 +2201,7 @@ function FLIGHTGROUP:onafterHolding(From, Event, To)
local text=string.format("Flight group %s is HOLDING now", self.groupname)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text)
self:T(self.lid..text)
-- Add flight to waiting/holding queue.
if self.flightcontrol then
@ -2936,18 +2930,13 @@ function FLIGHTGROUP:InitWaypoints()
-- Template waypoints.
self.waypoints0=self.group:GetTemplateRoutePoints()
self:I(self.waypoints0)
-- Waypoints
self.waypoints={}
for index,wp in pairs(self.waypoints0) do
env.info("FF index "..index)
local waypoint=self:_CreateWaypoint(wp)
local waypoint=self:_CreateWaypoint(wp)
self:_AddWaypoint(waypoint)
end
@ -2964,7 +2953,7 @@ function FLIGHTGROUP:InitWaypoints()
end
-- Debug info.
self:I(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown"))
self:T(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown"))
-- Update route.
if #self.waypoints>0 then
@ -2974,9 +2963,6 @@ function FLIGHTGROUP:InitWaypoints()
self.passedfinalwp=true
end
-- Update route (when airborne).
--self:_CheckGroupDone(1)
--self:__UpdateRoute(-1)
end
return self
@ -3251,12 +3237,6 @@ function FLIGHTGROUP:GetClosestAirbase()
local airbase=coord:GetClosestAirbase() --(nil, coalition)
if airbase then
env.info("FF Got closest airbase ".. airbase:GetName())
else
env.info("FF no closest airbase!")
end
return airbase
end

View File

@ -114,7 +114,7 @@ function NAVYGROUP:New(GroupName)
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("*", "CollitionWarning", "*") -- Collision warning.
self:AddTransition("*", "CollisionWarning", "*") -- Collision warning.
self:AddTransition("*", "ClearAhead", "*") -- Clear ahead.
self:AddTransition("*", "Dive", "Diving") -- Command a submarine to dive.
@ -195,12 +195,14 @@ end
-- @param #number WeaponType Type of weapon. Default auto.
-- @param #string Clock Time when to start the attack.
-- @param #number Prio Priority of the task.
-- @return Ops.OpsGroup#OPSGROUP.Task The task data.
function NAVYGROUP:AddTaskFireAtPoint(Coordinate, Radius, Nshots, WeaponType, Clock, Prio)
local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, Coordinate:GetVec2(), Radius, Nshots, WeaponType)
self:AddTask(DCStask, Clock, nil, Prio)
local task=self:AddTask(DCStask, Clock, nil, Prio)
return task
end
--- Add a *scheduled* task.
@ -210,12 +212,14 @@ end
-- @param #number WeaponType Type of weapon. Default auto.
-- @param #string Clock Time when to start the attack.
-- @param #number Prio Priority of the task.
-- @return Ops.OpsGroup#OPSGROUP.Task The task data.
function NAVYGROUP:AddTaskAttackGroup(TargetGroup, WeaponExpend, WeaponType, Clock, Prio)
local DCStask=CONTROLLABLE.TaskAttackGroup(nil, TargetGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit, GroupAttack)
self:AddTask(DCStask, Clock, nil, Prio)
local task=self:AddTask(DCStask, Clock, nil, Prio)
return task
end
--- Add aircraft recovery time window and recovery case.
@ -409,11 +413,9 @@ function NAVYGROUP:onafterStatus(From, Event, To)
end
if not self.ispathfinding then
if freepath<5000 then
self.ispathfinding=self:_FindPathToNextWaypoint()
--self.ispathfinding=self:_FindPathToNextWaypoint()
end
end
@ -466,7 +468,7 @@ function NAVYGROUP:onafterStatus(From, Event, To)
---
-- Task queue.
if #self.taskqueue>0 and self.verbose>1 then
if self.verbose>-1 and #self.taskqueue>0 then
local text=string.format("Tasks #%d", #self.taskqueue)
for i,_task in pairs(self.taskqueue) do
local task=_task --Ops.OpsGroup#OPSGROUP.Task

View File

@ -120,13 +120,11 @@ OPSGROUP = {
respawning = nil,
wpcounter = 1,
radio = {},
radioDefault = {},
option = {},
optionDefault = {},
tacan = {},
icls = {},
callsign = {},
callsignDefault = {},
}
--- Status of group element.
@ -1234,7 +1232,7 @@ function OPSGROUP:AddTaskWaypoint(task, Waypoint, description, prio, duration)
table.insert(self.taskqueue, newtask)
-- Info.
self:I(self.lid..string.format("Adding WAYPOINT task %s at WP %d", newtask.description, newtask.waypoint))
self:T(self.lid..string.format("Adding WAYPOINT task %s at WP ID=%d", newtask.description, newtask.waypoint))
self:T3({newtask=newtask})
-- Update route.
@ -2635,13 +2633,14 @@ end
-- @param #number wpnumber Waypoint index/number. Default is as last waypoint.
function OPSGROUP:_AddWaypoint(waypoint, wpnumber)
-- Index.
wpnumber=wpnumber or #self.waypoints+1
self:I(self.lid..string.format("Adding waypoint at index=%d id=%d", wpnumber, waypoint.uid))
-- Add waypoint to table.
table.insert(self.waypoints, wpnumber, waypoint)
-- Debug info.
self:T2(self.lid..string.format("Adding waypoint at index=%d id=%d", wpnumber, waypoint.uid))
end
--- Initialize Mission Editor waypoints.
@ -3069,9 +3068,7 @@ function OPSGROUP:SwitchTACAN(Channel, Morse, UnitName, Band)
self:I(self.lid..string.format("Switching TACAN to Channel %d%s Morse %s on unit %s", self.tacan.Channel, self.tacan.Band, tostring(self.tacan.Morse), self.tacan.BeaconName))
else
self:E(self.lid.."ERROR: Cound not set TACAN! Unit is not alive.")
end
end
@ -3165,9 +3162,7 @@ function OPSGROUP:SwitchICLS(Channel, Morse, UnitName)
self:I(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s", self.icls.Channel, tostring(self.icls.Morse), self.icls.BeaconName))
else
self:E(self.lid.."ERROR: Cound not set ICLS! Unit is not alive.")
end
end
@ -3324,6 +3319,7 @@ end
-- @return #OPSGROUP self
function OPSGROUP:SetDefaultCallsign(CallsignName, CallsignNumber)
self.callsignDefault={}
self.callsignDefault.NumberSquad=CallsignName
self.callsignDefault.NumberGroup=CallsignNumber or 1
@ -3344,9 +3340,8 @@ function OPSGROUP:SwitchCallsign(CallsignName, CallsignNumber)
self:I(self.lid..string.format("Switching callsign to %d-%d", self.callsign.NumberSquad, self.callsign.NumberGroup))
local group=self.group --Wrapper.Group#GROUP
group:CommandSetCallsign(self.callsign.NumberSquad, self.callsign.NumberGroup)
self.group:CommandSetCallsign(self.callsign.NumberSquad, self.callsign.NumberGroup)
end

View File

@ -2,7 +2,8 @@
--
-- **Main Features:**
--
-- * Stuff
-- * Manages AIRWINGS
-- * Handles missions (AUFTRAG) and finds the best airwing able to do the job
--
-- ===
--
@ -49,10 +50,7 @@ WINGCOMMANDER.version="0.1.0"
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Define A2A and A2G parameters.
-- TODO: Improve airwing selection. Mostly done!
-- DONE: Add/remove spawned flightgroups to detection set.
-- DONE: Borderzones.
-- NOGO: Maybe it's possible to preselect the assets for the mission.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -76,9 +74,10 @@ function WINGCOMMANDER:New()
-- From State --> Event --> To State
self:AddTransition("NotReadyYet", "Start", "OnDuty") -- Start WC.
self:AddTransition("*", "Status", "*") -- Status report.
self:AddTransition("*", "MissionAssign", "*") -- Mission was assigned to an AIRWING.
self:AddTransition("*", "Stop", "Stopped") -- Stop WC.
self:AddTransition("*", "AssignMission", "*") -- Mission was assigned to an AIRWING.
self:AddTransition("*", "CancelMission", "*") -- Cancel mission.
self:AddTransition("*", "Defcon", "*") -- Cancel mission.
------------------------
--- Pseudo Functions ---
@ -217,6 +216,7 @@ function WINGCOMMANDER:onafterStatus(From, Event, To)
-- Mission queue.
if #self.missionqueue>0 then
local text="Mission queue:"
for i,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
@ -226,6 +226,7 @@ function WINGCOMMANDER:onafterStatus(From, Event, To)
text=text..string.format("\n[%d] %s (%s): status=%s, target=%s", i, mission.name, mission.type, mission.status, target)
end
self:I(self.lid..text)
end
self:__Status(-30)
@ -235,14 +236,14 @@ end
-- FSM Events
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- On after "MissionAssign" event. Mission is added to the AIRWING mission queue.
--- On after "AssignMission" event. Mission is added to the AIRWING mission queue.
-- @param #WINGCOMMANDER self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.AirWing#AIRWING Airwing The AIRWING.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
function WINGCOMMANDER:onafterMissionAssign(From, Event, To, Airwing, Mission)
function WINGCOMMANDER:onafterAssignMission(From, Event, To, Airwing, Mission)
self:I(self.lid..string.format("Assigning mission %s (%s) to airwing %s", Mission.name, Mission.type, Airwing.alias))
Airwing:AddMission(Mission)
@ -268,7 +269,7 @@ function WINGCOMMANDER:onafterCancelMission(From, Event, To, Mission)
-- Airwing will cancel mission.
if Mission.airwing then
Mission.airwing:MissionCancel(Mission)
Mission.airwing:CancelMission(Mission)
end
end
@ -300,7 +301,7 @@ function WINGCOMMANDER:CheckMissionQueue()
if airwing then
-- Add mission to airwing.
self:MissionAssign(airwing, mission)
self:AssignMission(airwing, mission)
return
end

View File

@ -1429,16 +1429,6 @@ end
-- @return DCS#Task The DCS task structure.
function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType )
-- FireAtPoint = {
-- id = 'FireAtPoint',
-- params = {
-- point = Vec2,
-- radius = Distance,
-- expendQty = number,
-- expendQtyEnabled = boolean,
-- }
-- }
local DCSTask = {
id = 'FireAtPoint',
params = {
@ -1458,7 +1448,6 @@ function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType )
DCSTask.params.weaponType=WeaponType
end
self:T3( { DCSTask } )
return DCSTask
end