#include "game.lua" #include "script/common.lua" #include "ui/ui_extensions.lua" #include "ui/ui_helpers.lua" -- Custom heist mission implementation -- This script requires heist.lua in the level to work properly EndScreen = {} EndScreenButtons = {} EndScreenButtons.height = 50 EndScreenButtons.defaultWidth = 300 EndScreenButtons.width = {} EndScreenButtons.spacing = 28 + EndScreenButtons.height EndScreenButtons.totatHeight = 300 EndScreenButtons.capturedFocus = false gEndScreenTime = 0 gEndScreenHintScale = 0 gScoreStatsScale = 0 local bigFontSize = 32 timeLeft = 0 function init() state = "" savedScore = false score = 0 timeLeft = 0 endTimer = 0 endScreen = 0 endScreenScale = 0 end function tick(dt) --Read the current level state. This is set by heist.lua state = GetString("level.state") --If level is completed we need to deal with score if state == "win" and not savedScore then --Get the score from registry. These values are set by heist.lua score = GetInt("level.clearedprimary") + GetInt("level.clearedsecondary") timeLeft = GetFloat("level.timeleft") --Save the new score if it's better than the current highscore local oldScore = GetInt("savegame.mod.score") local oldTimeLeft = GetFloat("savegame.mod.timeleft") if score > oldScore or (score == oldScore and timeLeft > oldTimeLeft) then SetInt("savegame.mod.score", score) SetFloat("savegame.mod.timeleft", timeLeft) end --Do this only once savedScore = true end --If level is no longer in default state we need to handle win and lose if state ~= "" then --Wait two seconds to allow the escape vehicle to drive off endTimer = endTimer + dt if endTimer > 2 then if endScreen == 0 then SetValue("endScreen", 1, "cosine", 0.25) end end end end function draw() --End screen if endScreen > 0 then if LastInputDevice() == UI_DEVICE_GAMEPAD then UiSetCursorState(UI_CURSOR_HIDE_AND_LOCK) else UiSetCursorState(UI_CURSOR_SHOW) end --Set gEndScreenScale to ease in the end screen SetValue("endScreenScale", 1, "easeout", 0.5) --Call to draw the endscreen EndScreen.draw(endScreenScale, state) end end EndScreenButtons.getMaxWidth = function(self) local maxWidth = 0 for k, v in pairs(self.width) do if maxWidth < v then maxWidth = v end end return maxWidth end EndScreenButtons.drawButton = function(key, disabled, forceFocus) disabled = disabled or false forceFocus = forceFocus or false if EndScreenButtons.width[key] == nil then EndScreenButtons.width[key] = EndScreenButtons.defaultWidth end local useGamepad = LastInputDevice() == UI_DEVICE_GAMEPAD if disabled then UiPush() UiDisableInput() UiColorFilter(1,1,1,0.5) UiButtonImageBox("ui/common/box-outline-7.png", 6, 6, 1, 1, 1, 1) local pressed = UiTextButton(key, EndScreenButtons:getMaxWidth(), EndScreenButtons.height) UiPop() return pressed else UiPush() UiEnableInput() local id = UiNavGroupBegin() UiNavGroupSize(EndScreenButtons:getMaxWidth(), EndScreenButtons.height) if useGamepad and UiIsComponentInFocus(id) then UiButtonHoverColor(1, 1, 1, 1) UiButtonImageBox("ui/common/box-outline-7.png", 6, 6, 1, 1, 0.5, 1) UiColor(1, 1, 0.5) else UiButtonImageBox("ui/common/box-outline-7.png", 6, 6, 1, 1, 1, 1) UiColor(1,1,1) end if forceFocus and not EndScreenButtons.capturedFocus then UiForceFocus(id) EndScreenButtons.capturedFocus = true end UiBeginFrame() local result = UiTextButton(key, EndScreenButtons:getMaxWidth(), EndScreenButtons.height) EndScreenButtons.width[key] = UiEndFrame() UiNavGroupEnd() UiPop() return result end end EndScreen.drawEndScreenButtons = function(gameState) local useGamepad = LastInputDevice() == UI_DEVICE_GAMEPAD UiNavGroupBegin() UiPush() UiTranslate(UiCenter(), 20) UiFont("regular.ttf", 33) UiAlign("center middle") if gameState == "win" then if EndScreenButtons.drawButton("loc@UI_BUTTON_CONTINUE", false, true) then exitMission() end UiTranslate(0, EndScreenButtons.spacing) end local canQLoad = GetBool("game.canquickload") if EndScreenButtons.drawButton("loc@UI_BUTTON_QUICK_LOAD", not canQLoad, canQLoad and gameState ~= "win") then Command("game.quickload") end UiPush() if GetInt("savegame.mission.lee_tower.score") == 0 and canQLoad == false and GetBool("game.quicksaveinprogress")==false and gameState ~= "win" and gEndScreenHintScale > 0 then UiTranslate(170, 0) UiColorFilter(1,1,1,gEndScreenHintScale) drawHintArrow(GetTranslatedStringByKey("USE_QUICKSAVE")) end UiPop() UiTranslate(0, EndScreenButtons.spacing) if EndScreenButtons.drawButton("loc@UI_BUTTON_RESTART_MISSION", false, not canQLoad) then Restart() end UiTranslate(0, EndScreenButtons.spacing) if gameState ~= "win" then if EndScreenButtons.drawButton("loc@UI_BUTTON_ABORT_MISSION") then exitMission() end UiTranslate(0, EndScreenButtons.spacing) end if EndScreenButtons.drawButton("loc@UI_BUTTON_MAIN_MENU") then Menu() end UiTranslate(0, EndScreenButtons.spacing) if useGamepad then UiPush() UiTranslate(0, 6) UiAlign("center middle") UiColor(1, 1, 1, 1) UiDrawHintsCentered({ {ico = "[[menu:menu_accept;iconsize=42,42]]", txt="loc@UI_BUTTON_SELECT"} }) UiPop() UiTranslate(0, 68) else UiTranslate(0, -15) end _,EndScreenButtons.totatHeight = UiGetRelativePos() UiPop() UiNavGroupEnd() end EndScreen.w = 510 EndScreen.h = 1080 EndScreen.titleWidth = 300 EndScreen.contentWidth = 410 EndScreen.drawScoreGroup = function(width, group) if #group.items == 0 then return end UiFont("bold.ttf", 33) UiColor(group.color[1], group.color[2], group.color[3]) UiAlign("left") UiText(group.title) if group.value ~= nil then UiPush() UiAlign("right") UiTranslate(width, 0) UiText(group.value) UiPop() end UiTranslate(0, 45) for _, it in pairs(group.items) do if it.count ~= nil and it.count > 0 then UiPush() UiAlign("left bottom") UiFont("regular.ttf", 27) UiColorFilter(1, 1, 1, 0.7) UiText(it.title) UiPop() UiPush() UiTranslate(width, 0) UiAlign("right bottom") UiColorFilter(1, 1, 1, 1) UiFont("regular.ttf", 33) UiText(tostring(it.taken) .. "/" .. tostring(it.count)) UiPop() else UiPush() UiAlign("left bottom") UiFont("regular.ttf", 27) UiColorFilter(1, 1, 1, 0.7) UiText(it.title) UiPop() if it.value ~= nil then UiPush() UiTranslate(width, 0) UiAlign("right bottom") UiColorFilter(1, 1, 1, 1) UiFont("regular.ttf", 33) UiText(it.value) UiPop() end end UiTranslate(0, 45) end UiTranslate(0, 15) end EndScreen.drawScore = function(details, drawTimeLeft, missionTime, width) UiPush() UiAlign("left") UiTextAlignment("left") if gScoreStatsScale == 0 then SetValue("gScoreStatsScale", 1, "linear", 0.7) UiSound("common/score-stats-500.ogg") end UiFont("bold.ttf", bigFontSize) UiColor(.5, .5, .5) UiTranslate(0, 46) -- draw stats local statsItems = {} if drawTimeLeft > 0 then table.insert(statsItems, { title = "loc@UI_TEXT_TIME_LEFT", value = math.floor(drawTimeLeft*gScoreStatsScale*10+0.5)/10 .." "..GetTranslatedStringByKey("TIME_SECONDS_SHORT")}) end if missionTime > 0 then local function timeValue() local m = math.floor(gScoreStatsScale * missionTime / 60) local s = math.floor(gScoreStatsScale * missionTime - m * 60) if m > 0 then return m.." "..GetTranslatedStringByKey("TIME_MINUTES_SHORT").." "..s.." "..GetTranslatedStringByKey("TIME_SECONDS_SHORT") else return s.." "..GetTranslatedStringByKey("TIME_SECONDS_SHORT") end end table.insert(statsItems, { title = "loc@UI_TEXT_MISSION_TIME", value = timeValue() }) end if drawTimeLeft == 0 and missionTime == 0 then table.insert(statsItems, { title = "loc@UI_TEXT_MISSION_SKIPPED"}) end EndScreen.drawScoreGroup(width, { title = "loc@UI_TEXT_STATS", color = {1, 1, 0.5}, items = statsItems}) local targetItems = {} table.insert(targetItems, {count = details.required, taken = details.requiredTaken, title = "loc@UI_TEXT_REQUIRED", items = targetItems}) if details.optional > 0 then table.insert(targetItems, {count = details.optional, taken = details.optionalTaken, title = "loc@UI_TEXT_OPTIONAL", blink = true, items = targetItems}) end EndScreen.drawScoreGroup(width, { title = "loc@UI_TEXT_TARGETS", color = { 1, 1, 1}, items = targetItems }) local _,gScoreCanvasHeight = UiGetRelativePos() UiPop() return gScoreCanvasHeight end EndScreen.draw = function(f, gameState) if f <= 0 then return end SetBool("game.disablepause", true) gEndScreenTime = gEndScreenTime + GetTimeStep() if gEndScreenHintScale == 0.0 and gEndScreenTime > 2.0 then SetValue("gEndScreenHintScale", 1, "linear", 0.5) end if gEndScreenHintScale == 1.0 and gEndScreenTime > 10.0 then SetValue("gEndScreenHintScale", 0.0001, "linear", 0.5) end UiPush() UiTranslate(-EndScreen.w + EndScreen.w * f, 0) --Dialog UiAlign("top left") UiColor(0, 0, 0, 0.7 * f) UiRect(EndScreen.w, UiHeight()) UiWindow(EndScreen.w, UiHeight()) UiColor(1, 1, 1) UiPush() if gameState == "win" then UiPush() UiTranslate(UiCenter(), 53) UiAlign("top center") local th = fixedWidthText(GetTranslatedStringByKey("UI_TEXT_MISSION"), EndScreen.titleWidth, "bold.ttf", 86) UiTranslate(0, th + 15) fixedWidthText(GetTranslatedStringByKey("UI_TEXT_COMPLETED"), EndScreen.titleWidth, "bold.ttf", 60) UiPop() UiPush() local primary = GetInt("level.clearedprimary") local secondary = GetInt("level.clearedsecondary") local drawTimeLeft = GetFloat("level.timeleft") local missionTime = GetFloat("level.missiontime") local currentScore = primary + secondary UiTranslate(UiCenter(), 305) UiAlign("top center") UiFont("bold.ttf", 37) Ui.Color(0xBBBBBB) if GetBool("level.highscore") then UiText(GetTranslatedStringByKey("UI_TEXT_NEW_HIGHSCORE") .. " " ..currentScore, true) else UiText(GetTranslatedStringByKey("UI_TEXT_SCORE") .. " " ..currentScore, true) end UiTranslate(-UiCenter() + 50, 19) local details = { required = 2, optional = 1, requiredTaken = primary, optionalTaken = secondary } local h = EndScreen.drawScore(details, drawTimeLeft, missionTime, EndScreen.contentWidth) UiPop() UiTranslate(0, h) else UiPush() UiTranslate(UiCenter(), 60) UiAlign("top center") UiColor(1,0,0) local th = fixedWidthText(GetTranslatedStringByKey("UI_TEXT_MISSION"), EndScreen.titleWidth, "bold.ttf", 86) UiTranslate(0, th + 15) fixedWidthText(GetTranslatedStringByKey("UI_TEXT_FAILED"), EndScreen.titleWidth, "bold.ttf", 105) UiPop() UiPush() UiFont("regular.ttf", 27) UiAlign("top center") UiTextAlignment("center") UiTranslate(UiCenter(), 260) UiColor(.8, .8, .8) UiWordWrap(EndScreen.contentWidth) local reason = "" if gameState == "fail_dead" then reason = GetTranslatedStringByKey("REASON_YOU_DIED") elseif gameState == "fail_alarmtimer" then reason = GetTranslatedStringByKey("REASON_YOU_FAILED") elseif gameState == "fail_missiontimer" then reason = GetTranslatedStringByKey("REASON_YOU_RAN") elseif gameState == "fail_busted" then reason = GetTranslatedStringByKey("REASON_YOUR_ACTIONS") end local _, h = UiText(reason) UiPop() UiTranslate(0, 40 + h) end UiPop() UiTranslate(0, UiHeight() - EndScreenButtons.totatHeight) --Buttons at bottom UiMakeInteractive() EndScreen.drawEndScreenButtons(gameState) UiPop() end