diff --git a/_miz/SPEARHEADDEV.miz b/_miz/SPEARHEADDEV.miz index 6bd6e97..46b0ce2 100644 Binary files a/_miz/SPEARHEADDEV.miz and b/_miz/SPEARHEADDEV.miz differ diff --git a/spearhead.lua b/spearhead.lua index 3929519..184a19e 100644 --- a/spearhead.lua +++ b/spearhead.lua @@ -144,12 +144,11 @@ local stageConfig = { Spearhead.internal.GlobalCapManager.start(databaseManager, capConfig, stageConfig) Spearhead.internal.GlobalStageManager.start(databaseManager) ---[[ - TODO: REMOVE DEBUG -]] + Spearhead.Events.PublishStageNumberChanged(1) Spearhead.LoadingDone() --Check lines of code in directory per file: -- Get-ChildItem . -Include *.lua -Recurse | foreach {""+(Get-Content $_).Count + " => " + $_.name } --- find . -name '*.lua' | xargs wc -l \ No newline at end of file +-- find . -name '*.lua' | xargs wc -l + diff --git a/spearhead_base.lua b/spearhead_base.lua index af490b6..94a7c07 100644 --- a/spearhead_base.lua +++ b/spearhead_base.lua @@ -1608,7 +1608,7 @@ do event.id == world.event.S_EVENT_EJECTION or event.id == world.event.S_EVENT_UNIT_LOST then local object = event.initiator - if object and OnUnitLostListeners[object:getName()] then + if object and object.getName and OnUnitLostListeners[object:getName()] then for _, callable in pairs(OnUnitLostListeners[object:getName()]) do local succ, err = pcall(function() callable:OnUnitLost(object) diff --git a/spearhead_db.lua b/spearhead_db.lua index fe32ca7..836e0cd 100644 --- a/spearhead_db.lua +++ b/spearhead_db.lua @@ -84,6 +84,14 @@ do -- DB o.tables.descriptions[name] = layer_object.text end end + + local inZone = Spearhead.DcsUtil.isPositionInZones(layer_object.mapX, layer_object.mapY, o.tables.random_mission_zones) + if Spearhead.Util.tableLength(inZone) >= 1 then + local name = inZone[1] + if name ~= nil then + o.tables.descriptions[name] = layer_object.text + end + end end end end @@ -584,6 +592,19 @@ do -- DB Logger:info("Airbases: " .. Spearhead.Util.tableLength(o.tables.airbasesPerStage)) Logger:info("RedAirbase Groups: " .. Spearhead.Util.tableLength(o.tables.redAirbaseGroupsPerAirbase["21"])) + + for _, missionZone in pairs(o.tables.mission_zones) do + if o.tables.descriptions[missionZone] == nil then + Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing") + end + end + + for _, randomMission in pairs(o.tables.random_mission_zones) do + if o.tables.descriptions[randomMission] == nil then + Spearhead.AddMissionEditorWarning("Mission with zonename: " .. randomMission .. " does not have a briefing") + end + end + end singleton = o return o diff --git a/stageClasses/Mission.lua b/stageClasses/Mission.lua index 95f4934..316c868 100644 --- a/stageClasses/Mission.lua +++ b/stageClasses/Mission.lua @@ -102,6 +102,8 @@ do -- INIT Mission Class o.logger = logger o.code = database:GetNewMissionCode() + o.groupNamesPerUnit = {} + o.groupUnitAliveDict = {} o.targetAliveStates = {} o.hasSpecificTargets = false @@ -115,10 +117,13 @@ do -- INIT Mission Class --[[ OnUnit lost event ]]-- - local category = object:getCategory() + self.logger:debug("Getting on unit lost event") + + local category = Object.getCategory(object) if category == Object.Category.UNIT then local unitName = object:getName() - local groupName = object:getGroup():getName() + self.logger:debug("UnitName:" .. unitName) + local groupName = self.groupNamesPerUnit[unitName] self.groupUnitAliveDict[groupName][unitName] = false if self.targetAliveStates[groupName][unitName] then @@ -128,11 +133,13 @@ do -- INIT Mission Class 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 - CheckStateAsync(false) + timer.scheduleFunction(CheckStateAsync, self, timer.getTime() + 3) end o.MissionCompleteListeners = {} @@ -190,8 +197,8 @@ do -- INIT Mission Class TODO: Check own state based on mission type ]]-- - local specificTargetsAlive = false 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 @@ -199,8 +206,10 @@ do -- INIT Mission Class end end end + if specificTargetsAlive == false then + self.missionState = Mission.MissionState.COMPLETED + end else - local function CountAliveGroups() local aliveGroups = 0 @@ -235,8 +244,10 @@ do -- INIT Mission Class ]] 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!" ) + TriggerMissionComplete(self) --Schedule cleanup after 5 minutes of mission complete timer.scheduleFunction(CleanupDelayedAsync, self, timer.getTime() + 300) @@ -260,8 +271,42 @@ do -- INIT Mission Class 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 text = "Mission [" .. self.code .. "] ".. self.name .. "\n \n" .. self.missionbriefing .. " \n \nState TODO" + 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 @@ -278,14 +323,11 @@ do -- INIT Mission Class self.targetAliveStates[group_name] = {} if Spearhead.DcsUtil.IsGroupStatic(group_name) then - self.startingUnits = self.startingUnits + 1 Spearhead.Events.addOnUnitLostEventListener(group_name, self) - self.groupUnitAliveDict[group_name][group_name] = true 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_") @@ -293,12 +335,23 @@ do -- INIT Mission Class 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 diff --git a/stageClasses/Stage.lua b/stageClasses/Stage.lua index 5928970..cce13e4 100644 --- a/stageClasses/Stage.lua +++ b/stageClasses/Stage.lua @@ -281,7 +281,6 @@ do --init STAGE DIRECTOR for _, mission in pairs(self.db.missionsByCode) do totalmissions = totalmissions + 1 if mission.missionState == Spearhead.internal.Mission.MissionState.ACTIVE then - self.logger:debug("blaat") text = text .. "\n [" .. mission.code .. "] " .. mission.name .. " (" .. mission.missionTypeDisplayName .. ") \n" @@ -318,6 +317,7 @@ do --init STAGE DIRECTOR if previousActive <= self.stageNumber then if number > self.stageNumber then self:ActivateBlueStage() + self:RemoveAllMissionCommands() end end end @@ -335,12 +335,30 @@ do --init STAGE DIRECTOR 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 }) - self.logger:debug("blaat added command") - end o.AddCommmandsForMissionToAllPlayers = function(self, mission) @@ -364,18 +382,20 @@ do --init STAGE DIRECTOR end end + local removeMissionCommandsDelayed = function(input) + local self = input.self + local mission = input.mission + self:RemoveMissionCommands(mission) + end + o.OnMissionComplete = function(self, mission) - 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 + 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)