mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
commit
fc0c0f87dc
@ -7880,8 +7880,10 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
local _coord=unit:GetVec3()
|
||||
local _size=self:_GetObjectSize(unit:GetDCSObject())
|
||||
local _name=unit:GetName()
|
||||
if unit and unit:IsAlive() then
|
||||
table.insert(obstacles, {coord=_coord, size=_size, name=_name, type="unit"})
|
||||
end
|
||||
end
|
||||
|
||||
-- Check all statics.
|
||||
for _,static in pairs(_statics) do
|
||||
@ -7923,6 +7925,9 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
-- Loop over all units - each one needs a spot.
|
||||
for i=1,_asset.nunits do
|
||||
|
||||
-- Asset name
|
||||
local assetname=_asset.spawngroupname.."-"..tostring(i)
|
||||
|
||||
-- Loop over all parking spots.
|
||||
local gotit=false
|
||||
for _,_parkingspot in pairs(parkingdata) do
|
||||
@ -7946,13 +7951,13 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
|
||||
-- Spot is blocked.
|
||||
if not safe then
|
||||
--env.info(string.format("FF asset=%s (id=%d): spot id=%d dist=%.1fm is NOT SAFE", _asset.templatename, _asset.uid, _termid, dist))
|
||||
self:T3(self.lid..string.format("FF asset=%s (id=%d): spot id=%d dist=%.1fm is NOT SAFE", assetname, _asset.uid, _termid, dist))
|
||||
free=false
|
||||
problem=obstacle
|
||||
problem.dist=dist
|
||||
break
|
||||
else
|
||||
--env.info(string.format("FF asset=%s (id=%d): spot id=%d dist=%.1fm is SAFE", _asset.templatename, _asset.uid, _termid, dist))
|
||||
--env.info(string.format("FF asset=%s (id=%d): spot id=%d dist=%.1fm is SAFE", assetname, _asset.uid, _termid, dist))
|
||||
end
|
||||
|
||||
end
|
||||
@ -7964,10 +7969,10 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
table.insert(parking[_asset.uid], parkingspot)
|
||||
|
||||
-- Debug
|
||||
self:T(self.lid..string.format("Parking spot %d is free for asset id=%d!", _termid, _asset.uid))
|
||||
self:T(self.lid..string.format("Parking spot %d is free for asset %s [id=%d]!", _termid, assetname, _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"})
|
||||
table.insert(obstacles, {coord=_spot, size=_asset.size, name=assetname, type="asset"})
|
||||
|
||||
gotit=true
|
||||
break
|
||||
@ -7975,21 +7980,25 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
|
||||
else
|
||||
|
||||
-- Debug output for occupied spots.
|
||||
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)
|
||||
local text=string.format("Obstacle %s [type=%s] blocking spot=%d! Size=%.1f m and distance=%.1f m.", problem.name, problem.type, _termid, problem.size, problem.dist)
|
||||
self:I(self.lid..text)
|
||||
coord:MarkToAll(string.format(text))
|
||||
else
|
||||
self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
self:T2(self.lid..string.format("Terminal ID=%d: type=%s not supported", parkingspot.TerminalID, parkingspot.TerminalType))
|
||||
end -- check terminal type
|
||||
end -- loop over parking spots
|
||||
|
||||
-- No parking spot for at least one asset :(
|
||||
if not gotit then
|
||||
self:I(self.lid..string.format("WARNING: No free parking spot for asset id=%d",_asset.uid))
|
||||
self:I(self.lid..string.format("WARNING: No free parking spot for asset %s [id=%d]", assetname, _asset.uid))
|
||||
return nil
|
||||
end
|
||||
end -- loop over asset units
|
||||
|
||||
@ -3277,6 +3277,26 @@ function AUFTRAG:onafterStatus(From, Event, To)
|
||||
-- TODO: I commented this out for some reason but I forgot why...
|
||||
self:Cancel()
|
||||
|
||||
elseif self:IsExecuting() then
|
||||
|
||||
-- Had the case that mission was in state Executing but all assigned groups were dead.
|
||||
-- TODO: might need to loop over all assigned groups
|
||||
if Ngroups==0 then
|
||||
self:Done()
|
||||
else
|
||||
local done=true
|
||||
for groupname,data in pairs(self.groupdata or {}) do
|
||||
local groupdata=data --#AUFTRAG.GroupData
|
||||
local opsgroup=groupdata.opsgroup
|
||||
if opsgroup:IsAlive() then
|
||||
done=false
|
||||
end
|
||||
end
|
||||
if done then
|
||||
self:Done()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
-- @field #string Defcon Defence condition.
|
||||
-- @field #string strategy Strategy of the CHIEF.
|
||||
-- @field Ops.Commander#COMMANDER commander Commander of assigned legions.
|
||||
-- @field #boolean tacview Tactical overview.
|
||||
-- @extends Ops.Intelligence#INTEL
|
||||
|
||||
--- *In preparing for battle I have always found that plans are useless, but planning is indispensable* -- Dwight D Eisenhower
|
||||
@ -134,6 +135,7 @@ CHIEF = {
|
||||
borderzoneset = nil,
|
||||
yellowzoneset = nil,
|
||||
engagezoneset = nil,
|
||||
tacview = false,
|
||||
}
|
||||
|
||||
--- Defence condition.
|
||||
@ -601,6 +603,23 @@ function CHIEF:GetDefcon(Defcon)
|
||||
return self.Defcon
|
||||
end
|
||||
|
||||
--- Set tactical overview on.
|
||||
-- @param #CHIEF self
|
||||
-- @return #CHIEF self
|
||||
function CHIEF:SetTacticalOverviewOn()
|
||||
self.tacview=true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set tactical overview off.
|
||||
-- @param #CHIEF self
|
||||
-- @return #CHIEF self
|
||||
function CHIEF:SetTacticalOverviewOff()
|
||||
self.tacview=false
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set strategy.
|
||||
-- @param #CHIEF self
|
||||
-- @param #string Strategy Strategy. See @{#CHIEF.strategy}, e.g. `CHIEF.Strategy.DEFENSIVE` (default).
|
||||
@ -1114,7 +1133,7 @@ function CHIEF:onafterStatus(From, Event, To)
|
||||
---
|
||||
|
||||
-- Create TARGETs for all new contacts.
|
||||
local Nborder=0 ; local Nconflict=0 ; local Nattack=0
|
||||
self.Nborder=0 ; self.Nconflict=0 ; self.Nattack=0
|
||||
for _,_contact in pairs(self.Contacts) do
|
||||
local contact=_contact --Ops.Intelligence#INTEL.Contact
|
||||
local group=contact.group --Wrapper.Group#GROUP
|
||||
@ -1122,19 +1141,19 @@ function CHIEF:onafterStatus(From, Event, To)
|
||||
-- Check if contact inside of our borders.
|
||||
local inred=self:CheckGroupInBorder(group)
|
||||
if inred then
|
||||
Nborder=Nborder+1
|
||||
self.Nborder=self.Nborder+1
|
||||
end
|
||||
|
||||
-- Check if contact is in the conflict zones.
|
||||
local inyellow=self:CheckGroupInConflict(group)
|
||||
if inyellow then
|
||||
Nconflict=Nconflict+1
|
||||
self.Nconflict=self.Nconflict+1
|
||||
end
|
||||
|
||||
-- Check if contact is in the attack zones.
|
||||
local inattack=self:CheckGroupInAttack(group)
|
||||
if inattack then
|
||||
Nattack=Nattack+1
|
||||
self.Nattack=self.Nattack+1
|
||||
end
|
||||
|
||||
|
||||
@ -1162,9 +1181,9 @@ function CHIEF:onafterStatus(From, Event, To)
|
||||
---
|
||||
|
||||
-- TODO: Need to introduce time check to avoid fast oscillation between different defcon states in case groups move in and out of the zones.
|
||||
if Nborder>0 then
|
||||
if self.Nborder>0 then
|
||||
self:SetDefcon(CHIEF.DEFCON.RED)
|
||||
elseif Nconflict>0 then
|
||||
elseif self.Nconflict>0 then
|
||||
self:SetDefcon(CHIEF.DEFCON.YELLOW)
|
||||
else
|
||||
self:SetDefcon(CHIEF.DEFCON.GREEN)
|
||||
@ -1184,6 +1203,10 @@ function CHIEF:onafterStatus(From, Event, To)
|
||||
-- Check target queue and assign missions to new targets.
|
||||
self:CheckOpsZoneQueue()
|
||||
|
||||
|
||||
-- Display tactival overview.
|
||||
self:_TacticalOverview()
|
||||
|
||||
---
|
||||
-- Info General
|
||||
---
|
||||
@ -1196,7 +1219,7 @@ function CHIEF:onafterStatus(From, Event, To)
|
||||
|
||||
-- Info message
|
||||
local text=string.format("Defcon=%s Strategy=%s: Assets=%d, Contacts=%d [Border=%d, Conflict=%d, Attack=%d], Targets=%d, Missions=%d",
|
||||
self.Defcon, self.strategy, Nassets, Ncontacts, Nborder, Nconflict, Nattack, Ntargets, Nmissions)
|
||||
self.Defcon, self.strategy, Nassets, Ncontacts, self.Nborder, self.Nconflict, self.Nattack, Ntargets, Nmissions)
|
||||
self:I(self.lid..text)
|
||||
|
||||
end
|
||||
@ -1470,6 +1493,59 @@ end
|
||||
-- Target Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Display tactical overview.
|
||||
-- @param #CHIEF self
|
||||
function CHIEF:_TacticalOverview()
|
||||
|
||||
if self.tacview then
|
||||
|
||||
local NassetsTotal=self.commander:CountAssets()
|
||||
local NassetsStock=self.commander:CountAssets(true)
|
||||
local Ncontacts=#self.Contacts
|
||||
local Nmissions=#self.commander.missionqueue
|
||||
local Ntargets=#self.targetqueue
|
||||
local Nzones=#self.zonequeue
|
||||
|
||||
-- Info message
|
||||
local text=string.format("Tactical Overview\n")
|
||||
text=text..string.format("=================\n")
|
||||
|
||||
text=text..string.format("Strategy: %s - Defcon: %s\n", self.strategy, self.Defcon)
|
||||
|
||||
text=text..string.format("Contacts: %d [Border=%d, Conflict=%d, Attack=%d]\n", Ncontacts, self.Nborder, self.Nconflict, self.Nattack)
|
||||
|
||||
text=text..string.format("Targets: %d\n", Ntargets)
|
||||
|
||||
text=text..string.format("Missions: %d\n", Nmissions)
|
||||
for _,mtype in pairs(AUFTRAG.Type) do
|
||||
local n=self.commander:CountMissions(mtype)
|
||||
if n>0 then
|
||||
text=text..string.format(" - %s: %d\n", mtype, n)
|
||||
end
|
||||
end
|
||||
|
||||
text=text..string.format("Assets: %d [Stock %d]\n", NassetsTotal, NassetsStock)
|
||||
|
||||
text=text..string.format("Strategic Zones: %d\n", Nzones)
|
||||
for _,_stratzone in pairs(self.zonequeue) do
|
||||
local stratzone=_stratzone --#CHIEF.StrategicZone
|
||||
local owner=stratzone.opszone:GetOwnerName()
|
||||
text=text..string.format(" - %s: %s - %s [I=%d, P=%d]\n", stratzone.opszone:GetName(), owner, stratzone.opszone:GetState(), stratzone.importance, stratzone.prio)
|
||||
end
|
||||
|
||||
-- Message to coalition.
|
||||
MESSAGE:New(text, 60, nil, true):ToCoalition(self.coalition)
|
||||
|
||||
-- Output to log.
|
||||
if self.verbose>=4 then
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Check target queue and assign ONE valid target by adding it to the mission queue of the COMMANDER.
|
||||
-- @param #CHIEF self
|
||||
function CHIEF:CheckTargetQueue()
|
||||
|
||||
@ -1411,6 +1411,26 @@ function COMMANDER:CountAssets(InStock, MissionTypes, Attributes)
|
||||
return N
|
||||
end
|
||||
|
||||
--- Count assets of all assigned legions.
|
||||
-- @param #COMMANDER self
|
||||
-- @param #table MissionTypes (Optional) Count only missions of these types. Default is all types.
|
||||
-- @return #number Amount missions.
|
||||
function COMMANDER:CountMissions(MissionTypes)
|
||||
|
||||
local N=0
|
||||
for _,_mission in pairs(self.missionqueue) do
|
||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||
|
||||
-- Check if this mission type is requested.
|
||||
if AUFTRAG.CheckMissionType(mission.type, MissionTypes) then
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return N
|
||||
end
|
||||
|
||||
--- Count assets of all assigned legions.
|
||||
-- @param #COMMANDER self
|
||||
-- @param #boolean InStock If true, only assets that are in the warehouse stock/inventory are counted.
|
||||
|
||||
@ -413,6 +413,13 @@ function OPSZONE:GetOwner()
|
||||
return self.ownerCurrent
|
||||
end
|
||||
|
||||
--- Get coalition name of current owner of the zone.
|
||||
-- @param #OPSZONE self
|
||||
-- @return #string Owner coalition.
|
||||
function OPSZONE:GetOwnerName()
|
||||
return UTILS.GetCoalitionName(self.ownerCurrent)
|
||||
end
|
||||
|
||||
--- Get coordinate of zone.
|
||||
-- @param #OPSZONE self
|
||||
-- @return Core.Point#COORDINATE Coordinate of the zone.
|
||||
@ -421,7 +428,7 @@ function OPSZONE:GetCoordinate()
|
||||
return coordinate
|
||||
end
|
||||
|
||||
--- Get name.
|
||||
--- Get zone name.
|
||||
-- @param #OPSZONE self
|
||||
-- @return #string Name of the zone.
|
||||
function OPSZONE:GetName()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user