mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Ops
This commit is contained in:
parent
3ea8b3737f
commit
2a4f6020c2
@ -46,6 +46,7 @@
|
||||
-- @type WAREHOUSE
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #boolean Debug If true, send debug messages to all.
|
||||
-- @field #number verbose Verbosity level.
|
||||
-- @field #string wid Identifier of the warehouse printed before other output to DCS.log file.
|
||||
-- @field #boolean Report If true, send status messages to coalition.
|
||||
-- @field Wrapper.Static#STATIC warehouse The phyical warehouse structure.
|
||||
@ -1830,14 +1831,12 @@ WAREHOUSE.version="1.0.2"
|
||||
-- @param #string alias (Optional) Alias of the warehouse, i.e. the name it will be called when sending messages etc. Default is the name of the static
|
||||
-- @return #WAREHOUSE self
|
||||
function WAREHOUSE:New(warehouse, alias)
|
||||
BASE:T({warehouse=warehouse})
|
||||
|
||||
-- Check if just a string was given and convert to static.
|
||||
if type(warehouse)=="string" then
|
||||
local warehousename=warehouse
|
||||
warehouse=UNIT:FindByName(warehousename)
|
||||
if warehouse==nil then
|
||||
--env.info(string.format("No warehouse unit with name %s found trying static.", tostring(warehousename)))
|
||||
warehouse=STATIC:FindByName(warehousename, true)
|
||||
self.isunit=false
|
||||
else
|
||||
@ -1858,7 +1857,7 @@ function WAREHOUSE:New(warehouse, alias)
|
||||
env.info(string.format("Adding warehouse v%s for structure %s with alias %s", WAREHOUSE.version, warehouse:GetName(), self.alias))
|
||||
|
||||
-- Inherit everthing from FSM class.
|
||||
local self = BASE:Inherit(self, FSM:New()) -- #WAREHOUSE
|
||||
local self=BASE:Inherit(self, FSM:New()) -- #WAREHOUSE
|
||||
|
||||
-- Set some string id for output to DCS.log file.
|
||||
self.lid=string.format("WAREHOUSE %s | ", self.alias)
|
||||
@ -1890,6 +1889,8 @@ function WAREHOUSE:New(warehouse, alias)
|
||||
|
||||
-- Defaults
|
||||
self:SetMarker(true)
|
||||
self:SetReportOff()
|
||||
self:SetVerbosity(0)
|
||||
|
||||
-- Add warehouse to database.
|
||||
_WAREHOUSEDB.Warehouses[self.uid]=self
|
||||
@ -2551,6 +2552,15 @@ function WAREHOUSE:SetStatusUpdate(timeinterval)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set verbosity level.
|
||||
-- @param #WAREHOUSE self
|
||||
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
|
||||
-- @return #WAREHOUSE self
|
||||
function WAREHOUSE:SetVerbosity(VerbosityLevel)
|
||||
self.verbose=VerbosityLevel or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a zone where the (ground) assets of the warehouse are spawned once requested.
|
||||
-- @param #WAREHOUSE self
|
||||
-- @param Core.Zone#ZONE zone The spawn zone.
|
||||
@ -3253,16 +3263,6 @@ function WAREHOUSE:onafterStart(From, Event, To)
|
||||
-- Save self in static object. Easier to retrieve later.
|
||||
self.warehouse:SetState(self.warehouse, "WAREHOUSE", self)
|
||||
|
||||
-- THIS! caused aircraft to be spawned and started but they would never begin their route!
|
||||
-- VERY strange. Need to test more.
|
||||
--[[
|
||||
-- Debug mark warehouse & spawn zone.
|
||||
self.zone:BoundZone(30, self.country)
|
||||
self.spawnzone:BoundZone(30, self.country)
|
||||
]]
|
||||
|
||||
--self.spawnzone:GetCoordinate():MarkToCoalition(string.format("Warehouse %s spawn zone", self.alias), self:GetCoalition())
|
||||
|
||||
-- Get the closest point on road wrt spawnzone of ground assets.
|
||||
local _road=self.spawnzone:GetCoordinate():GetClosestPointToRoad()
|
||||
if _road and self.road==nil then
|
||||
@ -3402,13 +3402,17 @@ end
|
||||
-- @param #string To To state.
|
||||
function WAREHOUSE:onafterStatus(From, Event, To)
|
||||
|
||||
local FSMstate=self:GetState()
|
||||
|
||||
local coalition=self:GetCoalitionName()
|
||||
local country=self:GetCountryName()
|
||||
|
||||
-- Info.
|
||||
self:I(self.lid..string.format("State=%s %s [%s]: Assets=%d, Requests: waiting=%d, pending=%d", FSMstate, country, coalition, #self.stock, #self.queue, #self.pending))
|
||||
-- General info.
|
||||
if self.verbose>=1 then
|
||||
|
||||
local FSMstate=self:GetState()
|
||||
|
||||
local coalition=self:GetCoalitionName()
|
||||
local country=self:GetCountryName()
|
||||
|
||||
-- Info.
|
||||
self:I(self.lid..string.format("State=%s %s [%s]: Assets=%d, Requests: waiting=%d, pending=%d", FSMstate, country, coalition, #self.stock, #self.queue, #self.pending))
|
||||
end
|
||||
|
||||
-- Check if any pending jobs are done and can be deleted from the queue.
|
||||
self:_JobDone()
|
||||
@ -7616,10 +7620,10 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
local problem=nil
|
||||
|
||||
-- Safe parking using TO_AC from DCS result.
|
||||
self:I(self.lid..string.format("Parking spot %d TOAC=%s (safe park=%s).", _termid, tostring(_toac), tostring(self.safeparking)))
|
||||
self:T2(self.lid..string.format("Parking spot %d TOAC=%s (safe park=%s)", _termid, tostring(_toac), tostring(self.safeparking)))
|
||||
if self.safeparking and _toac then
|
||||
free=false
|
||||
self:I(self.lid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", _termid))
|
||||
self:T(self.lid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC)", _termid))
|
||||
end
|
||||
|
||||
-- Loop over all obstacles.
|
||||
@ -7648,7 +7652,8 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
-- Add parkingspot for this asset unit.
|
||||
table.insert(parking[_asset.uid], parkingspot)
|
||||
|
||||
self:I(self.lid..string.format("Parking spot %d is free for asset id=%d!", _termid, _asset.uid))
|
||||
-- Debug
|
||||
self:T(self.lid..string.format("Parking spot %d is free for asset id=%d!", _termid, _asset.uid))
|
||||
|
||||
-- Add the unit as obstacle so that this spot will not be available for the next unit.
|
||||
table.insert(obstacles, {coord=_spot, size=_asset.size, name=_asset.templatename, type="asset"})
|
||||
@ -7659,7 +7664,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
else
|
||||
|
||||
-- Debug output for occupied spots.
|
||||
self:I(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
|
||||
self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
|
||||
if self.Debug then
|
||||
local coord=problem.coord --Core.Point#COORDINATE
|
||||
local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist)
|
||||
@ -8284,67 +8289,70 @@ end
|
||||
-- @param #string name Name of the queue for info reasons.
|
||||
function WAREHOUSE:_PrintQueue(queue, name)
|
||||
|
||||
local total="Empty"
|
||||
if #queue>0 then
|
||||
total=string.format("Total = %d", #queue)
|
||||
end
|
||||
if self.verbose>=2 then
|
||||
|
||||
-- Init string.
|
||||
local text=string.format("%s at %s: %s",name, self.alias, total)
|
||||
|
||||
for i,qitem in ipairs(queue) do
|
||||
local qitem=qitem --#WAREHOUSE.Pendingitem
|
||||
|
||||
local uid=qitem.uid
|
||||
local prio=qitem.prio
|
||||
local clock="N/A"
|
||||
if qitem.timestamp then
|
||||
clock=tostring(UTILS.SecondsToClock(qitem.timestamp))
|
||||
local total="Empty"
|
||||
if #queue>0 then
|
||||
total=string.format("Total = %d", #queue)
|
||||
end
|
||||
local assignment=tostring(qitem.assignment)
|
||||
local requestor=qitem.warehouse.alias
|
||||
local airbasename=qitem.warehouse:GetAirbaseName()
|
||||
local requestorAirbaseCat=qitem.warehouse:GetAirbaseCategory()
|
||||
local assetdesc=qitem.assetdesc
|
||||
local assetdescval=qitem.assetdescval
|
||||
if assetdesc==WAREHOUSE.Descriptor.ASSETLIST then
|
||||
assetdescval="Asset list"
|
||||
|
||||
-- Init string.
|
||||
local text=string.format("%s at %s: %s",name, self.alias, total)
|
||||
|
||||
for i,qitem in ipairs(queue) do
|
||||
local qitem=qitem --#WAREHOUSE.Pendingitem
|
||||
|
||||
local uid=qitem.uid
|
||||
local prio=qitem.prio
|
||||
local clock="N/A"
|
||||
if qitem.timestamp then
|
||||
clock=tostring(UTILS.SecondsToClock(qitem.timestamp))
|
||||
end
|
||||
local assignment=tostring(qitem.assignment)
|
||||
local requestor=qitem.warehouse.alias
|
||||
local airbasename=qitem.warehouse:GetAirbaseName()
|
||||
local requestorAirbaseCat=qitem.warehouse:GetAirbaseCategory()
|
||||
local assetdesc=qitem.assetdesc
|
||||
local assetdescval=qitem.assetdescval
|
||||
if assetdesc==WAREHOUSE.Descriptor.ASSETLIST then
|
||||
assetdescval="Asset list"
|
||||
end
|
||||
local nasset=tostring(qitem.nasset)
|
||||
local ndelivered=tostring(qitem.ndelivered)
|
||||
local ncargogroupset="N/A"
|
||||
if qitem.cargogroupset then
|
||||
ncargogroupset=tostring(qitem.cargogroupset:Count())
|
||||
end
|
||||
local transporttype="N/A"
|
||||
if qitem.transporttype then
|
||||
transporttype=qitem.transporttype
|
||||
end
|
||||
local ntransport="N/A"
|
||||
if qitem.ntransport then
|
||||
ntransport=tostring(qitem.ntransport)
|
||||
end
|
||||
local ntransportalive="N/A"
|
||||
if qitem.transportgroupset then
|
||||
ntransportalive=tostring(qitem.transportgroupset:Count())
|
||||
end
|
||||
local ntransporthome="N/A"
|
||||
if qitem.ntransporthome then
|
||||
ntransporthome=tostring(qitem.ntransporthome)
|
||||
end
|
||||
|
||||
-- Output text:
|
||||
text=text..string.format(
|
||||
"\n%d) UID=%d, Prio=%d, Clock=%s, Assignment=%s | Requestor=%s [Airbase=%s, category=%d] | Assets(%s)=%s: #requested=%s / #alive=%s / #delivered=%s | Transport=%s: #requested=%s / #alive=%s / #home=%s",
|
||||
i, uid, prio, clock, assignment, requestor, airbasename, requestorAirbaseCat, assetdesc, assetdescval, nasset, ncargogroupset, ndelivered, transporttype, ntransport, ntransportalive, ntransporthome)
|
||||
|
||||
end
|
||||
local nasset=tostring(qitem.nasset)
|
||||
local ndelivered=tostring(qitem.ndelivered)
|
||||
local ncargogroupset="N/A"
|
||||
if qitem.cargogroupset then
|
||||
ncargogroupset=tostring(qitem.cargogroupset:Count())
|
||||
end
|
||||
local transporttype="N/A"
|
||||
if qitem.transporttype then
|
||||
transporttype=qitem.transporttype
|
||||
end
|
||||
local ntransport="N/A"
|
||||
if qitem.ntransport then
|
||||
ntransport=tostring(qitem.ntransport)
|
||||
end
|
||||
local ntransportalive="N/A"
|
||||
if qitem.transportgroupset then
|
||||
ntransportalive=tostring(qitem.transportgroupset:Count())
|
||||
end
|
||||
local ntransporthome="N/A"
|
||||
if qitem.ntransporthome then
|
||||
ntransporthome=tostring(qitem.ntransporthome)
|
||||
end
|
||||
|
||||
-- Output text:
|
||||
text=text..string.format(
|
||||
"\n%d) UID=%d, Prio=%d, Clock=%s, Assignment=%s | Requestor=%s [Airbase=%s, category=%d] | Assets(%s)=%s: #requested=%s / #alive=%s / #delivered=%s | Transport=%s: #requested=%s / #alive=%s / #home=%s",
|
||||
i, uid, prio, clock, assignment, requestor, airbasename, requestorAirbaseCat, assetdesc, assetdescval, nasset, ncargogroupset, ndelivered, transporttype, ntransport, ntransportalive, ntransporthome)
|
||||
|
||||
end
|
||||
|
||||
if #queue==0 then
|
||||
self:T(self.lid..text)
|
||||
else
|
||||
if total~="Empty" then
|
||||
|
||||
if #queue==0 then
|
||||
self:I(self.lid..text)
|
||||
else
|
||||
if total~="Empty" then
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -8352,17 +8360,19 @@ end
|
||||
--- Display status of warehouse.
|
||||
-- @param #WAREHOUSE self
|
||||
function WAREHOUSE:_DisplayStatus()
|
||||
local text=string.format("\n------------------------------------------------------\n")
|
||||
text=text..string.format("Warehouse %s status: %s\n", self.alias, self:GetState())
|
||||
text=text..string.format("------------------------------------------------------\n")
|
||||
text=text..string.format("Coalition name = %s\n", self:GetCoalitionName())
|
||||
text=text..string.format("Country name = %s\n", self:GetCountryName())
|
||||
text=text..string.format("Airbase name = %s (category=%d)\n", self:GetAirbaseName(), self:GetAirbaseCategory())
|
||||
text=text..string.format("Queued requests = %d\n", #self.queue)
|
||||
text=text..string.format("Pending requests = %d\n", #self.pending)
|
||||
text=text..string.format("------------------------------------------------------\n")
|
||||
text=text..self:_GetStockAssetsText()
|
||||
self:T(text)
|
||||
if self.verbose>=3 then
|
||||
local text=string.format("\n------------------------------------------------------\n")
|
||||
text=text..string.format("Warehouse %s status: %s\n", self.alias, self:GetState())
|
||||
text=text..string.format("------------------------------------------------------\n")
|
||||
text=text..string.format("Coalition name = %s\n", self:GetCoalitionName())
|
||||
text=text..string.format("Country name = %s\n", self:GetCountryName())
|
||||
text=text..string.format("Airbase name = %s (category=%d)\n", self:GetAirbaseName(), self:GetAirbaseCategory())
|
||||
text=text..string.format("Queued requests = %d\n", #self.queue)
|
||||
text=text..string.format("Pending requests = %d\n", #self.pending)
|
||||
text=text..string.format("------------------------------------------------------\n")
|
||||
text=text..self:_GetStockAssetsText()
|
||||
self:I(text)
|
||||
end
|
||||
end
|
||||
|
||||
--- Get text about warehouse stock.
|
||||
|
||||
@ -204,6 +204,7 @@ function AIRWING:New(warehousename, airwingname)
|
||||
self:AddTransition("*", "FlightOnMission", "*") -- Flight was spawned with a mission.
|
||||
|
||||
-- Defaults:
|
||||
self:SetVerbosity(0)
|
||||
self.nflightsCAP=0
|
||||
self.nflightsAWACS=0
|
||||
self.nflightsTANKERboom=0
|
||||
@ -559,6 +560,15 @@ function AIRWING:GetSquadron(SquadronName)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Set verbosity level.
|
||||
-- @param #AIRWING self
|
||||
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:SetVerbosity(VerbosityLevel)
|
||||
self.verbose=VerbosityLevel or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get squadron of an asset.
|
||||
-- @param #AIRWING self
|
||||
-- @param #AIRWING.SquadronAsset Asset The squadron asset.
|
||||
@ -792,93 +802,52 @@ function AIRWING:onafterStatus(From, Event, To)
|
||||
-- Check Rescue Helo missions.
|
||||
self:CheckRescuhelo()
|
||||
|
||||
-- Count missions not over yet.
|
||||
local nmissions=self:CountMissionsInQueue()
|
||||
|
||||
-- Count ALL payloads in stock. If any payload is unlimited, this gives 999.
|
||||
local Npayloads=self:CountPayloadsInStock(AUFTRAG.Type)
|
||||
|
||||
-- General info:
|
||||
-- TODO: assets total
|
||||
local text=string.format("%s: Missions=%d, Payloads=%d (%d), Squads=%d", fsmstate, nmissions, Npayloads, #self.payloads, #self.squadrons)
|
||||
self:I(self.lid..text)
|
||||
if self.verbose>=1 then
|
||||
|
||||
-- Count missions not over yet.
|
||||
local nmissions=self:CountMissionsInQueue()
|
||||
|
||||
-- Count ALL payloads in stock. If any payload is unlimited, this gives 999.
|
||||
local Npayloads=self:CountPayloadsInStock(AUFTRAG.Type)
|
||||
|
||||
-- TODO: assets total
|
||||
|
||||
-- Output.
|
||||
local text=string.format("%s: Missions=%d, Payloads=%d (%d), Squads=%d", fsmstate, nmissions, Npayloads, #self.payloads, #self.squadrons)
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
|
||||
------------------
|
||||
-- Mission Info --
|
||||
------------------
|
||||
local text=string.format("Missions Total=%d:", #self.missionqueue)
|
||||
for i,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
text=text..string.format("\n[%d] %s: Status=%s, Nassets=%d, Prio=%d, ID=%d (%s)", i, mission.type, mission.status, mission.nassets, mission.prio, mission.auftragsnummer, mission.name)
|
||||
if self.verbose>=2 then
|
||||
local text=string.format("Missions Total=%d:", #self.missionqueue)
|
||||
for i,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
text=text..string.format("\n[%d] %s: Status=%s, Nassets=%d, Prio=%d, ID=%d (%s)", i, mission.type, mission.status, mission.nassets, mission.prio, mission.auftragsnummer, mission.name)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
|
||||
|
||||
-------------------
|
||||
-- Squadron Info --
|
||||
-------------------
|
||||
local text="Squadrons:"
|
||||
for i,_squadron in pairs(self.squadrons) do
|
||||
local squadron=_squadron --Ops.Squadron#SQUADRON
|
||||
|
||||
local callsign=squadron.callsignName and UTILS.GetCallsignName(squadron.callsignName) or "N/A"
|
||||
local modex=squadron.modex and squadron.modex or -1
|
||||
local skill=squadron.skill and tostring(squadron.skill) or "N/A"
|
||||
|
||||
-- Squadron text
|
||||
text=text..string.format("\n* %s %s: %s*%d/%d, Callsign=%s, Modex=%d, Skill=%s", squadron.name, squadron:GetState(), squadron.aircrafttype, squadron:CountAssetsInStock(), #squadron.assets, callsign, modex, skill)
|
||||
|
||||
-- Loop over all assets.
|
||||
if self.verbose>1 then
|
||||
for j,_asset in pairs(squadron.assets) do
|
||||
local asset=_asset --#AIRWING.SquadronAsset
|
||||
local assignment=asset.assignment or "none"
|
||||
local name=asset.templatename
|
||||
local spawned=tostring(asset.spawned)
|
||||
local groupname=asset.spawngroupname
|
||||
local typename=asset.unittype
|
||||
|
||||
local mission=self:GetAssetCurrentMission(asset)
|
||||
local missiontext=""
|
||||
if mission then
|
||||
local distance=asset.flightgroup and UTILS.MetersToNM(mission:GetTargetDistance(asset.flightgroup.group:GetCoordinate())) or 0
|
||||
missiontext=string.format(" [%s (%s): status=%s, distance=%.1f NM]", mission.type, mission.name, mission.status, distance)
|
||||
end
|
||||
|
||||
-- Mission info.
|
||||
text=text..string.format("\n -[%d] %s*%d \"%s\": spawned=%s, mission=%s%s", j, typename, asset.nunits, asset.spawngroupname, spawned, tostring(self:IsAssetOnMission(asset)), missiontext)
|
||||
|
||||
-- Payload info.
|
||||
local payload=asset.payload and table.concat(self:GetPayloadMissionTypes(asset.payload), ", ") or "None"
|
||||
text=text.." payload="..payload
|
||||
|
||||
-- Flight status.
|
||||
text=text..", flight: "
|
||||
if asset.flightgroup and asset.flightgroup:IsAlive() then
|
||||
local status=asset.flightgroup:GetState()
|
||||
local fuelmin=asset.flightgroup:GetFuelMin()
|
||||
local fuellow=asset.flightgroup:IsFuelLow()
|
||||
local fuelcri=asset.flightgroup:IsFuelCritical()
|
||||
|
||||
text=text..string.format("%s fuel=%d", status, fuelmin)
|
||||
if fuelcri then
|
||||
text=text.." (critical!)"
|
||||
elseif fuellow then
|
||||
text=text.." (low)"
|
||||
end
|
||||
|
||||
local lifept, lifept0=asset.flightgroup:GetLifePoints()
|
||||
text=text..string.format(" life=%d/%d", lifept, lifept0)
|
||||
|
||||
local ammo=asset.flightgroup:GetAmmoTot()
|
||||
text=text..string.format(" ammo=[G=%d, R=%d, B=%d, M=%d]", ammo.Guns, ammo.Rockets, ammo.Bombs, ammo.Missiles)
|
||||
else
|
||||
text=text.."N/A"
|
||||
end
|
||||
end
|
||||
if self.verbose>=3 then
|
||||
local text="Squadrons:"
|
||||
for i,_squadron in pairs(self.squadrons) do
|
||||
local squadron=_squadron --Ops.Squadron#SQUADRON
|
||||
|
||||
local callsign=squadron.callsignName and UTILS.GetCallsignName(squadron.callsignName) or "N/A"
|
||||
local modex=squadron.modex and squadron.modex or -1
|
||||
local skill=squadron.skill and tostring(squadron.skill) or "N/A"
|
||||
|
||||
-- Squadron text
|
||||
text=text..string.format("\n* %s %s: %s*%d/%d, Callsign=%s, Modex=%d, Skill=%s", squadron.name, squadron:GetState(), squadron.aircrafttype, squadron:CountAssetsInStock(), #squadron.assets, callsign, modex, skill)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
|
||||
--------------
|
||||
-- Mission ---
|
||||
|
||||
@ -98,8 +98,9 @@
|
||||
--
|
||||
-- @field #table enrouteTasks Mission enroute tasks.
|
||||
--
|
||||
-- @field #number missionRepeated Number of times mission was repeated.
|
||||
-- @field #number missionRepeatMax Number of times mission is repeated if failed.
|
||||
-- @field #number repeated Number of times mission was repeated.
|
||||
-- @field #number NrepeatFailure Number of times mission is repeated if failed.
|
||||
-- @field #number NrepeatSuccess Number of times mission is repeated if successful.
|
||||
--
|
||||
-- @field Ops.OpsGroup#OPSGROUP.Radio radio Radio freq and modulation.
|
||||
-- @field Ops.OpsGroup#OPSGROUP.Beacon tacan TACAN setting.
|
||||
@ -259,7 +260,7 @@
|
||||
AUFTRAG = {
|
||||
ClassName = "AUFTRAG",
|
||||
Debug = false,
|
||||
verbose = 2,
|
||||
verbose = 0,
|
||||
lid = nil,
|
||||
auftragsnummer = nil,
|
||||
groupdata = {},
|
||||
@ -473,19 +474,20 @@ function AUFTRAG:New(Type)
|
||||
-- Auftragsnummer.
|
||||
self.auftragsnummer=_AUFTRAGSNR
|
||||
|
||||
-- Log id.
|
||||
-- Log ID.
|
||||
self:_SetLogID()
|
||||
|
||||
-- State is planned.
|
||||
self.status=AUFTRAG.Status.PLANNED
|
||||
|
||||
-- Defaults
|
||||
self:SetVerbosity(0)
|
||||
self:SetName()
|
||||
self:SetPriority()
|
||||
self:SetTime()
|
||||
self.engageAsGroup=true
|
||||
self.missionRepeated=0
|
||||
self.missionRepeatMax=0
|
||||
self.repeated=0
|
||||
self.NrepeatFailure=0
|
||||
self.NrepeatSuccess=0
|
||||
self.nassets=1
|
||||
self.dTevaluate=0
|
||||
@ -1413,16 +1415,16 @@ function AUFTRAG:SetPriority(Prio, Urgent)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set how many times the mission is repeated if it fails.
|
||||
--- Set how many times the mission is repeated if it fails. Only valid if the mission is handled by an AIRWING or higher level.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number Nrepeat Number of repeats. Default 0.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:SetRepeatOnFailure(Nrepeat)
|
||||
self.missionRepeatMax=Nrepeat or 0
|
||||
self.NrepeatFailure=Nrepeat or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set how many times the mission is repeated if it was successful.
|
||||
--- Set how many times the mission is repeated if it was successful. Only valid if the mission is handled by an AIRWING or higher level.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number Nrepeat Number of repeats. Default 0.
|
||||
-- @return #AUFTRAG self
|
||||
@ -1431,7 +1433,7 @@ function AUFTRAG:SetRepeatOnSuccess(Nrepeat)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Define how many assets are required to do the job.
|
||||
--- Define how many assets are required to do the job. Only valid if the mission is handled by an AIRWING or higher level.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number Nassets Number of asset groups. Default 1.
|
||||
-- @return #AUFTRAG self
|
||||
@ -1459,6 +1461,15 @@ function AUFTRAG:SetEnableMarkers(Coalition)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set verbosity level.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:SetVerbosity(VerbosityLevel)
|
||||
self.verbose=VerbosityLevel or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set weapon type used for the engagement.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number WeaponType Weapon type. Default is `ENUMS.WeaponFlag.Auto`.
|
||||
@ -1537,11 +1548,11 @@ function AUFTRAG:SetMissionSpeed(Speed)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set max engage range.
|
||||
--- Set max mission range. Only applies if the AUFTRAG is handled by an AIRWING or CHIEF. This is the max allowed distance from the airbase to the target.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #number Range Max range in NM. Default 100 NM.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:SetEngageRange(Range)
|
||||
function AUFTRAG:SetMissionRange(Range)
|
||||
self.engageRange=UTILS.NMToMeters(Range or 100)
|
||||
return self
|
||||
end
|
||||
@ -2003,6 +2014,7 @@ function AUFTRAG:onafterStatus(From, Event, To)
|
||||
self:E(self.lid..string.format("ERROR: FSM state %s != %s mission status!", fsmstate, self.status))
|
||||
end
|
||||
|
||||
-- General info.
|
||||
if self.verbose>=1 then
|
||||
|
||||
-- Mission start stop time.
|
||||
@ -2018,6 +2030,7 @@ function AUFTRAG:onafterStatus(From, Event, To)
|
||||
self:I(self.lid..string.format("Status %s: Target=%s, T=%s-%s, assets=%d, groups=%d, targets=%d, wing=%s, commander=%s", self.status, targetname, Cstart, Cstop, #self.assets, Ngroups, Ntargets, airwing, commander))
|
||||
end
|
||||
|
||||
-- Group info.
|
||||
if self.verbose>=2 then
|
||||
-- Data on assigned groups.
|
||||
local text="Group data:"
|
||||
@ -2508,8 +2521,8 @@ function AUFTRAG:onafterCancel(From, Event, To)
|
||||
self.Tover=timer.getAbsTime()
|
||||
|
||||
-- No more repeats.
|
||||
self.missionRepeatMax=self.missionRepeated
|
||||
self.NrepeatSuccess=self.missionRepeated
|
||||
self.NrepeatFailure=self.repeated
|
||||
self.NrepeatSuccess=self.repeated
|
||||
|
||||
-- Not necessary to delay the evaluaton?!
|
||||
self.dTevaluate=0
|
||||
@ -2556,16 +2569,16 @@ function AUFTRAG:onafterSuccess(From, Event, To)
|
||||
self.status=AUFTRAG.Status.SUCCESS
|
||||
self:T(self.lid..string.format("New mission status=%s", self.status))
|
||||
|
||||
if self.missionRepeated>=self.NrepeatSuccess then
|
||||
if self.repeated>=self.NrepeatSuccess then
|
||||
|
||||
-- Stop mission.
|
||||
self:I(self.lid..string.format("Mission SUCCESS! Number of max repeats reached [%d>=%d] ==> Stopping mission!", self.missionRepeated, self.NrepeatSuccess))
|
||||
self:I(self.lid..string.format("Mission SUCCESS! Number of max repeats reached [%d>=%d] ==> Stopping mission!", self.repeated, self.NrepeatSuccess))
|
||||
self:Stop()
|
||||
|
||||
else
|
||||
|
||||
-- Repeat mission.
|
||||
self:I(self.lid..string.format("Mission SUCCESS! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.missionRepeated+1, self.NrepeatSuccess))
|
||||
self:I(self.lid..string.format("Mission SUCCESS! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, self.NrepeatSuccess))
|
||||
self:Repeat()
|
||||
|
||||
end
|
||||
@ -2582,15 +2595,15 @@ function AUFTRAG:onafterFailed(From, Event, To)
|
||||
self.status=AUFTRAG.Status.FAILED
|
||||
self:T(self.lid..string.format("New mission status=%s", self.status))
|
||||
|
||||
if self.missionRepeated>=self.missionRepeatMax then
|
||||
if self.repeated>=self.NrepeatFailure then
|
||||
|
||||
self:I(self.lid..string.format("Mission FAILED! Number of max repeats reached [%d>=%d] ==> Stopping mission!", self.missionRepeated, self.missionRepeatMax))
|
||||
self:I(self.lid..string.format("Mission FAILED! Number of max repeats reached [%d>=%d] ==> Stopping mission!", self.repeated, self.NrepeatFailure))
|
||||
self:Stop()
|
||||
|
||||
else
|
||||
|
||||
-- Repeat mission.
|
||||
self:I(self.lid..string.format("Mission FAILED! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.missionRepeated+1, self.missionRepeatMax))
|
||||
self:I(self.lid..string.format("Mission FAILED! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, self.NrepeatFailure))
|
||||
self:Repeat()
|
||||
|
||||
end
|
||||
@ -2611,17 +2624,22 @@ function AUFTRAG:onafterRepeat(From, Event, To)
|
||||
self:T(self.lid..string.format("New mission status=%s (on Repeat)", self.status))
|
||||
|
||||
-- Increase repeat counter.
|
||||
self.missionRepeated=self.missionRepeated+1
|
||||
self.repeated=self.repeated+1
|
||||
|
||||
if self.wingcommander then
|
||||
if self.chief then
|
||||
|
||||
elseif self.wingcommander then
|
||||
|
||||
|
||||
|
||||
elseif self.airwing then
|
||||
|
||||
-- Already at the airwing ==> Queued()
|
||||
self:Queued(self.airwing)
|
||||
|
||||
else
|
||||
|
||||
self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, WINGCOMMANDER or AIRWING! Stopping AUFTRAG")
|
||||
self:Stop()
|
||||
end
|
||||
|
||||
|
||||
@ -2822,8 +2840,8 @@ end
|
||||
-- @return #string Name of the target or "N/A".
|
||||
function AUFTRAG:GetTargetName()
|
||||
|
||||
if self.engageTarget.Target then
|
||||
return self.engageTarget.Name
|
||||
if self.engageTarget then
|
||||
return self.engageTarget:GetName()
|
||||
end
|
||||
|
||||
return "N/A"
|
||||
|
||||
@ -1503,7 +1503,6 @@ function FLIGHTGROUP:onafterAirborne(From, Event, To)
|
||||
if self.ai then
|
||||
self:_CheckGroupDone(1)
|
||||
else
|
||||
--if not self.ai then
|
||||
self:_UpdateMenu()
|
||||
end
|
||||
end
|
||||
@ -1706,7 +1705,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
|
||||
---
|
||||
|
||||
if self:IsAirborne() then
|
||||
self:T2(self.lid.."No waypoints left ==> CheckGroupDone")
|
||||
self:I(self.lid.."No waypoints left ==> CheckGroupDone")
|
||||
self:_CheckGroupDone()
|
||||
end
|
||||
|
||||
@ -1897,7 +1896,15 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
|
||||
-- Cancel all missions.
|
||||
for _,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
self:MissionCancel(mission)
|
||||
local mystatus=mission:GetGroupStatus(self)
|
||||
|
||||
-- Check if mission is already over!
|
||||
if not (mystatus==AUFTRAG.GroupStatus.DONE or mystatus==AUFTRAG.GroupStatus.CANCELLED) then
|
||||
local text=string.format("Canceling mission %s in state=%s", mission.name, mission.status)
|
||||
env.info(text)
|
||||
self:MissionCancel(mission)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Defaults:
|
||||
@ -1907,7 +1914,6 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Flight group set to hold at airbase %s. SpeedTo=%d, SpeedHold=%d, SpeedLand=%d", airbase:GetName(), SpeedTo, SpeedHold, SpeedLand)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
local althold=self.ishelo and 1000+math.random(10)*100 or math.random(4,10)*1000
|
||||
@ -2087,7 +2093,6 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Coord, Altitude, Speed)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Flight group set to wait/orbit at altitude %d m and speed %.1f km/h", Altitude, Speed)
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
--TODO: set ROE passive. introduce roe event/state/variable.
|
||||
@ -2111,7 +2116,6 @@ function FLIGHTGROUP:onafterRefuel(From, Event, To, Coordinate)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Flight group set to refuel at the nearest tanker")
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
--TODO: set ROE passive. introduce roe event/state/variable.
|
||||
@ -2146,7 +2150,6 @@ end
|
||||
function FLIGHTGROUP:onafterRefueled(From, Event, To)
|
||||
-- Debug message.
|
||||
local text=string.format("Flight group finished refuelling")
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Check if flight is done.
|
||||
@ -2169,7 +2172,6 @@ function FLIGHTGROUP:onafterHolding(From, Event, To)
|
||||
self.Tholding=timer.getAbsTime()
|
||||
|
||||
local text=string.format("Flight group %s is HOLDING now", self.groupname)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Add flight to waiting/holding queue.
|
||||
@ -2280,7 +2282,6 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Low fuel for flight group %s", self.groupname)
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Set switch to true.
|
||||
@ -2350,7 +2351,6 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Critical fuel for flight group %s", self.groupname)
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Set switch to true.
|
||||
|
||||
@ -410,11 +410,6 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
||||
if self.detectionOn then
|
||||
self:_CheckDetectedUnits()
|
||||
end
|
||||
|
||||
-- Current heading and position of the carrier.
|
||||
local hdg=self:GetHeading()
|
||||
local pos=self:GetCoordinate()
|
||||
local speed=self.group:GetVelocityKNOTS()
|
||||
|
||||
-- Update last known position, orientation, velocity.
|
||||
self:_UpdatePosition()
|
||||
@ -450,35 +445,40 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
||||
|
||||
-- Check if group got stuck.
|
||||
self:_CheckStuck()
|
||||
|
||||
-- Get number of tasks and missions.
|
||||
local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks()
|
||||
local nMissions=self:CountRemainingMissison()
|
||||
|
||||
local intowind=self:IsSteamingIntoWind() and UTILS.SecondsToClock(self.intowind.Tstop-timer.getAbsTime(), true) or "N/A"
|
||||
local turning=tostring(self:IsTurning())
|
||||
local alt=pos.y
|
||||
local speedExpected=UTILS.MpsToKnots(self.speed or 0)
|
||||
|
||||
local wpidxCurr=self.currentwp
|
||||
local wpuidCurr=0
|
||||
local wpidxNext=self:GetWaypointIndexNext()
|
||||
local wpuidNext=0
|
||||
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint())
|
||||
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint(), true)
|
||||
local roe=self:GetROE() or 0
|
||||
local als=self:GetAlarmstate() or 0
|
||||
if self.verbose>=1 then
|
||||
|
||||
-- Info text.
|
||||
local text=string.format("%s [ROE=%d,AS=%d, T/M=%d/%d]: Wp=%d[%d]-->%d[%d] (of %d) Dist=%.1f NM ETA=%s - Speed=%.1f (%.1f) kts, Depth=%.1f m, Hdg=%03d, Turn=%s Collision=%d IntoWind=%s",
|
||||
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, #self.waypoints, wpDist, wpETA, speed, speedExpected, alt, hdg, turning, freepath, intowind)
|
||||
self:I(self.lid..text)
|
||||
-- Get number of tasks and missions.
|
||||
local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks()
|
||||
local nMissions=self:CountRemainingMissison()
|
||||
|
||||
local intowind=self:IsSteamingIntoWind() and UTILS.SecondsToClock(self.intowind.Tstop-timer.getAbsTime(), true) or "N/A"
|
||||
local turning=tostring(self:IsTurning())
|
||||
local alt=self.position.y
|
||||
local speed=UTILS.MpsToKnots(self.velocity)
|
||||
local speedExpected=UTILS.MpsToKnots(self.speed or 0)
|
||||
|
||||
local wpidxCurr=self.currentwp
|
||||
local wpuidCurr=0
|
||||
local wpidxNext=self:GetWaypointIndexNext()
|
||||
local wpuidNext=0
|
||||
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint())
|
||||
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint(), true)
|
||||
local roe=self:GetROE() or 0
|
||||
local als=self:GetAlarmstate() or 0
|
||||
|
||||
-- Info text.
|
||||
local text=string.format("%s [ROE=%d,AS=%d, T/M=%d/%d]: Wp=%d[%d]-->%d[%d] (of %d) Dist=%.1f NM ETA=%s - Speed=%.1f (%.1f) kts, Depth=%.1f m, Hdg=%03d, Turn=%s Collision=%d IntoWind=%s",
|
||||
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, #self.waypoints, wpDist, wpETA, speed, speedExpected, alt, self.heading, turning, freepath, intowind)
|
||||
self:I(self.lid..text)
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- Info text.
|
||||
local text=string.format("State %s: Alive=%s", fsmstate, tostring(self:IsAlive()))
|
||||
self:I(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -401,7 +401,17 @@ function OPSGROUP:GetLifePoints()
|
||||
end
|
||||
end
|
||||
|
||||
--- Set default cruise speed..
|
||||
|
||||
--- Set verbosity level.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
|
||||
-- @return #OPSGROUP self
|
||||
function OPSGROUP:SetVerbosity(VerbosityLevel)
|
||||
self.verbose=VerbosityLevel or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set default cruise speed.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number Speed Speed in knots.
|
||||
-- @return #OPSGROUP self
|
||||
@ -1017,7 +1027,7 @@ function OPSGROUP:RemoveWaypoint(wpindex)
|
||||
self.passedfinalwp=true
|
||||
end
|
||||
|
||||
env.info("FF passed final waypoint after remove! current wp = "..self.currentwp)
|
||||
--env.info("FF passed final waypoint after remove! current wp = "..self.currentwp)
|
||||
|
||||
self:_CheckGroupDone(1)
|
||||
|
||||
@ -1043,8 +1053,7 @@ function OPSGROUP:RemoveWaypoint(wpindex)
|
||||
self.currentwp=self.currentwp-1
|
||||
end
|
||||
|
||||
--self.currentwp=math.max(1, self.currentwp-1)
|
||||
env.info("FF current waypoint after remove "..self.currentwp)
|
||||
--env.info("FF current waypoint after remove "..self.currentwp)
|
||||
|
||||
end
|
||||
|
||||
@ -1099,7 +1108,7 @@ function OPSGROUP:SetTask(DCSTask)
|
||||
text=text..string.format("\n[%d] %s", i, tostring(task.id))
|
||||
end
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
end
|
||||
|
||||
return self
|
||||
@ -1123,7 +1132,7 @@ function OPSGROUP:PushTask(DCSTask)
|
||||
text=text..string.format("\n[%d] %s", i, tostring(task.id))
|
||||
end
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
end
|
||||
|
||||
return self
|
||||
@ -1367,7 +1376,6 @@ function OPSGROUP:RemoveTask(Task)
|
||||
-- Update route if this is a waypoint task.
|
||||
if task.type==OPSGROUP.TaskType.WAYPOINT and task.status==OPSGROUP.TaskStatus.SCHEDULED then
|
||||
self:_CheckGroupDone(1)
|
||||
--self:__UpdateRoute(-1)
|
||||
end
|
||||
|
||||
return true
|
||||
@ -1445,7 +1453,6 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Task %s ID=%d execute", tostring(Task.description), Task.id)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Cancel current task if there is any.
|
||||
@ -1556,7 +1563,6 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task)
|
||||
|
||||
-- Debug info.
|
||||
local text=string.format("Current task %s ID=%d cancelled (flag %s=%d)", Task.description, Task.id, Task.stopflag:GetName(), stopflag)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Set stop flag. When the flag is true, the _TaskDone function is executed and calls :TaskDone()
|
||||
@ -1617,7 +1623,6 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Task done: %s ID=%d", Task.description, Task.id)
|
||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- No current task.
|
||||
@ -1979,7 +1984,11 @@ end
|
||||
function OPSGROUP:onafterMissionCancel(From, Event, To, Mission)
|
||||
|
||||
if self.currentmission and Mission.auftragsnummer==self.currentmission then
|
||||
|
||||
|
||||
---
|
||||
-- Current Mission
|
||||
---
|
||||
|
||||
-- Get mission waypoint task.
|
||||
local Task=Mission:GetGroupWaypointTask(self)
|
||||
|
||||
@ -1995,11 +2004,15 @@ function OPSGROUP:onafterMissionCancel(From, Event, To, Mission)
|
||||
|
||||
else
|
||||
|
||||
-- Not the current mission.
|
||||
-- TODO: remove mission from queue?
|
||||
---
|
||||
-- NOT the current mission
|
||||
---
|
||||
|
||||
-- Set mission group status.
|
||||
Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.CANCELLED)
|
||||
Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.CANCELLED)
|
||||
|
||||
-- Remove mission from queue
|
||||
self:RemoveMission(Mission)
|
||||
|
||||
-- Send group RTB or WAIT if nothing left to do.
|
||||
self:_CheckGroupDone(1)
|
||||
@ -2019,7 +2032,6 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
|
||||
-- Debug info.
|
||||
local text=string.format("Mission %s DONE!", Mission.name)
|
||||
self:I(self.lid..text)
|
||||
MESSAGE:New(text, 30, self.groupname):ToAllIf(self.Debug)
|
||||
|
||||
-- Set group status.
|
||||
Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.DONE)
|
||||
@ -2241,7 +2253,6 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
|
||||
local text=string.format("Group passed waypoint %s/%d ID=%d: final=%s detour=%s astar=%s",
|
||||
tostring(wpindex), #self.waypoints, Waypoint.uid, tostring(self.passedfinalwp), tostring(Waypoint.detour), tostring(Waypoint.astar))
|
||||
self:I(self.lid..text)
|
||||
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
|
||||
|
||||
end
|
||||
|
||||
@ -2623,12 +2634,12 @@ end
|
||||
-- @param #OPSGROUP self
|
||||
function OPSGROUP:_PrintTaskAndMissionStatus()
|
||||
|
||||
---
|
||||
-- Tasks: verbose >= 2
|
||||
---
|
||||
-- Tasks: verbose >= 3
|
||||
---
|
||||
|
||||
-- Task queue.
|
||||
if #self.taskqueue>0 and self.verbose>=2 then
|
||||
if self.verbose>=3 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
|
||||
@ -2660,11 +2671,11 @@ function OPSGROUP:_PrintTaskAndMissionStatus()
|
||||
end
|
||||
|
||||
---
|
||||
-- Missions: verbose>=1
|
||||
-- Missions: verbose>=2
|
||||
---
|
||||
|
||||
-- Current mission name.
|
||||
if self.verbose>0 then
|
||||
if self.verbose>=2 then
|
||||
local Mission=self:GetMissionByID(self.currentmission)
|
||||
|
||||
-- Current status.
|
||||
@ -2687,7 +2698,8 @@ end
|
||||
|
||||
--- Enhance waypoint table.
|
||||
-- @param #OPSGROUP self
|
||||
-- @return #OPSGROUP.Waypoint Waypoint data.
|
||||
-- @param #OPSGROUP.Waypoint Waypoint data.
|
||||
-- @return #OPSGROUP.Waypoint Modified waypoint data.
|
||||
function OPSGROUP:_CreateWaypoint(waypoint)
|
||||
|
||||
-- Set uid.
|
||||
|
||||
@ -136,15 +136,20 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
|
||||
|
||||
-- Defaults.
|
||||
self.Ngroups=Ngroups or 3
|
||||
self:SetEngagementRange()
|
||||
self:SetMissionRange()
|
||||
self:SetSkill(AI.Skill.GOOD)
|
||||
self:SetVerbosity(0)
|
||||
|
||||
-- Everyone can ORBIT.
|
||||
self:AddMissionCapability(AUFTRAG.Type.ORBIT)
|
||||
|
||||
-- Generalized attribute.
|
||||
self.attribute=self.templategroup:GetAttribute()
|
||||
|
||||
-- Aircraft type.
|
||||
self.aircrafttype=self.templategroup:GetTypeName()
|
||||
|
||||
-- Refueling system.
|
||||
self.refuelSystem=select(2, self.templategroup:GetUnit(1):IsRefuelable())
|
||||
self.tankerSystem=select(2, self.templategroup:GetUnit(1):IsTanker())
|
||||
|
||||
@ -201,8 +206,6 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
|
||||
BASE:TraceClass(self.ClassName)
|
||||
BASE:TraceLevel(1)
|
||||
end
|
||||
self.Debug=true
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
@ -241,10 +244,19 @@ function SQUADRON:SetSkill(Skill)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set verbosity level.
|
||||
-- @param #SQUADRON self
|
||||
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
|
||||
-- @return #SQUADRON self
|
||||
function SQUADRON:SetVerbosity(VerbosityLevel)
|
||||
self.verbose=VerbosityLevel or 0
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set turnover and repair time. If an asset returns from a mission to the airwing, it will need some time until the asset is available for further missions.
|
||||
-- @param #SQUADRON self
|
||||
-- @param #number MaintenanceTime Time in minutes it takes until a flight is combat ready again. Default is 0 min.
|
||||
-- @param #number RepairTime Time in minutes it takes to repair a flight for each percent damage taken. Default is 0 min.
|
||||
-- @param #number RepairTime Time in minutes it takes to repair a flight for each life point taken. Default is 0 min.
|
||||
-- @return #SQUADRON self
|
||||
function SQUADRON:SetTurnoverTime(MaintenanceTime, RepairTime)
|
||||
self.maintenancetime=MaintenanceTime and MaintenanceTime*60 or 0
|
||||
@ -350,12 +362,12 @@ function SQUADRON:GetMissionPeformance(MissionType)
|
||||
return -1
|
||||
end
|
||||
|
||||
--- Set max engagement range.
|
||||
--- Set max mission range. Only missions in a circle of this radius around the squadron airbase are executed.
|
||||
-- @param #SQUADRON self
|
||||
-- @param #number EngageRange Engagement range in NM. Default 80 NM.
|
||||
-- @param #number Range Range in NM. Default 100 NM.
|
||||
-- @return #SQUADRON self
|
||||
function SQUADRON:SetEngagementRange(EngageRange)
|
||||
self.engageRange=UTILS.NMToMeters(EngageRange or 80)
|
||||
function SQUADRON:SetMissionRange(Range)
|
||||
self.engageRange=UTILS.NMToMeters(Range or 100)
|
||||
return self
|
||||
end
|
||||
|
||||
@ -565,27 +577,31 @@ end
|
||||
-- @param #string To To state.
|
||||
function SQUADRON:onafterStatus(From, Event, To)
|
||||
|
||||
-- FSM state.
|
||||
local fsmstate=self:GetState()
|
||||
if self.verbose>=1 then
|
||||
|
||||
local callsign=self.callsignName and UTILS.GetCallsignName(self.callsignName) or "N/A"
|
||||
local modex=self.modex and self.modex or -1
|
||||
local skill=self.skill and tostring(self.skill) or "N/A"
|
||||
-- FSM state.
|
||||
local fsmstate=self:GetState()
|
||||
|
||||
local NassetsTot=#self.assets
|
||||
local NassetsInS=self:CountAssetsInStock()
|
||||
local NassetsQP=0 ; local NassetsP=0 ; local NassetsQ=0
|
||||
if self.airwing then
|
||||
NassetsQP, NassetsP, NassetsQ=self.airwing:CountAssetsOnMission(nil, self)
|
||||
end
|
||||
|
||||
-- Short info.
|
||||
local text=string.format("%s [Type=%s, Callsign=%s, Modex=%d, Skill=%s]: Assets Total=%d, InStock=%d, OnMission=%d [P=%d, Q=%d]",
|
||||
fsmstate, self.aircrafttype, callsign, modex, skill, NassetsTot, NassetsInS, NassetsQP, NassetsP, NassetsQ)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Check if group has detected any units.
|
||||
self:_CheckAssetStatus()
|
||||
local callsign=self.callsignName and UTILS.GetCallsignName(self.callsignName) or "N/A"
|
||||
local modex=self.modex and self.modex or -1
|
||||
local skill=self.skill and tostring(self.skill) or "N/A"
|
||||
|
||||
local NassetsTot=#self.assets
|
||||
local NassetsInS=self:CountAssetsInStock()
|
||||
local NassetsQP=0 ; local NassetsP=0 ; local NassetsQ=0
|
||||
if self.airwing then
|
||||
NassetsQP, NassetsP, NassetsQ=self.airwing:CountAssetsOnMission(nil, self)
|
||||
end
|
||||
|
||||
-- Short info.
|
||||
local text=string.format("%s [Type=%s, Call=%s, Modex=%d, Skill=%s]: Assets Total=%d, Stock=%d, Mission=%d [Active=%d, Queue=%d]",
|
||||
fsmstate, self.aircrafttype, callsign, modex, skill, NassetsTot, NassetsInS, NassetsQP, NassetsP, NassetsQ)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Check if group has detected any units.
|
||||
self:_CheckAssetStatus()
|
||||
|
||||
end
|
||||
|
||||
if not self:IsStopped() then
|
||||
self:__Status(-30)
|
||||
@ -597,7 +613,8 @@ end
|
||||
-- @param #SQUADRON self
|
||||
function SQUADRON:_CheckAssetStatus()
|
||||
|
||||
if self.verbose>=0 then
|
||||
if self.verbose>=2 then
|
||||
|
||||
local text=""
|
||||
for j,_asset in pairs(self.assets) do
|
||||
local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset
|
||||
@ -647,8 +664,7 @@ function SQUADRON:_CheckAssetStatus()
|
||||
-- Payload info.
|
||||
local payload=asset.payload and table.concat(self.airwing:GetPayloadMissionTypes(asset.payload), ", ") or "None"
|
||||
text=text..", Payload={"..payload.."}"
|
||||
|
||||
|
||||
|
||||
else
|
||||
|
||||
---
|
||||
|
||||
@ -136,9 +136,12 @@ function TARGET:New(TargetObject)
|
||||
self:AddObject(TargetObject)
|
||||
|
||||
local Target=self.targets[1] --#TARGET.Object
|
||||
|
||||
self.name=self:GetTargetName(Target)
|
||||
|
||||
self.category=self:GetTargetCategory(Target)
|
||||
|
||||
-- Log ID.
|
||||
self.lid=string.format("TARGET #%03d %s | ", _TARGETID, self.category)
|
||||
|
||||
-- Start state.
|
||||
@ -660,6 +663,56 @@ function TARGET:GetTargetCoordinate(Target)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get target name.
|
||||
-- @param #TARGET self
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
-- @return #string Name of the target object.
|
||||
function TARGET:GetTargetName(Target)
|
||||
|
||||
if Target.Type==TARGET.ObjectType.GROUP then
|
||||
|
||||
if Target.Object and Target.Object:IsAlive() then
|
||||
|
||||
return Target.Object:GetName()
|
||||
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||
|
||||
if Target.Object and Target.Object:IsAlive() then
|
||||
return Target.Object:GetName()
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.STATIC then
|
||||
|
||||
if Target.Object and Target.Object:IsAlive() then
|
||||
return Target.Object:GetName()
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.AIRBASE then
|
||||
|
||||
if Target.Status==TARGET.ObjectStatus.ALIVE then
|
||||
return Target.Object:GetName()
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.COORDINATE then
|
||||
|
||||
local coord=Target.Object --Core.Point#COORDINATE
|
||||
|
||||
return coord:ToStringMGRS()
|
||||
|
||||
end
|
||||
|
||||
return "Unknown"
|
||||
end
|
||||
|
||||
--- Get name.
|
||||
-- @param #TARGET self
|
||||
-- @return #string Name of the target usually the first object.
|
||||
function TARGET:GetName()
|
||||
return self.name
|
||||
end
|
||||
|
||||
--- Get coordinate.
|
||||
-- @param #TARGET self
|
||||
-- @return Core.Point#COORDINATE Coordinate of the target.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- **Utils** - Lua Profiler.
|
||||
--
|
||||
--
|
||||
-- Find out how many times functions are called and how much real time it costs.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -13,11 +13,17 @@
|
||||
--- PROFILER class.
|
||||
-- @type PROFILER
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #table Counters Counters.
|
||||
-- @field #table Counters Function counters.
|
||||
-- @field #table dInfo Info.
|
||||
-- @field #table fTime Function time.
|
||||
-- @field #table fTimeTotal Total function time.
|
||||
-- @field #table eventhandler Event handler to get mission end event.
|
||||
-- @field #number TstartGame Game start time timer.getTime().
|
||||
-- @field #number TstartOS OS real start time os.clock.
|
||||
-- @field #boolean logUnknown Log unknown functions. Default is off.
|
||||
-- @field #number lowCpsThres Low calls per second threashold. Only write output if function has more calls per second than this value.
|
||||
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
|
||||
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
|
||||
|
||||
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? *
|
||||
--
|
||||
@ -27,8 +33,8 @@
|
||||
--
|
||||
-- # The PROFILER Concept
|
||||
--
|
||||
-- Profile your lua code. This tells you, which functions are called very often and which consume most CPU time.
|
||||
-- With this information you could optimize the perfomance of your code.
|
||||
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
|
||||
-- With this information you can optimize the perfomance of your code.
|
||||
--
|
||||
-- # Prerequisites
|
||||
--
|
||||
@ -37,19 +43,22 @@
|
||||
--
|
||||
-- # Start
|
||||
--
|
||||
-- The profiler can simply be started by
|
||||
-- The profiler can simply be started with the @{#PROFILER.Start}(*Delay, Duration*) function
|
||||
--
|
||||
-- PROFILER.Start()
|
||||
--
|
||||
-- The start can be delayed by specifying a the amount of seconds as argument, e.g. PROFILER.Start(60) to start profiling in 60 seconds.
|
||||
-- The optional parameter *Delay* can be used to delay the start by a certain amount of seconds and the optional parameter *Duration* can be used to
|
||||
-- stop the profiler after a certain amount of seconds.
|
||||
--
|
||||
-- # Stop
|
||||
--
|
||||
-- The profiler automatically stops when the mission ends. But it can be stopped any time by calling
|
||||
-- The profiler automatically stops when the mission ends. But it can be stopped any time with the @{#PROFILER.Stop}(*Delay*) function
|
||||
--
|
||||
-- PROFILER.Stop()
|
||||
--
|
||||
-- The stop call can be delayed by specifying the delay in seconds as optional argument, e.g. PROFILER.Stop(120) to stop it in 120 seconds.
|
||||
-- The optional parameter *Delay* can be used to specify a delay after which the profiler is stopped.
|
||||
--
|
||||
-- When the profiler is stopped, the output is written to a file.
|
||||
--
|
||||
-- # Output
|
||||
--
|
||||
@ -57,13 +66,19 @@
|
||||
--
|
||||
-- X:\User\<Your User Name>\Saved Games\DCS OpenBeta\Logs
|
||||
--
|
||||
-- ## Sort Output
|
||||
-- The default file name is "MooseProfiler.txt". If that file exists, the file name is "MooseProfiler-001.txt" etc.
|
||||
--
|
||||
-- By default the output is sorted with respect to the total time a function used.
|
||||
-- ## Data
|
||||
--
|
||||
-- The output can also be sorted with respect to the number of times the function was called by setting
|
||||
-- The data in the output file provides information on the functions that were called in the mission.
|
||||
--
|
||||
-- PROFILER.sortBy=1
|
||||
-- It will tell you how many times a function was called in total, how many times per second, how much time in total and the percentage of time.
|
||||
--
|
||||
-- If you only want output for functions that are called more than X times per second, you can set
|
||||
--
|
||||
-- PROFILER.lowCpsThres=1.5
|
||||
--
|
||||
-- With this setting, only functions which are called more than 1.5 times per second are displayed.
|
||||
--
|
||||
-- @field #PROFILER
|
||||
PROFILER = {
|
||||
@ -73,11 +88,10 @@ PROFILER = {
|
||||
fTime = {},
|
||||
fTimeTotal = {},
|
||||
eventHandler = {},
|
||||
startTime = nil,
|
||||
runTime = nil,
|
||||
logUnknown = false,
|
||||
lowCpsThres = 5,
|
||||
fileName = "",
|
||||
lowCpsThres = 0.0,
|
||||
fileNamePrefix = "MooseProfiler",
|
||||
fileNameSuffix = "txt"
|
||||
}
|
||||
|
||||
--- Waypoint data.
|
||||
@ -88,10 +102,6 @@ PROFILER = {
|
||||
-- @field #number count Number of function calls.
|
||||
-- @field #number tm Total time in seconds.
|
||||
|
||||
PROFILER.logUnknown=false -- Log unknown functions
|
||||
PROFILER.lowCpsThres=0 -- Skip results with less than X calls per second
|
||||
PROFILER.fileName="_LuaProfiler.txt"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Start/Stop Profiler
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -104,28 +114,58 @@ function PROFILER.Start(Delay, Duration)
|
||||
if Delay and Delay>0 then
|
||||
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration)
|
||||
else
|
||||
|
||||
-- Check if os and lfs are available.
|
||||
local go=true
|
||||
if not os then
|
||||
error("Profiler needs os to be desanitized")
|
||||
go=false
|
||||
end
|
||||
if not lfs then
|
||||
error("Profiler needs lfs to be desanitized")
|
||||
go=false
|
||||
end
|
||||
if not go then
|
||||
return
|
||||
end
|
||||
|
||||
-- Set start time.
|
||||
PROFILER.TstartGame=timer.getTime()
|
||||
PROFILER.TstartOS=os.clock()
|
||||
|
||||
-- Add event handler.
|
||||
world.addEventHandler(PROFILER.eventHandler)
|
||||
|
||||
--[[
|
||||
-- Message to screen.
|
||||
local function showProfilerRunning()
|
||||
timer.scheduleFunction(showProfilerRunning, nil, timer.getTime()+600)
|
||||
trigger.action.outText("### Profiler running ###", 600)
|
||||
end
|
||||
|
||||
end
|
||||
-- Message.
|
||||
showProfilerRunning()
|
||||
]]
|
||||
|
||||
-- Info in log.
|
||||
BASE:I('############################ Profiler Started ############################')
|
||||
env.info('############################ Profiler Started ############################')
|
||||
if Duration then
|
||||
env.info(string.format("Duration %d seconds", Duration))
|
||||
else
|
||||
env.info(string.format("Stopped when mission ends"))
|
||||
end
|
||||
env.info(string.format("Calls per second threshold %.3f/sec", PROFILER.lowCpsThres))
|
||||
env.info(string.format("Log file \"%s.%s\"", PROFILER.fileNamePrefix, PROFILER.fileNameSuffix))
|
||||
env.info('###############################################################################')
|
||||
|
||||
|
||||
-- Message on screen
|
||||
local duration=Duration or 600
|
||||
trigger.action.outText("### Profiler running ###", duration)
|
||||
|
||||
-- Set hook.
|
||||
debug.sethook(PROFILER.hook, "cr")
|
||||
|
||||
-- Auto stop profiler.
|
||||
if Duration then
|
||||
PROFILER.Stop(Duration)
|
||||
end
|
||||
@ -148,12 +188,14 @@ function PROFILER.Stop(Delay)
|
||||
debug.sethook()
|
||||
|
||||
|
||||
-- Run time.
|
||||
PROFILER.runTimeGame=timer.getTime()-PROFILER.TstartGame
|
||||
PROFILER.runTimeOS=os.clock()-PROFILER.TstartOS
|
||||
-- Run time game.
|
||||
local runTimeGame=timer.getTime()-PROFILER.TstartGame
|
||||
|
||||
-- Run time real OS.
|
||||
local runTimeOS=os.clock()-PROFILER.TstartOS
|
||||
|
||||
-- Show info.
|
||||
PROFILER.showInfo()
|
||||
PROFILER.showInfo(runTimeGame, runTimeOS)
|
||||
|
||||
end
|
||||
|
||||
@ -237,20 +279,20 @@ end
|
||||
--- Show table.
|
||||
-- @param #table data Data table.
|
||||
-- @param #function f The file.
|
||||
-- @param #boolean detailed Show detailed info.
|
||||
function PROFILER.showTable(data, f, detailed)
|
||||
-- @param #number runTimeGame Game run time in seconds.
|
||||
function PROFILER.showTable(data, f, runTimeGame)
|
||||
|
||||
-- Loop over data.
|
||||
for i=1, #data do
|
||||
local t=data[i] --#PROFILER.Data
|
||||
|
||||
-- Calls per second.
|
||||
local cps=t.count/PROFILER.runTimeGame
|
||||
local cps=t.count/runTimeGame
|
||||
|
||||
if (cps>=PROFILER.lowCpsThres) then
|
||||
|
||||
-- Output
|
||||
local text=string.format("%30s: %8d calls %8.1f/sec - Time %8.3f sec (%.3f %%) %s line %s", t.func, t.count, cps, t.tm, t.tm/PROFILER.runTimeGame*100, tostring(t.src), tostring(t.line))
|
||||
local text=string.format("%30s: %8d calls %8.1f/sec - Time %8.3f sec (%.3f %%) %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, tostring(t.src), tostring(t.line))
|
||||
PROFILER._flog(f, text)
|
||||
|
||||
end
|
||||
@ -259,16 +301,50 @@ function PROFILER.showTable(data, f, detailed)
|
||||
end
|
||||
|
||||
--- Write info to output file.
|
||||
function PROFILER.showInfo()
|
||||
-- @return #string File name.
|
||||
function PROFILER.getfilename()
|
||||
|
||||
local dir=lfs.writedir()..[[Logs\]]
|
||||
|
||||
local file=dir..PROFILER.fileNamePrefix.."."..PROFILER.fileNameSuffix
|
||||
|
||||
if not UTILS.FileExists(file) then
|
||||
return file
|
||||
end
|
||||
|
||||
for i=1,999 do
|
||||
|
||||
local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, PROFILER.fileNameSuffix)
|
||||
|
||||
if not UTILS.FileExists(file) then
|
||||
return file
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Write info to output file.
|
||||
-- @param #number runTimeGame Game time in seconds.
|
||||
-- @param #number runTimeOS OS time in seconds.
|
||||
function PROFILER.showInfo(runTimeGame, runTimeOS)
|
||||
|
||||
-- Output file.
|
||||
local file=lfs.writedir()..[[Logs\]]..PROFILER.fileName
|
||||
local file=PROFILER.getfilename()
|
||||
local f=io.open(file, 'w')
|
||||
|
||||
-- Gather data.
|
||||
local Ttot=0
|
||||
local Calls=0
|
||||
|
||||
local t={}
|
||||
|
||||
local tcopy=nil --#PROFILER.Data
|
||||
local tserialize=nil --#PROFILER.Data
|
||||
local tforgen=nil --#PROFILER.Data
|
||||
local tpairs=nil --#PROFILER.Data
|
||||
|
||||
|
||||
for func, count in pairs(PROFILER.Counters) do
|
||||
|
||||
local s,src,line,tm=PROFILER.getData(func)
|
||||
@ -277,26 +353,80 @@ function PROFILER.showInfo()
|
||||
if s==nil then s="<Unknown>" end
|
||||
end
|
||||
|
||||
if s~=nil and s~="_copy" and s~="_Serialize" and s~="(for generator)" and s~="pairs" then
|
||||
t[#t+1]=
|
||||
if s~=nil then
|
||||
|
||||
-- Profile data.
|
||||
local T=
|
||||
{ func=s,
|
||||
src=src,
|
||||
line=line,
|
||||
count=count,
|
||||
tm=tm,
|
||||
}
|
||||
} --#PROFILER.Data
|
||||
|
||||
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
|
||||
if s=="_copy" then
|
||||
if tcopy==nil then
|
||||
tcopy=T
|
||||
else
|
||||
tcopy.count=tcopy.count+T.count
|
||||
tcopy.tm=tcopy.tm+T.tm
|
||||
end
|
||||
elseif s=="_Serialize" then
|
||||
if tserialize==nil then
|
||||
tserialize=T
|
||||
else
|
||||
tserialize.count=tserialize.count+T.count
|
||||
tserialize.tm=tserialize.tm+T.tm
|
||||
end
|
||||
elseif s=="(for generator)" then
|
||||
if tforgen==nil then
|
||||
tforgen=T
|
||||
else
|
||||
tforgen.count=tforgen.count+T.count
|
||||
tforgen.tm=tforgen.tm+T.tm
|
||||
end
|
||||
elseif s=="pairs" then
|
||||
if tpairs==nil then
|
||||
tpairs=T
|
||||
else
|
||||
tpairs.count=tpairs.count+T.count
|
||||
tpairs.tm=tpairs.tm+T.tm
|
||||
end
|
||||
else
|
||||
table.insert(t, T)
|
||||
end
|
||||
|
||||
-- Total function time.
|
||||
Ttot=Ttot+tm
|
||||
|
||||
-- Total number of calls.
|
||||
Calls=Calls+count
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
-- Add special cases.
|
||||
if tcopy then
|
||||
table.insert(t, tcopy)
|
||||
end
|
||||
if tserialize then
|
||||
table.insert(t, tserialize)
|
||||
end
|
||||
if tforgen then
|
||||
table.insert(t, tforgen)
|
||||
end
|
||||
if tpairs then
|
||||
table.insert(t, tpairs)
|
||||
end
|
||||
|
||||
env.info("**************************************************************************************************")
|
||||
env.info(string.format("Profiler"))
|
||||
env.info(string.format("--------"))
|
||||
env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(PROFILER.runTimeGame, true), PROFILER.runTimeGame))
|
||||
env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(PROFILER.runTimeOS, true), PROFILER.runTimeOS))
|
||||
env.info(string.format("* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/PROFILER.runTimeGame*100))
|
||||
env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
|
||||
env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
|
||||
env.info(string.format("* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
|
||||
env.info(string.format("* Total functions : %d", #t))
|
||||
env.info(string.format("* Total func calls : %d", Calls))
|
||||
env.info(string.format("* Writing to file : \"%s\"", file))
|
||||
@ -315,16 +445,16 @@ function PROFILER.showInfo()
|
||||
PROFILER._flog(f,"---- Profiler Report ----")
|
||||
PROFILER._flog(f,"-------------------------")
|
||||
PROFILER._flog(f,"")
|
||||
PROFILER._flog(f,string.format("* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock(PROFILER.runTimeGame, true), PROFILER.runTimeGame))
|
||||
PROFILER._flog(f,string.format("* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock(PROFILER.runTimeOS, true), PROFILER.runTimeOS).." (can vary significantly compared to the game time)")
|
||||
PROFILER._flog(f,string.format("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/PROFILER.runTimeGame*100))
|
||||
PROFILER._flog(f,string.format("* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
|
||||
PROFILER._flog(f,string.format("* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
|
||||
PROFILER._flog(f,string.format("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
|
||||
PROFILER._flog(f,"")
|
||||
PROFILER._flog(f,string.format("* Total functions = %d", #t))
|
||||
PROFILER._flog(f,string.format("* Total func calls = %d", Calls))
|
||||
PROFILER._flog(f,"")
|
||||
PROFILER._flog(f,"************************************************************************************************************************")
|
||||
PROFILER._flog(f,"")
|
||||
PROFILER.showTable(t, f, true)
|
||||
PROFILER.showTable(t, f, runTimeGame)
|
||||
|
||||
-- Sort by number of calls.
|
||||
table.sort(t, function(a,b) return a.count>b.count end)
|
||||
@ -337,7 +467,7 @@ function PROFILER.showInfo()
|
||||
PROFILER._flog(f,"---- Data Sorted by Calls ----")
|
||||
PROFILER._flog(f,"------------------------------")
|
||||
PROFILER._flog(f,"")
|
||||
PROFILER.showTable(t, f, true)
|
||||
PROFILER.showTable(t, f, runTimeGame)
|
||||
|
||||
-- Closing.
|
||||
PROFILER._flog(f,"")
|
||||
|
||||
@ -755,7 +755,7 @@ end
|
||||
-- @param #string Text The updated text, displayed in the mark panel.
|
||||
function MARKER:onafterTextUpdate(From, Event, To, Text)
|
||||
|
||||
self:I(self.lid..string.format("New Marker Text:\n%s", Text))
|
||||
self:T(self.lid..string.format("New Marker Text:\n%s", Text))
|
||||
|
||||
end
|
||||
|
||||
@ -767,7 +767,7 @@ end
|
||||
-- @param Core.Point#COORDINATE Coordinate The updated coordinates.
|
||||
function MARKER:onafterCoordUpdate(From, Event, To, Coordinate)
|
||||
|
||||
self:I(self.lid..string.format("New Marker Coordinate in LL DMS: %s", Coordinate:ToStringLLDMS()))
|
||||
self:T(self.lid..string.format("New Marker Coordinate in LL DMS: %s", Coordinate:ToStringLLDMS()))
|
||||
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user