Merge branch 'FF/Ops' into FF/OpsRat

This commit is contained in:
Frank
2024-03-24 17:59:27 +01:00
53 changed files with 3631 additions and 2476 deletions

View File

@@ -914,12 +914,12 @@ function AUTOLASE:onafterMonitor(From, Event, To)
self:SetPilotMenu()
local detecteditems = self.Contacts or {} -- #table of Ops.Intelligence#INTEL.Contact
local detecteditems = self.Contacts or {} -- #table of Ops.Intel#INTEL.Contact
local groupsbythreat = {}
local report = REPORT:New("Detections")
local lines = 0
for _,_contact in pairs(detecteditems) do
local contact = _contact -- Ops.Intelligence#INTEL.Contact
local contact = _contact -- Ops.Intel#INTEL.Contact
local grp = contact.group
local coord = contact.position
local reccename = contact.recce or "none"

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@
-- @module Functional.Mantis
-- @image Functional.Mantis.jpg
--
-- Last Update: Dec 2023
-- Last Update: Feb 2024
-------------------------------------------------------------------------
--- **MANTIS** class, extends Core.Base#BASE
@@ -347,17 +347,17 @@ MANTIS.SamType = {
-- @field #string Type #MANTIS.SamType of SAM, i.e. SHORT, MEDIUM or LONG (range)
-- @field #string Radar Radar typename on unit level (used as key)
MANTIS.SamData = {
["Hawk"] = { Range=44, Blindspot=0, Height=9, Type="Medium", Radar="Hawk" }, -- measures in km
["NASAMS"] = { Range=14, Blindspot=0, Height=3, Type="Short", Radar="NSAMS" },
["Patriot"] = { Range=99, Blindspot=0, Height=9, Type="Long", Radar="Patriot" },
["Rapier"] = { Range=6, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot" },
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
["SA-5"] = { Range=250, Blindspot=7, Height=40, Type="Long", Radar="5N62V" },
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
["Roland"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Roland" },
["Roland"] = { Range=5, Blindspot=0, Height=5, Type="Short", Radar="Roland" },
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Short", Radar="Strela" },
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
@@ -376,7 +376,7 @@ MANTIS.SamData = {
["HQ-2"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
["SHORAD"] = { Range=3, Blindspot=0, Height=3, Type="Short", Radar="Igla" },
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
}
--- SAM data HDS
@@ -1222,10 +1222,10 @@ do
function MANTIS:_PreFilterHeight(height)
self:T(self.lid.."_PreFilterHeight")
local set = {}
local dlink = self.Detection -- Ops.Intelligence#INTEL_DLINK
local dlink = self.Detection -- Ops.Intel#INTEL_DLINK
local detectedgroups = dlink:GetContactTable()
for _,_contact in pairs(detectedgroups) do
local contact = _contact -- Ops.Intelligence#INTEL.Contact
local contact = _contact -- Ops.Intel#INTEL.Contact
local grp = contact.group -- Wrapper.Group#GROUP
if grp:IsAlive() then
if grp:GetHeight(true) < height then
@@ -1777,7 +1777,7 @@ do
-- @return #MANTIS self
function MANTIS:_CheckDLinkState()
self:T(self.lid .. "_CheckDLinkState")
local dlink = self.Detection -- Ops.Intelligence#INTEL_DLINK
local dlink = self.Detection -- Ops.Intel#INTEL_DLINK
local TS = timer.getAbsTime()
if not dlink:Is("Running") and (TS - self.DLTimeStamp > 29) then
self.DLink = false

View File

@@ -78,7 +78,8 @@
-- ### Authors: **FlightControl**
--
-- ### Contributions:
--
--
-- * **Applevangelist**: Additional functionality, fixes.
-- * **Wingthor (TAW)**: Testing & Advice.
-- * **Dutch-Baron (TAW)**: Testing & Advice.
-- * **Whisper**: Testing and Advice.
@@ -116,11 +117,13 @@
-- Special targets can be set that will give extra scores to the players when these are destroyed.
-- Use the methods @{#SCORING.AddUnitScore}() and @{#SCORING.RemoveUnitScore}() to specify a special additional score for a specific @{Wrapper.Unit}s.
-- Use the methods @{#SCORING.AddStaticScore}() and @{#SCORING.RemoveStaticScore}() to specify a special additional score for a specific @{Wrapper.Static}s.
-- Use the method @{#SCORING.SetGroupGroup}() to specify a special additional score for a specific @{Wrapper.Group}s.
-- Use the method @{#SCORING.AddScoreSetGroup}() to specify a special additional score for a specific @{Wrapper.Group}s gathered in a @{Core.Set#SET_GROUP}.
--
-- local Scoring = SCORING:New( "Scoring File" )
-- Scoring:AddUnitScore( UNIT:FindByName( "Unit #001" ), 200 )
-- Scoring:AddStaticScore( STATIC:FindByName( "Static #1" ), 100 )
-- local GroupSet = SET_GROUP:New():FilterPrefixes("RAT"):FilterStart()
-- Scoring:AddScoreSetGroup( GroupSet, 100)
--
-- The above grants an additional score of 200 points for Unit #001 and an additional 100 points of Static #1 if these are destroyed.
-- Note that later in the mission, one can remove these scores set, for example, when the a goal achievement time limit is over.
@@ -226,7 +229,7 @@ SCORING = {
ClassID = 0,
Players = {},
AutoSave = true,
version = "1.17.1"
version = "1.18.4"
}
local _SCORINGCoalition = {
@@ -245,13 +248,15 @@ local _SCORINGCategory = {
--- Creates a new SCORING object to administer the scoring achieved by players.
-- @param #SCORING self
-- @param #string GameName The name of the game. This name is also logged in the CSV score file.
-- @param #string SavePath (Optional) Path where to save the CSV file, defaults to your **<User>\\Saved Games\\DCS\\Logs** folder.
-- @param #boolean AutoSave (Optional) If passed as `false`, then swith autosave off.
-- @return #SCORING self
-- @usage
--
-- -- Define a new scoring object for the mission Gori Valley.
-- ScoringObject = SCORING:New( "Gori Valley" )
--
function SCORING:New( GameName )
function SCORING:New( GameName, SavePath, AutoSave )
-- Inherits from BASE
local self = BASE:Inherit( self, BASE:New() ) -- #SCORING
@@ -314,7 +319,8 @@ function SCORING:New( GameName )
end )
-- Create the CSV file.
self.AutoSave = true
self.AutoSavePath = SavePath
self.AutoSave = AutoSave or true
self:OpenCSV( GameName )
return self
@@ -428,6 +434,31 @@ function SCORING:AddScoreGroup( ScoreGroup, Score )
return self
end
--- Specify a special additional score for a @{Core.Set#SET_GROUP}.
-- @param #SCORING self
-- @param Core.Set#SET_GROUP Set The @{Core.Set#SET_GROUP} for which each @{Wrapper.Unit} in each Group a Score is given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddScoreSetGroup(Set, Score)
local set = Set:GetSetObjects()
for _,_group in pairs (set) do
if _group and _group:IsAlive() then
self:AddScoreGroup(_group,Score)
end
end
local function AddScore(group)
self:AddScoreGroup(group,Score)
end
function Set:OnAfterAdded(From,Event,To,ObjectName,Object)
AddScore(Object)
end
return self
end
--- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone.
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
-- This allows for a dynamic destruction zone evolution within your mission.
@@ -1030,11 +1061,11 @@ function SCORING:_EventOnHit( Event )
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
if PlayerHit.ThreatType == nil then
if PlayerHit.ThreatType == nil or PlayerHit.ThreatType == "" then
PlayerHit.ThreatLevel = 1
PlayerHit.ThreatType = "Unknown"
end
@@ -1141,7 +1172,7 @@ function SCORING:_EventOnHit( Event )
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
@@ -1288,17 +1319,17 @@ function SCORING:_EventOnDeadOrCrash( Event )
TargetDestroy.PenaltyDestroy = TargetDestroy.PenaltyDestroy + 1
self:OnKillPvP(Player, TargetPlayerName, true, TargetThreatLevel, Player.ThreatLevel, ThreatPenalty)
--self:OnKillPvP(PlayerName, TargetPlayerName, true, TargetThreatLevel, Player.ThreatLevel, ThreatPenalty)
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
self:OnKillPvP(Player, TargetPlayerName, true)
self:OnKillPvP(PlayerName, TargetPlayerName, true)
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
self:OnKillPvE(Player, TargetUnitName, true, TargetThreatLevel, Player.ThreatLevel, ThreatPenalty)
self:OnKillPvE(PlayerName, TargetUnitName, true, TargetThreatLevel, Player.ThreatLevel, ThreatPenalty)
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
@@ -1326,14 +1357,14 @@ function SCORING:_EventOnDeadOrCrash( Event )
else
Player.PlayerKills = 1
end
self:OnKillPvP(Player, TargetPlayerName, false, TargetThreatLevel, Player.ThreatLevel, ThreatScore)
self:OnKillPvP(PlayerName, TargetPlayerName, false, TargetThreatLevel, Player.ThreatLevel, ThreatScore)
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
self:OnKillPvE(Player, TargetUnitName, false, TargetThreatLevel, Player.ThreatLevel, ThreatScore)
self:OnKillPvE(PlayerName, TargetUnitName, false, TargetThreatLevel, Player.ThreatLevel, ThreatScore)
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
@@ -1811,10 +1842,11 @@ end
function SCORING:OpenCSV( ScoringCSV )
self:F( ScoringCSV )
if lfs and io and os and self.AutoSave then
if lfs and io and os and self.AutoSave == true then
if ScoringCSV then
self.ScoringCSV = ScoringCSV
local fdir = lfs.writedir() .. [[Logs\]] .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
local path = self.AutoSavePath or lfs.writedir() .. [[Logs\]]
local fdir = path .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
self.CSVFile, self.err = io.open( fdir, "w+" )
if not self.CSVFile then
@@ -1935,23 +1967,23 @@ end
--- Handles the event when one player kill another player
-- @param #SCORING self
-- @param #PLAYER Player the ataching player
-- @param #string TargetPlayerName the name of the killed player
-- @param #bool IsTeamKill true if this kill was a team kill
-- @param #number TargetThreatLevel Thread level of the target
-- @param #number PlayerThreatLevelThread level of the player
-- @param #string PlayerName The attacking player
-- @param #string TargetPlayerName The name of the killed player
-- @param #boolean IsTeamKill true if this kill was a team kill
-- @param #number TargetThreatLevel Threat level of the target
-- @param #number PlayerThreatLevel Threat level of the player
-- @param #number Score The score based on both threat levels
function SCORING:OnKillPvP(Player, TargetPlayerName, IsTeamKill, TargetThreatLevel, PlayerThreatLevel, Score)
function SCORING:OnKillPvP(PlayerName, TargetPlayerName, IsTeamKill, TargetThreatLevel, PlayerThreatLevel, Score)
end
--- Handles the event when one player kill another player
-- @param #SCORING self
-- @param #PLAYER Player the ataching player
-- @param #string PlayerName The attacking player
-- @param #string TargetUnitName the name of the killed unit
-- @param #bool IsTeamKill true if this kill was a team kill
-- @param #number TargetThreatLevel Thread level of the target
-- @param #number PlayerThreatLevelThread level of the player
-- @param #boolean IsTeamKill true if this kill was a team kill
-- @param #number TargetThreatLevel Threat level of the target
-- @param #number PlayerThreatLevel Threat level of the player
-- @param #number Score The score based on both threat levels
function SCORING:OnKillPvE(Player, TargetUnitName, IsTeamKill, TargetThreatLevel, PlayerThreatLevel, Score)
function SCORING:OnKillPvE(PlayerName, TargetUnitName, IsTeamKill, TargetThreatLevel, PlayerThreatLevel, Score)
end
end

View File

@@ -320,9 +320,6 @@ function SEAD:onafterCalculateHitZone(From,Event,To,SEADWeapon,pos0,height,SEADG
end
local seadset = SET_GROUP:New():FilterPrefixes(self.SEADGroupPrefixes):FilterZones({targetzone}):FilterOnce()
local tgtcoord = targetzone:GetRandomPointVec2()
--if tgtcoord and tgtcoord.ClassName == "COORDINATE" then
--local tgtgrp = seadset:FindNearestGroupFromPointVec2(tgtcoord)
local tgtgrp = seadset:GetRandom()
local _targetgroup = nil
local _targetgroupname = "none"

View File

@@ -41,6 +41,7 @@
-- @field #boolean usebudget
-- @field #number CaptureUnits
-- @field #number CaptureThreatlevel
-- @field #boolean ExcludeShips
-- @extends Core.Base#BASE
-- @extends Core.Fsm#FSM
@@ -176,7 +177,7 @@ STRATEGO = {
debug = false,
drawzone = false,
markzone = false,
version = "0.2.4",
version = "0.2.5",
portweight = 3,
POIweight = 1,
maxrunways = 3,
@@ -195,6 +196,7 @@ STRATEGO = {
usebudget = false,
CaptureUnits = 3,
CaptureThreatlevel = 1,
ExcludeShips = true,
}
---
@@ -256,6 +258,7 @@ function STRATEGO:New(Name,Coalition,MaxDist)
self.maxdist = MaxDist or 150 -- km
self.disttable = {}
self.routexists = {}
self.ExcludeShips = true
self.lid = string.format("STRATEGO %s %s | ",self.name,self.version)
@@ -427,6 +430,7 @@ function STRATEGO:AnalyseBases()
self.bases:ForEach(
function(afb)
local ab = afb -- Wrapper.Airbase#AIRBASE
if self.ExcludeShips and ab:IsShip() then return end
local abname = ab:GetName()
local runways = ab:GetRunways()
local numrwys = #runways
@@ -438,14 +442,14 @@ function STRATEGO:AnalyseBases()
local coa = ab:GetCoalition()
if coa == nil then return end -- Spawned FARPS issue - these have no tangible data
coa = coa+1
local abtype = "AIRBASE"
local abtype = STRATEGO.Type.AIRBASE
if ab:IsShip() then
numrwys = 1
abtype = "SHIP"
abtype = STRATEGO.Type.SHIP
end
if ab:IsHelipad() then
numrwys = 1
abtype = "FARP"
abtype = STRATEGO.Type.FARP
end
local coord = ab:GetCoordinate()
if debug then
@@ -481,10 +485,10 @@ function STRATEGO:UpdateNodeCoalitions()
local newtable = {}
for _id,_data in pairs(self.airbasetable) do
local data = _data -- #STRATEGO.Data
if data.type == "AIRBASE" or data.type == "FARP" then
data.coalition = AIRBASE:FindByName(data.name):GetCoalition()
if data.type == STRATEGO.Type.AIRBASE or data.type == STRATEGO.Type.FARP or data.type == STRATEGO.Type.SHIP then
data.coalition = AIRBASE:FindByName(data.name):GetCoalition() or 0
else
data.coalition = data.opszone:GetOwner()
data.coalition = data.opszone:GetOwner() or 0
end
newtable[_id] = _data
end
@@ -937,11 +941,13 @@ function STRATEGO:FindClosestConsolidationTarget(Startpoint,BaseWeight)
local cname = self.easynames[tname]
local targetweight = self.airbasetable[cname].baseweight
coa = self.airbasetable[cname].coalition
--self:T("Start -> End: "..startpoint.." -> "..cname)
if (dist < shortest) and (coa ~= self.coalition) and (BaseWeight >= targetweight) then
self:T("Found Consolidation Target: "..cname)
shortest = dist
target = cname
weight = self.airbasetable[cname].weight
coa = self.airbasetable[cname].coalition
coa = coa
end
end
end
@@ -974,8 +980,9 @@ function STRATEGO:FindClosestStrategicTarget(Startpoint,Weight)
local coa = self.airbasetable[cname].coalition
local tweight = self.airbasetable[cname].baseweight
local ttweight = self.airbasetable[cname].weight
self:T("Start -> End: "..startpoint.." -> "..cname)
--self:T("Start -> End: "..startpoint.." -> "..cname)
if (dist < shortest) and (coa ~= self.coalition) and (tweight >= Weight) then
self:T("Found Strategic Target: "..cname)
shortest = dist
target = cname
weight = self.airbasetable[cname].weight
@@ -996,38 +1003,31 @@ function STRATEGO:FindStrategicTargets()
local data = _data -- #STRATEGO.Data
if data.coalition == self.coalition then
local dist, name, points, coa = self:FindClosestStrategicTarget(data.name,data.weight)
if coa == coalition.side.NEUTRAL and points ~= 0 then
local fpoints = points + self.NeutralBenefit
local tries = 1
while targets[fpoints] or tries < 100 do
fpoints = points + (self.NeutralBenefit+math.random(1,100))
tries = tries + 1
end
targets[fpoints] = {
name = name,
dist = dist,
points = fpoints,
coalition = coa,
coalitionname = UTILS.GetCoalitionName(coa),
coordinate = self.airbasetable[name].coord,
}
if points > 0 then
self:T({dist=dist, name=name, points=points, coa=coa})
end
local enemycoa = self.coalition == coalition.side.BLUE and coalition.side.RED or coalition.side.BLUE
if coa == enemycoa and points ~= 0 then
local fpoints = points
local tries = 1
while targets[fpoints] or tries < 100 do
fpoints = points + (math.random(1,100))
tries = tries + 1
if points ~= 0 then
local enemycoa = self.coalition == coalition.side.BLUE and coalition.side.RED or coalition.side.BLUE
self:T("Enemycoa = "..enemycoa)
if coa == coalition.side.NEUTRAL then
local tdata = {}
tdata.name = name
tdata.dist = dist
tdata.points = points + self.NeutralBenefit
tdata.coalition = coa
tdata.coalitionname = UTILS.GetCoalitionName(coa)
tdata.coordinate = self.airbasetable[name].coord
table.insert(targets,tdata)
else
local tdata = {}
tdata.name = name
tdata.dist = dist
tdata.points = points
tdata.coalition = coa
tdata.coalitionname = UTILS.GetCoalitionName(coa)
tdata.coordinate = self.airbasetable[name].coord
table.insert(targets,tdata)
end
targets[fpoints] = {
name = name,
dist = dist,
points = fpoints,
coalition = coa,
coalitionname = UTILS.GetCoalitionName(coa),
coordinate = self.airbasetable[name].coord,
}
end
end
end
@@ -1044,38 +1044,31 @@ function STRATEGO:FindConsolidationTargets()
local data = _data -- #STRATEGO.Data
if data.coalition == self.coalition then
local dist, name, points, coa = self:FindClosestConsolidationTarget(data.name,self.maxrunways-1)
if coa == coalition.side.NEUTRAL and points ~= 0 then
local fpoints = points + self.NeutralBenefit
local tries = 1
while targets[fpoints] or tries < 100 do
fpoints = points - (self.NeutralBenefit+math.random(1,100))
tries = tries + 1
end
targets[fpoints] = {
name = name,
dist = dist,
points = fpoints,
coalition = coa,
coalitionname = UTILS.GetCoalitionName(coa),
coordinate = self.airbasetable[name].coord,
}
if points > 0 then
self:T({dist=dist, name=name, points=points, coa=coa})
end
local enemycoa = self.coalition == coalition.side.BLUE and coalition.side.RED or coalition.side.BLUE
if coa == enemycoa and points ~= 0 then
local fpoints = points
local tries = 1
while targets[fpoints] or tries < 100 do
fpoints = points - (math.random(1,100))
tries = tries + 1
if points ~= 0 then
local enemycoa = self.coalition == coalition.side.BLUE and coalition.side.RED or coalition.side.BLUE
self:T("Enemycoa = "..enemycoa)
if coa == coalition.side.NEUTRAL then
local tdata = {}
tdata.name = name
tdata.dist = dist
tdata.points = points + self.NeutralBenefit
tdata.coalition = coa
tdata.coalitionname = UTILS.GetCoalitionName(coa)
tdata.coordinate = self.airbasetable[name].coord
table.insert(targets,tdata)
else
local tdata = {}
tdata.name = name
tdata.dist = dist
tdata.points = points
tdata.coalition = coa
tdata.coalitionname = UTILS.GetCoalitionName(coa)
tdata.coordinate = self.airbasetable[name].coord
table.insert(targets,tdata)
end
targets[fpoints] = {
name = name,
dist = dist,
points = fpoints,
coalition = coa,
coalitionname = UTILS.GetCoalitionName(coa),
coordinate = self.airbasetable[name].coord,
}
end
end
end
@@ -1245,13 +1238,15 @@ end
-- @return #table Target Table with #STRATEGO.Target data or nil if none found.
function STRATEGO:FindAffordableStrategicTarget()
self:T(self.lid.."FindAffordableStrategicTarget")
local targets = self:FindStrategicTargets() -- #table of #STRATEGO.Target
local Stargets = self:FindStrategicTargets() -- #table of #STRATEGO.Target
--UTILS.PrintTableToLog(Stargets,1)
local budget = self.Budget
--local leftover = self.Budget
local target = nil -- #STRATEGO.Target
local ftarget = nil -- #STRATEGO.Target
local Targets = {}
for _,_data in pairs(targets) do
for _,_data in pairs(Stargets) do
local data = _data -- #STRATEGO.Target
self:T("Considering Strategic Target "..data.name)
--if data.points <= budget and budget-data.points < leftover then
if data.points <= budget then
--leftover = budget-data.points
@@ -1259,14 +1254,18 @@ function STRATEGO:FindAffordableStrategicTarget()
self:T(self.lid.."Affordable strategic target: "..data.name)
end
end
if not targets then
if #Targets == 0 then
self:T(self.lid.."No suitable target found!")
return nil
end
target = Targets[math.random(1,#Targets)]
if target then
self:T(self.lid.."Final affordable strategic target: "..target.name)
return target
if #Targets > 1 then
ftarget = Targets[math.random(1,#Targets)]
else
ftarget = Targets[1]
end
if ftarget then
self:T(self.lid.."Final affordable strategic target: "..ftarget.name)
return ftarget
else
return nil
end
@@ -1277,13 +1276,15 @@ end
-- @return #table Target Table with #STRATEGO.Target data or nil if none found.
function STRATEGO:FindAffordableConsolidationTarget()
self:T(self.lid.."FindAffordableConsolidationTarget")
local targets = self:FindConsolidationTargets() -- #table of #STRATEGO.Target
local Ctargets = self:FindConsolidationTargets() -- #table of #STRATEGO.Target
--UTILS.PrintTableToLog(Ctargets,1)
local budget = self.Budget
--local leftover = self.Budget
local target = nil -- #STRATEGO.Target
local ftarget = nil -- #STRATEGO.Target
local Targets = {}
for _,_data in pairs(targets) do
for _,_data in pairs(Ctargets) do
local data = _data -- #STRATEGO.Target
self:T("Considering Consolidation Target "..data.name)
--if data.points <= budget and budget-data.points < leftover then
if data.points <= budget then
--leftover = budget-data.points
@@ -1291,14 +1292,18 @@ function STRATEGO:FindAffordableConsolidationTarget()
self:T(self.lid.."Affordable consolidation target: "..data.name)
end
end
if not targets then
if #Targets == 0 then
self:T(self.lid.."No suitable target found!")
return nil
end
target = Targets[math.random(1,#Targets)]
if target then
self:T(self.lid.."Final affordable consolidation target: "..target.name)
return target
if #Targets > 1 then
ftarget = Targets[math.random(1,#Targets)]
else
ftarget = Targets[1]
end
if ftarget then
self:T(self.lid.."Final affordable consolidation target: "..ftarget.name)
return ftarget
else
return nil
end

View File

@@ -1629,7 +1629,7 @@ WAREHOUSE = {
-- @field #boolean arrived If true, asset arrived at its destination.
--
-- @field #number damage Damage of asset group in percent.
-- @field Ops.AirWing#AIRWING.Payload payload The payload of the asset.
-- @field Ops.Airwing#AIRWING.Payload payload The payload of the asset.
-- @field Ops.OpsGroup#OPSGROUP flightgroup The flightgroup object.
-- @field Ops.Cohort#COHORT cohort The cohort this asset belongs to.
-- @field Ops.Legion#LEGION legion The legion this asset belonts to.