Merge branch 'master' of https://gitlab.com/madsbuvi/openmw.git into openxr_vr

# Conflicts:
#	CMakeLists.txt
#	apps/openmw/engine.cpp
#	apps/openmw/mwgui/windowmanagerimp.cpp
#	apps/openmw/mwinput/inputmanagerimp.cpp
#	apps/openmw/mwinput/inputmanagerimp.hpp
#	apps/openmw/mwphysics/physicssystem.cpp
#	apps/openmw/mwrender/water.cpp
#	apps/openmw/mwrender/water.hpp
#	apps/openmw/mwworld/worldimp.cpp
pull/615/head
Mads Buvik Sandvei 5 years ago
commit cbbc82f053

1
.gitignore vendored

@ -30,6 +30,7 @@ cmake-build-*
files/windows/*.aps
## qt-creator
CMakeLists.txt.user*
.vs
## resources
data

@ -23,6 +23,7 @@ Debian:
artifacts:
paths:
- build/artifacts/
MacOS:
tags:
- macos
@ -42,18 +43,21 @@ MacOS:
Windows:
tags:
- win10
- msvc2017
except:
- branches # because our CI VMs are not public, MRs can't use them and timeout
- windows
stage: build
allow_failure: true
script:
# - env # turn on for debugging
- sh %CI_PROJECT_DIR%/CI/before_script.msvc.sh -c Release -p x64 -v 2017 -V
- SET msBuildLocation="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
- call %msBuildLocation% MSVC2017_64\OpenMW.sln /t:Build /p:Configuration=Release /m:%NUMBER_OF_PROCESSORS%
- 7z a OpenMW_MSVC2017_64_%CI_BUILD_REF_NAME%_%CI_BUILD_ID%.zip %CI_PROJECT_DIR%\MSVC2017_64\Release\
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
- echo ${time}
- echo "started by ${GITLAB_USER_NAME}"
# TODO: to anyone wanting to do further work here, we need to figure out how to get the below working
# TODO: on gitlab's new shared windows runners. They currently don't have bash or anything else installed
# TODO: it is currently just a bare windows 10 with powershell.
# - env # turn on for debugging
# - sh %CI_PROJECT_DIR%/CI/before_script.msvc.sh -c Release -p x64 -v 2017 -V
# - SET msBuildLocation="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
# - call %msBuildLocation% MSVC2017_64\OpenMW.sln /t:Build /p:Configuration=Release /m:%NUMBER_OF_PROCESSORS%
# - 7z a OpenMW_MSVC2017_64_%CI_BUILD_REF_NAME%_%CI_BUILD_ID%.zip %CI_PROJECT_DIR%\MSVC2017_64\Release\
cache:
paths:
- deps

@ -25,7 +25,7 @@ addons:
# Audio, Video and Misc. deps
libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev,
# The other ones from OpenMW ppa
libbullet-dev, libopenscenegraph-3.4-dev, libmygui-dev
libbullet-dev, libopenscenegraph-dev, libmygui-dev
]
coverity_scan: # TODO: currently takes too long, disabled openmw/openmw-cs for now.
project:

@ -1,3 +1,22 @@
0.47.0
------
Bug #1952: Incorrect particle lighting
Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs
Bug #3676: NiParticleColorModifier isn't applied properly
Bug #4774: Guards are ignorant of an invisible player that tries to attack them
Bug #5108: Savegame bloating due to inefficient fog textures format
Bug #5358: ForceGreeting always resets the dialogue window completely
Bug #5363: Enchantment autocalc not always 0/1
Bug #5364: Script fails/stops if trying to startscript an unknown script
Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound
Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures
Bug #5370: Opening an unlocked but trapped door uses the key
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work
Bug #5416: Junk non-node records before the root node are not handled gracefully
Feature #5362: Show the soul gems' trapped soul in count dialog
0.46.0
------
@ -153,7 +172,6 @@
Bug #5099: Non-swimming enemies will enter water if player is water walking
Bug #5103: Sneaking state behavior is still inconsistent
Bug #5104: Black Dart's enchantment doesn't trigger at low Enchant levels
Bug #5105: NPCs start combat with werewolves from any distance
Bug #5106: Still can jump even when encumbered
Bug #5110: ModRegion with a redundant numerical argument breaks script execution
Bug #5112: Insufficient magicka for current spell not reflected on HUD icon
@ -171,6 +189,7 @@
Bug #5159: NiMaterialColorController can only control the diffuse color
Bug #5161: Creature companions can't be activated when they are knocked down
Bug #5164: Faction owned items handling is incorrect
Bug #5163: UserData is not copied during node cloning
Bug #5166: Scripts still should be executed after player's death
Bug #5167: Player can select and cast spells before magic menu is enabled
Bug #5168: Force1stPerson and Force3rdPerson commands are not really force view change
@ -204,12 +223,14 @@
Bug #5264: "Damage Fatigue" Magic Effect Can Bring Fatigue below 0
Bug #5269: Editor: Cell lighting in resaved cleaned content files is corrupted
Bug #5278: Console command Show doesn't fall back to global variable after local var not found
Bug #5300: NPCs don't switch from torch to shield when starting combat
Bug #5308: World map copying makes save loading much slower
Bug #5313: Node properties of identical type are not applied in the correct order
Bug #5326: Formatting issues in the settings.cfg
Bug #5328: Skills aren't properly reset for dead actors
Feature #1774: Handle AvoidNode
Bug #5345: Dopey Necromancy does not work due to a missing quote
Bug #5350: An attempt to launch magic bolt causes "AL error invalid value" error
Bug #5352: Light source items' duration is decremented while they aren't visible
Feature #1724: Handle AvoidNode
Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls
Feature #3442: Default values for fallbacks from ini file
@ -240,6 +261,7 @@
Feature #4882: Support for NiPalette node
Feature #4887: Add openmw command option to set initial random seed
Feature #4890: Make Distant Terrain configurable
Feature #4944: Pause audio when OpenMW is minimized
Feature #4958: Support eight blood types
Feature #4962: Add casting animations for magic items
Feature #4968: Scalable UI widget skins
@ -266,10 +288,12 @@
Feature #5170: Editor: Land shape editing, land selection
Feature #5172: Editor: Delete instances/references with keypress in scene window
Feature #5193: Weapon sheathing
Feature #5201: Editor: Show tool outline in scene view, when using editmodes
Feature #5219: Impelement TestCells console command
Feature #5224: Handle NiKeyframeController for NiTriShape
Feature #5274: Editor: Keyboard shortcut to drop objects to ground/obstacle in scene view
Feature #5304: Morrowind-style bump-mapping
Feature #5311: Support for gyroscopic input (e.g. Android)
Feature #5314: Ingredient filter in the alchemy window
Task #4686: Upgrade media decoder to a more current FFmpeg API
Task #4695: Optimize Distant Terrain memory consumption

@ -5,112 +5,36 @@
***
0.46.0
0.47.0
------
The OpenMW team is proud to announce the release of version 0.46.0! Grab it from our Downloads Page for all operating systems. ***short summary: shadows, recastnavigation, etc.***
The OpenMW team is proud to announce the release of version 0.47.0! Grab it from our Downloads Page for all operating systems. ***short summary: XXX ***
Check out the release video (***add link***) and the OpenMW-CS release video (***add link***) by the ***add flattering adjective*** Atahualpa, and see below for the full list of changes.
Known Issues:
- There's currently no way to redirect the logging output to the command prompt on Windows Release builds -- this will be resolved in version 0.46.0
- To use generic Linux binaries, Qt4 and libpng12 must be installed on your system
- On macOS, launching OpenMW from OpenMW-CS requires OpenMW.app and OpenMW-CS.app to be siblings
New Features:
- NIF files which contain an "AvoidNode" are ignored by the pathfinding algorithm (#1724)
- Navmeshes are used for AI pathfinding which should resolve most related issues (#2229)
- Movement input from gamepad joysticks is transformed into analogue values (#3025)
- Sane default values for openmw.cfg file to overcome the original morrowind.ini file (#3442)
- Option to invert x-axis for controllers (#3610)
- Local variables of objects selected in the console can now be directly read and set without explicitly stating the object (#3893)
- In-game option to enable or disable controllers (#3980)
- Sneak mode can be toggled using a controller (#4001)
- Controllers use original engine's default key bindings (#4360)
- Support for sheathing animations, including weapon holstering, scabbards (except for throwing weapons), and quivers for projectiles (#4673)
- Support for "NiRollController" in NIF files to ensure correct rotation of models in "Weapon Sheathing" mod (#4675)
- Support for native animated containers (#4730)
- Support for VAO ("Vertex Array Objects") from OSG 3.5.6 or later (#4756)
- Support for "NiSwitchNode" in NIF files to allow future implementation of native support for extended features like harvestable plants or glowing - windows (#4812)
- Native support for glowing windows (and other daytime-dependent meshes) by adding internal day-night-mode switch (#4836)
- Shadows (#4851)
- More configuration options for in-game water reflections (#4859)
- Command line option to specify a random seed to be used by the game's random-number generator ("RNG") for debugging purposes (#4887)
- Configuration options for distant terrain to adjust quality and performance impact (#4890)
- Dialogue to split item stacks now displays the name of the trapped soul for stacks of soul gems (#5362)
New Editor Features:
- "Faction Ranks" table for "Faction" records (#4209)
- Changes to height editing can be cancelled without changes to data (press esc to cancel) (#4840)
- Land heightmap/shape editing and vertex selection (#5170)
- Deleting instances with a keypress (#5172)
- Dropping objects with keyboard shortcuts (#5274)
- ?
Bug Fixes:
- The Mouse Wheel can now be used for key bindings (#2679)
- Scripted Items cannot be stacked anymore to avoid multiple script execution (#2969)
- Stray text after an "else" statement is now ignored, like in the original engine, to handle mods which erroneously use "else if" statements (#3006)
- "SetPos" and "SetPosition" commands now more closely replicate the original engine's behaviour (#3109)
- "Reserved keys [F3], [F4], [F10], and [F11] cannot be assigned to in-game controls anymore (#3282)
- Windows: Reserved [Windows] key cannot be assigned to in-game controls anymore (#3282)"
- Windows: Windows-internal display scaling no longer breaks main menu (#3623)
- Normal maps on mirrored UVs are no longer inverted (#3733)
- Teleporting attempts are now also detected if teleporting is disabled to ensure compatibility with certain mods (#3765)
- Throwing weapons are now correctly rotated during throwing animation when using the "Improved Thrown Weapon Projectiles" mod (#3778)
- Birthsign abilities are no longer restored upon loading to ensure mod compatibility (#4329)
- Player character's model is no longer scaled in first-person mode to prevent issues with arrows obscuring the crosshair (#4383)
- Optional: Ranged attacks now bypass normal weapon resistance or weakness if ammunition and/or bow are appropriate (#4384)
- Fall damage is now also applied when first reloading a savegame and when your character is near the ground in the loaded game (#4411)
- Rain drops are no longer delayed when your character emerges from water (#4540)
- ESM record for prison markers is now hardcoded like, e.g., door markers or temple markers (#4701)
- Loading a savegame which includes active messages no longer crashes the game (#4714)
- An empty pointer actor no longer throws an exception upon exiting the dialogue menu (#4715)
- Inventory paper doll no longer simultaneously displays shield and two-handed weapon during drawing and holstering animations (#4720)
- "Reset actors" command ("ra") no longer tries to reset actors originating from inactive cells, e.g., followers (#4723)
- "Reset actors" command ("ra") now traces reset actors to the ground and also resets fall damage (#4723)"
- Land texture records can now be overwritten by content files to create mods like "Winter in Morrowind" (#4736)
- Disabling collision no longer forces your character to walking speed, but also allows them to run or sneak (#4746)
- NPCs now also use the skeleton associated with their specified model, not only the animations (#4747)
- Sneaking und swimming idle animations are no longer interrupted if your character is in attack-ready state in first-person view (#4750)
- Numerical fallback values with invalid values (e.g., stray text) in the openmw.cfg file no longer crash or break the game (#4768)
- Character's "jumping" flag is no longer unnecessarily reset to ensure compatibility with certain mods, e.g., "Sotha Sil Expanded" (#4775)
- Calling "GetSpellEffects", "GetEffect", or "GetSpell" function on non-actor objects now returns 0, fixing issues with "Sotha Sil Expanded" - (#4778)
- AI values for actors without AIDT ("AI Data") subrecord are now set to zero upon loading instead of filling in "random" values (#4778)
- Running and sneaking are now also considered in in-game checks when your character is in midair, fixing an issue with the "Reign of Fire" mod - (#4797)
- Collision checks are now immediately updated when an object is moved to ensure compatibility with "Sotha Sil Expanded" (#4800)
- Stray special characters before the "begin" statement of a script are now ignored to ensure, once again, compatibility with "Sotha Sil Expanded" - (#4803)
- Particle nodes with an empty "sizes" array are now correctly loaded and no longer cause an exception (#4804)
- Handling of "root bone" and "bip01" nodes in NIF files now matches the original engine's behaviour to ensure compatibility with "Skyrim: Home of - the Nords" (#4810)
- Creatures without specified sound files now fallback to the sounds of the first creature sharing the same model (#4813)
- "Journal" command now also closes a quest when the specified "finish quest" entry has a lower value than the current one for that quest (#4815)
- Spell effects are no longer applied when a spell is successfully absorbed (#4820)
- World state is no longer updated for every in-game hour your character is in jail but only once, which should significantly reduce loading times - (#4823)
- "NiUVController" in NIF files now only affects textures which use the specified "UV Set" index, usually 0; ensures compatibility with "Glow in the Dahrk" (#4827)
- Visual effects ("VFX") for magic effects are now played immediately after the effect is triggered to not accidentally skip the VFX, e.g., when actors drink potions in battle (#4828)
- Meshes with "NiLODNode" or "NiSwitchNode" no longer cause crashes when they contain particles (#4837)
- Localisations can now make use of implicit keywords to create hyperlinks in dialogue text (#4841)
- Actors outside of the processing range no longer appear for one frame when they are spawned (#4860)
- Stray text after a local-variable declaration is now ignored to ensure mod compatibility (#4867)
- Range and default values of AI data fields now match the original engine's ones (#4876)
- "Startup" scripts are now always run once upon starting OpenMW (#4877)
- Stray explicit reference calls for global variables are now ignored to ensure mod compatibility, e.g., with "Sotha Sil Expanded" (#4888)
- Title screen music now loops (#4896)
- "Specular power" is no longer hardcoded but uses the specified value in the shader code (#4916)
- Werewolves can now also attack if their transformation happened during an attack move (#4922)
- Plug-ins with valid empty subrecords are now correctly loaded, which fixes issues with the "DC - Return of Great House Dagoth" mod (#4938)
- Hand-to-hand attacks are now movement-based when the "always use best attack" option is turned off, like in the original engine (#4942)
- NiParticleColorModifier in NIF files is now properly handled which solves issues regarding particle effects, e.g., smoke and fire (#1952, #3676)
- Targetting non-unique actors in scripts is now supported (#2311)
- Guards no longer ignore attacks of invisible players but rather initiate dialogue and flee if the player resists being arrested (#4774)
- Changing the dialogue window without closing it no longer clears the dialogue history in order to allow, e.g., emulation of three-way dialogue via ForceGreeting (#5358)
- Scripts which try to start a non-existent global script now skip that step and continue execution instead of breaking (#5364)
- Selecting already equipped spells or magic items via hotkey no longer triggers the equip sound to play (#5367)
- 'Scale' argument in levelled creature lists is now taken into account when spawning creatures from such lists (#5369)
- Morrowind legacy madness: Using a key on a trapped door/container now only disarms the trap if the door/container is locked (#5370)
Editor Bug Fixes:
- Certain numerical fields now only accept unsigned 8-bit integers to avoid overflows (#2987)
- Preview option is now disabled for levelled lists (#4703)
- Opening the "Scene" view from the "Instances" table now also works for exterior cells (#4705)
- Colour fields in interior-cell records now also use the colour picker widget (#4745)
- Cloned, added, or moved instances no longer disappear at load-time (#4748)
- "Clear" function in the content selector no longer tries to execute a "Remove" action on an empty file list (#4757)
- Terrain texture editing for plugins now correctly handles drags from base file (#4904)
- Engine no longer tries to swap buffers of windows which weren't exposed to Qt's window management system (#4911)
- Minimap doesn't get corrupted, when editing new omwgame (#5177)
- Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400)
Miscellaneous:
- Upgraded to FFMPEG3 for media decoding (#4686)
- Optimised terrain code to drastically increase performance with distant terrain enabled (#4695)
- Windows: Added support for NMake to the prebuild script (#4721)
- Prevent save-game bloating by using an appropriate fog texture format (#5108)
- Ensure that 'Enchantment autocalc" flag is treated as flag in OpenMW-CS and in our esm tools (#5363)

@ -0,0 +1,26 @@
& "${env:COMSPEC}" /c ActivateMSVC.bat "&&" set | ForEach-Object {
$name, $value = $_ -split '=', 2
Set-Content env:\"$name" $value
}
$MissingTools = $false
$tools = "cl", "link", "rc", "mt", "awooga"
$descriptions = "MSVC Compiler", "MSVC Linker", "MS Windows Resource Compiler", "MS Windows Manifest Tool", "A made up command"
for ($i = 0; $i -lt $tools.Length; $i++) {
$present = $true
try {
Get-Command $tools[$i] *>&1 | Out-Null
$present = $present -and $?
} catch {
$present = $false
}
if (!$present) {
Write-Warning "$($tools[$i]) ($($descriptions[$i])) missing."
$MissingTools = $true
}
}
if ($MissingTools) {
Write-Error "Some build tools were unavailable after activating MSVC in the shell. It's likely that your Visual Studio $MSVC_DISPLAY_YEAR installation needs repairing."
exit 1
}

@ -0,0 +1,76 @@
#!/bin/bash
set -euo pipefail
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "Error: Script not sourced."
echo "You must source this script for it to work, i.e. "
echo "source ./activate_msvc.sh"
echo "or"
echo ". ./activate_msvc.sh"
exit 1
fi
command -v unixPathAsWindows >/dev/null 2>&1 || function unixPathAsWindows {
if command -v cygpath >/dev/null 2>&1; then
cygpath -w $1
else
echo "$1" | sed "s,^/\([^/]\)/,\\1:/," | sed "s,/,\\\\,g"
fi
}
function windowsSystemPathAsUnix {
if command -v cygpath >/dev/null 2>&1; then
cygpath -u -p $1
else
IFS=';' read -r -a paths <<< "$1"
declare -a convertedPaths
for entry in paths; do
convertedPaths+=(windowsPathAsUnix $entry)
done
convertedPath=printf ":%s" ${convertedPaths[@]}
echo ${convertedPath:1}
fi
}
# capture CMD environment so we know what's been changed
declare -A originalCmdEnv
originalIFS="$IFS"
IFS=$'\n\r'
for pair in $(cmd //c "set"); do
IFS='=' read -r -a separatedPair <<< "${pair}"
originalCmdEnv["${separatedPair[0]}"]="${separatedPair[1]}"
done
# capture CMD environment in a shell with MSVC activated
cmdEnv="$(cmd //c "$(unixPathAsWindows "$(dirname "${BASH_SOURCE[0]}")")\ActivateMSVC.bat" "&&" set)"
declare -A cmdEnvChanges
for pair in $cmdEnv; do
if [ -n "$pair" ]; then
IFS='=' read -r -a separatedPair <<< "${pair}"
key="${separatedPair[0]}"
value="${separatedPair[1]}"
if ! [ ${originalCmdEnv[$key]+_} ] || [ "${originalCmdEnv[$key]}" != "$value" ]; then
if [ $key != 'PATH' ] && [ $key != 'path' ] && [ $key != 'Path' ]; then
export "$key=$value"
else
export PATH=$(windowsSystemPathAsUnix $value)
fi
fi
fi
done
MISSINGTOOLS=0
command -v cl >/dev/null 2>&1 || { echo "Error: cl (MSVC Compiler) missing."; MISSINGTOOLS=1; }
command -v link >/dev/null 2>&1 || { echo "Error: link (MSVC Linker) missing."; MISSINGTOOLS=1; }
command -v rc >/dev/null 2>&1 || { echo "Error: rc (MS Windows Resource Compiler) missing."; MISSINGTOOLS=1; }
command -v mt >/dev/null 2>&1 || { echo "Error: mt (MS Windows Manifest Tool) missing."; MISSINGTOOLS=1; }
if [ $MISSINGTOOLS -ne 0 ]; then
echo "Some build tools were unavailable after activating MSVC in the shell. It's likely that your Visual Studio $MSVC_DISPLAY_YEAR installation needs repairing."
return 1
fi
IFS="$originalIFS"

@ -5,5 +5,5 @@ brew outdated pkgconfig || brew upgrade pkgconfig
brew install qt
brew install ccache
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-110f3d3.zip -o ~/openmw-deps.zip
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null

@ -25,7 +25,6 @@ ${ANALYZE} cmake \
-DBUILD_ESSIMPORTER=${BUILD_OPENMW_CS} \
-DBUILD_WIZARD=${BUILD_OPENMW_CS} \
-DBUILD_NIFTEST=${BUILD_OPENMW_CS} \
-DBUILD_MYGUI_PLUGIN=${BUILD_OPENMW_CS} \
-DBUILD_UNITTESTS=1 \
-DUSE_SYSTEM_TINYXML=1 \
-DDESIRED_QT_VERSION=5 \

@ -1,25 +1,50 @@
#!/bin/bash
# set -x # turn-on for debugging
function wrappedExit {
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
exit $1
else
return $1
fi
}
MISSINGTOOLS=0
command -v 7z >/dev/null 2>&1 || { echo "Error: 7z (7zip) is not on the path."; MISSINGTOOLS=1; }
command -v cmake >/dev/null 2>&1 || { echo "Error: cmake (CMake) is not on the path."; MISSINGTOOLS=1; }
command -v python >/dev/null 2>&1 || { echo "Warning: Python is not on the path, automatic Qt installation impossible."; }
if [ $MISSINGTOOLS -ne 0 ]; then
exit 1
wrappedExit 1
fi
WORKINGDIR="$(pwd)"
case "$WORKINGDIR" in
*[[:space:]]*)
echo "Error: Working directory contains spaces."
exit 1
wrappedExit 1
;;
esac
set -euo pipefail
function windowsPathAsUnix {
if command -v cygpath >/dev/null 2>&1; then
cygpath -u $1
else
echo "$1" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,"
fi
}
function unixPathAsWindows {
if command -v cygpath >/dev/null 2>&1; then
cygpath -w $1
else
echo "$1" | sed "s,^/\([^/]\)/,\\1:/," | sed "s,/,\\\\,g"
fi
}
APPVEYOR=${APPVEYOR:-}
CI=${CI:-}
STEP=${STEP:-}
@ -32,10 +57,19 @@ KEEP=""
UNITY_BUILD=""
VS_VERSION=""
NMAKE=""
NINJA=""
PDBS=""
PLATFORM=""
CONFIGURATION=""
TEST_FRAMEWORK=""
GOOGLE_INSTALL_ROOT=""
INSTALL_PREFIX="."
BULLET_DOUBLE=""
BULLET_DBL=""
BULLET_DBL_DISPLAY="Single precision"
ACTIVATE_MSVC=""
SINGLE_CONFIG=""
while [ $# -gt 0 ]; do
ARGSTR=$1
@ -44,7 +78,7 @@ while [ $# -gt 0 ]; do
if [ ${ARGSTR:0:1} != "-" ]; then
echo "Unknown argument $ARGSTR"
echo "Try '$0 -h'"
exit 1
wrappedExit 1
fi
for (( i=1; i<${#ARGSTR}; i++ )); do
@ -56,6 +90,9 @@ while [ $# -gt 0 ]; do
d )
SKIP_DOWNLOAD=true ;;
D )
BULLET_DOUBLE=true ;;
e )
SKIP_EXTRACT=true ;;
@ -71,11 +108,17 @@ while [ $# -gt 0 ]; do
n )
NMAKE=true ;;
N )
NINJA=true ;;
p )
PLATFORM=$1
shift ;;
P )
PDBS=true ;;
c )
CONFIGURATION=$1
shift ;;
@ -83,14 +126,20 @@ while [ $# -gt 0 ]; do
t )
TEST_FRAMEWORK=true ;;
i )
INSTALL_PREFIX=$(echo "$1" | sed 's;\\;/;g' | sed -E 's;/+;/;g')
shift ;;
h )
cat <<EOF
Usage: $0 [-cdehkpuvV]
Usage: $0 [-cdehkpuvVi]
Options:
-c <Release/Debug>
Set the configuration, can also be set with environment variable CONFIGURATION.
-d
Skip checking the downloads.
-D
Use double-precision Bullet
-e
Skip extracting dependencies.
-h
@ -106,23 +155,33 @@ Options:
-v <2013/2015/2017/2019>
Choose the Visual Studio version to use.
-n
Produce NMake makefiles instead of a Visual Studio solution.
Produce NMake makefiles instead of a Visual Studio solution. Cannout be used with -N.
-N
Produce Ninja (multi-config if CMake is new enough to support it) files instead of a Visual Studio solution. Cannot be used with -n..
-P
Download debug symbols where available
-V
Run verbosely
-i
CMake install prefix
EOF
exit 0
wrappedExit 0
;;
* )
echo "Unknown argument $ARG."
echo "Try '$0 -h'"
exit 1 ;;
wrappedExit 1 ;;
esac
done
done
if [ -n "$NMAKE" ]; then
command -v nmake -? >/dev/null 2>&1 || { echo "Error: nmake (NMake) is not on the path. Make sure you have the necessary environment variables set for command-line C++ development (for example, by starting from a Developer Command Prompt)."; exit 1; }
if [ -n "$NMAKE" ] || [ -n "$NINJA" ]; then
if [ -n "$NMAKE" ] && [ -n "$NINJA" ]; then
echo "Cannout run in NMake and Ninja mode at the same time."
wrappedExit 1
fi
ACTIVATE_MSVC=true
fi
if [ -z $VERBOSE ]; then
@ -132,7 +191,7 @@ fi
if [ -z $APPVEYOR ]; then
echo "Running prebuild outside of Appveyor."
DIR=$(echo "$0" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,")
DIR=$(windowsPathAsUnix "${BASH_SOURCE[0]}")
cd $(dirname "$DIR")/..
else
echo "Running prebuild in Appveyor."
@ -257,6 +316,7 @@ case $VS_VERSION in
MSVC_REAL_VER="16"
MSVC_VER="14.2"
MSVC_YEAR="2015"
MSVC_REAL_YEAR="2019"
MSVC_DISPLAY_YEAR="2019"
BOOST_VER="1.71.0"
BOOST_VER_URL="1_71_0"
@ -269,6 +329,7 @@ case $VS_VERSION in
MSVC_REAL_VER="15"
MSVC_VER="14.1"
MSVC_YEAR="2015"
MSVC_REAL_YEAR="2017"
MSVC_DISPLAY_YEAR="2017"
BOOST_VER="1.67.0"
BOOST_VER_URL="1_67_0"
@ -281,6 +342,7 @@ case $VS_VERSION in
MSVC_REAL_VER="14"
MSVC_VER="14.0"
MSVC_YEAR="2015"
MSVC_REAL_YEAR="2015"
MSVC_DISPLAY_YEAR="2015"
BOOST_VER="1.67.0"
BOOST_VER_URL="1_67_0"
@ -288,15 +350,8 @@ case $VS_VERSION in
;;
12|12.0|2013 )
GENERATOR="Visual Studio 12 2013"
TOOLSET="vc120"
MSVC_REAL_VER="12"
MSVC_VER="12.0"
MSVC_YEAR="2013"
MSVC_DISPLAY_YEAR="2013"
BOOST_VER="1.58.0"
BOOST_VER_URL="1_58_0"
BOOST_VER_SDK="105800"
echo "Visual Studio 2013 is no longer supported"
exit 1
;;
esac
@ -315,7 +370,7 @@ case $PLATFORM in
* )
echo "Unknown platform $PLATFORM."
exit 1
wrappedExit 1
;;
esac
@ -342,9 +397,18 @@ fi
if [ -n "$NMAKE" ]; then
GENERATOR="NMake Makefiles"
SINGLE_CONFIG=true
fi
if [ -n "$NINJA" ]; then
GENERATOR="Ninja Multi-Config"
if ! cmake -E capabilities | grep -F "$GENERATOR" > /dev/null; then
SINGLE_CONFIG=true
GENERATOR="Ninja"
fi
fi
if [ $MSVC_REAL_VER -ge 16 ]; then
if [ $MSVC_REAL_VER -ge 16 ] && [ -z "$NMAKE" ] && [ -z "$NINJA" ]; then
if [ $BITS -eq 64 ]; then
add_cmake_opts "-G\"$GENERATOR\" -A x64"
else
@ -354,7 +418,7 @@ else
add_cmake_opts "-G\"$GENERATOR\""
fi
if [ -n "$NMAKE" ]; then
if [ -n "$SINGLE_CONFIG" ]; then
add_cmake_opts "-DCMAKE_BUILD_TYPE=${BUILD_CONFIG}"
fi
@ -362,6 +426,12 @@ if ! [ -z $UNITY_BUILD ]; then
add_cmake_opts "-DOPENMW_UNITY_BUILD=True"
fi
if [ -n "$BULLET_DOUBLE" ]; then
BULLET_DBL="-double"
BULLET_DBL_DISPLAY="Double precision"
add_cmake_opts "-DBULLET_USE_DOUBLES=True"
fi
echo
echo "==================================="
echo "Starting prebuild on MSVC${MSVC_DISPLAY_YEAR} WIN${BITS}"
@ -386,45 +456,54 @@ if [ -z $SKIP_DOWNLOAD ]; then
fi
# Bullet
download "Bullet 2.86" \
"https://www.lysator.liu.se/~ace/OpenMW/deps/Bullet-2.86-msvc${MSVC_YEAR}-win${BITS}.7z" \
"Bullet-2.86-msvc${MSVC_YEAR}-win${BITS}.7z"
download "Bullet 2.89 (${BULLET_DBL_DISPLAY})" \
"https://rgw.ctrl-c.liu.se/openmw/Deps/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" \
"Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z"
# FFmpeg
download "FFmpeg 3.2.4" \
"https://ffmpeg.zeranoe.com/builds/win${BITS}/shared/ffmpeg-3.2.4-win${BITS}-shared.zip" \
"ffmpeg-3.2.4-win${BITS}.zip" \
"https://ffmpeg.zeranoe.com/builds/win${BITS}/dev/ffmpeg-3.2.4-win${BITS}-dev.zip" \
"ffmpeg-3.2.4-dev-win${BITS}.zip"
download "FFmpeg 4.2.2" \
"https://ffmpeg.zeranoe.com/builds/win${BITS}/shared/ffmpeg-4.2.2-win${BITS}-shared.zip" \
"ffmpeg-4.2.2-win${BITS}.zip" \
"https://ffmpeg.zeranoe.com/builds/win${BITS}/dev/ffmpeg-4.2.2-win${BITS}-dev.zip" \
"ffmpeg-4.2.2-dev-win${BITS}.zip"
# MyGUI
download "MyGUI 3.2.2" \
"https://www.lysator.liu.se/~ace/OpenMW/deps/MyGUI-3.2.2-msvc${MSVC_YEAR}-win${BITS}.7z" \
"MyGUI-3.2.2-msvc${MSVC_YEAR}-win${BITS}.7z"
download "MyGUI 3.4.0" \
"https://rgw.ctrl-c.liu.se/openmw/Deps/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \
"MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z"
if [ -n "$PDBS" ]; then
download "MyGUI symbols" \
"https://rgw.ctrl-c.liu.se/openmw/Deps/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \
"MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z"
fi
# OpenAL
download "OpenAL-Soft 1.19.1" \
"http://openal-soft.org/openal-binaries/openal-soft-1.19.1-bin.zip" \
"OpenAL-Soft-1.19.1.zip"
download "OpenAL-Soft 1.20.1" \
"http://openal-soft.org/openal-binaries/openal-soft-1.20.1-bin.zip" \
"OpenAL-Soft-1.20.1.zip"
# OSG
download "OpenSceneGraph 3.4.1-scrawl" \
"https://www.lysator.liu.se/~ace/OpenMW/deps/OSG-3.4.1-scrawl-msvc${MSVC_YEAR}-win${BITS}.7z" \
"OSG-3.4.1-scrawl-msvc${MSVC_YEAR}-win${BITS}.7z"
download "OpenSceneGraph 3.6.5" \
"https://rgw.ctrl-c.liu.se/openmw/Deps/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \
"OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z"
if [ -n "$PDBS" ]; then
download "OpenSceneGraph symbols" \
"https://rgw.ctrl-c.liu.se/openmw/Deps/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \
"OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z"
fi
# Qt
if [ -z $APPVEYOR ]; then
if [ $BITS == "64" ]; then
QT_SUFFIX="_64"
else
QT_SUFFIX=""
if [ "${MSVC_REAL_YEAR}" = "2015" ] && [ "${BITS}" = "32" ]; then
echo "Qt no longer provides MSVC2015 Win32 packages, switch to 64-bit or a newer Visual Studio. Sorry."
exit 1
fi
download "Qt 5.7.0" \
"https://download.qt.io/new_archive/qt/5.7/5.7.0/qt-opensource-windows-x86-msvc${MSVC_YEAR}${QT_SUFFIX}-5.7.0.exe" \
"qt-5.7.0-msvc${MSVC_YEAR}-win${BITS}.exe" \
"https://www.lysator.liu.se/~ace/OpenMW/deps/qt-5-install.qs" \
"qt-5-install.qs"
download "AQt installer" \
"https://files.pythonhosted.org/packages/f3/bb/aee972f08deecca31bfc46b5aedfad1ce6c7f3aaf1288d685e4a914b53ac/aqtinstall-0.8-py2.py3-none-any.whl" \
"aqtinstall-0.8-py2.py3-none-any.whl"
fi
# SDL2
@ -449,7 +528,13 @@ cd .. #/..
BUILD_DIR="MSVC${MSVC_DISPLAY_YEAR}_${BITS}"
if [ -n "$NMAKE" ]; then
BUILD_DIR="${BUILD_DIR}_NMake_${BUILD_CONFIG}"
BUILD_DIR="${BUILD_DIR}_NMake"
elif [ -n "$NINJA" ]; then
BUILD_DIR="${BUILD_DIR}_Ninja"
fi
if [ -n "$SINGLE_CONFIG" ]; then
BUILD_DIR="${BUILD_DIR}_${BUILD_CONFIG}"
fi
if [ -z $KEEP ]; then
@ -487,10 +572,10 @@ fi
# We work around this by installing to root of the current working drive and then move it to our deps
# get the current working drive's root, we'll install to that temporarily
CWD_DRIVE_ROOT="$(powershell -command '(get-location).Drive.Root')Boost_temp"
CWD_DRIVE_ROOT_BASH=$(echo "$CWD_DRIVE_ROOT" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,")
CWD_DRIVE_ROOT_BASH=$(windowsPathAsUnix "$CWD_DRIVE_ROOT")
if [ -d CWD_DRIVE_ROOT_BASH ]; then
printf "Cannot continue, ${CWD_DRIVE_ROOT_BASH} aka ${CWD_DRIVE_ROOT} already exists. Please remove before re-running. ";
exit 1;
wrappedExit 1;
fi
if [ -d ${BOOST_SDK} ] && grep "BOOST_VERSION ${BOOST_VER_SDK}" Boost/boost/version.hpp > /dev/null; then
@ -526,15 +611,15 @@ fi
cd $DEPS
echo
# Bullet
printf "Bullet 2.86... "
printf "Bullet 2.89 (${BULLET_DBL_DISPLAY})... "
{
cd $DEPS_INSTALL
if [ -d Bullet ]; then
printf -- "Exists. (No version checking) "
elif [ -z $SKIP_EXTRACT ]; then
rm -rf Bullet
eval 7z x -y "${DEPS}/Bullet-2.86-msvc${MSVC_YEAR}-win${BITS}.7z" $STRIP
mv "Bullet-2.86-msvc${MSVC_YEAR}-win${BITS}" Bullet
eval 7z x -y "${DEPS}/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" $STRIP
mv "Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}" Bullet
fi
export BULLET_ROOT="$(real_pwd)/Bullet"
echo Done.
@ -542,21 +627,21 @@ printf "Bullet 2.86... "
cd $DEPS
echo
# FFmpeg
printf "FFmpeg 3.2.4... "
printf "FFmpeg 4.2.2... "
{
cd $DEPS_INSTALL
if [ -d FFmpeg ] && grep "FFmpeg version: 3.2.4" FFmpeg/README.txt > /dev/null; then
if [ -d FFmpeg ] && grep "4.2.2" FFmpeg/README.txt > /dev/null; then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
rm -rf FFmpeg
eval 7z x -y "${DEPS}/ffmpeg-3.2.4-win${BITS}.zip" $STRIP
eval 7z x -y "${DEPS}/ffmpeg-3.2.4-dev-win${BITS}.zip" $STRIP
mv "ffmpeg-3.2.4-win${BITS}-shared" FFmpeg
cp -r "ffmpeg-3.2.4-win${BITS}-dev/"* FFmpeg/
rm -rf "ffmpeg-3.2.4-win${BITS}-dev"
eval 7z x -y "${DEPS}/ffmpeg-4.2.2-win${BITS}.zip" $STRIP
eval 7z x -y "${DEPS}/ffmpeg-4.2.2-dev-win${BITS}.zip" $STRIP
mv "ffmpeg-4.2.2-win${BITS}-shared" FFmpeg
cp -r "ffmpeg-4.2.2-win${BITS}-dev/"* FFmpeg/
rm -rf "ffmpeg-4.2.2-win${BITS}-dev"
fi
export FFMPEG_HOME="$(real_pwd)/FFmpeg"
add_runtime_dlls "$(pwd)/FFmpeg/bin/"{avcodec-57,avformat-57,avutil-55,swresample-2,swscale-4}.dll
add_runtime_dlls "$(pwd)/FFmpeg/bin/"{avcodec-58,avformat-58,avutil-56,swresample-3,swscale-5}.dll
if [ $BITS -eq 32 ]; then
add_cmake_opts "-DCMAKE_EXE_LINKER_FLAGS=\"/machine:X86 /safeseh:no\""
fi
@ -565,62 +650,66 @@ printf "FFmpeg 3.2.4... "
cd $DEPS
echo
# MyGUI
printf "MyGUI 3.2.2... "
printf "MyGUI 3.4.0... "
{
cd $DEPS_INSTALL
if [ -d MyGUI ] && \
grep "MYGUI_VERSION_MAJOR 3" MyGUI/include/MYGUI/MyGUI_Prerequest.h > /dev/null && \
grep "MYGUI_VERSION_MINOR 2" MyGUI/include/MYGUI/MyGUI_Prerequest.h > /dev/null && \
grep "MYGUI_VERSION_PATCH 2" MyGUI/include/MYGUI/MyGUI_Prerequest.h > /dev/null
grep "MYGUI_VERSION_MINOR 4" MyGUI/include/MYGUI/MyGUI_Prerequest.h > /dev/null && \
grep "MYGUI_VERSION_PATCH 0" MyGUI/include/MYGUI/MyGUI_Prerequest.h > /dev/null
then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
rm -rf MyGUI
eval 7z x -y "${DEPS}/MyGUI-3.2.2-msvc${MSVC_YEAR}-win${BITS}.7z" $STRIP
mv "MyGUI-3.2.2-msvc${MSVC_YEAR}-win${BITS}" MyGUI
eval 7z x -y "${DEPS}/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" $STRIP
[ -n "$PDBS" ] && eval 7z x -y "${DEPS}/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" $STRIP
mv "MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}" MyGUI
fi
export MYGUI_HOME="$(real_pwd)/MyGUI"
if [ $CONFIGURATION == "Debug" ]; then
SUFFIX="_d"
MYGUI_CONFIGURATION="Debug"
else
SUFFIX=""
MYGUI_CONFIGURATION="RelWithDebInfo"
fi
add_runtime_dlls "$(pwd)/MyGUI/bin/${CONFIGURATION}/MyGUIEngine${SUFFIX}.dll"
add_runtime_dlls "$(pwd)/MyGUI/bin/${MYGUI_CONFIGURATION}/MyGUIEngine${SUFFIX}.dll"
echo Done.
}
cd $DEPS
echo
# OpenAL
printf "OpenAL-Soft 1.19.1... "
printf "OpenAL-Soft 1.20.1... "
{
if [ -d openal-soft-1.19.1-bin ]; then
if [ -d openal-soft-1.20.1-bin ]; then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
rm -rf openal-soft-1.19.1-bin
eval 7z x -y OpenAL-Soft-1.19.1.zip $STRIP
rm -rf openal-soft-1.20.1-bin
eval 7z x -y OpenAL-Soft-1.20.1.zip $STRIP
fi
OPENAL_SDK="$(real_pwd)/openal-soft-1.19.1-bin"
OPENAL_SDK="$(real_pwd)/openal-soft-1.20.1-bin"
add_cmake_opts -DOPENAL_INCLUDE_DIR="${OPENAL_SDK}/include/AL" \
-DOPENAL_LIBRARY="${OPENAL_SDK}/libs/Win${BITS}/OpenAL32.lib"
add_runtime_dlls "$(pwd)/openal-soft-1.19.1-bin/bin/WIN${BITS}/soft_oal.dll:OpenAL32.dll"
add_runtime_dlls "$(pwd)/openal-soft-1.20.1-bin/bin/WIN${BITS}/soft_oal.dll:OpenAL32.dll"
echo Done.
}
cd $DEPS
echo
# OSG
printf "OSG 3.4.1-scrawl... "
printf "OSG 3.6.5... "
{
cd $DEPS_INSTALL
if [ -d OSG ] && \
grep "OPENSCENEGRAPH_MAJOR_VERSION 3" OSG/include/osg/Version > /dev/null && \
grep "OPENSCENEGRAPH_MINOR_VERSION 4" OSG/include/osg/Version > /dev/null && \
grep "OPENSCENEGRAPH_PATCH_VERSION 1" OSG/include/osg/Version > /dev/null
grep "OPENSCENEGRAPH_MINOR_VERSION 6" OSG/include/osg/Version > /dev/null && \
grep "OPENSCENEGRAPH_PATCH_VERSION 5" OSG/include/osg/Version > /dev/null
then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
rm -rf OSG
eval 7z x -y "${DEPS}/OSG-3.4.1-scrawl-msvc${MSVC_YEAR}-win${BITS}.7z" $STRIP
mv "OSG-3.4.1-scrawl-msvc${MSVC_YEAR}-win${BITS}" OSG
eval 7z x -y "${DEPS}/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" $STRIP
[ -n "$PDBS" ] && eval 7z x -y "${DEPS}/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" $STRIP
mv "OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}" OSG
fi
OSG_SDK="$(real_pwd)/OSG"
add_cmake_opts -DOSG_DIR="$OSG_SDK"
@ -629,17 +718,17 @@ printf "OSG 3.4.1-scrawl... "
else
SUFFIX=""
fi
add_runtime_dlls "$(pwd)/OSG/bin/"{OpenThreads,zlib,libpng*}${SUFFIX}.dll \
add_runtime_dlls "$(pwd)/OSG/bin/"{OpenThreads,zlib,libpng}${SUFFIX}.dll \
"$(pwd)/OSG/bin/osg"{,Animation,DB,FX,GA,Particle,Text,Util,Viewer,Shadow}${SUFFIX}.dll
add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.4.1/osgdb_"{bmp,dds,freetype,jpeg,osg,png,tga}${SUFFIX}.dll
add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.4.1/osgdb_serializers_osg"{,animation,fx,ga,particle,text,util,viewer,shadow}${SUFFIX}.dll
add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_"{bmp,dds,freetype,jpeg,osg,png,tga}${SUFFIX}.dll
add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_serializers_osg"{,animation,fx,ga,particle,text,util,viewer,shadow}${SUFFIX}.dll
echo Done.
}
cd $DEPS
echo
# Qt
if [ -z $APPVEYOR ]; then
printf "Qt 5.7.0... "
printf "Qt 5.15.0... "
else
printf "Qt 5.13 AppVeyor... "
fi
@ -651,21 +740,44 @@ fi
fi
if [ -z $APPVEYOR ]; then
cd $DEPS_INSTALL
QT_SDK="$(real_pwd)/Qt/5.7/msvc${MSVC_YEAR}${SUFFIX}"
if [ -d Qt ] && head -n2 Qt/InstallationLog.txt | grep "5.7.0" > /dev/null; then
QT_SDK="$(real_pwd)/Qt/5.15.0/msvc${MSVC_REAL_YEAR}${SUFFIX}"
if [ -d 'Qt/5.15.0' ]; then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
pushd "$DEPS" > /dev/null
if ! [ -d 'aqt-venv' ]; then
echo " Creating Virtualenv for aqt..."
eval python -m venv aqt-venv $STRIP
fi
if [ -d 'aqt-venv/bin' ]; then
VENV_BIN_DIR='bin'
elif [ -d 'aqt-venv/Scripts' ]; then
VENV_BIN_DIR='Scripts'
else
echo "Error: Failed to create virtualenv."
exit 1
fi
if ! [ -e "aqt-venv/${VENV_BIN_DIR}/aqt" ]; then
echo " Installing aqt wheel into virtualenv..."
eval "aqt-venv/${VENV_BIN_DIR}/pip" install aqtinstall-0.8-py2.py3-none-any.whl $STRIP
fi
popd > /dev/null
rm -rf Qt
cp "${DEPS}/qt-5-install.qs" qt-install.qs
sed -i "s|INSTALL_DIR|$(real_pwd)/Qt|" qt-install.qs
sed -i "s/qt.VERSION.winBITS_msvcYEAR/qt.57.win${BITS}_msvc${MSVC_YEAR}${SUFFIX}/" qt-install.qs
printf -- "(Installation might take a while) "
"${DEPS}/qt-5.7.0-msvc${MSVC_YEAR}-win${BITS}.exe" --script qt-install.qs --silent
mv qt-install.qs Qt/
echo Done.
mkdir Qt
cd Qt
eval "${DEPS}/aqt-venv/${VENV_BIN_DIR}/aqt" install 5.15.0 windows desktop "win${BITS}_msvc${MSVC_REAL_YEAR}${SUFFIX}" $STRIP
printf " Cleaning up extraneous data... "
rm -r "$(real_pwd)/Qt/"{dist,Docs,Examples,Tools,vcredist,components.xml,MaintenanceTool.dat,MaintenanceTool.exe,MaintenanceTool.ini,network.xml,qt-install.qs}
rm -rf Qt/{aqtinstall.log,Tools}
echo Done.
fi
cd $QT_SDK
add_cmake_opts -DDESIRED_QT_VERSION=5 \
-DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \
@ -688,7 +800,7 @@ fi
else
SUFFIX=""
fi
DIR=$(echo "${QT_SDK}" | sed "s,\\\\,/,g" | sed "s,\(.\):,/\\1,")
DIR=$(windowsPathAsUnix "${QT_SDK}")
add_runtime_dlls "${DIR}/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${SUFFIX}.dll
add_qt_platform_dlls "${DIR}/plugins/platforms/qwindows${SUFFIX}.dll"
echo Done.
@ -759,10 +871,8 @@ echo
cd $DEPS_INSTALL/..
echo
echo "Setting up OpenMW build..."
add_cmake_opts -DBUILD_BSATOOL=no \
-DBUILD_ESMTOOL=no \
-DBUILD_MYGUI_PLUGIN=no \
-DOPENMW_MP_BUILD=on
add_cmake_opts -DOPENMW_MP_BUILD=on
add_cmake_opts -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}"
if [ ! -z $CI ]; then
case $STEP in
components )
@ -801,14 +911,15 @@ fi
#if [ -z $CI ]; then
echo "- Copying Runtime DLLs..."
DLL_PREFIX=""
if [ -z $NMAKE ]; then
if [ -z $SINGLE_CONFIG ]; then
mkdir -p $BUILD_CONFIG
DLL_PREFIX="$BUILD_CONFIG/"
fi
for DLL in $RUNTIME_DLLS; do
TARGET="$(basename "$DLL")"
if [[ "$DLL" == *":"* ]]; then
IFS=':'; SPLIT=( ${DLL} ); unset IFS
originalIFS="$IFS"
IFS=':'; SPLIT=( ${DLL} ); IFS=$originalIFS
DLL=${SPLIT[0]}
TARGET=${SPLIT[1]}
fi
@ -817,10 +928,10 @@ fi
done
echo
echo "- OSG Plugin DLLs..."
mkdir -p ${DLL_PREFIX}osgPlugins-3.4.1
mkdir -p ${DLL_PREFIX}osgPlugins-3.6.5
for DLL in $OSG_PLUGINS; do
echo " $(basename $DLL)."
cp "$DLL" ${DLL_PREFIX}osgPlugins-3.4.1
cp "$DLL" ${DLL_PREFIX}osgPlugins-3.6.5
done
echo
echo "- Qt Platform DLLs..."
@ -831,6 +942,42 @@ fi
done
echo
#fi
if ! [ -z $ACTIVATE_MSVC ]; then
echo -n "- Activating MSVC in the current shell... "
command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; }
MSVC_INSTALLATION_PATH=$(vswhere -legacy -version "[$MSVC_VER,$(awk "BEGIN { print $MSVC_REAL_VER + 1; exit }"))" -property installationPath)
if [ $MSVC_REAL_VER -ge 15 ]; then
echo "@\"${MSVC_INSTALLATION_PATH}\Common7\Tools\VsDevCmd.bat\" -no_logo -arch=$([ $BITS -eq 64 ] && echo "amd64" || echo "x86") -host_arch=$([ $(uname -m) == 'x86_64' ] && echo "amd64" || echo "x86")" > ActivateMSVC.bat
else
if [ $(uname -m) == 'x86_64' ]; then
if [ $BITS -eq 64 ]; then
compiler=amd64
else
compiler=amd64_x86
fi
else
if [ $BITS -eq 64 ]; then
compiler=x86_amd64
else
compiler=x86
fi
fi
echo "@\"${MSVC_INSTALLATION_PATH}\VC\vcvarsall.bat\" $compiler" > ActivateMSVC.bat
fi
cp "../CI/activate_msvc.sh" .
sed -i "s/\$MSVC_DISPLAY_YEAR/$MSVC_DISPLAY_YEAR/g" activate_msvc.sh
source ./activate_msvc.sh
cp "../CI/ActivateMSVC.ps1" .
sed -i "s/\$MSVC_DISPLAY_YEAR/$MSVC_DISPLAY_YEAR/g" ActivateMSVC.ps1
echo "done."
echo
fi
if [ -z $VERBOSE ]; then
printf -- "- Configuring... "
else
@ -841,8 +988,34 @@ RET=$?
if [ -z $VERBOSE ]; then
if [ $RET -eq 0 ]; then
echo Done.
if [ -n $ACTIVATE_MSVC ]; then
echo
echo "Note: you must manually activate MSVC for the shell in which you want to do the build."
echo
echo "Some scripts have been created in the build directory to do so in an existing shell."
echo "Bash: source activate_msvc.sh"
echo "CMD: ActivateMSVC.bat"
echo "PowerShell: ActivateMSVC.ps1"
echo
echo "You may find options to launch a Development/Native Tools/Cross Tools shell in your start menu or Visual Studio."
echo
if [ $(uname -m) == 'x86_64' ]; then
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x64_x64
else
inheritEnvironments=msvc_x64
fi
else
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x86_x64
else
inheritEnvironments=msvc_x86
fi
fi
echo "In Visual Studio 15.3 (2017 Update 3) or later, try setting '\"inheritEnvironments\": [ \"$inheritEnvironments\" ]' in CMakeSettings.json to build in the IDE."
fi
else
echo Failed.
fi
fi
exit $RET
wrappedExit $RET

@ -19,6 +19,5 @@ cmake \
-D OPENMW_OSX_DEPLOYMENT=TRUE \
-D DESIRED_QT_VERSION=5 \
-D BUILD_ESMTOOL=FALSE \
-D BUILD_MYGUI_PLUGIN=FALSE \
-G"Unix Makefiles" \
..

@ -1,6 +1,6 @@
#!/bin/sh -e
git clone -b release-1.8.1 https://github.com/google/googletest.git
git clone -b release-1.10.0 https://github.com/google/googletest.git
cd googletest
mkdir build
cd build

@ -8,11 +8,11 @@ option(BUILD_ESSIMPORTER "Build ESS (Morrowind save game) importer" ON)
option(BUILD_BSATOOL "Build BSA extractor" ON)
option(BUILD_ESMTOOL "Build ESM inspector" ON)
option(BUILD_NIFTEST "Build nif file tester" ON)
option(BUILD_MYGUI_PLUGIN "Build MyGUI plugin for OpenMW resources, to use with MyGUI tools" ON)
option(BUILD_DOCS "Build documentation." OFF)
option(BUILD_VR_OPENXR "Build VR support using OpenXR" on)
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest" OFF)
option(BULLET_USE_DOUBLES "Use double precision for Bullet" OFF)
if (NOT BUILD_LAUNCHER AND NOT BUILD_OPENCS AND NOT BUILD_WIZARD)
set(USE_QT FALSE)
@ -55,7 +55,7 @@ endif()
message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 46)
set(OPENMW_VERSION_MINOR 47)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_VERSION_COMMITHASH "")
@ -64,6 +64,8 @@ set(OPENMW_VERSION_COMMITDATE "")
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
set(OPENMW_DOC_BASEURL "https://openmw.readthedocs.io/en/master/")
set(GIT_CHECKOUT FALSE)
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
find_package(Git)
@ -322,7 +324,7 @@ set(Boost_NO_BOOST_CMAKE ON)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
find_package(MyGUI 3.2.2 REQUIRED)
find_package(SDL2 REQUIRED)
find_package(SDL2 2.0.9 REQUIRED)
find_package(OpenAL REQUIRED)
find_package(Bullet ${REQUIRED_BULLET_VERSION} REQUIRED COMPONENTS BulletCollision LinearMath)
@ -404,19 +406,13 @@ copy_resource_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
configure_resource_file(${OpenMW_SOURCE_DIR}/files/gamecontrollerdb.txt
"${OpenMW_BINARY_DIR}" "gamecontrollerdb.txt")
configure_resource_file(${OpenMW_SOURCE_DIR}/files/gamecontrollerdb_204.txt
"${OpenMW_BINARY_DIR}" "gamecontrollerdb_204.txt")
configure_resource_file(${OpenMW_SOURCE_DIR}/files/gamecontrollerdb_205.txt
"${OpenMW_BINARY_DIR}" "gamecontrollerdb_205.txt")
if (NOT WIN32 AND NOT APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
"${OpenMW_BINARY_DIR}/openmw.desktop")
configure_file(${OpenMW_SOURCE_DIR}/files/org.openmw.launcher.desktop
"${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml
"${OpenMW_BINARY_DIR}/openmw.appdata.xml")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.desktop
"${OpenMW_BINARY_DIR}/openmw-cs.desktop")
configure_file(${OpenMW_SOURCE_DIR}/files/org.openmw.cs.desktop
"${OpenMW_BINARY_DIR}/org.openmw.cs.desktop")
endif()
# CXX Compiler settings
@ -482,19 +478,16 @@ IF(NOT WIN32 AND NOT APPLE)
IF(BUILD_WIZARD)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-wizard" DESTINATION "${BINDIR}" )
ENDIF(BUILD_WIZARD)
#if(BUILD_MYGUI_PLUGIN)
# INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
#ENDIF(BUILD_MYGUI_PLUGIN)
# Install licenses
INSTALL(FILES "files/mygui/DejaVu Font License.txt" DESTINATION "${LICDIR}" )
# Install icon and desktop file
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.appdata.xml" DESTINATION "${DATAROOTDIR}/metainfo" COMPONENT "openmw")
IF(BUILD_OPENCS)
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "opencs")
INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.cs.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "opencs")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/openmw-cs.png" DESTINATION "${ICONDIR}" COMPONENT "opencs")
ENDIF(BUILD_OPENCS)
@ -503,8 +496,6 @@ IF(NOT WIN32 AND NOT APPLE)
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb_204.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb_205.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
IF(BUILD_OPENCS)
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
@ -532,15 +523,6 @@ if(WIN32)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/settings-default.cfg" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb_204.txt" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/gamecontrollerdb_204.txt" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb_205.txt" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/gamecontrollerdb_205.txt" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
if(BUILD_MYGUI_PLUGIN)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Debug/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
ENDIF(BUILD_MYGUI_PLUGIN)
IF(DESIRED_QT_VERSION MATCHES 5)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/platforms" DESTINATION "." CONFIGURATIONS Debug)
@ -627,6 +609,7 @@ endif()
# Components
add_subdirectory (components)
target_compile_definitions(components PRIVATE OPENMW_DOC_BASEURL="${OPENMW_DOC_BASEURL}")
# Apps and tools
if (BUILD_OPENMW)
@ -743,6 +726,7 @@ if (WIN32)
# caused by boost
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
4643 # Forward declaring 'X' in namespace std is not permitted by the C++ Standard. (in *_std_fwd.h files)
5204 # Class has virtual functions, but its trivial destructor is not virtual
# caused by MyGUI
4275 # non dll-interface class 'std::exception' used as base for dll-interface class 'MyGUI::Exception'
@ -956,4 +940,3 @@ if (DOXYGEN_FOUND)
WORKING_DIRECTORY ${OpenMW_BINARY_DIR}
COMMENT "Generating documentation for the github-pages at ${DOXYGEN_PAGES_OUTPUT_DIR}" VERBATIM)
endif ()

@ -21,7 +21,7 @@ Pull Request Guidelines
To facilitate the review process, your pull request description should include the following, if applicable:
* A link back to the bug report or forum discussion that prompted the change. Note: when linking bugs, use the syntax ```[Bug #xyz](https://bugs.openmw.org/issues/#xyz)``` to create a clickable link. Writing only 'Bug #xyz' will unfortunately create a link to the Github pull request with that number instead.
* A link back to the bug report or forum discussion that prompted the change. Note: when linking bugs, use the syntax ```[Bug #xyz](https://gitlab.com/OpenMW/openmw/issues/#xyz)``` to create a clickable link. Writing only 'Bug #xyz' will unfortunately create a link to the Github pull request with that number instead.
* Summary of the changes made
* Reasoning / motivation behind the change
* What testing you have carried out to verify the change

@ -7,7 +7,7 @@ OpenMW is an open-source game engine that supports playing Morrowind by Bethesda
OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
* Version: 0.46.0
* Version: 0.47.0
* License: GPLv3 (see [LICENSE](https://github.com/OpenMW/openmw/blob/master/LICENSE) for more information)
* Website: https://www.openmw.org
* IRC: #openmw on irc.freenode.net

@ -258,18 +258,37 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
if(quiet) continue;
std::cout << " Refnum: " << ref.mRefNum.mIndex << std::endl;
std::cout << " ID: '" << ref.mRefID << "'\n";
std::cout << " Owner: '" << ref.mOwner << "'\n";
std::cout << " Global: '" << ref.mGlobalVariable << "'" << std::endl;
std::cout << " Faction: '" << ref.mFaction << "'" << std::endl;
std::cout << " Faction rank: '" << ref.mFactionRank << "'" << std::endl;
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
std::cout << " Uses/health: '" << ref.mChargeInt << "'\n";
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
std::cout << " ID: " << ref.mRefID << std::endl;
std::cout << " Position: (" << ref.mPos.pos[0] << ", " << ref.mPos.pos[1] << ", " << ref.mPos.pos[2] << ")" << std::endl;
if (ref.mScale != 1.f)
std::cout << " Scale: " << ref.mScale << std::endl;
if (!ref.mOwner.empty())
std::cout << " Owner: " << ref.mOwner << std::endl;
if (!ref.mGlobalVariable.empty())
std::cout << " Global: " << ref.mGlobalVariable << std::endl;
if (!ref.mFaction.empty())
std::cout << " Faction: " << ref.mFaction << std::endl;
if (!ref.mFaction.empty() || ref.mFactionRank != -2)
std::cout << " Faction rank: " << ref.mFactionRank << std::endl;
std::cout << " Enchantment charge: " << ref.mEnchantmentCharge << std::endl;
std::cout << " Uses/health: " << ref.mChargeInt << std::endl;
std::cout << " Gold value: " << ref.mGoldValue << std::endl;
std::cout << " Blocked: " << static_cast<int>(ref.mReferenceBlocked) << std::endl;
std::cout << " Deleted: " << deleted << std::endl;
if (!ref.mKey.empty())
std::cout << " Key: '" << ref.mKey << "'" << std::endl;
std::cout << " Key: " << ref.mKey << std::endl;
std::cout << " Lock level: " << ref.mLockLevel << std::endl;
if (!ref.mTrap.empty())
std::cout << " Trap: " << ref.mTrap << std::endl;
if (!ref.mSoul.empty())
std::cout << " Soul: " << ref.mSoul << std::endl;
if (ref.mTeleport)
{
std::cout << " Destination position: (" << ref.mDoorDest.pos[0] << ", "
<< ref.mDoorDest.pos[1] << ", " << ref.mDoorDest.pos[2] << ")" << std::endl;
if (!ref.mDestCell.empty())
std::cout << " Destination cell: " << ref.mDestCell << std::endl;
}
}
}

@ -4,6 +4,7 @@
#include <components/esm/loadcell.hpp>
#include <components/esm/loadcont.hpp>
#include <components/esm/loadcrea.hpp>
#include <components/esm/loadench.hpp>
#include <components/esm/loadlevlist.hpp>
#include <components/esm/loadligh.hpp>
#include <components/esm/loadmgef.hpp>
@ -726,6 +727,16 @@ std::string creatureFlags(int flags)
return properties;
}
std::string enchantmentFlags(int flags)
{
std::string properties;
if (flags == 0) properties += "[None] ";
if (flags & ESM::Enchantment::Autocalc) properties += "Autocalc ";
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc)) properties += "Invalid ";
properties += Misc::StringUtils::format("(0x%08X)", flags);
return properties;
}
std::string landFlags(int flags)
{
std::string properties;

@ -49,6 +49,7 @@ std::string bodyPartFlags(int flags);
std::string cellFlags(int flags);
std::string containerFlags(int flags);
std::string creatureFlags(int flags);
std::string enchantmentFlags(int flags);
std::string landFlags(int flags);
std::string creatureListFlags(int flags);
std::string itemListFlags(int flags);

@ -714,7 +714,7 @@ void Record<ESM::Enchantment>::print()
<< " (" << mData.mData.mType << ")" << std::endl;
std::cout << " Cost: " << mData.mData.mCost << std::endl;
std::cout << " Charge: " << mData.mData.mCharge << std::endl;
std::cout << " AutoCalc: " << mData.mData.mAutocalc << std::endl;
std::cout << " Flags: " << enchantmentFlags(mData.mData.mFlags) << std::endl;
printEffectList(mData.mEffects);
std::cout << " Deleted: " << mIsDeleted << std::endl;
}

@ -1,6 +1,7 @@
#include "maindialog.hpp"
#include <components/version/version.hpp>
#include <components/misc/helpviewer.hpp>
#include <QDate>
#include <QMessageBox>
@ -54,12 +55,15 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
iconWidget->setCurrentRow(0);
iconWidget->setFlow(QListView::LeftToRight);
QPushButton *helpButton = new QPushButton(tr("Help"));
QPushButton *playButton = new QPushButton(tr("Play"));
buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole);
buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
connect(buttonBox, SIGNAL(helpRequested()), this, SLOT(help()));
// Remove what's this? button
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
@ -614,3 +618,8 @@ void Launcher::MainDialog::play()
if (mGameInvoker->startProcess(QLatin1String("openmw"), true))
return qApp->quit();
}
void Launcher::MainDialog::help()
{
Misc::HelpViewer::openHelp("reference/index.html");
}

@ -59,6 +59,7 @@ namespace Launcher
public slots:
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
void play();
void help();
private slots:
void wizardStarted();

@ -89,7 +89,7 @@ opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode instancemode instanceselectionmode instancemovemode
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
cellwater terraintexturemode actor terrainselection terrainshapemode
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw
)
opencs_units_noqt (view/render
@ -97,6 +97,10 @@ opencs_units_noqt (view/render
cellarrow cellmarker cellborder pathgrid
)
opencs_hdrs_noqt (view/render
mask
)
opencs_units (view/tools
reportsubview reporttable searchsubview searchbox merge

@ -356,7 +356,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1];
refRecord.mRefNum.save (writer, false, "MVRF");
writer.writeHNT ("CNDT", moved.mTarget, 8);
writer.writeHNT ("CNDT", moved.mTarget);
}
refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);

@ -271,6 +271,8 @@ void CSMPrefs::State::declare()
declareShortcut ("document-file-newaddon", "New Addon", QKeySequence());
declareShortcut ("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O));
declareShortcut ("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S));
declareShortcut ("document-help-help", "Help", QKeySequence(Qt::Key_F1));
declareShortcut ("document-help-tutorial", "Tutorial", QKeySequence());
declareShortcut ("document-file-verify", "Verify", QKeySequence());
declareShortcut ("document-file-merge", "Merge", QKeySequence());
declareShortcut ("document-file-errorlog", "Open Load Error Log", QKeySequence());

@ -33,13 +33,10 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message
CSMWorld::UniversalId id( CSMWorld::UniversalId::Type_BodyPart, bodyPart.mId );
// Check BYDT
if (bodyPart.mData.mPart > 14 )
if (bodyPart.mData.mPart >= ESM::BodyPart::MP_Count )
messages.add(id, "Invalid part", "", CSMDoc::Message::Severity_Error);
if (bodyPart.mData.mFlags > 3 )
messages.add(id, "Invalid flags", "", CSMDoc::Message::Severity_Error);
if (bodyPart.mData.mType > 2 )
if (bodyPart.mData.mType > ESM::BodyPart::MT_Armor )
messages.add(id, "Invalid type", "", CSMDoc::Message::Severity_Error);
// Check MODL
@ -48,9 +45,12 @@ void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &message
else if ( mMeshes.searchId( bodyPart.mModel ) == -1 )
messages.add(id, "Model '" + bodyPart.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error);
// Check FNAM
if ( bodyPart.mRace.empty() )
messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error);
else if ( mRaces.searchId( bodyPart.mRace ) == -1 )
messages.add(id, "Race '" + bodyPart.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error);
// Check FNAM for skin body parts (for non-skin body parts it's meaningless)
if ( bodyPart.mData.mType == ESM::BodyPart::MT_Skin )
{
if ( bodyPart.mRace.empty() )
messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error);
else if ( mRaces.searchId( bodyPart.mRace ) == -1 )
messages.add(id, "Race '" + bodyPart.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error);
}
}

@ -91,9 +91,14 @@ std::pair<int, int> CSMWorld::CellCoordinates::toVertexCoords(const osg::Vec3d&
return std::make_pair(x, y);
}
float CSMWorld::CellCoordinates::textureGlobalToWorldCoords(int textureGlobal)
float CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(int textureGlobal)
{
return ESM::Land::REAL_SIZE * static_cast<float>(textureGlobal) / ESM::Land::LAND_TEXTURE_SIZE;
return ESM::Land::REAL_SIZE * (static_cast<float>(textureGlobal) + 0.25f) / ESM::Land::LAND_TEXTURE_SIZE;
}
float CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(int textureGlobal)
{
return ESM::Land::REAL_SIZE * (static_cast<float>(textureGlobal) - 0.25f) / ESM::Land::LAND_TEXTURE_SIZE;
}
float CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(int vertexGlobal)

@ -54,8 +54,11 @@ namespace CSMWorld
///Converts worldspace coordinates to global vertex selection.
static std::pair<int, int> toVertexCoords(const osg::Vec3d& worldPos);
///Converts global texture coordinate to worldspace coordinate that is at the upper left corner of the selected texture.
static float textureGlobalToWorldCoords(int textureGlobal);
///Converts global texture coordinate X to worldspace coordinate, offset by 0.25f.
static float textureGlobalXToWorldCoords(int textureGlobal);
///Converts global texture coordinate Y to worldspace coordinate, offset by 0.25f.
static float textureGlobalYToWorldCoords(int textureGlobal);
///Converts global vertex coordinate to worldspace coordinate
static float vertexGlobalToWorldCoords(int vertexGlobal);

@ -373,7 +373,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
mEnchantments.addColumn (new EnchantmentTypeColumn<ESM::Enchantment>);
mEnchantments.addColumn (new CostColumn<ESM::Enchantment>);
mEnchantments.addColumn (new ChargesColumn2<ESM::Enchantment>);
mEnchantments.addColumn (new AutoCalcColumn<ESM::Enchantment>);
mEnchantments.addColumn (new FlagColumn<ESM::Enchantment> (Columns::ColumnId_AutoCalc, ESM::Enchantment::Autocalc));
// Enchantment effects
mEnchantments.addColumn (new NestedParentColumn<ESM::Enchantment> (Columns::ColumnId_EffectList));
index = mEnchantments.getColumns()-1;

@ -18,10 +18,10 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CellRef ref;
ref.mNew = false;
ESM::MovedCellRef mref;
mref.mRefNum.mIndex = 0;
bool isDeleted = false;
// hack to initialise mindex
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, isDeleted, true, &mref))
while (ESM::Cell::getNextRef(reader, ref, isDeleted, true, &mref))
{
// Keep mOriginalCell empty when in modified (as an indicator that the
// original cell will always be equal the current cell).
@ -60,6 +60,8 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
else
ref.mCell = cell2.mId;
mref.mRefNum.mIndex = 0;
// ignore content file number
std::map<ESM::RefNum, std::string>::iterator iter = cache.begin();
for (; iter != cache.end(); ++iter)

@ -31,6 +31,7 @@
#include "../tools/subviews.hpp"
#include <components/misc/helpviewer.hpp>
#include <components/version/version.hpp>
#include "viewmanager.hpp"
@ -315,6 +316,12 @@ void CSVDoc::View::setupHelpMenu()
{
QMenu *help = menuBar()->addMenu (tr ("Help"));
QAction* helpInfo = createMenuEntry("Help", ":/info.png", help, "document-help-help");
connect (helpInfo, SIGNAL (triggered()), this, SLOT (openHelp()));
QAction* tutorial = createMenuEntry("Tutorial", ":/info.png", help, "document-help-tutorial");
connect (tutorial, SIGNAL (triggered()), this, SLOT (tutorial()));
QAction* about = createMenuEntry("About OpenMW-CS", ":./info.png", help, "document-help-about");
connect (about, SIGNAL (triggered()), this, SLOT (infoAbout()));
@ -708,6 +715,16 @@ void CSVDoc::View::save()
mDocument->save();
}
void CSVDoc::View::openHelp()
{
Misc::HelpViewer::openHelp("manuals/openmw-cs/index.html");
}
void CSVDoc::View::tutorial()
{
Misc::HelpViewer::openHelp("manuals/openmw-cs/tour.html");
}
void CSVDoc::View::infoAbout()
{
// Get current OpenMW version

@ -169,6 +169,10 @@ namespace CSVDoc
void exit();
static void openHelp();
static void tutorial();
void infoAbout();
void infoAboutQt();

@ -1,12 +1,18 @@
#include "editwidget.hpp"
#include <QAbstractItemModel>
#include <QAction>
#include <QContextMenuEvent>
#include <QMenu>
#include <QString>
#include <QApplication>
#include <components/misc/helpviewer.hpp>
#include "../../model/world/data.hpp"
#include "../../model/world/idtablebase.hpp"
#include "../../model/world/columns.hpp"
#include "../../model/prefs/shortcut.hpp"
CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent)
: QLineEdit (parent), mParser (data), mIsEmpty(true)
@ -29,6 +35,13 @@ CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent)
mStateColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Modification);
mDescColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Description);
mHelpAction = new QAction (tr ("Help"), this);
connect (mHelpAction, SIGNAL (triggered()), this, SLOT (openHelp()));
mHelpAction->setIcon(QIcon(":/info.png"));
addAction (mHelpAction);
auto* openHelpShortcut = new CSMPrefs::Shortcut("help", this);
openHelpShortcut->associateAction(mHelpAction);
}
void CSVFilter::EditWidget::textChanged (const QString& text)
@ -211,3 +224,17 @@ std::string CSVFilter::EditWidget::generateFilter (std::pair< std::string, std::
return ss.str();
}
void CSVFilter::EditWidget::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *menu = createStandardContextMenu();
menu->addAction(mHelpAction);
menu->exec(event->globalPos());
delete menu;
}
void CSVFilter::EditWidget::openHelp()
{
Misc::HelpViewer::openHelp("manuals/openmw-cs/record-filters.html");
}

@ -26,6 +26,7 @@ namespace CSVFilter
bool mIsEmpty;
int mStateColumnIndex;
int mDescColumnIndex;
QAction *mHelpAction;
public:
@ -40,6 +41,7 @@ namespace CSVFilter
private:
std::string generateFilter(std::pair<std::string, std::vector<std::string> >& seekedString) const;
void contextMenuEvent (QContextMenuEvent *event) override;
private slots:
@ -51,6 +53,8 @@ namespace CSVFilter
void filterRowsInserted (const QModelIndex& parent, int start, int end);
static void openHelp();
};
}

@ -0,0 +1,307 @@
#include "brushdraw.hpp"
#include <limits>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Array>
#include <osgUtil/LineSegmentIntersector>
#include "../../model/world/cellcoordinates.hpp"
#include "../widget/brushshapes.hpp"
#include "mask.hpp"
CSVRender::BrushDraw::BrushDraw(osg::ref_ptr<osg::Group> parentNode, bool textureMode) :
mParentNode(parentNode), mTextureMode(textureMode)
{
mBrushDrawNode = new osg::Group();
mGeometry = new osg::Geometry();
mBrushDrawNode->addChild(mGeometry);
mParentNode->addChild(mBrushDrawNode);
if (mTextureMode)
mLandSizeFactor = static_cast<float>(ESM::Land::REAL_SIZE) / static_cast<float>(ESM::Land::LAND_TEXTURE_SIZE);
else
mLandSizeFactor = static_cast<float>(ESM::Land::REAL_SIZE) / static_cast<float>(ESM::Land::LAND_SIZE - 1);
}
CSVRender::BrushDraw::~BrushDraw()
{
mBrushDrawNode->removeChild(mGeometry);
mParentNode->removeChild(mBrushDrawNode);
}
float CSVRender::BrushDraw::getIntersectionHeight (const osg::Vec3d& point)
{
osg::Vec3d start = point;
osg::Vec3d end = point;
start.z() = std::numeric_limits<int>::max();
end.z() = std::numeric_limits<int>::lowest();
osg::Vec3d direction = end - start;
// Get intersection
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(
osgUtil::Intersector::MODEL, start, end) );
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
visitor.setTraversalMask(Mask_Terrain);
mParentNode->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
// reject back-facing polygons
if (direction * intersection.getWorldIntersectNormal() > 0)
{
continue;
}
return intersection.getWorldIntersectPoint().z();
}
return 0.0f;
}
void CSVRender::BrushDraw::buildPointGeometry(const osg::Vec3d& point)
{
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry());
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
const float brushOutlineHeight (1.0f);
const float crossHeadSize (8.0f);
osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f);
vertices->push_back(osg::Vec3d(
point.x() - crossHeadSize,
point.y() - crossHeadSize,
getIntersectionHeight(osg::Vec3d(
point.x() - crossHeadSize,
point.y() - crossHeadSize,
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
vertices->push_back(osg::Vec3d(
point.x() + crossHeadSize,
point.y() + crossHeadSize,
getIntersectionHeight(osg::Vec3d(
point.x() + crossHeadSize,
point.y() + crossHeadSize,
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
vertices->push_back(osg::Vec3d(
point.x() + crossHeadSize,
point.y() - crossHeadSize,
getIntersectionHeight(osg::Vec3d(
point.x() + crossHeadSize,
point.y() - crossHeadSize,
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
vertices->push_back(osg::Vec3d(
point.x() - crossHeadSize,
point.y() + crossHeadSize,
getIntersectionHeight(osg::Vec3d(
point.x() - crossHeadSize,
point.y() + crossHeadSize,
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
geom->setVertexArray(vertices);
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 4));
mGeometry = geom;
}
void CSVRender::BrushDraw::buildSquareGeometry(const float& radius, const osg::Vec3d& point)
{
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry());
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
const float brushOutlineHeight (1.0f);
float diameter = radius * 2;
int resolution = static_cast<int>(2.f * diameter / mLandSizeFactor); //half a vertex resolution
float resAdjustedLandSizeFactor = mLandSizeFactor / 2;
osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f);
for (int i = 0; i < resolution; i++)
{
int step = i * resAdjustedLandSizeFactor;
int step2 = (i + 1) * resAdjustedLandSizeFactor;
osg::Vec3d upHorizontalLinePoint1(
point.x() - radius + step,
point.y() - radius,
getIntersectionHeight(osg::Vec3d(
point.x() - radius + step,
point.y() - radius,
point.z())) + brushOutlineHeight);
osg::Vec3d upHorizontalLinePoint2(
point.x() - radius + step2,
point.y() - radius,
getIntersectionHeight(osg::Vec3d(
point.x() - radius + step2,
point.y() - radius,
point.z())) + brushOutlineHeight);
osg::Vec3d upVerticalLinePoint1(
point.x() - radius,
point.y() - radius + step,
getIntersectionHeight(osg::Vec3d(
point.x() - radius,
point.y() - radius + step,
point.z())) + brushOutlineHeight);
osg::Vec3d upVerticalLinePoint2(
point.x() - radius,
point.y() - radius + step2,
getIntersectionHeight(osg::Vec3d(
point.x() - radius,
point.y() - radius + step2,
point.z())) + brushOutlineHeight);
osg::Vec3d downHorizontalLinePoint1(
point.x() + radius - step,
point.y() + radius,
getIntersectionHeight(osg::Vec3d(
point.x() + radius - step,
point.y() + radius,
point.z())) + brushOutlineHeight);
osg::Vec3d downHorizontalLinePoint2(
point.x() + radius - step2,
point.y() + radius,
getIntersectionHeight(osg::Vec3d(
point.x() + radius - step2,
point.y() + radius,
point.z())) + brushOutlineHeight);
osg::Vec3d downVerticalLinePoint1(
point.x() + radius,
point.y() + radius - step,
getIntersectionHeight(osg::Vec3d(
point.x() + radius,
point.y() + radius - step,
point.z())) + brushOutlineHeight);
osg::Vec3d downVerticalLinePoint2(
point.x() + radius,
point.y() + radius - step2,
getIntersectionHeight(osg::Vec3d(
point.x() + radius,
point.y() + radius - step2,
point.z())) + brushOutlineHeight);
vertices->push_back(upHorizontalLinePoint1);
colors->push_back(lineColor);
vertices->push_back(upHorizontalLinePoint2);
colors->push_back(lineColor);
vertices->push_back(upVerticalLinePoint1);
colors->push_back(lineColor);
vertices->push_back(upVerticalLinePoint2);
colors->push_back(lineColor);
vertices->push_back(downHorizontalLinePoint1);
colors->push_back(lineColor);
vertices->push_back(downHorizontalLinePoint2);
colors->push_back(lineColor);
vertices->push_back(downVerticalLinePoint1);
colors->push_back(lineColor);
vertices->push_back(downVerticalLinePoint2);
colors->push_back(lineColor);
}
geom->setVertexArray(vertices);
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, resolution * 8));
mGeometry = geom;
}
void CSVRender::BrushDraw::buildCircleGeometry(const float& radius, const osg::Vec3d& point)
{
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry());
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
const int amountOfPoints = (osg::PI * 2.0f) * radius / 20;
const float step ((osg::PI * 2.0f) / static_cast<float>(amountOfPoints));
const float brushOutlineHeight (1.0f);
osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f);
for (int i = 0; i < amountOfPoints + 2; i++)
{
float angle (i * step);
vertices->push_back(osg::Vec3d(
point.x() + radius * cosf(angle),
point.y() + radius * sinf(angle),
getIntersectionHeight(osg::Vec3d(
point.x() + radius * cosf(angle),
point.y() + radius * sinf(angle),
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
angle = static_cast<float>(i + 1) * step;
vertices->push_back(osg::Vec3d(
point.x() + radius * cosf(angle),
point.y() + radius * sinf(angle),
getIntersectionHeight(osg::Vec3d(
point.x() + radius * cosf(angle),
point.y() + radius * sinf(angle),
point.z()) ) + brushOutlineHeight));
colors->push_back(lineColor);
}
geom->setVertexArray(vertices);
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, amountOfPoints * 2));
mGeometry = geom;
}
void CSVRender::BrushDraw::buildCustomGeometry(const float& radius, const osg::Vec3d& point)
{
// Not implemented
}
void CSVRender::BrushDraw::update(osg::Vec3d point, int brushSize, CSVWidget::BrushShape toolShape)
{
if (mBrushDrawNode->containsNode(mGeometry))
mBrushDrawNode->removeChild(mGeometry);
float radius = (mLandSizeFactor * brushSize) / 2;
osg::Vec3d snapToGridPoint = point;
if (mTextureMode)
{
std::pair<int, int> snapToGridXY = CSMWorld::CellCoordinates::toTextureCoords(point);
float offsetToMiddle = mLandSizeFactor * 0.5f;
snapToGridPoint = osg::Vec3d(
CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(snapToGridXY.first) + offsetToMiddle,
CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(snapToGridXY.second) + offsetToMiddle,
point.z());
}
else
{
std::pair<int, int> snapToGridXY = CSMWorld::CellCoordinates::toVertexCoords(point);
snapToGridPoint = osg::Vec3d(
CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.first),
CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.second),
point.z());
}
switch (toolShape)
{
case (CSVWidget::BrushShape_Point) :
buildPointGeometry(snapToGridPoint);
break;
case (CSVWidget::BrushShape_Square) :
buildSquareGeometry(radius, snapToGridPoint);
break;
case (CSVWidget::BrushShape_Circle) :
buildCircleGeometry(radius, snapToGridPoint);
break;
case (CSVWidget::BrushShape_Custom) :
buildSquareGeometry(1, snapToGridPoint);
//buildCustomGeometry
break;
}
mGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
mBrushDrawNode->addChild(mGeometry);
}
void CSVRender::BrushDraw::hide()
{
if (mBrushDrawNode->containsNode(mGeometry))
mBrushDrawNode->removeChild(mGeometry);
}

@ -0,0 +1,36 @@
#ifndef CSV_RENDER_BRUSHDRAW_H
#define CSV_RENDER_BRUSHDRAW_H
#include <osg/Group>
#include <osg/Geometry>
#include <components/esm/loadland.hpp>
#include "../widget/brushshapes.hpp"
namespace CSVRender
{
class BrushDraw
{
public:
BrushDraw(osg::ref_ptr<osg::Group> parentNode, bool textureMode = false);
~BrushDraw();
void update(osg::Vec3d point, int brushSize, CSVWidget::BrushShape toolShape);
void hide();
private:
void buildPointGeometry(const osg::Vec3d& point);
void buildSquareGeometry(const float& radius, const osg::Vec3d& point);
void buildCircleGeometry(const float& radius, const osg::Vec3d& point);
void buildCustomGeometry(const float& radius, const osg::Vec3d& point);
float getIntersectionHeight (const osg::Vec3d& point);
osg::ref_ptr<osg::Group> mParentNode;
osg::ref_ptr<osg::Group> mBrushDrawNode;
osg::ref_ptr<osg::Geometry> mGeometry;
bool mTextureMode;
float mLandSizeFactor;
};
}
#endif

@ -9,7 +9,6 @@
#include <components/esm/loadcell.hpp>
#include <components/esm/loadland.hpp>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/terrain/terraingrid.hpp>
#include "../../model/world/idtable.hpp"
@ -22,6 +21,7 @@
#include "cellborder.hpp"
#include "cellarrow.hpp"
#include "cellmarker.hpp"
#include "mask.hpp"
#include "pathgrid.hpp"
#include "terrainstorage.hpp"
#include "object.hpp"
@ -92,7 +92,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
std::unique_ptr<Object> object (new Object (mData, mCellNode, id, false));
if (mSubModeElementMask & SceneUtil::Mask_EditorReference)
if (mSubModeElementMask & Mask_Reference)
object->setSubMode (mSubMode);
mObjects.insert (std::make_pair (id, object.release()));
@ -134,7 +134,7 @@ void CSVRender::Cell::updateLand()
else
{
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, mCellNode,
mData.getResourceSystem().get(), mTerrainStorage));
mData.getResourceSystem().get(), mTerrainStorage, Mask_Terrain));
}
mTerrain->loadCell(esmLand.mX, esmLand.mY);
@ -434,7 +434,7 @@ void CSVRender::Cell::reloadAssets()
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
{
if (elementMask & SceneUtil::Mask_EditorReference)
if (elementMask & Mask_Reference)
{
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
@ -451,7 +451,7 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
iter->second->setSelected (selected);
}
}
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
if (mPathgrid && elementMask & Mask_Pathgrid)
{
// Only one pathgrid may be selected, so some operations will only have an effect
// if the pathgrid is already focused
@ -546,12 +546,12 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (un
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & SceneUtil::Mask_EditorReference)
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->getSelected())
result.push_back (iter->second->getTag());
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
if (mPathgrid && elementMask & Mask_Pathgrid)
if (mPathgrid->isSelected())
result.push_back(mPathgrid->getTag());
@ -562,7 +562,7 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getEdited (unsig
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & SceneUtil::Mask_EditorReference)
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->isEdited())
@ -576,7 +576,7 @@ void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
mSubMode = subMode;
mSubModeElementMask = elementMask;
if (elementMask & SceneUtil::Mask_EditorReference)
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
iter->second->setSubMode (subMode);
@ -584,10 +584,10 @@ void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask)
void CSVRender::Cell::reset (unsigned int elementMask)
{
if (elementMask & SceneUtil::Mask_EditorReference)
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
iter->second->reset();
if (mPathgrid && elementMask & SceneUtil::Mask_Pathgrid)
if (mPathgrid && elementMask & Mask_Pathgrid)
mPathgrid->resetIndicators();
}

@ -11,10 +11,11 @@
#include "../../model/prefs/shortcutmanager.hpp"
#include <components/misc/constants.hpp>
#include <components/sceneutil/vismask.hpp>
#include "mask.hpp"
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
: TagBase (SceneUtil::Mask_EditorCellArrow), mArrow (arrow)
: TagBase (Mask_CellArrow), mArrow (arrow)
{}
CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const
@ -174,7 +175,7 @@ CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction,
mParentNode->addChild (mBaseNode);
mBaseNode->setNodeMask (SceneUtil::Mask_EditorCellArrow);
mBaseNode->setNodeMask (Mask_CellArrow);
adjustTransform();
buildShape();

@ -7,7 +7,8 @@
#include <osg/PrimitiveSet>
#include <components/esm/loadland.hpp>
#include <components/sceneutil/vismask.hpp>
#include "mask.hpp"
#include "../../model/world/cellcoordinates.hpp"
@ -19,7 +20,7 @@ CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoor
: mParentNode(cellNode)
{
mBaseNode = new osg::PositionAttitudeTransform();
mBaseNode->setNodeMask(SceneUtil::Mask_EditorCellBorder);
mBaseNode->setNodeMask(Mask_CellBorder);
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
mParentNode->addChild(mBaseNode);

@ -8,7 +8,7 @@
#include <components/misc/constants.hpp>
CSVRender::CellMarkerTag::CellMarkerTag(CellMarker *marker)
: TagBase(SceneUtil::Mask_EditorCellMarker), mMarker(marker)
: TagBase(Mask_CellMarker), mMarker(marker)
{}
CSVRender::CellMarker *CSVRender::CellMarkerTag::getCellMarker() const
@ -79,7 +79,7 @@ CSVRender::CellMarker::CellMarker(
mMarkerNode->getOrCreateStateSet()->setAttribute(mat);
mMarkerNode->setUserData(new CellMarkerTag(this));
mMarkerNode->setNodeMask(SceneUtil::Mask_EditorCellMarker);
mMarkerNode->setNodeMask(Mask_CellMarker);
mCellNode->addChild(mMarkerNode);

@ -11,12 +11,12 @@
#include <components/resource/imagemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/waterutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/world/cell.hpp"
#include "../../model/world/cellcoordinates.hpp"
#include "../../model/world/data.hpp"
#include "mask.hpp"
namespace CSVRender
{
@ -38,7 +38,7 @@ namespace CSVRender
mWaterTransform->setPosition(osg::Vec3f(cellCoords.getX() * CellSize + CellSize / 2.f,
cellCoords.getY() * CellSize + CellSize / 2.f, 0));
mWaterTransform->setNodeMask(SceneUtil::Mask_Water);
mWaterTransform->setNodeMask(Mask_Water);
mParentNode->addChild(mWaterTransform);
mWaterNode = new osg::Geode();

@ -73,6 +73,8 @@ void CSVRender::EditMode::dropEvent (QDropEvent *event) {}
void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {}
void CSVRender::EditMode::mouseMoveEvent (QMouseEvent *event) {}
int CSVRender::EditMode::getSubMode() const
{
return -1;

@ -98,6 +98,8 @@ namespace CSVRender
/// Default-implementation: ignored
virtual void dragMoveEvent (QDragMoveEvent *event);
virtual void mouseMoveEvent (QMouseEvent *event);
/// Default: return -1
virtual int getSubMode() const;
};

@ -21,7 +21,7 @@
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
#include <components/sceneutil/vismask.hpp>
#include "mask.hpp"
#include "object.hpp"
#include "worldspacewidget.hpp"
@ -97,7 +97,7 @@ osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos)
}
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr<osg::Group> parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, "Instance editing",
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, "Instance editing",
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
mDragAxis (-1), mLocked (false), mUnitScaleDist(1), mParentNode (parentNode)
{
@ -157,13 +157,13 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
std::string subMode = mSubMode->getCurrentId();
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), SceneUtil::Mask_EditorReference);
getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), Mask_Reference);
}
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
{
mDragMode = DragMode_None;
getWorldspaceWidget().reset (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().reset (Mask_Reference);
if (mSelectionMode)
{
@ -216,7 +216,7 @@ void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& h
void CSVRender::InstanceMode::primarySelectPressed (const WorldspaceHitResult& hit)
{
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().clearSelection (Mask_Reference);
if (hit.tag)
{
@ -251,13 +251,13 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask());
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Reference);
if (selection.empty())
{
// Only change selection at the start of drag if no object is already selected
if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().clearSelection (Mask_Reference);
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (hit.tag.get()))
{
CSVRender::Object* object = objectTag->mObject;
@ -265,7 +265,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
}
}
selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
selection = getWorldspaceWidget().getSelection (Mask_Reference);
if (selection.empty())
return false;
}
@ -291,7 +291,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos)
mDragMode = DragMode_Scale;
// Calculate scale factor
std::vector<osg::ref_ptr<TagBase> > editedSelection = getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > editedSelection = getWorldspaceWidget().getEdited (Mask_Reference);
osg::Vec3f center = getScreenCoords(getSelectionCenter(editedSelection));
int widgetHeight = getWorldspaceWidget().height();
@ -327,7 +327,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
osg::Vec3f offset;
osg::Quat rotation;
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getEdited (Mask_Reference);
if (mDragMode == DragMode_Move)
{
@ -484,7 +484,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou
void CSVRender::InstanceMode::dragCompleted(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection =
getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().getEdited (Mask_Reference);
QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack();
@ -516,7 +516,7 @@ void CSVRender::InstanceMode::dragCompleted(const QPoint& pos)
void CSVRender::InstanceMode::dragAborted()
{
getWorldspaceWidget().reset (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().reset (Mask_Reference);
mDragMode = DragMode_None;
}
@ -535,7 +535,7 @@ void CSVRender::InstanceMode::dragWheel (int diff, double speedFactor)
offset *= diff * speedFactor;
std::vector<osg::ref_ptr<TagBase> > selection =
getWorldspaceWidget().getEdited (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().getEdited (Mask_Reference);
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
iter!=selection.end(); ++iter)
@ -677,12 +677,12 @@ void CSVRender::InstanceMode::subModeChanged (const std::string& id)
{
mSubModeId = id;
getWorldspaceWidget().abortDrag();
getWorldspaceWidget().setSubMode (getSubModeFromId (id), SceneUtil::Mask_EditorReference);
getWorldspaceWidget().setSubMode (getSubModeFromId (id), Mask_Reference);
}
void CSVRender::InstanceMode::deleteSelectedInstances(bool active)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Reference);
if (selection.empty()) return;
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
@ -695,7 +695,7 @@ void CSVRender::InstanceMode::deleteSelectedInstances(bool active)
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
macro.push(new CSMWorld::DeleteCommand(referencesTable, objectTag->mObject->getReferenceId()));
getWorldspaceWidget().clearSelection (SceneUtil::Mask_EditorReference);
getWorldspaceWidget().clearSelection (Mask_Reference);
}
void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object* object, float objectHeight)
@ -713,22 +713,20 @@ void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object*
osgUtil::IntersectionVisitor visitor(intersector);
if (dropMode == TerrainSep)
visitor.setTraversalMask(SceneUtil::Mask_Terrain);
visitor.setTraversalMask(Mask_Terrain);
if (dropMode == CollisionSep)
visitor.setTraversalMask(SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference);
visitor.setTraversalMask(Mask_Terrain | Mask_Reference);
mParentNode->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
if (it != intersector->getIntersections().end())
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
ESM::Position position = object->getPosition();
object->setEdited (Object::Override_Position);
position.pos[2] = intersection.getWorldIntersectPoint().z() + objectHeight;
object->setPosition(position.pos);
return;
}
}
@ -747,14 +745,14 @@ float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Objec
osgUtil::IntersectionVisitor visitor(intersector);
if (dropMode == Terrain)
visitor.setTraversalMask(SceneUtil::Mask_Terrain);
visitor.setTraversalMask(Mask_Terrain);
if (dropMode == Collision)
visitor.setTraversalMask(SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference);
visitor.setTraversalMask(Mask_Terrain | Mask_Reference);
mParentNode->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
if (it != intersector->getIntersections().end())
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
float collisionLevel = intersection.getWorldIntersectPoint().z();
@ -786,7 +784,7 @@ void CSVRender::InstanceMode::dropSelectedInstancesToTerrainSeparately()
void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString commandMsg)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Reference);
if (selection.empty())
return;
@ -843,7 +841,7 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman
CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worldspacewidget)
: mWorldspaceWidget(worldspacewidget)
{
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
for(osg::ref_ptr<TagBase> tag: selection)
{
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
@ -852,7 +850,7 @@ CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worlds
osg::ref_ptr<osg::Group> objectNodeWithoutGUI = objectTag->mObject->getBaseNode();
osg::ComputeBoundsVisitor computeBounds;
computeBounds.setTraversalMask(SceneUtil::Mask_EditorReference);
computeBounds.setTraversalMask(Mask_Reference);
objectNodeWithoutGUI->accept(computeBounds);
osg::BoundingBox bounds = computeBounds.getBoundingBox();
float boundingBoxOffset = 0.0f;
@ -862,14 +860,14 @@ CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worlds
mObjectHeights.emplace_back(boundingBoxOffset);
mOldMasks.emplace_back(objectNodeWithGUI->getNodeMask());
objectNodeWithGUI->setNodeMask(SceneUtil::Mask_Disabled);
objectNodeWithGUI->setNodeMask(0);
}
}
}
CSVRender::DropObjectDataHandler::~DropObjectDataHandler()
{
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
int counter = 0;
for(osg::ref_ptr<TagBase> tag: selection)
{

@ -6,15 +6,13 @@
#include "../../model/world/idtable.hpp"
#include "../../model/world/commands.hpp"
#include <components/sceneutil/vismask.hpp>
#include "worldspacewidget.hpp"
#include "object.hpp"
namespace CSVRender
{
InstanceSelectionMode::InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget)
: SelectionMode(parent, worldspaceWidget, SceneUtil::Mask_EditorReference)
: SelectionMode(parent, worldspaceWidget, Mask_Reference)
{
mSelectSame = new QAction("Extend selection to instances with same object ID", this);
mDeleteSelection = new QAction("Delete selected instances", this);
@ -38,12 +36,12 @@ namespace CSVRender
void InstanceSelectionMode::selectSame()
{
getWorldspaceWidget().selectAllWithSameParentId(SceneUtil::Mask_EditorReference);
getWorldspaceWidget().selectAllWithSameParentId(Mask_Reference);
}
void InstanceSelectionMode::deleteSelection()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(SceneUtil::Mask_EditorReference);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(Mask_Reference);
CSMWorld::IdTable& referencesTable = dynamic_cast<CSMWorld::IdTable&>(
*getWorldspaceWidget().getDocument().getData().getTableModel(CSMWorld::UniversalId::Type_References));

@ -0,0 +1,32 @@
#ifndef CSV_RENDER_ELEMENTS_H
#define CSV_RENDER_ELEMENTS_H
namespace CSVRender
{
/// Node masks used on the OSG scene graph in OpenMW-CS.
/// @note See the respective file in OpenMW (apps/openmw/mwrender/vismask.hpp)
/// for general usage hints about node masks.
/// @copydoc MWRender::VisMask
enum Mask
{
// elements that are part of the actual scene
Mask_Reference = 0x2,
Mask_Pathgrid = 0x4,
Mask_Water = 0x8,
Mask_Fog = 0x10,
Mask_Terrain = 0x20,
// used within models
Mask_ParticleSystem = 0x100,
Mask_Lighting = 0x200,
// control elements
Mask_CellMarker = 0x10000,
Mask_CellArrow = 0x20000,
Mask_CellBorder = 0x40000
};
}
#endif

@ -29,9 +29,9 @@
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/lightutil.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "actor.hpp"
#include "mask.hpp"
const float CSVRender::Object::MarkerShaftWidth = 30;
@ -58,7 +58,7 @@ namespace
CSVRender::ObjectTag::ObjectTag (Object* object)
: TagBase (SceneUtil::Mask_EditorReference), mObject (object)
: TagBase (Mask_Reference), mObject (object)
{}
QString CSVRender::ObjectTag::getToolTip (bool hideBasics) const
@ -140,7 +140,7 @@ void CSVRender::Object::update()
if (light)
{
bool isExterior = false; // FIXME
SceneUtil::addLight(mBaseNode, light, isExterior);
SceneUtil::addLight(mBaseNode, light, Mask_ParticleSystem, Mask_Lighting, isExterior);
}
}
@ -429,7 +429,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
parentNode->addChild (mRootNode);
mRootNode->setNodeMask(SceneUtil::Mask_EditorReference);
mRootNode->setNodeMask(Mask_Reference);
if (referenceable)
{

@ -21,6 +21,7 @@
#include "../widget/scenetooltoggle2.hpp"
#include "editmode.hpp"
#include "mask.hpp"
#include "cameracontroller.hpp"
#include "cellarrow.hpp"
#include "terraintexturemode.hpp"
@ -126,8 +127,8 @@ void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Button_Terrain, SceneUtil::Mask_Terrain, "Terrain");
//tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true);
tool->addButton (Button_Terrain, Mask_Terrain, "Terrain");
tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true);
}
void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
@ -141,16 +142,16 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
tool->addButton (
new TerrainTextureMode (this, mRootNode, tool), "terrain-texture");
tool->addButton (
new EditMode (this, QIcon (":placeholder"), SceneUtil::Mask_EditorReference, "Terrain vertex paint editing"),
new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain vertex paint editing"),
"terrain-vertex");
tool->addButton (
new EditMode (this, QIcon (":placeholder"), SceneUtil::Mask_EditorReference, "Terrain movement"),
new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain movement"),
"terrain-move");
}
void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
{
if (hit.tag && hit.tag->getMask()==SceneUtil::Mask_EditorCellArrow)
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
{
if (CellArrowTag *cellArrowTag = dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
{
@ -873,9 +874,9 @@ CSVWidget::SceneToolToggle2 *CSVRender::PagedWorldspaceWidget::makeControlVisibi
mControlElements = new CSVWidget::SceneToolToggle2 (parent,
"Controls & Guides Visibility", ":scenetoolbar/scene-view-marker-c", ":scenetoolbar/scene-view-marker-");
mControlElements->addButton (1, SceneUtil::Mask_EditorCellMarker, "Cell Marker");
mControlElements->addButton (2, SceneUtil::Mask_EditorCellArrow, "Cell Arrows");
mControlElements->addButton (4, SceneUtil::Mask_EditorCellBorder, "Cell Border");
mControlElements->addButton (1, Mask_CellMarker, "Cell Marker");
mControlElements->addButton (2, Mask_CellArrow, "Cell Arrows");
mControlElements->addButton (4, Mask_CellBorder, "Cell Border");
mControlElements->setSelectionMask (0xffffffff);

@ -10,7 +10,6 @@
#include <osg/Vec3>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/world/cell.hpp"
#include "../../model/world/commands.hpp"
@ -32,7 +31,7 @@ namespace CSVRender
};
PathgridTag::PathgridTag(Pathgrid* pathgrid)
: TagBase(SceneUtil::Mask_Pathgrid), mPathgrid(pathgrid)
: TagBase(Mask_Pathgrid), mPathgrid(pathgrid)
{
}
@ -71,7 +70,7 @@ namespace CSVRender
mBaseNode->setPosition(osg::Vec3f(mCoords.getX() * CoordScalar, mCoords.getY() * CoordScalar, 0.f));
mBaseNode->setUserData(mTag);
mBaseNode->setUpdateCallback(new PathgridNodeCallback());
mBaseNode->setNodeMask(SceneUtil::Mask_Pathgrid);
mBaseNode->setNodeMask(Mask_Pathgrid);
mParent->addChild(mBaseNode);
mPathgridGeode = new osg::Geode();

@ -4,7 +4,6 @@
#include <QPoint>
#include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../../model/prefs/state.hpp"
@ -16,6 +15,7 @@
#include "../widget/scenetoolbar.hpp"
#include "cell.hpp"
#include "mask.hpp"
#include "pathgrid.hpp"
#include "pathgridselectionmode.hpp"
#include "worldspacewidget.hpp"
@ -23,7 +23,7 @@
namespace CSVRender
{
PathgridMode::PathgridMode(WorldspaceWidget* worldspaceWidget, QWidget* parent)
: EditMode(worldspaceWidget, QIcon(":placeholder"), SceneUtil::Mask_Pathgrid | SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference,
: EditMode(worldspaceWidget, QIcon(":placeholder"), Mask_Pathgrid | Mask_Terrain | Mask_Reference,
getTooltip(), parent)
, mDragMode(DragMode_None)
, mFromNode(0)
@ -110,7 +110,7 @@ namespace CSVRender
void PathgridMode::primarySelectPressed(const WorldspaceHitResult& hit)
{
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
if (hit.tag)
{
@ -131,7 +131,7 @@ namespace CSVRender
{
if (tag->getPathgrid()->getId() != mLastId)
{
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
mLastId = tag->getPathgrid()->getId();
}
@ -142,12 +142,12 @@ namespace CSVRender
}
}
getWorldspaceWidget().clearSelection(SceneUtil::Mask_Pathgrid);
getWorldspaceWidget().clearSelection(Mask_Pathgrid);
}
bool PathgridMode::primaryEditStartDrag(const QPoint& pos)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{
@ -156,7 +156,7 @@ namespace CSVRender
if (dynamic_cast<PathgridTag*>(hit.tag.get()))
{
primarySelectPressed(hit);
selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
}
}
@ -192,7 +192,7 @@ namespace CSVRender
{
if (mDragMode == DragMode_Move)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(SceneUtil::Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection(Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
@ -233,7 +233,7 @@ namespace CSVRender
{
if (mDragMode == DragMode_Move)
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
if (PathgridTag* tag = dynamic_cast<PathgridTag*>(it->get()))
@ -272,11 +272,11 @@ namespace CSVRender
}
mDragMode = DragMode_None;
getWorldspaceWidget().reset(SceneUtil::Mask_Pathgrid);
getWorldspaceWidget().reset(Mask_Pathgrid);
}
void PathgridMode::dragAborted()
{
getWorldspaceWidget().reset(SceneUtil::Mask_Pathgrid);
getWorldspaceWidget().reset(Mask_Pathgrid);
}
}

@ -13,7 +13,7 @@
namespace CSVRender
{
PathgridSelectionMode::PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget)
: SelectionMode(parent, worldspaceWidget, SceneUtil::Mask_Pathgrid)
: SelectionMode(parent, worldspaceWidget, Mask_Pathgrid)
{
mRemoveSelectedNodes = new QAction("Remove selected nodes", this);
mRemoveSelectedEdges = new QAction("Remove edges between selected nodes", this);
@ -37,7 +37,7 @@ namespace CSVRender
void PathgridSelectionMode::removeSelectedNodes()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{
@ -54,7 +54,7 @@ namespace CSVRender
void PathgridSelectionMode::removeSelectedEdges()
{
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (SceneUtil::Mask_Pathgrid);
std::vector<osg::ref_ptr<TagBase> > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid);
for (std::vector<osg::ref_ptr<TagBase> >::iterator it = selection.begin(); it != selection.end(); ++it)
{

@ -17,7 +17,6 @@
#include <components/resource/scenemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/scenetoolmode.hpp"
@ -26,6 +25,7 @@
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "lighting.hpp"
#include "mask.hpp"
#include "cameracontroller.hpp"
namespace CSVRender
@ -71,7 +71,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager;
lightMgr->setStartLight(1);
lightMgr->setLightingMask(SceneUtil::Mask_Lighting);
lightMgr->setLightingMask(Mask_Lighting);
mRootNode = lightMgr;
mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
@ -88,8 +88,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
// Add ability to signal osg to show its statistics for debugging purposes
mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(SceneUtil::Mask_UpdateVisitor));
viewer.addView(mView);
viewer.setDone(false);
viewer.realize();
@ -122,7 +120,7 @@ void RenderWidget::flagAsModified()
void RenderWidget::setVisibilityMask(int mask)
{
mView->getCamera()->setCullMask(mask | SceneUtil::Mask_ParticleSystem | SceneUtil::Mask_Lighting);
mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting);
}
osg::Camera *RenderWidget::getCamera()
@ -212,7 +210,7 @@ SceneWidget::SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSyste
mOrbitCamControl = new OrbitCameraController(this);
mCurrentCamControl = mFreeCamControl;
mOrbitCamControl->setPickingMask(SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain);
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
mOrbitCamControl->setConstRoll( CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue() );
@ -221,7 +219,7 @@ SceneWidget::SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSyste
setLighting(&mLightingDay);
mResourceSystem->getSceneManager()->setParticleSystemMask(SceneUtil::Mask_ParticleSystem);
mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem);
// Recieve mouse move event even if mouse button is not pressed
setMouseTracking(true);
@ -350,7 +348,7 @@ void SceneWidget::update(double dt)
}
else
{
mCurrentCamControl->setup(mRootNode, SceneUtil::Mask_EditorReference | SceneUtil::Mask_Terrain, CameraController::WorldUp);
mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp);
mCamPositionSet = true;
}
}

@ -3,6 +3,8 @@
#include "../widget/scenetoolmode.hpp"
#include "mask.hpp"
class QAction;
namespace CSVRender

@ -1,9 +1,9 @@
#include "tagbase.hpp"
CSVRender::TagBase::TagBase (SceneUtil::VisMask mask) : mMask (mask) {}
CSVRender::TagBase::TagBase (Mask mask) : mMask (mask) {}
SceneUtil::VisMask CSVRender::TagBase::getMask() const
CSVRender::Mask CSVRender::TagBase::getMask() const
{
return mMask;
}

@ -5,19 +5,19 @@
#include <QString>
#include <components/sceneutil/vismask.hpp>
#include "mask.hpp"
namespace CSVRender
{
class TagBase : public osg::Referenced
{
SceneUtil::VisMask mMask;
Mask mMask;
public:
TagBase (SceneUtil::VisMask mask);
TagBase (Mask mask);
SceneUtil::VisMask getMask() const;
Mask getMask() const;
virtual QString getToolTip (bool hideBasics) const;

@ -171,9 +171,6 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
{
if (!mSelection.empty())
{
// Nudge selection by 1/4th of a texture size, similar how blendmaps are nudged
const float nudgePercentage = 0.25f;
const int nudgeOffset = (ESM::Land::REAL_SIZE / ESM::Land::LAND_TEXTURE_SIZE) * nudgePercentage;
const int landHeightsNudge = (ESM::Land::REAL_SIZE / ESM::Land::LAND_SIZE) / (ESM::Land::LAND_SIZE - 1); // Does this work with all land size configurations?
const int textureSizeToLandSizeModifier = (ESM::Land::LAND_SIZE - 1) / ESM::Land::LAND_TEXTURE_SIZE;
@ -196,10 +193,10 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
{
for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++)
{
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(drawPreviousX + nudgeOffset, CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y + 1) - nudgeOffset, calculateLandHeight(x1+(i-1), y2)+2));
vertices->push_back(osg::Vec3f(drawCurrentX + nudgeOffset, CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y + 1) - nudgeOffset, calculateLandHeight(x1+i, y2)+2));
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+(i-1), y2)+2));
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+i, y2)+2));
}
}
@ -208,10 +205,10 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
{
for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++)
{
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + (i - 1) *(ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(drawPreviousX + nudgeOffset, CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) - nudgeOffset, calculateLandHeight(x1+(i-1), y1)+2));
vertices->push_back(osg::Vec3f(drawCurrentX + nudgeOffset, CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) - nudgeOffset, calculateLandHeight(x1+i, y1)+2));
float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + (i - 1) *(ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+(i-1), y1)+2));
vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+i, y1)+2));
}
}
@ -220,10 +217,10 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
{
for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++)
{
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x + 1) + nudgeOffset, drawPreviousY - nudgeOffset, calculateLandHeight(x2, y1+(i-1))+2));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x + 1) + nudgeOffset, drawCurrentY - nudgeOffset, calculateLandHeight(x2, y1+i)+2));
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawPreviousY, calculateLandHeight(x2, y1+(i-1))+2));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawCurrentY, calculateLandHeight(x2, y1+i)+2));
}
}
@ -232,10 +229,10 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
{
for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++)
{
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + nudgeOffset, drawPreviousY - nudgeOffset, calculateLandHeight(x1, y1+(i-1))+2));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalToWorldCoords(x) + nudgeOffset, drawCurrentY - nudgeOffset, calculateLandHeight(x1, y1+i)+2));
float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawPreviousY, calculateLandHeight(x1, y1+(i-1))+2));
vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawCurrentY, calculateLandHeight(x1, y1+i)+2));
}
}
}

@ -17,7 +17,6 @@
#include <components/esm/loadland.hpp>
#include <components/debug/debuglog.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/brushshapes.hpp"
#include "../widget/modebutton.hpp"
@ -37,14 +36,16 @@
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/universalid.hpp"
#include "brushdraw.hpp"
#include "editmode.hpp"
#include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "tagbase.hpp"
#include "terrainselection.hpp"
#include "worldspacewidget.hpp"
CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference, "Terrain land editing", parent),
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain | Mask_Reference, "Terrain land editing", parent),
mParentNode(parentNode)
{
}
@ -67,6 +68,9 @@ void CSVRender::TerrainShapeMode::activate(CSVWidget::SceneToolbar* toolbar)
connect(mShapeBrushScenetool->mShapeBrushWindow->mToolStrengthSlider, SIGNAL(valueChanged(int)), this, SLOT(setShapeEditToolStrength(int)));
}
if (!mBrushDraw)
mBrushDraw.reset(new BrushDraw(mParentNode));
EditMode::activate(toolbar);
toolbar->addTool (mShapeBrushScenetool);
}
@ -83,6 +87,9 @@ void CSVRender::TerrainShapeMode::deactivate(CSVWidget::SceneToolbar* toolbar)
mTerrainShapeSelection.reset();
}
if (mBrushDraw)
mBrushDraw.reset();
EditMode::deactivate(toolbar);
}
@ -1382,6 +1389,15 @@ void CSVRender::TerrainShapeMode::dragMoveEvent (QDragMoveEvent *event)
{
}
void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event)
{
WorldspaceHitResult hit = getWorldspaceWidget().mousePick(event->pos(), getInteractionMask());
if (hit.hit && mBrushDraw && !(mShapeEditTool == ShapeEditTool_Drag && mIsEditing))
mBrushDraw->update(hit.worldPos, mBrushSize, mBrushShape);
if (!hit.hit && mBrushDraw && !(mShapeEditTool == ShapeEditTool_Drag && mIsEditing))
mBrushDraw->hide();
}
void CSVRender::TerrainShapeMode::setBrushSize(int brushSize)
{
mBrushSize = brushSize;

@ -19,6 +19,7 @@
#include "../widget/brushshapes.hpp"
#endif
#include "brushdraw.hpp"
#include "terrainselection.hpp"
namespace CSVWidget
@ -89,6 +90,7 @@ namespace CSVRender
void dragWheel (int diff, double speedFactor) final;
void dragMoveEvent (QDragMoveEvent *event) final;
void mouseMoveEvent (QMouseEvent *event) final;
private:
@ -168,6 +170,7 @@ namespace CSVRender
std::string mBrushTexture;
int mBrushSize = 1;
CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point;
std::unique_ptr<BrushDraw> mBrushDraw;
std::vector<std::pair<int, int>> mCustomBrushShape;
CSVWidget::SceneToolShapeBrush *mShapeBrushScenetool = nullptr;
int mDragMode = InteractionType_None;

@ -13,7 +13,6 @@
#include <osg/Group>
#include <components/esm/loadland.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../widget/modebutton.hpp"
#include "../widget/scenetoolbar.hpp"
@ -32,17 +31,20 @@
#include "../../model/world/resourcetable.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/universalid.hpp"
#include "../widget/brushshapes.hpp"
#include "brushdraw.hpp"
#include "editmode.hpp"
#include "pagedworldspacewidget.hpp"
#include "mask.hpp"
#include "object.hpp" // Something small needed regarding pointers from here ()
#include "worldspacewidget.hpp"
CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, SceneUtil::Mask_Terrain | SceneUtil::Mask_EditorReference, "Terrain texture editing", parent),
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent),
mBrushTexture("L0#0"),
mBrushSize(1),
mBrushShape(0),
mBrushShape(CSVWidget::BrushShape_Point),
mTextureBrushScenetool(nullptr),
mDragMode(InteractionType_None),
mParentNode(parentNode),
@ -57,7 +59,7 @@ void CSVRender::TerrainTextureMode::activate(CSVWidget::SceneToolbar* toolbar)
mTextureBrushScenetool = new CSVWidget::SceneToolTextureBrush (toolbar, "scenetooltexturebrush", getWorldspaceWidget().getDocument());
connect(mTextureBrushScenetool, SIGNAL (clicked()), mTextureBrushScenetool, SLOT (activate()));
connect(mTextureBrushScenetool->mTextureBrushWindow, SIGNAL(passBrushSize(int)), this, SLOT(setBrushSize(int)));
connect(mTextureBrushScenetool->mTextureBrushWindow, SIGNAL(passBrushShape(int)), this, SLOT(setBrushShape(int)));
connect(mTextureBrushScenetool->mTextureBrushWindow, SIGNAL(passBrushShape(CSVWidget::BrushShape)), this, SLOT(setBrushShape(CSVWidget::BrushShape)));
connect(mTextureBrushScenetool->mTextureBrushWindow->mSizeSliders->mBrushSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(setBrushSize(int)));
connect(mTextureBrushScenetool, SIGNAL(passTextureId(std::string)), this, SLOT(setBrushTexture(std::string)));
connect(mTextureBrushScenetool->mTextureBrushWindow, SIGNAL(passTextureId(std::string)), this, SLOT(setBrushTexture(std::string)));
@ -72,6 +74,9 @@ void CSVRender::TerrainTextureMode::activate(CSVWidget::SceneToolbar* toolbar)
mTerrainTextureSelection.reset(new TerrainSelection(mParentNode, &getWorldspaceWidget(), TerrainSelectionType::Texture));
}
if (!mBrushDraw)
mBrushDraw.reset(new BrushDraw(mParentNode, true));
EditMode::activate(toolbar);
toolbar->addTool (mTextureBrushScenetool);
}
@ -90,6 +95,9 @@ void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar)
mTerrainTextureSelection.reset();
}
if (mBrushDraw)
mBrushDraw.reset();
EditMode::deactivate(toolbar);
}
@ -328,11 +336,9 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1);
int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1
int rf = mBrushSize / 2;
int r = mBrushSize / 2 + 1;
int distance = 0;
int r = static_cast<float>(mBrushSize) / 2;
if (mBrushShape == 0)
if (mBrushShape == CSVWidget::BrushShape_Point)
{
CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer);
@ -344,7 +350,7 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
}
}
if (mBrushShape == 1)
if (mBrushShape == CSVWidget::BrushShape_Square)
{
int upperLeftCellX = cellX - std::floor(r / landTextureSize);
int upperLeftCellY = cellY - std::floor(r / landTextureSize);
@ -394,7 +400,7 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
}
}
if (mBrushShape == 2)
if (mBrushShape == CSVWidget::BrushShape_Circle)
{
int upperLeftCellX = cellX - std::floor(r / landTextureSize);
int upperLeftCellY = cellY - std::floor(r / landTextureSize);
@ -419,7 +425,6 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
{
for(int j = 0; j < landTextureSize; j++)
{
if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r)
{
int distanceX(0);
@ -430,7 +435,8 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j;
if (i_cell == cellX) distanceX = abs(i-xHitInCell);
if (j_cell == cellY) distanceY = abs(j-yHitInCell);
distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
float distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
float rf = static_cast<float>(mBrushSize) / 2;
if (distance < rf) newTerrain[j*landTextureSize+i] = brushInt;
}
else
@ -443,7 +449,8 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j;
if (i_cell == cellX) distanceX = abs(i-xHitInCell);
if (j_cell == cellY) distanceY = abs(j-yHitInCell);
distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
float distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2)));
float rf = static_cast<float>(mBrushSize) / 2;
if (distance < rf) newTerrain[j*landTextureSize+i] = brushInt;
}
}
@ -454,7 +461,7 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
}
}
if (mBrushShape == 3)
if (mBrushShape == CSVWidget::BrushShape_Custom)
{
CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value<CSMWorld::LandTexturesColumn::DataType>();
CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer);
@ -506,12 +513,12 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, i
int r = mBrushSize / 2;
std::vector<std::pair<int, int>> selections;
if (mBrushShape == 0)
if (mBrushShape == CSVWidget::BrushShape_Point)
{
if (isInCellSelection(texCoords.first, texCoords.second)) selections.emplace_back(texCoords);
}
if (mBrushShape == 1)
if (mBrushShape == CSVWidget::BrushShape_Square)
{
for (int i = -r; i <= r; i++)
{
@ -527,14 +534,15 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, i
}
}
if (mBrushShape == 2)
if (mBrushShape == CSVWidget::BrushShape_Circle)
{
for (int i = -r; i <= r; i++)
{
for (int j = -r; j <= r; j++)
{
osg::Vec2f coords(i,j);
if (std::round(coords.length()) < r)
float rf = static_cast<float>(mBrushSize) / 2;
if (std::round(coords.length()) < rf)
{
int x = i + texCoords.first;
int y = j + texCoords.second;
@ -547,7 +555,7 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair<int, i
}
}
if (mBrushShape == 3)
if (mBrushShape == CSVWidget::BrushShape_Custom)
{
if(!mCustomBrushShape.empty())
{
@ -707,17 +715,27 @@ void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event)
{
}
void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event)
{
WorldspaceHitResult hit = getWorldspaceWidget().mousePick(event->pos(), getInteractionMask());
if (hit.hit && mBrushDraw)
mBrushDraw->update(hit.worldPos, mBrushSize, mBrushShape);
if (!hit.hit && mBrushDraw)
mBrushDraw->hide();
}
void CSVRender::TerrainTextureMode::setBrushSize(int brushSize)
{
mBrushSize = brushSize;
}
void CSVRender::TerrainTextureMode::setBrushShape(int brushShape)
void CSVRender::TerrainTextureMode::setBrushShape(CSVWidget::BrushShape brushShape)
{
mBrushShape = brushShape;
//Set custom brush shape
if (mBrushShape == 3 && !mTerrainTextureSelection->getTerrainSelection().empty())
if (mBrushShape == CSVWidget::BrushShape_Custom && !mTerrainTextureSelection->getTerrainSelection().empty())
{
auto terrainSelection = mTerrainTextureSelection->getTerrainSelection();
int selectionCenterX = 0;

@ -17,6 +17,8 @@
#include "../../model/world/commands.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/landtexture.hpp"
#include "../widget/brushshapes.hpp"
#include "brushdraw.hpp"
#endif
#include "terrainselection.hpp"
@ -81,6 +83,8 @@ namespace CSVRender
void dragWheel (int diff, double speedFactor) final;
void dragMoveEvent (QDragMoveEvent *event) final;
void mouseMoveEvent (QMouseEvent *event) final;
private:
/// \brief Handle brush mechanics, maths regarding worldspace hit etc.
void editTerrainTextureGrid (const WorldspaceHitResult& hit);
@ -104,7 +108,8 @@ namespace CSVRender
std::string mCellId;
std::string mBrushTexture;
int mBrushSize;
int mBrushShape;
CSVWidget::BrushShape mBrushShape;
std::unique_ptr<BrushDraw> mBrushDraw;
std::vector<std::pair<int, int>> mCustomBrushShape;
CSVWidget::SceneToolTextureBrush *mTextureBrushScenetool;
int mDragMode;
@ -121,7 +126,7 @@ namespace CSVRender
public slots:
void handleDropEvent(QDropEvent *event);
void setBrushSize(int brushSize);
void setBrushShape(int brushShape);
void setBrushShape(CSVWidget::BrushShape brushShape);
void setBrushTexture(std::string brushShape);
};
}

@ -16,6 +16,7 @@
#include "../widget/scenetooltoggle2.hpp"
#include "cameracontroller.hpp"
#include "mask.hpp"
#include "tagbase.hpp"
void CSVRender::UnpagedWorldspaceWidget::update()
@ -303,8 +304,8 @@ void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Button_Terrain, SceneUtil::Mask_Terrain, "Terrain", "", true);
//tool->addButton (Button_Fog, Mask_Fog, "Fog");
tool->addButton (Button_Terrain, Mask_Terrain, "Terrain", "", true);
tool->addButton (Button_Fog, Mask_Fog, "Fog");
}
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()

@ -26,9 +26,8 @@
#include "../widget/scenetooltoggle2.hpp"
#include "../widget/scenetoolrun.hpp"
#include <components/sceneutil/vismask.hpp>
#include "object.hpp"
#include "mask.hpp"
#include "instancemode.hpp"
#include "pathgridmode.hpp"
#include "cameracontroller.hpp"
@ -139,7 +138,7 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti
{
float alpha = setting->toDouble();
// getSelection is virtual, thus this can not be called from the constructor
auto selection = getSelection(SceneUtil::Mask_EditorReference);
auto selection = getSelection(Mask_Reference);
for (osg::ref_ptr<TagBase> tag : selection)
{
if (auto objTag = dynamic_cast<ObjectTag*>(tag.get()))
@ -346,7 +345,7 @@ unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
{
mInteractionMask = mask | SceneUtil::Mask_EditorCellMarker | SceneUtil::Mask_EditorCellArrow;
mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow;
}
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
@ -362,9 +361,9 @@ void CSVRender::WorldspaceWidget::setEditLock (bool locked)
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
tool->addButton (Button_Reference, SceneUtil::Mask_EditorReference, "Instances");
tool->addButton (Button_Water, SceneUtil::Mask_Water, "Water");
tool->addButton (Button_Pathgrid, SceneUtil::Mask_Pathgrid, "Pathgrid");
tool->addButton (Button_Reference, Mask_Reference, "Instances");
tool->addButton (Button_Water, Mask_Water, "Water");
tool->addButton (Button_Pathgrid, Mask_Pathgrid, "Pathgrid");
}
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
@ -613,6 +612,8 @@ void CSVRender::WorldspaceWidget::updateOverlay()
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
{
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).mouseMoveEvent (event);
if (mDragging)
{
int diffX = event->x() - mDragX;

@ -8,6 +8,7 @@
#include "../../model/world/tablemimedata.hpp"
#include "scenewidget.hpp"
#include "mask.hpp"
namespace CSMPrefs
{

@ -57,9 +57,6 @@ CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *p
CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QWidget *parent)
: QFrame(parent, Qt::Popup),
mBrushShape(0),
mBrushSize(1),
mBrushTexture("L0#0"),
mDocument(document)
{
mBrushTextureLabel = "Selected texture: " + mBrushTexture + " ";
@ -207,10 +204,14 @@ void CSVWidget::TextureBrushWindow::setBrushSize(int brushSize)
void CSVWidget::TextureBrushWindow::setBrushShape()
{
if(mButtonPoint->isChecked()) mBrushShape = 0;
if(mButtonSquare->isChecked()) mBrushShape = 1;
if(mButtonCircle->isChecked()) mBrushShape = 2;
if(mButtonCustom->isChecked()) mBrushShape = 3;
if (mButtonPoint->isChecked())
mBrushShape = CSVWidget::BrushShape_Point;
if (mButtonSquare->isChecked())
mBrushShape = CSVWidget::BrushShape_Square;
if (mButtonCircle->isChecked())
mBrushShape = CSVWidget::BrushShape_Circle;
if (mButtonCustom->isChecked())
mBrushShape = CSVWidget::BrushShape_Custom;
emit passBrushShape(mBrushShape);
}
@ -228,7 +229,7 @@ CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush (SceneToolbar *parent, c
mBrushHistory[0] = "L0#0";
setAcceptDrops(true);
connect(mTextureBrushWindow, SIGNAL(passBrushShape(int)), this, SLOT(setButtonIcon(int)));
connect(mTextureBrushWindow, SIGNAL(passBrushShape(CSVWidget::BrushShape)), this, SLOT(setButtonIcon(CSVWidget::BrushShape)));
setButtonIcon(mTextureBrushWindow->mBrushShape);
mPanel = new QFrame (this, Qt::Popup);
@ -258,31 +259,31 @@ CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush (SceneToolbar *parent, c
}
void CSVWidget::SceneToolTextureBrush::setButtonIcon (int brushShape)
void CSVWidget::SceneToolTextureBrush::setButtonIcon (CSVWidget::BrushShape brushShape)
{
QString tooltip = "Change brush settings <p>Currently selected: ";
switch (brushShape)
{
case 0:
case BrushShape_Point:
setIcon (QIcon (QPixmap (":scenetoolbar/brush-point")));
tooltip += mTextureBrushWindow->toolTipPoint;
break;
case 1:
case BrushShape_Square:
setIcon (QIcon (QPixmap (":scenetoolbar/brush-square")));
tooltip += mTextureBrushWindow->toolTipSquare;
break;
case 2:
case BrushShape_Circle:
setIcon (QIcon (QPixmap (":scenetoolbar/brush-circle")));
tooltip += mTextureBrushWindow->toolTipCircle;
break;
case 3:
case BrushShape_Custom:
setIcon (QIcon (QPixmap (":scenetoolbar/brush-custom")));
tooltip += mTextureBrushWindow->toolTipCustom;

@ -15,6 +15,7 @@
#include <QPushButton>
#ifndef Q_MOC_RUN
#include "brushshapes.hpp"
#include "scenetool.hpp"
#include "../../model/doc/document.hpp"
@ -65,9 +66,9 @@ namespace CSVWidget
const QString toolTipCustom = "Paint custom selection (not implemented yet)";
private:
int mBrushShape;
int mBrushSize;
std::string mBrushTexture;
CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point;
int mBrushSize = 1;
std::string mBrushTexture = "L0#0";
CSMDoc::Document& mDocument;
QLabel *mSelectedBrush;
QGroupBox *mHorizontalGroupBox;
@ -88,7 +89,7 @@ namespace CSVWidget
signals:
void passBrushSize (int brushSize);
void passBrushShape(int brushShape);
void passBrushShape(CSVWidget::BrushShape brushShape);
void passTextureId(std::string brushTexture);
};
@ -120,7 +121,7 @@ namespace CSVWidget
friend class CSVRender::TerrainTextureMode;
public slots:
void setButtonIcon(int brushShape);
void setButtonIcon(CSVWidget::BrushShape brushShape);
void updateBrushHistory (const std::string& mBrushTexture);
void clicked (const QModelIndex& index);
virtual void activate();

@ -7,6 +7,7 @@
#include <QString>
#include <QtCore/qnamespace.h>
#include <components/misc/helpviewer.hpp>
#include <components/misc/stringops.hpp>
#include "../../model/doc/document.hpp"
@ -155,6 +156,9 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
}
}
if (mHelpAction)
menu.addAction (mHelpAction);
menu.exec (event->globalPos());
}
@ -387,6 +391,13 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
addAction (mEditIdAction);
mHelpAction = new QAction (tr ("Help"), this);
connect (mHelpAction, SIGNAL (triggered()), this, SLOT (openHelp()));
mHelpAction->setIcon(QIcon(":/info.png"));
addAction (mHelpAction);
CSMPrefs::Shortcut* openHelpShortcut = new CSMPrefs::Shortcut("help", this);
openHelpShortcut->associateAction(mHelpAction);
connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (tableSizeUpdate()));
@ -561,6 +572,11 @@ void CSVWorld::Table::editCell()
emit editRequest(mEditIdAction->getCurrentId(), "");
}
void CSVWorld::Table::openHelp()
{
Misc::HelpViewer::openHelp("manuals/openmw-cs/tables.html");
}
void CSVWorld::Table::viewRecord()
{
if (!(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_View))

@ -65,6 +65,7 @@ namespace CSVWorld
QAction *mPreviewAction;
QAction *mExtendedDeleteAction;
QAction *mExtendedRevertAction;
QAction *mHelpAction;
TableEditIdAction *mEditIdAction;
CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTableBase *mModel;
@ -128,6 +129,8 @@ namespace CSVWorld
void editCell();
static void openHelp();
void editRecord();
void cloneRecord();

@ -15,17 +15,22 @@ set(GAME_HEADER
engine.hpp
)
if (BULLET_USE_DOUBLES)
add_definitions(-DBT_USE_DOUBLE_PRECISION)
endif()
source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation rotatecontroller sky npcanimation
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager navmesh actorspaths recastmesh
)
add_openmw_dir (mwinput
inputmanagerimp
actions actionmanager bindingsmanager controllermanager controlswitch
inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager
)
add_openmw_dir (mwgui
@ -70,7 +75,9 @@ add_openmw_dir (mwworld
)
add_openmw_dir (mwphysics
physicssystem trace collisiontype actor convert object heightfield
physicssystem trace collisiontype actor convert object heightfield closestnotmerayresultcallback
contacttestresultcallback deepestnotmecontacttestresultcallback stepper movementsolver
closestnotmeconvexresultcallback
)
add_openmw_dir (mwclass
@ -81,9 +88,10 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics
mechanicsmanagerimp stat creaturestats magiceffects movement actorutil
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellsuccess spellcasting
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
character actors objects aistate coordinateconverter trading weaponpriority spellpriority weapontype
character actors objects aistate coordinateconverter trading weaponpriority spellpriority weapontype spellutil tickableeffects
spellabsorption linkedeffects
)
add_openmw_dir (mwstate
@ -246,8 +254,6 @@ if(APPLE)
configure_file("${OpenMW_BINARY_DIR}/settings-default.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/openmw.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb_204.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb_205.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY)
add_custom_command(TARGET openmw
POST_BUILD

@ -26,7 +26,6 @@
#include <components/compiler/extensions0.hpp>
#include <components/sceneutil/vismask.hpp>
#include <components/sceneutil/workqueue.hpp>
#include <components/files/configurationmanager.hpp>
@ -48,6 +47,8 @@
#include "mwworld/player.hpp"
#include "mwworld/worldimp.hpp"
#include "mwrender/vismask.hpp"
#include "mwclass/classes.hpp"
#include "mwdialogue/dialoguemanagerimp.hpp"
@ -100,8 +101,13 @@ bool OMW::Engine::frame(float frametime)
// When the window is minimized, pause the game. Currently this *has* to be here to work around a MyGUI bug.
// If we are not currently rendering, then RenderItems will not be reused resulting in a memory leak upon changing widget textures (fixed in MyGUI 3.3.2),
// and destroyed widgets will not be deleted (not fixed yet, https://github.com/MyGUI/mygui/issues/21)
if (!mEnvironment.getInputManager()->isWindowVisible())
if (!mEnvironment.getWindowManager()->isWindowVisible())
{
mEnvironment.getSoundManager()->pausePlayback();
return false;
}
else
mEnvironment.getSoundManager()->resumePlayback();
// sound
if (mUseSound)
@ -240,7 +246,9 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
{
MWClass::registerClasses();
Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_GAMECONTROLLER|SDL_INIT_JOYSTICK;
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); // We use only gamepads
Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_GAMECONTROLLER|SDL_INIT_JOYSTICK|SDL_INIT_SENSOR;
if(SDL_WasInit(flags) == 0)
{
SDL_SetMainReady();
@ -515,22 +523,9 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
else
Log(Debug::Info) << "Loading keybindings file: " << keybinderUser;
// find correct path to the game controller bindings
// File format for controller mappings is different for SDL <= 2.0.4, 2.0.5, and >= 2.0.6
SDL_version linkedSdlVersion;
SDL_GetVersion(&linkedSdlVersion);
std::string controllerFileName;
if (linkedSdlVersion.major == 2 && linkedSdlVersion.minor == 0 && linkedSdlVersion.patch <= 4) {
controllerFileName = "gamecontrollerdb_204.txt";
} else if (linkedSdlVersion.major == 2 && linkedSdlVersion.minor == 0 && linkedSdlVersion.patch == 5) {
controllerFileName = "gamecontrollerdb_205.txt";
} else {
controllerFileName = "gamecontrollerdb.txt";
}
const std::string userdefault = mCfgMgr.getUserConfigPath().string() + "/" + controllerFileName;
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/" + controllerFileName;
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/" + controllerFileName;
const std::string userdefault = mCfgMgr.getUserConfigPath().string() + "/gamecontrollerdb.txt";
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/gamecontrollerdb.txt";
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/gamecontrollerdb.txt";
std::string userGameControllerdb;
if (boost::filesystem::exists(userdefault)){
@ -546,25 +541,25 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
gameControllerdb = globaldefault;
else
gameControllerdb = ""; //if it doesn't exist, pass in an empty string
MWInput::InputManager* input =
#ifdef USE_OPENXR
new MWVR::OpenXRInputManager(mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
#else
new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
#endif
mEnvironment.setInputManager (input);
std::string myguiResources = (mResDir / "mygui").string();
osg::ref_ptr<osg::Group> guiRoot = new osg::Group;
guiRoot->setName("GUI Root");
guiRoot->setNodeMask(SceneUtil::Mask_GUI);
guiRoot->setNodeMask(MWRender::Mask_GUI);
rootNode->addChild(guiRoot);
MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(),
MWGui::WindowManager* window = new MWGui::WindowManager(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(),
mCfgMgr.getLogPath().string() + std::string("/"), myguiResources,
mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts,
Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string());
mEnvironment.setWindowManager (window);
MWInput::InputManager* input =
#ifdef USE_OPENXR
new MWVR::OpenXRInputManager(mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
#else
new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
#endif
mEnvironment.setInputManager (input);
// Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
@ -584,7 +579,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mFileCollections, mContentFiles, mEncoder, mActivationDistanceOverride, mCellName,
mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string()));
mEnvironment.getWorld()->setupPlayer();
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
window->setStore(mEnvironment.getWorld()->getStore());
window->initUI();
@ -681,7 +675,6 @@ private:
};
// Initialise and enter main loop.
void OMW::Engine::go()
{
assert (!mContentFiles.empty());
@ -710,7 +703,8 @@ void OMW::Engine::go()
mViewer->setUseConfigureAffinity(false);
#endif
mScreenCaptureOperation = new WriteScreenshotToFileOperation(mCfgMgr.getUserDataPath().string(),
mScreenCaptureOperation = new WriteScreenshotToFileOperation(
mCfgMgr.getScreenshotPath().string(),
Settings::Manager::getString("screenshot format", "General"));
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation);

@ -38,8 +38,6 @@ namespace MWBase
virtual ~InputManager() {}
virtual bool isWindowVisible() = 0;
virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0;
virtual void changeInputMode(bool guiMode) = 0;
@ -47,6 +45,8 @@ namespace MWBase
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
virtual void setDragDrop(bool dragDrop) = 0;
virtual void setGamepadGuiCursorEnabled(bool enabled) = 0;
virtual void setAttemptJump(bool jumping) = 0;
virtual void toggleControlSwitch (const std::string& sw, bool value) = 0;
virtual bool getControlSwitch (const std::string& sw) = 0;
@ -54,8 +54,6 @@ namespace MWBase
virtual std::string getActionDescription (int action) = 0;
virtual std::string getActionKeyBindingName (int action) = 0;
virtual std::string getActionControllerBindingName (int action) = 0;
virtual std::string sdlControllerAxisToString(int axis) = 0;
virtual std::string sdlControllerButtonToString(int button) = 0;
///Actions available for binding to keyboard buttons
virtual std::vector<int> getActionKeySorting() = 0;
///Actions available for binding to controller buttons
@ -71,10 +69,15 @@ namespace MWBase
/// Returns if the last used input device was a joystick or a keyboard
/// @return true if joystick, false otherwise
virtual bool joystickLastUsed() = 0;
virtual void setJoystickLastUsed(bool enabled) = 0;
virtual int countSavedGameRecords() const = 0;
virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0;
virtual void resetIdleTime() = 0;
virtual void executeAction(int action) = 0;
};
}

@ -35,7 +35,7 @@ namespace MWBase
virtual ~ScriptManager() {}
virtual void run (const std::string& name, Interpreter::Context& interpreterContext) = 0;
virtual bool run (const std::string& name, Interpreter::Context& interpreterContext) = 0;
///< Run the script with the given name (compile first, if not compiled yet)
virtual bool compile (const std::string& name) = 0;

@ -14,6 +14,14 @@ namespace MWWorld
namespace MWSound
{
// Each entry excepts of MaxCount should be used only in one place
enum BlockerType
{
VideoPlayback,
MaxCount
};
class Sound;
class Stream;
struct Sound_Decoder;
@ -168,12 +176,15 @@ namespace MWBase
///< Is the given sound currently playing on the given object?
/// If you want to check if sound played with playSound is playing, use empty Ptr
virtual void pauseSounds(int types=static_cast<int>(Type::Mask)) = 0;
virtual void pauseSounds(MWSound::BlockerType blocker, int types=int(Type::Mask)) = 0;
///< Pauses all currently playing sounds, including music.
virtual void resumeSounds(int types=static_cast<int>(Type::Mask)) = 0;
virtual void resumeSounds(MWSound::BlockerType blocker) = 0;
///< Resumes all previously paused sounds.
virtual void pausePlayback() = 0;
virtual void resumePlayback() = 0;
virtual void update(float duration) = 0;
virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) = 0;

@ -11,6 +11,8 @@
#include "../mwgui/mode.hpp"
#include <components/sdlutil/events.hpp>
namespace Loading
{
class Listener;
@ -86,7 +88,7 @@ namespace SFO
namespace MWBase
{
/// \brief Interface for widnow manager (implemented in MWGui)
class WindowManager
class WindowManager : public SDLUtil::WindowListener
{
WindowManager (const WindowManager&);
///< not implemented
@ -269,8 +271,6 @@ namespace MWBase
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
virtual void windowResized(int x, int y) = 0;
virtual void executeInConsole (const std::string& path) = 0;
virtual void enableRest() = 0;
@ -361,6 +361,11 @@ namespace MWBase
virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) = 0;
virtual bool injectKeyRelease(MyGUI::KeyCode key) = 0;
virtual void windowVisibilityChange(bool visible) = 0;
virtual void windowResized(int x, int y) = 0;
virtual void windowClosed() = 0;
virtual bool isWindowVisible() = 0;
};
}

@ -201,6 +201,8 @@ namespace MWBase
virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0;
///< Search is limited to the active cells.
virtual MWWorld::Ptr searchPtrViaRefNum (const std::string& id, const ESM::RefNum& refNum) = 0;
virtual MWWorld::Ptr findContainer (const MWWorld::ConstPtr& ptr) = 0;
///< Return a pointer to a liveCellRef which contains \a ptr.
/// \note Search is limited to the active cells.

@ -3,7 +3,6 @@
#include <components/esm/loadacti.hpp>
#include <components/misc/rng.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
@ -20,6 +19,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwgui/tooltips.hpp"
@ -34,7 +34,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -177,11 +177,10 @@ namespace MWClass
}
}
if ((isLocked || isTrapped) && hasKey)
if (isLocked && hasKey)
{
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
if(isLocked)
ptr.getCellRef().unlock();
ptr.getCellRef().unlock();
// using a key disarms the trap
if(isTrapped)
{

@ -125,6 +125,7 @@ namespace MWClass
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
MWWorld::ManualRef manualRef(store, id);
manualRef.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
manualRef.getPtr().getCellRef().setScale(ptr.getCellRef().getScale());
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(manualRef.getPtr(), ptr.getCell() , ptr.getCellRef().getPosition());
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
customData.mSpawn = false;

@ -3,7 +3,6 @@
#include <components/esm/loaddoor.hpp>
#include <components/esm/doorstate.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -26,6 +25,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/animation.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwmechanics/actorutil.hpp"
@ -58,7 +58,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}
@ -158,12 +158,11 @@ namespace MWClass
}
}
if ((isLocked || isTrapped) && hasKey)
if (isLocked && hasKey)
{
if(actor == MWMechanics::getPlayer())
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
if(isLocked)
ptr.getCellRef().unlock(); //Call the function here. because that makes sense.
ptr.getCellRef().unlock(); //Call the function here. because that makes sense.
// using a key disarms the trap
if(isTrapped)
{

@ -141,8 +141,6 @@ namespace MWClass
MWGui::ToolTipInfo info;
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
bool gold = isGold(ptr);
if (gold)
count *= getValue(ptr);
@ -153,18 +151,9 @@ namespace MWClass
else // gold displays its count also if it's 1.
countString = " (" + std::to_string(count) + ")";
info.caption = MyGUI::TextIterator::toTagsString(getName(ptr)) + countString;
info.caption = MyGUI::TextIterator::toTagsString(getName(ptr)) + countString + MWGui::ToolTips::getSoulString(ptr.getCellRef());
info.icon = ref->mBase->mIcon;
if (ref->mRef.getSoul() != "")
{
const ESM::Creature *creature = store.get<ESM::Creature>().search(ref->mRef.getSoul());
if (creature && !creature->mName.empty())
info.caption += " (" + creature->mName + ")";
else if (creature)
info.caption += " (" + creature->mId + ")";
}
std::string text;
text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}");

@ -2,7 +2,6 @@
#include <components/esm/loadstat.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwphysics/physicssystem.hpp"
@ -10,6 +9,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
namespace MWClass
{
@ -19,7 +19,7 @@ namespace MWClass
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model);
ptr.getRefData().getBaseNode()->setNodeMask(SceneUtil::Mask_Static);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -31,6 +31,7 @@ namespace MWGui
{
AlchemyWindow::AlchemyWindow()
: WindowBase("openmw_alchemy_window.layout")
, mCurrentFilter(FilterType::ByName)
, mModel(nullptr)
, mSortModel(nullptr)
, mAlchemy(new MWMechanics::Alchemy())
@ -192,16 +193,16 @@ namespace MWGui
std::set<std::string> itemNames, itemEffects;
for (size_t i = 0; i < mModel->getItemCount(); ++i)
{
auto const& base = mModel->getItem(i).mBase;
if (base.getTypeName() != typeid(ESM::Ingredient).name())
MWWorld::Ptr item = mModel->getItem(i).mBase;
if (item.getTypeName() != typeid(ESM::Ingredient).name())
continue;
itemNames.insert(base.getClass().getName(base));
itemNames.insert(item.getClass().getName(item));
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
auto const alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
auto const effects = MWMechanics::Alchemy::effectsDescription(base, alchemySkill);
auto const effects = MWMechanics::Alchemy::effectsDescription(item, alchemySkill);
itemEffects.insert(effects.begin(), effects.end());
}

@ -34,6 +34,8 @@ namespace MWGui
/// right edge. The second integer is the height of all
/// text combined prior to pagination.
virtual std::pair <unsigned int, unsigned int> getSize () const = 0;
virtual ~TypesetBook() = default;
};
struct GlyphInfo
@ -87,8 +89,7 @@ namespace MWGui
typedef uint8_t const * Utf8Point;
typedef std::pair <Utf8Point, Utf8Point> Utf8Span;
virtual ~BookTypesetter() = default;
enum Alignment {
AlignLeft = -1,

@ -16,6 +16,7 @@
#include "draganddrop.hpp"
#include "countdialog.hpp"
#include "widgets.hpp"
#include "tooltips.hpp"
namespace
{
@ -86,7 +87,8 @@ void CompanionWindow::onItemSelected(int index)
if (count > 1 && !shift)
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->openCountDialog(object.getClass().getName(object), "#{sTake}", count);
std::string name = object.getClass().getName(object) + MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem);
}

@ -25,6 +25,7 @@
#include "sortfilteritemmodel.hpp"
#include "pickpocketitemmodel.hpp"
#include "draganddrop.hpp"
#include "tooltips.hpp"
namespace MWGui
{
@ -83,7 +84,8 @@ namespace MWGui
if (count > 1 && !shift)
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->openCountDialog(object.getClass().getName(object), "#{sTake}", count);
std::string name = object.getClass().getName(object) + MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, "#{sTake}", count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
}

@ -358,7 +358,9 @@ namespace MWGui
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
if (exit())
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
}
}
void DialogueWindow::onSelectListItem(const std::string& topic, int id)
@ -422,9 +424,7 @@ namespace MWGui
bool sameActor = (mPtr == actor);
if (!sameActor)
{
for (DialogueText* text : mHistoryContents)
delete text;
mHistoryContents.clear();
// The history is not reset here
mKeywords.clear();
mTopicsList->clear();
for (Link* link : mLinks)
@ -479,6 +479,16 @@ namespace MWGui
mDeleteLater.clear();
}
void DialogueWindow::onClose()
{
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Dialogue))
return;
// Reset history
for (DialogueText* text : mHistoryContents)
delete text;
mHistoryContents.clear();
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
if (mKeywords == keyWords && isCompanion() == mIsCompanion)

@ -133,6 +133,8 @@ namespace MWGui
void updateTopics();
void onClose();
protected:
void updateTopicsPane();
bool isCompanion(const MWWorld::Ptr& actor);

@ -38,6 +38,7 @@
#include "tradewindow.hpp"
#include "draganddrop.hpp"
#include "widgets.hpp"
#include "tooltips.hpp"
namespace
{
@ -302,7 +303,8 @@ namespace MWGui
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
std::string message = mTrading ? "#{sQuanityMenuMessage01}" : "#{sTake}";
dialog->openCountDialog(object.getClass().getName(object), message, count);
std::string name = object.getClass().getName(object) + MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, message, count);
dialog->eventOkClicked.clear();
if (mTrading)
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
@ -734,7 +736,8 @@ namespace MWGui
&& (type != typeid(ESM::Potion).name()))
return;
if (object.getClass().getName(object) == "") // objects without name presented to user can never be picked up
// An object that can be picked up must have a tooltip.
if (!object.getClass().hasToolTip(object))
return;
int count = object.getRefData().getCount();

@ -32,26 +32,6 @@ namespace MWGui
{
}
bool ItemStack::stacks(const ItemStack &other)
{
if(mBase == other.mBase)
return true;
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
if (mBase.getContainerStore() && other.mBase.getContainerStore())
return mBase.getContainerStore()->stacks(mBase, other.mBase)
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
if (mBase.getContainerStore())
return mBase.getContainerStore()->stacks(mBase, other.mBase);
if (other.mBase.getContainerStore())
return other.mBase.getContainerStore()->stacks(mBase, other.mBase);
MWWorld::ContainerStore store;
return store.stacks(mBase, other.mBase);
}
bool operator == (const ItemStack& left, const ItemStack& right)
{
if (left.mType != right.mType)

@ -13,7 +13,6 @@ namespace MWGui
{
ItemStack (const MWWorld::Ptr& base, ItemModel* creator, size_t count);
ItemStack();
bool stacks (const ItemStack& other);
///< like operator==, only without checking mType
enum Type

@ -39,6 +39,8 @@ namespace MWGui
/// and end of the span relative to the body, and a valid topic ID if
/// the span represents a keyword, or zero if not.
virtual void visitSpans (std::function <void (TopicId, size_t, size_t)> visitor) const = 0;
virtual ~Entry() = default;
};
/// An interface to topic data.
@ -47,6 +49,8 @@ namespace MWGui
/// Returns a pre-formatted span of UTF8 encoded text representing
/// the name of the NPC this portion of dialog was heard from.
virtual Utf8Span source () const = 0;
virtual ~TopicEntry() = default;
};
/// An interface to journal data.
@ -55,8 +59,9 @@ namespace MWGui
/// Returns a pre-formatted span of UTF8 encoded text representing
/// the in-game date this entry was added to the journal.
virtual Utf8Span timestamp () const = 0;
};
virtual ~JournalEntry() = default;
};
/// called prior to journal opening
virtual void load () = 0;
@ -85,6 +90,8 @@ namespace MWGui
// create an instance of the default journal view model implementation
static Ptr create ();
virtual ~JournalViewModel() = default;
};
}

@ -116,6 +116,12 @@ void KeyboardNavigation::onFrame()
if (!mEnabled)
return;
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr);
return;
}
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (focus == mCurrentFocus)
@ -215,6 +221,9 @@ bool KeyboardNavigation::injectKeyPress(MyGUI::KeyCode key, unsigned int text, b
bool KeyboardNavigation::switchFocus(int direction, bool wrap)
{
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
return false;
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
bool isCycle = (direction == D_Prev || direction == D_Next);

@ -1,5 +1,7 @@
#include "loadingscreen.hpp"
#include <array>
#include <osgViewer/Viewer>
#include <osg/Texture2D>
@ -14,13 +16,14 @@
#include <components/myguiplatform/myguitexture.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/manager.hpp>
#include <components/sceneutil/vismask.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwrender/vismask.hpp"
#include "backgroundimage.hpp"
namespace MWGui
@ -66,7 +69,7 @@ namespace MWGui
mVFS->normalizeFilename(pattern);
/* priority given to the left */
std::list<std::string> supported_extensions = {".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"};
const std::array<std::string, 7> supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}};
auto found = index.lower_bound(pattern);
while (found != index.end())
@ -77,7 +80,7 @@ namespace MWGui
size_t pos = name.find_last_of('.');
if (pos != std::string::npos)
{
for(auto const extension: supported_extensions)
for(auto const& extension: supported_extensions)
{
if (name.compare(pos, name.size() - pos, extension) == 0)
{
@ -331,12 +334,6 @@ namespace MWGui
setupCopyFramebufferToTextureCallback();
}
// Turn off rendering except the GUI
int oldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask();
int oldCullMask = mViewer->getCamera()->getCullMask();
mViewer->getUpdateVisitor()->setTraversalMask(SceneUtil::Mask_GUI|SceneUtil::Mask_PreCompile);
mViewer->getCamera()->setCullMask(SceneUtil::Mask_GUI|SceneUtil::Mask_PreCompile);
MWBase::Environment::get().getInputManager()->update(0, true, true);
//osg::Timer timer;
@ -352,10 +349,6 @@ namespace MWGui
//if (mViewer->getIncrementalCompileOperation())
//std::cout << "num to compile " << mViewer->getIncrementalCompileOperation()->getToCompile().size() << std::endl;
// resume 3d rendering
mViewer->getUpdateVisitor()->setTraversalMask(oldUpdateMask);
mViewer->getCamera()->setCullMask(oldCullMask);
mLastRenderTime = mTimer.time_m();
}

@ -209,6 +209,7 @@ namespace MWGui
MyGUI::IntCoord(mx*mMapWidgetSize, my*mMapWidgetSize, mMapWidgetSize, mMapWidgetSize),
MyGUI::Align::Top | MyGUI::Align::Left);
fog->setDepth(Local_FogLayer);
fog->setColour(MyGUI::Colour(0, 0, 0));
map->setNeedMouseFocus(false);
fog->setNeedMouseFocus(false);

