mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-30 22:41:23 +00:00
Merge branch 'master' of gitlab.com:openmw/openmw into lua_controller_cursor
This commit is contained in:
commit
6491bb4910
543 changed files with 8905 additions and 6750 deletions
|
@ -521,13 +521,13 @@ Ubuntu_GCC_integration_tests_asan:
|
||||||
- build/OpenMW-*.dmg
|
- build/OpenMW-*.dmg
|
||||||
- "build/**/*.log"
|
- "build/**/*.log"
|
||||||
|
|
||||||
macOS13_Xcode14_arm64:
|
macOS14_Xcode15_arm64:
|
||||||
extends: .MacOS
|
extends: .MacOS
|
||||||
image: macos-12-xcode-14
|
image: macos-14-xcode-15
|
||||||
tags:
|
tags:
|
||||||
- saas-macos-medium-m1
|
- saas-macos-medium-m1
|
||||||
cache:
|
cache:
|
||||||
key: macOS12_Xcode14_arm64.v4
|
key: macOS14_Xcode15_arm64.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 3G
|
CCACHE_SIZE: 3G
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ macOS13_Xcode14_arm64:
|
||||||
- cd MSVC2019_64_Ninja
|
- cd MSVC2019_64_Ninja
|
||||||
- .\ActivateMSVC.ps1
|
- .\ActivateMSVC.ps1
|
||||||
- cmake --build . --config $config
|
- cmake --build . --config $config
|
||||||
- ccache --show-stats
|
- ccache --show-stats -v
|
||||||
- cd $config
|
- cd $config
|
||||||
- echo "CI_COMMIT_REF_NAME ${CI_COMMIT_REF_NAME}`nCI_JOB_ID ${CI_JOB_ID}`nCI_COMMIT_SHA ${CI_COMMIT_SHA}" | Out-File -Encoding UTF8 CI-ID.txt
|
- echo "CI_COMMIT_REF_NAME ${CI_COMMIT_REF_NAME}`nCI_JOB_ID ${CI_JOB_ID}`nCI_COMMIT_SHA ${CI_COMMIT_SHA}" | Out-File -Encoding UTF8 CI-ID.txt
|
||||||
- $artifactDirectory = "$(Make-SafeFileName("${CI_PROJECT_NAMESPACE}"))/$(Make-SafeFileName("${CI_COMMIT_REF_NAME}"))/$(Make-SafeFileName("${CI_COMMIT_SHORT_SHA}-${CI_JOB_ID}"))/"
|
- $artifactDirectory = "$(Make-SafeFileName("${CI_PROJECT_NAMESPACE}"))/$(Make-SafeFileName("${CI_COMMIT_REF_NAME}"))/$(Make-SafeFileName("${CI_COMMIT_SHORT_SHA}-${CI_JOB_ID}"))/"
|
||||||
|
@ -666,7 +666,6 @@ macOS13_Xcode14_arm64:
|
||||||
- choco source disable -n=chocolatey
|
- choco source disable -n=chocolatey
|
||||||
- choco install git --force --params "/GitAndUnixToolsOnPath" -y
|
- choco install git --force --params "/GitAndUnixToolsOnPath" -y
|
||||||
- choco install 7zip -y
|
- choco install 7zip -y
|
||||||
- choco install ccache -y
|
|
||||||
- choco install vswhere -y
|
- choco install vswhere -y
|
||||||
- choco install python -y
|
- choco install python -y
|
||||||
- choco install awscli -y
|
- choco install awscli -y
|
||||||
|
@ -689,15 +688,11 @@ macOS13_Xcode14_arm64:
|
||||||
- $time = (Get-Date -Format "HH:mm:ss")
|
- $time = (Get-Date -Format "HH:mm:ss")
|
||||||
- echo ${time}
|
- echo ${time}
|
||||||
- echo "started by ${GITLAB_USER_NAME}"
|
- echo "started by ${GITLAB_USER_NAME}"
|
||||||
- $env:CCACHE_BASEDIR = Get-Location
|
|
||||||
- $env:CCACHE_DIR = "$(Get-Location)\ccache"
|
|
||||||
- New-Item -Type Directory -Force -Path $env:CCACHE_DIR
|
|
||||||
- New-Item -Type File -Force -Path MSVC2019_64\.cmake\api\v1\query\codemodel-v2
|
- New-Item -Type File -Force -Path MSVC2019_64\.cmake\api\v1\query\codemodel-v2
|
||||||
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -b -t -C $multiview -E
|
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -b -t -C $multiview -E
|
||||||
- cd MSVC2019_64
|
- cd MSVC2019_64
|
||||||
- Get-Volume
|
- Get-Volume
|
||||||
- cmake --build . --config $config
|
- cmake --build . --config $config
|
||||||
- ccache --show-stats
|
|
||||||
- cd $config
|
- cd $config
|
||||||
- echo "CI_COMMIT_REF_NAME ${CI_COMMIT_REF_NAME}`nCI_JOB_ID ${CI_JOB_ID}`nCI_COMMIT_SHA ${CI_COMMIT_SHA}" | Out-File -Encoding UTF8 CI-ID.txt
|
- echo "CI_COMMIT_REF_NAME ${CI_COMMIT_REF_NAME}`nCI_JOB_ID ${CI_JOB_ID}`nCI_COMMIT_SHA ${CI_COMMIT_SHA}" | Out-File -Encoding UTF8 CI-ID.txt
|
||||||
- $artifactDirectory = "$(Make-SafeFileName("${CI_PROJECT_NAMESPACE}"))/$(Make-SafeFileName("${CI_COMMIT_REF_NAME}"))/$(Make-SafeFileName("${CI_COMMIT_SHORT_SHA}-${CI_JOB_ID}"))/"
|
- $artifactDirectory = "$(Make-SafeFileName("${CI_PROJECT_NAMESPACE}"))/$(Make-SafeFileName("${CI_COMMIT_REF_NAME}"))/$(Make-SafeFileName("${CI_COMMIT_SHORT_SHA}-${CI_JOB_ID}"))/"
|
||||||
|
@ -729,7 +724,6 @@ macOS13_Xcode14_arm64:
|
||||||
cache:
|
cache:
|
||||||
key: msbuild-v8
|
key: msbuild-v8
|
||||||
paths:
|
paths:
|
||||||
- ccache
|
|
||||||
- deps
|
- deps
|
||||||
- MSVC2019_64/deps/Qt
|
- MSVC2019_64/deps/Qt
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
|
@ -15,6 +15,7 @@ Programmers
|
||||||
Nicolay Korslund - Project leader 2008-2010
|
Nicolay Korslund - Project leader 2008-2010
|
||||||
scrawl - Top contributor
|
scrawl - Top contributor
|
||||||
|
|
||||||
|
AbduSharif
|
||||||
Adam Hogan (aurix)
|
Adam Hogan (aurix)
|
||||||
Aesylwinn
|
Aesylwinn
|
||||||
aegis
|
aegis
|
||||||
|
|
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -33,6 +33,8 @@
|
||||||
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
|
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
|
||||||
Bug #6025: Subrecords cannot overlap records
|
Bug #6025: Subrecords cannot overlap records
|
||||||
Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex
|
Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex
|
||||||
|
Bug #6146: Lua command `actor:setEquipment` doesn't trigger mwscripts when equipping or unequipping a scripted item
|
||||||
|
Bug #6156: 1ft Charm or Sound magic effect vfx doesn't work properly
|
||||||
Bug #6190: Unintuitive sun specularity time of day dependence
|
Bug #6190: Unintuitive sun specularity time of day dependence
|
||||||
Bug #6222: global map cell size can crash openmw if set to too high a value
|
Bug #6222: global map cell size can crash openmw if set to too high a value
|
||||||
Bug #6313: Followers with high Fight can turn hostile
|
Bug #6313: Followers with high Fight can turn hostile
|
||||||
|
@ -56,6 +58,7 @@
|
||||||
Bug #6973: Fade in happens after the scene load and is shown
|
Bug #6973: Fade in happens after the scene load and is shown
|
||||||
Bug #6974: Only harmful effects are reflected
|
Bug #6974: Only harmful effects are reflected
|
||||||
Bug #6977: Sun damage implementation does not match research
|
Bug #6977: Sun damage implementation does not match research
|
||||||
|
Bug #6985: Issues with Magic Cards numbers readability
|
||||||
Bug #6986: Sound magic effect does not make noise
|
Bug #6986: Sound magic effect does not make noise
|
||||||
Bug #6987: Set/Mod Blindness should not darken the screen
|
Bug #6987: Set/Mod Blindness should not darken the screen
|
||||||
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind
|
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind
|
||||||
|
@ -71,12 +74,15 @@
|
||||||
Bug #7084: Resurrecting an actor doesn't take into account base record changes
|
Bug #7084: Resurrecting an actor doesn't take into account base record changes
|
||||||
Bug #7088: Deleting last save game of last character doesn't clear character name/details
|
Bug #7088: Deleting last save game of last character doesn't clear character name/details
|
||||||
Bug #7092: BSA archives from higher priority directories don't take priority
|
Bug #7092: BSA archives from higher priority directories don't take priority
|
||||||
|
Bug #7102: Some HQ Creatures mod models can hit the 8 texture slots limit with 0.48
|
||||||
Bug #7103: Multiple paths pointing to the same plugin but with different cases lead to automatically removed config entries
|
Bug #7103: Multiple paths pointing to the same plugin but with different cases lead to automatically removed config entries
|
||||||
Bug #7122: Teleportation to underwater should cancel active water walking effect
|
Bug #7122: Teleportation to underwater should cancel active water walking effect
|
||||||
Bug #7131: MyGUI log spam when post processing HUD is open
|
Bug #7131: MyGUI log spam when post processing HUD is open
|
||||||
Bug #7134: Saves with an invalid last generated RefNum can be loaded
|
Bug #7134: Saves with an invalid last generated RefNum can be loaded
|
||||||
Bug #7163: Myar Aranath: Wheat breaks the GUI
|
Bug #7163: Myar Aranath: Wheat breaks the GUI
|
||||||
|
Bug #7168: Fix average scene luminance
|
||||||
Bug #7172: Current music playlist continues playing indefinitely if next playlist is empty
|
Bug #7172: Current music playlist continues playing indefinitely if next playlist is empty
|
||||||
|
Bug #7202: Post-processing normals for terrain, water randomly stop rendering
|
||||||
Bug #7204: Missing actor scripts freeze the game
|
Bug #7204: Missing actor scripts freeze the game
|
||||||
Bug #7229: Error marker loading failure is not handled
|
Bug #7229: Error marker loading failure is not handled
|
||||||
Bug #7243: Supporting loading external files from VFS from esm files
|
Bug #7243: Supporting loading external files from VFS from esm files
|
||||||
|
@ -93,22 +99,26 @@
|
||||||
Bug #7415: Unbreakable lock discrepancies
|
Bug #7415: Unbreakable lock discrepancies
|
||||||
Bug #7416: Modpccrimelevel is different from vanilla
|
Bug #7416: Modpccrimelevel is different from vanilla
|
||||||
Bug #7428: AutoCalc flag is not used to calculate enchantment costs
|
Bug #7428: AutoCalc flag is not used to calculate enchantment costs
|
||||||
|
Bug #7447: OpenMW-CS: Dragging a cell of a different type (from the initial type) into the 3D view crashes OpenMW-CS
|
||||||
Bug #7450: Evading obstacles does not work for actors missing certain animations
|
Bug #7450: Evading obstacles does not work for actors missing certain animations
|
||||||
Bug #7459: Icons get stacked on the cursor when picking up multiple items simultaneously
|
Bug #7459: Icons get stacked on the cursor when picking up multiple items simultaneously
|
||||||
Bug #7472: Crash when enchanting last projectiles
|
Bug #7472: Crash when enchanting last projectiles
|
||||||
Bug #7475: Equipping a constant effect item doesn't update the magic menu
|
Bug #7475: Equipping a constant effect item doesn't update the magic menu
|
||||||
Bug #7502: Data directories dialog (0.48.0) forces adding subdirectory instead of intended directory
|
Bug #7502: Data directories dialog (0.48.0) forces adding subdirectory instead of intended directory
|
||||||
Bug #7505: Distant terrain does not support sample size greater than cell size
|
Bug #7505: Distant terrain does not support sample size greater than cell size
|
||||||
|
Bug #7535: Bookart paths for textures in OpenMW vs vanilla Morrowind
|
||||||
Bug #7553: Faction reaction loading is incorrect
|
Bug #7553: Faction reaction loading is incorrect
|
||||||
Bug #7557: Terrain::ChunkManager::createChunk is called twice for the same position, lod on initial loading
|
Bug #7557: Terrain::ChunkManager::createChunk is called twice for the same position, lod on initial loading
|
||||||
Bug #7573: Drain Fatigue can't bring fatigue below zero by default
|
Bug #7573: Drain Fatigue can't bring fatigue below zero by default
|
||||||
Bug #7585: Difference in interior lighting between OpenMW with legacy lighting method enabled and vanilla Morrowind
|
Bug #7585: Difference in interior lighting between OpenMW with legacy lighting method enabled and vanilla Morrowind
|
||||||
|
Bug #7587: Quick load related crash
|
||||||
Bug #7603: Scripts menu size is not updated properly
|
Bug #7603: Scripts menu size is not updated properly
|
||||||
Bug #7604: Goblins Grunt becomes idle once injured
|
Bug #7604: Goblins Grunt becomes idle once injured
|
||||||
Bug #7609: ForceGreeting should not open dialogue for werewolves
|
Bug #7609: ForceGreeting should not open dialogue for werewolves
|
||||||
Bug #7611: Beast races' idle animations slide after turning or jumping in place
|
Bug #7611: Beast races' idle animations slide after turning or jumping in place
|
||||||
Bug #7617: The death prompt asks the player if they wanted to load the character's last created save
|
Bug #7617: The death prompt asks the player if they wanted to load the character's last created save
|
||||||
Bug #7619: Long map notes may get cut off
|
Bug #7619: Long map notes may get cut off
|
||||||
|
Bug #7623: Incorrect placement of the script info in the engraved ring of healing tooltip
|
||||||
Bug #7630: Charm can be cast on creatures
|
Bug #7630: Charm can be cast on creatures
|
||||||
Bug #7631: Cannot trade with/talk to Creeper or Mudcrab Merchant when they're fleeing
|
Bug #7631: Cannot trade with/talk to Creeper or Mudcrab Merchant when they're fleeing
|
||||||
Bug #7633: Groundcover should ignore non-geometry Drawables
|
Bug #7633: Groundcover should ignore non-geometry Drawables
|
||||||
|
@ -129,6 +139,7 @@
|
||||||
Bug #7679: Scene luminance value flashes when toggling shaders
|
Bug #7679: Scene luminance value flashes when toggling shaders
|
||||||
Bug #7685: Corky sometimes doesn't follow Llovyn Andus
|
Bug #7685: Corky sometimes doesn't follow Llovyn Andus
|
||||||
Bug #7712: Casting doesn't support spells and enchantments with no effects
|
Bug #7712: Casting doesn't support spells and enchantments with no effects
|
||||||
|
Bug #7721: CS: Special Chars Not Allowed in IDs
|
||||||
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
|
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
|
||||||
Bug #7724: Guards don't help vs werewolves
|
Bug #7724: Guards don't help vs werewolves
|
||||||
Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name
|
Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name
|
||||||
|
@ -136,6 +147,7 @@
|
||||||
Bug #7753: Editor: Actors Don't Scale According to Their Race
|
Bug #7753: Editor: Actors Don't Scale According to Their Race
|
||||||
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
||||||
Bug #7761: Rain and ambient loop sounds are mutually exclusive
|
Bug #7761: Rain and ambient loop sounds are mutually exclusive
|
||||||
|
Bug #7763: Bullet shape loading problems, assorted
|
||||||
Bug #7765: OpenMW-CS: Touch Record option is broken
|
Bug #7765: OpenMW-CS: Touch Record option is broken
|
||||||
Bug #7769: Sword of the Perithia: Broken NPCs
|
Bug #7769: Sword of the Perithia: Broken NPCs
|
||||||
Bug #7770: Sword of the Perithia: Script execution failure
|
Bug #7770: Sword of the Perithia: Script execution failure
|
||||||
|
@ -143,22 +155,34 @@
|
||||||
Bug #7785: OpenMW-CS initialising Skill and Attribute fields to 0 instead of -1 on non-FortifyStat spells
|
Bug #7785: OpenMW-CS initialising Skill and Attribute fields to 0 instead of -1 on non-FortifyStat spells
|
||||||
Bug #7794: Fleeing NPCs name tooltip doesn't appear
|
Bug #7794: Fleeing NPCs name tooltip doesn't appear
|
||||||
Bug #7796: Absorbed enchantments don't restore magicka
|
Bug #7796: Absorbed enchantments don't restore magicka
|
||||||
|
Bug #7823: Game crashes when launching it.
|
||||||
Bug #7832: Ingredient tooltips show magnitude for Fortify Maximum Magicka effect
|
Bug #7832: Ingredient tooltips show magnitude for Fortify Maximum Magicka effect
|
||||||
Bug #7840: First run of the launcher doesn't save viewing distance as the default value
|
Bug #7840: First run of the launcher doesn't save viewing distance as the default value
|
||||||
|
Bug #7841: Editor: "Dirty" water heights are saved in modified CELLs
|
||||||
|
Bug #7859: AutoCalc flag is not used to calculate potion value
|
||||||
|
Bug #7861: OpenMW-CS: Incorrect DIAL's type in INFO records
|
||||||
|
Bug #7872: Region sounds use wrong odds
|
||||||
|
Bug #7886: Equip and unequip animations can't share the animation track section
|
||||||
|
Bug #7887: Editor: Mismatched reported script data size and actual data size causes a crash during save
|
||||||
|
Bug #7898: Editor: Invalid reference scales are allowed
|
||||||
|
Bug #7899: Editor: Doors can't be unlocked
|
||||||
|
Bug #7901: Editor: Teleport-related fields shouldn't be editable if a ref does not teleport
|
||||||
|
Bug #7908: Key bindings names in the settings menu are layout-specific
|
||||||
Feature #2566: Handle NAM9 records for manual cell references
|
Feature #2566: Handle NAM9 records for manual cell references
|
||||||
Feature #3537: Shader-based water ripples
|
Feature #3537: Shader-based water ripples
|
||||||
Feature #5173: Support for NiFogProperty
|
Feature #5173: Support for NiFogProperty
|
||||||
Feature #5492: Let rain and snow collide with statics
|
Feature #5492: Let rain and snow collide with statics
|
||||||
Feature #5926: Refraction based on water depth
|
Feature #5926: Refraction based on water depth
|
||||||
Feature #5944: Option to use camera as sound listener
|
Feature #5944: Option to use camera as sound listener
|
||||||
Feature #6149: Dehardcode Lua API_REVISION
|
|
||||||
Feature #6152: Playing music via lua scripts
|
Feature #6152: Playing music via lua scripts
|
||||||
Feature #6188: Specular lighting from point light sources
|
Feature #6188: Specular lighting from point light sources
|
||||||
Feature #6411: Support translations in openmw-launcher
|
Feature #6411: Support translations in openmw-launcher
|
||||||
Feature #6447: Add LOD support to Object Paging
|
Feature #6447: Add LOD support to Object Paging
|
||||||
Feature #6491: Add support for Qt6
|
Feature #6491: Add support for Qt6
|
||||||
Feature #6556: Lua API for sounds
|
Feature #6556: Lua API for sounds
|
||||||
|
Feature #6679: Design a custom Input Action API
|
||||||
Feature #6726: Lua API for creating new objects
|
Feature #6726: Lua API for creating new objects
|
||||||
|
Feature #6727: Lua API for records of all object types
|
||||||
Feature #6864: Lua file access API
|
Feature #6864: Lua file access API
|
||||||
Feature #6922: Improve launcher appearance
|
Feature #6922: Improve launcher appearance
|
||||||
Feature #6933: Support high-resolution cursor textures
|
Feature #6933: Support high-resolution cursor textures
|
||||||
|
@ -171,16 +195,19 @@
|
||||||
Feature #7125: Remembering console commands between sessions
|
Feature #7125: Remembering console commands between sessions
|
||||||
Feature #7129: Add support for non-adaptive VSync
|
Feature #7129: Add support for non-adaptive VSync
|
||||||
Feature #7130: Ability to set MyGUI logging verbosity
|
Feature #7130: Ability to set MyGUI logging verbosity
|
||||||
|
Feature #7142: MWScript Lua API
|
||||||
Feature #7148: Optimize string literal lookup in mwscript
|
Feature #7148: Optimize string literal lookup in mwscript
|
||||||
|
Feature #7161: OpenMW-CS: Make adding and filtering TopicInfos easier
|
||||||
Feature #7194: Ori to show texture paths
|
Feature #7194: Ori to show texture paths
|
||||||
Feature #7214: Searching in the in-game console
|
Feature #7214: Searching in the in-game console
|
||||||
Feature #7284: Searching in the console with regex and toggleable case-sensitivity
|
Feature #7248: Searching in the console with regex and toggleable case-sensitivity
|
||||||
Feature #7468: Factions API for Lua
|
Feature #7468: Factions API for Lua
|
||||||
Feature #7477: NegativeLight Magic Effect flag
|
Feature #7477: NegativeLight Magic Effect flag
|
||||||
Feature #7499: OpenMW-CS: Generate record filters by drag & dropping cell content to the filters field
|
Feature #7499: OpenMW-CS: Generate record filters by drag & dropping cell content to the filters field
|
||||||
Feature #7546: Start the game on Fredas
|
Feature #7546: Start the game on Fredas
|
||||||
Feature #7554: Controller binding for tab for menu navigation
|
Feature #7554: Controller binding for tab for menu navigation
|
||||||
Feature #7568: Uninterruptable scripted music
|
Feature #7568: Uninterruptable scripted music
|
||||||
|
Feature #7590: [Lua] Ability to deserialize YAML data from scripts
|
||||||
Feature #7606: Launcher: allow Shift-select in Archives tab
|
Feature #7606: Launcher: allow Shift-select in Archives tab
|
||||||
Feature #7608: Make the missing dependencies warning when loading a savegame more helpful
|
Feature #7608: Make the missing dependencies warning when loading a savegame more helpful
|
||||||
Feature #7618: Show the player character's health in the save details
|
Feature #7618: Show the player character's health in the save details
|
||||||
|
@ -193,8 +220,14 @@
|
||||||
Feature #7792: Support Timescale Clouds
|
Feature #7792: Support Timescale Clouds
|
||||||
Feature #7795: Support MaxNumberRipples INI setting
|
Feature #7795: Support MaxNumberRipples INI setting
|
||||||
Feature #7805: Lua Menu context
|
Feature #7805: Lua Menu context
|
||||||
|
Feature #7860: Lua: Expose NPC AI settings (fight, alarm, flee)
|
||||||
|
Feature #7875: Disable MyGUI windows snapping
|
||||||
|
Feature #7914: Do not allow to move GUI windows out of screen
|
||||||
Task #5896: Do not use deprecated MyGUI properties
|
Task #5896: Do not use deprecated MyGUI properties
|
||||||
|
Task #6085: Replace boost::filesystem with std::filesystem
|
||||||
|
Task #6149: Dehardcode Lua API_REVISION
|
||||||
Task #6624: Drop support for saves made prior to 0.45
|
Task #6624: Drop support for saves made prior to 0.45
|
||||||
|
Task #7048: Get rid of std::bind
|
||||||
Task #7113: Move from std::atoi to std::from_char
|
Task #7113: Move from std::atoi to std::from_char
|
||||||
Task #7117: Replace boost::scoped_array with std::vector
|
Task #7117: Replace boost::scoped_array with std::vector
|
||||||
Task #7151: Do not use std::strerror to get errno error message
|
Task #7151: Do not use std::strerror to get errno error message
|
||||||
|
|
|
@ -528,8 +528,12 @@ if ! [ -z $UNITY_BUILD ]; then
|
||||||
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
|
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ -z $USE_CCACHE ]; then
|
if [ -n "$USE_CCACHE" ]; then
|
||||||
add_cmake_opts "-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
|
if [ -n "$NMAKE" ] || [ -n "$NINJA" ]; then
|
||||||
|
add_cmake_opts "-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DPRECOMPILE_HEADERS_WITH_MSVC=OFF"
|
||||||
|
else
|
||||||
|
echo "Ignoring -C (CCache) as it is incompatible with Visual Studio CMake generators"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# turn on LTO by default
|
# turn on LTO by default
|
||||||
|
|
|
@ -4,8 +4,8 @@ set -o pipefail
|
||||||
|
|
||||||
LUPDATE="${LUPDATE:-lupdate}"
|
LUPDATE="${LUPDATE:-lupdate}"
|
||||||
|
|
||||||
${LUPDATE:?} apps/wizard -ts files/lang/wizard_*.ts
|
${LUPDATE:?} -locations none apps/wizard -ts files/lang/wizard_*.ts
|
||||||
${LUPDATE:?} apps/launcher -ts files/lang/launcher_*.ts
|
${LUPDATE:?} -locations none apps/launcher -ts files/lang/launcher_*.ts
|
||||||
${LUPDATE:?} components/contentselector components/process -ts files/lang/components_*.ts
|
${LUPDATE:?} -locations none components/contentselector components/process -ts files/lang/components_*.ts
|
||||||
|
|
||||||
! (git diff --name-only | grep -q "^") || (echo -e "\033[0;31mBuild a 'translations' CMake target to update Qt localization for these files:\033[0;0m"; git diff --name-only | xargs -i echo -e "\033[0;31m{}\033[0;0m"; exit -1)
|
! (git diff --name-only | grep -q "^") || (echo -e "\033[0;31mBuild a 'translations' CMake target to update Qt localization for these files:\033[0;0m"; git diff --name-only | xargs -i echo -e "\033[0;31m{}\033[0;0m"; exit -1)
|
||||||
|
|
|
@ -20,6 +20,7 @@ apps/openmw_test_suite/lua/test_storage.cpp
|
||||||
apps/openmw_test_suite/lua/test_ui_content.cpp
|
apps/openmw_test_suite/lua/test_ui_content.cpp
|
||||||
apps/openmw_test_suite/lua/test_utilpackage.cpp
|
apps/openmw_test_suite/lua/test_utilpackage.cpp
|
||||||
apps/openmw_test_suite/lua/test_inputactions.cpp
|
apps/openmw_test_suite/lua/test_inputactions.cpp
|
||||||
|
apps/openmw_test_suite/lua/test_yaml.cpp
|
||||||
apps/openmw_test_suite/misc/test_endianness.cpp
|
apps/openmw_test_suite/misc/test_endianness.cpp
|
||||||
apps/openmw_test_suite/misc/test_resourcehelpers.cpp
|
apps/openmw_test_suite/misc/test_resourcehelpers.cpp
|
||||||
apps/openmw_test_suite/misc/test_stringops.cpp
|
apps/openmw_test_suite/misc/test_stringops.cpp
|
||||||
|
|
|
@ -44,6 +44,7 @@ option(BUILD_BENCHMARKS "Build benchmarks with Google Benchmark" OFF)
|
||||||
option(BUILD_NAVMESHTOOL "Build navmesh tool" ON)
|
option(BUILD_NAVMESHTOOL "Build navmesh tool" ON)
|
||||||
option(BUILD_BULLETOBJECTTOOL "Build Bullet object tool" ON)
|
option(BUILD_BULLETOBJECTTOOL "Build Bullet object tool" ON)
|
||||||
option(BUILD_OPENCS_TESTS "Build OpenMW Construction Set tests" OFF)
|
option(BUILD_OPENCS_TESTS "Build OpenMW Construction Set tests" OFF)
|
||||||
|
option(PRECOMPILE_HEADERS_WITH_MSVC "Precompile most common used headers with MSVC (alternative to ccache)" ON)
|
||||||
|
|
||||||
set(OpenGL_GL_PREFERENCE LEGACY) # Use LEGACY as we use GL2; GLNVD is for GL3 and up.
|
set(OpenGL_GL_PREFERENCE LEGACY) # Use LEGACY as we use GL2; GLNVD is for GL3 and up.
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ message(STATUS "Configuring OpenMW...")
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 49)
|
set(OPENMW_VERSION_MINOR 49)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
set(OPENMW_LUA_API_REVISION 54)
|
set(OPENMW_LUA_API_REVISION 59)
|
||||||
set(OPENMW_POSTPROCESSING_API_REVISION 1)
|
set(OPENMW_POSTPROCESSING_API_REVISION 1)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -89,7 +90,7 @@ set(OPENMW_VERSION_COMMITDATE "")
|
||||||
|
|
||||||
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||||
|
|
||||||
set(OPENMW_DOC_BASEURL "https://openmw.readthedocs.io/en/stable/")
|
set(OPENMW_DOC_BASEURL "https://openmw.readthedocs.io/en/")
|
||||||
|
|
||||||
set(GIT_CHECKOUT FALSE)
|
set(GIT_CHECKOUT FALSE)
|
||||||
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||||
|
@ -190,6 +191,22 @@ if (MSVC)
|
||||||
add_compile_options(/bigobj)
|
add_compile_options(/bigobj)
|
||||||
|
|
||||||
add_compile_options(/Zc:__cplusplus)
|
add_compile_options(/Zc:__cplusplus)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_LAUNCHER OR CMAKE_C_COMPILER_LAUNCHER)
|
||||||
|
if (CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||||
|
message(STATUS "A compiler launcher was specified, but will be unused by the current generator (${CMAKE_GENERATOR})")
|
||||||
|
else()
|
||||||
|
foreach (config_lower ${CMAKE_CONFIGURATION_TYPES})
|
||||||
|
string(TOUPPER "${config_lower}" config)
|
||||||
|
if (CMAKE_C_COMPILER_LAUNCHER STREQUAL "ccache")
|
||||||
|
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_${config} "${CMAKE_C_FLAGS_${config}}")
|
||||||
|
endif()
|
||||||
|
if (CMAKE_CXX_COMPILER_LAUNCHER STREQUAL "ccache")
|
||||||
|
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_${config} "${CMAKE_CXX_FLAGS_${config}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set up common paths
|
# Set up common paths
|
||||||
|
@ -718,67 +735,66 @@ if (WIN32)
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(d ${WARNINGS_DISABLE})
|
foreach(d ${WARNINGS_DISABLE})
|
||||||
set(WARNINGS "${WARNINGS} /wd${d}")
|
list(APPEND WARNINGS "/wd${d}")
|
||||||
endforeach(d)
|
endforeach(d)
|
||||||
|
|
||||||
if(OPENMW_MSVC_WERROR)
|
if(OPENMW_MSVC_WERROR)
|
||||||
set(WARNINGS "${WARNINGS} /WX")
|
list(APPEND WARNINGS "/WX")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(components PRIVATE ${WARNINGS})
|
||||||
set_target_properties(osg-ffmpeg-videoplayer PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(osg-ffmpeg-videoplayer PRIVATE ${WARNINGS})
|
||||||
|
|
||||||
if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920)
|
if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920)
|
||||||
target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE)
|
target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_BSATOOL)
|
if (BUILD_BSATOOL)
|
||||||
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(bsatool PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_ESMTOOL)
|
if (BUILD_ESMTOOL)
|
||||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(esmtool PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_ESSIMPORTER)
|
if (BUILD_ESSIMPORTER)
|
||||||
set_target_properties(openmw-essimporter PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-essimporter PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_LAUNCHER)
|
if (BUILD_LAUNCHER)
|
||||||
set_target_properties(openmw-launcher PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-launcher PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_MWINIIMPORTER)
|
if (BUILD_MWINIIMPORTER)
|
||||||
set_target_properties(openmw-iniimporter PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-iniimporter PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_OPENCS)
|
if (BUILD_OPENCS)
|
||||||
set_target_properties(openmw-cs PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-cs PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_OPENMW)
|
if (BUILD_OPENMW)
|
||||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_WIZARD)
|
if (BUILD_WIZARD)
|
||||||
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-wizard PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_UNITTESTS)
|
if (BUILD_UNITTESTS)
|
||||||
set_target_properties(openmw_test_suite PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw_test_suite PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_BENCHMARKS)
|
if (BUILD_BENCHMARKS)
|
||||||
set_target_properties(openmw_detournavigator_navmeshtilescache_benchmark PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_NAVMESHTOOL)
|
if (BUILD_NAVMESHTOOL)
|
||||||
set_target_properties(openmw-navmeshtool PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
target_compile_options(openmw-navmeshtool PRIVATE ${WARNINGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_BULLETOBJECTTOOL)
|
if (BUILD_BULLETOBJECTTOOL)
|
||||||
set(WARNINGS "${WARNINGS} ${MT_BUILD}")
|
target_compile_options(openmw-bulletobjecttool PRIVATE ${WARNINGS} ${MT_BUILD})
|
||||||
set_target_properties(openmw-bulletobjecttool PROPERTIES COMPILE_FLAGS "${WARNINGS}")
|
|
||||||
endif()
|
endif()
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
|
@ -1090,17 +1106,17 @@ if (USE_QT)
|
||||||
file(GLOB COMPONENTS_TS_FILES ${CMAKE_SOURCE_DIR}/files/lang/components_*.ts)
|
file(GLOB COMPONENTS_TS_FILES ${CMAKE_SOURCE_DIR}/files/lang/components_*.ts)
|
||||||
get_target_property(QT_LUPDATE_EXECUTABLE Qt::lupdate IMPORTED_LOCATION)
|
get_target_property(QT_LUPDATE_EXECUTABLE Qt::lupdate IMPORTED_LOCATION)
|
||||||
add_custom_target(translations
|
add_custom_target(translations
|
||||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/components/contentselector ${CMAKE_SOURCE_DIR}/components/process -ts ${COMPONENTS_TS_FILES}
|
COMMAND ${QT_LUPDATE_EXECUTABLE} -locations none ${CMAKE_SOURCE_DIR}/components/contentselector ${CMAKE_SOURCE_DIR}/components/process -ts ${COMPONENTS_TS_FILES}
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/components
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/components
|
||||||
VERBATIM
|
VERBATIM
|
||||||
COMMAND_EXPAND_LISTS
|
COMMAND_EXPAND_LISTS
|
||||||
|
|
||||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/apps/wizard -ts ${WIZARD_TS_FILES}
|
COMMAND ${QT_LUPDATE_EXECUTABLE} -locations none ${CMAKE_SOURCE_DIR}/apps/wizard -ts ${WIZARD_TS_FILES}
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/wizard
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/wizard
|
||||||
VERBATIM
|
VERBATIM
|
||||||
COMMAND_EXPAND_LISTS
|
COMMAND_EXPAND_LISTS
|
||||||
|
|
||||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/apps/launcher -ts ${LAUNCHER_TS_FILES}
|
COMMAND ${QT_LUPDATE_EXECUTABLE} -locations none ${CMAKE_SOURCE_DIR}/apps/launcher -ts ${LAUNCHER_TS_FILES}
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/launcher
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/launcher
|
||||||
VERBATIM
|
VERBATIM
|
||||||
COMMAND_EXPAND_LISTS)
|
COMMAND_EXPAND_LISTS)
|
||||||
|
|
|
@ -20,7 +20,7 @@ Font Licenses:
|
||||||
Current Status
|
Current Status
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
The main quests in Morrowind, Tribunal and Bloodmoon are all completable. Some issues with side quests are to be expected (but rare). Check the [bug tracker](https://gitlab.com/OpenMW/openmw/issues?label_name%5B%5D=1.0) for a list of issues we need to resolve before the "1.0" release. Even before the "1.0" release however, OpenMW boasts some new [features](https://wiki.openmw.org/index.php?title=Features), such as improved graphics and user interfaces.
|
The main quests in Morrowind, Tribunal and Bloodmoon are all completable. Some issues with side quests are to be expected (but rare). Check the [bug tracker](https://gitlab.com/OpenMW/openmw/-/issues/?milestone_title=openmw-1.0) for a list of issues we need to resolve before the "1.0" release. Even before the "1.0" release however, OpenMW boasts some new [features](https://wiki.openmw.org/index.php?title=Features), such as improved graphics and user interfaces.
|
||||||
|
|
||||||
Pre-existing modifications created for the original Morrowind engine can be hit-and-miss. The OpenMW script compiler performs more thorough error-checking than Morrowind does, meaning that a mod created for Morrowind may not necessarily run in OpenMW. Some mods also rely on quirky behaviour or engine bugs in order to work. We are considering such compatibility issues on a case-by-case basis - in some cases adding a workaround to OpenMW may be feasible, in other cases fixing the mod will be the only option. If you know of any mods that work or don't work, feel free to add them to the [Mod status](https://wiki.openmw.org/index.php?title=Mod_status) wiki page.
|
Pre-existing modifications created for the original Morrowind engine can be hit-and-miss. The OpenMW script compiler performs more thorough error-checking than Morrowind does, meaning that a mod created for Morrowind may not necessarily run in OpenMW. Some mods also rely on quirky behaviour or engine bugs in order to work. We are considering such compatibility issues on a case-by-case basis - in some cases adding a workaround to OpenMW may be feasible, in other cases fixing the mod will be the only option. If you know of any mods that work or don't work, feel free to add them to the [Mod status](https://wiki.openmw.org/index.php?title=Mod_status) wiki page.
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE <algorithm>)
|
target_precompile_headers(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE <algorithm>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ namespace
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
const auto& key = keys[n++ % keys.size()];
|
const auto& key = keys[n++ % keys.size()];
|
||||||
const auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh);
|
auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh);
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ namespace
|
||||||
while (state.KeepRunning())
|
while (state.KeepRunning())
|
||||||
{
|
{
|
||||||
const auto& key = keys[n++ % keys.size()];
|
const auto& key = keys[n++ % keys.size()];
|
||||||
const auto result = cache.set(
|
auto result = cache.set(
|
||||||
key.mAgentBounds, key.mTilePosition, key.mRecastMesh, std::make_unique<PreparedNavMeshData>());
|
key.mAgentBounds, key.mTilePosition, key.mRecastMesh, std::make_unique<PreparedNavMeshData>());
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(openmw_esm_refid_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(openmw_esm_refid_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw_esm_refid_benchmark PRIVATE <algorithm>)
|
target_precompile_headers(openmw_esm_refid_benchmark PRIVATE <algorithm>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(openmw_settings_access_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(openmw_settings_access_benchmark ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw_settings_access_benchmark PRIVATE <algorithm>)
|
target_precompile_headers(openmw_settings_access_benchmark PRIVATE <algorithm>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
static const float v = Settings::Manager::getFloat("sky blending start", "Fog");
|
static float v = Settings::Manager::getFloat("sky blending start", "Fog");
|
||||||
benchmark::DoNotOptimize(v);
|
benchmark::DoNotOptimize(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
static const float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
||||||
static const bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
||||||
benchmark::DoNotOptimize(v1);
|
benchmark::DoNotOptimize(v1);
|
||||||
benchmark::DoNotOptimize(v2);
|
benchmark::DoNotOptimize(v2);
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,9 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
static const float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
||||||
static const bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
||||||
static const int v3 = Settings::Manager::getInt("reflection detail", "Water");
|
static int v3 = Settings::Manager::getInt("reflection detail", "Water");
|
||||||
benchmark::DoNotOptimize(v1);
|
benchmark::DoNotOptimize(v1);
|
||||||
benchmark::DoNotOptimize(v2);
|
benchmark::DoNotOptimize(v2);
|
||||||
benchmark::DoNotOptimize(v3);
|
benchmark::DoNotOptimize(v3);
|
||||||
|
@ -71,7 +71,8 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::fog().mSkyBlendingStart.get());
|
float v = Settings::fog().mSkyBlendingStart.get();
|
||||||
|
benchmark::DoNotOptimize(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +80,10 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::postProcessing().mTransparentPostpass.get());
|
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
||||||
benchmark::DoNotOptimize(Settings::camera().mNearClip.get());
|
float v2 = Settings::camera().mNearClip.get();
|
||||||
|
benchmark::DoNotOptimize(v1);
|
||||||
|
benchmark::DoNotOptimize(v2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +91,12 @@ namespace
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for (auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::postProcessing().mTransparentPostpass.get());
|
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
||||||
benchmark::DoNotOptimize(Settings::camera().mNearClip.get());
|
float v2 = Settings::camera().mNearClip.get();
|
||||||
benchmark::DoNotOptimize(Settings::water().mReflectionDetail.get());
|
int v3 = Settings::water().mReflectionDetail.get();
|
||||||
|
benchmark::DoNotOptimize(v1);
|
||||||
|
benchmark::DoNotOptimize(v2);
|
||||||
|
benchmark::DoNotOptimize(v3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(bsatool gcov)
|
target_link_libraries(bsatool gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(bsatool PRIVATE
|
target_precompile_headers(bsatool PRIVATE
|
||||||
<filesystem>
|
<filesystem>
|
||||||
<fstream>
|
<fstream>
|
||||||
|
|
|
@ -329,17 +329,19 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
switch (bsaVersion)
|
switch (bsaVersion)
|
||||||
{
|
{
|
||||||
case Bsa::BSAVER_COMPRESSED:
|
case Bsa::BsaVersion::Unknown:
|
||||||
return call<Bsa::CompressedBSAFile>(info);
|
break;
|
||||||
case Bsa::BSAVER_BA2_GNRL:
|
case Bsa::BsaVersion::Uncompressed:
|
||||||
return call<Bsa::BA2GNRLFile>(info);
|
|
||||||
case Bsa::BSAVER_BA2_DX10:
|
|
||||||
return call<Bsa::BA2DX10File>(info);
|
|
||||||
case Bsa::BSAVER_UNCOMPRESSED:
|
|
||||||
return call<Bsa::BSAFile>(info);
|
return call<Bsa::BSAFile>(info);
|
||||||
default:
|
case Bsa::BsaVersion::Compressed:
|
||||||
throw std::runtime_error("Unrecognised BSA archive");
|
return call<Bsa::CompressedBSAFile>(info);
|
||||||
|
case Bsa::BsaVersion::BA2GNRL:
|
||||||
|
return call<Bsa::BA2GNRLFile>(info);
|
||||||
|
case Bsa::BsaVersion::BA2DX10:
|
||||||
|
return call<Bsa::BA2DX10File>(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Unrecognised BSA archive");
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ if (WIN32)
|
||||||
install(TARGETS openmw-bulletobjecttool RUNTIME DESTINATION ".")
|
install(TARGETS openmw-bulletobjecttool RUNTIME DESTINATION ".")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-bulletobjecttool PRIVATE
|
target_precompile_headers(openmw-bulletobjecttool PRIVATE
|
||||||
<string>
|
<string>
|
||||||
<vector>
|
<vector>
|
||||||
|
|
|
@ -25,7 +25,7 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(esmtool gcov)
|
target_link_libraries(esmtool gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(esmtool PRIVATE
|
target_precompile_headers(esmtool PRIVATE
|
||||||
<fstream>
|
<fstream>
|
||||||
<string>
|
<string>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "labels.hpp"
|
#include "labels.hpp"
|
||||||
|
|
||||||
|
#include <components/esm3/loadalch.hpp>
|
||||||
#include <components/esm3/loadbody.hpp>
|
#include <components/esm3/loadbody.hpp>
|
||||||
#include <components/esm3/loadcell.hpp>
|
#include <components/esm3/loadcell.hpp>
|
||||||
#include <components/esm3/loadcont.hpp>
|
#include <components/esm3/loadcont.hpp>
|
||||||
|
@ -987,3 +988,16 @@ std::string recordFlags(uint32_t flags)
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string potionFlags(int flags)
|
||||||
|
{
|
||||||
|
std::string properties;
|
||||||
|
if (flags == 0)
|
||||||
|
properties += "[None] ";
|
||||||
|
if (flags & ESM::Potion::Autocalc)
|
||||||
|
properties += "Autocalc ";
|
||||||
|
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
||||||
|
properties += "Invalid ";
|
||||||
|
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ std::string itemListFlags(int flags);
|
||||||
std::string lightFlags(int flags);
|
std::string lightFlags(int flags);
|
||||||
std::string magicEffectFlags(int flags);
|
std::string magicEffectFlags(int flags);
|
||||||
std::string npcFlags(int flags);
|
std::string npcFlags(int flags);
|
||||||
|
std::string potionFlags(int flags);
|
||||||
std::string raceFlags(int flags);
|
std::string raceFlags(int flags);
|
||||||
std::string spellFlags(int flags);
|
std::string spellFlags(int flags);
|
||||||
std::string weaponFlags(int flags);
|
std::string weaponFlags(int flags);
|
||||||
|
|
|
@ -180,22 +180,23 @@ namespace
|
||||||
void printEffectList(const ESM::EffectList& effects)
|
void printEffectList(const ESM::EffectList& effects)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const ESM::ENAMstruct& effect : effects.mList)
|
for (const ESM::IndexedENAMstruct& effect : effects.mList)
|
||||||
{
|
{
|
||||||
std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mEffectID) << " (" << effect.mEffectID
|
std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mData.mEffectID) << " ("
|
||||||
<< ")" << std::endl;
|
<< effect.mData.mEffectID << ")" << std::endl;
|
||||||
if (effect.mSkill != -1)
|
if (effect.mData.mSkill != -1)
|
||||||
std::cout << " Skill: " << skillLabel(effect.mSkill) << " (" << (int)effect.mSkill << ")"
|
std::cout << " Skill: " << skillLabel(effect.mData.mSkill) << " (" << (int)effect.mData.mSkill << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
if (effect.mAttribute != -1)
|
if (effect.mData.mAttribute != -1)
|
||||||
std::cout << " Attribute: " << attributeLabel(effect.mAttribute) << " (" << (int)effect.mAttribute
|
std::cout << " Attribute: " << attributeLabel(effect.mData.mAttribute) << " ("
|
||||||
<< ")" << std::endl;
|
<< (int)effect.mData.mAttribute << ")" << std::endl;
|
||||||
std::cout << " Range: " << rangeTypeLabel(effect.mRange) << " (" << effect.mRange << ")" << std::endl;
|
std::cout << " Range: " << rangeTypeLabel(effect.mData.mRange) << " (" << effect.mData.mRange << ")"
|
||||||
|
<< std::endl;
|
||||||
// Area is always zero if range type is "Self"
|
// Area is always zero if range type is "Self"
|
||||||
if (effect.mRange != ESM::RT_Self)
|
if (effect.mData.mRange != ESM::RT_Self)
|
||||||
std::cout << " Area: " << effect.mArea << std::endl;
|
std::cout << " Area: " << effect.mData.mArea << std::endl;
|
||||||
std::cout << " Duration: " << effect.mDuration << std::endl;
|
std::cout << " Duration: " << effect.mData.mDuration << std::endl;
|
||||||
std::cout << " Magnitude: " << effect.mMagnMin << "-" << effect.mMagnMax << std::endl;
|
std::cout << " Magnitude: " << effect.mData.mMagnMin << "-" << effect.mData.mMagnMax << std::endl;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,7 +480,7 @@ namespace EsmTool
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl;
|
std::cout << " Flags: " << potionFlags(mData.mData.mFlags) << std::endl;
|
||||||
printEffectList(mData.mEffects);
|
printEffectList(mData.mEffects);
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -612,7 +613,6 @@ namespace EsmTool
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl;
|
std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl;
|
||||||
std::cout << " Water Level Int: " << mData.mWaterInt << std::endl;
|
|
||||||
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -840,8 +840,7 @@ namespace EsmTool
|
||||||
|
|
||||||
std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) << " (" << mData.mQuestStatus << ")"
|
std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) << " (" << mData.mQuestStatus << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl;
|
std::cout << " Type: " << dialogTypeLabel(mData.mData.mType) << std::endl;
|
||||||
std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl;
|
|
||||||
|
|
||||||
for (const ESM::DialInfo::SelectStruct& rule : mData.mSelects)
|
for (const ESM::DialInfo::SelectStruct& rule : mData.mSelects)
|
||||||
std::cout << " Select Rule: " << ruleString(rule) << std::endl;
|
std::cout << " Select Rule: " << ruleString(rule) << std::endl;
|
||||||
|
@ -898,9 +897,6 @@ namespace EsmTool
|
||||||
if (const ESM::Land::LandData* data = mData.getLandData(mData.mDataTypes))
|
if (const ESM::Land::LandData* data = mData.getLandData(mData.mDataTypes))
|
||||||
{
|
{
|
||||||
std::cout << " Height Offset: " << data->mHeightOffset << std::endl;
|
std::cout << " Height Offset: " << data->mHeightOffset << std::endl;
|
||||||
// Lots of missing members.
|
|
||||||
std::cout << " Unknown1: " << data->mUnk1 << std::endl;
|
|
||||||
std::cout << " Unknown2: " << static_cast<unsigned>(data->mUnk2) << std::endl;
|
|
||||||
}
|
}
|
||||||
mData.unloadData();
|
mData.unloadData();
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
|
@ -1138,7 +1134,6 @@ namespace EsmTool
|
||||||
std::cout << " Coordinates: (" << point.mX << "," << point.mY << "," << point.mZ << ")" << std::endl;
|
std::cout << " Coordinates: (" << point.mX << "," << point.mY << "," << point.mZ << ")" << std::endl;
|
||||||
std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl;
|
std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl;
|
||||||
std::cout << " Connections: " << (int)point.mConnectionNum << std::endl;
|
std::cout << " Connections: " << (int)point.mConnectionNum << std::endl;
|
||||||
std::cout << " Unknown: " << point.mUnknown << std::endl;
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ if (WIN32)
|
||||||
INSTALL(TARGETS openmw-essimporter RUNTIME DESTINATION ".")
|
INSTALL(TARGETS openmw-essimporter RUNTIME DESTINATION ".")
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-essimporter PRIVATE
|
target_precompile_headers(openmw-essimporter PRIVATE
|
||||||
<algorithm>
|
<algorithm>
|
||||||
<filesystem>
|
<filesystem>
|
||||||
|
|
|
@ -232,7 +232,7 @@ namespace ESSImport
|
||||||
esm.skip(4);
|
esm.skip(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.getExact(nam8, 32);
|
esm.getT(nam8);
|
||||||
|
|
||||||
newcell.mFogOfWar.reserve(16 * 16);
|
newcell.mFogOfWar.reserve(16 * 16);
|
||||||
for (int x = 0; x < 16; ++x)
|
for (int x = 0; x < 16; ++x)
|
||||||
|
|
|
@ -1,10 +1,30 @@
|
||||||
#include "importcellref.hpp"
|
#include "importcellref.hpp"
|
||||||
|
|
||||||
#include <components/esm3/esmreader.hpp>
|
#include <components/esm3/esmreader.hpp>
|
||||||
|
#include <components/misc/concepts.hpp>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
{
|
{
|
||||||
|
template <Misc::SameAsWithoutCvref<ACDT> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
f(v.mUnknown, v.mFlags, v.mBreathMeter, v.mUnknown2, v.mDynamic, v.mUnknown3, v.mAttributes, v.mMagicEffects,
|
||||||
|
v.mUnknown4, v.mGoldPool, v.mCountDown, v.mUnknown5);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Misc::SameAsWithoutCvref<ACSC> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
f(v.mUnknown1, v.mFlags, v.mUnknown2, v.mCorpseClearCountdown, v.mUnknown3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Misc::SameAsWithoutCvref<ANIS> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
f(v.mGroupIndex, v.mUnknown, v.mTime);
|
||||||
|
}
|
||||||
|
|
||||||
void CellRef::load(ESM::ESMReader& esm)
|
void CellRef::load(ESM::ESMReader& esm)
|
||||||
{
|
{
|
||||||
|
@ -45,14 +65,9 @@ namespace ESSImport
|
||||||
bool isDeleted = false;
|
bool isDeleted = false;
|
||||||
ESM::CellRef::loadData(esm, isDeleted);
|
ESM::CellRef::loadData(esm, isDeleted);
|
||||||
|
|
||||||
mActorData.mHasACDT
|
mActorData.mHasACDT = esm.getOptionalComposite("ACDT", mActorData.mACDT);
|
||||||
= esm.getHNOT("ACDT", mActorData.mACDT.mUnknown, mActorData.mACDT.mFlags, mActorData.mACDT.mBreathMeter,
|
|
||||||
mActorData.mACDT.mUnknown2, mActorData.mACDT.mDynamic, mActorData.mACDT.mUnknown3,
|
|
||||||
mActorData.mACDT.mAttributes, mActorData.mACDT.mMagicEffects, mActorData.mACDT.mUnknown4,
|
|
||||||
mActorData.mACDT.mGoldPool, mActorData.mACDT.mCountDown, mActorData.mACDT.mUnknown5);
|
|
||||||
|
|
||||||
mActorData.mHasACSC = esm.getHNOT("ACSC", mActorData.mACSC.mUnknown1, mActorData.mACSC.mFlags,
|
mActorData.mHasACSC = esm.getOptionalComposite("ACSC", mActorData.mACSC);
|
||||||
mActorData.mACSC.mUnknown2, mActorData.mACSC.mCorpseClearCountdown, mActorData.mACSC.mUnknown3);
|
|
||||||
|
|
||||||
if (esm.isNextSub("ACSL"))
|
if (esm.isNextSub("ACSL"))
|
||||||
esm.skipHSubSize(112);
|
esm.skipHSubSize(112);
|
||||||
|
@ -127,8 +142,7 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("ND3D"))
|
if (esm.isNextSub("ND3D"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
mActorData.mHasANIS
|
mActorData.mHasANIS = esm.getOptionalComposite("ANIS", mActorData.mANIS);
|
||||||
= esm.getHNOT("ANIS", mActorData.mANIS.mGroupIndex, mActorData.mANIS.mUnknown, mActorData.mANIS.mTime);
|
|
||||||
|
|
||||||
if (esm.isNextSub("LVCR"))
|
if (esm.isNextSub("LVCR"))
|
||||||
{
|
{
|
||||||
|
@ -146,7 +160,7 @@ namespace ESSImport
|
||||||
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
||||||
// alarmvoi0000.ess
|
// alarmvoi0000.ess
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
esm.getHNOT("DATA", mPos.pos, mPos.rot);
|
esm.getOptionalComposite("DATA", mPos);
|
||||||
|
|
||||||
mDeleted = 0;
|
mDeleted = 0;
|
||||||
if (esm.isNextSub("DELE"))
|
if (esm.isNextSub("DELE"))
|
||||||
|
|
|
@ -135,7 +135,7 @@ namespace ESSImport
|
||||||
sub.mFileOffset = esm.getFileOffset();
|
sub.mFileOffset = esm.getFileOffset();
|
||||||
sub.mName = esm.retSubName().toString();
|
sub.mName = esm.retSubName().toString();
|
||||||
sub.mData.resize(esm.getSubSize());
|
sub.mData.resize(esm.getSubSize());
|
||||||
esm.getExact(&sub.mData[0], sub.mData.size());
|
esm.getExact(sub.mData.data(), sub.mData.size());
|
||||||
rec.mSubrecords.push_back(sub);
|
rec.mSubrecords.push_back(sub);
|
||||||
}
|
}
|
||||||
file.mRecords.push_back(rec);
|
file.mRecords.push_back(rec);
|
||||||
|
|
|
@ -94,7 +94,7 @@ if(USE_QT)
|
||||||
set_property(TARGET openmw-launcher PROPERTY AUTOMOC ON)
|
set_property(TARGET openmw-launcher PROPERTY AUTOMOC ON)
|
||||||
endif(USE_QT)
|
endif(USE_QT)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-launcher PRIVATE
|
target_precompile_headers(openmw-launcher PRIVATE
|
||||||
<boost/program_options/options_description.hpp>
|
<boost/program_options/options_description.hpp>
|
||||||
|
|
||||||
|
|
|
@ -819,7 +819,7 @@ void Launcher::DataFilesPage::addArchivesFromDir(const QString& path)
|
||||||
for (const auto& fileinfo : dir.entryInfoList(archiveFilter))
|
for (const auto& fileinfo : dir.entryInfoList(archiveFilter))
|
||||||
{
|
{
|
||||||
const auto absPath = fileinfo.absoluteFilePath();
|
const auto absPath = fileinfo.absoluteFilePath();
|
||||||
if (Bsa::BSAFile::detectVersion(Files::pathFromQString(absPath)) == Bsa::BSAVER_UNKNOWN)
|
if (Bsa::BSAFile::detectVersion(Files::pathFromQString(absPath)) == Bsa::BsaVersion::Unknown)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto fileName = fileinfo.fileName();
|
const auto fileName = fileinfo.fileName();
|
||||||
|
|
|
@ -193,8 +193,10 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
loadSettingBool(Settings::game().mSmoothMovement, *smoothMovementCheckBox);
|
loadSettingBool(Settings::game().mSmoothMovement, *smoothMovementCheckBox);
|
||||||
loadSettingBool(Settings::game().mPlayerMovementIgnoresAnimation, *playerMovementIgnoresAnimationCheckBox);
|
loadSettingBool(Settings::game().mPlayerMovementIgnoresAnimation, *playerMovementIgnoresAnimationCheckBox);
|
||||||
|
|
||||||
distantLandCheckBox->setCheckState(
|
connect(distantLandCheckBox, &QCheckBox::toggled, this, &SettingsPage::slotDistantLandToggled);
|
||||||
Settings::terrain().mDistantTerrain && Settings::terrain().mObjectPaging ? Qt::Checked : Qt::Unchecked);
|
bool distantLandEnabled = Settings::terrain().mDistantTerrain && Settings::terrain().mObjectPaging;
|
||||||
|
distantLandCheckBox->setCheckState(distantLandEnabled ? Qt::Checked : Qt::Unchecked);
|
||||||
|
slotDistantLandToggled(distantLandEnabled);
|
||||||
|
|
||||||
loadSettingBool(Settings::terrain().mObjectPagingActiveGrid, *activeGridObjectPagingCheckBox);
|
loadSettingBool(Settings::terrain().mObjectPagingActiveGrid, *activeGridObjectPagingCheckBox);
|
||||||
viewingDistanceComboBox->setValue(convertToCells(Settings::camera().mViewingDistance));
|
viewingDistanceComboBox->setValue(convertToCells(Settings::camera().mViewingDistance));
|
||||||
|
@ -244,6 +246,11 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes));
|
int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes));
|
||||||
if (shadowResIndex != -1)
|
if (shadowResIndex != -1)
|
||||||
shadowResolutionComboBox->setCurrentIndex(shadowResIndex);
|
shadowResolutionComboBox->setCurrentIndex(shadowResIndex);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shadowResolutionComboBox->addItem(QString::number(shadowRes));
|
||||||
|
shadowResolutionComboBox->setCurrentIndex(shadowResolutionComboBox->count() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
connect(shadowDistanceCheckBox, &QCheckBox::toggled, this, &SettingsPage::slotShadowDistLimitToggled);
|
connect(shadowDistanceCheckBox, &QCheckBox::toggled, this, &SettingsPage::slotShadowDistLimitToggled);
|
||||||
|
|
||||||
|
@ -583,9 +590,16 @@ void Launcher::SettingsPage::slotShadowDistLimitToggled(bool checked)
|
||||||
fadeStartSpinBox->setEnabled(checked);
|
fadeStartSpinBox->setEnabled(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::slotDistantLandToggled(bool checked)
|
||||||
|
{
|
||||||
|
activeGridObjectPagingCheckBox->setEnabled(checked);
|
||||||
|
objectPagingMinSizeComboBox->setEnabled(checked);
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::SettingsPage::slotLightTypeCurrentIndexChanged(int index)
|
void Launcher::SettingsPage::slotLightTypeCurrentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
lightsMaximumDistanceSpinBox->setEnabled(index != 0);
|
lightsMaximumDistanceSpinBox->setEnabled(index != 0);
|
||||||
|
lightFadeMultiplierSpinBox->setEnabled(index != 0);
|
||||||
lightsMaxLightsSpinBox->setEnabled(index != 0);
|
lightsMaxLightsSpinBox->setEnabled(index != 0);
|
||||||
lightsBoundingSphereMultiplierSpinBox->setEnabled(index != 0);
|
lightsBoundingSphereMultiplierSpinBox->setEnabled(index != 0);
|
||||||
lightsMinimumInteriorBrightnessSpinBox->setEnabled(index != 0);
|
lightsMinimumInteriorBrightnessSpinBox->setEnabled(index != 0);
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace Launcher
|
||||||
void slotPostProcessToggled(bool checked);
|
void slotPostProcessToggled(bool checked);
|
||||||
void slotSkyBlendingToggled(bool checked);
|
void slotSkyBlendingToggled(bool checked);
|
||||||
void slotShadowDistLimitToggled(bool checked);
|
void slotShadowDistLimitToggled(bool checked);
|
||||||
|
void slotDistantLandToggled(bool checked);
|
||||||
void slotLightTypeCurrentIndexChanged(int index);
|
void slotLightTypeCurrentIndexChanged(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -652,45 +652,6 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="terrainLayout" columnstretch="0,0">
|
<layout class="QGridLayout" name="terrainLayout" columnstretch="0,0">
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="distantLandCheckBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>If true, use paging and LOD algorithms to display the entire terrain. If false, only display terrain of the loaded cells.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Distant land</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QDoubleSpinBox" name="viewingDistanceComboBox">
|
|
||||||
<property name="decimals">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string> cells</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.125000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<spacer name="verticalSpacer_15">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="objectPagingMinSizeLabel">
|
<widget class="QLabel" name="objectPagingMinSizeLabel">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Controls how large an object must be to be visible in the scene. The object’s size is divided by its distance to the camera and the result of the division is compared with this value. The smaller this value is, the more objects you will see in the scene.</p></body></html></string>
|
<string><html><head/><body><p>Controls how large an object must be to be visible in the scene. The object’s size is divided by its distance to the camera and the result of the division is compared with this value. The smaller this value is, the more objects you will see in the scene.</p></body></html></string>
|
||||||
|
@ -700,14 +661,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="4" column="1">
|
||||||
<widget class="QLabel" name="viewingDistanceLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Viewing distance</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QDoubleSpinBox" name="objectPagingMinSizeComboBox">
|
<widget class="QDoubleSpinBox" name="objectPagingMinSizeComboBox">
|
||||||
<property name="decimals">
|
<property name="decimals">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
|
@ -723,7 +677,53 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="viewingDistanceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Viewing distance</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="viewingDistanceComboBox">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> cells</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.125000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<spacer name="verticalSpacer_15">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="distantLandCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>If true, use paging and LOD algorithms to display the entire terrain. If false, only display terrain of the loaded cells.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Distant land</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="activeGridObjectPagingCheckBox">
|
<widget class="QCheckBox" name="activeGridObjectPagingCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Use object paging for active cells grid.</p></body></html></string>
|
<string><html><head/><body><p>Use object paging for active cells grid.</p></body></html></string>
|
||||||
|
@ -869,6 +869,9 @@
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>81920</number>
|
<number>81920</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>8192</number>
|
<number>8192</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -972,6 +975,9 @@
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<double>0.900000000000000</double>
|
<double>0.900000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1027,7 +1033,7 @@
|
||||||
<string><html><head/><body><p>Maximum distance at which lights will appear (measured in units).</p><p>Set this to 0 to use an unlimited distance.</p></body></html></string>
|
<string><html><head/><body><p>Maximum distance at which lights will appear (measured in units).</p><p>Set this to 0 to use an unlimited distance.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Lights maximum distance</string>
|
<string>Maximum light distance</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1050,7 +1056,7 @@
|
||||||
<string><html><head/><body><p>Maximum number of lights per object.</p><p>A low number near default will cause light popping similar to what you would see with legacy lighting.</p></body></html></string>
|
<string><html><head/><body><p>Maximum number of lights per object.</p><p>A low number near default will cause light popping similar to what you would see with legacy lighting.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Max light sources</string>
|
<string>Max lights</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1060,7 +1066,7 @@
|
||||||
<string><html><head/><body><p>Fraction of maximum distance at which lights will start to fade.</p><p>Set this to a low value for slower transitions or a high value for quicker transitions.</p></body></html></string>
|
<string><html><head/><body><p>Fraction of maximum distance at which lights will start to fade.</p><p>Set this to a low value for slower transitions or a high value for quicker transitions.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Lights fade multiplier</string>
|
<string>Fade start multiplier</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1102,7 +1108,7 @@
|
||||||
<string><html><head/><body><p>Multipler for bounding sphere of lights.</p><p>Higher numbers allows for smooth falloff but require an increase in number of max lights.</p><p>Does not effect the illumination or strength of lights.</p></body></html></string>
|
<string><html><head/><body><p>Multipler for bounding sphere of lights.</p><p>Higher numbers allows for smooth falloff but require an increase in number of max lights.</p><p>Does not effect the illumination or strength of lights.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Lights bounding sphere multiplier</string>
|
<string>Bounding sphere multiplier</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1112,7 +1118,7 @@
|
||||||
<string><html><head/><body><p>Minimum ambient interior brightness.</p><p>Increase this if you feel interiors are too dark.</p></body></html></string>
|
<string><html><head/><body><p>Minimum ambient interior brightness.</p><p>Increase this if you feel interiors are too dark.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Lights minimum interior brightness</string>
|
<string>Minimum interior brightness</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1323,7 +1329,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item>
|
||||||
<widget class="QCheckBox" name="cameraListenerCheckBox">
|
<widget class="QCheckBox" name="cameraListenerCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
|
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
|
||||||
|
|
|
@ -33,7 +33,7 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(openmw-iniimporter gcov)
|
target_link_libraries(openmw-iniimporter gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-iniimporter PRIVATE
|
target_precompile_headers(openmw-iniimporter PRIVATE
|
||||||
<string>
|
<string>
|
||||||
<vector>
|
<vector>
|
||||||
|
|
|
@ -21,7 +21,7 @@ if (WIN32)
|
||||||
install(TARGETS openmw-navmeshtool RUNTIME DESTINATION ".")
|
install(TARGETS openmw-navmeshtool RUNTIME DESTINATION ".")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-navmeshtool PRIVATE
|
target_precompile_headers(openmw-navmeshtool PRIVATE
|
||||||
<algorithm>
|
<algorithm>
|
||||||
<memory>
|
<memory>
|
||||||
|
|
|
@ -17,6 +17,6 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(niftest gcov)
|
target_link_libraries(niftest gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(niftest PRIVATE <filesystem>)
|
target_precompile_headers(niftest PRIVATE <filesystem>)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -42,29 +42,10 @@ bool isBSA(const std::filesystem::path& filename)
|
||||||
return hasExtension(filename, ".bsa") || hasExtension(filename, ".ba2");
|
return hasExtension(filename, ".bsa") || hasExtension(filename, ".ba2");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VFS::Archive> makeBsaArchive(const std::filesystem::path& path)
|
|
||||||
{
|
|
||||||
switch (Bsa::BSAFile::detectVersion(path))
|
|
||||||
{
|
|
||||||
case Bsa::BSAVER_COMPRESSED:
|
|
||||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_COMPRESSED>::type>(path);
|
|
||||||
case Bsa::BSAVER_BA2_GNRL:
|
|
||||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_GNRL>::type>(path);
|
|
||||||
case Bsa::BSAVER_BA2_DX10:
|
|
||||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_BA2_DX10>::type>(path);
|
|
||||||
case Bsa::BSAVER_UNCOMPRESSED:
|
|
||||||
return std::make_unique<VFS::ArchiveSelector<Bsa::BSAVER_UNCOMPRESSED>::type>(path);
|
|
||||||
case Bsa::BSAVER_UNKNOWN:
|
|
||||||
default:
|
|
||||||
std::cerr << "'" << Files::pathToUnicodeString(path) << "' is not a recognized BSA archive" << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
|
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
if (isBSA(path))
|
if (isBSA(path))
|
||||||
return makeBsaArchive(path);
|
return VFS::makeBsaArchive(path);
|
||||||
if (std::filesystem::is_directory(path))
|
if (std::filesystem::is_directory(path))
|
||||||
return std::make_unique<VFS::FileSystemArchive>(path);
|
return std::make_unique<VFS::FileSystemArchive>(path);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -84,10 +65,10 @@ void readNIF(
|
||||||
std::cout << " from '" << Files::pathToUnicodeString(isBSA(source) ? source.filename() : source) << "'";
|
std::cout << " from '" << Files::pathToUnicodeString(isBSA(source) ? source.filename() : source) << "'";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
std::filesystem::path fullPath = !source.empty() ? source / path : path;
|
const std::filesystem::path fullPath = !source.empty() ? source / path : path;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Nif::NIFFile file(fullPath);
|
Nif::NIFFile file(Files::pathToUnicodeString(fullPath));
|
||||||
Nif::Reader reader(file, nullptr);
|
Nif::Reader reader(file, nullptr);
|
||||||
if (vfs != nullptr)
|
if (vfs != nullptr)
|
||||||
reader.parse(vfs->get(pathStr));
|
reader.parse(vfs->get(pathStr));
|
||||||
|
@ -124,17 +105,23 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
|
||||||
|
|
||||||
if (!archivePath.empty() && !isBSA(archivePath))
|
if (!archivePath.empty() && !isBSA(archivePath))
|
||||||
{
|
{
|
||||||
Files::PathContainer dataDirs = { archivePath };
|
const Files::Collections fileCollections({ archivePath });
|
||||||
const Files::Collections fileCollections = Files::Collections(dataDirs);
|
|
||||||
const Files::MultiDirCollection& bsaCol = fileCollections.getCollection(".bsa");
|
const Files::MultiDirCollection& bsaCol = fileCollections.getCollection(".bsa");
|
||||||
const Files::MultiDirCollection& ba2Col = fileCollections.getCollection(".ba2");
|
const Files::MultiDirCollection& ba2Col = fileCollections.getCollection(".ba2");
|
||||||
for (auto& file : bsaCol)
|
for (const Files::MultiDirCollection& collection : { bsaCol, ba2Col })
|
||||||
{
|
{
|
||||||
readVFS(makeBsaArchive(file.second), file.second, quiet);
|
for (auto& file : collection)
|
||||||
}
|
{
|
||||||
for (auto& file : ba2Col)
|
try
|
||||||
{
|
{
|
||||||
readVFS(makeBsaArchive(file.second), file.second, quiet);
|
readVFS(VFS::makeBsaArchive(file.second), file.second, quiet);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to read archive file '" << Files::pathToUnicodeString(file.second)
|
||||||
|
<< "': " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(openmw-cs-lib gcov)
|
target_link_libraries(openmw-cs-lib gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-cs-lib PRIVATE
|
target_precompile_headers(openmw-cs-lib PRIVATE
|
||||||
<boost/program_options/options_description.hpp>
|
<boost/program_options/options_description.hpp>
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform(int stage, Messages& messages
|
||||||
if (topic.mState == CSMWorld::RecordBase::State_Deleted)
|
if (topic.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
{
|
{
|
||||||
// if the topic is deleted, we do not need to bother with INFO records.
|
// if the topic is deleted, we do not need to bother with INFO records.
|
||||||
ESM::Dialogue dialogue = topic.get();
|
const ESM::Dialogue& dialogue = topic.get();
|
||||||
writer.startRecord(dialogue.sRecordId);
|
writer.startRecord(dialogue.sRecordId);
|
||||||
dialogue.save(writer, true);
|
dialogue.save(writer, true);
|
||||||
writer.endRecord(dialogue.sRecordId);
|
writer.endRecord(dialogue.sRecordId);
|
||||||
|
@ -187,6 +187,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform(int stage, Messages& messages
|
||||||
{
|
{
|
||||||
ESM::DialInfo info = record.get();
|
ESM::DialInfo info = record.get();
|
||||||
info.mId = record.get().mOriginalId;
|
info.mId = record.get().mOriginalId;
|
||||||
|
info.mData.mType = topic.get().mType;
|
||||||
|
|
||||||
if (iter == infos.begin())
|
if (iter == infos.begin())
|
||||||
info.mPrev = ESM::RefId();
|
info.mPrev = ESM::RefId();
|
||||||
|
|
|
@ -452,7 +452,10 @@ std::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseText()
|
||||||
return std::shared_ptr<Node>();
|
return std::shared_ptr<Node>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<TextNode>(columnId, text);
|
auto node = std::make_shared<TextNode>(columnId, text);
|
||||||
|
if (!node->isValid())
|
||||||
|
error();
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseValue()
|
std::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseValue()
|
||||||
|
|
|
@ -34,6 +34,8 @@ namespace CSMFilter
|
||||||
///< Return a string that represents this node.
|
///< Return a string that represents this node.
|
||||||
///
|
///
|
||||||
/// \param numericColumns Use numeric IDs instead of string to represent columns.
|
/// \param numericColumns Use numeric IDs instead of string to represent columns.
|
||||||
|
|
||||||
|
bool isValid() { return mRegExp.isValid(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ void CSMPrefs::State::declare()
|
||||||
.setTooltip(
|
.setTooltip(
|
||||||
"When editing a record, open the view in a new window,"
|
"When editing a record, open the view in a new window,"
|
||||||
" rather than docked in the main view.");
|
" rather than docked in the main view.");
|
||||||
|
declareInt(mValues->mIdTables.mFilterDelay, "Delay before applying a filter (in miliseconds)");
|
||||||
|
|
||||||
declareCategory("ID Dialogues");
|
declareCategory("ID Dialogues");
|
||||||
declareBool(mValues->mIdDialogues.mToolbar, "Show toolbar");
|
declareBool(mValues->mIdDialogues.mToolbar, "Show toolbar");
|
||||||
|
|
|
@ -138,6 +138,7 @@ namespace CSMPrefs
|
||||||
EnumSettingValue mJumpToAdded{ mIndex, sName, "jump-to-added", sJumpAndSelectValues, 0 };
|
EnumSettingValue mJumpToAdded{ mIndex, sName, "jump-to-added", sJumpAndSelectValues, 0 };
|
||||||
Settings::SettingValue<bool> mExtendedConfig{ mIndex, sName, "extended-config", false };
|
Settings::SettingValue<bool> mExtendedConfig{ mIndex, sName, "extended-config", false };
|
||||||
Settings::SettingValue<bool> mSubviewNewWindow{ mIndex, sName, "subview-new-window", false };
|
Settings::SettingValue<bool> mSubviewNewWindow{ mIndex, sName, "subview-new-window", false };
|
||||||
|
Settings::SettingValue<int> mFilterDelay{ mIndex, sName, "filter-delay", 500 };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IdDialoguesCategory : Settings::WithIndex
|
struct IdDialoguesCategory : Settings::WithIndex
|
||||||
|
|
|
@ -60,38 +60,38 @@ void CSMTools::EnchantmentCheckStage::perform(int stage, CSMDoc::Messages& messa
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<ESM::ENAMstruct>::const_iterator effect = enchantment.mEffects.mList.begin();
|
std::vector<ESM::IndexedENAMstruct>::const_iterator effect = enchantment.mEffects.mList.begin();
|
||||||
|
|
||||||
for (size_t i = 1; i <= enchantment.mEffects.mList.size(); i++)
|
for (size_t i = 1; i <= enchantment.mEffects.mList.size(); i++)
|
||||||
{
|
{
|
||||||
const std::string number = std::to_string(i);
|
const std::string number = std::to_string(i);
|
||||||
// At the time of writing this effects, attributes and skills are hardcoded
|
// At the time of writing this effects, attributes and skills are hardcoded
|
||||||
if (effect->mEffectID < 0 || effect->mEffectID > 142)
|
if (effect->mData.mEffectID < 0 || effect->mData.mEffectID > 142)
|
||||||
{
|
{
|
||||||
messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error);
|
messages.add(id, "Effect #" + number + " is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
++effect;
|
++effect;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effect->mSkill < -1 || effect->mSkill > 26)
|
if (effect->mData.mSkill < -1 || effect->mData.mSkill > 26)
|
||||||
messages.add(
|
messages.add(
|
||||||
id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error);
|
id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mAttribute < -1 || effect->mAttribute > 7)
|
if (effect->mData.mAttribute < -1 || effect->mData.mAttribute > 7)
|
||||||
messages.add(
|
messages.add(
|
||||||
id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error);
|
id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mRange < 0 || effect->mRange > 2)
|
if (effect->mData.mRange < 0 || effect->mData.mRange > 2)
|
||||||
messages.add(id, "Effect #" + number + " range is invalid", "", CSMDoc::Message::Severity_Error);
|
messages.add(id, "Effect #" + number + " range is invalid", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mArea < 0)
|
if (effect->mData.mArea < 0)
|
||||||
messages.add(id, "Effect #" + number + " area is negative", "", CSMDoc::Message::Severity_Error);
|
messages.add(id, "Effect #" + number + " area is negative", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mDuration < 0)
|
if (effect->mData.mDuration < 0)
|
||||||
messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error);
|
messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mMagnMin < 0)
|
if (effect->mData.mMagnMin < 0)
|
||||||
messages.add(
|
messages.add(
|
||||||
id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error);
|
id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mMagnMax < 0)
|
if (effect->mData.mMagnMax < 0)
|
||||||
messages.add(
|
messages.add(
|
||||||
id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error);
|
id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error);
|
||||||
if (effect->mMagnMin > effect->mMagnMax)
|
if (effect->mData.mMagnMin > effect->mData.mMagnMax)
|
||||||
messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "",
|
messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "",
|
||||||
CSMDoc::Message::Severity_Error);
|
CSMDoc::Message::Severity_Error);
|
||||||
++effect;
|
++effect;
|
||||||
|
|
|
@ -58,7 +58,12 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages& messa
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ESM::MagicEffect effect = record.get();
|
ESM::MagicEffect effect = record.get();
|
||||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, effect.mId);
|
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_MagicEffect, CSMWorld::getRecordId(effect));
|
||||||
|
|
||||||
|
if (effect.mData.mSpeed <= 0.0f)
|
||||||
|
{
|
||||||
|
messages.add(id, "Speed is less than or equal to zero", "", CSMDoc::Message::Severity_Error);
|
||||||
|
}
|
||||||
|
|
||||||
if (effect.mDescription.empty())
|
if (effect.mDescription.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -971,7 +971,7 @@ namespace CSMWorld
|
||||||
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||||
{
|
{
|
||||||
ESXRecordT record2 = record.get();
|
ESXRecordT record2 = record.get();
|
||||||
record2.mScale = data.toFloat();
|
record2.mScale = std::clamp(data.toFloat(), 0.5f, 2.0f);
|
||||||
record.setModified(record2);
|
record.setModified(record2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,8 +1136,8 @@ namespace CSMWorld
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
struct TeleportColumn : public Column<ESXRecordT>
|
struct TeleportColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
TeleportColumn()
|
TeleportColumn(int flags)
|
||||||
: Column<ESXRecordT>(Columns::ColumnId_Teleport, ColumnBase::Display_Boolean)
|
: Column<ESXRecordT>(Columns::ColumnId_Teleport, ColumnBase::Display_Boolean, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,6 +1165,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
QVariant get(const Record<ESXRecordT>& record) const override
|
QVariant get(const Record<ESXRecordT>& record) const override
|
||||||
{
|
{
|
||||||
|
if (!record.get().mTeleport)
|
||||||
|
return QVariant();
|
||||||
return QString::fromUtf8(record.get().mDestCell.c_str());
|
return QString::fromUtf8(record.get().mDestCell.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,6 +1184,26 @@ namespace CSMWorld
|
||||||
bool isUserEditable() const override { return true; }
|
bool isUserEditable() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ESXRecordT>
|
||||||
|
struct IsLockedColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
IsLockedColumn(int flags)
|
||||||
|
: Column<ESXRecordT>(Columns::ColumnId_IsLocked, ColumnBase::Display_Boolean, flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant get(const Record<ESXRecordT>& record) const override { return record.get().mIsLocked; }
|
||||||
|
|
||||||
|
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
record2.mIsLocked = data.toBool();
|
||||||
|
record.setModified(record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEditable() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
struct LockLevelColumn : public Column<ESXRecordT>
|
struct LockLevelColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
|
@ -1190,7 +1212,12 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant get(const Record<ESXRecordT>& record) const override { return record.get().mLockLevel; }
|
QVariant get(const Record<ESXRecordT>& record) const override
|
||||||
|
{
|
||||||
|
if (record.get().mIsLocked)
|
||||||
|
return record.get().mLockLevel;
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||||
{
|
{
|
||||||
|
@ -1212,7 +1239,9 @@ namespace CSMWorld
|
||||||
|
|
||||||
QVariant get(const Record<ESXRecordT>& record) const override
|
QVariant get(const Record<ESXRecordT>& record) const override
|
||||||
{
|
{
|
||||||
return QString::fromUtf8(record.get().mKey.getRefIdString().c_str());
|
if (record.get().mIsLocked)
|
||||||
|
return QString::fromUtf8(record.get().mKey.getRefIdString().c_str());
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||||
|
@ -1282,17 +1311,21 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESM::Position ESXRecordT::*mPosition;
|
ESM::Position ESXRecordT::*mPosition;
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
bool mIsDoor;
|
||||||
|
|
||||||
PosColumn(ESM::Position ESXRecordT::*position, int index, bool door)
|
PosColumn(ESM::Position ESXRecordT::*position, int index, bool door)
|
||||||
: Column<ESXRecordT>((door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos) + index,
|
: Column<ESXRecordT>((door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos) + index,
|
||||||
ColumnBase::Display_Float)
|
ColumnBase::Display_Float)
|
||||||
, mPosition(position)
|
, mPosition(position)
|
||||||
, mIndex(index)
|
, mIndex(index)
|
||||||
|
, mIsDoor(door)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant get(const Record<ESXRecordT>& record) const override
|
QVariant get(const Record<ESXRecordT>& record) const override
|
||||||
{
|
{
|
||||||
|
if (!record.get().mTeleport && mIsDoor)
|
||||||
|
return QVariant();
|
||||||
const ESM::Position& position = record.get().*mPosition;
|
const ESM::Position& position = record.get().*mPosition;
|
||||||
return position.pos[mIndex];
|
return position.pos[mIndex];
|
||||||
}
|
}
|
||||||
|
@ -1316,17 +1349,21 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESM::Position ESXRecordT::*mPosition;
|
ESM::Position ESXRecordT::*mPosition;
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
bool mIsDoor;
|
||||||
|
|
||||||
RotColumn(ESM::Position ESXRecordT::*position, int index, bool door)
|
RotColumn(ESM::Position ESXRecordT::*position, int index, bool door)
|
||||||
: Column<ESXRecordT>((door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot) + index,
|
: Column<ESXRecordT>((door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot) + index,
|
||||||
ColumnBase::Display_Double)
|
ColumnBase::Display_Double)
|
||||||
, mPosition(position)
|
, mPosition(position)
|
||||||
, mIndex(index)
|
, mIndex(index)
|
||||||
|
, mIsDoor(door)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant get(const Record<ESXRecordT>& record) const override
|
QVariant get(const Record<ESXRecordT>& record) const override
|
||||||
{
|
{
|
||||||
|
if (!record.get().mTeleport && mIsDoor)
|
||||||
|
return QVariant();
|
||||||
const ESM::Position& position = record.get().*mPosition;
|
const ESM::Position& position = record.get().*mPosition;
|
||||||
return osg::RadiansToDegrees(position.rot[mIndex]);
|
return osg::RadiansToDegrees(position.rot[mIndex]);
|
||||||
}
|
}
|
||||||
|
@ -2052,6 +2089,26 @@ namespace CSMWorld
|
||||||
bool isEditable() const override { return true; }
|
bool isEditable() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ESXRecordT>
|
||||||
|
struct ProjectileSpeedColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
ProjectileSpeedColumn()
|
||||||
|
: Column<ESXRecordT>(Columns::ColumnId_ProjectileSpeed, ColumnBase::Display_Float)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant get(const Record<ESXRecordT>& record) const override { return record.get().mData.mSpeed; }
|
||||||
|
|
||||||
|
void set(Record<ESXRecordT>& record, const QVariant& data) override
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
record2.mData.mSpeed = data.toFloat();
|
||||||
|
record.setModified(record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEditable() const override { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
struct SchoolColumn : public Column<ESXRecordT>
|
struct SchoolColumn : public Column<ESXRecordT>
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,8 +57,10 @@ namespace CSMWorld
|
||||||
{ ColumnId_Charges, "Charges" },
|
{ ColumnId_Charges, "Charges" },
|
||||||
{ ColumnId_Enchantment, "Enchantment" },
|
{ ColumnId_Enchantment, "Enchantment" },
|
||||||
{ ColumnId_StackCount, "Count" },
|
{ ColumnId_StackCount, "Count" },
|
||||||
|
{ ColumnId_GoldValue, "Value" },
|
||||||
{ ColumnId_Teleport, "Teleport" },
|
{ ColumnId_Teleport, "Teleport" },
|
||||||
{ ColumnId_TeleportCell, "Teleport Cell" },
|
{ ColumnId_TeleportCell, "Teleport Cell" },
|
||||||
|
{ ColumnId_IsLocked, "Locked" },
|
||||||
{ ColumnId_LockLevel, "Lock Level" },
|
{ ColumnId_LockLevel, "Lock Level" },
|
||||||
{ ColumnId_Key, "Key" },
|
{ ColumnId_Key, "Key" },
|
||||||
{ ColumnId_Trap, "Trap" },
|
{ ColumnId_Trap, "Trap" },
|
||||||
|
@ -235,6 +237,7 @@ namespace CSMWorld
|
||||||
{ ColumnId_RegionSounds, "Sounds" },
|
{ ColumnId_RegionSounds, "Sounds" },
|
||||||
{ ColumnId_SoundName, "Sound Name" },
|
{ ColumnId_SoundName, "Sound Name" },
|
||||||
{ ColumnId_SoundChance, "Chance" },
|
{ ColumnId_SoundChance, "Chance" },
|
||||||
|
{ ColumnId_SoundProbability, "Probability" },
|
||||||
|
|
||||||
{ ColumnId_FactionReactions, "Reactions" },
|
{ ColumnId_FactionReactions, "Reactions" },
|
||||||
{ ColumnId_FactionRanks, "Ranks" },
|
{ ColumnId_FactionRanks, "Ranks" },
|
||||||
|
@ -376,6 +379,7 @@ namespace CSMWorld
|
||||||
{ ColumnId_Blocked, "Blocked" },
|
{ ColumnId_Blocked, "Blocked" },
|
||||||
|
|
||||||
{ ColumnId_LevelledCreatureId, "Levelled Creature" },
|
{ ColumnId_LevelledCreatureId, "Levelled Creature" },
|
||||||
|
{ ColumnId_ProjectileSpeed, "Projectile Speed" },
|
||||||
|
|
||||||
// end marker
|
// end marker
|
||||||
{ -1, 0 },
|
{ -1, 0 },
|
||||||
|
|
|
@ -349,6 +349,14 @@ namespace CSMWorld
|
||||||
|
|
||||||
ColumnId_SelectionGroupObjects = 316,
|
ColumnId_SelectionGroupObjects = 316,
|
||||||
|
|
||||||
|
ColumnId_SoundProbability = 317,
|
||||||
|
|
||||||
|
ColumnId_IsLocked = 318,
|
||||||
|
|
||||||
|
ColumnId_ProjectileSpeed = 319,
|
||||||
|
|
||||||
|
ColumnId_GoldValue = 320,
|
||||||
|
|
||||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||||
// to extend the number of use values.
|
// to extend the number of use values.
|
||||||
ColumnId_UseValue1 = 0x10000,
|
ColumnId_UseValue1 = 0x10000,
|
||||||
|
|
|
@ -161,7 +161,7 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
defines["radialFog"] = "0";
|
defines["radialFog"] = "0";
|
||||||
defines["lightingModel"] = "0";
|
defines["lightingModel"] = "0";
|
||||||
defines["reverseZ"] = "0";
|
defines["reverseZ"] = "0";
|
||||||
defines["refraction_enabled"] = "0";
|
defines["waterRefraction"] = "0";
|
||||||
for (const auto& define : shadowDefines)
|
for (const auto& define : shadowDefines)
|
||||||
defines[define.first] = define.second;
|
defines[define.first] = define.second;
|
||||||
mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines);
|
mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(defines);
|
||||||
|
@ -301,8 +301,8 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
mRegions.addColumn(new NestedParentColumn<ESM::Region>(Columns::ColumnId_RegionWeather));
|
mRegions.addColumn(new NestedParentColumn<ESM::Region>(Columns::ColumnId_RegionWeather));
|
||||||
index = mRegions.getColumns() - 1;
|
index = mRegions.getColumns() - 1;
|
||||||
mRegions.addAdapter(std::make_pair(&mRegions.getColumn(index), new RegionWeatherAdapter()));
|
mRegions.addAdapter(std::make_pair(&mRegions.getColumn(index), new RegionWeatherAdapter()));
|
||||||
mRegions.getNestableColumn(index)->addColumn(
|
mRegions.getNestableColumn(index)->addColumn(new NestedChildColumn(
|
||||||
new NestedChildColumn(Columns::ColumnId_WeatherName, ColumnBase::Display_String, false));
|
Columns::ColumnId_WeatherName, ColumnBase::Display_String, ColumnBase::Flag_Dialogue, false));
|
||||||
mRegions.getNestableColumn(index)->addColumn(
|
mRegions.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn(Columns::ColumnId_WeatherChance, ColumnBase::Display_UnsignedInteger8));
|
new NestedChildColumn(Columns::ColumnId_WeatherChance, ColumnBase::Display_UnsignedInteger8));
|
||||||
// Region Sounds
|
// Region Sounds
|
||||||
|
@ -313,6 +313,8 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
new NestedChildColumn(Columns::ColumnId_SoundName, ColumnBase::Display_Sound));
|
new NestedChildColumn(Columns::ColumnId_SoundName, ColumnBase::Display_Sound));
|
||||||
mRegions.getNestableColumn(index)->addColumn(
|
mRegions.getNestableColumn(index)->addColumn(
|
||||||
new NestedChildColumn(Columns::ColumnId_SoundChance, ColumnBase::Display_UnsignedInteger8));
|
new NestedChildColumn(Columns::ColumnId_SoundChance, ColumnBase::Display_UnsignedInteger8));
|
||||||
|
mRegions.getNestableColumn(index)->addColumn(new NestedChildColumn(
|
||||||
|
Columns::ColumnId_SoundProbability, ColumnBase::Display_String, ColumnBase::Flag_Dialogue, false));
|
||||||
|
|
||||||
mBirthsigns.addColumn(new StringIdColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn(new StringIdColumn<ESM::BirthSign>);
|
||||||
mBirthsigns.addColumn(new RecordStateColumn<ESM::BirthSign>);
|
mBirthsigns.addColumn(new RecordStateColumn<ESM::BirthSign>);
|
||||||
|
@ -500,6 +502,7 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
mMagicEffects.addColumn(new FixedRecordTypeColumn<ESM::MagicEffect>(UniversalId::Type_MagicEffect));
|
mMagicEffects.addColumn(new FixedRecordTypeColumn<ESM::MagicEffect>(UniversalId::Type_MagicEffect));
|
||||||
mMagicEffects.addColumn(new SchoolColumn<ESM::MagicEffect>);
|
mMagicEffects.addColumn(new SchoolColumn<ESM::MagicEffect>);
|
||||||
mMagicEffects.addColumn(new BaseCostColumn<ESM::MagicEffect>);
|
mMagicEffects.addColumn(new BaseCostColumn<ESM::MagicEffect>);
|
||||||
|
mMagicEffects.addColumn(new ProjectileSpeedColumn<ESM::MagicEffect>);
|
||||||
mMagicEffects.addColumn(new EffectTextureColumn<ESM::MagicEffect>(Columns::ColumnId_Icon));
|
mMagicEffects.addColumn(new EffectTextureColumn<ESM::MagicEffect>(Columns::ColumnId_Icon));
|
||||||
mMagicEffects.addColumn(new EffectTextureColumn<ESM::MagicEffect>(Columns::ColumnId_Particle));
|
mMagicEffects.addColumn(new EffectTextureColumn<ESM::MagicEffect>(Columns::ColumnId_Particle));
|
||||||
mMagicEffects.addColumn(new EffectObjectColumn<ESM::MagicEffect>(Columns::ColumnId_CastingObject));
|
mMagicEffects.addColumn(new EffectObjectColumn<ESM::MagicEffect>(Columns::ColumnId_CastingObject));
|
||||||
|
@ -510,6 +513,7 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_HitSound));
|
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_HitSound));
|
||||||
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_AreaSound));
|
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_AreaSound));
|
||||||
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_BoltSound));
|
mMagicEffects.addColumn(new EffectSoundColumn<ESM::MagicEffect>(Columns::ColumnId_BoltSound));
|
||||||
|
|
||||||
mMagicEffects.addColumn(
|
mMagicEffects.addColumn(
|
||||||
new FlagColumn<ESM::MagicEffect>(Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking));
|
new FlagColumn<ESM::MagicEffect>(Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking));
|
||||||
mMagicEffects.addColumn(
|
mMagicEffects.addColumn(
|
||||||
|
@ -589,7 +593,8 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
mRefs.addColumn(new ChargesColumn<CellRef>);
|
mRefs.addColumn(new ChargesColumn<CellRef>);
|
||||||
mRefs.addColumn(new EnchantmentChargesColumn<CellRef>);
|
mRefs.addColumn(new EnchantmentChargesColumn<CellRef>);
|
||||||
mRefs.addColumn(new StackSizeColumn<CellRef>);
|
mRefs.addColumn(new StackSizeColumn<CellRef>);
|
||||||
mRefs.addColumn(new TeleportColumn<CellRef>);
|
mRefs.addColumn(new TeleportColumn<CellRef>(
|
||||||
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
||||||
mRefs.addColumn(new TeleportCellColumn<CellRef>);
|
mRefs.addColumn(new TeleportCellColumn<CellRef>);
|
||||||
mRefs.addColumn(new PosColumn<CellRef>(&CellRef::mDoorDest, 0, true));
|
mRefs.addColumn(new PosColumn<CellRef>(&CellRef::mDoorDest, 0, true));
|
||||||
mRefs.addColumn(new PosColumn<CellRef>(&CellRef::mDoorDest, 1, true));
|
mRefs.addColumn(new PosColumn<CellRef>(&CellRef::mDoorDest, 1, true));
|
||||||
|
@ -597,6 +602,8 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, const Files::PathContainer& data
|
||||||
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 0, true));
|
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 0, true));
|
||||||
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 1, true));
|
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 1, true));
|
||||||
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 2, true));
|
mRefs.addColumn(new RotColumn<CellRef>(&CellRef::mDoorDest, 2, true));
|
||||||
|
mRefs.addColumn(new IsLockedColumn<CellRef>(
|
||||||
|
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
||||||
mRefs.addColumn(new LockLevelColumn<CellRef>);
|
mRefs.addColumn(new LockLevelColumn<CellRef>);
|
||||||
mRefs.addColumn(new KeyColumn<CellRef>);
|
mRefs.addColumn(new KeyColumn<CellRef>);
|
||||||
mRefs.addColumn(new TrapColumn<CellRef>);
|
mRefs.addColumn(new TrapColumn<CellRef>);
|
||||||
|
|
|
@ -63,9 +63,18 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow(int sourceRow, const QModelIn
|
||||||
|
|
||||||
CSMWorld::IdTableProxyModel::IdTableProxyModel(QObject* parent)
|
CSMWorld::IdTableProxyModel::IdTableProxyModel(QObject* parent)
|
||||||
: QSortFilterProxyModel(parent)
|
: QSortFilterProxyModel(parent)
|
||||||
|
, mFilterTimer{ new QTimer(this) }
|
||||||
, mSourceModel(nullptr)
|
, mSourceModel(nullptr)
|
||||||
{
|
{
|
||||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
mFilterTimer->setSingleShot(true);
|
||||||
|
int intervalSetting = CSMPrefs::State::get()["ID Tables"]["filter-delay"].toInt();
|
||||||
|
mFilterTimer->setInterval(intervalSetting);
|
||||||
|
|
||||||
|
connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this,
|
||||||
|
[this](const CSMPrefs::Setting* setting) { this->settingChanged(setting); });
|
||||||
|
connect(mFilterTimer.get(), &QTimer::timeout, this, [this]() { this->timerTimeout(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex(const std::string& id, int column) const
|
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex(const std::string& id, int column) const
|
||||||
|
@ -87,10 +96,8 @@ void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel* model)
|
||||||
|
|
||||||
void CSMWorld::IdTableProxyModel::setFilter(const std::shared_ptr<CSMFilter::Node>& filter)
|
void CSMWorld::IdTableProxyModel::setFilter(const std::shared_ptr<CSMFilter::Node>& filter)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
mAwaitingFilter = filter;
|
||||||
mFilter = filter;
|
mFilterTimer->start();
|
||||||
updateColumnMap();
|
|
||||||
endResetModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||||
|
@ -131,6 +138,26 @@ void CSMWorld::IdTableProxyModel::refreshFilter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IdTableProxyModel::timerTimeout()
|
||||||
|
{
|
||||||
|
if (mAwaitingFilter)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
mFilter = mAwaitingFilter;
|
||||||
|
updateColumnMap();
|
||||||
|
endResetModel();
|
||||||
|
mAwaitingFilter.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::IdTableProxyModel::settingChanged(const CSMPrefs::Setting* setting)
|
||||||
|
{
|
||||||
|
if (*setting == "ID Tables/filter-delay")
|
||||||
|
{
|
||||||
|
mFilterTimer->setInterval(setting->toInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end)
|
void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end)
|
||||||
{
|
{
|
||||||
refreshFilter();
|
refreshFilter();
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "../prefs/state.hpp"
|
||||||
|
|
||||||
#include "columns.hpp"
|
#include "columns.hpp"
|
||||||
|
|
||||||
|
@ -29,6 +32,8 @@ namespace CSMWorld
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
std::shared_ptr<CSMFilter::Node> mFilter;
|
std::shared_ptr<CSMFilter::Node> mFilter;
|
||||||
|
std::unique_ptr<QTimer> mFilterTimer;
|
||||||
|
std::shared_ptr<CSMFilter::Node> mAwaitingFilter;
|
||||||
std::map<int, int> mColumnMap; // column ID, column index in this model (or -1)
|
std::map<int, int> mColumnMap; // column ID, column index in this model (or -1)
|
||||||
|
|
||||||
// Cache of enum values for enum columns (e.g. Modified, Record Type).
|
// Cache of enum values for enum columns (e.g. Modified, Record Type).
|
||||||
|
@ -68,6 +73,10 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual void sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
virtual void sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void timerTimeout();
|
||||||
|
|
||||||
|
void settingChanged(const CSMPrefs::Setting* setting);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void rowAdded(const std::string& id);
|
void rowAdded(const std::string& id);
|
||||||
|
|
|
@ -38,7 +38,6 @@ namespace CSMWorld
|
||||||
point.mZ = 0;
|
point.mZ = 0;
|
||||||
point.mAutogenerated = 0;
|
point.mAutogenerated = 0;
|
||||||
point.mConnectionNum = 0;
|
point.mConnectionNum = 0;
|
||||||
point.mUnknown = 0;
|
|
||||||
|
|
||||||
points.insert(points.begin() + position, point);
|
points.insert(points.begin() + position, point);
|
||||||
pathgrid.mData.mPoints = pathgrid.mPoints.size();
|
pathgrid.mData.mPoints = pathgrid.mPoints.size();
|
||||||
|
@ -414,20 +413,32 @@ namespace CSMWorld
|
||||||
|
|
||||||
QVariant RegionSoundListAdapter::getData(const Record<ESM::Region>& record, int subRowIndex, int subColIndex) const
|
QVariant RegionSoundListAdapter::getData(const Record<ESM::Region>& record, int subRowIndex, int subColIndex) const
|
||||||
{
|
{
|
||||||
ESM::Region region = record.get();
|
const ESM::Region& region = record.get();
|
||||||
|
|
||||||
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
|
const std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
|
||||||
|
|
||||||
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(soundList.size()))
|
const size_t index = static_cast<size_t>(subRowIndex);
|
||||||
|
if (subRowIndex < 0 || index >= soundList.size())
|
||||||
throw std::runtime_error("index out of range");
|
throw std::runtime_error("index out of range");
|
||||||
|
|
||||||
ESM::Region::SoundRef soundRef = soundList[subRowIndex];
|
const ESM::Region::SoundRef& soundRef = soundList[subRowIndex];
|
||||||
switch (subColIndex)
|
switch (subColIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return QString(soundRef.mSound.getRefIdString().c_str());
|
return QString(soundRef.mSound.getRefIdString().c_str());
|
||||||
case 1:
|
case 1:
|
||||||
return soundRef.mChance;
|
return soundRef.mChance;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
float probability = 1.f;
|
||||||
|
for (size_t i = 0; i < index; ++i)
|
||||||
|
{
|
||||||
|
const float p = std::min(soundList[i].mChance / 100.f, 1.f);
|
||||||
|
probability *= 1.f - p;
|
||||||
|
}
|
||||||
|
probability *= std::min(soundRef.mChance / 100.f, 1.f) * 100.f;
|
||||||
|
return QString("%1%").arg(probability, 0, 'f', 2);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Region sounds subcolumn index out of range");
|
throw std::runtime_error("Region sounds subcolumn index out of range");
|
||||||
}
|
}
|
||||||
|
@ -463,7 +474,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
int RegionSoundListAdapter::getColumnsCount(const Record<ESM::Region>& record) const
|
int RegionSoundListAdapter::getColumnsCount(const Record<ESM::Region>& record) const
|
||||||
{
|
{
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegionSoundListAdapter::getRowsCount(const Record<ESM::Region>& record) const
|
int RegionSoundListAdapter::getRowsCount(const Record<ESM::Region>& record) const
|
||||||
|
@ -996,7 +1007,10 @@ namespace CSMWorld
|
||||||
case 5:
|
case 5:
|
||||||
{
|
{
|
||||||
if (isInterior && interiorWater)
|
if (isInterior && interiorWater)
|
||||||
|
{
|
||||||
cell.mWater = value.toFloat();
|
cell.mWater = value.toFloat();
|
||||||
|
cell.setHasWaterHeightSub(true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return; // return without saving
|
return; // return without saving
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -255,20 +255,22 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESXRecordT magic = record.get();
|
ESXRecordT magic = record.get();
|
||||||
|
|
||||||
std::vector<ESM::ENAMstruct>& effectsList = magic.mEffects.mList;
|
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
|
||||||
|
|
||||||
// blank row
|
// blank row
|
||||||
ESM::ENAMstruct effect;
|
ESM::IndexedENAMstruct effect;
|
||||||
effect.mEffectID = 0;
|
effect.mIndex = position;
|
||||||
effect.mSkill = -1;
|
effect.mData.mEffectID = 0;
|
||||||
effect.mAttribute = -1;
|
effect.mData.mSkill = -1;
|
||||||
effect.mRange = 0;
|
effect.mData.mAttribute = -1;
|
||||||
effect.mArea = 0;
|
effect.mData.mRange = 0;
|
||||||
effect.mDuration = 0;
|
effect.mData.mArea = 0;
|
||||||
effect.mMagnMin = 0;
|
effect.mData.mDuration = 0;
|
||||||
effect.mMagnMax = 0;
|
effect.mData.mMagnMin = 0;
|
||||||
|
effect.mData.mMagnMax = 0;
|
||||||
|
|
||||||
effectsList.insert(effectsList.begin() + position, effect);
|
effectsList.insert(effectsList.begin() + position, effect);
|
||||||
|
magic.mEffects.updateIndexes();
|
||||||
|
|
||||||
record.setModified(magic);
|
record.setModified(magic);
|
||||||
}
|
}
|
||||||
|
@ -277,12 +279,13 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESXRecordT magic = record.get();
|
ESXRecordT magic = record.get();
|
||||||
|
|
||||||
std::vector<ESM::ENAMstruct>& effectsList = magic.mEffects.mList;
|
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
|
||||||
|
|
||||||
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(effectsList.size()))
|
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(effectsList.size()))
|
||||||
throw std::runtime_error("index out of range");
|
throw std::runtime_error("index out of range");
|
||||||
|
|
||||||
effectsList.erase(effectsList.begin() + rowToRemove);
|
effectsList.erase(effectsList.begin() + rowToRemove);
|
||||||
|
magic.mEffects.updateIndexes();
|
||||||
|
|
||||||
record.setModified(magic);
|
record.setModified(magic);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +295,7 @@ namespace CSMWorld
|
||||||
ESXRecordT magic = record.get();
|
ESXRecordT magic = record.get();
|
||||||
|
|
||||||
magic.mEffects.mList
|
magic.mEffects.mList
|
||||||
= static_cast<const NestedTableWrapper<std::vector<ESM::ENAMstruct>>&>(nestedTable).mNestedTable;
|
= static_cast<const NestedTableWrapper<std::vector<ESM::IndexedENAMstruct>>&>(nestedTable).mNestedTable;
|
||||||
|
|
||||||
record.setModified(magic);
|
record.setModified(magic);
|
||||||
}
|
}
|
||||||
|
@ -300,19 +303,19 @@ namespace CSMWorld
|
||||||
NestedTableWrapperBase* table(const Record<ESXRecordT>& record) const override
|
NestedTableWrapperBase* table(const Record<ESXRecordT>& record) const override
|
||||||
{
|
{
|
||||||
// deleted by dtor of NestedTableStoring
|
// deleted by dtor of NestedTableStoring
|
||||||
return new NestedTableWrapper<std::vector<ESM::ENAMstruct>>(record.get().mEffects.mList);
|
return new NestedTableWrapper<std::vector<ESM::IndexedENAMstruct>>(record.get().mEffects.mList);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const override
|
QVariant getData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const override
|
||||||
{
|
{
|
||||||
ESXRecordT magic = record.get();
|
ESXRecordT magic = record.get();
|
||||||
|
|
||||||
std::vector<ESM::ENAMstruct>& effectsList = magic.mEffects.mList;
|
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
|
||||||
|
|
||||||
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
|
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
|
||||||
throw std::runtime_error("index out of range");
|
throw std::runtime_error("index out of range");
|
||||||
|
|
||||||
ESM::ENAMstruct effect = effectsList[subRowIndex];
|
ESM::ENAMstruct effect = effectsList[subRowIndex].mData;
|
||||||
switch (subColIndex)
|
switch (subColIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -374,12 +377,12 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESXRecordT magic = record.get();
|
ESXRecordT magic = record.get();
|
||||||
|
|
||||||
std::vector<ESM::ENAMstruct>& effectsList = magic.mEffects.mList;
|
std::vector<ESM::IndexedENAMstruct>& effectsList = magic.mEffects.mList;
|
||||||
|
|
||||||
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
|
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(effectsList.size()))
|
||||||
throw std::runtime_error("index out of range");
|
throw std::runtime_error("index out of range");
|
||||||
|
|
||||||
ESM::ENAMstruct effect = effectsList[subRowIndex];
|
ESM::ENAMstruct effect = effectsList[subRowIndex].mData;
|
||||||
switch (subColIndex)
|
switch (subColIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -438,7 +441,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("Magic Effects subcolumn index out of range");
|
throw std::runtime_error("Magic Effects subcolumn index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
magic.mEffects.mList[subRowIndex] = effect;
|
magic.mEffects.mList[subRowIndex].mData = effect;
|
||||||
|
|
||||||
record.setModified(magic);
|
record.setModified(magic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,11 @@ namespace CSMWorld
|
||||||
|
|
||||||
State mState;
|
State mState;
|
||||||
|
|
||||||
|
explicit RecordBase(State state)
|
||||||
|
: mState(state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~RecordBase() = default;
|
virtual ~RecordBase() = default;
|
||||||
|
|
||||||
virtual std::unique_ptr<RecordBase> clone() const = 0;
|
virtual std::unique_ptr<RecordBase> clone() const = 0;
|
||||||
|
@ -69,21 +74,18 @@ namespace CSMWorld
|
||||||
|
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
Record<ESXRecordT>::Record()
|
Record<ESXRecordT>::Record()
|
||||||
: mBase()
|
: RecordBase(State_BaseOnly)
|
||||||
|
, mBase()
|
||||||
, mModified()
|
, mModified()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
Record<ESXRecordT>::Record(State state, const ESXRecordT* base, const ESXRecordT* modified)
|
Record<ESXRecordT>::Record(State state, const ESXRecordT* base, const ESXRecordT* modified)
|
||||||
|
: RecordBase(state)
|
||||||
|
, mBase(base == nullptr ? ESXRecordT{} : *base)
|
||||||
|
, mModified(modified == nullptr ? ESXRecordT{} : *modified)
|
||||||
{
|
{
|
||||||
if (base)
|
|
||||||
mBase = *base;
|
|
||||||
|
|
||||||
if (modified)
|
|
||||||
mModified = *modified;
|
|
||||||
|
|
||||||
this->mState = state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ESXRecordT>
|
template <typename ESXRecordT>
|
||||||
|
|
|
@ -33,7 +33,7 @@ QVariant CSMWorld::PotionRefIdAdapter::getData(const RefIdColumn* column, const
|
||||||
data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion)));
|
data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion)));
|
||||||
|
|
||||||
if (column == mAutoCalc)
|
if (column == mAutoCalc)
|
||||||
return record.get().mData.mAutoCalc != 0;
|
return record.get().mData.mFlags & ESM::Potion::Autocalc;
|
||||||
|
|
||||||
// to show nested tables in dialogue subview, see IdTree::hasChildren()
|
// to show nested tables in dialogue subview, see IdTree::hasChildren()
|
||||||
if (column == mColumns.mEffects)
|
if (column == mColumns.mEffects)
|
||||||
|
@ -51,7 +51,7 @@ void CSMWorld::PotionRefIdAdapter::setData(
|
||||||
ESM::Potion potion = record.get();
|
ESM::Potion potion = record.get();
|
||||||
|
|
||||||
if (column == mAutoCalc)
|
if (column == mAutoCalc)
|
||||||
potion.mData.mAutoCalc = value.toInt();
|
potion.mData.mFlags = value.toBool();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InventoryRefIdAdapter<ESM::Potion>::setData(column, data, index, value);
|
InventoryRefIdAdapter<ESM::Potion>::setData(column, data, index, value);
|
||||||
|
|
|
@ -97,7 +97,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||||
inventoryColumns.mIcon = &mColumns.back();
|
inventoryColumns.mIcon = &mColumns.back();
|
||||||
mColumns.emplace_back(Columns::ColumnId_Weight, ColumnBase::Display_Float);
|
mColumns.emplace_back(Columns::ColumnId_Weight, ColumnBase::Display_Float);
|
||||||
inventoryColumns.mWeight = &mColumns.back();
|
inventoryColumns.mWeight = &mColumns.back();
|
||||||
mColumns.emplace_back(Columns::ColumnId_StackCount, ColumnBase::Display_Integer);
|
mColumns.emplace_back(Columns::ColumnId_GoldValue, ColumnBase::Display_Integer);
|
||||||
inventoryColumns.mValue = &mColumns.back();
|
inventoryColumns.mValue = &mColumns.back();
|
||||||
|
|
||||||
IngredientColumns ingredientColumns(inventoryColumns);
|
IngredientColumns ingredientColumns(inventoryColumns);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "regionmap.hpp"
|
#include "regionmap.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
#include <QPalette>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
|
@ -21,20 +23,33 @@
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
|
|
||||||
CSMWorld::RegionMap::CellDescription::CellDescription()
|
namespace CSMWorld
|
||||||
: mDeleted(false)
|
|
||||||
{
|
{
|
||||||
|
float getLandHeight(const CSMWorld::Cell& cell, CSMWorld::Data& data)
|
||||||
|
{
|
||||||
|
const IdCollection<Land>& lands = data.getLand();
|
||||||
|
int landIndex = lands.searchId(cell.mId);
|
||||||
|
if (landIndex == -1)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
// If any part of land is above water, returns > 0 - otherwise returns < 0
|
||||||
|
const Land& land = lands.getRecord(landIndex).get();
|
||||||
|
if (land.getLandData())
|
||||||
|
return land.getLandData()->mMaxHeight - cell.mWater;
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::RegionMap::CellDescription::CellDescription(const Record<Cell>& cell)
|
CSMWorld::RegionMap::CellDescription::CellDescription(const Record<Cell>& cell, float landHeight)
|
||||||
{
|
{
|
||||||
const Cell& cell2 = cell.get();
|
const Cell& cell2 = cell.get();
|
||||||
|
|
||||||
if (!cell2.isExterior())
|
if (!cell2.isExterior())
|
||||||
throw std::logic_error("Interior cell in region map");
|
throw std::logic_error("Interior cell in region map");
|
||||||
|
|
||||||
|
mMaxLandHeight = landHeight;
|
||||||
mDeleted = cell.isDeleted();
|
mDeleted = cell.isDeleted();
|
||||||
|
|
||||||
mRegion = cell2.mRegion;
|
mRegion = cell2.mRegion;
|
||||||
mName = cell2.mName;
|
mName = cell2.mName;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +107,7 @@ void CSMWorld::RegionMap::buildMap()
|
||||||
|
|
||||||
if (cell2.isExterior())
|
if (cell2.isExterior())
|
||||||
{
|
{
|
||||||
CellDescription description(cell);
|
CellDescription description(cell, getLandHeight(cell2, mData));
|
||||||
|
|
||||||
CellCoordinates index = getIndex(cell2);
|
CellCoordinates index = getIndex(cell2);
|
||||||
|
|
||||||
|
@ -140,7 +155,7 @@ void CSMWorld::RegionMap::addCells(int start, int end)
|
||||||
{
|
{
|
||||||
CellCoordinates index = getIndex(cell2);
|
CellCoordinates index = getIndex(cell2);
|
||||||
|
|
||||||
CellDescription description(cell);
|
CellDescription description(cell, getLandHeight(cell.get(), mData));
|
||||||
|
|
||||||
addCell(index, description);
|
addCell(index, description);
|
||||||
}
|
}
|
||||||
|
@ -335,10 +350,11 @@ QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const
|
||||||
auto iter = mColours.find(cell->second.mRegion);
|
auto iter = mColours.find(cell->second.mRegion);
|
||||||
|
|
||||||
if (iter != mColours.end())
|
if (iter != mColours.end())
|
||||||
return QBrush(QColor(iter->second & 0xff, (iter->second >> 8) & 0xff, (iter->second >> 16) & 0xff));
|
return QBrush(QColor(iter->second & 0xff, (iter->second >> 8) & 0xff, (iter->second >> 16) & 0xff),
|
||||||
|
cell->second.mMaxLandHeight > 0 ? Qt::SolidPattern : Qt::CrossPattern);
|
||||||
|
|
||||||
if (cell->second.mRegion.empty())
|
if (cell->second.mRegion.empty()) // no region
|
||||||
return QBrush(Qt::Dense6Pattern); // no region
|
return QBrush(cell->second.mMaxLandHeight > 0 ? Qt::Dense3Pattern : Qt::Dense6Pattern);
|
||||||
|
|
||||||
return QBrush(Qt::red, Qt::Dense6Pattern); // invalid region
|
return QBrush(Qt::red, Qt::Dense6Pattern); // invalid region
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,12 @@ namespace CSMWorld
|
||||||
private:
|
private:
|
||||||
struct CellDescription
|
struct CellDescription
|
||||||
{
|
{
|
||||||
|
float mMaxLandHeight;
|
||||||
bool mDeleted;
|
bool mDeleted;
|
||||||
ESM::RefId mRegion;
|
ESM::RefId mRegion;
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
CellDescription();
|
CellDescription(const Record<Cell>& cell, float landHeight);
|
||||||
|
|
||||||
CellDescription(const Record<Cell>& cell);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Data& mData;
|
Data& mData;
|
||||||
|
|
|
@ -58,7 +58,8 @@ namespace CSVRender
|
||||||
|
|
||||||
InstanceSelectionMode::~InstanceSelectionMode()
|
InstanceSelectionMode::~InstanceSelectionMode()
|
||||||
{
|
{
|
||||||
mParentNode->removeChild(mBaseNode);
|
if (mBaseNode)
|
||||||
|
mParentNode->removeChild(mBaseNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSelectionMode::setDragStart(const osg::Vec3d& dragStart)
|
void InstanceSelectionMode::setDragStart(const osg::Vec3d& dragStart)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <osg/Vec4f>
|
#include <osg/Vec4f>
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/position.hpp>
|
||||||
#include <components/esm/refid.hpp>
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "tagbase.hpp"
|
#include "tagbase.hpp"
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
#include <components/sceneutil/glextensions.hpp>
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
|
||||||
#include "../widget/scenetoolmode.hpp"
|
#include "../widget/scenetoolmode.hpp"
|
||||||
|
@ -76,6 +77,8 @@ namespace CSVRender
|
||||||
= new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height());
|
= new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height());
|
||||||
mWidget->setGraphicsWindowEmbedded(window);
|
mWidget->setGraphicsWindowEmbedded(window);
|
||||||
|
|
||||||
|
mRenderer->setRealizeOperation(new SceneUtil::GetGLExtensionsOperation());
|
||||||
|
|
||||||
int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt();
|
int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt();
|
||||||
mRenderer->setRunMaxFrameRate(frameRateLimit);
|
mRenderer->setRunMaxFrameRate(frameRateLimit);
|
||||||
mRenderer->setUseConfigureAffinity(false);
|
mRenderer->setUseConfigureAffinity(false);
|
||||||
|
|
|
@ -2,17 +2,6 @@
|
||||||
|
|
||||||
#include <components/misc/strings/lower.hpp>
|
#include <components/misc/strings/lower.hpp>
|
||||||
|
|
||||||
bool CSVWorld::IdValidator::isValid(const QChar& c, bool first) const
|
|
||||||
{
|
|
||||||
if (c.isLetter() || c == '_')
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!first && (c.isDigit() || c.isSpace()))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVWorld::IdValidator::IdValidator(bool relaxed, QObject* parent)
|
CSVWorld::IdValidator::IdValidator(bool relaxed, QObject* parent)
|
||||||
: QValidator(parent)
|
: QValidator(parent)
|
||||||
, mRelaxed(relaxed)
|
, mRelaxed(relaxed)
|
||||||
|
@ -92,7 +81,7 @@ QValidator::State CSVWorld::IdValidator::validate(QString& input, int& pos) cons
|
||||||
{
|
{
|
||||||
prevScope = false;
|
prevScope = false;
|
||||||
|
|
||||||
if (!isValid(*iter, first))
|
if (!iter->isPrint())
|
||||||
return QValidator::Invalid;
|
return QValidator::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,6 @@ namespace CSVWorld
|
||||||
std::string mNamespace;
|
std::string mNamespace;
|
||||||
mutable std::string mError;
|
mutable std::string mError;
|
||||||
|
|
||||||
private:
|
|
||||||
bool isValid(const QChar& c, bool first) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IdValidator(bool relaxed = false, QObject* parent = nullptr);
|
IdValidator(bool relaxed = false, QObject* parent = nullptr);
|
||||||
///< \param relaxed Relaxed rules for IDs that also functino as user visible text
|
///< \param relaxed Relaxed rules for IDs that also functino as user visible text
|
||||||
|
|
|
@ -224,6 +224,10 @@ CSVWorld::RegionMap::RegionMap(const CSMWorld::UniversalId& universalId, CSMDoc:
|
||||||
addAction(mViewInTableAction);
|
addAction(mViewInTableAction);
|
||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
// Make columns square incase QSizeHint doesnt apply
|
||||||
|
for (int column = 0; column < this->model()->columnCount(); ++column)
|
||||||
|
this->setColumnWidth(column, this->rowHeight(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::RegionMap::selectAll()
|
void CSVWorld::RegionMap::selectAll()
|
||||||
|
@ -358,12 +362,23 @@ std::vector<CSMWorld::UniversalId> CSVWorld::RegionMap::getDraggedRecords() cons
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::RegionMap::dragMoveEvent(QDragMoveEvent* event)
|
||||||
|
{
|
||||||
|
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*>(event->mimeData());
|
||||||
|
if (mime != nullptr && (mime->holdsType(CSMWorld::UniversalId::Type_Region)))
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWorld::RegionMap::dropEvent(QDropEvent* event)
|
void CSVWorld::RegionMap::dropEvent(QDropEvent* event)
|
||||||
{
|
{
|
||||||
QModelIndex index = indexAt(event->pos());
|
QModelIndex index = indexAt(event->pos());
|
||||||
|
|
||||||
bool exists = QTableView::model()->data(index, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern);
|
bool exists = QTableView::model()->data(index, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern);
|
||||||
|
|
||||||
if (!index.isValid() || !exists)
|
if (!index.isValid() || !exists)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace CSVWorld
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
|
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||||
|
|
||||||
void dropEvent(QDropEvent* event) override;
|
void dropEvent(QDropEvent* event) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -26,7 +26,7 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||||
target_link_libraries(openmw-cs-tests PRIVATE gcov)
|
target_link_libraries(openmw-cs-tests PRIVATE gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw-cs-tests PRIVATE
|
target_precompile_headers(openmw-cs-tests PRIVATE
|
||||||
<gtest/gtest.h>
|
<gtest/gtest.h>
|
||||||
)
|
)
|
||||||
|
|
|
@ -63,8 +63,8 @@ add_openmw_dir (mwlua
|
||||||
luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant
|
luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant
|
||||||
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings
|
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings
|
||||||
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings
|
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings
|
||||||
postprocessingbindings stats debugbindings corebindings worldbindings worker magicbindings factionbindings
|
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker magicbindings factionbindings
|
||||||
classbindings itemdata inputprocessor animationbindings birthsignbindings
|
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings
|
||||||
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc
|
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc
|
||||||
types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus
|
types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus
|
||||||
types/potion types/ingredient types/misc types/repair types/armor types/light types/static
|
types/potion types/ingredient types/misc types/repair types/armor types/light types/static
|
||||||
|
@ -103,7 +103,7 @@ add_openmw_dir (mwmechanics
|
||||||
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
|
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
|
||||||
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance
|
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance
|
||||||
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction summoning
|
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction summoning
|
||||||
character actors objects aistate trading weaponpriority spellpriority weapontype spellutil
|
character actors objects aistate weaponpriority spellpriority weapontype spellutil
|
||||||
spelleffects
|
spelleffects
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ target_link_libraries(openmw
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND PRECOMPILE_HEADERS_WITH_MSVC)
|
||||||
target_precompile_headers(openmw PRIVATE
|
target_precompile_headers(openmw PRIVATE
|
||||||
<boost/program_options/options_description.hpp>
|
<boost/program_options/options_description.hpp>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <components/stereo/multiview.hpp>
|
#include <components/stereo/multiview.hpp>
|
||||||
#include <components/stereo/stereomanager.hpp>
|
#include <components/stereo/stereomanager.hpp>
|
||||||
|
|
||||||
|
#include <components/sceneutil/glextensions.hpp>
|
||||||
#include <components/sceneutil/workqueue.hpp>
|
#include <components/sceneutil/workqueue.hpp>
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
@ -600,6 +601,7 @@ void OMW::Engine::createWindow()
|
||||||
mViewer->setRealizeOperation(realizeOperations);
|
mViewer->setRealizeOperation(realizeOperations);
|
||||||
osg::ref_ptr<IdentifyOpenGLOperation> identifyOp = new IdentifyOpenGLOperation();
|
osg::ref_ptr<IdentifyOpenGLOperation> identifyOp = new IdentifyOpenGLOperation();
|
||||||
realizeOperations->add(identifyOp);
|
realizeOperations->add(identifyOp);
|
||||||
|
realizeOperations->add(new SceneUtil::GetGLExtensionsOperation());
|
||||||
|
|
||||||
if (Debug::shouldDebugOpenGL())
|
if (Debug::shouldDebugOpenGL())
|
||||||
realizeOperations->add(new Debug::EnableGLDebugOperation());
|
realizeOperations->add(new Debug::EnableGLDebugOperation());
|
||||||
|
@ -780,13 +782,13 @@ void OMW::Engine::prepareEngine()
|
||||||
// gui needs our shaders path before everything else
|
// gui needs our shaders path before everything else
|
||||||
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");
|
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");
|
||||||
|
|
||||||
osg::ref_ptr<osg::GLExtensions> exts = osg::GLExtensions::Get(0, false);
|
osg::GLExtensions& exts = SceneUtil::getGLExtensions();
|
||||||
bool shadersSupported = exts && (exts->glslLanguageVersion >= 1.2f);
|
bool shadersSupported = exts.glslLanguageVersion >= 1.2f;
|
||||||
|
|
||||||
#if OSG_VERSION_LESS_THAN(3, 6, 6)
|
#if OSG_VERSION_LESS_THAN(3, 6, 6)
|
||||||
// hack fix for https://github.com/openscenegraph/OpenSceneGraph/issues/1028
|
// hack fix for https://github.com/openscenegraph/OpenSceneGraph/issues/1028
|
||||||
if (exts)
|
if (!osg::isGLExtensionSupported(exts.contextID, "NV_framebuffer_multisample_coverage"))
|
||||||
exts->glRenderbufferStorageMultisampleCoverageNV = nullptr;
|
exts.glRenderbufferStorageMultisampleCoverageNV = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> guiRoot = new osg::Group;
|
osg::ref_ptr<osg::Group> guiRoot = new osg::Group;
|
||||||
|
@ -963,17 +965,17 @@ void OMW::Engine::go()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup profiler
|
// Setup profiler
|
||||||
osg::ref_ptr<Resource::Profiler> statshandler = new Resource::Profiler(stats.is_open(), mVFS.get());
|
osg::ref_ptr<Resource::Profiler> statsHandler = new Resource::Profiler(stats.is_open(), *mVFS);
|
||||||
|
|
||||||
initStatsHandler(*statshandler);
|
initStatsHandler(*statsHandler);
|
||||||
|
|
||||||
mViewer->addEventHandler(statshandler);
|
mViewer->addEventHandler(statsHandler);
|
||||||
|
|
||||||
osg::ref_ptr<Resource::StatsHandler> resourceshandler = new Resource::StatsHandler(stats.is_open(), mVFS.get());
|
osg::ref_ptr<Resource::StatsHandler> resourcesHandler = new Resource::StatsHandler(stats.is_open(), *mVFS);
|
||||||
mViewer->addEventHandler(resourceshandler);
|
mViewer->addEventHandler(resourcesHandler);
|
||||||
|
|
||||||
if (stats.is_open())
|
if (stats.is_open())
|
||||||
Resource::CollectStatistics(mViewer);
|
Resource::collectStatistics(*mViewer);
|
||||||
|
|
||||||
// Start the game
|
// Start the game
|
||||||
if (!mSaveGameFile.empty())
|
if (!mSaveGameFile.empty())
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <components/fallback/fallback.hpp>
|
#include <components/fallback/fallback.hpp>
|
||||||
#include <components/fallback/validate.hpp>
|
#include <components/fallback/validate.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#include <components/misc/osgpluginchecker.hpp>
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
#include <components/platform/platform.hpp>
|
#include <components/platform/platform.hpp>
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
|
@ -228,6 +229,9 @@ int runApplication(int argc, char* argv[])
|
||||||
|
|
||||||
if (parseOptions(argc, argv, *engine, cfgMgr))
|
if (parseOptions(argc, argv, *engine, cfgMgr))
|
||||||
{
|
{
|
||||||
|
if (!Misc::checkRequiredOSGPluginsArePresent())
|
||||||
|
return 1;
|
||||||
|
|
||||||
engine->go();
|
engine->go();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ namespace MWBase
|
||||||
virtual bool isReadyToBlock(const MWWorld::Ptr& ptr) const = 0;
|
virtual bool isReadyToBlock(const MWWorld::Ptr& ptr) const = 0;
|
||||||
virtual bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const = 0;
|
virtual bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
|
||||||
virtual void castSpell(const MWWorld::Ptr& ptr, const ESM::RefId& spellId, bool manualSpell) = 0;
|
virtual void castSpell(const MWWorld::Ptr& ptr, const ESM::RefId& spellId, bool scriptedSpell) = 0;
|
||||||
|
|
||||||
virtual void processChangedSettings(const std::set<std::pair<std::string, std::string>>& settings) = 0;
|
virtual void processChangedSettings(const std::set<std::pair<std::string, std::string>>& settings) = 0;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <components/vfs/pathutil.hpp>
|
||||||
|
|
||||||
#include "../mwsound/type.hpp"
|
#include "../mwsound/type.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
@ -129,11 +131,11 @@ namespace MWBase
|
||||||
/// \param name of the folder that contains the playlist
|
/// \param name of the folder that contains the playlist
|
||||||
/// Title music playlist is predefined
|
/// Title music playlist is predefined
|
||||||
|
|
||||||
virtual void say(const MWWorld::ConstPtr& reference, const std::string& filename) = 0;
|
virtual void say(const MWWorld::ConstPtr& reference, VFS::Path::NormalizedView filename) = 0;
|
||||||
///< Make an actor say some text.
|
///< Make an actor say some text.
|
||||||
/// \param filename name of a sound file in the VFS
|
/// \param filename name of a sound file in the VFS
|
||||||
|
|
||||||
virtual void say(const std::string& filename) = 0;
|
virtual void say(VFS::Path::NormalizedView filename) = 0;
|
||||||
///< Say some text, without an actor ref
|
///< Say some text, without an actor ref
|
||||||
/// \param filename name of a sound file in the VFS
|
/// \param filename name of a sound file in the VFS
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual bool isConsoleMode() const = 0;
|
virtual bool isConsoleMode() const = 0;
|
||||||
virtual bool isPostProcessorHudVisible() const = 0;
|
virtual bool isPostProcessorHudVisible() const = 0;
|
||||||
|
virtual bool isSettingsWindowVisible() const = 0;
|
||||||
virtual bool isInteractiveMessageBoxActive() const = 0;
|
virtual bool isInteractiveMessageBoxActive() const = 0;
|
||||||
|
|
||||||
virtual void toggleVisible(MWGui::GuiWindow wnd) = 0;
|
virtual void toggleVisible(MWGui::GuiWindow wnd) = 0;
|
||||||
|
@ -157,7 +158,6 @@ namespace MWBase
|
||||||
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
|
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
|
||||||
virtual MWGui::TradeWindow* getTradeWindow() = 0;
|
virtual MWGui::TradeWindow* getTradeWindow() = 0;
|
||||||
virtual MWGui::PostProcessorHud* getPostProcessorHud() = 0;
|
virtual MWGui::PostProcessorHud* getPostProcessorHud() = 0;
|
||||||
virtual MWGui::SettingsWindow* getSettingsWindow() = 0;
|
|
||||||
|
|
||||||
/// Make the player use an item, while updating GUI state accordingly
|
/// Make the player use an item, while updating GUI state accordingly
|
||||||
virtual void useItem(const MWWorld::Ptr& item, bool force = false) = 0;
|
virtual void useItem(const MWWorld::Ptr& item, bool force = false) = 0;
|
||||||
|
@ -202,9 +202,6 @@ namespace MWBase
|
||||||
|
|
||||||
virtual bool getFullHelp() const = 0;
|
virtual bool getFullHelp() const = 0;
|
||||||
|
|
||||||
virtual void setActiveMap(int x, int y, bool interior) = 0;
|
|
||||||
///< set the indices of the map texture that should be used
|
|
||||||
|
|
||||||
/// sets the visibility of the drowning bar
|
/// sets the visibility of the drowning bar
|
||||||
virtual void setDrowningBarVisibility(bool visible) = 0;
|
virtual void setDrowningBarVisibility(bool visible) = 0;
|
||||||
|
|
||||||
|
@ -293,7 +290,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void setEnemy(const MWWorld::Ptr& enemy) = 0;
|
virtual void setEnemy(const MWWorld::Ptr& enemy) = 0;
|
||||||
|
|
||||||
virtual int getMessagesCount() const = 0;
|
virtual std::size_t getMessagesCount() const = 0;
|
||||||
|
|
||||||
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
||||||
|
|
||||||
|
@ -345,6 +342,7 @@ namespace MWBase
|
||||||
virtual void toggleConsole() = 0;
|
virtual void toggleConsole() = 0;
|
||||||
virtual void toggleDebugWindow() = 0;
|
virtual void toggleDebugWindow() = 0;
|
||||||
virtual void togglePostProcessorHud() = 0;
|
virtual void togglePostProcessorHud() = 0;
|
||||||
|
virtual void toggleSettingsWindow() = 0;
|
||||||
|
|
||||||
/// Cycle to next or previous spell
|
/// Cycle to next or previous spell
|
||||||
virtual void cycleSpell(bool next) = 0;
|
virtual void cycleSpell(bool next) = 0;
|
||||||
|
|
|
@ -183,8 +183,6 @@ namespace MWBase
|
||||||
/// generate a name.
|
/// generate a name.
|
||||||
virtual std::string_view getCellName(const MWWorld::Cell& cell) const = 0;
|
virtual std::string_view getCellName(const MWWorld::Cell& cell) const = 0;
|
||||||
|
|
||||||
virtual std::string_view getCellName(const ESM::Cell* cell) const = 0;
|
|
||||||
|
|
||||||
virtual void removeRefScript(const MWWorld::CellRef* ref) = 0;
|
virtual void removeRefScript(const MWWorld::CellRef* ref) = 0;
|
||||||
//< Remove the script attached to ref from mLocalScripts
|
//< Remove the script attached to ref from mLocalScripts
|
||||||
|
|
||||||
|
@ -463,7 +461,7 @@ namespace MWBase
|
||||||
*/
|
*/
|
||||||
virtual MWWorld::SpellCastState startSpellCast(const MWWorld::Ptr& actor) = 0;
|
virtual MWWorld::SpellCastState startSpellCast(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
virtual void castSpell(const MWWorld::Ptr& actor, bool manualSpell = false) = 0;
|
virtual void castSpell(const MWWorld::Ptr& actor, bool scriptedSpell = false) = 0;
|
||||||
|
|
||||||
virtual void launchMagicBolt(const ESM::RefId& spellId, const MWWorld::Ptr& caster,
|
virtual void launchMagicBolt(const ESM::RefId& spellId, const MWWorld::Ptr& caster,
|
||||||
const osg::Vec3f& fallbackDirection, ESM::RefNum item)
|
const osg::Vec3f& fallbackDirection, ESM::RefNum item)
|
||||||
|
|
|
@ -104,13 +104,11 @@ namespace MWClass
|
||||||
std::string_view name = getName(ptr);
|
std::string_view name = getName(ptr);
|
||||||
info.caption = MyGUI::TextIterator::toTagsString(MyGUI::UString(name)) + MWGui::ToolTips::getCountString(count);
|
info.caption = MyGUI::TextIterator::toTagsString(MyGUI::UString(name)) + MWGui::ToolTips::getCountString(count);
|
||||||
|
|
||||||
std::string text;
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
info.text = std::move(text);
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
||||||
|
|
|
@ -257,8 +257,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
|
|
@ -121,8 +121,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
|
|
@ -164,8 +164,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
|
|
@ -265,10 +265,10 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
if (ptr.getCellRef().getRefId() == "stolen_goods")
|
if (ptr.getCellRef().getRefId() == "stolen_goods")
|
||||||
text += "\nYou can not use evidence chests";
|
info.extra += "\nYou cannot use evidence chests";
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -316,11 +316,11 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
const unsigned char* attack = nullptr;
|
const unsigned char* attack = nullptr;
|
||||||
if (type == ESM::Weapon::AT_Chop)
|
if (type == ESM::Weapon::AT_Chop)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop.data();
|
||||||
else if (type == ESM::Weapon::AT_Slash)
|
else if (type == ESM::Weapon::AT_Slash)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash.data();
|
||||||
else if (type == ESM::Weapon::AT_Thrust)
|
else if (type == ESM::Weapon::AT_Thrust)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust.data();
|
||||||
if (attack)
|
if (attack)
|
||||||
{
|
{
|
||||||
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
@ -591,10 +591,8 @@ namespace MWClass
|
||||||
std::string_view name = getName(ptr);
|
std::string_view name = getName(ptr);
|
||||||
info.caption = MyGUI::TextIterator::toTagsString(MyGUI::UString(name));
|
info.caption = MyGUI::TextIterator::toTagsString(MyGUI::UString(name));
|
||||||
|
|
||||||
std::string text;
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
info.text = std::move(text);
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace MWClass
|
||||||
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(ESM::MagicEffect::Telekinesis);
|
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(ESM::MagicEffect::Telekinesis);
|
||||||
|
|
||||||
animation->addSpellCastGlow(
|
animation->addSpellCastGlow(
|
||||||
effect, 1); // 1 second glow to match the time taken for a door opening or closing
|
effect->getColor(), 1); // 1 second glow to match the time taken for a door opening or closing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +290,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
|
|
@ -173,8 +173,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -118,8 +118,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -163,8 +163,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -635,11 +635,11 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
const unsigned char* attack = nullptr;
|
const unsigned char* attack = nullptr;
|
||||||
if (type == ESM::Weapon::AT_Chop)
|
if (type == ESM::Weapon::AT_Chop)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop.data();
|
||||||
else if (type == ESM::Weapon::AT_Slash)
|
else if (type == ESM::Weapon::AT_Slash)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash.data();
|
||||||
else if (type == ESM::Weapon::AT_Thrust)
|
else if (type == ESM::Weapon::AT_Thrust)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust.data();
|
||||||
if (attack)
|
if (attack)
|
||||||
{
|
{
|
||||||
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
@ -1118,7 +1118,7 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullHelp)
|
if (fullHelp)
|
||||||
info.text = MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra = MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/alchemy.hpp"
|
#include "../mwmechanics/alchemy.hpp"
|
||||||
|
#include "../mwmechanics/spellutil.hpp"
|
||||||
|
|
||||||
#include "classmodel.hpp"
|
#include "classmodel.hpp"
|
||||||
|
|
||||||
|
@ -65,9 +66,7 @@ namespace MWClass
|
||||||
|
|
||||||
int Potion::getValue(const MWWorld::ConstPtr& ptr) const
|
int Potion::getValue(const MWWorld::ConstPtr& ptr) const
|
||||||
{
|
{
|
||||||
const MWWorld::LiveCellRef<ESM::Potion>* ref = ptr.get<ESM::Potion>();
|
return MWMechanics::getPotionValue(*ptr.get<ESM::Potion>()->mBase);
|
||||||
|
|
||||||
return ref->mBase->mData.mValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::RefId& Potion::getUpSoundId(const MWWorld::ConstPtr& ptr) const
|
const ESM::RefId& Potion::getUpSoundId(const MWWorld::ConstPtr& ptr) const
|
||||||
|
@ -101,7 +100,7 @@ namespace MWClass
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
|
||||||
|
|
||||||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
||||||
|
|
||||||
|
@ -114,8 +113,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -117,8 +117,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -119,8 +119,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -239,8 +239,8 @@ namespace MWClass
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
||||||
{
|
{
|
||||||
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
info.extra += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
info.extra += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
||||||
}
|
}
|
||||||
|
|
||||||
info.text = std::move(text);
|
info.text = std::move(text);
|
||||||
|
|
|
@ -653,7 +653,7 @@ namespace MWDialogue
|
||||||
if (Settings::gui().mSubtitles)
|
if (Settings::gui().mSubtitles)
|
||||||
winMgr->messageBox(info->mResponse);
|
winMgr->messageBox(info->mResponse);
|
||||||
if (!info->mSound.empty())
|
if (!info->mSound.empty())
|
||||||
sndMgr->say(actor, Misc::ResourceHelpers::correctSoundPath(info->mSound));
|
sndMgr->say(actor, Misc::ResourceHelpers::correctSoundPath(VFS::Path::Normalized(info->mSound)));
|
||||||
if (!info->mResultScript.empty())
|
if (!info->mResultScript.empty())
|
||||||
executeScript(info->mResultScript, actor);
|
executeScript(info->mResultScript, actor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace MWDialogue
|
||||||
// some keywords might be longer variations of other keywords, so we definitely need a list of
|
// some keywords might be longer variations of other keywords, so we definitely need a list of
|
||||||
// candidates the first element in the pair is length of the match, i.e. depth from the first character
|
// candidates the first element in the pair is length of the match, i.e. depth from the first character
|
||||||
// on
|
// on
|
||||||
std::vector<typename std::pair<int, typename Entry::childen_t::const_iterator>> candidates;
|
std::vector<typename std::pair<std::ptrdiff_t, typename Entry::childen_t::const_iterator>> candidates;
|
||||||
|
|
||||||
while ((j + 1) != end)
|
while ((j + 1) != end)
|
||||||
{
|
{
|
||||||
|
@ -148,11 +148,11 @@ namespace MWDialogue
|
||||||
// resolve overlapping keywords
|
// resolve overlapping keywords
|
||||||
while (!matches.empty())
|
while (!matches.empty())
|
||||||
{
|
{
|
||||||
int longestKeywordSize = 0;
|
std::size_t longestKeywordSize = 0;
|
||||||
typename std::vector<Match>::iterator longestKeyword = matches.begin();
|
typename std::vector<Match>::iterator longestKeyword = matches.begin();
|
||||||
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
|
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
|
||||||
{
|
{
|
||||||
int size = it->mEnd - it->mBeg;
|
std::size_t size = it->mEnd - it->mBeg;
|
||||||
if (size > longestKeywordSize)
|
if (size > longestKeywordSize)
|
||||||
{
|
{
|
||||||
longestKeywordSize = size;
|
longestKeywordSize = size;
|
||||||
|
@ -199,7 +199,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
void seed_impl(std::string_view keyword, value_t value, size_t depth, Entry& entry)
|
void seed_impl(std::string_view keyword, value_t value, size_t depth, Entry& entry)
|
||||||
{
|
{
|
||||||
int ch = Misc::StringUtils::toLower(keyword.at(depth));
|
auto ch = Misc::StringUtils::toLower(keyword.at(depth));
|
||||||
|
|
||||||
typename Entry::childen_t::iterator j = entry.mChildren.find(ch);
|
typename Entry::childen_t::iterator j = entry.mChildren.find(ch);
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace
|
||||||
{
|
{
|
||||||
const std::string mText;
|
const std::string mText;
|
||||||
const Response mResponses[3];
|
const Response mResponses[3];
|
||||||
const std::string mSound;
|
const VFS::Path::Normalized mSound;
|
||||||
};
|
};
|
||||||
|
|
||||||
Step sGenerateClassSteps(int number)
|
Step sGenerateClassSteps(int number)
|
||||||
|
|
|
@ -771,11 +771,6 @@ namespace MWGui
|
||||||
return output.append(matches.front());
|
return output.append(matches.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::onResChange(int width, int height)
|
|
||||||
{
|
|
||||||
setCoord(10, 10, width - 10, height / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr)
|
void Console::updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr)
|
||||||
{
|
{
|
||||||
if (mPtr == currentPtr)
|
if (mPtr == currentPtr)
|
||||||
|
|
|
@ -47,8 +47,6 @@ namespace MWGui
|
||||||
|
|
||||||
void onOpen() override;
|
void onOpen() override;
|
||||||
|
|
||||||
void onResChange(int width, int height) override;
|
|
||||||
|
|
||||||
// Print a message to the console, in specified color.
|
// Print a message to the console, in specified color.
|
||||||
void print(const std::string& msg, std::string_view color = MWBase::WindowManager::sConsoleColor_Default);
|
void print(const std::string& msg, std::string_view color = MWBase::WindowManager::sConsoleColor_Default);
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,7 @@ namespace MWGui
|
||||||
|
|
||||||
void EnchantingDialog::notifyEffectsChanged()
|
void EnchantingDialog::notifyEffectsChanged()
|
||||||
{
|
{
|
||||||
mEffectList.mList = mEffects;
|
mEffectList.populate(mEffects);
|
||||||
mEnchanting.setEffect(mEffectList);
|
mEnchanting.setEffect(mEffectList);
|
||||||
updateLabels();
|
updateLabels();
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,7 +427,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
// use the icon of the first effect
|
// use the icon of the first effect
|
||||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(
|
const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(
|
||||||
spell->mEffects.mList.front().mEffectID);
|
spell->mEffects.mList.front().mData.mEffectID);
|
||||||
std::string icon = effect->mIcon;
|
std::string icon = effect->mIcon;
|
||||||
std::replace(icon.begin(), icon.end(), '/', '\\');
|
std::replace(icon.begin(), icon.end(), '/', '\\');
|
||||||
size_t slashPos = icon.rfind('\\');
|
size_t slashPos = icon.rfind('\\');
|
||||||
|
|
|
@ -417,6 +417,8 @@ namespace MWGui
|
||||||
|
|
||||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||||
{
|
{
|
||||||
|
WindowBase::clampWindowCoordinates(_sender);
|
||||||
|
|
||||||
adjustPanes();
|
adjustPanes();
|
||||||
const WindowSettingValues settings = getModeSettings(mGuiMode);
|
const WindowSettingValues settings = getModeSettings(mGuiMode);
|
||||||
|
|
||||||
|
|
|
@ -246,12 +246,12 @@ namespace MWGui
|
||||||
|
|
||||||
bool forward = (direction == D_Next || direction == D_Right || direction == D_Down);
|
bool forward = (direction == D_Next || direction == D_Right || direction == D_Down);
|
||||||
|
|
||||||
int index = found - keyFocusList.begin();
|
std::ptrdiff_t index{ found - keyFocusList.begin() };
|
||||||
index = forward ? (index + 1) : (index - 1);
|
index = forward ? (index + 1) : (index - 1);
|
||||||
if (wrap)
|
if (wrap)
|
||||||
index = (index + keyFocusList.size()) % keyFocusList.size();
|
index = (index + keyFocusList.size()) % keyFocusList.size();
|
||||||
else
|
else
|
||||||
index = std::clamp<int>(index, 0, keyFocusList.size() - 1);
|
index = std::clamp<std::ptrdiff_t>(index, 0, keyFocusList.size() - 1);
|
||||||
|
|
||||||
MyGUI::Widget* next = keyFocusList[index];
|
MyGUI::Widget* next = keyFocusList[index];
|
||||||
int vertdiff = next->getTop() - focus->getTop();
|
int vertdiff = next->getTop() - focus->getTop();
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
else if (name == "options")
|
else if (name == "options")
|
||||||
{
|
{
|
||||||
winMgr->getSettingsWindow()->setVisible(true);
|
winMgr->toggleSettingsWindow();
|
||||||
}
|
}
|
||||||
else if (name == "credits")
|
else if (name == "credits")
|
||||||
winMgr->playVideo("mw_credits.bik", true);
|
winMgr->playVideo("mw_credits.bik", true);
|
||||||
|
@ -212,6 +212,12 @@ namespace MWGui
|
||||||
|
|
||||||
bool MainMenu::exit()
|
bool MainMenu::exit()
|
||||||
{
|
{
|
||||||
|
if (MWBase::Environment::get().getWindowManager()->isSettingsWindowVisible())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->toggleSettingsWindow();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Running;
|
return MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,13 @@ namespace
|
||||||
return std::clamp(
|
return std::clamp(
|
||||||
viewingDistanceInCells, Constants::CellGridRadius, Settings::map().mMaxLocalViewingDistance.get());
|
viewingDistanceInCells, Constants::CellGridRadius, Settings::map().mMaxLocalViewingDistance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESM::RefId getCellIdInWorldSpace(const MWWorld::Cell& cell, int x, int y)
|
||||||
|
{
|
||||||
|
if (cell.isExterior())
|
||||||
|
return ESM::Cell::generateIdForCell(true, {}, x, y);
|
||||||
|
return cell.getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
@ -170,12 +177,9 @@ namespace MWGui
|
||||||
LocalMapBase::LocalMapBase(
|
LocalMapBase::LocalMapBase(
|
||||||
CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled)
|
CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled)
|
||||||
: mLocalMapRender(localMapRender)
|
: mLocalMapRender(localMapRender)
|
||||||
, mCurX(0)
|
, mActiveCell(nullptr)
|
||||||
, mCurY(0)
|
|
||||||
, mInterior(false)
|
|
||||||
, mLocalMap(nullptr)
|
, mLocalMap(nullptr)
|
||||||
, mCompass(nullptr)
|
, mCompass(nullptr)
|
||||||
, mChanged(true)
|
|
||||||
, mFogOfWarToggled(true)
|
, mFogOfWarToggled(true)
|
||||||
, mFogOfWarEnabled(fogOfWarEnabled)
|
, mFogOfWarEnabled(fogOfWarEnabled)
|
||||||
, mNumCells(1)
|
, mNumCells(1)
|
||||||
|
@ -231,12 +235,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
|
||||||
{
|
|
||||||
mPrefix = prefix;
|
|
||||||
mChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LocalMapBase::toggleFogOfWar()
|
bool LocalMapBase::toggleFogOfWar()
|
||||||
{
|
{
|
||||||
mFogOfWarToggled = !mFogOfWarToggled;
|
mFogOfWarToggled = !mFogOfWarToggled;
|
||||||
|
@ -262,8 +260,8 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
// normalized cell coordinates
|
// normalized cell coordinates
|
||||||
auto mapWidgetSize = getWidgetSize();
|
auto mapWidgetSize = getWidgetSize();
|
||||||
return MyGUI::IntPoint(std::round(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize),
|
return MyGUI::IntPoint(std::round((nX + mCellDistance + cellX - mActiveCell->getGridX()) * mapWidgetSize),
|
||||||
std::round(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize));
|
std::round((nY + mCellDistance - cellY + mActiveCell->getGridY()) * mapWidgetSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const
|
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const
|
||||||
|
@ -272,7 +270,7 @@ namespace MWGui
|
||||||
// normalized cell coordinates
|
// normalized cell coordinates
|
||||||
float nX, nY;
|
float nX, nY;
|
||||||
|
|
||||||
if (!mInterior)
|
if (mActiveCell->isExterior())
|
||||||
{
|
{
|
||||||
ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(worldX, worldY);
|
ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(worldX, worldY);
|
||||||
cellIndex.x() = cellPos.mX;
|
cellIndex.x() = cellPos.mX;
|
||||||
|
@ -336,7 +334,7 @@ namespace MWGui
|
||||||
|
|
||||||
std::vector<MyGUI::Widget*>& LocalMapBase::currentDoorMarkersWidgets()
|
std::vector<MyGUI::Widget*>& LocalMapBase::currentDoorMarkersWidgets()
|
||||||
{
|
{
|
||||||
return mInterior ? mInteriorDoorMarkerWidgets : mExteriorDoorMarkerWidgets;
|
return mActiveCell->isExterior() ? mExteriorDoorMarkerWidgets : mInteriorDoorMarkerWidgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::updateCustomMarkers()
|
void LocalMapBase::updateCustomMarkers()
|
||||||
|
@ -344,12 +342,14 @@ namespace MWGui
|
||||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||||
MyGUI::Gui::getInstance().destroyWidget(widget);
|
MyGUI::Gui::getInstance().destroyWidget(widget);
|
||||||
mCustomMarkerWidgets.clear();
|
mCustomMarkerWidgets.clear();
|
||||||
|
if (!mActiveCell)
|
||||||
|
return;
|
||||||
for (int dX = -mCellDistance; dX <= mCellDistance; ++dX)
|
for (int dX = -mCellDistance; dX <= mCellDistance; ++dX)
|
||||||
{
|
{
|
||||||
for (int dY = -mCellDistance; dY <= mCellDistance; ++dY)
|
for (int dY = -mCellDistance; dY <= mCellDistance; ++dY)
|
||||||
{
|
{
|
||||||
ESM::RefId cellRefId = ESM::Cell::generateIdForCell(!mInterior, mPrefix, mCurX + dX, mCurY + dY);
|
ESM::RefId cellRefId
|
||||||
|
= getCellIdInWorldSpace(*mActiveCell, mActiveCell->getGridX() + dX, mActiveCell->getGridY() + dY);
|
||||||
|
|
||||||
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellRefId);
|
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellRefId);
|
||||||
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second;
|
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second;
|
||||||
|
@ -377,16 +377,25 @@ namespace MWGui
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
void LocalMapBase::setActiveCell(const MWWorld::Cell& cell)
|
||||||
{
|
{
|
||||||
if (x == mCurX && y == mCurY && mInterior == interior && !mChanged)
|
if (&cell == mActiveCell)
|
||||||
return; // don't do anything if we're still in the same cell
|
return; // don't do anything if we're still in the same cell
|
||||||
|
|
||||||
if (!interior && !(x == mCurX && y == mCurY))
|
const int x = cell.getGridX();
|
||||||
|
const int y = cell.getGridY();
|
||||||
|
|
||||||
|
if (cell.isExterior())
|
||||||
{
|
{
|
||||||
const MyGUI::IntRect intersection
|
int curX = 0;
|
||||||
= { std::max(x, mCurX) - mCellDistance, std::max(y, mCurY) - mCellDistance,
|
int curY = 0;
|
||||||
std::min(x, mCurX) + mCellDistance, std::min(y, mCurY) + mCellDistance };
|
if (mActiveCell)
|
||||||
|
{
|
||||||
|
curX = mActiveCell->getGridX();
|
||||||
|
curY = mActiveCell->getGridY();
|
||||||
|
}
|
||||||
|
const MyGUI::IntRect intersection = { std::max(x, curX) - mCellDistance, std::max(y, curY) - mCellDistance,
|
||||||
|
std::min(x, curX) + mCellDistance, std::min(y, curY) + mCellDistance };
|
||||||
|
|
||||||
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
|
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
|
||||||
const MyGUI::IntRect currentView = createRect({ x, y }, mCellDistance);
|
const MyGUI::IntRect currentView = createRect({ x, y }, mCellDistance);
|
||||||
|
@ -407,17 +416,14 @@ namespace MWGui
|
||||||
for (auto& widget : mDoorMarkersToRecycle)
|
for (auto& widget : mDoorMarkersToRecycle)
|
||||||
widget->setVisible(false);
|
widget->setVisible(false);
|
||||||
|
|
||||||
for (auto const& cell : mMaps)
|
for (auto const& entry : mMaps)
|
||||||
{
|
{
|
||||||
if (mHasALastActiveCell && !intersection.inside({ cell.mCellX, cell.mCellY }))
|
if (mHasALastActiveCell && !intersection.inside({ entry.mCellX, entry.mCellY }))
|
||||||
mLocalMapRender->removeExteriorCell(cell.mCellX, cell.mCellY);
|
mLocalMapRender->removeExteriorCell(entry.mCellX, entry.mCellY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurX = x;
|
mActiveCell = &cell;
|
||||||
mCurY = y;
|
|
||||||
mInterior = interior;
|
|
||||||
mChanged = false;
|
|
||||||
|
|
||||||
for (int mx = 0; mx < mNumCells; ++mx)
|
for (int mx = 0; mx < mNumCells; ++mx)
|
||||||
{
|
{
|
||||||
|
@ -441,7 +447,7 @@ namespace MWGui
|
||||||
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||||
|
|
||||||
if (!mInterior)
|
if (mActiveCell->isExterior())
|
||||||
mHasALastActiveCell = true;
|
mHasALastActiveCell = true;
|
||||||
|
|
||||||
updateMagicMarkers();
|
updateMagicMarkers();
|
||||||
|
@ -580,7 +586,7 @@ namespace MWGui
|
||||||
|
|
||||||
if (!entry.mMapTexture)
|
if (!entry.mMapTexture)
|
||||||
{
|
{
|
||||||
if (!mInterior)
|
if (mActiveCell->isExterior())
|
||||||
requestMapRender(&MWBase::Environment::get().getWorldModel()->getExterior(
|
requestMapRender(&MWBase::Environment::get().getWorldModel()->getExterior(
|
||||||
ESM::ExteriorCellLocation(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)));
|
ESM::ExteriorCellLocation(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)));
|
||||||
|
|
||||||
|
@ -626,12 +632,12 @@ namespace MWGui
|
||||||
mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
|
mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
|
||||||
mInteriorDoorMarkerWidgets.clear();
|
mInteriorDoorMarkerWidgets.clear();
|
||||||
|
|
||||||
if (mInterior)
|
if (!mActiveCell->isExterior())
|
||||||
{
|
{
|
||||||
for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets)
|
for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets)
|
||||||
widget->setVisible(false);
|
widget->setVisible(false);
|
||||||
|
|
||||||
MWWorld::CellStore& cell = worldModel->getInterior(mPrefix);
|
MWWorld::CellStore& cell = worldModel->getInterior(mActiveCell->getNameId());
|
||||||
world->getDoorMarkers(cell, doors);
|
world->getDoorMarkers(cell, doors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -678,7 +684,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
currentDoorMarkersWidgets().push_back(markerWidget);
|
currentDoorMarkersWidgets().push_back(markerWidget);
|
||||||
if (!mInterior)
|
if (mActiveCell->isExterior())
|
||||||
mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget);
|
mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,8 +707,7 @@ namespace MWGui
|
||||||
MWWorld::CellStore* markedCell = nullptr;
|
MWWorld::CellStore* markedCell = nullptr;
|
||||||
ESM::Position markedPosition;
|
ESM::Position markedPosition;
|
||||||
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
|
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
|
||||||
if (markedCell && markedCell->isExterior() == !mInterior
|
if (markedCell && markedCell->getCell()->getWorldSpace() == mActiveCell->getWorldSpace())
|
||||||
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->getNameId(), mPrefix)))
|
|
||||||
{
|
{
|
||||||
MarkerUserData markerPos(mLocalMapRender);
|
MarkerUserData markerPos(mLocalMapRender);
|
||||||
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||||
|
@ -870,11 +875,11 @@ namespace MWGui
|
||||||
int y = (int(widgetPos.top / float(mapWidgetSize)) - mCellDistance) * -1;
|
int y = (int(widgetPos.top / float(mapWidgetSize)) - mCellDistance) * -1;
|
||||||
float nX = widgetPos.left / float(mapWidgetSize) - int(widgetPos.left / float(mapWidgetSize));
|
float nX = widgetPos.left / float(mapWidgetSize) - int(widgetPos.left / float(mapWidgetSize));
|
||||||
float nY = widgetPos.top / float(mapWidgetSize) - int(widgetPos.top / float(mapWidgetSize));
|
float nY = widgetPos.top / float(mapWidgetSize) - int(widgetPos.top / float(mapWidgetSize));
|
||||||
x += mCurX;
|
x += mActiveCell->getGridX();
|
||||||
y += mCurY;
|
y += mActiveCell->getGridY();
|
||||||
|
|
||||||
osg::Vec2f worldPos;
|
osg::Vec2f worldPos;
|
||||||
if (mInterior)
|
if (!mActiveCell->isExterior())
|
||||||
{
|
{
|
||||||
worldPos = mLocalMapRender->interiorMapToWorldPosition(nX, nY, x, y);
|
worldPos = mLocalMapRender->interiorMapToWorldPosition(nX, nY, x, y);
|
||||||
}
|
}
|
||||||
|
@ -886,7 +891,7 @@ namespace MWGui
|
||||||
|
|
||||||
mEditingMarker.mWorldX = worldPos.x();
|
mEditingMarker.mWorldX = worldPos.x();
|
||||||
mEditingMarker.mWorldY = worldPos.y();
|
mEditingMarker.mWorldY = worldPos.y();
|
||||||
ESM::RefId clickedId = ESM::Cell::generateIdForCell(!mInterior, LocalMapBase::mPrefix, x, y);
|
ESM::RefId clickedId = getCellIdInWorldSpace(*mActiveCell, x, y);
|
||||||
|
|
||||||
mEditingMarker.mCell = clickedId;
|
mEditingMarker.mCell = clickedId;
|
||||||
|
|
||||||
|
@ -977,7 +982,7 @@ namespace MWGui
|
||||||
resizeGlobalMap();
|
resizeGlobalMap();
|
||||||
|
|
||||||
float x = mCurPos.x(), y = mCurPos.y();
|
float x = mCurPos.x(), y = mCurPos.y();
|
||||||
if (mInterior)
|
if (!mActiveCell->isExterior())
|
||||||
{
|
{
|
||||||
auto pos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
|
auto pos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
|
||||||
x = pos.x();
|
x = pos.x();
|
||||||
|
@ -1020,7 +1025,7 @@ namespace MWGui
|
||||||
resizeGlobalMap();
|
resizeGlobalMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
MapWindow::~MapWindow() {}
|
MapWindow::~MapWindow() = default;
|
||||||
|
|
||||||
void MapWindow::setCellName(const std::string& cellName)
|
void MapWindow::setCellName(const std::string& cellName)
|
||||||
{
|
{
|
||||||
|
@ -1289,7 +1294,7 @@ namespace MWGui
|
||||||
mMarkers.clear();
|
mMarkers.clear();
|
||||||
|
|
||||||
mGlobalMapRender->clear();
|
mGlobalMapRender->clear();
|
||||||
mChanged = true;
|
mActiveCell = nullptr;
|
||||||
|
|
||||||
for (auto& widgetPair : mGlobalMapMarkers)
|
for (auto& widgetPair : mGlobalMapMarkers)
|
||||||
MyGUI::Gui::getInstance().destroyWidget(widgetPair.first.widget);
|
MyGUI::Gui::getInstance().destroyWidget(widgetPair.first.widget);
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace ESM
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
class Cell;
|
||||||
class CellStore;
|
class CellStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +78,7 @@ namespace MWGui
|
||||||
virtual ~LocalMapBase();
|
virtual ~LocalMapBase();
|
||||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius);
|
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius);
|
||||||
|
|
||||||
void setCellPrefix(const std::string& prefix);
|
void setActiveCell(const MWWorld::Cell& cell);
|
||||||
void setActiveCell(const int x, const int y, bool interior = false);
|
|
||||||
void requestMapRender(const MWWorld::CellStore* cell);
|
void requestMapRender(const MWWorld::CellStore* cell);
|
||||||
void setPlayerDir(const float x, const float y);
|
void setPlayerDir(const float x, const float y);
|
||||||
void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
|
void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
|
||||||
|
@ -115,15 +115,12 @@ namespace MWGui
|
||||||
float mLocalMapZoom = 1.f;
|
float mLocalMapZoom = 1.f;
|
||||||
MWRender::LocalMap* mLocalMapRender;
|
MWRender::LocalMap* mLocalMapRender;
|
||||||
|
|
||||||
int mCurX, mCurY; // the position of the active cell on the global map (in cell coords)
|
const MWWorld::Cell* mActiveCell;
|
||||||
bool mHasALastActiveCell = false;
|
bool mHasALastActiveCell = false;
|
||||||
osg::Vec2f mCurPos; // the position of the player in the world (in cell coords)
|
osg::Vec2f mCurPos; // the position of the player in the world (in cell coords)
|
||||||
|
|
||||||
bool mInterior;
|
|
||||||
MyGUI::ScrollView* mLocalMap;
|
MyGUI::ScrollView* mLocalMap;
|
||||||
MyGUI::ImageBox* mCompass;
|
MyGUI::ImageBox* mCompass;
|
||||||
std::string mPrefix;
|
|
||||||
bool mChanged;
|
|
||||||
bool mFogOfWarToggled;
|
bool mFogOfWarToggled;
|
||||||
bool mFogOfWarEnabled;
|
bool mFogOfWarEnabled;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace MWGui
|
||||||
MessageBoxManager::clear();
|
MessageBoxManager::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MessageBoxManager::getMessagesCount()
|
std::size_t MessageBoxManager::getMessagesCount()
|
||||||
{
|
{
|
||||||
return mMessageBoxes.size();
|
return mMessageBoxes.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace MWGui
|
||||||
bool immediate = false, int defaultFocus = -1);
|
bool immediate = false, int defaultFocus = -1);
|
||||||
bool isInteractiveMessageBox();
|
bool isInteractiveMessageBox();
|
||||||
|
|
||||||
int getMessagesCount();
|
std::size_t getMessagesCount();
|
||||||
|
|
||||||
const InteractiveMessageBox* getInteractiveMessageBox() const { return mInterMessageBoxe.get(); }
|
const InteractiveMessageBox* getInteractiveMessageBox() const { return mInterMessageBoxe.get(); }
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue