From 51e6fdbcb442936a9d630f4ea3c8b8c78d73b950 Mon Sep 17 00:00:00 2001 From: Diject Date: Thu, 1 Jan 2026 17:49:32 +0300 Subject: [PATCH] Add estimated time and improve map extraction UI --- files/data/scripts/map_extractor/global.lua | 46 +++++++++++++++++---- files/data/scripts/map_extractor/menu.lua | 38 +++++++++-------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/files/data/scripts/map_extractor/global.lua b/files/data/scripts/map_extractor/global.lua index e900b47f9d..ce503b5997 100644 --- a/files/data/scripts/map_extractor/global.lua +++ b/files/data/scripts/map_extractor/global.lua @@ -1,11 +1,15 @@ local util = require("openmw.util") local world = require("openmw.world") local async = require("openmw.async") +local core = require("openmw.core") +local types = require("openmw.types") local visitedCells = {} local cellCount = #world.cells local i = cellCount +local lastTimestamp = core.getRealTime() - 100 +local timeFromLast = 100 local function getExCellId(gridX, gridY) @@ -41,6 +45,12 @@ local function processAndTeleport(skipExtraction) end repeat + if i % 50 == 0 then + local currentTime = core.getRealTime() + timeFromLast = (timeFromLast + currentTime - lastTimestamp) / 2 + lastTimestamp = currentTime + end + local res, cell = pcall(function () return world.cells[i] end) @@ -68,10 +78,18 @@ local function processAndTeleport(skipExtraction) end do - pl:teleport(cell, pos) + local estimatedTimeLeft = math.max(timeFromLast, 1) / 50 * i + local hours = math.floor(estimatedTimeLeft / 3600) + estimatedTimeLeft = estimatedTimeLeft % 3600 + local minutes = math.floor(estimatedTimeLeft / 60) + local seconds = estimatedTimeLeft % 60 pl:sendEvent("builtin:map_extractor:updateMenu", { line2 = string.format("Processed %d / %d cells", cellCount - i, cellCount), + line3 = string.format("Estimated time left: %d:%02d:%02.0f", hours, minutes, seconds), }) + + pl:teleport(cell, pos) + break end @@ -82,6 +100,7 @@ local function processAndTeleport(skipExtraction) pl:sendEvent("builtin:map_extractor:updateMenu", { line1 = "Map extraction complete.", line2 = "", + line3 = "", }) end end @@ -91,17 +110,28 @@ end async:newUnsavableSimulationTimer(0.1, function () - world.players[1]:sendEvent("builtin:map_extractor:updateMenu", {line1 = "Generating world map..."}) + local pl = world.players[1] + pl:sendEvent("builtin:map_extractor:updateMenu", {line1 = "Generating world map..."}) world.enableExtractionMode() - world.extractWorldMap() + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.Controls, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.Fighting, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.Jumping, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.Looking, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.Magic, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.VanityMode, false) + types.Player.setControlSwitch(pl, types.Player.CONTROL_SWITCH.ViewMode, false) - if not world.getOverwriteFlag() then - for _, cellId in pairs(world.getExistingLocalMapIds() or {}) do - visitedCells[cellId] = true + async:newUnsavableSimulationTimer(0.1, function () + world.extractWorldMap() + + if not world.getOverwriteFlag() then + for _, cellId in pairs(world.getExistingLocalMapIds() or {}) do + visitedCells[cellId] = true + end end - end - processAndTeleport(true) + processAndTeleport(true) + end) end) diff --git a/files/data/scripts/map_extractor/menu.lua b/files/data/scripts/map_extractor/menu.lua index be96329d70..7d8e21ee7a 100644 --- a/files/data/scripts/map_extractor/menu.lua +++ b/files/data/scripts/map_extractor/menu.lua @@ -2,25 +2,15 @@ local ui = require("openmw.ui") local util = require("openmw.util") +local screenSize = ui.layers[ui.layers.indexOf("HUD")].size + + ui.layers.insertAfter("MainMenuBackground", "builtin:map_extractor", {interactive = false}) -local content = ui.content{ - { - type = ui.TYPE.Text, - props = { - text = "", - textSize = 20, - autoSize = true, - textColor = util.color.rgb(1, 1, 1), - textAlignH = ui.ALIGNMENT.Center, - textAlignV = ui.ALIGNMENT.Center, - textShadow = true, - textShadowColor = util.color.rgb(0, 0, 0), - anchor = util.vector2(0.5, 0.5), - }, - }, - { - type = ui.TYPE.Text, + +local function textLine() + return { + type = ui.TYPE.TextEdit, props = { text = "", textSize = 20, @@ -31,8 +21,19 @@ local content = ui.content{ textShadow = true, textShadowColor = util.color.rgb(0, 0, 0), anchor = util.vector2(0.5, 0.5), + size = util.vector2(screenSize.x, 0), + multiline = true, + wordWrap = true, + readOnly = true, }, } +end + + +local content = ui.content{ + textLine(), + textLine(), + textLine(), } @@ -70,6 +71,9 @@ return { if data.line2 then content[2].props.text = data.line2 end + if data.line3 then + content[3].props.text = data.line3 + end menu:update() end,