@ -19,7 +19,7 @@
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwmechanics/spellutil.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp"
@ -401,7 +401,8 @@ namespace MWGui
return;
}
MWBase::Environment::get().getWindowManager()->useItem(item);
if (!store.isEquipped(item))
MWBase::Environment::get().getWindowManager()->useItem(item);
MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
// change draw state only if the item is in player's right hand
if (rightHand != store.end() && item == *rightHand)
@ -411,8 +412,8 @@ namespace MWGui
}
else if (key->type == Type_MagicItem)
{
// equip, if it can be equipped
if (!item.getClass().getEquipmentSlots(item).first.empty())
// equip, if it can be equipped and isn't yet equipped
if (!item.getClass().getEquipmentSlots(item).first.empty() && !store.isEquipped(item))
{
MWBase::Environment::get().getWindowManager()->useItem(item);

@ -15,10 +15,10 @@
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/spellutil.hpp"
#include "tooltips.hpp"
#include "class.hpp"

@ -7,7 +7,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwmechanics/spellutil.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/inventorystore.hpp"

@ -18,7 +18,7 @@
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwmechanics/spellutil.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp"

@ -17,7 +17,7 @@
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwmechanics/spellutil.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "mapwindow.hpp"
@ -651,6 +651,20 @@ namespace MWGui
return " (" + MyGUI::utility::toString(value) + ")";
}
std::string ToolTips::getSoulString(const MWWorld::CellRef& cellref)
{
std::string soul = cellref.getSoul();
if (soul.empty())
return std::string();
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Creature *creature = store.get<ESM::Creature>().search(soul);
if (!creature)
return std::string();
if (creature->mName.empty())
return " (" + creature->mId + ")";
return " (" + creature->mName + ")";
}
std::string ToolTips::getCellRefString(const MWWorld::CellRef& cellref)
{
std::string ret;

@ -81,6 +81,9 @@ namespace MWGui
static std::string getCountString(const int value);
///< @return blank string if count is 1, or else " (value)"
static std::string getSoulString(const MWWorld::CellRef& cellref);
///< Returns a string containing the name of the creature that the ID in the cellref's soul field belongs to.
static std::string getCellRefString(const MWWorld::CellRef& cellref);
///< Returns a string containing debug tooltip information about the given cellref.

@ -27,6 +27,7 @@
#include "tradeitemmodel.hpp"
#include "countdialog.hpp"
#include "controllers.hpp"
#include "tooltips.hpp"
namespace
{
@ -205,7 +206,8 @@ namespace MWGui
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
std::string message = "#{sQuanityMenuMessage02}";
dialog->openCountDialog(object.getClass().getName(object), message, count);
std::string name = object.getClass().getName(object) + MWGui::ToolTips::getSoulString(object.getCellRef());
dialog->openCountDialog(name, message, count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &TradeWindow::sellItem);
mItemToSell = mSortModel->mapToSource(index);

@ -76,6 +76,21 @@ void VideoWidget::stop()
mPlayer->close();
}
void VideoWidget::pause()
{
mPlayer->pause();
}
void VideoWidget::resume()
{
mPlayer->play();
}
bool VideoWidget::isPaused() const
{
return mPlayer->isPaused();
}
bool VideoWidget::hasAudioStream()
{
return mPlayer->hasAudioStream();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save