moved files and added compile script
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
local StagesByName = {}
|
||||
|
||||
|
||||
GlobalStageManager = {}
|
||||
GlobalStageManager.start = function (database)
|
||||
|
||||
for _, stageName in pairs(database:getStagezoneNames()) do
|
||||
|
||||
local logger = Spearhead.LoggerTemplate:new(stageName, Spearhead.config.logLevel)
|
||||
local stage = Spearhead.internal.Stage:new(stageName, database, logger)
|
||||
|
||||
StagesByName[stageName] = stage
|
||||
|
||||
local logger = Spearhead.LoggerTemplate:new("StageManager", Spearhead.config.logLevel)
|
||||
logger:info("Initiated " .. Spearhead.Util.tableLength(StagesByName) .. " airbases for cap")
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Spearhead.internal.GlobalStageManager = GlobalStageManager
|
||||
@@ -0,0 +1,368 @@
|
||||
|
||||
--- A mission Object.
|
||||
local Mission = {}
|
||||
do -- INIT Mission Class
|
||||
|
||||
local MINIMAL_UNITS_ALIVE_RATIO = 0.20
|
||||
|
||||
local Defaults = {}
|
||||
Defaults.MainMenu = "Missions"
|
||||
Defaults.SelectMenuSubMenus = { Defaults.MainMenu, "Select Mission" }
|
||||
Defaults.ShowMissionSubs = { Defaults.MainMenu }
|
||||
|
||||
local PlayersInMission = {}
|
||||
local MissionType = {
|
||||
UNKNOWN = 0,
|
||||
STRIKE = 1,
|
||||
BAI = 2,
|
||||
DEAD = 3,
|
||||
SAM = 4,
|
||||
}
|
||||
|
||||
do --INIT MISSION TYPE FUNCTIONS
|
||||
---Parse string to mission type
|
||||
---@param input string
|
||||
MissionType.Parse = function(input)
|
||||
if input == nil then
|
||||
return Mission.MissionType.UNKNOWN
|
||||
end
|
||||
|
||||
input = string.lower(input)
|
||||
if input == "dead" then return MissionType.DEAD end
|
||||
if input == "strike" then return MissionType.STRIKE end
|
||||
if input == "bai" then return MissionType.BAI end
|
||||
if input == "sam" then return MissionType.SAM end
|
||||
return Mission.MissionType.UNKNOWN
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param input number missionType
|
||||
---@return string text
|
||||
MissionType.toString = function(input)
|
||||
if input == MissionType.DEAD then return "DEAD" end
|
||||
if input == MissionType.STRIKE then return "STRIKE" end
|
||||
if input == MissionType.BAI then return "BAI" end
|
||||
if input == MissionType.SAM then return "SAM" end
|
||||
return "?"
|
||||
end
|
||||
end
|
||||
Mission.MissionType = MissionType
|
||||
|
||||
Mission.MissionState = {
|
||||
NEW = 0,
|
||||
ACTIVE = 1,
|
||||
COMPLETED = 2,
|
||||
}
|
||||
|
||||
---comment
|
||||
---@param missionZoneName string missionZoneName
|
||||
---@param database table db dependency injection
|
||||
---@return table?
|
||||
function Mission:new(missionZoneName, database, logger)
|
||||
local o = {}
|
||||
setmetatable(o, { __index = self })
|
||||
|
||||
local function ParseGroupName(input)
|
||||
local split_name = Spearhead.Util.split_string(input, "_")
|
||||
local split_length = Spearhead.Util.tableLength(split_name)
|
||||
if Spearhead.Util.startswith(input, "RANDOMMISSION") == true and split_length < 4 then
|
||||
Spearhead.AddMissionEditorWarning("Random Mission with zonename " .. input .. " not in right format")
|
||||
return nil
|
||||
elseif split_length < 3 then
|
||||
Spearhead.AddMissionEditorWarning("Mission with zonename" .. input .. " not in right format")
|
||||
return nil
|
||||
end
|
||||
local type = split_name[2]
|
||||
local parsedType = Mission.MissionType.Parse(type)
|
||||
|
||||
if parsedType == nil then
|
||||
Spearhead.AddMissionEditorWarning("Mission with zonename '" .. input .. "' has an unsupported type '" .. (type or "nil" ))
|
||||
return nil
|
||||
end
|
||||
local name = split_name[3]
|
||||
return {
|
||||
missionName = name,
|
||||
type = parsedType
|
||||
}
|
||||
end
|
||||
|
||||
local parsed = ParseGroupName(missionZoneName)
|
||||
if parsed == nil then return nil end
|
||||
|
||||
o.missionZoneName = missionZoneName
|
||||
o.database = database
|
||||
o.groupNames = database:getGroupsForMissionZone(missionZoneName)
|
||||
o.name = parsed.missionName
|
||||
o.missionType = parsed.type
|
||||
o.missionTypeDisplayName = Mission.MissionType.toString(o.missionType)
|
||||
o.startingGroups = Spearhead.Util.tableLength(o.groupNames)
|
||||
o.missionState = Mission.MissionState.NEW
|
||||
o.missionbriefing = database:GetDescriptionForMission(missionZoneName)
|
||||
o.startingUnits = 0
|
||||
o.logger = logger
|
||||
o.code = database:GetNewMissionCode()
|
||||
|
||||
o.groupNamesPerUnit = {}
|
||||
|
||||
o.groupUnitAliveDict = {}
|
||||
o.targetAliveStates = {}
|
||||
o.hasSpecificTargets = false
|
||||
|
||||
local CheckStateAsync = function (self, time)
|
||||
self:CheckAndUpdateSelf()
|
||||
return nil
|
||||
end
|
||||
|
||||
o.OnUnitLost = function(self, object)
|
||||
--[[
|
||||
OnUnit lost event
|
||||
]]--
|
||||
self.logger:debug("Getting on unit lost event")
|
||||
|
||||
local category = Object.getCategory(object)
|
||||
if category == Object.Category.UNIT then
|
||||
local unitName = object:getName()
|
||||
self.logger:debug("UnitName:" .. unitName)
|
||||
local groupName = self.groupNamesPerUnit[unitName]
|
||||
self.groupUnitAliveDict[groupName][unitName] = false
|
||||
|
||||
if self.targetAliveStates[groupName][unitName] then
|
||||
self.targetAliveStates[groupName][unitName] = false
|
||||
end
|
||||
elseif category == Object.Category.STATIC then
|
||||
local name = object:getName()
|
||||
self.groupUnitAliveDict[name][name] = false
|
||||
|
||||
self.logger:debug("Name " .. name)
|
||||
|
||||
if self.targetAliveStates[name][name] then
|
||||
self.targetAliveStates[name][name] = false
|
||||
end
|
||||
end
|
||||
timer.scheduleFunction(CheckStateAsync, self, timer.getTime() + 3)
|
||||
end
|
||||
|
||||
o.MissionCompleteListeners = {}
|
||||
---comment
|
||||
---@param self table
|
||||
---@param listener table Object that implements "OnMissionComplete(self, mission)"
|
||||
o.AddMissionCompleteListener = function(self, listener)
|
||||
if type(listener) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(self.MissionCompleteListeners, listener)
|
||||
end
|
||||
|
||||
local TriggerMissionComplete = function(self)
|
||||
for _, callable in pairs(self.MissionCompleteListeners) do
|
||||
local succ, err = pcall( function()
|
||||
callable:OnMissionComplete(self)
|
||||
end)
|
||||
if err then
|
||||
self.logger:warn("Error in misstion complete listener:" .. err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local StartCheckingAndUpdateSelfContinuous = function (self)
|
||||
local CheckAndUpdate = function(self, time)
|
||||
self:CheckAndUpdateSelf(true)
|
||||
if self.missionState == Mission.MissionState.COMPLETED or self.missionState == Mission.MissionState.NEW then
|
||||
return nil
|
||||
else
|
||||
return time + 60
|
||||
end
|
||||
end
|
||||
|
||||
timer.scheduleFunction(CheckAndUpdate, self, timer.getTime() + 300)
|
||||
end
|
||||
|
||||
local CleanupDelayedAsync = function (self, time)
|
||||
self:Cleanup()
|
||||
return nil
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param self table
|
||||
---@param checkUnitHealth boolean?
|
||||
o.CheckAndUpdateSelf = function(self, checkUnitHealth)
|
||||
if not checkUnitHealth then checkUnitHealth = false end
|
||||
|
||||
if self.missionState == Mission.MissionState.COMPLETED then
|
||||
return
|
||||
end
|
||||
|
||||
if self.hasSpecificTargets == true then
|
||||
local specificTargetsAlive = false
|
||||
for groupName, unitNameDict in pairs(self.targetAliveStates) do
|
||||
for unitName, isAlive in pairs(unitNameDict) do
|
||||
if isAlive == true then
|
||||
specificTargetsAlive = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if specificTargetsAlive == false then
|
||||
self.missionState = Mission.MissionState.COMPLETED
|
||||
end
|
||||
else
|
||||
local function CountAliveGroups()
|
||||
local aliveGroups = 0
|
||||
|
||||
for _, group in pairs(self.groupUnitAliveDict) do
|
||||
local groupTotal = 0
|
||||
local groupDeath = 0
|
||||
for _, isAlive in pairs(group) do
|
||||
if isAlive ~= true then
|
||||
groupDeath = groupDeath + 1
|
||||
end
|
||||
groupTotal = groupTotal + 1
|
||||
end
|
||||
|
||||
local aliveRatio = (groupTotal - groupDeath) / groupTotal
|
||||
if aliveRatio >= MINIMAL_UNITS_ALIVE_RATIO then
|
||||
aliveGroups = aliveGroups + 1
|
||||
end
|
||||
end
|
||||
|
||||
return aliveGroups
|
||||
end
|
||||
|
||||
if self.missionType == Mission.MissionType.STRIKE then --strike targets should normally have TGT targets
|
||||
if CountAliveGroups() == 0 then
|
||||
self.missionState = Mission.MissionState.COMPLETED
|
||||
end
|
||||
elseif self.missionType == Mission.MissionType.BAI then
|
||||
if CountAliveGroups() == 0 then
|
||||
self.missionState = Mission.MissionState.COMPLETED
|
||||
end
|
||||
end
|
||||
--[[
|
||||
TODO: Other checks for mission complete
|
||||
]]
|
||||
end
|
||||
|
||||
if self.missionState == Mission.MissionState.COMPLETED then
|
||||
self.logger:debug("Mission complete " .. self.name)
|
||||
trigger.action.outText("Mission " .. self.name .. " (" .. self.code .. ") was completed succesfully!", 20)
|
||||
|
||||
TriggerMissionComplete(self)
|
||||
--Schedule cleanup after 5 minutes of mission complete
|
||||
--timer.scheduleFunction(CleanupDelayedAsync, self, timer.getTime() + 300)
|
||||
end
|
||||
end
|
||||
|
||||
---Activates groups for this mission
|
||||
---@param self table
|
||||
o.Activate = function(self)
|
||||
if self.missionState == Mission.MissionState.ACTIVE then
|
||||
return
|
||||
end
|
||||
|
||||
self.missionState = Mission.MissionState.ACTIVE
|
||||
do --spawn groups
|
||||
for key, groupname in pairs(self.groupNames) do
|
||||
Spearhead.DcsUtil.SpawnGroupTemplate(groupname)
|
||||
end
|
||||
end
|
||||
|
||||
StartCheckingAndUpdateSelfContinuous(self)
|
||||
end
|
||||
|
||||
local ToStateString = function(self)
|
||||
if self.hasSpecificTargets then
|
||||
local dead = 0
|
||||
local total = 0
|
||||
for _, group in pairs(self.targetAliveStates) do
|
||||
for _, isAlive in pairs(group) do
|
||||
total = total + 1
|
||||
if isAlive == false then
|
||||
dead = dead + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
local completionPercentage = math.floor((dead / total) * 100)
|
||||
return "Targets Destroyed: " .. completionPercentage .. "%"
|
||||
else
|
||||
local dead = 0
|
||||
local total = 0
|
||||
for _, group in pairs(self.targetAliveStates) do
|
||||
for _, isAlive in pairs(group) do
|
||||
total = total + 1
|
||||
if isAlive == false then
|
||||
dead = dead + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local completionPercentage = math.floor((dead / total) * 100)
|
||||
return "Targets Destroyed: " .. completionPercentage .. "%"
|
||||
end
|
||||
end
|
||||
|
||||
o.ShowBriefing = function(self, groupId)
|
||||
local stateString = ToStateString(self)
|
||||
|
||||
if self.missionbriefing == nil then self.missionbriefing = "No briefing available" end
|
||||
local text = "Mission [" .. self.code .. "] ".. self.name .. "\n \n" .. self.missionbriefing .. " \n \n" .. stateString
|
||||
trigger.action.outTextForGroup(groupId, text, 30);
|
||||
end
|
||||
|
||||
o.Cleanup = function(self)
|
||||
for key, groupName in pairs(self.groupNames) do
|
||||
Spearhead.DcsUtil.DestroyGroup(groupName)
|
||||
end
|
||||
end
|
||||
|
||||
local Init = function(self)
|
||||
for key, group_name in pairs(self.groupNames) do
|
||||
|
||||
self.groupUnitAliveDict[group_name] = {}
|
||||
self.targetAliveStates[group_name] = {}
|
||||
|
||||
if Spearhead.DcsUtil.IsGroupStatic(group_name) then
|
||||
Spearhead.Events.addOnUnitLostEventListener(group_name, self)
|
||||
|
||||
if Spearhead.Util.startswith(group_name, "TGT_") == true then
|
||||
self.targetAliveStates[group_name][group_name] = true
|
||||
end
|
||||
else
|
||||
local group = Group.getByName(group_name)
|
||||
local isGroupTarget = Spearhead.Util.startswith(group_name, "TGT_")
|
||||
|
||||
self.startingUnits = self.startingUnits + group:getInitialSize()
|
||||
for _, unit in pairs(group:getUnits()) do
|
||||
local unitName = unit:getName()
|
||||
|
||||
self.groupNamesPerUnit[unitName] = group_name
|
||||
|
||||
Spearhead.Events.addOnUnitLostEventListener(unitName, self)
|
||||
self.groupUnitAliveDict[group_name][unitName] = true
|
||||
|
||||
if isGroupTarget == true or Spearhead.Util.startswith(unitName, "TGT_") == true then
|
||||
self.targetAliveStates[group_name][unitName] = true
|
||||
end
|
||||
|
||||
if self.missionType == MissionType.DEAD or self.missionType == MissionType.SAM then
|
||||
local desc = unit:getDesc()
|
||||
local attributes = desc.attributes
|
||||
if attributes["SAM"] == true or attributes["SAM TR"] or attributes["AAA"] then
|
||||
self.targetAliveStates[group_name][unitName] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Spearhead.Util.tableLength(self.targetAliveStates) > 0 then
|
||||
self.hasSpecificTargets = true
|
||||
end
|
||||
end
|
||||
|
||||
Init(o)
|
||||
return o;
|
||||
end
|
||||
end
|
||||
|
||||
Spearhead.internal.Mission = Mission
|
||||
@@ -0,0 +1,443 @@
|
||||
|
||||
local Stage = {}
|
||||
do --init STAGE DIRECTOR
|
||||
|
||||
|
||||
local stageDrawingId = 0
|
||||
|
||||
---comment
|
||||
---@param stagezone_name string
|
||||
---@param database table
|
||||
---@param logger table
|
||||
---@return table?
|
||||
function Stage:new(stagezone_name, database, logger, stageConfig)
|
||||
local o = {}
|
||||
setmetatable(o, { __index = self })
|
||||
|
||||
o.zoneName = stagezone_name
|
||||
|
||||
local split = Spearhead.Util.split_string(stagezone_name, "_")
|
||||
if Spearhead.Util.tableLength(split) < 2 then
|
||||
Spearhead.AddMissionEditorWarning("Stage zone with name " .. stagezone_name .. " does not have a order number or valid format")
|
||||
return nil
|
||||
end
|
||||
|
||||
local orderNumber = tonumber(split[2])
|
||||
if orderNumber == nil then
|
||||
Spearhead.AddMissionEditorWarning("Stage zone with name " .. stagezone_name .. " does not have a valid order number : " .. split[2])
|
||||
return nil
|
||||
end
|
||||
|
||||
o.stageNumber = orderNumber
|
||||
o.database = database
|
||||
o.logger = logger
|
||||
o.db = {}
|
||||
o.db.missionsByCode = {}
|
||||
o.db.missions = {}
|
||||
o.db.sams = {}
|
||||
o.db.redAirbasegroups = {}
|
||||
o.db.blueAirbasegroups = {}
|
||||
o.db.airbaseIds = {}
|
||||
o.db.farps = {}
|
||||
o.activeStage = 0
|
||||
o.preActivated = false
|
||||
o.stageConfig = stageConfig or {}
|
||||
o.stageDrawingId = stageDrawingId + 1
|
||||
|
||||
stageDrawingId = stageDrawingId + 1
|
||||
|
||||
do --Init Stage
|
||||
logger:info("Initiating new Stage with name: " .. stagezone_name)
|
||||
|
||||
local missionZones = database:getMissionsForStage(stagezone_name)
|
||||
for _, missionZone in pairs(missionZones) do
|
||||
local mission = Spearhead.internal.Mission:new(missionZone, database, logger)
|
||||
if mission then
|
||||
o.db.missionsByCode[mission.code] = mission
|
||||
if mission.missionType == Spearhead.internal.Mission.MissionType.SAM then
|
||||
table.insert(o.db.sams, mission)
|
||||
else
|
||||
table.insert(o.db.missions, mission)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local randomMissionNames = database:getRandomMissionsForStage(stagezone_name)
|
||||
|
||||
local randomMissionByName = {}
|
||||
for _, missionZoneName in pairs(randomMissionNames) do
|
||||
local mission = Spearhead.internal.Mission:new(missionZoneName, database, logger)
|
||||
if mission then
|
||||
if randomMissionByName[mission.name] == nil then
|
||||
randomMissionByName[mission.name] = {}
|
||||
end
|
||||
table.insert(randomMissionByName[mission.name], mission)
|
||||
end
|
||||
end
|
||||
|
||||
for _, missions in pairs(randomMissionByName) do
|
||||
local mission = Spearhead.Util.randomFromList(missions)
|
||||
if mission then
|
||||
o.db.missionsByCode[mission.code] = mission
|
||||
if mission.missionType == Spearhead.internal.Mission.MissionType.SAM then
|
||||
table.insert(o.db.sams, mission)
|
||||
else
|
||||
table.insert(o.db.missions, mission)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local airbaseIds = database:getAirbaseIdsInStage(o.zoneName)
|
||||
if airbaseIds ~= nil and type(airbaseIds) == "table" then
|
||||
o.db.airbaseIds = airbaseIds
|
||||
for _, airbaseId in pairs(airbaseIds) do
|
||||
|
||||
for _, groupName in pairs(database:getRedGroupsAtAirbase(airbaseId)) do
|
||||
table.insert(o.db.redAirbasegroups, groupName)
|
||||
end
|
||||
|
||||
for _, groupName in pairs(database:getBlueGroupsAtAirbase(airbaseId)) do
|
||||
table.insert(o.db.blueAirbasegroups, groupName)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local farps = database:getFarpZonesInStage(o.zoneName)
|
||||
if farps ~= nil and type(farps) == "table" then o.db.farps = farps end
|
||||
end
|
||||
|
||||
o.IsComplete = function(self)
|
||||
for i, mission in pairs(self.db.missions) do
|
||||
local state = mission:GetState()
|
||||
if state == Spearhead.Mission.MissionState.ACTIVE or state == Spearhead.Mission.MissionState.NEW then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---Activates all SAMS, Airbase units etc all at once.
|
||||
---@param self table
|
||||
o.PreActivate = function(self)
|
||||
if self.preActivated == false then
|
||||
self.preActivated = true
|
||||
for key, mission in pairs(self.db.sams) do
|
||||
if mission and mission.Activate then
|
||||
mission:Activate()
|
||||
end
|
||||
end
|
||||
self.logger:debug("Pre-activating stage with airbase groups amount: " .. Spearhead.Util.tableLength(self.db.redAirbasegroups))
|
||||
|
||||
for _ , groupName in pairs(self.db.redAirbasegroups) do
|
||||
Spearhead.DcsUtil.SpawnGroupTemplate(groupName)
|
||||
end
|
||||
end
|
||||
|
||||
if self.activeStage == self.stageNumber then
|
||||
for _, mission in pairs(self.db.sams) do
|
||||
self:AddCommmandsForMissionToAllPlayers(mission)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local activateMissionsIfApplicableAsync = function(self)
|
||||
self:ActivateMissionsIfApplicable(self)
|
||||
end
|
||||
|
||||
o.MarkStage = function(self, blue)
|
||||
local fillColor = {1, 0, 0, 0.1}
|
||||
local line ={ 1, 0,0, 1 }
|
||||
if blue == true then
|
||||
fillColor = {0, 0, 1, 0.1}
|
||||
line ={ 0, 0,1, 1 }
|
||||
end
|
||||
|
||||
local zone = Spearhead.DcsUtil.getZoneByName(self.zoneName)
|
||||
if zone then
|
||||
self.logger:debug("drawing stage")
|
||||
if zone.zone_type == Spearhead.DcsUtil.ZoneType.Cilinder then
|
||||
trigger.action.circleToAll(-1, self.stageDrawingId, {x = zone.x, y = 0 , z = zone.z}, zone.radius, {0,0,0,0}, {0,0,0,0},4, true)
|
||||
else
|
||||
--trigger.action.circleToAll(-1, self.stageDrawingId, {x = zone.x, y = 0 , z = zone.z}, zone.radius, { 1, 0,0, 1 }, {1,0,0,1},4, true)
|
||||
trigger.action.quadToAll( -1, self.stageDrawingId, zone.verts[2], zone.verts[1], zone.verts[4], zone.verts[3], {0,0,0,0}, {0,0,0,0}, 4, true)
|
||||
end
|
||||
|
||||
trigger.action.setMarkupColorFill(self.stageDrawingId, fillColor)
|
||||
trigger.action.setMarkupColor(self.stageDrawingId, line)
|
||||
end
|
||||
end
|
||||
|
||||
o.ActivateStage = function(self)
|
||||
pcall(function()
|
||||
self:MarkStage()
|
||||
end)
|
||||
|
||||
self:PreActivate()
|
||||
|
||||
local miscGroups = self.database:getMiscGroupsAtStage(self.zoneName)
|
||||
self.logger:debug("Activating Misc groups for zone: " .. Spearhead.Util.tableLength(miscGroups))
|
||||
for _, groupName in pairs(miscGroups) do
|
||||
Spearhead.DcsUtil.SpawnGroupTemplate(groupName)
|
||||
end
|
||||
|
||||
for _, mission in pairs(self.db.missions) do
|
||||
if mission.missionType == Spearhead.internal.Mission.MissionType.DEAD then
|
||||
mission:Activate()
|
||||
self:AddCommmandsForMissionToAllPlayers(mission)
|
||||
end
|
||||
end
|
||||
timer.scheduleFunction(activateMissionsIfApplicableAsync, self, timer.getTime() + 5)
|
||||
end
|
||||
|
||||
o.ActivateMissionsIfApplicable = function (self)
|
||||
local activeCount = 0
|
||||
|
||||
local availableMissions = {}
|
||||
for _, mission in pairs(self.db.missionsByCode) do
|
||||
if mission.missionState == Spearhead.internal.Mission.MissionState.ACTIVE then
|
||||
activeCount = activeCount + 1
|
||||
end
|
||||
|
||||
if mission.missionState == Spearhead.internal.Mission.MissionState.NEW then
|
||||
table.insert(availableMissions, mission)
|
||||
end
|
||||
end
|
||||
|
||||
local max = self.stageConfig.maxMissionsInStage or 10
|
||||
|
||||
local availableMissionsCount = Spearhead.Util.tableLength(availableMissions)
|
||||
if activeCount < max and availableMissionsCount > 0 then
|
||||
for i = activeCount+1, max do
|
||||
if availableMissionsCount == 0 then
|
||||
i = max+1 --exits this loop
|
||||
else
|
||||
local index = math.random(1, availableMissionsCount)
|
||||
local mission = table.remove(availableMissions, index)
|
||||
if mission then
|
||||
mission:Activate()
|
||||
self:AddCommmandsForMissionToAllPlayers(mission)
|
||||
end
|
||||
availableMissionsCount = availableMissionsCount - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Cleans up all missions
|
||||
---@param self table
|
||||
o.Clean = function(self)
|
||||
for key, mission in pairs(self.db.missions) do
|
||||
mission:Cleanup()
|
||||
end
|
||||
|
||||
for key, samMission in pairs(self.db.sams) do
|
||||
samMission:Cleanup()
|
||||
end
|
||||
|
||||
for _, airbase in pairs(self.db.airbases) do
|
||||
for _, redGroupName in pairs(airbase.redAirbaseGroupNames) do
|
||||
Spearhead.DcsUtil.DcsUtil.DestroyGroup(redGroupName)
|
||||
end
|
||||
end
|
||||
|
||||
logger:debug("'" .. Spearhead.Util.toString(self.zoneName) .. "' cleaned")
|
||||
end
|
||||
|
||||
local ActivateBlueAsync = function(self)
|
||||
pcall(function()
|
||||
self:MarkStage(true)
|
||||
end)
|
||||
|
||||
for key, airbaseId in pairs(self.db.airbaseIds) do
|
||||
local airbase = Spearhead.DcsUtil.getAirbaseById(airbaseId)
|
||||
|
||||
if airbase then
|
||||
local startingCoalition = Spearhead.DcsUtil.getStartingCoalition(airbaseId)
|
||||
if startingCoalition == coalition.side.BLUE then
|
||||
airbase:setCoalition(2)
|
||||
for _, blueGroupName in pairs(self.db.blueAirbasegroups) do
|
||||
Spearhead.DcsUtil.SpawnGroupTemplate(blueGroupName)
|
||||
end
|
||||
else
|
||||
airbase:setCoalition(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Sets airfields to blue and spawns friendly farps
|
||||
o.ActivateBlueStage = function(self)
|
||||
logger:debug("Setting stage '" .. Spearhead.Util.toString(self.zoneName) .. "' to blue")
|
||||
|
||||
for _, groupName in pairs(self.db.redAirbasegroups) do
|
||||
Spearhead.DcsUtil.DestroyGroup(groupName)
|
||||
end
|
||||
|
||||
for _, mission in pairs(self.db.missions) do
|
||||
mission:Cleanup()
|
||||
end
|
||||
|
||||
for _, mission in pairs(self.db.sams) do
|
||||
mission:Cleanup()
|
||||
end
|
||||
|
||||
timer.scheduleFunction(ActivateBlueAsync, self, timer.getTime() + 3)
|
||||
|
||||
-- for key, farp in pairs(self.db.farps) do
|
||||
-- if farp.helipadnames then
|
||||
-- for _, helipadName in pairs(farp.helipadnames) do
|
||||
-- local helipad = Airbase.getByName(helipadName)
|
||||
-- if helipad then
|
||||
-- logger:debug("Enabling: '" .. helipad:getName() .. "'")
|
||||
-- helipad:setCoalition(2)
|
||||
-- else
|
||||
-- logger:warn(helipadName .. " not found when spawning farps")
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if farp.group_names then
|
||||
-- for _, groupName in pairs(farp.group_names) do
|
||||
-- Spearhead.DcsUtil.SpawnGroupTemplate(groupName)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
|
||||
o.OnStatusRequestReceived = function(self, groupId)
|
||||
if self.activeStage ~= self.stageNumber then
|
||||
return
|
||||
end
|
||||
|
||||
trigger.action.outTextForGroup(groupId, "Status Update incoming... ", 3)
|
||||
|
||||
local text = "Mission Status: \n"
|
||||
|
||||
local totalmissions = 0
|
||||
local completedMissions = 0
|
||||
for _, mission in pairs(self.db.missionsByCode) do
|
||||
totalmissions = totalmissions + 1
|
||||
if mission.missionState == Spearhead.internal.Mission.MissionState.ACTIVE then
|
||||
|
||||
text = text .. "\n [" .. mission.code .. "] " .. mission.name ..
|
||||
" (" .. mission.missionTypeDisplayName .. ") \n"
|
||||
end
|
||||
|
||||
if mission.missionState == Spearhead.internal.Mission.MissionState.COMPLETED then
|
||||
completedMissions = completedMissions + 1
|
||||
end
|
||||
end
|
||||
|
||||
local completionPercentage = math.floor((completedMissions / totalmissions) * 100)
|
||||
text = text .. " \n Missions Complete: " .. completionPercentage .. "%"
|
||||
|
||||
self.logger:debug(text)
|
||||
trigger.action.outTextForGroup(groupId, text, 20)
|
||||
end
|
||||
|
||||
o.OnStageNumberChanged = function (self, number)
|
||||
|
||||
if self.activeStage == number then --only activate once for a stage
|
||||
return
|
||||
end
|
||||
|
||||
local previousActive = self.activeStage
|
||||
self.activeStage = number
|
||||
if Spearhead.capInfo.IsCapActiveWhenZoneIsActive(self.zoneName, number) == true then
|
||||
self:PreActivate()
|
||||
end
|
||||
|
||||
if number == self.stageNumber then
|
||||
self:ActivateStage()
|
||||
end
|
||||
|
||||
if previousActive <= self.stageNumber then
|
||||
if number > self.stageNumber then
|
||||
self:ActivateBlueStage()
|
||||
self:RemoveAllMissionCommands()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- input = { self, groupId, missionCode }
|
||||
local ShowBriefingClicked = function (input)
|
||||
|
||||
local self = input.self
|
||||
local groupId = input.groupId
|
||||
local missionCode = input.missionCode
|
||||
|
||||
local mission = self.db.missionsByCode[missionCode]
|
||||
if mission then
|
||||
mission:ShowBriefing(groupId)
|
||||
end
|
||||
end
|
||||
|
||||
o.RemoveMissionCommands = function (self, mission)
|
||||
|
||||
self.logger:debug("Removing commands for: " .. mission.name)
|
||||
|
||||
local folderName = mission.name .. "(" .. mission.missionTypeDisplayName .. ")"
|
||||
for i = 0, 2 do
|
||||
local players = coalition.getPlayers(i)
|
||||
for _, playerUnit in pairs(players) do
|
||||
local groupId = playerUnit:getGroup():getID()
|
||||
missionCommands.removeItemForGroup(groupId, { "Missions", folderName })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
o.RemoveAllMissionCommands = function (self)
|
||||
for _, mission in pairs(self.db.missionsByCode) do
|
||||
self:RemoveMissionCommands(mission)
|
||||
end
|
||||
end
|
||||
|
||||
o.AddCommandsForMissionToGroup = function (self, groupId, mission)
|
||||
local folderName = mission.name .. "(" .. mission.missionTypeDisplayName .. ")"
|
||||
missionCommands.addSubMenuForGroup(groupId, folderName, { "Missions"} )
|
||||
missionCommands.addCommandForGroup(groupId, "Show Briefing", { "Missions", folderName }, ShowBriefingClicked, { self = self, groupId = groupId, missionCode = mission.code })
|
||||
end
|
||||
|
||||
o.AddCommmandsForMissionToAllPlayers = function(self, mission)
|
||||
for i = 0, 2 do
|
||||
local players = coalition.getPlayers(i)
|
||||
for _, playerUnit in pairs(players) do
|
||||
local groupId = playerUnit:getGroup():getID()
|
||||
self:AddCommandsForMissionToGroup(groupId, mission)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
o.OnPlayerEntersUnit = function (self, unit)
|
||||
if self.activeStage == self.stageNumber then
|
||||
local groupId = unit:getGroup():getID()
|
||||
for _, mission in pairs(self.db.missionsByCode) do
|
||||
if mission.missionState == Spearhead.internal.Mission.MissionState.ACTIVE then
|
||||
self:AddCommandsForMissionToGroup(groupId, mission)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local removeMissionCommandsDelayed = function(input)
|
||||
local self = input.self
|
||||
local mission = input.mission
|
||||
self:RemoveMissionCommands(mission)
|
||||
end
|
||||
|
||||
o.OnMissionComplete = function(self, mission)
|
||||
timer.scheduleFunction(removeMissionCommandsDelayed, { self = self, mission = mission}, timer.getTime() + 20)
|
||||
timer.scheduleFunction(activateMissionsIfApplicableAsync, self, timer.getTime() + 10)
|
||||
end
|
||||
|
||||
for _, mission in pairs(o.db.missionsByCode) do
|
||||
mission:AddMissionCompleteListener(o)
|
||||
end
|
||||
|
||||
Spearhead.Events.AddOnStatusRequestReceivedListener(o)
|
||||
Spearhead.Events.AddStageNumberChangedListener(o)
|
||||
return o
|
||||
end
|
||||
end
|
||||
|
||||
Spearhead.internal.Stage = Stage
|
||||
Reference in New Issue
Block a user