209 lines
8.2 KiB
Lua

-- ====================================================================================
-- TUM.MISSION - HANDLES THE MAIN MISSION
-- ====================================================================================
-- ====================================================================================
TUM.mission = {}
TUM.mission.status = {
NONE = 0,
IN_PROGRESS = 1,
COMPLETED = 2,
FAILED = 3,
}
TUM.mission.endCause = { -- Why did the mission end?
ABORTED = 1,
COMPLETED = 2,
FAILED = 3
}
do
local OBJECTIVES_REMINDER_INTERVAL = 5
local missionStatus = TUM.mission.status.NONE
local objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL
function TUM.mission.getStatus()
return missionStatus
end
local function closeMission(removeAllUnits)
if removeAllUnits then
TUM.airForce.removeAll()
TUM.ambientWorld.removeAll()
TUM.enemyAirDefense.removeAll()
TUM.objectives.removeAll()
end
missionStatus = TUM.mission.status.NONE
TUM.intermission.createMenu()
end
function TUM.mission.checkMissionStatus(silent)
silent = silent or false
if missionStatus ~= TUM.mission.status.IN_PROGRESS then return end
if TUM.objectives.areAllCompleted() then
missionStatus = TUM.mission.status.COMPLETED
DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1)
trigger.action.outSound("UI-MissionEnd.ogg")
if not silent then
TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "commandMissionComplete", nil, "Command", true)
end
end
end
function TUM.mission.beginMission(silent)
silent = silent or false
closeMission(true)
TUM.intermission.removeMissionZonesMarkers()
for _=1,TUM.settings.getValue(TUM.settings.id.TARGET_COUNT) do
TUM.objectives.add()
end
if TUM.objectives.getCount() == 0 then
TUM.log("Couldn't create any objective, mission creation failed.", TUM.logLevel.WARNING)
closeMission(true)
return
end
TUM.supportAWACS.create() -- Create the AWACS aircraft if it wasn't airborne already
TUM.enemyAirDefense.create() -- Must be called once objectives have been created
TUM.airForce.create() -- Must be called once objectives have been created
TUM.missionMenu.create() -- Must be called once objectives have been created
local briefingOrder = DCSEx.table.shuffle({1, 2, 3, 4, 5}) -- Just to make sure the same description is used twice
local briefingText = ""
for i=1,TUM.objectives.getCount() do
local obj = TUM.objectives.getObjective(i)
briefingText = briefingText.."Objective "..obj.name..":\n"
local descriptions = Library.tasks[obj.taskID].description.briefing
briefingText = briefingText..descriptions[DCSEx.math.clamp(briefingOrder[i], 1, #descriptions)]
if i < TUM.objectives.getCount() then
briefingText = briefingText.."\n\n"
end
end
DCSEx.envMission.setBriefing(TUM.settings.getPlayerCoalition(), briefingText)
DCSEx.envMission.setBriefing(TUM.settings.getEnemyCoalition(), "")
missionStatus = TUM.mission.status.IN_PROGRESS
if not silent then
DCSEx.dcs.outPicture("Pic-MissionStart.png", 5, true, 0, 1, 1, 25, 1)
trigger.action.outSound("UI-MissionStart.ogg")
end
trigger.action.outText("MISSION OBJECTIVES:\n"..TUM.mission.getSummaryString(), 10)
objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL
end
function TUM.mission.getSummaryString(onlyShowIncomplete, doublePercentage)
onlyShowIncomplete = onlyShowIncomplete or false
if missionStatus == TUM.mission.status.NONE then return "" end
local missionSummary = ""
for i=1,TUM.objectives.getCount() do
local o = TUM.objectives.getObjective(i)
if o then
if not o.completed or not onlyShowIncomplete then
missionSummary = missionSummary.."- Objective "..o.name..": "..Library.tasks[o.taskID].description.short
if not o.completed then
missionSummary = missionSummary.." ("..TUM.objectives.getObjectiveProgress(i, doublePercentage)..")"
else
missionSummary = missionSummary.." [DONE!]"
end
if i < TUM.objectives.getCount() then
missionSummary = missionSummary.."\n"
end
end
end
end
return missionSummary
end
function TUM.mission.endMission(endCause)
endCause = endCause or TUM.mission.endCause.ABORTED
if endCause == TUM.mission.endCause.ABORTED then
DCSEx.dcs.outPicture("Pic-MissionAborted.png", 5, true, 0, 1, 1, 25, 1)
TUM.playerScore.reset(true, "mission aborted")
elseif endCause == TUM.mission.endCause.COMPLETED then
DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1)
elseif endCause == TUM.mission.endCause.FAILED then
DCSEx.dcs.outPicture("Pic-MissionFailed.png", 5, true, 0, 1, 1, 25, 1)
end
trigger.action.outSound("UI-MissionEnd.ogg")
closeMission(true)
end
----------------------------------------------------------
-- Called on every mission update tick (every 15 seconds)
-- @return True if a radio message or other output was triggered, false otherwise
----------------------------------------------------------
function TUM.mission.onClockTick()
if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end -- Not currenly in a mission
if TUM.objectives.getCount() <= 0 then return false end -- No objectives
objectivesReminderIntervalLeft = objectivesReminderIntervalLeft - 1
if objectivesReminderIntervalLeft > 0 then return false end
objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL
TUM.mission.playMissionSummaryRadioMessage(true, false)
return true
end
-------------------------------------
-- Called when an event is raised
-- @param event The DCS World event
-------------------------------------
function TUM.mission.onEvent(event)
if missionStatus == TUM.mission.status.NONE then return end
if not event.initiator then return end
if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end
if not event.initiator:getPlayerName() then return end
-- All objectives complete and all players on the ground? Mission is complete
if event.id == world.event.S_EVENT_RUNWAY_TOUCH or event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT or event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then
if TUM.objectives.areAllCompleted() and #DCSEx.world.getPlayersInAir(TUM.settings.getPlayerCoalition()) == 0 then
TUM.mission.endMission(TUM.mission.endCause.COMPLETED)
end
end
if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end
-- When player dies in single-player, fail the mission
if event.id == world.event.S_EVENT_CRASH or event.id == world.event.S_EVENT_EJECTION or event.id == world.event.S_EVENT_PILOT_DEAD then
TUM.mission.endMission(TUM.mission.endCause.FAILED)
end
end
function TUM.mission.playMissionSummaryRadioMessage(onlyShowIncomplete, delayed)
onlyShowIncomplete = onlyShowIncomplete or false
delayed = delayed or false
local incompleteObjectives = TUM.objectives.getCount() - TUM.objectives.getCompletedCount()
local messageID = "commandMissionComplete"
if incompleteObjectives > 1 then
messageID = "commandObjectivesManyLeft"
elseif incompleteObjectives == 1 then
messageID = "commandObjectivesOneLeft"
end
TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), messageID, { TUM.mission.getSummaryString(onlyShowIncomplete, true) }, "COMMAND", delayed)
end
end