Improved menu interaction and added pinning functionality (#23)
* Improved menu interaction * Added Overview message * Added Pinning functionality. Pinning a mission so you can easily pull up the briefing again. * Added "Clear View" command to get rid of the message on the screen.
This commit is contained in:
Binary file not shown.
@@ -4,6 +4,7 @@
|
|||||||
do -- mission aliases
|
do -- mission aliases
|
||||||
|
|
||||||
--- @alias MissionPriority
|
--- @alias MissionPriority
|
||||||
|
--- | "none"
|
||||||
--- | "primary"
|
--- | "primary"
|
||||||
--- | "secondary"
|
--- | "secondary"
|
||||||
|
|
||||||
|
|||||||
@@ -121,13 +121,29 @@ do -- INIT UTIL
|
|||||||
end
|
end
|
||||||
|
|
||||||
---comment
|
---comment
|
||||||
---@param a table DCS Point vector {x, z , y}
|
---@param a Vec2 DCS Point vector {x, z , y}
|
||||||
---@param b table DCS Point vector {x, z , y}
|
---@param b Vec2 DCS Point vector {x, z , y}
|
||||||
---@return number
|
---@return number
|
||||||
function UTIL.VectorDistance(a, b)
|
function UTIL.VectorDistance2d(a, b)
|
||||||
return math.sqrt((b.x - a.x) ^ 2 + (b.z - a.z) ^ 2)
|
return math.sqrt((b.x - a.x) ^ 2 + (b.y - a.y) ^ 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param a Vec3
|
||||||
|
---@param b Vec3
|
||||||
|
---@return number
|
||||||
|
function UTIL.VectorDistance3d(a, b)
|
||||||
|
return UTIL.vectorMagnitude({ x = a.x - b.x, y = a.y - b.y, z = a.z - b.z })
|
||||||
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param vec Vec3
|
||||||
|
---@return number
|
||||||
|
function UTIL.vectorMagnitude(vec)
|
||||||
|
return (vec.x ^ 2 + vec.y ^ 2 + vec.z ^ 2) ^ 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
---comment
|
---comment
|
||||||
---@param polygon table of pairs { x, z }
|
---@param polygon table of pairs { x, z }
|
||||||
---@param x number X location
|
---@param x number X location
|
||||||
@@ -770,7 +786,7 @@ do -- INIT DCS_UTIL
|
|||||||
end
|
end
|
||||||
|
|
||||||
---comment Get all units that are players
|
---comment Get all units that are players
|
||||||
---@return table units
|
---@return Array<Unit> units
|
||||||
function DCS_UTIL.getAllPlayerUnits()
|
function DCS_UTIL.getAllPlayerUnits()
|
||||||
local units = {}
|
local units = {}
|
||||||
for i = 0,2 do
|
for i = 0,2 do
|
||||||
@@ -917,6 +933,23 @@ do -- INIT DCS_UTIL
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param groupId number
|
||||||
|
---@return Group?
|
||||||
|
function DCS_UTIL.GetPlayerGroupByGroupID(groupId)
|
||||||
|
for i = 0,2 do
|
||||||
|
local players = coalition.getPlayers(i)
|
||||||
|
for key, unit in pairs(players) do
|
||||||
|
if unit and unit:isExist() == true then
|
||||||
|
local group = unit:getGroup()
|
||||||
|
if group and group:getID() == groupId then
|
||||||
|
return group
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
DCS_UTIL.__INIT();
|
DCS_UTIL.__INIT();
|
||||||
end
|
end
|
||||||
Spearhead.DcsUtil = DCS_UTIL
|
Spearhead.DcsUtil = DCS_UTIL
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
---@field StageZones table<string, StageZoneData> table<StageZoneName, StageZoneData>
|
---@field StageZones table<string, StageZoneData> table<StageZoneName, StageZoneData>
|
||||||
---@field MissionZones Array<string> All Mission Zone Names
|
---@field MissionZones Array<string> All Mission Zone Names
|
||||||
---@field RandomMissionZones Array<string> All Random mission names
|
---@field RandomMissionZones Array<string> All Random mission names
|
||||||
|
---@field MissionZonesLocations table<string, Vec2> All Mission Zone Locations
|
||||||
---@field StageZonesByNumber table<string, Array<string>> Stage zones grouped by index number
|
---@field StageZonesByNumber table<string, Array<string>> Stage zones grouped by index number
|
||||||
---@field AllFarpZones Array<string>
|
---@field AllFarpZones Array<string>
|
||||||
---@field FarpIdsInFarpZones table<string, Array<integer>> farp pad Id's in farp zones.
|
---@field FarpIdsInFarpZones table<string, Array<integer>> farp pad Id's in farp zones.
|
||||||
@@ -74,6 +75,7 @@ function Database.New(Logger)
|
|||||||
DescriptionsByMission = {},
|
DescriptionsByMission = {},
|
||||||
FarpIdsInFarpZones = {},
|
FarpIdsInFarpZones = {},
|
||||||
MissionZones = {},
|
MissionZones = {},
|
||||||
|
MissionZonesLocations = {},
|
||||||
StageZoneNames = {},
|
StageZoneNames = {},
|
||||||
RandomMissionZones = {},
|
RandomMissionZones = {},
|
||||||
StageZones = {},
|
StageZones = {},
|
||||||
@@ -97,6 +99,10 @@ function Database.New(Logger)
|
|||||||
do -- INIT ZONE TABLES
|
do -- INIT ZONE TABLES
|
||||||
for zone_ind, zone_data in pairs(Spearhead.DcsUtil.__trigger_zones) do
|
for zone_ind, zone_data in pairs(Spearhead.DcsUtil.__trigger_zones) do
|
||||||
local zone_name = zone_data.name
|
local zone_name = zone_data.name
|
||||||
|
|
||||||
|
---@type Vec2
|
||||||
|
local zoneLocation = { x = zone_data.x, y = zone_data.z }
|
||||||
|
|
||||||
local split_string = Spearhead.Util.split_string(zone_name, "_")
|
local split_string = Spearhead.Util.split_string(zone_name, "_")
|
||||||
table.insert(self._tables.AllZoneNames, zone_name)
|
table.insert(self._tables.AllZoneNames, zone_name)
|
||||||
|
|
||||||
@@ -130,10 +136,12 @@ function Database.New(Logger)
|
|||||||
|
|
||||||
if string.lower(split_string[1]) == "mission" then
|
if string.lower(split_string[1]) == "mission" then
|
||||||
table.insert(self._tables.MissionZones, zone_name)
|
table.insert(self._tables.MissionZones, zone_name)
|
||||||
|
self._tables.MissionZonesLocations[zone_name] = zoneLocation
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.lower(split_string[1]) == "randommission" then
|
if string.lower(split_string[1]) == "randommission" then
|
||||||
table.insert(self._tables.RandomMissionZones, zone_name)
|
table.insert(self._tables.RandomMissionZones, zone_name)
|
||||||
|
self._tables.MissionZonesLocations[zone_name] = zoneLocation
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.lower(split_string[1]) == "farp" then
|
if string.lower(split_string[1]) == "farp" then
|
||||||
@@ -241,15 +249,13 @@ function Database.New(Logger)
|
|||||||
|
|
||||||
for _, missionZone in pairs(self._tables.MissionZones) do
|
for _, missionZone in pairs(self._tables.MissionZones) do
|
||||||
if self._tables.DescriptionsByMission[missionZone] == nil then
|
if self._tables.DescriptionsByMission[missionZone] == nil then
|
||||||
Spearhead.AddMissionEditorWarning("Mission with zonename: " ..
|
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
|
||||||
missionZone .. " does not have a briefing")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, missionZone in pairs(self._tables.RandomMissionZones) do
|
for _, missionZone in pairs(self._tables.RandomMissionZones) do
|
||||||
if self._tables.DescriptionsByMission[missionZone] == nil then
|
if self._tables.DescriptionsByMission[missionZone] == nil then
|
||||||
Spearhead.AddMissionEditorWarning("Mission with zonename: " ..
|
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
|
||||||
missionZone .. " does not have a briefing")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -541,6 +547,13 @@ function Database:GetDescriptionForMission(missionZoneName)
|
|||||||
return self._tables.DescriptionsByMission[missionZoneName]
|
return self._tables.DescriptionsByMission[missionZoneName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param missionZoneName any
|
||||||
|
---@return Vec2?
|
||||||
|
function Database:GetLocationForMissionZone(missionZoneName)
|
||||||
|
return self._tables.MissionZonesLocations[missionZoneName]
|
||||||
|
end
|
||||||
|
|
||||||
function Database:getCapRouteInZone(stageNumber, baseId)
|
function Database:getCapRouteInZone(stageNumber, baseId)
|
||||||
local stageNumber = tostring(stageNumber) or "nothing"
|
local stageNumber = tostring(stageNumber) or "nothing"
|
||||||
local routeData = self._tables.CapDataPerStageNumber[stageNumber]
|
local routeData = self._tables.CapDataPerStageNumber[stageNumber]
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
---@class Mission : OnUnitLostListener
|
---@class Mission : OnUnitLostListener
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field missionType missionType
|
---@field missionType missionType
|
||||||
|
---@field displayMissionType string
|
||||||
---@field code string
|
---@field code string
|
||||||
---@field priority MissionPriority
|
---@field priority MissionPriority
|
||||||
|
---@field location Vec2?
|
||||||
---@field private _state MissionState
|
---@field private _state MissionState
|
||||||
---@field private _zoneName string
|
---@field private _zoneName string
|
||||||
---@field private _database Database
|
---@field private _database Database
|
||||||
@@ -12,10 +14,9 @@
|
|||||||
---@field private _missionBriefing string?
|
---@field private _missionBriefing string?
|
||||||
---@field private _missionGroups MissionGroups
|
---@field private _missionGroups MissionGroups
|
||||||
---@field private _completeListeners Array<MissionCompleteListener>
|
---@field private _completeListeners Array<MissionCompleteListener>
|
||||||
|
---@field private _missionCommandsHelper MissionCommandsHelper
|
||||||
local Mission = {}
|
local Mission = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @class MissionCompleteListener
|
--- @class MissionCompleteListener
|
||||||
--- @field OnMissionComplete fun(self: any, mission:Mission)
|
--- @field OnMissionComplete fun(self: any, mission:Mission)
|
||||||
|
|
||||||
@@ -78,12 +79,16 @@ function Mission.New(zoneName, priority, database, logger)
|
|||||||
self._zoneName = zoneName
|
self._zoneName = zoneName
|
||||||
self.name = parsed.missionName
|
self.name = parsed.missionName
|
||||||
self.missionType = parsed.type
|
self.missionType = parsed.type
|
||||||
|
self.displayMissionType = self.missionType or "unknown"
|
||||||
|
if self.missionType == "SAM" then self.displayMissionType = "DEAD" end
|
||||||
|
self.location = database:GetLocationForMissionZone(zoneName)
|
||||||
self.code = tostring(database:GetNewMissionCode())
|
self.code = tostring(database:GetNewMissionCode())
|
||||||
self.priority = priority
|
self.priority = priority
|
||||||
self._state = "NEW"
|
self._state = "NEW"
|
||||||
|
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
self._database = database
|
self._database = database
|
||||||
|
self._missionCommandsHelper = Spearhead.classes.stageClasses.helpers.MissionCommandsHelper.getOrCreate(logger.LogLevel)
|
||||||
self._completeListeners = {}
|
self._completeListeners = {}
|
||||||
|
|
||||||
self._missionBriefing = database:getMissionBriefingForMissionZone(zoneName)
|
self._missionBriefing = database:getMissionBriefingForMissionZone(zoneName)
|
||||||
@@ -154,7 +159,7 @@ function Mission:SpawnActive()
|
|||||||
group:Spawn()
|
group:Spawn()
|
||||||
end
|
end
|
||||||
|
|
||||||
Spearhead.classes.stageClasses.helpers.MissionCommandsHelper.AddMissionToCommands(self)
|
self._missionCommandsHelper:AddMissionToCommands(self)
|
||||||
|
|
||||||
self:StartCheckingContinuous()
|
self:StartCheckingContinuous()
|
||||||
end
|
end
|
||||||
@@ -345,7 +350,8 @@ end
|
|||||||
|
|
||||||
---private usage advised
|
---private usage advised
|
||||||
function Mission:NotifyMissionComplete()
|
function Mission:NotifyMissionComplete()
|
||||||
Spearhead.classes.stageClasses.helpers.MissionCommandsHelper.RemoveMissionToCommands(self)
|
|
||||||
|
self._missionCommandsHelper:RemoveMissionToCommands(self)
|
||||||
self._logger:info("Mission Completed: " .. self._zoneName)
|
self._logger:info("Mission Completed: " .. self._zoneName)
|
||||||
trigger.action.outText("Mission " .. self.name .. " [" .. self.code .. "] was completed succesfully" , 20)
|
trigger.action.outText("Mission " .. self.name .. " [" .. self.code .. "] was completed succesfully" , 20)
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ function BlueSam.New(database, logger, zoneName)
|
|||||||
do
|
do
|
||||||
local groups = database:getBlueSamGroupsInZone(zoneName)
|
local groups = database:getBlueSamGroupsInZone(zoneName)
|
||||||
|
|
||||||
|
---@type table<string, Vec3>
|
||||||
local blueUnitsPos = {}
|
local blueUnitsPos = {}
|
||||||
|
|
||||||
|
---@type table<string, Vec3>
|
||||||
local redUnitsPos = {}
|
local redUnitsPos = {}
|
||||||
|
|
||||||
for _, groupName in pairs(groups) do
|
for _, groupName in pairs(groups) do
|
||||||
@@ -53,7 +56,7 @@ function BlueSam.New(database, logger, zoneName)
|
|||||||
local cleanup_distance = 5
|
local cleanup_distance = 5
|
||||||
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
||||||
for redUnitName, redUnitPos in pairs(redUnitsPos) do
|
for redUnitName, redUnitPos in pairs(redUnitsPos) do
|
||||||
local distance = Spearhead.Util.VectorDistance(blueUnitPos, redUnitPos)
|
local distance = Spearhead.Util.VectorDistance3d(blueUnitPos, redUnitPos)
|
||||||
env.info("distance: " .. tostring(distance))
|
env.info("distance: " .. tostring(distance))
|
||||||
if distance <= cleanup_distance then
|
if distance <= cleanup_distance then
|
||||||
self._cleanupUnits[redUnitName] = true
|
self._cleanupUnits[redUnitName] = true
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ function StageBase.New(databaseManager, logger, airbaseName)
|
|||||||
self._initialSide = Spearhead.DcsUtil.getStartingCoalition(self._airbase)
|
self._initialSide = Spearhead.DcsUtil.getStartingCoalition(self._airbase)
|
||||||
|
|
||||||
do --init
|
do --init
|
||||||
|
|
||||||
|
---@type table<string, Vec3>
|
||||||
local redUnitsPos = {}
|
local redUnitsPos = {}
|
||||||
|
|
||||||
|
---@type table<string, Vec3>
|
||||||
local blueUnitsPos = {}
|
local blueUnitsPos = {}
|
||||||
|
|
||||||
do -- fill tables
|
do -- fill tables
|
||||||
@@ -72,7 +76,7 @@ function StageBase.New(databaseManager, logger, airbaseName)
|
|||||||
|
|
||||||
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
||||||
for redUnitName, redUnitPos in pairs(redUnitsPos) do
|
for redUnitName, redUnitPos in pairs(redUnitsPos) do
|
||||||
local distance = Spearhead.Util.VectorDistance(blueUnitPos, redUnitPos)
|
local distance = Spearhead.Util.VectorDistance3d(blueUnitPos, redUnitPos)
|
||||||
env.info("distance: " .. tostring(distance))
|
env.info("distance: " .. tostring(distance))
|
||||||
if distance <= cleanup_distance then
|
if distance <= cleanup_distance then
|
||||||
self._cleanup_units[redUnitName] = true
|
self._cleanup_units[redUnitName] = true
|
||||||
|
|||||||
@@ -47,6 +47,13 @@ Stage.__index = Stage
|
|||||||
|
|
||||||
local stageDrawingId = 100
|
local stageDrawingId = 100
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param database Database
|
||||||
|
---@param stageConfig StageConfig
|
||||||
|
---@param logger Logger
|
||||||
|
---@param initData StageInitData
|
||||||
|
---@param missionPriority MissionPriority
|
||||||
|
---@return Stage
|
||||||
function Stage:superNew(database, stageConfig, logger, initData, missionPriority)
|
function Stage:superNew(database, stageConfig, logger, initData, missionPriority)
|
||||||
|
|
||||||
logger:debug("[BaseStage] Initiating stage with name: " .. initData.stageZoneName)
|
logger:debug("[BaseStage] Initiating stage with name: " .. initData.stageZoneName)
|
||||||
@@ -116,7 +123,7 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
|
|||||||
local randomMissionNames = database:getRandomMissionsForStage(self.zoneName)
|
local randomMissionNames = database:getRandomMissionsForStage(self.zoneName)
|
||||||
local randomMissionByName = {}
|
local randomMissionByName = {}
|
||||||
for _, missionZoneName in pairs(randomMissionNames) do
|
for _, missionZoneName in pairs(randomMissionNames) do
|
||||||
local mission = Spearhead.classes.stageClasses.Missions.Mission.New(missionZoneName, "primary", database, logger)
|
local mission = Spearhead.classes.stageClasses.Missions.Mission.New(missionZoneName, self._missionPriority, database, logger)
|
||||||
if mission then
|
if mission then
|
||||||
if randomMissionByName[mission.name] == nil then
|
if randomMissionByName[mission.name] == nil then
|
||||||
randomMissionByName[mission.name] = {}
|
randomMissionByName[mission.name] = {}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ setmetatable(ExtraStage, Stage)
|
|||||||
function ExtraStage.New(database, stageConfig, logger, initData)
|
function ExtraStage.New(database, stageConfig, logger, initData)
|
||||||
|
|
||||||
local self = setmetatable({}, { __index = ExtraStage }) --[[@as ExtraStage]]
|
local self = setmetatable({}, { __index = ExtraStage }) --[[@as ExtraStage]]
|
||||||
self:superNew(database, stageConfig, logger, initData)
|
self:superNew(database, stageConfig, logger, initData, "secondary")
|
||||||
|
|
||||||
self.OnPostBlueActivated = function (selfStage)
|
self.OnPostBlueActivated = function (selfStage)
|
||||||
selfStage:MarkStage("GRAY")
|
selfStage:MarkStage("GRAY")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ setmetatable(PrimaryStage, Stage)
|
|||||||
function PrimaryStage.New(database, stageConfig, logger, initData)
|
function PrimaryStage.New(database, stageConfig, logger, initData)
|
||||||
|
|
||||||
local self = setmetatable({}, { __index = PrimaryStage }) --[[@as PrimaryStage]]
|
local self = setmetatable({}, { __index = PrimaryStage }) --[[@as PrimaryStage]]
|
||||||
self:superNew(database, stageConfig, logger, initData)
|
self:superNew(database, stageConfig, logger, initData, "primary")
|
||||||
return self
|
return self
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ local WaitingStageInitData = {}
|
|||||||
function WaitingStage.New(database, stageConfig, logger, initData)
|
function WaitingStage.New(database, stageConfig, logger, initData)
|
||||||
|
|
||||||
local self = setmetatable({}, { __index = WaitingStage }) --[[@as WaitingStage]]
|
local self = setmetatable({}, { __index = WaitingStage }) --[[@as WaitingStage]]
|
||||||
self:superNew(database, stageConfig, logger, initData)
|
self:superNew(database, stageConfig, logger, initData, "none")
|
||||||
|
|
||||||
self._waitTimeSeconds = 5
|
self._waitTimeSeconds = 5
|
||||||
if initData.waitingSeconds and initData.waitingSeconds > 5 then self._waitTimeSeconds = initData.waitingSeconds end
|
if initData.waitingSeconds and initData.waitingSeconds > 5 then self._waitTimeSeconds = initData.waitingSeconds end
|
||||||
|
|||||||
@@ -1,130 +1,276 @@
|
|||||||
|
---@class MissionCommandsHelper
|
||||||
|
---@field missionsByCode table<string, Mission> @table of missions by their code
|
||||||
|
---@field enabledByCode table<string, boolean> @table of enabled missions by their code
|
||||||
|
---@field updateNeeded boolean @flag to indicate if an update is needed
|
||||||
|
---@field lastUpdate number @last update time
|
||||||
|
---@field updateContinuous fun(self: MissionCommandsHelper, time: number): number @function to update commands continuously
|
||||||
|
---@field pinnedByGroup table<string, Mission> @table of pinned missions by group ID
|
||||||
|
---@field private _logger Logger @logger instance for logging
|
||||||
local MissionCommandsHelper = {}
|
local MissionCommandsHelper = {}
|
||||||
do
|
MissionCommandsHelper.__index = MissionCommandsHelper
|
||||||
---@type table<string, Mission>
|
|
||||||
local missionsByCode = {}
|
|
||||||
|
|
||||||
---@type table<string, boolean>
|
|
||||||
local enabledByCode = {}
|
|
||||||
|
|
||||||
local updateNeeded = false
|
local instance = nil
|
||||||
|
|
||||||
---Add a mission to the F10 commands menu
|
---@return MissionCommandsHelper
|
||||||
---@param mission Mission
|
---@param logLevel string @log level for the logger
|
||||||
MissionCommandsHelper.AddMissionToCommands = function (mission)
|
function MissionCommandsHelper.getOrCreate(logLevel)
|
||||||
missionsByCode[tostring(mission.code)] = mission
|
if instance == nil then
|
||||||
enabledByCode[tostring(mission.code)] = true
|
local self = setmetatable({}, MissionCommandsHelper)
|
||||||
updateNeeded = true
|
|
||||||
end
|
|
||||||
|
|
||||||
---Removes a mission from the F10 commands menu
|
self._logger = Spearhead.LoggerTemplate.new("MissionCommandsHelper", logLevel)
|
||||||
---@param mission Mission
|
|
||||||
MissionCommandsHelper.RemoveMissionToCommands = function (mission)
|
|
||||||
enabledByCode[tostring(mission.code)] = false
|
|
||||||
updateNeeded = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local folderNames = {
|
self.missionsByCode = {}
|
||||||
primary = "Primary Missions",
|
self.enabledByCode = {}
|
||||||
secondary = "Secondary Missions"
|
self.updateNeeded = false
|
||||||
}
|
self.pinnedByGroup = {}
|
||||||
|
self.lastUpdate = 0
|
||||||
|
|
||||||
---Add Base Folder
|
---comment
|
||||||
---@param groupId integer
|
---@param selfA MissionCommandsHelper
|
||||||
local addMissionFolders = function(groupId)
|
---@param time number
|
||||||
missionCommands.addSubMenuForGroup(groupId, folderNames.primary)
|
---@return number
|
||||||
missionCommands.addSubMenuForGroup(groupId, folderNames.secondary)
|
self.updateContinuous = function(selfA, time)
|
||||||
end
|
if selfA.updateNeeded == false and timer.getTime() - selfA.lastUpdate < 10 then
|
||||||
|
return time + 2
|
||||||
|
end
|
||||||
|
|
||||||
---Add Mission Folder
|
for _, unit in pairs(Spearhead.DcsUtil.getAllPlayerUnits()) do
|
||||||
---@param groupId integer
|
if unit and unit:isExist() then
|
||||||
local removeMissionFolders = function(groupId)
|
local group = unit:getGroup()
|
||||||
missionCommands.removeItemForGroup(groupId , { folderNames.primary } )
|
if group then
|
||||||
missionCommands.removeItemForGroup(groupId , { folderNames.secondary } )
|
selfA:updateCommandsForGroup(group:getID())
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local missionBriefingRequested = function(args)
|
selfA.lastUpdate = timer.getTime()
|
||||||
---@type Mission
|
selfA.updateNeeded = false
|
||||||
local mission = args.mission
|
return time + 3
|
||||||
local groupID = args.groupId
|
|
||||||
|
|
||||||
mission:ShowBriefing(groupID)
|
|
||||||
end
|
|
||||||
|
|
||||||
---comment
|
|
||||||
---@param groupId integer
|
|
||||||
---@param mission Mission
|
|
||||||
local addMissionCommands = function(groupId, mission)
|
|
||||||
|
|
||||||
local path = nil
|
|
||||||
|
|
||||||
if mission.priority == "primary" then
|
|
||||||
path = { [1] = folderNames.primary }
|
|
||||||
elseif mission.priority == "secondary" then
|
|
||||||
path = { [1] = folderNames.secondary }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if path then
|
timer.scheduleFunction(self.updateContinuous, self, timer.getTime() + 5)
|
||||||
local missionFolderName = "[" .. mission.code .. "]" .. mission.name
|
Spearhead.Events.AddOnPlayerEnterUnitListener(self)
|
||||||
missionCommands.addSubMenuForGroup(groupId, missionFolderName, path)
|
instance = self
|
||||||
table.insert(path, missionFolderName)
|
|
||||||
missionCommands.addCommandForGroup(groupId, "Briefing" , path , missionBriefingRequested, { groupId = groupId, mission = mission })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local updateCommandsForGroup = function(group)
|
return instance
|
||||||
local groupID = group:getID()
|
end
|
||||||
|
|
||||||
-- Cleanup mission folder
|
|
||||||
removeMissionFolders(groupID)
|
|
||||||
|
|
||||||
-- Add mission folders
|
---@class MissionBriefingRequestedArgs
|
||||||
addMissionFolders(groupID)
|
---@field mission Mission @the mission object
|
||||||
|
---@field groupId integer @the group ID of the player requesting the briefing
|
||||||
|
|
||||||
for code, enabled in pairs(enabledByCode) do
|
---comment
|
||||||
|
---@param args MissionBriefingRequestedArgs
|
||||||
|
local missionBriefingRequested = function(args)
|
||||||
|
---@type Mission
|
||||||
|
local mission = args.mission
|
||||||
|
local groupID = args.groupId
|
||||||
|
|
||||||
|
mission:ShowBriefing(groupID)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---@class PinMissionCommandArgs
|
||||||
|
---@field self MissionCommandsHelper @the MissionCommandsHelper instance
|
||||||
|
---@field groupId integer @the group ID of the player requesting the briefing
|
||||||
|
---@field mission Mission @the mission object
|
||||||
|
|
||||||
|
local pinMissionCommand = function(args)
|
||||||
|
---@type MissionCommandsHelper
|
||||||
|
local self = args.self
|
||||||
|
local groupID = args.groupId
|
||||||
|
local mission = args.mission
|
||||||
|
|
||||||
|
if mission then
|
||||||
|
self:PinMission(mission, groupID)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
function MissionCommandsHelper:AddOverviewCommand(groupID)
|
||||||
|
|
||||||
|
local MissionsOverviewToGroup = function (id)
|
||||||
|
|
||||||
|
local text = "Missions Overview\n\n"
|
||||||
|
|
||||||
|
local group = Spearhead.DcsUtil.GetPlayerGroupByGroupID(id)
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param mission Mission
|
||||||
|
---@return string
|
||||||
|
local function formatLine(mission)
|
||||||
|
|
||||||
|
local distanceText = "?"
|
||||||
|
if group then
|
||||||
|
local lead = group:getUnit(1)
|
||||||
|
if lead and lead:isExist() == true then
|
||||||
|
local pos = lead:getPoint()
|
||||||
|
local Vec2Pos = { x= pos.x, y=pos.z }
|
||||||
|
local distance = Spearhead.Util.VectorDistance2d(Vec2Pos, mission.location) / 1852
|
||||||
|
distanceText = string.format("~%d", math.floor(distance))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return string.format("[%s] %-15s %-20s %10s nM\n", mission.code, mission.displayMissionType, mission.name, distanceText)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Primary missions
|
||||||
|
text = text .. "Primary Missions\n"
|
||||||
|
for code, enabled in pairs(self.enabledByCode) do
|
||||||
|
|
||||||
if enabled == true then
|
if enabled == true then
|
||||||
local mission = missionsByCode[code]
|
local mission = self.missionsByCode[code]
|
||||||
if mission then
|
if mission and mission.priority == "primary" then
|
||||||
addMissionCommands(groupID, mission)
|
text = text .. formatLine(mission)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local UpdateContinuous = function(none, time)
|
|
||||||
if updateNeeded == false then
|
|
||||||
return time + 15
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, unit in pairs(Spearhead.DcsUtil.getAllPlayerUnits()) do
|
|
||||||
if unit and unit:isExist() then
|
|
||||||
local group = unit:getGroup()
|
|
||||||
if group then
|
|
||||||
updateCommandsForGroup(group)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
updateNeeded = false
|
---Secondary missions
|
||||||
return time + 15
|
text = text .. "\nSecondary Missions\n"
|
||||||
end
|
for code, enabled in pairs(self.enabledByCode) do
|
||||||
|
|
||||||
timer.scheduleFunction(UpdateContinuous, {}, timer.getTime() + 10)
|
if enabled == true then
|
||||||
|
local mission = self.missionsByCode[code]
|
||||||
do -- Player enter unit listener
|
if mission and mission.priority == "secondary" then
|
||||||
local onPlayerEnterUnit = function(unit)
|
text = text .. formatLine(mission)
|
||||||
if unit then
|
end
|
||||||
local group = unit:getGroup()
|
|
||||||
if group then updateCommandsForGroup(group) end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trigger.action.outTextForGroup(id, text, 20, true)
|
||||||
|
end
|
||||||
|
|
||||||
local OnPlayerEnterUnitListener = {
|
missionCommands.removeItemForGroup(groupID, { "Overview" } )
|
||||||
OnPlayerEntersUnit = function (self, unit)
|
missionCommands.addCommandForGroup(groupID, "Overview", nil, MissionsOverviewToGroup, groupID)
|
||||||
onPlayerEnterUnit(unit)
|
end
|
||||||
end,
|
|
||||||
}
|
---@private
|
||||||
Spearhead.Events.AddOnPlayerEnterUnitListener(OnPlayerEnterUnitListener)
|
function MissionCommandsHelper:AddPinnedMission(groupID)
|
||||||
|
|
||||||
|
local pinndedMission = self.pinnedByGroup[tostring(groupID)]
|
||||||
|
missionCommands.removeItemForGroup(groupID, { "Pinned Mission" })
|
||||||
|
|
||||||
|
if pinndedMission and self.enabledByCode[tostring(pinndedMission.code)] == true then
|
||||||
|
missionCommands.addCommandForGroup(groupID, "Pinned Mission", nil, missionBriefingRequested, { groupId = groupID, mission = pinndedMission })
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param groupID number
|
||||||
|
function MissionCommandsHelper:updateCommandsForGroup(groupID)
|
||||||
|
|
||||||
|
self:AddPinnedMission(groupID)
|
||||||
|
self:AddOverviewCommand(groupID)
|
||||||
|
|
||||||
|
self:ResetFolders(groupID)
|
||||||
|
|
||||||
|
for code, enabled in pairs(self.enabledByCode) do
|
||||||
|
if enabled == true then
|
||||||
|
local mission = self.missionsByCode[code]
|
||||||
|
if mission then
|
||||||
|
self:addMissionCommands(groupID, mission)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param id number
|
||||||
|
local clearView = function(id)
|
||||||
|
trigger.action.outTextForGroup(id, "clearing...", 1, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
missionCommands.removeItemForGroup(groupID, { "Clear View" } )
|
||||||
|
missionCommands.addCommandForGroup(groupID, "Clear View", nil, clearView, groupID)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local folderNames = {
|
||||||
|
primary = "Primary Missions",
|
||||||
|
secondary = "Secondary Missions"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function MissionCommandsHelper:PinMission(mission, groupID)
|
||||||
|
self._logger:debug("Pinning mission: [" .. mission.code .. "]" .. mission.name)
|
||||||
|
self.pinnedByGroup[tostring(groupID)] = mission
|
||||||
|
trigger.action.outTextForGroup(groupID, "Pinned mission: [" .. mission.code .. "]" .. mission.name, 3, true)
|
||||||
|
|
||||||
|
self:updateCommandsForGroup(groupID)
|
||||||
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@private
|
||||||
|
---@param groupId integer
|
||||||
|
---@param mission Mission
|
||||||
|
function MissionCommandsHelper:addMissionCommands(groupId, mission)
|
||||||
|
local path = nil
|
||||||
|
|
||||||
|
if mission.priority == "primary" then
|
||||||
|
path = { [1] = folderNames.primary }
|
||||||
|
elseif mission.priority == "secondary" then
|
||||||
|
path = { [1] = folderNames.secondary }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if path then
|
||||||
|
self._logger:debug("Registering command: [" .. mission.code .. "]" .. mission.name)
|
||||||
|
local missionFolderName = "[" .. mission.code .. "]" .. mission.name
|
||||||
|
missionCommands.addSubMenuForGroup(groupId, missionFolderName, path)
|
||||||
|
table.insert(path, missionFolderName)
|
||||||
|
missionCommands.addCommandForGroup(groupId, "Briefing", path, missionBriefingRequested,{ groupId = groupId, mission = mission })
|
||||||
|
missionCommands.addCommandForGroup(groupId, "Pin", path, pinMissionCommand, { self = self, groupId = groupId, mission = mission })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param mission Mission
|
||||||
|
function MissionCommandsHelper:AddMissionToCommands(mission)
|
||||||
|
self._logger:debug("Adding mission to commands: [" .. mission.code .. "]" .. mission.name)
|
||||||
|
self.missionsByCode[tostring(mission.code)] = mission
|
||||||
|
self.enabledByCode[tostring(mission.code)] = true
|
||||||
|
self.updateNeeded = true
|
||||||
|
end
|
||||||
|
|
||||||
|
---Removes a mission from the F10 commands menu
|
||||||
|
---@param mission Mission
|
||||||
|
function MissionCommandsHelper:RemoveMissionToCommands(mission)
|
||||||
|
self.enabledByCode[tostring(mission.code)] = false
|
||||||
|
self.updateNeeded = true
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@param groupId integer
|
||||||
|
function MissionCommandsHelper:addMissionFolders(groupId)
|
||||||
|
missionCommands.addSubMenuForGroup(groupId, folderNames.primary)
|
||||||
|
missionCommands.addSubMenuForGroup(groupId, folderNames.secondary)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@param groupId integer
|
||||||
|
function MissionCommandsHelper:removeMissionFolders(groupId)
|
||||||
|
missionCommands.removeItemForGroup(groupId, { folderNames.primary })
|
||||||
|
missionCommands.removeItemForGroup(groupId, { folderNames.secondary })
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
function MissionCommandsHelper:ResetFolders(groupID)
|
||||||
|
-- Cleanup mission folder
|
||||||
|
self:removeMissionFolders(groupID)
|
||||||
|
|
||||||
|
-- Add mission folders
|
||||||
|
self:addMissionFolders(groupID)
|
||||||
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param unit Unit
|
||||||
|
function MissionCommandsHelper:OnPlayerEntersUnit(unit)
|
||||||
|
if unit then
|
||||||
|
local group = unit:getGroup()
|
||||||
|
if group then self:updateCommandsForGroup(group:getID()) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
|
|
||||||
--Single player purpose
|
--Single player purpose
|
||||||
|
|
||||||
|
local defaultLogLevel = "INFO"
|
||||||
local debug = false
|
local debug = false
|
||||||
local id = net.get_my_player_id()
|
local id = net.get_my_player_id()
|
||||||
if id == 0 then
|
if id == 0 then
|
||||||
debug = true
|
debug = true
|
||||||
|
defaultLogLevel = "DEBUG"
|
||||||
end
|
end
|
||||||
|
|
||||||
local startTime = timer.getTime() * 1000
|
local startTime = timer.getTime() * 1000
|
||||||
|
|
||||||
Spearhead.Events.Init("DEBUG")
|
Spearhead.Events.Init(defaultLogLevel)
|
||||||
|
|
||||||
local dbLogger = Spearhead.LoggerTemplate.new("database", "INFO")
|
local dbLogger = Spearhead.LoggerTemplate.new("database", defaultLogLevel)
|
||||||
local standardLogger = Spearhead.LoggerTemplate.new("", "INFO")
|
local standardLogger = Spearhead.LoggerTemplate.new("", defaultLogLevel)
|
||||||
local databaseManager = Spearhead.DB.New(dbLogger)
|
local databaseManager = Spearhead.DB.New(dbLogger)
|
||||||
|
Spearhead.classes.stageClasses.helpers.MissionCommandsHelper.getOrCreate(defaultLogLevel) -- initiate
|
||||||
|
|
||||||
local capConfig = Spearhead.internal.configuration.CapConfig:new();
|
local capConfig = Spearhead.internal.configuration.CapConfig:new();
|
||||||
local stageConfig = Spearhead.internal.configuration.StageConfig:new();
|
local stageConfig = Spearhead.internal.configuration.StageConfig:new();
|
||||||
@@ -22,7 +24,7 @@ local stageConfig = Spearhead.internal.configuration.StageConfig:new();
|
|||||||
local startingStage = stageConfig.startingStage or 1
|
local startingStage = stageConfig.startingStage or 1
|
||||||
if SpearheadConfig and SpearheadConfig.Persistence and SpearheadConfig.Persistence.enabled == true then
|
if SpearheadConfig and SpearheadConfig.Persistence and SpearheadConfig.Persistence.enabled == true then
|
||||||
standardLogger:info("Persistence enabled")
|
standardLogger:info("Persistence enabled")
|
||||||
local persistenceLogger = Spearhead.LoggerTemplate.new("Persistence", "INFO")
|
local persistenceLogger = Spearhead.LoggerTemplate.new("Persistence", defaultLogLevel)
|
||||||
Spearhead.classes.persistence.Persistence.Init(persistenceLogger)
|
Spearhead.classes.persistence.Persistence.Init(persistenceLogger)
|
||||||
|
|
||||||
local persistanceStage = Spearhead.classes.persistence.Persistence.GetActiveStage()
|
local persistanceStage = Spearhead.classes.persistence.Persistence.GetActiveStage()
|
||||||
|
|||||||
Reference in New Issue
Block a user