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:
commit
252e4349fe
16
scripts/data/cross_cell_border/README.md
Normal file
16
scripts/data/cross_cell_border/README.md
Normal 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
|
||||
```
|
25
scripts/data/cross_cell_border/common.lua
Normal file
25
scripts/data/cross_cell_border/common.lua
Normal 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
|
@ -0,0 +1,2 @@
|
||||
GLOBAL: global.lua
|
||||
PLAYER: player.lua
|
20
scripts/data/cross_cell_border/global.lua
Normal file
20
scripts/data/cross_cell_border/global.lua
Normal 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,
|
||||
},
|
||||
}
|
95
scripts/data/cross_cell_border/player.lua
Normal file
95
scripts/data/cross_cell_border/player.lua
Normal 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,
|
||||
},
|
||||
}
|
2
scripts/data/cross_cell_border/setup.mwscript
Normal file
2
scripts/data/cross_cell_border/setup.mwscript
Normal file
@ -0,0 +1,2 @@
|
||||
player->SetFlying 1
|
||||
tcl
|
Loading…
x
Reference in New Issue
Block a user