1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-14 01:19:59 +00:00

Merge branch 'cross_cell_borders_test' into 'master'

Draft: Add scripts to benchmark cell border crossing

See merge request OpenMW/openmw!3101
This commit is contained in:
elsid 2025-03-13 06:25:35 +00:00
commit 252e4349fe
6 changed files with 160 additions and 0 deletions

View File

@ -0,0 +1,16 @@
#Cross cell border benchmark
A set of scripts to provide an automatic way to travel at high speed over multiple cells in the exterior world.
Use `"3,6"` as the start cell of an approximate center of the Morrowind default worldspace.
The player moves by a rectangular spiral with limit by simulation time.
Simple usage:
```bash
"${OPENMW_BINARY_DIR:?}/openmw" \
--skip-menu \
--no-grab \
--start "3,6" \
--script-run "${OPENMW_SOURCE_DIR:?}/scripts/data/cross_cell_border/setup.mwscript" \
--data "${OPENMW_SOURCE_DIR:?}/scripts/data/cross_cell_border" \
--content cross_cell_border.omwscripts
```

View File

@ -0,0 +1,25 @@
local core = require('openmw.core')
local module = {}
function module.makeCoroutineWithErrorReporting(fn)
local fatalErr = nil
local function coroutineImpl()
local ok, err = pcall(fn)
if ok then
return
end
fatalErr = err
end
local co = coroutine.create(coroutineImpl)
return function()
if coroutine.status(co) ~= 'dead' and not core.isWorldPaused() then
coroutine.resume(co)
if fatalErr then
error(fatalErr, 2)
end
end
end
end
return module

View File

@ -0,0 +1,2 @@
GLOBAL: global.lua
PLAYER: player.lua

View File

@ -0,0 +1,20 @@
local util = require('openmw.util')
local world = require('openmw.world')
local common = require('common')
local function startMoveAcrossExteriorWorld()
player:teleport('', util.vector3(player.position.x, player.position.y, 10000), util.vector3(0, 0, 0))
coroutine.yield()
player:sendEvent('startMoveAcrossExteriorWorld')
end
local function setPlayer(value)
player = value
end
return {
engineHandlers = {
onUpdate = common.makeCoroutineWithErrorReporting(startMoveAcrossExteriorWorld),
onPlayerAdded = setPlayer,
},
}

View File

@ -0,0 +1,95 @@
local core = require('openmw.core')
local input = require('openmw.input')
local self = require('openmw.self')
local types = require('openmw.types')
local util = require('openmw.util')
local common = require('common')
local started = false
local function rotate90DegreesByZ(vector)
return util.vector2(-vector.y, vector.x)
end
local function getRotationAngle(value)
-- for compatibility with 0.48
return value.z or value:getYaw()
end
local function streerTo(target)
self.controls.jump = false
self.controls.run = true
self.controls.sideMovement = 0
local direction = target - self.position
local targetAngle = math.atan2(direction.x, direction.y)
local diffAngle = util.normalizeAngle(targetAngle - getRotationAngle(self.rotation))
local maxYawChange = 0.05
self.controls.yawChange = util.clamp(diffAngle, -maxYawChange, maxYawChange)
if math.abs(diffAngle) <= maxYawChange and direction:length() > 0 then
self.controls.movement = 1
else
self.controls.movement = 0
end
end
local function toCellCenterPosition(x, y, z, cellSize)
return util.vector3((x + 0.5) * cellSize, (y + 0.5) * cellSize, z)
end
local function toCellLocation(position, cellSize)
return util.vector2(math.floor(position.x / cellSize), math.floor(position.y / cellSize))
end
local function moveAcrossExteriorWorld()
local cellSize = 8192
local currentCell = toCellLocation(self.position, cellSize)
local cellDirection = util.vector2(0, 1)
local visitedCells = {}
visitedCells[tostring(currentCell)] = true
types.Actor.stats.attributes.speed(self).base = 4096
local endTime = core.getSimulationTime() + 60
while core.getSimulationTime() < endTime do
local nextCell = currentCell + cellDirection
local target = toCellCenterPosition(nextCell.x, nextCell.y, self.position.z, cellSize)
while toCellLocation(self.position, cellSize) ~= nextCell and (target - self.position):length() > 1024 do
streerTo(target)
coroutine.yield()
end
visitedCells[tostring(nextCell)] = true
currentCell = nextCell
local newDirection = rotate90DegreesByZ(cellDirection)
if visitedCells[tostring(currentCell + newDirection)] ~= true then
cellDirection = newDirection
end
end
core.quit()
end
local function startMoveAcrossExteriorWorld()
input.setControlSwitch(input.CONTROL_SWITCH.Fighting, false)
input.setControlSwitch(input.CONTROL_SWITCH.Jumping, false)
input.setControlSwitch(input.CONTROL_SWITCH.Looking, false)
input.setControlSwitch(input.CONTROL_SWITCH.Magic, false)
input.setControlSwitch(input.CONTROL_SWITCH.VanityMode, false)
input.setControlSwitch(input.CONTROL_SWITCH.ViewMode, false)
started = true
end
local function setUpMoveAcrossExteriorWorld()
local impl = common.makeCoroutineWithErrorReporting(moveAcrossExteriorWorld)
return function()
if started then
impl()
end
end
end
return {
engineHandlers = {
onFrame = setUpMoveAcrossExteriorWorld(),
},
eventHandlers = {
startMoveAcrossExteriorWorld = startMoveAcrossExteriorWorld,
},
}

View File

@ -0,0 +1,2 @@
player->SetFlying 1
tcl