Briefing as location (#64)

* Added briefing location as primary location coords

* added pin briefing and briefing duration chagnes

* updated command menu logic, sorting and naming

---------

Co-authored-by: dutchie032 <dutchie032>
This commit is contained in:
2025-12-14 13:54:48 +01:00
committed by GitHub
co-authored by dutchie032 <dutchie032>
parent 7c5701532b
commit f0aee49de2
7 changed files with 2020 additions and 1895 deletions
+7
View File
@@ -44,3 +44,10 @@ Since automated testing for now doesn't seem feasible, please make sure to verif
Finalise the PR and let the maintainers know! <br/> Finalise the PR and let the maintainers know! <br/>
We can all have a look and discuss the changes. <br/> We can all have a look and discuss the changes. <br/>
# TODO:
- Would it be possible to generate optional markers on mission briefing locations for Tomcat / Phantom navigation? Then Jester can type it in for the pilots automatically.
+34
View File
@@ -0,0 +1,34 @@
local briefingMessageTime = nil
---@class GlobalConfig
---@field private _briefingTime number ;
local GlobalConfig = {}
GlobalConfig.__index = GlobalConfig;
---@return GlobalConfig
function GlobalConfig.New()
local self = setmetatable({}, GlobalConfig)
self._briefingTime = 30
if SpearheadConfig then
if SpearheadConfig.briefingMessageDuration then
self._briefingTime = SpearheadConfig.briefingMessageDuration
end
end
return self
end
function GlobalConfig:getBriefingTime()
return self._briefingTime or 30
end
if Spearhead == nil then Spearhead = {} end
Spearhead.GlobalConfig = GlobalConfig.New()
@@ -13,6 +13,16 @@
local MissionCommandsHelper = {} local MissionCommandsHelper = {}
MissionCommandsHelper.__index = MissionCommandsHelper MissionCommandsHelper.__index = MissionCommandsHelper
---@param list Array<Mission>
---@param groupPos Vec2
local function sortMissions(list, groupPos)
table.sort(list, function(a, b)
local distA = Spearhead.Util.VectorDistance2d(groupPos, a.location or {x=0, y=0})
local distB = Spearhead.Util.VectorDistance2d(groupPos, b.location or {x=0, y=0})
return distA < distB;
end)
end
local id = 0 local id = 0
local instance = nil local instance = nil
@@ -145,6 +155,7 @@ end
---@field groupId integer @the group ID of the player requesting the briefing ---@field groupId integer @the group ID of the player requesting the briefing
---@field mission Mission @the mission object ---@field mission Mission @the mission object
---@param args PinMissionCommandArgs
local pinMissionCommand = function(args) local pinMissionCommand = function(args)
---@type MissionCommandsHelper ---@type MissionCommandsHelper
local self = args.self local self = args.self
@@ -164,6 +175,12 @@ function MissionCommandsHelper:AddOverviewCommand(groupID)
local text = "Missions Overview\n\n" local text = "Missions Overview\n\n"
local group = Spearhead.DcsUtil.GetPlayerGroupByGroupID(id) local group = Spearhead.DcsUtil.GetPlayerGroupByGroupID(id)
---@type Vec2
local groupPos = { x=0, y=0 }
if group then
local pos = group:getUnit(1):getPosition().p
groupPos = { x= pos.x, y=pos.z }
end
---comment ---comment
---@param mission Mission ---@param mission Mission
@@ -188,29 +205,49 @@ function MissionCommandsHelper:AddOverviewCommand(groupID)
text = text .. briefing .. "\n\n" text = text .. briefing .. "\n\n"
end end
---Primary missions ---Primary missions
text = text .. "Primary Missions\n" text = text .. "Primary Missions\n"
for code, enabled in pairs(self.enabledByCode) do
---@type Array<Mission>
local primaryMissions = {}
for code, enabled in pairs(self.enabledByCode) do
if enabled == true then if enabled == true then
local mission = self.missionsByCode[code] local mission = self.missionsByCode[code]
if mission and mission:getState() == "ACTIVE" and mission.priority == "primary" then if mission and mission:getState() == "ACTIVE" and mission.priority == "primary" then
table.insert(primaryMissions, mission)
end
end
end
sortMissions(primaryMissions, groupPos)
for _, mission in pairs(primaryMissions) do
text = text .. formatLine(mission) text = text .. formatLine(mission)
end end
end
end
---Secondary missions ---Secondary missions
text = text .. "\nSecondary Missions\n" text = text .. "\nSecondary Missions\n"
---@type Array<Mission>
local secondaryMissions = {}
for code, enabled in pairs(self.enabledByCode) do for code, enabled in pairs(self.enabledByCode) do
if enabled == true then if enabled == true then
local mission = self.missionsByCode[code] local mission = self.missionsByCode[code]
if mission and mission:getState() == "ACTIVE" and mission.priority == "secondary" then if mission and mission:getState() == "ACTIVE" and mission.priority == "secondary" then
table.insert(secondaryMissions, mission)
end
end
end
sortMissions(secondaryMissions, groupPos)
for _, mission in pairs(secondaryMissions) do
text = text .. formatLine(mission) text = text .. formatLine(mission)
end end
end
end
trigger.action.outTextForGroup(id, text, 20, true) trigger.action.outTextForGroup(id, text, 20, true)
end end
@@ -255,6 +292,12 @@ function MissionCommandsHelper:updateCommandsForGroup(groupID)
missionCommands.removeItemForGroup(groupID, { "Clear View" } ) missionCommands.removeItemForGroup(groupID, { "Clear View" } )
missionCommands.addCommandForGroup(groupID, "Clear View", nil, clearView, groupID) missionCommands.addCommandForGroup(groupID, "Clear View", nil, clearView, groupID)
missionCommands.removeItemForGroup(groupID, { "Refresh Missions" } )
missionCommands.addCommandForGroup(groupID, "Refresh Missions", nil, function(refresh_mission_id)
self._logger:debug("Manual refresh of missions for group: " .. tostring(refresh_mission_id))
self:updateCommandsForGroup(refresh_mission_id)
end, groupID)
end end
local folderNames = { local folderNames = {
@@ -265,25 +308,76 @@ local folderNames = {
} }
---@param mission Mission
---@param groupID integer
function MissionCommandsHelper:PinMission(mission, groupID) function MissionCommandsHelper:PinMission(mission, groupID)
self._logger:debug("Pinning mission: [" .. mission.code .. "]" .. mission.name) self._logger:debug("Pinning mission: [" .. mission.code .. "]" .. mission.name)
self.pinnedByGroup[tostring(groupID)] = mission self.pinnedByGroup[tostring(groupID)] = mission
trigger.action.outTextForGroup(groupID, "Pinned mission: [" .. mission.code .. "]" .. mission.name, 3, true) trigger.action.outTextForGroup(groupID, "Pinned mission: [" .. mission.code .. "]" .. mission.name, 3, true)
self:updateCommandsForGroup(groupID) self:updateCommandsForGroup(groupID)
mission:ShowBriefing(groupID)
end end
function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID) function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID)
local perFolder = 9 local perFolder = 9
local group = Spearhead.DcsUtil.GetPlayerGroupByGroupID(groupID)
---@type Vec2
local groupPos = { x=0, y=0 }
if group then
local pos = group:getUnit(1):getPosition().p
groupPos = { x= pos.x, y=pos.z }
end
do --- primary missions do --- primary missions
local count = 0 local count = 0
local path = { [1] = folderNames.primary } local path = { [1] = folderNames.primary }
---@type Array<Mission>
local primaryMissions = {}
for code, enabled in pairs(self.enabledByCode) do for code, enabled in pairs(self.enabledByCode) do
if enabled == true then if enabled == true then
local mission = self.missionsByCode[code] local mission = self.missionsByCode[code]
if mission and mission.priority == "primary" then if mission and mission.priority == "primary" then
table.insert(primaryMissions, mission)
end
end
end
sortMissions(primaryMissions, groupPos)
for _, mission in pairs(primaryMissions) do
count = count + 1
if count <= perFolder then
local copied = Spearhead.Util.deepCopyTable(path)
self:addMissionCommands(groupID, copied, mission)
else
local name = "Next Menu ..."
missionCommands.addSubMenuForGroup(groupID, name, path)
path[#path+1] = name
count = 0
end
end
end
do --- secondary missions
local count = 0
local path = { [1] = folderNames.secondary }
local secondaryMissions = {}
for code, enabled in pairs(self.enabledByCode) do
if enabled == true then
local mission = self.missionsByCode[code]
if mission and mission.priority == "secondary" then
table.insert(secondaryMissions, mission)
end
end
end
sortMissions(secondaryMissions, groupPos)
for _, mission in pairs(secondaryMissions) do
count = count + 1 count = count + 1
if count <= perFolder then if count <= perFolder then
local copied = Spearhead.Util.deepCopyTable(path) local copied = Spearhead.Util.deepCopyTable(path)
@@ -297,29 +391,6 @@ function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID)
end end
end end
end end
end
do --- secondary missions
local count = 0
local path = { [1] = folderNames.secondary }
for code, enabled in pairs(self.enabledByCode) do
if enabled == true then
local mission = self.missionsByCode[code]
if mission and mission.priority == "secondary" then
count = count + 1
if count <= perFolder then
local copied = Spearhead.Util.deepCopyTable(path)
self:addMissionCommands(groupID, copied, mission)
else
local name = "Next Menu ..."
missionCommands.addSubMenuForGroup(groupID, name, path)
path[#path+1] = "more missions ..."
end
end
end
end
end
end
---comment ---comment
---@private ---@private
@@ -329,7 +400,20 @@ end
function MissionCommandsHelper:addMissionCommands(groupId, path, mission) function MissionCommandsHelper:addMissionCommands(groupId, path, mission)
if path then if path then
local missionFolderName = "[" .. mission.code .. "]" .. mission.name
local group = Spearhead.DcsUtil.GetPlayerGroupByGroupID(groupId)
local distance = "[?]"
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 dist = Spearhead.Util.VectorDistance2d(Vec2Pos, mission.location) / 1852
distance = "[" .. string.format("~%dnM", math.floor(dist)) .. "]"
end
end
local missionFolderName = "[" .. mission.code .. "]" .. distance .. mission.name .. "( " .. mission.missionTypeDisplay .. " )"
missionCommands.addSubMenuForGroup(groupId, missionFolderName, path) missionCommands.addSubMenuForGroup(groupId, missionFolderName, path)
table.insert(path, missionFolderName) table.insert(path, missionFolderName)
@@ -375,7 +459,6 @@ function MissionCommandsHelper:AddSupplyHubCommandsIfApplicable(groupID)
local path = { [1] = folderNames.supplyHub } local path = { [1] = folderNames.supplyHub }
---@type LoadCargoCommandParams ---@type LoadCargoCommandParams
local farpParams1000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "FARP_CRATE_1000", supplyUnitsTracker = self._supplyUnitsTracker } local farpParams1000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "FARP_CRATE_1000", supplyUnitsTracker = self._supplyUnitsTracker }
missionCommands.addCommandForGroup(groupID, "Load FARP Crate (1000)", path, loadCargoCommand, farpParams1000) missionCommands.addCommandForGroup(groupID, "Load FARP Crate (1000)", path, loadCargoCommand, farpParams1000)
@@ -119,7 +119,7 @@ function BuildableMission:ShowBriefing(groupID)
"\n\n" .. "\n\n" ..
"NOTE: Do not land in the orange construction zone!" "NOTE: Do not land in the orange construction zone!"
trigger.action.outTextForGroup(groupID, briefing, 30) trigger.action.outTextForGroup(groupID, briefing, Spearhead.GlobalConfig:getBriefingTime())
end end
function BuildableMission:MarkMissionAreaToGroup(groupID) function BuildableMission:MarkMissionAreaToGroup(groupID)
@@ -94,7 +94,7 @@ function Mission:ShowBriefing(groupId)
local text = "Mission [" .. local text = "Mission [" ..
self.code .. "] " .. self.name .. "\n \n" .. briefing .. " \n \n" .. stateString self.code .. "] " .. self.name .. "\n \n" .. briefing .. " \n \n" .. stateString
trigger.action.outTextForGroup(groupId, text, 30); trigger.action.outTextForGroup(groupId, text, Spearhead.GlobalConfig:getBriefingTime());
end end
@@ -143,9 +143,6 @@ if not Spearhead.classes.stageClasses.missions then Spearhead.classes.stageClass
if not Spearhead.classes.stageClasses.missions.baseMissions then Spearhead.classes.stageClasses.missions.baseMissions = {} end if not Spearhead.classes.stageClasses.missions.baseMissions then Spearhead.classes.stageClasses.missions.baseMissions = {} end
Spearhead.classes.stageClasses.missions.baseMissions.Mission = Mission Spearhead.classes.stageClasses.missions.baseMissions.Mission = Mission
do --aliases do --aliases
--- @alias MissionPriority --- @alias MissionPriority
+4
View File
@@ -4,6 +4,10 @@ SpearheadConfig = {
---DEBUG LOGGING ---DEBUG LOGGING
debugEnabled = false, -- default false debugEnabled = false, -- default false
--- The time briefings should be displayed by default.
--- Players can always "Clear Messages" through the F10 menu, so setting it to a high value can be
briefingMessageDuration = 30, --default 30
CapConfig = { CapConfig = {
--quickly enable of disable the entire CAP Logic --quickly enable of disable the entire CAP Logic
--(you can also just rename all units to not be named "CAP_") --(you can also just rename all units to not be named "CAP_")