From 34931d0159dec84e7cfd9c07e5b9de1a6be23844 Mon Sep 17 00:00:00 2001 From: Diject Date: Sat, 3 Jan 2026 11:27:35 +0300 Subject: [PATCH] Add playerCellOnly option to extractLocalMaps --- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwlua/worldbindings.cpp | 7 ++-- apps/openmw/mwworld/worldimp.cpp | 36 +++++++++++++++++++-- apps/openmw/mwworld/worldimp.hpp | 2 +- files/data/scripts/map_extractor/global.lua | 9 +++--- files/lua_api/openmw/world.lua | 7 +++- 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index c51b03e3ec..d570177da2 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -619,7 +619,7 @@ namespace MWBase virtual void extractWorldMap() = 0; ///< Extract world map using path from options or default - virtual void extractLocalMaps() = 0; + virtual void extractLocalMaps(bool playerCellOnly = false) = 0; ///< Extract local maps using path from options or default virtual bool isMapExtractionActive() const = 0; diff --git a/apps/openmw/mwlua/worldbindings.cpp b/apps/openmw/mwlua/worldbindings.cpp index 1f887a0b8b..6f720974a5 100644 --- a/apps/openmw/mwlua/worldbindings.cpp +++ b/apps/openmw/mwlua/worldbindings.cpp @@ -259,11 +259,12 @@ namespace MWLua "extractWorldMapAction"); }; - api["extractLocalMaps"] = [context, lua = context.mLua]() { + api["extractLocalMaps"] = [context, lua = context.mLua](sol::optional playerCellOnly) { checkGameInitialized(lua); + bool onlyPlayerCell = playerCellOnly.value_or(false); context.mLuaManager->addAction( - [] { - MWBase::Environment::get().getWorld()->extractLocalMaps(); + [onlyPlayerCell] { + MWBase::Environment::get().getWorld()->extractLocalMaps(onlyPlayerCell); }, "extractLocalMapsAction"); }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ee8f39f5dc..240ff39eb1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3930,7 +3930,7 @@ namespace MWWorld mMapExtractor->extractWorldMap(); } - void World::extractLocalMaps() + void World::extractLocalMaps(bool playerCellOnly) { if (!mMapExtractor) { @@ -3942,9 +3942,39 @@ namespace MWWorld { mMapExtractor->setLocalMap(localMap); } + const auto& activeCells = mWorldScene->getActiveCells(); - std::vector cells(activeCells.begin(), activeCells.end()); - mMapExtractor->extractLocalMaps(cells); + std::vector cells; + + if (playerCellOnly) + { + MWWorld::Ptr player = getPlayerPtr(); + if (!player.isEmpty() && player.isInCell()) + { + MWWorld::CellStore* playerCell = player.getCell(); + + // Only extract for exterior cells + // Interior cells are always single, so no filtering needed + if (playerCell && playerCell->isExterior()) + { + cells.push_back(playerCell); + } + else + { + cells.assign(activeCells.begin(), activeCells.end()); + } + } + } + else + { + // Extract all active cells + cells.assign(activeCells.begin(), activeCells.end()); + } + + if (!cells.empty()) + { + mMapExtractor->extractLocalMaps(cells); + } } bool World::isMapExtractionActive() const diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 1eb0583869..e7a54347d4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -693,7 +693,7 @@ namespace MWWorld bool getOverwriteMaps() const override { return mOverwriteMaps; } void extractWorldMap() override; - void extractLocalMaps() override; + void extractLocalMaps(bool playerCellOnly = false) override; bool isMapExtractionActive() const override; void saveToLocalMapDir(std::string_view filename, std::string_view stringData) override; diff --git a/files/data/scripts/map_extractor/global.lua b/files/data/scripts/map_extractor/global.lua index c60ad0df71..040d53db5e 100644 --- a/files/data/scripts/map_extractor/global.lua +++ b/files/data/scripts/map_extractor/global.lua @@ -8,8 +8,9 @@ local visitedCells = {} local cellCount = #world.cells local i = cellCount -local lastTimestamp = core.getRealTime() - 100 -local timeFromLast = 100 +local lastTimestamp = core.getRealTime() - 50 +local timeFromLast = 50 +local onlyPlayerCell = false local function getExCellId(gridX, gridY) @@ -66,7 +67,7 @@ local function processAndTeleport(skipExtraction) local pl = world.players[1] if not skipExtraction then - world.extractLocalMaps() + world.extractLocalMaps(onlyPlayerCell) end local function func() @@ -98,7 +99,7 @@ local function processAndTeleport(skipExtraction) if not cell or not customCellId or visitedCells[customCellId] then goto continue end visitedCells[customCellId] = true - if cell.isExterior then + if not onlyPlayerCell and cell.isExterior then for j = cell.gridX - 1, cell.gridX + 1 do for k = cell.gridY - 1, cell.gridY + 1 do visitedCells[getExCellId(j, k)] = true diff --git a/files/lua_api/openmw/world.lua b/files/lua_api/openmw/world.lua index b580760efd..e341d80edf 100644 --- a/files/lua_api/openmw/world.lua +++ b/files/lua_api/openmw/world.lua @@ -236,7 +236,12 @@ -- or defaults to "./textures/advanced_world_map/local" if not specified. -- By default, existing maps are not overwritten. Use --overwrite-maps option to force overwriting. -- @function [parent=#world] extractLocalMaps --- @usage world.extractLocalMaps() -- Use path from option or default +-- @param #boolean playerCellOnly (optional, false by default) If true, extracts only the player's current cell. +-- For exterior cells, this extracts only the player's cell instead of all 9 loaded cells. +-- For interior cells, this has no effect as only one cell is loaded anyway. +-- @usage world.extractLocalMaps() -- Extract all active cells (default) +-- @usage world.extractLocalMaps(false) -- Same as above, extract all active cells +-- @usage world.extractLocalMaps(true) -- Extract only player's current cell (exterior only) --- -- Enable extraction mode for map generation.