diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index 2c492a949..3bd050937 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -234,7 +234,8 @@ FORMATION = { -- @param #BASE self -- @return #BASE function BASE:New() - local self = routines.utils.deepCopy( self ) -- Create a new self instance + --local self = routines.utils.deepCopy( self ) -- Create a new self instance + local self = UTILS.DeepCopy(self) _ClassID = _ClassID + 1 self.ClassID = _ClassID diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 91311559a..d23079f07 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -139,6 +139,16 @@ AIRWING = { -- @field #number noccupied Number of flights on this patrol point. -- @field Wrapper.Marker#MARKER marker F10 marker. +--- Patrol zone. +-- @type AIRWING.PatrolZone +-- @field Core.Zone#ZONE zone Zone. +-- @field #number altitude Altitude in feet. +-- @field #number heading Heading in degrees. +-- @field #number leg Leg length in NM. +-- @field #number speed Speed in knots. +-- @field Ops.Auftrag#AUFTRAG mission Mission assigned. +-- @field Wrapper.Marker#MARKER marker F10 marker. + --- AWACS zone. -- @type AIRWING.AwacsZone -- @field Core.Zone#ZONE zone Zone. @@ -146,20 +156,13 @@ AIRWING = { -- @field #number heading Heading in degrees. -- @field #number leg Leg length in NM. -- @field #number speed Speed in knots. --- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`. -- @field Ops.Auftrag#AUFTRAG mission Mission assigned. -- @field Wrapper.Marker#MARKER marker F10 marker. --- Tanker zone. -- @type AIRWING.TankerZone --- @field Core.Point#COORDINATE coord Patrol coordinate. --- @field #number altitude Altitude in feet. --- @field #number heading Heading in degrees. --- @field #number leg Leg length in NM. --- @field #number speed Speed in knots. -- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`. --- @field Ops.Auftrag#AUFTRAG mission Mission assigned. --- @field Wrapper.Marker#MARKER marker F10 marker. +-- @extends #AIRWING.PatrolZone --- AIRWING class version. -- @field #string version diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index d6ed68002..f8775e972 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -4098,12 +4098,13 @@ end -- @return #number Number of alive target units. function AUFTRAG:CountMissionTargets() + local N=0 + if self.engageTarget then - return self.engageTarget:CountTargets() - else - return 0 + N=self.engageTarget:CountTargets() end + return N end --- Get initial number of targets. @@ -4167,14 +4168,16 @@ end -- @param #AUFTRAG self -- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things. function AUFTRAG:GetObjective() - return self:GetTargetData():GetObject() + local objective=self:GetTargetData():GetObject() + return objective end --- Get type of target. -- @param #AUFTRAG self -- @return #string The target type. function AUFTRAG:GetTargetType() - return self:GetTargetData().Type + local ttype=self:GetTargetData().Type + return ttype end --- Get 2D vector of target. @@ -4183,7 +4186,8 @@ end function AUFTRAG:GetTargetVec2() local coord=self:GetTargetCoordinate() if coord then - return coord:GetVec2() + local vec2=coord:GetVec2() + return vec2 end return nil end @@ -4216,7 +4220,8 @@ end function AUFTRAG:GetTargetName() if self.engageTarget then - return self.engageTarget:GetName() + local name=self.engageTarget:GetName() + return name end return "N/A" diff --git a/Moose Development/Moose/Ops/Chief.lua b/Moose Development/Moose/Ops/Chief.lua index be51a22ce..e1be3bdb0 100644 --- a/Moose Development/Moose/Ops/Chief.lua +++ b/Moose Development/Moose/Ops/Chief.lua @@ -645,7 +645,7 @@ function CHIEF:IsTarget(Target) for _,_target in pairs(self.targetqueue) do local target=_target --Ops.Target#TARGET - if target.uid==Target.uid then + if target.uid==Target.uid or target:GetName()==Target:GetName() then return true end end @@ -725,20 +725,54 @@ function CHIEF:AddRefuellingZone(RefuellingZone) return supplyzone end ---- Add an AWACS zone. +--- Add a CAP zone. -- @param #CHIEF self --- @param Core.Zone#ZONE AwacsZone Zone. +-- @param Core.Zone#ZONE Zone Zone. -- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. -- @param #number Speed Orbit speed in KIAS. Default 350 kts. -- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Leg Length of race-track in NM. Default 30 NM. --- @return Ops.AirWing#AIRWING.AwacsZone The AWACS zone. -function CHIEF:AddAwacsZone(AwacsZone, Altitude, Speed, Heading, Leg) +-- @return Ops.AirWing#AIRWING.PatrolZone The CAP zone data. +function CHIEF:AddCapZone(Zone, Altitude, Speed, Heading, Leg) -- Hand over to commander. - local awacszone=self.commander:AddAwacsZone(AwacsZone, Altitude, Speed, Heading, Leg) + local zone=self.commander:AddCapZone(Zone, Altitude, Speed, Heading, Leg) - return awacszone + return zone +end + + +--- Add an AWACS zone. +-- @param #CHIEF self +-- @param Core.Zone#ZONE Zone Zone. +-- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. +-- @param #number Speed Orbit speed in KIAS. Default 350 kts. +-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). +-- @param #number Leg Length of race-track in NM. Default 30 NM. +-- @return Ops.AirWing#AIRWING.PatrolZone The AWACS zone data. +function CHIEF:AddAwacsZone(Zone, Altitude, Speed, Heading, Leg) + + -- Hand over to commander. + local zone=self.commander:AddAwacsZone(Zone, Altitude, Speed, Heading, Leg) + + return zone +end + +--- Add a refuelling tanker zone. +-- @param #CHIEF self +-- @param Core.Zone#ZONE Zone Zone. +-- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. +-- @param #number Speed Orbit speed in KIAS. Default 350 kts. +-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). +-- @param #number Leg Length of race-track in NM. Default 30 NM. +-- @param #number RefuelSystem Refuelling system. +-- @return Ops.AirWing#AIRWING.TankerZone The tanker zone data. +function CHIEF:AddTankerZone(Zone, Altitude, Speed, Heading, Leg, RefuelSystem) + + -- Hand over to commander. + local zone=self.commander:AddTankerZone(Zone, Altitude, Speed, Heading, Leg, RefuelSystem) + + return zone end @@ -931,12 +965,14 @@ function CHIEF:onafterStatus(From, Event, To) -- Cancel this mission. contact.mission:Cancel() - - -- Remove a target from the queue. - self:RemoveTarget(contact.target) end + -- Remove a target from the queue. + if contact.target then + self:RemoveTarget(contact.target) + end + end --- @@ -1330,11 +1366,17 @@ function CHIEF:CheckTargetQueue() for _,_target in pairs(self.targetqueue) do local target=_target --Ops.Target#TARGET + local isAlive=target:IsAlive() + local isImportant=(target.importance==nil or target.importance<=vip) + -- Is this a threat? local isThreat=target.threatlevel0>=self.threatLevelMin and target.threatlevel0<=self.threatLevelMax + + -- Debug message. + self:T(self.lid..string.format("Target %s: Alive=%s, Threat=%s, Important=%s", target:GetName(), tostring(isAlive), tostring(isThreat), tostring(isImportant))) -- Check that target is alive and not already a mission has been assigned. - if target:IsAlive() and (target.importance==nil or target.importance<=vip) and isThreat and not target.mission then + if isAlive and isThreat and isImportant and not target.mission then -- Check if this target is "valid", i.e. fits with the current strategy. local valid=false diff --git a/Moose Development/Moose/Ops/Cohort.lua b/Moose Development/Moose/Ops/Cohort.lua index 3e6a45508..611f56abd 100644 --- a/Moose Development/Moose/Ops/Cohort.lua +++ b/Moose Development/Moose/Ops/Cohort.lua @@ -81,7 +81,7 @@ COHORT.version="0.0.2" -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: A lot! +-- TODO: Create FLOTILLA class. -- DONE: Make general so that PLATOON and SQUADRON can inherit this class. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/Commander.lua b/Moose Development/Moose/Ops/Commander.lua index 06f2df9ef..d3f478966 100644 --- a/Moose Development/Moose/Ops/Commander.lua +++ b/Moose Development/Moose/Ops/Commander.lua @@ -24,7 +24,9 @@ -- @field #table transportqueue Transport queue. -- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.SupplyZone`. -- @field #table refuellingZones Refuelling zones. Each element is of type `#BRIGADE.SupplyZone`. --- @field #table awacsZones AWACS zones. Each element is of type `#AIRWING.AwacsZone`. +-- @field #table capZones CAP zones. Each element is of type `#AIRWING.PatrolZone`. +-- @field #table awacsZones AWACS zones. Each element is of type `#AIRWING.PatrolZone`. +-- @field #table tankerZones Tanker zones. Each element is of type `#AIRWING.TankerZone`. -- @field Ops.Chief#CHIEF chief Chief of staff. -- @extends Core.Fsm#FSM @@ -47,7 +49,9 @@ COMMANDER = { transportqueue = {}, rearmingZones = {}, refuellingZones = {}, + capZones = {}, awacsZones = {}, + tankerZones = {}, } --- COMMANDER class version. @@ -58,6 +62,8 @@ COMMANDER.version="0.1.0" -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- TODO: Add CAP zones. +-- TODO: Add tanker zones. -- DONE: Improve legion selection. Mostly done! -- DONE: Find solution for missions, which require a transport. This is not as easy as it sounds since the selected mission assets restrict the possible transport assets. -- DONE: Add ops transports. @@ -81,7 +87,7 @@ function COMMANDER:New(Coalition, Alias) -- Set coaliton. self.coalition=Coalition -- Alias name. - self.alias=Alias or string.format("Jon Doe") + self.alias=Alias or string.format("John Doe") -- Log ID. self.lid=string.format("COMMANDER %s [%s] | ", self.alias, UTILS.GetCoalitionName(self.coalition)) @@ -416,19 +422,44 @@ function COMMANDER:AddRefuellingZone(RefuellingZone) return rearmingzone end ---- Add an AWACS zone. +--- Add a CAP zone. -- @param #COMMANDER self --- @param Core.Zone#ZONE AwacsZone Zone. +-- @param Core.Zone#ZONE CapZone Zone. -- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. -- @param #number Speed Orbit speed in KIAS. Default 350 kts. -- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Leg Length of race-track in NM. Default 30 NM. --- @return Ops.AirWing#AIRWING.AwacsZone The AWACS zone. -function COMMANDER:AddAwacsZone(AwacsZone, Altitude, Speed, Heading, Leg) +-- @return Ops.AirWing#AIRWING.PatrolZone The CAP zone data. +function COMMANDER:AddCapZone(Zone, Altitude, Speed, Heading, Leg) - local awacszone={} --Ops.AirWing#AIRWING.AwacsZone + local patrolzone={} --Ops.AirWing#AIRWING.PatrolZone - awacszone.zone=AwacsZone + patrolzone.zone=Zone + patrolzone.altitude=Altitude or 12000 + patrolzone.heading=Heading or 270 + patrolzone.speed=UTILS.KnotsToAltKIAS(Speed or 350, patrolzone.altitude) + patrolzone.leg=Leg or 30 + patrolzone.mission=nil + patrolzone.marker=MARKER:New(patrolzone.zone:GetCoordinate(), "AWACS Zone"):ToCoalition(self:GetCoalition()) + + table.insert(self.capZones, patrolzone) + + return awacszone +end + +--- Add an AWACS zone. +-- @param #COMMANDER self +-- @param Core.Zone#ZONE Zone Zone. +-- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. +-- @param #number Speed Orbit speed in KIAS. Default 350 kts. +-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). +-- @param #number Leg Length of race-track in NM. Default 30 NM. +-- @return Ops.AirWing#AIRWING.PatrolZone The AWACS zone data. +function COMMANDER:AddAwacsZone(Zone, Altitude, Speed, Heading, Leg) + + local awacszone={} --Ops.AirWing#AIRWING.PatrolZone + + awacszone.zone=Zone awacszone.altitude=Altitude or 12000 awacszone.heading=Heading or 270 awacszone.speed=UTILS.KnotsToAltKIAS(Speed or 350, awacszone.altitude) @@ -441,6 +472,33 @@ function COMMANDER:AddAwacsZone(AwacsZone, Altitude, Speed, Heading, Leg) return awacszone end +--- Add a refuelling tanker zone. +-- @param #COMMANDER self +-- @param Core.Zone#ZONE Zone Zone. +-- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet. +-- @param #number Speed Orbit speed in KIAS. Default 350 kts. +-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). +-- @param #number Leg Length of race-track in NM. Default 30 NM. +-- @param #number RefuelSystem Refuelling system. +-- @return Ops.AirWing#AIRWING.TankerZone The tanker zone data. +function COMMANDER:AddTankerZone(Zone, Altitude, Speed, Heading, Leg, RefuelSystem) + + local tankerzone={} --Ops.AirWing#AIRWING.TankerZone + + tankerzone.zone=Zone + tankerzone.altitude=Altitude or 12000 + tankerzone.heading=Heading or 270 + tankerzone.speed=UTILS.KnotsToAltKIAS(Speed or 350, tankerzone.altitude) + tankerzone.leg=Leg or 30 + tankerzone.refuelsystem=RefuelSystem + tankerzone.mission=nil + tankerzone.marker=MARKER:New(tankerzone.zone:GetCoordinate(), "Tanker Zone"):ToCoalition(self:GetCoalition()) + + table.insert(self.tankerZones, tankerzone) + + return awacszone +end + --- Check if this mission is already in the queue. -- @param #COMMANDER self -- @param Ops.Auftrag#AUFTRAG Mission The mission. @@ -526,16 +584,39 @@ function COMMANDER:onafterStatus(From, Event, To) self:AddMission(supplyzone.mission) end end + + + -- Check CAP zones. + for _,_patrolzone in pairs(self.capZones) do + local patrolzone=_patrolzone --Ops.AirWing#AIRWING.PatrolZone + -- Check if mission is nil or over. + if (not patrolzone.mission) or patrolzone.mission:IsOver() then + local Coordinate=patrolzone.zone:GetCoordinate() + patrolzone.mission=AUFTRAG:NewCAP(patrolzone.zone, patrolzone.altitude, patrolzone.speed, Coordinate, patrolzone.heading, patrolzone.leg) + self:AddMission(patrolzone.mission) + end + end -- Check AWACS zones. for _,_awacszone in pairs(self.awacsZones) do - local awacszone=_awacszone --Ops.AirWing#AIRWING.AwacsZone + local awacszone=_awacszone --Ops.AirWing#AIRWING.Patrol -- Check if mission is nil or over. if (not awacszone.mission) or awacszone.mission:IsOver() then local Coordinate=awacszone.zone:GetCoordinate() awacszone.mission=AUFTRAG:NewAWACS(Coordinate, awacszone.altitude, awacszone.speed, awacszone.heading, awacszone.leg) self:AddMission(awacszone.mission) end + end + + -- Check Tanker zones. + for _,_tankerzone in pairs(self.tankerZones) do + local tankerzone=_tankerzone --Ops.AirWing#AIRWING.TankerZone + -- Check if mission is nil or over. + if (not tankerzone.mission) or tankerzone.mission:IsOver() then + local Coordinate=tankerzone.zone:GetCoordinate() + tankerzone.mission=AUFTRAG:NewTANKER(Coordinate, tankerzone.altitude, tankerzone.speed, tankerzone.heading, tankerzone.leg, tankerzone.refuelsystem) + self:AddMission(tankerzone.mission) + end end --- diff --git a/Moose Development/Moose/Ops/FlightControl.lua b/Moose Development/Moose/Ops/FlightControl.lua index 97917bb7e..3465a12c5 100644 --- a/Moose Development/Moose/Ops/FlightControl.lua +++ b/Moose Development/Moose/Ops/FlightControl.lua @@ -2161,6 +2161,7 @@ function FLIGHTCONTROL:RemoveParkingGuard(spot, delay) else if spot.ParkingGuard then + self:I(self.lid..string.format("Removing parking guard at spot %d", spot.TerminalID)) spot.ParkingGuard:Destroy() spot.ParkingGuard=nil end diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 46d170ffa..1c5e657cd 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -2487,8 +2487,9 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand) -- Warning, looks like this can make DCS CRASH! Had this after calling RTB once passed the final waypoint. --self:ClearTasks() - -- Just route the group. Respawn might happen when going from holding to final. - self:Route(wp) + -- Just route the group. Respawn might happen when going from holding to final. + -- NOTE: I have delayed that here because of RTB calling _LandAtAirbase which resets current task immediately. So the stop flag change to 1 will not trigger TaskDone() and a current mission is not done either + self:Route(wp, 0.1) end diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index 746f5344e..0d639291c 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -49,8 +49,8 @@ LEGION.version="0.1.0" -- ToDo list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: Create FLOTILLA class. --- TODO: OPS transport. +-- TODO: Create FLEED class. +-- DONE: OPS transport. -- DONE: Make general so it can be inherited by AIRWING and BRIGADE classes. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -440,7 +440,7 @@ function LEGION:onafterStart(From, Event, To) self:GetParent(self, LEGION).onafterStart(self, From, Event, To) -- Info. - self:I(self.lid..string.format("Starting LEGION v%s", LEGION.version)) + self:T3(self.lid..string.format("Starting LEGION v%s", LEGION.version)) end diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 4473b92f9..459bf826d 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -6067,6 +6067,10 @@ function OPSGROUP:onafterStop(From, Event, To) if self.Scheduler then self.Scheduler:Clear() end + + if self.flightcontrol then + + end if self:IsAlive() and not (self:IsDead() or self:IsStopped()) then local life, life0=self:GetLifePoints() diff --git a/Moose Development/Moose/Ops/Target.lua b/Moose Development/Moose/Ops/Target.lua index 32b9eafd1..33cce7664 100644 --- a/Moose Development/Moose/Ops/Target.lua +++ b/Moose Development/Moose/Ops/Target.lua @@ -136,6 +136,7 @@ TARGET.version="0.5.2" -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- TODO: Had cases where target life was 0 but target was not dead. Need to figure out why! -- TODO: Add pseudo functions. -- DONE: Initial object can be nil. @@ -383,6 +384,11 @@ function TARGET:onafterStatus(From, Event, To) damaged=true end + if life==0 then + self:I(self.lid..string.format("FF life is zero but no object dead event fired ==> object dead now for traget object %s!", tostring(target.Name))) + self:ObjectDead(target) + end + end -- Target was damaged. @@ -1056,7 +1062,8 @@ end -- @param #TARGET self -- @return #string Name of the target usually the first object. function TARGET:GetName() - return self.name or "Unknown" + local name=self.name or "Unknown" + return name end --- Get 2D vector. diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 19664867a..5e9ca5105 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -1053,7 +1053,7 @@ function UNIT:GetThreatLevel() elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and not Attributes["ATGM"] then ThreatLevel = 3 elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2 - elseif Attributes["Infantry"] then ThreatLevel = 1 + elseif Attributes["Infantry"] or Attributes["EWR"] then ThreatLevel = 1 end ThreatText = ThreatLevels[ThreatLevel+1]