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:
committed by
GitHub
co-authored by
dutchie032 <dutchie032>
parent
7c5701532b
commit
f0aee49de2
@@ -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.
|
||||||
|
|||||||
@@ -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,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_")
|
||||||
|
|||||||
Reference in New Issue
Block a user