mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 21:09:41 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw into joystick
Conflicts: CMakeLists.txt
This commit is contained in:
commit
2b7287cbd2
388 changed files with 6072 additions and 3554 deletions
|
@ -31,6 +31,7 @@ before_script:
|
||||||
script:
|
script:
|
||||||
- cd ./build
|
- cd ./build
|
||||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j4; fi
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j4; fi
|
||||||
|
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
||||||
after_script:
|
after_script:
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||||
notifications:
|
notifications:
|
||||||
|
|
|
@ -33,12 +33,13 @@ Programmers
|
||||||
Douglas Diniz (Dgdiniz)
|
Douglas Diniz (Dgdiniz)
|
||||||
Douglas Mencken (dougmencken)
|
Douglas Mencken (dougmencken)
|
||||||
dreamer-dead
|
dreamer-dead
|
||||||
dteviot
|
David Teviotdale (dteviot)
|
||||||
Edmondo Tommasina (edmondo)
|
Edmondo Tommasina (edmondo)
|
||||||
Eduard Cot (trombonecot)
|
Eduard Cot (trombonecot)
|
||||||
Eli2
|
Eli2
|
||||||
Emanuel Guével (potatoesmaster)
|
Emanuel Guével (potatoesmaster)
|
||||||
eroen
|
eroen
|
||||||
|
Evgeniy Mineev (sandstranger)
|
||||||
Fil Krynicki (filkry)
|
Fil Krynicki (filkry)
|
||||||
Gašper Sedej
|
Gašper Sedej
|
||||||
gugus/gus
|
gugus/gus
|
||||||
|
@ -75,20 +76,22 @@ Programmers
|
||||||
Michał Bień (Glorf)
|
Michał Bień (Glorf)
|
||||||
Miroslav Puda (pakanek)
|
Miroslav Puda (pakanek)
|
||||||
MiroslavR
|
MiroslavR
|
||||||
|
naclander
|
||||||
Narmo
|
Narmo
|
||||||
Nathan Jeffords (blunted2night)
|
Nathan Jeffords (blunted2night)
|
||||||
|
NeveHanter
|
||||||
Nikolay Kasyanov (corristo)
|
Nikolay Kasyanov (corristo)
|
||||||
nobrakal
|
nobrakal
|
||||||
Nolan Poe (nopoe)
|
Nolan Poe (nopoe)
|
||||||
Paul McElroy (Greendogo)
|
Paul McElroy (Greendogo)
|
||||||
Pieter van der Kloet (pvdk)
|
Pieter van der Kloet (pvdk)
|
||||||
Radu-Marius Popovici (rpopovici)
|
Radu-Marius Popovici (rpopovici)
|
||||||
|
rdimesio
|
||||||
riothamus
|
riothamus
|
||||||
Robert MacGregor (Ragora)
|
Robert MacGregor (Ragora)
|
||||||
Rohit Nirmal
|
Rohit Nirmal
|
||||||
Roman Melnik (Kromgart)
|
Roman Melnik (Kromgart)
|
||||||
Roman Proskuryakov (humbug)
|
Roman Proskuryakov (humbug)
|
||||||
sandstranger
|
|
||||||
Sandy Carter (bwrsandman)
|
Sandy Carter (bwrsandman)
|
||||||
Scott Howard
|
Scott Howard
|
||||||
Sebastian Wick (swick)
|
Sebastian Wick (swick)
|
||||||
|
|
124
CHANGELOG.md
124
CHANGELOG.md
|
@ -1,3 +1,127 @@
|
||||||
|
0.35.0
|
||||||
|
------
|
||||||
|
|
||||||
|
Bug #244: Clipping/static in relation to the ghostgate/fence sound.
|
||||||
|
Bug #531: Missing transparent menu items
|
||||||
|
Bug #811: Content Lists in openmw.cfg are overwritten
|
||||||
|
Bug #925: OpenCS doesn't launch because it thinks its already started
|
||||||
|
Bug #969: Water shader strange behaviour on AMD card
|
||||||
|
Bug #1049: Partially highlighted word in dialogue may cause incorrect line break
|
||||||
|
Bug #1069: omwlauncher.exe crashes due to file lock
|
||||||
|
Bug #1192: It is possible to jump on top of hostile creatures in combat
|
||||||
|
Bug #1342: Loud ambient sounds
|
||||||
|
Bug #1431: Creatures can climb the player
|
||||||
|
Bug #1605: Guard in CharGen doesn't turn around to face you when reaching stairs
|
||||||
|
Bug #1624: Moon edges don't transition properly
|
||||||
|
Bug #1634: Items dropped by PC have collision
|
||||||
|
Bug #1637: Weird NPC behaviour in Vivec, Hlaalu Ancestral Vaults?
|
||||||
|
Bug #1638: Cannot climb staircases
|
||||||
|
Bug #1648: Enchanted equipment badly handled at game reload
|
||||||
|
Bug #1663: Crash when casting spell at enemy near you
|
||||||
|
Bug #1683: Scale doesn't apply to animated collision nodes
|
||||||
|
Bug #1702: Active enchanted item forgotten
|
||||||
|
Bug #1730: Scripts names starting with digit(s) fail to compile
|
||||||
|
Bug #1743: Moons are transparent
|
||||||
|
Bug #1745: Shadows crash: Assertion `mEffects.empty()' failed.
|
||||||
|
Bug #1785: Can't equip two-handed weapon and shield
|
||||||
|
Bug #1809: Player falls too easily
|
||||||
|
Bug #1825: Sword of Perithia can´t run in OpenMW
|
||||||
|
Bug #1899: The launcher resets any alterations you´ve made in the mod list order,
|
||||||
|
Bug #1964: Idle voices/dialogs not triggered correctly
|
||||||
|
Bug #1980: Please, change default click behavior in OpenMW Launchers Data Files list
|
||||||
|
Bug #1984: Vampire corpses standing up when looting the first item
|
||||||
|
Bug #1985: Calm spell does nothing
|
||||||
|
Bug #1986: Spell name lights up on mouseover but spell cost does not
|
||||||
|
Bug #1989: Tooltip still shown when menu toggled off
|
||||||
|
Bug #2010: Raindrops Displayed While Underwater
|
||||||
|
Bug #2023: Walking into plants causes massive framedrop
|
||||||
|
Bug #2031: [MOD: Shrines - Restore Health and Cancel Options]: Restore health option doesn't work
|
||||||
|
Bug #2039: Lake Fjalding pillar of fire not rendered
|
||||||
|
Bug #2040: AI_follow should stop further from the target
|
||||||
|
Bug #2076: Slaughterfish AI
|
||||||
|
Bug #2077: Direction of long jump can be changed much more than it is possible in vanilla
|
||||||
|
Bug #2078: error during rendering: Object '' not found (const)
|
||||||
|
Bug #2105: Lockpicking causes screen sync glitch
|
||||||
|
Bug #2113: [MOD: Julan Ashlander Companion] Julan does not act correctly within the Ghostfence.
|
||||||
|
Bug #2123: Window glow mod: Collision issues
|
||||||
|
Bug #2133: Missing collision for bridges in Balmora when using Morrowind Rebirth 2.81
|
||||||
|
Bug #2135: Casting a summon spell while the summon is active does not reset the summon.
|
||||||
|
Bug #2144: Changing equipment will unequip drawn arrows/bolts
|
||||||
|
Bug #2169: Yellow on faces when using opengl renderer and mods from overhaul on windows
|
||||||
|
Bug #2175: Pathgrid mods do not overwrite the existing pathgrid
|
||||||
|
Bug #2176: Morrowind -Russian localization end add-on ChaosHeart. Error in framelistener;object ;frenzying toush; not found <const>
|
||||||
|
Bug #2181: Mod Morrowind crafting merchants die.
|
||||||
|
Bug #2182: mods changing skill progression double the bonus for class specialization
|
||||||
|
Bug #2183: Editor: Skills "use value" only allows integer between 0 and 99
|
||||||
|
Bug #2184: Animated Morrowind Expanded produces an error on Open MW Launch
|
||||||
|
Bug #2185: Conditional Operator formats
|
||||||
|
Bug #2193: Quest: Gateway Ghost
|
||||||
|
Bug #2194: Cannot summon multiples of the same creature
|
||||||
|
Bug #2195: Pathgrid in the (0,0) exterior cell not loaded
|
||||||
|
Bug #2200: Outdoor NPCs can stray away and keep walking into a wall
|
||||||
|
Bug #2201: Creatures do not receive fall damage
|
||||||
|
Bug #2202: The enchantment the item can hold is calculated incorrectly
|
||||||
|
Bug #2203: Having the mod Living Cities of Vvardenfall running causes the game world to fail to load after leaving the prison ship
|
||||||
|
Bug #2204: Abot's Water Life - Book rendered incorrectly
|
||||||
|
Bug #2205: sound_waterfall script no longer compiles
|
||||||
|
Bug #2206: Dialogue script fails to compile (extra .)
|
||||||
|
Bug #2207: Script using – instead of - character does not compile
|
||||||
|
Bug #2208: Failing dialogue scripts in french Morrowind.esm
|
||||||
|
Bug #2214: LGNPC Vivec Redoran 1.62 and The King Rat (Size and inventory Issues)
|
||||||
|
Bug #2215: Beast races can use enchanted boots
|
||||||
|
Bug #2218: Incorrect names body parts in 3D models for open helmet with skinning
|
||||||
|
Bug #2219: Orcs in Ghorak Manor in Caldera don't attack if you pick their pockets.
|
||||||
|
Bug #2220: Chargen race preview head incorrect orientation
|
||||||
|
Bug #2223: Reseting rock falling animation
|
||||||
|
Bug #2224: Fortify Attribute effects do not stack when Spellmaking.
|
||||||
|
Bug #2226: OpenCS pseudo-crash
|
||||||
|
Bug #2230: segfaulting when entering Ald'ruhn with a specific mod: "fermeture la nuit" (closed by night)
|
||||||
|
Bug #2233: Area effect spells on touch do not have the area effect
|
||||||
|
Bug #2234: Dwarven Crossbow clips through the ground when dropped
|
||||||
|
Bug #2235: class SettingsBase<> reverses the order of entries with multiple keys.
|
||||||
|
Bug #2236: Weird two handed longsword + torch interaction
|
||||||
|
Bug #2237: Shooting arrows while sneaking do not agro
|
||||||
|
Bug #2238: Bipedal creatures not using weapons are not handled properly
|
||||||
|
Bug #2245: Incorrect topic highlighting in HT_SpyBaladas quest
|
||||||
|
Bug #2252: Tab completion incomplete for places using COC from the console.
|
||||||
|
Bug #2255: Camera reverts to first person on load
|
||||||
|
Bug #2259: enhancement: the save/load progress bar is not very progressive
|
||||||
|
Bug #2263: TogglePOV can not be bound to Alt key
|
||||||
|
Bug #2267: dialogue disabling via mod
|
||||||
|
Bug #2268: Highlighting Files with load order problems in Data Files tab of Launcher
|
||||||
|
Bug #2276: [Mod]ShotN issues with Karthwasten
|
||||||
|
Bug #2283: Count argument for PlaceAt functions not working
|
||||||
|
Bug #2284: Local map notes should be visible on door marker leading to the cell with the note
|
||||||
|
Bug #2293: There is a graphical glitch at the end of the spell's animation in 3rd Person (looking over the shoulder) view
|
||||||
|
Bug #2294: When using Skyrim UI Overhaul, the tops of pinnable menus are invisible
|
||||||
|
Bug #2302: Random leveled items repeat way too often in a single dungeon
|
||||||
|
Bug #2306: Enchanted arrows should not be retrievable from corpses
|
||||||
|
Bug #2308: No sound effect when drawing the next throwing knife
|
||||||
|
Bug #2309: Guards chase see the player character even if they're invisible
|
||||||
|
Bug #2319: Inverted controls and other issues after becoming a vampire
|
||||||
|
Bug #2324: Spells cast when crossing cell border are imprinted on the local map
|
||||||
|
Bug #2330: Actors with Drain Health effect retain health after dying
|
||||||
|
Bug #2331: tgm (god mode) won't allow the player to cast spells if the player doesn't have enough mana
|
||||||
|
Bug #2332: Error in framelistener: Need a skeleton to attach the arrow to
|
||||||
|
Feature #114: ess-Importer
|
||||||
|
Feature #504: Editor: Delete selected rows from result windows
|
||||||
|
Feature #1024: Addition of remaining equipping hotkeys
|
||||||
|
Feature #1067: Handle NIF interpolation type 4 (XYZ_ROTATION_KEY)
|
||||||
|
Feature #1125: AI fast-forward
|
||||||
|
Feature #1228: Drowning while knocked out
|
||||||
|
Feature #1325: Editor: Opening window and User Settings window cleanup
|
||||||
|
Feature #1537: Ability to change the grid size from 3x3 to 5x5 (or more with good pc)
|
||||||
|
Feature #1546: Leveled list script functions
|
||||||
|
Feature #1659: Test dialogue scripts in --script-all
|
||||||
|
Feature #1720: NPC lookAt controller
|
||||||
|
Feature #2178: Load initial particle system state from NIF files
|
||||||
|
Feature #2197: Editor: When clicking on a script error in the report window set cursor in script editor to the respective line/column
|
||||||
|
Feature #2261: Warn when loading save games with mod mismatch
|
||||||
|
Feature #2313: ess-Importer: convert global map exploration overlay
|
||||||
|
Feature #2318: Add commandline option to load a save game
|
||||||
|
Task #810: Rename "profile" to "content list"
|
||||||
|
Task #2196: Label local/global openmw.cfg files via comments
|
||||||
|
|
||||||
0.34.0
|
0.34.0
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,4 @@ export CC=clang
|
||||||
brew tap openmw/openmw
|
brew tap openmw/openmw
|
||||||
brew update
|
brew update
|
||||||
brew unlink boost
|
brew unlink boost
|
||||||
brew install openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg qt unshield
|
brew install openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg openmw/openmw/qt unshield
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
project(OpenMW)
|
project(OpenMW)
|
||||||
|
|
||||||
|
# If the user doesn't supply a CMAKE_BUILD_TYPE via command line, choose one for them.
|
||||||
|
IF(NOT CMAKE_BUILD_TYPE)
|
||||||
|
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||||
|
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||||
|
FORCE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
||||||
|
|
||||||
|
@ -12,7 +19,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
message(STATUS "Configuring OpenMW...")
|
message(STATUS "Configuring OpenMW...")
|
||||||
|
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 34)
|
set(OPENMW_VERSION_MINOR 35)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -374,10 +381,8 @@ configure_file(${OpenMW_SOURCE_DIR}/files/gamecontrollerdb.txt
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||||
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw-mimeinfo.xml
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.desktop
|
||||||
"${OpenMW_BINARY_DIR}/openmw-mimeinfo.xml")
|
"${OpenMW_BINARY_DIR}/openmw-cs.desktop")
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/opencs.desktop
|
|
||||||
"${OpenMW_BINARY_DIR}/opencs.desktop")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compiler settings
|
# Compiler settings
|
||||||
|
@ -389,13 +394,19 @@ if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||||
SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}")
|
||||||
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||||
|
elseif (MSVC)
|
||||||
|
# Enable link-time code generation globally for all linking
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
|
||||||
|
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
|
||||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
IF(NOT WIN32 AND NOT APPLE)
|
IF(NOT WIN32 AND NOT APPLE)
|
||||||
# Linux building
|
# Linux building
|
||||||
# Paths
|
# Paths
|
||||||
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||||
SET(LIBDIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Where to install libraries")
|
SET(LIBDIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "Where to install libraries")
|
||||||
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
SET(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||||
SET(GLOBAL_DATA_PATH "${DATAROOTDIR}/games/" CACHE PATH "Set data path prefix")
|
SET(GLOBAL_DATA_PATH "${DATAROOTDIR}/games/" CACHE PATH "Set data path prefix")
|
||||||
SET(DATADIR "${GLOBAL_DATA_PATH}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
SET(DATADIR "${GLOBAL_DATA_PATH}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||||
|
@ -411,7 +422,7 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
# Install binaries
|
# Install binaries
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||||
IF(BUILD_LAUNCHER)
|
IF(BUILD_LAUNCHER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-launcher" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_LAUNCHER)
|
ENDIF(BUILD_LAUNCHER)
|
||||||
IF(BUILD_BSATOOL)
|
IF(BUILD_BSATOOL)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
|
||||||
|
@ -420,13 +431,13 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_ESMTOOL)
|
ENDIF(BUILD_ESMTOOL)
|
||||||
IF(BUILD_MWINIIMPORTER)
|
IF(BUILD_MWINIIMPORTER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-iniimporter" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_MWINIIMPORTER)
|
ENDIF(BUILD_MWINIIMPORTER)
|
||||||
IF(BUILD_ESSIMPORTER)
|
IF(BUILD_ESSIMPORTER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-essimporter" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-essimporter" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_ESSIMPORTER)
|
ENDIF(BUILD_ESSIMPORTER)
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-cs" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
IF(BUILD_NIFTEST)
|
IF(BUILD_NIFTEST)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
||||||
|
@ -443,25 +454,25 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||||
|
|
||||||
# Install icon and desktop file
|
# Install icon and desktop file
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-mimeinfo.xml" DESTINATION "${DATAROOTDIR}/mime/packages" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.desktop" DESTINATION "${DATAROOTDIR}/applications" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "opencs")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "opencs")
|
||||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/opencs.png" DESTINATION "${ICONDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "opencs")
|
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/openmw-cs.png" DESTINATION "${ICONDIR}" COMPONENT "opencs")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
|
||||||
# Install global configuration files
|
# Install global configuration files
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||||
|
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "opencs")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
|
||||||
# Install resources
|
# Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources")
|
||||||
INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources")
|
INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources")
|
||||||
ENDIF(NOT WIN32 AND NOT APPLE)
|
ENDIF(NOT WIN32 AND NOT APPLE)
|
||||||
|
|
||||||
|
@ -481,16 +492,16 @@ if(WIN32)
|
||||||
DESTINATION ".")
|
DESTINATION ".")
|
||||||
|
|
||||||
IF(BUILD_LAUNCHER)
|
IF(BUILD_LAUNCHER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION ".")
|
||||||
ENDIF(BUILD_LAUNCHER)
|
ENDIF(BUILD_LAUNCHER)
|
||||||
IF(BUILD_MWINIIMPORTER)
|
IF(BUILD_MWINIIMPORTER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/mwiniimport.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION ".")
|
||||||
ENDIF(BUILD_MWINIIMPORTER)
|
ENDIF(BUILD_MWINIIMPORTER)
|
||||||
IF(BUILD_ESSIMPORTER)
|
IF(BUILD_ESSIMPORTER)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION ".")
|
||||||
ENDIF(BUILD_ESSIMPORTER)
|
ENDIF(BUILD_ESSIMPORTER)
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/opencs.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
IF(BUILD_WIZARD)
|
IF(BUILD_WIZARD)
|
||||||
|
@ -511,10 +522,10 @@ if(WIN32)
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW")
|
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW")
|
||||||
IF(BUILD_LAUNCHER)
|
IF(BUILD_LAUNCHER)
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};omwlauncher;OpenMW Launcher")
|
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-launcher;OpenMW Launcher")
|
||||||
ENDIF(BUILD_LAUNCHER)
|
ENDIF(BUILD_LAUNCHER)
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set")
|
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-cs;OpenMW Construction Set")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
IF(BUILD_WIZARD)
|
IF(BUILD_WIZARD)
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-wizard;OpenMW Wizard")
|
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-wizard;OpenMW Wizard")
|
||||||
|
@ -530,7 +541,7 @@ if(WIN32)
|
||||||
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}")
|
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}")
|
||||||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||||
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
|
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
|
||||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
|
SET(CPACK_NSIS_INSTALLED_ICON_NAME "openmw-launcher.exe")
|
||||||
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||||
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||||
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
|
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
|
||||||
|
@ -667,6 +678,7 @@ if (WIN32)
|
||||||
4193 # #pragma warning(pop) : no matching '#pragma warning(push)'
|
4193 # #pragma warning(pop) : no matching '#pragma warning(push)'
|
||||||
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
|
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
|
||||||
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
|
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
|
||||||
|
4315 # undocumented, 'this' pointer for member might not be aligned (OgreMemoryStlAllocator.h)
|
||||||
|
|
||||||
# caused by boost
|
# caused by boost
|
||||||
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
||||||
|
@ -674,6 +686,7 @@ if (WIN32)
|
||||||
# OpenMW specific warnings
|
# OpenMW specific warnings
|
||||||
4099 # Type mismatch, declared class or struct is defined with other type
|
4099 # Type mismatch, declared class or struct is defined with other type
|
||||||
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
||||||
|
4101 # Unreferenced local variable (-Wunused-variable)
|
||||||
4127 # Conditional expression is constant
|
4127 # Conditional expression is constant
|
||||||
4242 # Storing value in a variable of a smaller type, possible loss of data
|
4242 # Storing value in a variable of a smaller type, possible loss of data
|
||||||
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
||||||
|
@ -695,16 +708,18 @@ if (WIN32)
|
||||||
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
|
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
|
||||||
set(SHINY_WARNINGS "${WARNINGS} /wd4245")
|
set(SHINY_WARNINGS "${WARNINGS} /wd4245")
|
||||||
set_target_properties(shiny PROPERTIES COMPILE_FLAGS "${SHINY_WARNINGS} ${MT_BUILD}")
|
set_target_properties(shiny PROPERTIES COMPILE_FLAGS "${SHINY_WARNINGS} ${MT_BUILD}")
|
||||||
# there's an unreferenced local variable in the ogre platform, suppress it
|
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
set(SHINY_OGRE_WARNINGS "${WARNINGS} /wd4101")
|
|
||||||
set_target_properties(shiny.OgrePlatform PROPERTIES COMPILE_FLAGS "${SHINY_OGRE_WARNINGS} ${MT_BUILD}")
|
|
||||||
set_target_properties(sdl4ogre PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(sdl4ogre PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
# oics uses tinyxml, which has an initialized but unused variable
|
# oics uses tinyxml, which has an initialized but unused variable
|
||||||
set(OICS_WARNINGS "${WARNINGS} /wd4189")
|
set(OICS_WARNINGS "${WARNINGS} /wd4189")
|
||||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
||||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
|
set_target_properties(ogre-ffmpeg-videoplayer PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
|
if (BUILD_MYGUI_PLUGIN)
|
||||||
|
set_target_properties(Plugin_MyGUI_OpenMW_Resources PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
|
endif (BUILD_MYGUI_PLUGIN)
|
||||||
if (BUILD_LAUNCHER)
|
if (BUILD_LAUNCHER)
|
||||||
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(openmw-launcher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
endif (BUILD_LAUNCHER)
|
endif (BUILD_LAUNCHER)
|
||||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
if (BUILD_BSATOOL)
|
if (BUILD_BSATOOL)
|
||||||
|
@ -719,10 +734,13 @@ if (WIN32)
|
||||||
if (BUILD_OPENCS)
|
if (BUILD_OPENCS)
|
||||||
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
||||||
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
||||||
set_target_properties(opencs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
set_target_properties(openmw-cs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
||||||
endif (BUILD_OPENCS)
|
endif (BUILD_OPENCS)
|
||||||
|
if (BUILD_ESSIMPORTER)
|
||||||
|
set_target_properties(openmw-essimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
|
endif (BUILD_ESSIMPORTER)
|
||||||
if (BUILD_MWINIIMPORTER)
|
if (BUILD_MWINIIMPORTER)
|
||||||
set_target_properties(mwiniimport PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(openmw-iniimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
endif (BUILD_MWINIIMPORTER)
|
endif (BUILD_MWINIIMPORTER)
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
|
@ -767,7 +785,7 @@ if (APPLE)
|
||||||
|
|
||||||
set(OPENMW_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
|
set(OPENMW_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
|
||||||
|
|
||||||
set(OPENCS_BUNDLE_NAME "OpenCS.app")
|
set(OPENCS_BUNDLE_NAME "OpenMW-CS.app")
|
||||||
set(OPENCS_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}")
|
set(OPENCS_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}")
|
||||||
|
|
||||||
set(ABSOLUTE_PLUGINS "")
|
set(ABSOLUTE_PLUGINS "")
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
OpenMW
|
OpenMW
|
||||||
======
|
======
|
||||||
|
|
||||||
[](https://travis-ci.org/OpenMW/openmw)
|
[](https://travis-ci.org/OpenMW/openmw) [](https://scan.coverity.com/projects/3740)
|
||||||
|
|
||||||
[](https://scan.coverity.com/projects/3740)
|
|
||||||
|
|
||||||
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
||||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
||||||
|
|
||||||
* Version: 0.34.0
|
* Version: 0.35.0
|
||||||
* License: GPL (see docs/license/GPL3.txt for more information)
|
* License: GPL (see docs/license/GPL3.txt for more information)
|
||||||
* Website: http://www.openmw.org
|
* Website: http://www.openmw.org
|
||||||
* IRC: #openmw on irc.freenode.net
|
* IRC: #openmw on irc.freenode.net
|
||||||
|
@ -71,6 +69,9 @@ Command line options
|
||||||
--script-blacklist-use [=arg(=1)] (=1)
|
--script-blacklist-use [=arg(=1)] (=1)
|
||||||
enable script blacklisting
|
enable script blacklisting
|
||||||
--load-savegame arg load a save game file on game startup
|
--load-savegame arg load a save game file on game startup
|
||||||
|
(specify an absolute filename or a
|
||||||
|
filename relative to the current
|
||||||
|
working directory)
|
||||||
--skip-menu [=arg(=1)] (=0) skip main menu on game startup
|
--skip-menu [=arg(=1)] (=0) skip main menu on game startup
|
||||||
--new-game [=arg(=1)] (=0) run new game sequence (ignored if
|
--new-game [=arg(=1)] (=0) run new game sequence (ignored if
|
||||||
skip-menu=0)
|
skip-menu=0)
|
||||||
|
|
|
@ -59,6 +59,7 @@ struct Arguments
|
||||||
std::string outname;
|
std::string outname;
|
||||||
|
|
||||||
std::vector<std::string> types;
|
std::vector<std::string> types;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
ESMData data;
|
ESMData data;
|
||||||
ESM::ESMReader reader;
|
ESM::ESMReader reader;
|
||||||
|
@ -78,6 +79,8 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
("type,t", bpo::value< std::vector<std::string> >(),
|
("type,t", bpo::value< std::vector<std::string> >(),
|
||||||
"Show only records of this type (four character record code). May "
|
"Show only records of this type (four character record code). May "
|
||||||
"be specified multiple times. Only affects dump mode.")
|
"be specified multiple times. Only affects dump mode.")
|
||||||
|
("name,n", bpo::value<std::string>(),
|
||||||
|
"Show only the record with this name. Only affects dump mode.")
|
||||||
("plain,p", "Print contents of dialogs, books and scripts. "
|
("plain,p", "Print contents of dialogs, books and scripts. "
|
||||||
"(skipped by default)"
|
"(skipped by default)"
|
||||||
"Only affects dump mode.")
|
"Only affects dump mode.")
|
||||||
|
@ -149,6 +152,8 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
|
|
||||||
if (variables.count("type") > 0)
|
if (variables.count("type") > 0)
|
||||||
info.types = variables["type"].as< std::vector<std::string> >();
|
info.types = variables["type"].as< std::vector<std::string> >();
|
||||||
|
if (variables.count("name") > 0)
|
||||||
|
info.name = variables["name"].as<std::string>();
|
||||||
|
|
||||||
info.mode = variables["mode"].as<std::string>();
|
info.mode = variables["mode"].as<std::string>();
|
||||||
if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp"))
|
if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp"))
|
||||||
|
@ -265,6 +270,8 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
||||||
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
||||||
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
||||||
std::cout << " Deleted: " << deleted << std::endl;
|
std::cout << " Deleted: " << deleted << std::endl;
|
||||||
|
if (!ref.mKey.empty())
|
||||||
|
std::cout << " Key: '" << ref.mKey << "'" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +365,9 @@ int load(Arguments& info)
|
||||||
if (id.empty())
|
if (id.empty())
|
||||||
id = esm.getHNOString("INAM");
|
id = esm.getHNOString("INAM");
|
||||||
|
|
||||||
|
if (!info.name.empty() && !Misc::StringUtils::ciEqual(info.name, id))
|
||||||
|
interested = false;
|
||||||
|
|
||||||
if(!quiet && interested)
|
if(!quiet && interested)
|
||||||
std::cout << "\nRecord: " << n.toString()
|
std::cout << "\nRecord: " << n.toString()
|
||||||
<< " '" << id << "'\n";
|
<< " '" << id << "'\n";
|
||||||
|
@ -385,7 +395,7 @@ int load(Arguments& info)
|
||||||
record->load(esm);
|
record->load(esm);
|
||||||
if (!quiet && interested) record->print();
|
if (!quiet && interested) record->print();
|
||||||
|
|
||||||
if (record->getType().val == ESM::REC_CELL && loadCells) {
|
if (record->getType().val == ESM::REC_CELL && loadCells && interested) {
|
||||||
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
|
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "labels.hpp"
|
#include "labels.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
void printAIPackage(ESM::AIPackage p)
|
void printAIPackage(ESM::AIPackage p)
|
||||||
|
@ -533,10 +535,10 @@ void Record<ESM::Class>::print()
|
||||||
std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization)
|
std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization)
|
||||||
<< " (" << mData.mData.mSpecialization << ")" << std::endl;
|
<< " (" << mData.mData.mSpecialization << ")" << std::endl;
|
||||||
for (int i = 0; i != 5; i++)
|
for (int i = 0; i != 5; i++)
|
||||||
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][0])
|
std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][0])
|
||||||
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
|
<< " (" << mData.mData.mSkills[i][0] << ")" << std::endl;
|
||||||
for (int i = 0; i != 5; i++)
|
for (int i = 0; i != 5; i++)
|
||||||
std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1])
|
||||||
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
<< " (" << mData.mData.mSkills[i][1] << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,7 +754,7 @@ void Record<ESM::DialInfo>::print()
|
||||||
if (mData.mCell != "")
|
if (mData.mCell != "")
|
||||||
std::cout << " Cell: " << mData.mCell << std::endl;
|
std::cout << " Cell: " << mData.mCell << std::endl;
|
||||||
if (mData.mData.mDisposition > 0)
|
if (mData.mData.mDisposition > 0)
|
||||||
std::cout << " Disposition: " << mData.mData.mDisposition << std::endl;
|
std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl;
|
||||||
if (mData.mData.mGender != ESM::DialInfo::NA)
|
if (mData.mData.mGender != ESM::DialInfo::NA)
|
||||||
std::cout << " Gender: " << mData.mData.mGender << std::endl;
|
std::cout << " Gender: " << mData.mData.mGender << std::endl;
|
||||||
if (mData.mSound != "")
|
if (mData.mSound != "")
|
||||||
|
@ -812,7 +814,6 @@ void Record<ESM::Land>::print()
|
||||||
{
|
{
|
||||||
std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl;
|
std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl;
|
||||||
std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " HasData: " << mData.mHasData << std::endl;
|
|
||||||
std::cout << " DataTypes: " << mData.mDataTypes << std::endl;
|
std::cout << " DataTypes: " << mData.mDataTypes << std::endl;
|
||||||
|
|
||||||
// Seems like this should done with reference counting in the
|
// Seems like this should done with reference counting in the
|
||||||
|
@ -836,7 +837,7 @@ void Record<ESM::CreatureLevList>::print()
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||||
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Creature: Level: " << iit->mLevel
|
std::cout << " Creature: Level: " << iit->mLevel
|
||||||
<< " Creature: " << iit->mId << std::endl;
|
<< " Creature: " << iit->mId << std::endl;
|
||||||
|
@ -848,7 +849,7 @@ void Record<ESM::ItemLevList>::print()
|
||||||
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl;
|
||||||
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
std::cout << " Number of items: " << mData.mList.size() << std::endl;
|
||||||
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
|
std::vector<ESM::LevelledListBase::LevelItem>::iterator iit;
|
||||||
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
|
||||||
std::cout << " Inventory: Level: " << iit->mLevel
|
std::cout << " Inventory: Level: " << iit->mLevel
|
||||||
<< " Item: " << iit->mId << std::endl;
|
<< " Item: " << iit->mId << std::endl;
|
||||||
|
|
|
@ -24,6 +24,8 @@ set(ESSIMPORTER_FILES
|
||||||
convertcrec.cpp
|
convertcrec.cpp
|
||||||
convertcntc.cpp
|
convertcntc.cpp
|
||||||
convertscri.cpp
|
convertscri.cpp
|
||||||
|
convertscpt.cpp
|
||||||
|
convertplayer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(openmw-essimporter
|
add_executable(openmw-essimporter
|
||||||
|
|
|
@ -29,6 +29,12 @@ namespace ESSImport
|
||||||
}
|
}
|
||||||
cStats.mGoldPool = acdt.mGoldPool;
|
cStats.mGoldPool = acdt.mGoldPool;
|
||||||
cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer;
|
cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer;
|
||||||
|
cStats.mAttacked = acdt.mFlags & Attacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats)
|
||||||
|
{
|
||||||
|
cStats.mDead = acsc.mFlags & Dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats)
|
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats)
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace ESSImport
|
||||||
|
|
||||||
|
|
||||||
void convertACDT (const ACDT& acdt, ESM::CreatureStats& cStats);
|
void convertACDT (const ACDT& acdt, ESM::CreatureStats& cStats);
|
||||||
|
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats);
|
||||||
|
|
||||||
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats);
|
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <OgreImage.h>
|
#include <OgreImage.h>
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
|
||||||
#include <components/esm/creaturestate.hpp>
|
#include <components/esm/creaturestate.hpp>
|
||||||
#include <components/esm/containerstate.hpp>
|
#include <components/esm/containerstate.hpp>
|
||||||
|
@ -69,7 +70,65 @@ namespace ESSImport
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
data.resize(esm.getSubSize());
|
data.resize(esm.getSubSize());
|
||||||
esm.getExact(&data[0], data.size());
|
esm.getExact(&data[0], data.size());
|
||||||
convertImage(&data[0], data.size(), maph.size, maph.size, Ogre::PF_BYTE_RGB, "map.tga");
|
|
||||||
|
Ogre::DataStreamPtr stream (new Ogre::MemoryDataStream(&data[0], data.size()));
|
||||||
|
mGlobalMapImage.loadRawData(stream, maph.size, maph.size, 1, Ogre::PF_BYTE_RGB);
|
||||||
|
// to match openmw size
|
||||||
|
mGlobalMapImage.resize(maph.size*2, maph.size*2, Ogre::Image::FILTER_BILINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertFMAP::write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
int numcells = mGlobalMapImage.getWidth() / 18; // NB truncating, doesn't divide perfectly
|
||||||
|
// with the 512x512 map the game has by default
|
||||||
|
int cellSize = mGlobalMapImage.getWidth()/numcells;
|
||||||
|
|
||||||
|
// Note the upper left corner of the (0,0) cell should be at (width/2, height/2)
|
||||||
|
|
||||||
|
mContext->mGlobalMapState.mBounds.mMinX = -numcells/2;
|
||||||
|
mContext->mGlobalMapState.mBounds.mMaxX = (numcells-1)/2;
|
||||||
|
mContext->mGlobalMapState.mBounds.mMinY = -(numcells-1)/2;
|
||||||
|
mContext->mGlobalMapState.mBounds.mMaxY = numcells/2;
|
||||||
|
|
||||||
|
Ogre::Image image2;
|
||||||
|
std::vector<Ogre::uint8> data;
|
||||||
|
int width = cellSize*numcells;
|
||||||
|
int height = cellSize*numcells;
|
||||||
|
data.resize(width*height*4, 0);
|
||||||
|
image2.loadDynamicImage(&data[0], width, height, Ogre::PF_BYTE_RGBA);
|
||||||
|
|
||||||
|
for (std::set<std::pair<int, int> >::const_iterator it = mContext->mExploredCells.begin(); it != mContext->mExploredCells.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first > mContext->mGlobalMapState.mBounds.mMaxX
|
||||||
|
|| it->first < mContext->mGlobalMapState.mBounds.mMinX
|
||||||
|
|| it->second > mContext->mGlobalMapState.mBounds.mMaxY
|
||||||
|
|| it->second < mContext->mGlobalMapState.mBounds.mMinY)
|
||||||
|
{
|
||||||
|
// out of bounds, I think this could happen, since the original engine had a fixed-size map
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int imageLeftSrc = mGlobalMapImage.getWidth()/2;
|
||||||
|
int imageTopSrc = mGlobalMapImage.getHeight()/2;
|
||||||
|
imageLeftSrc += it->first * cellSize;
|
||||||
|
imageTopSrc -= it->second * cellSize;
|
||||||
|
int imageLeftDst = width/2;
|
||||||
|
int imageTopDst = height/2;
|
||||||
|
imageLeftDst += it->first * cellSize;
|
||||||
|
imageTopDst -= it->second * cellSize;
|
||||||
|
for (int x=0; x<cellSize; ++x)
|
||||||
|
for (int y=0; y<cellSize; ++y)
|
||||||
|
image2.setColourAt(mGlobalMapImage.getColourAt(imageLeftSrc+x, imageTopSrc+y, 0)
|
||||||
|
, imageLeftDst+x, imageTopDst+y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::DataStreamPtr encoded = image2.encode("png");
|
||||||
|
mContext->mGlobalMapState.mImageData.resize(encoded->size());
|
||||||
|
encoded->read(&mContext->mGlobalMapState.mImageData[0], encoded->size());
|
||||||
|
|
||||||
|
esm.startRecord(ESM::REC_GMAP);
|
||||||
|
mContext->mGlobalMapState.save(esm);
|
||||||
|
esm.endRecord(ESM::REC_GMAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertCell::read(ESM::ESMReader &esm)
|
void ConvertCell::read(ESM::ESMReader &esm)
|
||||||
|
@ -103,6 +162,10 @@ namespace ESSImport
|
||||||
// (probably offset of that specific fog texture?)
|
// (probably offset of that specific fog texture?)
|
||||||
while (esm.isNextSub("NAM8"))
|
while (esm.isNextSub("NAM8"))
|
||||||
{
|
{
|
||||||
|
if (cell.isExterior()) // TODO: NAM8 occasionally exists for cells that haven't been explored.
|
||||||
|
// are there any flags marking explored cells?
|
||||||
|
mContext->mExploredCells.insert(std::make_pair(cell.mData.mX, cell.mData.mY));
|
||||||
|
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
|
|
||||||
if (esm.getSubSize() == 36)
|
if (esm.getSubSize() == 36)
|
||||||
|
@ -211,6 +274,8 @@ namespace ESSImport
|
||||||
const CellRef& cellref = *refIt;
|
const CellRef& cellref = *refIt;
|
||||||
ESM::CellRef out (cellref);
|
ESM::CellRef out (cellref);
|
||||||
|
|
||||||
|
// TODO: use mContext->mCreatures/mNpcs
|
||||||
|
|
||||||
if (!isIndexedRefId(cellref.mIndexedRefId))
|
if (!isIndexedRefId(cellref.mIndexedRefId))
|
||||||
{
|
{
|
||||||
// non-indexed RefNum, i.e. no CREC/NPCC/CNTC record associated with it
|
// non-indexed RefNum, i.e. no CREC/NPCC/CNTC record associated with it
|
||||||
|
@ -246,9 +311,12 @@ namespace ESSImport
|
||||||
objstate.blank();
|
objstate.blank();
|
||||||
objstate.mRef = out;
|
objstate.mRef = out;
|
||||||
objstate.mRef.mRefID = idLower;
|
objstate.mRef.mRefID = idLower;
|
||||||
// probably need more micromanagement here so we don't overwrite values
|
// TODO: need more micromanagement here so we don't overwrite values
|
||||||
// from the ESM with default values
|
// from the ESM with default values
|
||||||
|
if (cellref.mHasACDT)
|
||||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||||
|
if (cellref.mHasACSC)
|
||||||
|
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||||
convertNpcData(cellref, objstate.mNpcStats);
|
convertNpcData(cellref, objstate.mNpcStats);
|
||||||
convertNPCC(npccIt->second, objstate);
|
convertNPCC(npccIt->second, objstate);
|
||||||
convertCellRef(cellref, objstate);
|
convertCellRef(cellref, objstate);
|
||||||
|
@ -280,9 +348,12 @@ namespace ESSImport
|
||||||
objstate.blank();
|
objstate.blank();
|
||||||
objstate.mRef = out;
|
objstate.mRef = out;
|
||||||
objstate.mRef.mRefID = idLower;
|
objstate.mRef.mRefID = idLower;
|
||||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
// TODO: need more micromanagement here so we don't overwrite values
|
||||||
// probably need more micromanagement here so we don't overwrite values
|
|
||||||
// from the ESM with default values
|
// from the ESM with default values
|
||||||
|
if (cellref.mHasACDT)
|
||||||
|
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||||
|
if (cellref.mHasACSC)
|
||||||
|
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||||
convertCREC(crecIt->second, objstate);
|
convertCREC(crecIt->second, objstate);
|
||||||
convertCellRef(cellref, objstate);
|
convertCellRef(cellref, objstate);
|
||||||
esm.writeHNT ("OBJE", ESM::REC_CREA);
|
esm.writeHNT ("OBJE", ESM::REC_CREA);
|
||||||
|
@ -313,10 +384,6 @@ namespace ESSImport
|
||||||
it->save(esm);
|
it->save(esm);
|
||||||
esm.endRecord(ESM::REC_MARK);
|
esm.endRecord(ESM::REC_MARK);
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.startRecord(ESM::REC_GMAP);
|
|
||||||
mContext->mGlobalMapState.save(esm);
|
|
||||||
esm.endRecord(ESM::REC_GMAP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef OPENMW_ESSIMPORT_CONVERTER_H
|
#ifndef OPENMW_ESSIMPORT_CONVERTER_H
|
||||||
#define OPENMW_ESSIMPORT_CONVERTER_H
|
#define OPENMW_ESSIMPORT_CONVERTER_H
|
||||||
|
|
||||||
|
#include <OgreImage.h>
|
||||||
|
|
||||||
#include <components/esm/esmreader.hpp>
|
#include <components/esm/esmreader.hpp>
|
||||||
#include <components/esm/esmwriter.hpp>
|
#include <components/esm/esmwriter.hpp>
|
||||||
|
|
||||||
|
@ -13,6 +15,10 @@
|
||||||
#include <components/esm/dialoguestate.hpp>
|
#include <components/esm/dialoguestate.hpp>
|
||||||
#include <components/esm/custommarkerstate.hpp>
|
#include <components/esm/custommarkerstate.hpp>
|
||||||
#include <components/esm/loadcrea.hpp>
|
#include <components/esm/loadcrea.hpp>
|
||||||
|
#include <components/esm/weatherstate.hpp>
|
||||||
|
#include <components/esm/globalscript.hpp>
|
||||||
|
#include <components/esm/queststate.hpp>
|
||||||
|
#include <components/esm/stolenitems.hpp>
|
||||||
|
|
||||||
#include "importcrec.hpp"
|
#include "importcrec.hpp"
|
||||||
#include "importcntc.hpp"
|
#include "importcntc.hpp"
|
||||||
|
@ -29,6 +35,8 @@
|
||||||
|
|
||||||
#include "convertacdt.hpp"
|
#include "convertacdt.hpp"
|
||||||
#include "convertnpcc.hpp"
|
#include "convertnpcc.hpp"
|
||||||
|
#include "convertscpt.hpp"
|
||||||
|
#include "convertplayer.hpp"
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
{
|
{
|
||||||
|
@ -98,10 +106,10 @@ public:
|
||||||
npc.load(esm);
|
npc.load(esm);
|
||||||
if (id != "player")
|
if (id != "player")
|
||||||
{
|
{
|
||||||
// TODO:
|
// Handles changes to the NPC struct, but since there is no index here
|
||||||
// this should handle changes to the NPC struct, but since there is no index here
|
|
||||||
// it will apply to ALL instances of the class. seems to be the reason for the
|
// it will apply to ALL instances of the class. seems to be the reason for the
|
||||||
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
||||||
|
mContext->mNpcs[Misc::StringUtils::lowerCase(id)] = npc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -133,6 +141,7 @@ public:
|
||||||
ESM::Creature creature;
|
ESM::Creature creature;
|
||||||
std::string id = esm.getHNString("NAME");
|
std::string id = esm.getHNString("NAME");
|
||||||
creature.load(esm);
|
creature.load(esm);
|
||||||
|
mContext->mCreatures[Misc::StringUtils::lowerCase(id)] = creature;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +215,7 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int index = npcc.mNPDT.mIndex;
|
int index = npcc.mNPDT.mIndex;
|
||||||
mContext->mNpcChanges.insert(std::make_pair(std::make_pair(index,id), npcc)).second;
|
mContext->mNpcChanges.insert(std::make_pair(std::make_pair(index,id), npcc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -253,32 +262,23 @@ private:
|
||||||
class ConvertPCDT : public Converter
|
class ConvertPCDT : public Converter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ConvertPCDT() : mFirstPersonCam(true) {}
|
||||||
|
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
PCDT pcdt;
|
PCDT pcdt;
|
||||||
pcdt.load(esm);
|
pcdt.load(esm);
|
||||||
|
|
||||||
mContext->mPlayer.mBirthsign = pcdt.mBirthsign;
|
convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam);
|
||||||
mContext->mPlayer.mObject.mNpcStats.mBounty = pcdt.mBounty;
|
}
|
||||||
for (std::vector<PCDT::FNAM>::const_iterator it = pcdt.mFactions.begin(); it != pcdt.mFactions.end(); ++it)
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
{
|
{
|
||||||
ESM::NpcStats::Faction faction;
|
esm.startRecord(ESM::REC_CAM_);
|
||||||
faction.mExpelled = it->mFlags & 0x2;
|
esm.writeHNT("FIRS", mFirstPersonCam);
|
||||||
faction.mRank = it->mRank;
|
esm.endRecord(ESM::REC_CAM_);
|
||||||
faction.mReputation = it->mReputation;
|
|
||||||
mContext->mPlayer.mObject.mNpcStats.mFactions[it->mFactionName.toString()] = faction;
|
|
||||||
}
|
|
||||||
for (int i=0; i<8; ++i)
|
|
||||||
mContext->mPlayer.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
|
||||||
mContext->mPlayer.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
|
||||||
it != pcdt.mKnownDialogueTopics.end(); ++it)
|
|
||||||
{
|
|
||||||
mContext->mDialogueState.mKnownTopics.push_back(Misc::StringUtils::lowerCase(*it));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
bool mFirstPersonCam;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertCNTC : public Converter
|
class ConvertCNTC : public Converter
|
||||||
|
@ -308,6 +308,10 @@ class ConvertFMAP : public Converter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader &esm);
|
virtual void read(ESM::ESMReader &esm);
|
||||||
|
virtual void write(ESM::ESMWriter &esm);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ogre::Image mGlobalMapImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertCell : public Converter
|
class ConvertCell : public Converter
|
||||||
|
@ -384,29 +388,55 @@ public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
std::string itemid = esm.getHNString("NAME");
|
std::string itemid = esm.getHNString("NAME");
|
||||||
|
Misc::StringUtils::toLower(itemid);
|
||||||
|
|
||||||
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
||||||
{
|
{
|
||||||
if (esm.retSubName().toString() == "FNAM")
|
if (esm.retSubName().toString() == "FNAM")
|
||||||
{
|
{
|
||||||
std::string factionid = esm.getHString();
|
std::string factionid = esm.getHString();
|
||||||
mFactionStolenItems.insert(std::make_pair(itemid, factionid));
|
mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string ownerid = esm.getHString();
|
std::string ownerid = esm.getHString();
|
||||||
mStolenItems.insert(std::make_pair(itemid, ownerid));
|
mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
ESM::StolenItems items;
|
||||||
|
for (std::map<std::string, std::set<Owner> >::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
|
||||||
|
{
|
||||||
|
std::map<std::pair<std::string, bool>, int> owners;
|
||||||
|
for (std::set<Owner>::const_iterator ownerIt = it->second.begin(); ownerIt != it->second.end(); ++ownerIt)
|
||||||
|
{
|
||||||
|
owners.insert(std::make_pair(std::make_pair(ownerIt->first, ownerIt->second)
|
||||||
|
// Since OpenMW doesn't suffer from the owner contamination bug,
|
||||||
|
// it needs a count argument. But for legacy savegames, we don't know
|
||||||
|
// this count, so must assume all items of that ID are stolen,
|
||||||
|
// like vanilla MW did.
|
||||||
|
,std::numeric_limits<int>::max()));
|
||||||
|
}
|
||||||
|
|
||||||
|
items.mStolenItems.insert(std::make_pair(it->first, owners));
|
||||||
|
}
|
||||||
|
|
||||||
|
esm.startRecord(ESM::REC_STLN);
|
||||||
|
items.write(esm);
|
||||||
|
esm.endRecord(ESM::REC_STLN);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::multimap<std::string, std::string> mStolenItems;
|
typedef std::pair<std::string, bool> Owner; // <owner id, bool isFaction>
|
||||||
std::multimap<std::string, std::string> mFactionStolenItems;
|
|
||||||
|
std::map<std::string, std::set<Owner> > mStolenItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Seen responses for a dialogue topic?
|
/// Seen responses for a dialogue topic?
|
||||||
/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs
|
/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs
|
||||||
/// Dialogue conversion problems (probably have to adjust OpenMW format) -
|
/// Dialogue conversion problems:
|
||||||
/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID.
|
/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID.
|
||||||
/// - Seen dialogue responses only store the INFO id, rather than the fulltext.
|
/// - Seen dialogue responses only store the INFO id, rather than the fulltext.
|
||||||
/// - Quest stages only store the INFO id, rather than the journal entry fulltext.
|
/// - Quest stages only store the INFO id, rather than the journal entry fulltext.
|
||||||
|
@ -428,7 +458,24 @@ public:
|
||||||
std::string id = esm.getHNString("NAME");
|
std::string id = esm.getHNString("NAME");
|
||||||
DIAL dial;
|
DIAL dial;
|
||||||
dial.load(esm);
|
dial.load(esm);
|
||||||
|
if (dial.mIndex > 0)
|
||||||
|
mDials[id] = dial;
|
||||||
}
|
}
|
||||||
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
for (std::map<std::string, DIAL>::const_iterator it = mDials.begin(); it != mDials.end(); ++it)
|
||||||
|
{
|
||||||
|
esm.startRecord(ESM::REC_QUES);
|
||||||
|
ESM::QuestState state;
|
||||||
|
state.mFinished = 0;
|
||||||
|
state.mState = it->second.mIndex;
|
||||||
|
state.mTopic = Misc::StringUtils::lowerCase(it->first);
|
||||||
|
state.save(esm);
|
||||||
|
esm.endRecord(ESM::REC_QUES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::map<std::string, DIAL> mDials;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertQUES : public Converter
|
class ConvertQUES : public Converter
|
||||||
|
@ -455,11 +502,69 @@ public:
|
||||||
class ConvertGAME : public Converter
|
class ConvertGAME : public Converter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ConvertGAME() : mHasGame(false) {}
|
||||||
|
|
||||||
|
std::string toString(int weatherId)
|
||||||
|
{
|
||||||
|
switch (weatherId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "clear";
|
||||||
|
case 1:
|
||||||
|
return "cloudy";
|
||||||
|
case 2:
|
||||||
|
return "foggy";
|
||||||
|
case 3:
|
||||||
|
return "overcast";
|
||||||
|
case 4:
|
||||||
|
return "rain";
|
||||||
|
case 5:
|
||||||
|
return "thunderstorm";
|
||||||
|
case 6:
|
||||||
|
return "ashstorm";
|
||||||
|
case 7:
|
||||||
|
return "blight";
|
||||||
|
case 8:
|
||||||
|
return "snow";
|
||||||
|
case 9:
|
||||||
|
return "blizzard";
|
||||||
|
case -1:
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::stringstream error;
|
||||||
|
error << "unknown weather id: " << weatherId;
|
||||||
|
throw std::runtime_error(error.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
GAME game;
|
mGame.load(esm);
|
||||||
game.load(esm);
|
mHasGame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
if (!mHasGame)
|
||||||
|
return;
|
||||||
|
esm.startRecord(ESM::REC_WTHR);
|
||||||
|
ESM::WeatherState weather;
|
||||||
|
weather.mCurrentWeather = toString(mGame.mGMDT.mCurrentWeather);
|
||||||
|
weather.mNextWeather = toString(mGame.mGMDT.mNextWeather);
|
||||||
|
weather.mRemainingTransitionTime = mGame.mGMDT.mWeatherTransition/100.f*(0.015*24*3600);
|
||||||
|
weather.mHour = mContext->mHour;
|
||||||
|
weather.mWindSpeed = 0.f;
|
||||||
|
weather.mTimePassed = 0.0;
|
||||||
|
weather.mFirstUpdate = false;
|
||||||
|
weather.save(esm);
|
||||||
|
esm.endRecord(ESM::REC_WTHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mHasGame;
|
||||||
|
GAME mGame;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Running global script
|
/// Running global script
|
||||||
|
@ -470,7 +575,21 @@ public:
|
||||||
{
|
{
|
||||||
SCPT script;
|
SCPT script;
|
||||||
script.load(esm);
|
script.load(esm);
|
||||||
|
ESM::GlobalScript out;
|
||||||
|
convertSCPT(script, out);
|
||||||
|
mScripts.push_back(out);
|
||||||
}
|
}
|
||||||
|
virtual void write(ESM::ESMWriter &esm)
|
||||||
|
{
|
||||||
|
for (std::vector<ESM::GlobalScript>::const_iterator it = mScripts.begin(); it != mScripts.end(); ++it)
|
||||||
|
{
|
||||||
|
esm.startRecord(ESM::REC_GSCR);
|
||||||
|
it->save(esm);
|
||||||
|
esm.endRecord(ESM::REC_GSCR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<ESM::GlobalScript> mScripts;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
38
apps/essimporter/convertplayer.cpp
Normal file
38
apps/essimporter/convertplayer.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include "convertplayer.hpp"
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics, bool& firstPersonCam)
|
||||||
|
{
|
||||||
|
out.mBirthsign = pcdt.mBirthsign;
|
||||||
|
out.mObject.mNpcStats.mBounty = pcdt.mBounty;
|
||||||
|
for (std::vector<PCDT::FNAM>::const_iterator it = pcdt.mFactions.begin(); it != pcdt.mFactions.end(); ++it)
|
||||||
|
{
|
||||||
|
ESM::NpcStats::Faction faction;
|
||||||
|
faction.mExpelled = (it->mFlags & 0x2) != 0;
|
||||||
|
faction.mRank = it->mRank;
|
||||||
|
faction.mReputation = it->mReputation;
|
||||||
|
out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction;
|
||||||
|
}
|
||||||
|
for (int i=0; i<8; ++i)
|
||||||
|
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
||||||
|
for (int i=0; i<27; ++i)
|
||||||
|
out.mObject.mNpcStats.mSkills[i].mRegular.mProgress = pcdt.mPNAM.mSkillProgress[i];
|
||||||
|
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
||||||
|
|
||||||
|
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
||||||
|
out.mObject.mCreatureStats.mDrawState = 1;
|
||||||
|
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell)
|
||||||
|
out.mObject.mCreatureStats.mDrawState = 2;
|
||||||
|
|
||||||
|
firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
||||||
|
it != pcdt.mKnownDialogueTopics.end(); ++it)
|
||||||
|
{
|
||||||
|
outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
apps/essimporter/convertplayer.hpp
Normal file
15
apps/essimporter/convertplayer.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_CONVERTPLAYER_H
|
||||||
|
#define OPENMW_ESSIMPORT_CONVERTPLAYER_H
|
||||||
|
|
||||||
|
#include "importplayer.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/player.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics, bool& firstPersonCam);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
17
apps/essimporter/convertscpt.cpp
Normal file
17
apps/essimporter/convertscpt.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "convertscpt.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "convertscri.hpp"
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void convertSCPT(const SCPT &scpt, ESM::GlobalScript &out)
|
||||||
|
{
|
||||||
|
out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString());
|
||||||
|
out.mRunning = scpt.mRunning;
|
||||||
|
convertSCRI(scpt.mSCRI, out.mLocals);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
apps/essimporter/convertscpt.hpp
Normal file
15
apps/essimporter/convertscpt.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_CONVERTSCPT_H
|
||||||
|
#define OPENMW_ESSIMPORT_CONVERTSCPT_H
|
||||||
|
|
||||||
|
#include <components/esm/globalscript.hpp>
|
||||||
|
|
||||||
|
#include "importscpt.hpp"
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void convertSCPT(const SCPT& scpt, ESM::GlobalScript& out);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -20,12 +20,22 @@ namespace ESSImport
|
||||||
|
|
||||||
ESM::CellRef::loadData(esm);
|
ESM::CellRef::loadData(esm);
|
||||||
|
|
||||||
// FIXME: not all actors have this, add flag
|
mHasACDT = false;
|
||||||
esm.getHNOT(mACDT, "ACDT");
|
if (esm.isNextSub("ACDT"))
|
||||||
|
{
|
||||||
|
mHasACDT = true;
|
||||||
|
esm.getHT(mACDT);
|
||||||
|
}
|
||||||
|
|
||||||
ACSC acsc;
|
mHasACSC = false;
|
||||||
esm.getHNOT(acsc, "ACSC");
|
if (esm.isNextSub("ACSC"))
|
||||||
esm.getHNOT(acsc, "ACSL");
|
{
|
||||||
|
mHasACSC = true;
|
||||||
|
esm.getHT(mACSC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esm.isNextSub("ACSL"))
|
||||||
|
esm.skipHSubSize(112);
|
||||||
|
|
||||||
if (esm.isNextSub("CSTN"))
|
if (esm.isNextSub("CSTN"))
|
||||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||||
|
@ -60,10 +70,6 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("PWPS"))
|
if (esm.isNextSub("PWPS"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
// unsure at which point between LSTN and CHRD
|
|
||||||
if (esm.isNextSub("APUD"))
|
|
||||||
esm.skipHSub(); // 40 bytes, starts with string "ancestor guardian". maybe spellcasting in progress?
|
|
||||||
|
|
||||||
if (esm.isNextSub("WNAM"))
|
if (esm.isNextSub("WNAM"))
|
||||||
{
|
{
|
||||||
std::string id = esm.getHString();
|
std::string id = esm.getHString();
|
||||||
|
@ -77,6 +83,20 @@ namespace ESSImport
|
||||||
esm.skipHSub(); // 4 byte, 0
|
esm.skipHSub(); // 4 byte, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (esm.isNextSub("APUD"))
|
||||||
|
{
|
||||||
|
// used power
|
||||||
|
esm.getSubHeader();
|
||||||
|
std::string id = esm.getString(32);
|
||||||
|
(void)id;
|
||||||
|
// timestamp can't be used: this is the total hours passed, calculated by
|
||||||
|
// timestamp = 24 * (365 * year + cumulativeDays[month] + day)
|
||||||
|
// unfortunately cumulativeDays[month] is not clearly defined,
|
||||||
|
// in the (non-MCP) vanilla version the first month was missing, but MCP added it.
|
||||||
|
double timestamp;
|
||||||
|
esm.getT(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: not all actors have this, add flag
|
// FIXME: not all actors have this, add flag
|
||||||
if (esm.isNextSub("CHRD")) // npc only
|
if (esm.isNextSub("CHRD")) // npc only
|
||||||
esm.getHExact(mSkills, 27*2*sizeof(int));
|
esm.getHExact(mSkills, 27*2*sizeof(int));
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
@ -17,7 +17,13 @@ namespace ESSImport
|
||||||
|
|
||||||
enum ACDTFlags
|
enum ACDTFlags
|
||||||
{
|
{
|
||||||
TalkedToPlayer = 0x4
|
TalkedToPlayer = 0x4,
|
||||||
|
Attacked = 0x100,
|
||||||
|
Unknown = 0x200
|
||||||
|
};
|
||||||
|
enum ACSCFlags
|
||||||
|
{
|
||||||
|
Dead = 0x2
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Actor data, shared by (at least) REFR and CellRef
|
/// Actor data, shared by (at least) REFR and CellRef
|
||||||
|
@ -28,24 +34,38 @@ namespace ESSImport
|
||||||
// Note, not stored at *all*:
|
// Note, not stored at *all*:
|
||||||
// - Level changes are lost on reload, except for the player (there it's in the NPC record).
|
// - Level changes are lost on reload, except for the player (there it's in the NPC record).
|
||||||
unsigned char mUnknown[12];
|
unsigned char mUnknown[12];
|
||||||
unsigned char mFlags; // ACDTFlags
|
unsigned int mFlags;
|
||||||
unsigned char mUnknown1[3];
|
|
||||||
float mBreathMeter; // Seconds left before drowning
|
float mBreathMeter; // Seconds left before drowning
|
||||||
unsigned char mUnknown2[20];
|
unsigned char mUnknown2[20];
|
||||||
float mDynamic[3][2];
|
float mDynamic[3][2];
|
||||||
unsigned char mUnknown3[16];
|
unsigned char mUnknown3[16];
|
||||||
float mAttributes[8][2];
|
float mAttributes[8][2];
|
||||||
unsigned char mUnknown4[112];
|
float mMagicEffects[27]; // Effect attributes: https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attributes
|
||||||
|
unsigned char mUnknown4[4];
|
||||||
unsigned int mGoldPool;
|
unsigned int mGoldPool;
|
||||||
unsigned char mUnknown5[4];
|
unsigned char mCountDown; // seen the same value as in ACSC.mCorpseClearCountdown, maybe
|
||||||
|
// this one is for respawning?
|
||||||
|
unsigned char mUnknown5[3];
|
||||||
|
};
|
||||||
|
struct ACSC
|
||||||
|
{
|
||||||
|
unsigned char mUnknown1[17];
|
||||||
|
unsigned char mFlags; // ACSCFlags
|
||||||
|
unsigned char mUnknown2[22];
|
||||||
|
unsigned char mCorpseClearCountdown; // hours?
|
||||||
|
unsigned char mUnknown3[71];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct ActorData : public ESM::CellRef
|
struct ActorData : public ESM::CellRef
|
||||||
{
|
{
|
||||||
|
bool mHasACDT;
|
||||||
ACDT mACDT;
|
ACDT mACDT;
|
||||||
|
|
||||||
int mSkills[27][2];
|
bool mHasACSC;
|
||||||
|
ACSC mACSC;
|
||||||
|
|
||||||
|
int mSkills[27][2]; // skills, base and modified
|
||||||
|
|
||||||
// creature combat stats, base and modified
|
// creature combat stats, base and modified
|
||||||
// I think these can be ignored in the conversion, because it is not possible
|
// I think these can be ignored in the conversion, because it is not possible
|
||||||
|
@ -60,12 +80,6 @@ namespace ESSImport
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unknown, shared by (at least) REFR and CellRef
|
|
||||||
struct ACSC
|
|
||||||
{
|
|
||||||
unsigned char unknown[112];
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ESSImport
|
||||||
ActorData::load(esm);
|
ActorData::load(esm);
|
||||||
if (esm.isNextSub("LVCR"))
|
if (esm.isNextSub("LVCR"))
|
||||||
{
|
{
|
||||||
// occurs on leveled creature spawner references
|
// occurs on levelled creature spawner references
|
||||||
// probably some identifier for the creature that has been spawned?
|
// probably some identifier for the creature that has been spawned?
|
||||||
unsigned char lvcr;
|
unsigned char lvcr;
|
||||||
esm.getHT(lvcr);
|
esm.getHT(lvcr);
|
||||||
|
@ -32,7 +32,7 @@ namespace ESSImport
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
esm.getHNOT(mEnabled, "ZNAM");
|
esm.getHNOT(mEnabled, "ZNAM");
|
||||||
|
|
||||||
// DATA should occur for all references, except leveled creature spawners
|
// DATA should occur for all references, except levelled creature spawners
|
||||||
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
||||||
// alarmvoi0000.ess
|
// alarmvoi0000.ess
|
||||||
esm.getHNOT(mPos, "DATA", 24);
|
esm.getHNOT(mPos, "DATA", 24);
|
||||||
|
|
|
@ -14,10 +14,10 @@ namespace ESSImport
|
||||||
float scale;
|
float scale;
|
||||||
esm.getHNOT(scale, "XSCL");
|
esm.getHNOT(scale, "XSCL");
|
||||||
|
|
||||||
// FIXME: use AiPackageList, need to fix getSubName()
|
|
||||||
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||||
|| esm.isNextSub("AI_A"))
|
|| esm.isNextSub("AI_A"))
|
||||||
esm.skipHSub();
|
mAiPackages.add(esm);
|
||||||
|
|
||||||
mInventory.load(esm);
|
mInventory.load(esm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define OPENMW_ESSIMPORT_CREC_H
|
#define OPENMW_ESSIMPORT_CREC_H
|
||||||
|
|
||||||
#include "importinventory.hpp"
|
#include "importinventory.hpp"
|
||||||
|
#include <components/esm/aipackage.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,7 @@ namespace ESSImport
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
Inventory mInventory;
|
Inventory mInventory;
|
||||||
|
ESM::AIPackageList mAiPackages;
|
||||||
|
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define OPENMW_ESSIMPORT_IMPORTDIAL_H
|
#define OPENMW_ESSIMPORT_IMPORTDIAL_H
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "importer.hpp"
|
#include "importer.hpp"
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@
|
||||||
#include <components/esm/loadlevlist.hpp>
|
#include <components/esm/loadlevlist.hpp>
|
||||||
#include <components/esm/loadglob.hpp>
|
#include <components/esm/loadglob.hpp>
|
||||||
|
|
||||||
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
#include "importercontext.hpp"
|
#include "importercontext.hpp"
|
||||||
|
|
||||||
#include "converter.hpp"
|
#include "converter.hpp"
|
||||||
|
@ -43,9 +46,10 @@ namespace
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
{
|
{
|
||||||
|
|
||||||
Importer::Importer(const std::string &essfile, const std::string &outfile)
|
Importer::Importer(const std::string &essfile, const std::string &outfile, const std::string &encoding)
|
||||||
: mEssFile(essfile)
|
: mEssFile(essfile)
|
||||||
, mOutFile(outfile)
|
, mOutFile(outfile)
|
||||||
|
, mEncoding(encoding)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -166,14 +170,30 @@ namespace ESSImport
|
||||||
std::cout << "Data 1:" << std::endl;
|
std::cout << "Data 1:" << std::endl;
|
||||||
for (unsigned int k=0; k<sub.mData.size(); ++k)
|
for (unsigned int k=0; k<sub.mData.size(); ++k)
|
||||||
{
|
{
|
||||||
|
bool different = false;
|
||||||
|
if (k >= sub2.mData.size() || sub2.mData[k] != sub.mData[k])
|
||||||
|
different = true;
|
||||||
|
|
||||||
|
if (different)
|
||||||
|
std::cout << "\033[033m";
|
||||||
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub.mData[k] << " ";
|
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub.mData[k] << " ";
|
||||||
|
if (different)
|
||||||
|
std::cout << "\033[0m";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "Data 2:" << std::endl;
|
std::cout << "Data 2:" << std::endl;
|
||||||
for (unsigned int k=0; k<sub2.mData.size(); ++k)
|
for (unsigned int k=0; k<sub2.mData.size(); ++k)
|
||||||
{
|
{
|
||||||
|
bool different = false;
|
||||||
|
if (k >= sub.mData.size() || sub.mData[k] != sub2.mData[k])
|
||||||
|
different = true;
|
||||||
|
|
||||||
|
if (different)
|
||||||
|
std::cout << "\033[033m";
|
||||||
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub2.mData[k] << " ";
|
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub2.mData[k] << " ";
|
||||||
|
if (different)
|
||||||
|
std::cout << "\033[0m";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -187,10 +207,10 @@ namespace ESSImport
|
||||||
Ogre::LogManager logman;
|
Ogre::LogManager logman;
|
||||||
Ogre::Root root;
|
Ogre::Root root;
|
||||||
|
|
||||||
// TODO: set up encoding on ESMReader based on openmw.cfg / --encoding switch
|
ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncoding));
|
||||||
|
|
||||||
ESM::ESMReader esm;
|
ESM::ESMReader esm;
|
||||||
esm.open(mEssFile);
|
esm.open(mEssFile);
|
||||||
|
esm.setEncoder(&encoder);
|
||||||
|
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
|
@ -341,8 +361,8 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
// exterior cell -> determine cell coordinates based on position
|
// exterior cell -> determine cell coordinates based on position
|
||||||
const int cellSize = 8192;
|
const int cellSize = 8192;
|
||||||
int cellX = std::floor(context.mPlayer.mObject.mPosition.pos[0]/cellSize);
|
int cellX = static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[0]/cellSize));
|
||||||
int cellY = std::floor(context.mPlayer.mObject.mPosition.pos[1]/cellSize);
|
int cellY = static_cast<int>(std::floor(context.mPlayer.mObject.mPosition.pos[1] / cellSize));
|
||||||
context.mPlayer.mCellId.mIndex.mX = cellX;
|
context.mPlayer.mCellId.mIndex.mX = cellX;
|
||||||
context.mPlayer.mCellId.mIndex.mY = cellY;
|
context.mPlayer.mCellId.mIndex.mY = cellY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace ESSImport
|
||||||
class Importer
|
class Importer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Importer(const std::string& essfile, const std::string& outfile);
|
Importer(const std::string& essfile, const std::string& outfile, const std::string& encoding);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ namespace ESSImport
|
||||||
private:
|
private:
|
||||||
std::string mEssFile;
|
std::string mEssFile;
|
||||||
std::string mOutFile;
|
std::string mOutFile;
|
||||||
|
std::string mEncoding;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <components/esm/player.hpp>
|
#include <components/esm/player.hpp>
|
||||||
#include <components/esm/dialoguestate.hpp>
|
#include <components/esm/dialoguestate.hpp>
|
||||||
#include <components/esm/globalmap.hpp>
|
#include <components/esm/globalmap.hpp>
|
||||||
|
#include <components/esm/loadcrea.hpp>
|
||||||
|
#include <components/esm/loadnpc.hpp>
|
||||||
|
|
||||||
#include "importnpcc.hpp"
|
#include "importnpcc.hpp"
|
||||||
#include "importcrec.hpp"
|
#include "importcrec.hpp"
|
||||||
|
@ -15,6 +17,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -29,6 +32,9 @@ namespace ESSImport
|
||||||
|
|
||||||
ESM::DialogueState mDialogueState;
|
ESM::DialogueState mDialogueState;
|
||||||
|
|
||||||
|
// cells which should show an explored overlay on the global map
|
||||||
|
std::set<std::pair<int, int> > mExploredCells;
|
||||||
|
|
||||||
ESM::GlobalMap mGlobalMapState;
|
ESM::GlobalMap mGlobalMapState;
|
||||||
|
|
||||||
int mDay, mMonth, mYear;
|
int mDay, mMonth, mYear;
|
||||||
|
@ -39,6 +45,9 @@ namespace ESSImport
|
||||||
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
|
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
|
||||||
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
|
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
|
||||||
|
|
||||||
|
std::map<std::string, ESM::Creature> mCreatures;
|
||||||
|
std::map<std::string, ESM::NPC> mNpcs;
|
||||||
|
|
||||||
Context()
|
Context()
|
||||||
{
|
{
|
||||||
mPlayer.mAutoMove = 0;
|
mPlayer.mAutoMove = 0;
|
||||||
|
|
|
@ -7,7 +7,23 @@ namespace ESSImport
|
||||||
|
|
||||||
void GAME::load(ESM::ESMReader &esm)
|
void GAME::load(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
esm.getHNT(mGMDT, "GMDT");
|
esm.getSubNameIs("GMDT");
|
||||||
|
esm.getSubHeader();
|
||||||
|
if (esm.getSubSize() == 92)
|
||||||
|
{
|
||||||
|
esm.getExact(&mGMDT, 92);
|
||||||
|
mGMDT.mSecundaPhase = 0;
|
||||||
|
}
|
||||||
|
else if (esm.getSubSize() == 96)
|
||||||
|
{
|
||||||
|
esm.getT(mGMDT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esm.fail("unexpected subrecord size for GAME.GMDT");
|
||||||
|
|
||||||
|
mGMDT.mWeatherTransition &= (0x000000ff);
|
||||||
|
mGMDT.mSecundaPhase &= (0x000000ff);
|
||||||
|
mGMDT.mMasserPhase &= (0x000000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace ESSImport
|
||||||
int mCurrentWeather, mNextWeather;
|
int mCurrentWeather, mNextWeather;
|
||||||
int mWeatherTransition; // 0-100 transition between weathers, top 3 bytes may be garbage
|
int mWeatherTransition; // 0-100 transition between weathers, top 3 bytes may be garbage
|
||||||
float mTimeOfNextTransition; // weather changes when gamehour == timeOfNextTransition
|
float mTimeOfNextTransition; // weather changes when gamehour == timeOfNextTransition
|
||||||
int masserPhase, secundaPhase; // top 3 bytes may be garbage
|
int mMasserPhase, mSecundaPhase; // top 3 bytes may be garbage
|
||||||
};
|
};
|
||||||
|
|
||||||
GMDT mGMDT;
|
GMDT mGMDT;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
|
|
@ -9,10 +9,9 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
esm.getHNT(mNPDT, "NPDT");
|
esm.getHNT(mNPDT, "NPDT");
|
||||||
|
|
||||||
// FIXME: use AiPackageList, need to fix getSubName()
|
|
||||||
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||||
|| esm.isNextSub("AI_A"))
|
|| esm.isNextSub("AI_A"))
|
||||||
esm.skipHSub();
|
mAiPackages.add(esm);
|
||||||
|
|
||||||
mInventory.load(esm);
|
mInventory.load(esm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace ESSImport
|
||||||
} mNPDT;
|
} mNPDT;
|
||||||
|
|
||||||
Inventory mInventory;
|
Inventory mInventory;
|
||||||
|
ESM::AIPackageList mAiPackages;
|
||||||
|
|
||||||
void load(ESM::ESMReader &esm);
|
void load(ESM::ESMReader &esm);
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,17 @@ struct PCDT
|
||||||
|
|
||||||
std::vector<std::string> mKnownDialogueTopics;
|
std::vector<std::string> mKnownDialogueTopics;
|
||||||
|
|
||||||
|
enum DrawState_
|
||||||
|
{
|
||||||
|
DrawState_Weapon = 0x80,
|
||||||
|
DrawState_Spell = 0x100
|
||||||
|
};
|
||||||
|
enum CameraState
|
||||||
|
{
|
||||||
|
CameraState_FirstPerson = 0x8,
|
||||||
|
CameraState_ThirdPerson = 0xa
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct FNAM
|
struct FNAM
|
||||||
|
@ -49,11 +60,13 @@ struct PCDT
|
||||||
unsigned char mUnknown2[3];
|
unsigned char mUnknown2[3];
|
||||||
ESM::NAME32 mFactionName;
|
ESM::NAME32 mFactionName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PNAM
|
struct PNAM
|
||||||
{
|
{
|
||||||
unsigned char mUnknown1[4];
|
short mDrawState; // DrawState
|
||||||
unsigned char mLevelProgress;
|
short mCameraState; // CameraState
|
||||||
unsigned char mUnknown2[111];
|
unsigned int mLevelProgress;
|
||||||
|
float mSkillProgress[27]; // skill progress, non-uniform scaled
|
||||||
unsigned char mSkillIncreases[8]; // number of skill increases for each attribute
|
unsigned char mSkillIncreases[8]; // number of skill increases for each attribute
|
||||||
unsigned char mUnknown3[88];
|
unsigned char mUnknown3[88];
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
class ESMReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
|
|
|
@ -13,8 +13,14 @@ namespace ESSImport
|
||||||
|
|
||||||
mSCRI.load(esm);
|
mSCRI.load(esm);
|
||||||
|
|
||||||
mRNAM = -1;
|
mRefNum = -1;
|
||||||
esm.getHNOT(mRNAM, "RNAM");
|
if (esm.isNextSub("RNAM"))
|
||||||
|
{
|
||||||
|
mRunning = true;
|
||||||
|
esm.getHT(mRefNum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
|
|
||||||
// A running global script
|
// A running global script
|
||||||
// TODO: test how targeted scripts are saved
|
|
||||||
struct SCPT
|
struct SCPT
|
||||||
{
|
{
|
||||||
ESM::Script::SCHD mSCHD;
|
ESM::Script::SCHD mSCHD;
|
||||||
|
@ -22,7 +21,8 @@ namespace ESSImport
|
||||||
// values of local variables
|
// values of local variables
|
||||||
SCRI mSCRI;
|
SCRI mSCRI;
|
||||||
|
|
||||||
int mRNAM; // unknown, seems to be -1 for some scripts, some huge integer for others
|
bool mRunning;
|
||||||
|
int mRefNum; // Targeted reference, -1: no reference
|
||||||
|
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "importer.hpp"
|
#include "importer.hpp"
|
||||||
|
|
||||||
namespace bpo = boost::program_options;
|
namespace bpo = boost::program_options;
|
||||||
|
@ -23,31 +25,36 @@ int main(int argc, char** argv)
|
||||||
("mwsave,m", bpo::value<std::string>(), "morrowind .ess save file")
|
("mwsave,m", bpo::value<std::string>(), "morrowind .ess save file")
|
||||||
("output,o", bpo::value<std::string>(), "output file (.omwsave)")
|
("output,o", bpo::value<std::string>(), "output file (.omwsave)")
|
||||||
("compare,c", "compare two .ess files")
|
("compare,c", "compare two .ess files")
|
||||||
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file")
|
||||||
;
|
;
|
||||||
p_desc.add("mwsave", 1).add("output", 1);
|
p_desc.add("mwsave", 1).add("output", 1);
|
||||||
|
|
||||||
bpo::variables_map vm;
|
bpo::variables_map variables;
|
||||||
|
|
||||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
||||||
.options(desc)
|
.options(desc)
|
||||||
.positional(p_desc)
|
.positional(p_desc)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
bpo::store(parsed, vm);
|
bpo::store(parsed, variables);
|
||||||
|
|
||||||
if(vm.count("help") || !vm.count("mwsave") || !vm.count("output")) {
|
if(variables.count("help") || !variables.count("mwsave") || !variables.count("output")) {
|
||||||
std::cout << desc;
|
std::cout << desc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpo::notify(vm);
|
bpo::notify(variables);
|
||||||
|
|
||||||
std::string essFile = vm["mwsave"].as<std::string>();
|
Files::ConfigurationManager cfgManager(true);
|
||||||
std::string outputFile = vm["output"].as<std::string>();
|
cfgManager.readConfiguration(variables, desc);
|
||||||
|
|
||||||
ESSImport::Importer importer(essFile, outputFile);
|
std::string essFile = variables["mwsave"].as<std::string>();
|
||||||
|
std::string outputFile = variables["output"].as<std::string>();
|
||||||
|
std::string encoding = variables["encoding"].as<std::string>();
|
||||||
|
|
||||||
if (vm.count("compare"))
|
ESSImport::Importer importer(essFile, outputFile, encoding);
|
||||||
|
|
||||||
|
if (variables.count("compare"))
|
||||||
importer.compare();
|
importer.compare();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,7 @@ if(NOT WIN32)
|
||||||
endif(NOT WIN32)
|
endif(NOT WIN32)
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
add_executable(omwlauncher
|
add_executable(openmw-launcher
|
||||||
${GUI_TYPE}
|
${GUI_TYPE}
|
||||||
${LAUNCHER}
|
${LAUNCHER}
|
||||||
${LAUNCHER_HEADER}
|
${LAUNCHER_HEADER}
|
||||||
|
@ -87,7 +87,7 @@ add_executable(omwlauncher
|
||||||
${UI_HDRS}
|
${UI_HDRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(omwlauncher
|
target_link_libraries(openmw-launcher
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${OGRE_STATIC_PLUGINS}
|
${OGRE_STATIC_PLUGINS}
|
||||||
|
@ -99,6 +99,6 @@ target_link_libraries(omwlauncher
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(omwlauncher gcov)
|
target_link_libraries(openmw-launcher gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
#include "utils/profilescombobox.hpp"
|
#include "utils/profilescombobox.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
const char *Launcher::DataFilesPage::mDefaultContentListName = "Default";
|
||||||
|
|
||||||
Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Config::LauncherSettings &launcherSettings, QWidget *parent)
|
Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Config::LauncherSettings &launcherSettings, QWidget *parent)
|
||||||
: mCfgMgr(cfg)
|
: mCfgMgr(cfg)
|
||||||
, mGameSettings(gameSettings)
|
, mGameSettings(gameSettings)
|
||||||
|
@ -48,9 +51,9 @@ void Launcher::DataFilesPage::buildView()
|
||||||
ui.deleteProfileButton->setToolTip ("Delete an existing Content List");
|
ui.deleteProfileButton->setToolTip ("Delete an existing Content List");
|
||||||
|
|
||||||
//combo box
|
//combo box
|
||||||
ui.profilesComboBox->addItem ("Default");
|
ui.profilesComboBox->addItem(mDefaultContentListName);
|
||||||
ui.profilesComboBox->setPlaceholderText (QString("Select a Content List..."));
|
ui.profilesComboBox->setPlaceholderText (QString("Select a Content List..."));
|
||||||
ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(QLatin1String("Default")));
|
ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(QLatin1String(mDefaultContentListName)));
|
||||||
|
|
||||||
// Add the actions to the toolbuttons
|
// Add the actions to the toolbuttons
|
||||||
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
|
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
|
||||||
|
@ -69,19 +72,6 @@ void Launcher::DataFilesPage::buildView()
|
||||||
|
|
||||||
bool Launcher::DataFilesPage::loadSettings()
|
bool Launcher::DataFilesPage::loadSettings()
|
||||||
{
|
{
|
||||||
QStringList paths = mGameSettings.getDataDirs();
|
|
||||||
|
|
||||||
foreach (const QString &path, paths)
|
|
||||||
mSelector->addFiles(path);
|
|
||||||
|
|
||||||
mDataLocal = mGameSettings.getDataLocal();
|
|
||||||
|
|
||||||
if (!mDataLocal.isEmpty())
|
|
||||||
mSelector->addFiles(mDataLocal);
|
|
||||||
|
|
||||||
paths.insert (0, mDataLocal);
|
|
||||||
PathIterator pathIterator (paths);
|
|
||||||
|
|
||||||
QStringList profiles = mLauncherSettings.getContentLists();
|
QStringList profiles = mLauncherSettings.getContentLists();
|
||||||
QString currentProfile = mLauncherSettings.getCurrentContentListName();
|
QString currentProfile = mLauncherSettings.getCurrentContentListName();
|
||||||
|
|
||||||
|
@ -94,11 +84,27 @@ bool Launcher::DataFilesPage::loadSettings()
|
||||||
if (!currentProfile.isEmpty())
|
if (!currentProfile.isEmpty())
|
||||||
addProfile(currentProfile, true);
|
addProfile(currentProfile, true);
|
||||||
|
|
||||||
mSelector->setProfileContent(filesInProfile(currentProfile, pathIterator));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
||||||
|
{
|
||||||
|
QStringList paths = mGameSettings.getDataDirs();
|
||||||
|
|
||||||
|
foreach(const QString &path, paths)
|
||||||
|
mSelector->addFiles(path);
|
||||||
|
|
||||||
|
mDataLocal = mGameSettings.getDataLocal();
|
||||||
|
|
||||||
|
if (!mDataLocal.isEmpty())
|
||||||
|
mSelector->addFiles(mDataLocal);
|
||||||
|
|
||||||
|
paths.insert(0, mDataLocal);
|
||||||
|
PathIterator pathIterator(paths);
|
||||||
|
|
||||||
|
mSelector->setProfileContent(filesInProfile(contentModelName, pathIterator));
|
||||||
|
}
|
||||||
|
|
||||||
QStringList Launcher::DataFilesPage::filesInProfile(const QString& profileName, PathIterator& pathIterator)
|
QStringList Launcher::DataFilesPage::filesInProfile(const QString& profileName, PathIterator& pathIterator)
|
||||||
{
|
{
|
||||||
QStringList files = mLauncherSettings.getContentListFiles(profileName);
|
QStringList files = mLauncherSettings.getContentListFiles(profileName);
|
||||||
|
@ -175,7 +181,7 @@ void Launcher::DataFilesPage::setProfile (const QString &previous, const QString
|
||||||
|
|
||||||
ui.profilesComboBox->setCurrentProfile (ui.profilesComboBox->findText (current));
|
ui.profilesComboBox->setCurrentProfile (ui.profilesComboBox->findText (current));
|
||||||
|
|
||||||
loadSettings();
|
populateFileViews(current);
|
||||||
|
|
||||||
checkForDefaultProfile();
|
checkForDefaultProfile();
|
||||||
}
|
}
|
||||||
|
@ -229,13 +235,6 @@ void Launcher::DataFilesPage::on_newProfileAction_triggered()
|
||||||
mLauncherSettings.setCurrentContentListName(profile);
|
mLauncherSettings.setCurrentContentListName(profile);
|
||||||
|
|
||||||
addProfile(profile, true);
|
addProfile(profile, true);
|
||||||
mSelector->clearCheckStates();
|
|
||||||
|
|
||||||
mSelector->setGameFile();
|
|
||||||
|
|
||||||
saveSettings();
|
|
||||||
|
|
||||||
emit signalProfileChanged (ui.profilesComboBox->findText(profile));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurrent)
|
void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurrent)
|
||||||
|
@ -262,15 +261,13 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
|
||||||
|
|
||||||
// this should work since the Default profile can't be deleted and is always index 0
|
// this should work since the Default profile can't be deleted and is always index 0
|
||||||
int next = ui.profilesComboBox->currentIndex()-1;
|
int next = ui.profilesComboBox->currentIndex()-1;
|
||||||
|
|
||||||
|
// changing the profile forces a reload of plugin file views.
|
||||||
ui.profilesComboBox->setCurrentIndex(next);
|
ui.profilesComboBox->setCurrentIndex(next);
|
||||||
|
|
||||||
removeProfile(profile);
|
removeProfile(profile);
|
||||||
ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile));
|
ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile));
|
||||||
|
|
||||||
saveSettings();
|
|
||||||
|
|
||||||
loadSettings();
|
|
||||||
|
|
||||||
checkForDefaultProfile();
|
checkForDefaultProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +287,7 @@ void Launcher::DataFilesPage::updateOkButton(const QString &text)
|
||||||
void Launcher::DataFilesPage::checkForDefaultProfile()
|
void Launcher::DataFilesPage::checkForDefaultProfile()
|
||||||
{
|
{
|
||||||
//don't allow deleting "Default" profile
|
//don't allow deleting "Default" profile
|
||||||
bool success = (ui.profilesComboBox->currentText() != "Default");
|
bool success = (ui.profilesComboBox->currentText() != mDefaultContentListName);
|
||||||
|
|
||||||
ui.deleteProfileAction->setEnabled (success);
|
ui.deleteProfileAction->setEnabled (success);
|
||||||
ui.profilesComboBox->setEditEnabled (success);
|
ui.profilesComboBox->setEditEnabled (success);
|
||||||
|
|
|
@ -58,6 +58,10 @@ namespace Launcher
|
||||||
void on_newProfileAction_triggered();
|
void on_newProfileAction_triggered();
|
||||||
void on_deleteProfileAction_triggered();
|
void on_deleteProfileAction_triggered();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Content List that is always present
|
||||||
|
const static char *mDefaultContentListName;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TextInputDialog *mProfileDialog;
|
TextInputDialog *mProfileDialog;
|
||||||
|
@ -82,6 +86,7 @@ namespace Launcher
|
||||||
bool showDeleteMessageBox (const QString &text);
|
bool showDeleteMessageBox (const QString &text);
|
||||||
void addProfile (const QString &profile, bool setAsCurrent);
|
void addProfile (const QString &profile, bool setAsCurrent);
|
||||||
void checkForDefaultProfile();
|
void checkForDefaultProfile();
|
||||||
|
void populateFileViews(const QString& contentModelName);
|
||||||
|
|
||||||
class PathIterator
|
class PathIterator
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL_video.h>
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreRenderSystem.h>
|
#include <OgreRenderSystem.h>
|
||||||
|
@ -67,7 +67,7 @@ bool Launcher::GraphicsPage::setupOgre()
|
||||||
}
|
}
|
||||||
catch(Ogre::Exception &ex)
|
catch(Ogre::Exception &ex)
|
||||||
{
|
{
|
||||||
QString ogreError = QString::fromStdString(ex.getFullDescription().c_str());
|
QString ogreError = QString::fromUtf8(ex.getFullDescription().c_str());
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setWindowTitle("Error creating Ogre::Root");
|
msgBox.setWindowTitle("Error creating Ogre::Root");
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
@ -135,7 +135,7 @@ bool Launcher::GraphicsPage::setupSDL()
|
||||||
msgBox.setWindowTitle(tr("Error receiving number of screens"));
|
msgBox.setWindowTitle(tr("Error receiving number of screens"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromUtf8(SDL_GetError()) + "<br>");
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ QStringList Launcher::GraphicsPage::getAvailableOptions(const QString &key, Ogre
|
||||||
opt_it != i->second.possibleValues.end(); ++opt_it, ++idx)
|
opt_it != i->second.possibleValues.end(); ++opt_it, ++idx)
|
||||||
{
|
{
|
||||||
if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0) {
|
if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0) {
|
||||||
result << ((key == "FSAA") ? QString("MSAA ") : QString("")) + QString::fromStdString((*opt_it).c_str()).simplified();
|
result << ((key == "FSAA") ? QString("MSAA ") : QString("")) + QString::fromUtf8((*opt_it).c_str()).simplified();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||||
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromUtf8(SDL_GetError()) + "<br>");
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||||
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(tr("<br><b>SDL_GetDisplayMode failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
msgBox.setText(tr("<br><b>SDL_GetDisplayMode failed:</b><br><br>") + QString::fromUtf8(SDL_GetError()) + "<br>");
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
@ -23,9 +24,11 @@ int main(int argc, char *argv[])
|
||||||
SDL_SetMainReady();
|
SDL_SetMainReady();
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
{
|
{
|
||||||
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
qDebug() << "SDL_Init failed: " << QString::fromUtf8(SDL_GetError());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
signal(SIGINT, SIG_DFL); // We don't want to use the SDL event loop in the launcher,
|
||||||
|
// so reset SIGINT which SDL wants to redirect to an SDL_Quit event.
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
|
|
@ -27,25 +27,6 @@ using namespace Process;
|
||||||
Launcher::MainDialog::MainDialog(QWidget *parent)
|
Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
: mGameSettings(mCfgMgr), QMainWindow (parent)
|
: mGameSettings(mCfgMgr), QMainWindow (parent)
|
||||||
{
|
{
|
||||||
// Install the stylesheet font
|
|
||||||
QFile file;
|
|
||||||
QFontDatabase fontDatabase;
|
|
||||||
|
|
||||||
const QStringList fonts = fontDatabase.families();
|
|
||||||
|
|
||||||
// Check if the font is installed
|
|
||||||
if (!fonts.contains("EB Garamond")) {
|
|
||||||
|
|
||||||
QString font = QString::fromUtf8(mCfgMgr.getGlobalDataPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
|
|
||||||
file.setFileName(font);
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
font = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
fontDatabase.addApplicationFont(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
mGameInvoker = new ProcessInvoker();
|
mGameInvoker = new ProcessInvoker();
|
||||||
|
@ -80,6 +61,7 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
QString revision(OPENMW_VERSION_COMMITHASH);
|
QString revision(OPENMW_VERSION_COMMITHASH);
|
||||||
QString tag(OPENMW_VERSION_TAGHASH);
|
QString tag(OPENMW_VERSION_TAGHASH);
|
||||||
|
|
||||||
|
versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
if (!revision.isEmpty() && !tag.isEmpty())
|
if (!revision.isEmpty() && !tag.isEmpty())
|
||||||
{
|
{
|
||||||
if (revision == tag) {
|
if (revision == tag) {
|
||||||
|
@ -257,24 +239,8 @@ void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem
|
||||||
current = previous;
|
current = previous;
|
||||||
|
|
||||||
int currentIndex = iconWidget->row(current);
|
int currentIndex = iconWidget->row(current);
|
||||||
// int previousIndex = iconWidget->row(previous);
|
|
||||||
|
|
||||||
pagesWidget->setCurrentIndex(currentIndex);
|
pagesWidget->setCurrentIndex(currentIndex);
|
||||||
|
mSettingsPage->resetProgressBar();
|
||||||
// DataFilesPage *previousPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(previousIndex));
|
|
||||||
// DataFilesPage *currentPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(currentIndex));
|
|
||||||
|
|
||||||
// //special call to update/save data files page list view when it's displayed/hidden.
|
|
||||||
// if (previousPage)
|
|
||||||
// {
|
|
||||||
// if (previousPage->objectName() == "DataFilesPage")
|
|
||||||
// previousPage->saveSettings();
|
|
||||||
// }
|
|
||||||
// else if (currentPage)
|
|
||||||
// {
|
|
||||||
// if (currentPage->objectName() == "DataFilesPage")
|
|
||||||
// currentPage->loadSettings();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupLauncherSettings()
|
bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <components/config/launchersettings.hpp>
|
#include <components/config/launchersettings.hpp>
|
||||||
|
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
|
#include "datafilespage.hpp"
|
||||||
|
|
||||||
using namespace Process;
|
using namespace Process;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
|
||||||
|
|
||||||
mWizardInvoker = new ProcessInvoker();
|
mWizardInvoker = new ProcessInvoker();
|
||||||
mImporterInvoker = new ProcessInvoker();
|
mImporterInvoker = new ProcessInvoker();
|
||||||
|
resetProgressBar();
|
||||||
|
|
||||||
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
||||||
this, SLOT(wizardStarted()));
|
this, SLOT(wizardStarted()));
|
||||||
|
@ -93,7 +95,7 @@ Launcher::SettingsPage::~SettingsPage()
|
||||||
|
|
||||||
void Launcher::SettingsPage::on_wizardButton_clicked()
|
void Launcher::SettingsPage::on_wizardButton_clicked()
|
||||||
{
|
{
|
||||||
saveSettings();
|
mMain->writeSettings();
|
||||||
|
|
||||||
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
||||||
return;
|
return;
|
||||||
|
@ -101,7 +103,7 @@ void Launcher::SettingsPage::on_wizardButton_clicked()
|
||||||
|
|
||||||
void Launcher::SettingsPage::on_importerButton_clicked()
|
void Launcher::SettingsPage::on_importerButton_clicked()
|
||||||
{
|
{
|
||||||
saveSettings();
|
mMain->writeSettings();
|
||||||
|
|
||||||
// Create the file if it doesn't already exist, else the importer will fail
|
// Create the file if it doesn't already exist, else the importer will fail
|
||||||
QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()));
|
QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()));
|
||||||
|
@ -140,8 +142,13 @@ void Launcher::SettingsPage::on_importerButton_clicked()
|
||||||
|
|
||||||
qDebug() << "arguments " << arguments;
|
qDebug() << "arguments " << arguments;
|
||||||
|
|
||||||
if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
|
// start the progress bar as a "bouncing ball"
|
||||||
return;
|
progressBar->setMaximum(0);
|
||||||
|
progressBar->setValue(0);
|
||||||
|
if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false))
|
||||||
|
{
|
||||||
|
resetProgressBar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::SettingsPage::on_browseButton_clicked()
|
void Launcher::SettingsPage::on_browseButton_clicked()
|
||||||
|
@ -196,27 +203,35 @@ void Launcher::SettingsPage::importerStarted()
|
||||||
void Launcher::SettingsPage::importerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
void Launcher::SettingsPage::importerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
{
|
{
|
||||||
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
||||||
return;
|
|
||||||
|
|
||||||
// Re-read the settings in their current state
|
|
||||||
mMain->reloadSettings();
|
|
||||||
|
|
||||||
// Import selected data files from openmw.cfg
|
|
||||||
if (addonsCheckBox->isChecked())
|
|
||||||
{
|
{
|
||||||
if (mProfileDialog->exec() == QDialog::Accepted)
|
resetProgressBar();
|
||||||
{
|
|
||||||
const QString profile(mProfileDialog->lineEdit()->text());
|
QMessageBox msgBox;
|
||||||
const QStringList files(mGameSettings.getContentList());
|
msgBox.setWindowTitle(tr("Importer finished"));
|
||||||
mLauncherSettings.setCurrentContentListName(profile);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
mLauncherSettings.setContentList(profile, files);
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
|
msgBox.setText(tr("Failed to import settings from INI file."));
|
||||||
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// indicate progress finished
|
||||||
|
progressBar->setMaximum(1);
|
||||||
|
progressBar->setValue(1);
|
||||||
|
|
||||||
|
// Importer may have changed settings, so refresh
|
||||||
|
mMain->reloadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
mMain->reloadSettings();
|
|
||||||
importerButton->setEnabled(true);
|
importerButton->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::resetProgressBar()
|
||||||
|
{
|
||||||
|
// set progress bar to 0 %
|
||||||
|
progressBar->reset();
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::SettingsPage::updateOkButton(const QString &text)
|
void Launcher::SettingsPage::updateOkButton(const QString &text)
|
||||||
{
|
{
|
||||||
// We do this here because we need to access the profiles
|
// We do this here because we need to access the profiles
|
||||||
|
|
|
@ -30,6 +30,9 @@ namespace Launcher
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
bool loadSettings();
|
bool loadSettings();
|
||||||
|
|
||||||
|
/// set progress bar on page to 0%
|
||||||
|
void resetProgressBar();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void on_wizardButton_clicked();
|
void on_wizardButton_clicked();
|
||||||
|
@ -57,7 +60,6 @@ namespace Launcher
|
||||||
MainDialog *mMain;
|
MainDialog *mMain;
|
||||||
TextInputDialog *mProfileDialog;
|
TextInputDialog *mProfileDialog;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,16 @@ set(MWINIIMPORT_HEADER
|
||||||
|
|
||||||
source_group(launcher FILES ${MWINIIMPORT} ${MWINIIMPORT_HEADER})
|
source_group(launcher FILES ${MWINIIMPORT} ${MWINIIMPORT_HEADER})
|
||||||
|
|
||||||
add_executable(mwiniimport
|
add_executable(openmw-iniimporter
|
||||||
${MWINIIMPORT}
|
${MWINIIMPORT}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(mwiniimport
|
target_link_libraries(openmw-iniimporter
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
add_definitions (--coverage)
|
add_definitions (--coverage)
|
||||||
target_link_libraries(mwiniimport gcov)
|
target_link_libraries(openmw-iniimporter gcov)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/version.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
namespace bfs = boost::filesystem;
|
||||||
|
@ -660,7 +661,7 @@ std::string MwIniImporter::numberToString(int n) {
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const {
|
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::path& filename) const {
|
||||||
std::cout << "load ini file: " << filename << std::endl;
|
std::cout << "load ini file: " << filename << std::endl;
|
||||||
|
|
||||||
std::string section("");
|
std::string section("");
|
||||||
|
@ -719,7 +720,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) {
|
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::path& filename) {
|
||||||
std::cout << "load cfg file: " << filename << std::endl;
|
std::cout << "load cfg file: " << filename << std::endl;
|
||||||
|
|
||||||
MwIniImporter::multistrmap map;
|
MwIniImporter::multistrmap map;
|
||||||
|
@ -825,10 +826,14 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
|
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, const boost::filesystem::path& iniFilename) const {
|
||||||
std::vector<std::string> contentFiles;
|
std::vector<std::pair<std::time_t, std::string> > contentFiles;
|
||||||
std::string baseGameFile("Game Files:GameFile");
|
std::string baseGameFile("Game Files:GameFile");
|
||||||
std::string gameFile("");
|
std::string gameFile("");
|
||||||
|
std::time_t defaultTime = 0;
|
||||||
|
|
||||||
|
// assume the Game Files are all in a "Data Files" directory under the directory holding Morrowind.ini
|
||||||
|
const boost::filesystem::path gameFilesDir(iniFilename.parent_path() /= "Data Files");
|
||||||
|
|
||||||
multistrmap::const_iterator it = ini.begin();
|
multistrmap::const_iterator it = ini.begin();
|
||||||
for(int i=0; it != ini.end(); i++) {
|
for(int i=0; it != ini.end(); i++) {
|
||||||
|
@ -845,18 +850,20 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) co
|
||||||
Misc::StringUtils::toLower(filetype);
|
Misc::StringUtils::toLower(filetype);
|
||||||
|
|
||||||
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
|
if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) {
|
||||||
contentFiles.push_back(*entry);
|
boost::filesystem::path filepath(gameFilesDir);
|
||||||
|
filepath /= *entry;
|
||||||
|
contentFiles.push_back(std::make_pair(lastWriteTime(filepath, defaultTime), *entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gameFile = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.erase("content");
|
cfg.erase("content");
|
||||||
cfg.insert( std::make_pair("content", std::vector<std::string>() ) );
|
cfg.insert( std::make_pair("content", std::vector<std::string>() ) );
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) {
|
// this will sort files by time order first, then alphabetical (maybe), I suspect non ASCII filenames will be stuffed.
|
||||||
cfg["content"].push_back(*it);
|
sort(contentFiles.begin(), contentFiles.end());
|
||||||
|
for(std::vector<std::pair<std::time_t, std::string> >::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) {
|
||||||
|
cfg["content"].push_back(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,3 +880,27 @@ void MwIniImporter::setInputEncoding(const ToUTF8::FromType &encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime)
|
||||||
|
{
|
||||||
|
std::time_t writeTime(defaultTime);
|
||||||
|
if (boost::filesystem::exists(filename))
|
||||||
|
{
|
||||||
|
// FixMe: remove #if when Boost dependency for Linux builds updated
|
||||||
|
// This allows Linux to build until then
|
||||||
|
#if (BOOST_VERSION >= 104800)
|
||||||
|
// need to resolve any symlinks so that we get time of file, not symlink
|
||||||
|
boost::filesystem::path resolved = boost::filesystem::canonical(filename);
|
||||||
|
#else
|
||||||
|
boost::filesystem::path resolved = filename;
|
||||||
|
#endif
|
||||||
|
writeTime = boost::filesystem::last_write_time(resolved);
|
||||||
|
std::cout << "content file: " << resolved << " timestamp = (" << writeTime <<
|
||||||
|
") " << asctime(localtime(&writeTime)) << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "content file: " << filename << " not found" << std::endl;
|
||||||
|
}
|
||||||
|
return writeTime;
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/to_utf8/to_utf8.hpp>
|
||||||
|
|
||||||
|
@ -17,17 +18,22 @@ class MwIniImporter {
|
||||||
MwIniImporter();
|
MwIniImporter();
|
||||||
void setInputEncoding(const ToUTF8::FromType& encoding);
|
void setInputEncoding(const ToUTF8::FromType& encoding);
|
||||||
void setVerbose(bool verbose);
|
void setVerbose(bool verbose);
|
||||||
multistrmap loadIniFile(const std::string& filename) const;
|
multistrmap loadIniFile(const boost::filesystem::path& filename) const;
|
||||||
static multistrmap loadCfgFile(const std::string& filename);
|
static multistrmap loadCfgFile(const boost::filesystem::path& filename);
|
||||||
void merge(multistrmap &cfg, const multistrmap &ini) const;
|
void merge(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
|
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
|
void importGameFiles(multistrmap &cfg, const multistrmap &ini,
|
||||||
|
const boost::filesystem::path& iniFilename) const;
|
||||||
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
|
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
|
||||||
static void writeToFile(std::ostream &out, const multistrmap &cfg);
|
static void writeToFile(std::ostream &out, const multistrmap &cfg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
|
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
|
||||||
static std::string numberToString(int n);
|
static std::string numberToString(int n);
|
||||||
|
|
||||||
|
/// \return file's "last modified time", used in original MW to determine plug-in load order
|
||||||
|
static std::time_t lastWriteTime(const boost::filesystem::path& filename, std::time_t defaultTime);
|
||||||
|
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
strmap mMergeMap;
|
strmap mMergeMap;
|
||||||
std::vector<std::string> mMergeFallback;
|
std::vector<std::string> mMergeFallback;
|
||||||
|
|
|
@ -59,7 +59,7 @@ int wmain(int argc, wchar_t *wargv[]) {
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bpo::options_description desc("Syntax: mwiniimporter <options> inifile configfile\nAllowed options");
|
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
|
||||||
bpo::positional_options_description p_desc;
|
bpo::positional_options_description p_desc;
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce help message")
|
("help,h", "produce help message")
|
||||||
|
@ -93,8 +93,8 @@ int wmain(int argc, wchar_t *wargv[]) {
|
||||||
|
|
||||||
bpo::notify(vm);
|
bpo::notify(vm);
|
||||||
|
|
||||||
std::string iniFile = vm["ini"].as<std::string>();
|
boost::filesystem::path iniFile(vm["ini"].as<std::string>());
|
||||||
std::string cfgFile = vm["cfg"].as<std::string>();
|
boost::filesystem::path cfgFile(vm["cfg"].as<std::string>());
|
||||||
|
|
||||||
// if no output is given, write back to cfg file
|
// if no output is given, write back to cfg file
|
||||||
std::string outputFile(vm["output"].as<std::string>());
|
std::string outputFile(vm["output"].as<std::string>());
|
||||||
|
@ -123,7 +123,7 @@ int wmain(int argc, wchar_t *wargv[]) {
|
||||||
importer.mergeFallback(cfg, ini);
|
importer.mergeFallback(cfg, ini);
|
||||||
|
|
||||||
if(vm.count("game-files")) {
|
if(vm.count("game-files")) {
|
||||||
importer.importGameFiles(cfg, ini);
|
importer.importGameFiles(cfg, ini, iniFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!vm.count("no-archives")) {
|
if(!vm.count("no-archives")) {
|
||||||
|
|
|
@ -4,8 +4,6 @@ set (OPENCS_SRC main.cpp
|
||||||
|
|
||||||
opencs_units (. editor)
|
opencs_units (. editor)
|
||||||
|
|
||||||
set (CMAKE_BUILD_TYPE DEBUG)
|
|
||||||
|
|
||||||
opencs_units (model/doc
|
opencs_units (model/doc
|
||||||
document operation saving documentmanager loader runner
|
document operation saving documentmanager loader runner
|
||||||
)
|
)
|
||||||
|
@ -41,7 +39,7 @@ opencs_units (model/tools
|
||||||
|
|
||||||
opencs_units_noqt (model/tools
|
opencs_units_noqt (model/tools
|
||||||
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck
|
||||||
birthsigncheck spellcheck referenceablecheck scriptcheck bodypartcheck
|
birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,7 +144,7 @@ set (OPENCS_UI
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/filedialog.ui
|
${CMAKE_SOURCE_DIR}/files/ui/filedialog.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group (opencs FILES ${OPENCS_SRC} ${OPENCS_HDR})
|
source_group (openmw-cs FILES ${OPENCS_SRC} ${OPENCS_HDR})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(QT_USE_QTMAIN TRUE)
|
set(QT_USE_QTMAIN TRUE)
|
||||||
|
@ -169,12 +167,12 @@ qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/opencs.icns)
|
set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/openmw-cs.icns)
|
||||||
else()
|
else()
|
||||||
set (OPENCS_MAC_ICON "")
|
set (OPENCS_MAC_ICON "")
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
add_executable(opencs
|
add_executable(openmw-cs
|
||||||
MACOSX_BUNDLE
|
MACOSX_BUNDLE
|
||||||
${OENGINE_BULLET}
|
${OENGINE_BULLET}
|
||||||
${OPENCS_SRC}
|
${OPENCS_SRC}
|
||||||
|
@ -185,10 +183,10 @@ add_executable(opencs
|
||||||
)
|
)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set_target_properties(opencs PROPERTIES
|
set_target_properties(openmw-cs PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}"
|
||||||
OUTPUT_NAME "OpenCS"
|
OUTPUT_NAME "OpenMW-CS"
|
||||||
MACOSX_BUNDLE_ICON_FILE "opencs.icns"
|
MACOSX_BUNDLE_ICON_FILE "openmw-cs.icns"
|
||||||
MACOSX_BUNDLE_BUNDLE_NAME "OpenCS"
|
MACOSX_BUNDLE_BUNDLE_NAME "OpenCS"
|
||||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.openmw.opencs"
|
MACOSX_BUNDLE_GUI_IDENTIFIER "org.openmw.opencs"
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${OPENMW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${OPENMW_VERSION}
|
||||||
|
@ -199,7 +197,7 @@ if(APPLE)
|
||||||
MACOSX_PACKAGE_LOCATION Resources)
|
MACOSX_PACKAGE_LOCATION Resources)
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
target_link_libraries(opencs
|
target_link_libraries(openmw-cs
|
||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${OGRE_Overlay_LIBRARIES}
|
${OGRE_Overlay_LIBRARIES}
|
||||||
${OGRE_STATIC_PLUGINS}
|
${OGRE_STATIC_PLUGINS}
|
||||||
|
@ -211,5 +209,5 @@ target_link_libraries(opencs
|
||||||
)
|
)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
INSTALL(TARGETS opencs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
|
INSTALL(TARGETS openmw-cs BUNDLE DESTINATION OpenMW COMPONENT BUNDLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -96,7 +96,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||||
std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig()
|
std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig()
|
||||||
{
|
{
|
||||||
boost::program_options::variables_map variables;
|
boost::program_options::variables_map variables;
|
||||||
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
boost::program_options::options_description desc("Syntax: openmw-cs <options>\nAllowed options");
|
||||||
|
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken()->composing())
|
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken()->composing())
|
||||||
|
@ -249,7 +249,7 @@ bool CS::Editor::makeIPCServer()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mPid = boost::filesystem::temp_directory_path();
|
mPid = boost::filesystem::temp_directory_path();
|
||||||
mPid /= "opencs.pid";
|
mPid /= "openmw-cs.pid";
|
||||||
bool pidExists = boost::filesystem::exists(mPid);
|
bool pidExists = boost::filesystem::exists(mPid);
|
||||||
|
|
||||||
mPidFile.open(mPid);
|
mPidFile.open(mPid);
|
||||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char *argv[])
|
||||||
application.setLibraryPaths(libraryPaths);
|
application.setLibraryPaths(libraryPaths);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
application.setWindowIcon (QIcon (":./opencs.png"));
|
application.setWindowIcon (QIcon (":./openmw-cs.png"));
|
||||||
|
|
||||||
CS::Editor editor (ogreInit);
|
CS::Editor editor (ogreInit);
|
||||||
|
|
||||||
|
|
110
apps/opencs/model/tools/referencecheck.cpp
Normal file
110
apps/opencs/model/tools/referencecheck.cpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#include "referencecheck.hpp"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
CSMTools::ReferenceCheckStage::ReferenceCheckStage(
|
||||||
|
const CSMWorld::RefCollection& references,
|
||||||
|
const CSMWorld::RefIdCollection& referencables,
|
||||||
|
const CSMWorld::IdCollection<CSMWorld::Cell>& cells,
|
||||||
|
const CSMWorld::IdCollection<ESM::Faction>& factions)
|
||||||
|
:
|
||||||
|
mReferences(references),
|
||||||
|
mReferencables(referencables),
|
||||||
|
mDataSet(referencables.getDataSet()),
|
||||||
|
mCells(cells),
|
||||||
|
mFactions(factions)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::CellRef>& record = mReferences.getRecord(stage);
|
||||||
|
|
||||||
|
if (record.isDeleted())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const CSMWorld::CellRef& cellRef = record.get();
|
||||||
|
const CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Reference, cellRef.mId);
|
||||||
|
|
||||||
|
// Check for empty reference id
|
||||||
|
if (cellRef.mRefID.empty()) {
|
||||||
|
messages.push_back(std::make_pair(id, " is an empty reference"));
|
||||||
|
} else {
|
||||||
|
// Check for non existing referenced object
|
||||||
|
if (mReferencables.searchId(cellRef.mRefID) == -1) {
|
||||||
|
messages.push_back(std::make_pair(id, " is referencing non existing object " + cellRef.mRefID));
|
||||||
|
} else {
|
||||||
|
// Check if reference charge is valid for it's proper referenced type
|
||||||
|
CSMWorld::RefIdData::LocalIndex localIndex = mDataSet.searchId(cellRef.mRefID);
|
||||||
|
bool isLight = localIndex.second == CSMWorld::UniversalId::Type_Light;
|
||||||
|
if ((isLight && cellRef.mChargeFloat < -1) || (!isLight && cellRef.mChargeInt < -1)) {
|
||||||
|
std::string str = " has invalid charge ";
|
||||||
|
if (localIndex.second == CSMWorld::UniversalId::Type_Light)
|
||||||
|
str += boost::lexical_cast<std::string>(cellRef.mChargeFloat);
|
||||||
|
else
|
||||||
|
str += boost::lexical_cast<std::string>(cellRef.mChargeInt);
|
||||||
|
messages.push_back(std::make_pair(id, id.getId() + str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if referenced object is in valid cell
|
||||||
|
if (mCells.searchId(cellRef.mCell) == -1)
|
||||||
|
messages.push_back(std::make_pair(id, " is referencing object from non existing cell " + cellRef.mCell));
|
||||||
|
|
||||||
|
// If object have owner, check if that owner reference is valid
|
||||||
|
if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1)
|
||||||
|
messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner));
|
||||||
|
|
||||||
|
// If object have creature soul trapped, check if that creature reference is valid
|
||||||
|
if (!cellRef.mSoul.empty())
|
||||||
|
if (mReferencables.searchId(cellRef.mSoul) == -1)
|
||||||
|
messages.push_back(std::make_pair(id, " has non existing trapped soul " + cellRef.mSoul));
|
||||||
|
|
||||||
|
bool hasFaction = !cellRef.mFaction.empty();
|
||||||
|
|
||||||
|
// If object have faction, check if that faction reference is valid
|
||||||
|
if (hasFaction)
|
||||||
|
if (mFactions.searchId(cellRef.mFaction) == -1)
|
||||||
|
messages.push_back(std::make_pair(id, " has non existing faction " + cellRef.mFaction));
|
||||||
|
|
||||||
|
// Check item's faction rank
|
||||||
|
if (hasFaction && cellRef.mFactionRank < -1)
|
||||||
|
messages.push_back(std::make_pair(id, " has faction set but has invalid faction rank " + cellRef.mFactionRank));
|
||||||
|
else if (!hasFaction && cellRef.mFactionRank != -2)
|
||||||
|
messages.push_back(std::make_pair(id, " has invalid faction rank " + cellRef.mFactionRank));
|
||||||
|
|
||||||
|
// If door have destination cell, check if that reference is valid
|
||||||
|
if (!cellRef.mDestCell.empty())
|
||||||
|
if (mCells.searchId(cellRef.mDestCell) == -1)
|
||||||
|
messages.push_back(std::make_pair(id, " has non existing destination cell " + cellRef.mDestCell));
|
||||||
|
|
||||||
|
// Check if scale isn't negative
|
||||||
|
if (cellRef.mScale < 0)
|
||||||
|
{
|
||||||
|
std::string str = " has negative scale ";
|
||||||
|
str += boost::lexical_cast<std::string>(cellRef.mScale);
|
||||||
|
messages.push_back(std::make_pair(id, id.getId() + str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if enchantement points aren't negative or are at full (-1)
|
||||||
|
if (cellRef.mEnchantmentCharge < 0 && cellRef.mEnchantmentCharge != -1)
|
||||||
|
{
|
||||||
|
std::string str = " has negative enchantment points ";
|
||||||
|
str += boost::lexical_cast<std::string>(cellRef.mEnchantmentCharge);
|
||||||
|
messages.push_back(std::make_pair(id, id.getId() + str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if gold value isn't negative
|
||||||
|
if (cellRef.mGoldValue < 0)
|
||||||
|
{
|
||||||
|
std::string str = " has negative gold value ";
|
||||||
|
str += cellRef.mGoldValue;
|
||||||
|
messages.push_back(std::make_pair(id, id.getId() + str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMTools::ReferenceCheckStage::setup()
|
||||||
|
{
|
||||||
|
return mReferences.getSize();
|
||||||
|
}
|
29
apps/opencs/model/tools/referencecheck.hpp
Normal file
29
apps/opencs/model/tools/referencecheck.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef CSM_TOOLS_REFERENCECHECK_H
|
||||||
|
#define CSM_TOOLS_REFERENCECHECK_H
|
||||||
|
|
||||||
|
#include "../doc/state.hpp"
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class ReferenceCheckStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReferenceCheckStage (const CSMWorld::RefCollection& references,
|
||||||
|
const CSMWorld::RefIdCollection& referencables,
|
||||||
|
const CSMWorld::IdCollection<CSMWorld::Cell>& cells,
|
||||||
|
const CSMWorld::IdCollection<ESM::Faction>& factions);
|
||||||
|
|
||||||
|
virtual void perform(int stage, CSMDoc::Messages& messages);
|
||||||
|
virtual int setup();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CSMWorld::RefCollection& mReferences;
|
||||||
|
const CSMWorld::RefIdCollection& mReferencables;
|
||||||
|
const CSMWorld::RefIdData& mDataSet;
|
||||||
|
const CSMWorld::IdCollection<CSMWorld::Cell>& mCells;
|
||||||
|
const CSMWorld::IdCollection<ESM::Faction>& mFactions;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CSM_TOOLS_REFERENCECHECK_H
|
|
@ -23,6 +23,7 @@
|
||||||
#include "referenceablecheck.hpp"
|
#include "referenceablecheck.hpp"
|
||||||
#include "scriptcheck.hpp"
|
#include "scriptcheck.hpp"
|
||||||
#include "bodypartcheck.hpp"
|
#include "bodypartcheck.hpp"
|
||||||
|
#include "referencecheck.hpp"
|
||||||
|
|
||||||
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
CSMDoc::Operation *CSMTools::Tools::get (int type)
|
||||||
{
|
{
|
||||||
|
@ -57,9 +58,6 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||||
mandatoryIds.push_back ("GameHour");
|
mandatoryIds.push_back ("GameHour");
|
||||||
mandatoryIds.push_back ("Month");
|
mandatoryIds.push_back ("Month");
|
||||||
mandatoryIds.push_back ("PCRace");
|
mandatoryIds.push_back ("PCRace");
|
||||||
mandatoryIds.push_back ("PCVampire");
|
|
||||||
mandatoryIds.push_back ("PCWerewolf");
|
|
||||||
mandatoryIds.push_back ("PCYear");
|
|
||||||
|
|
||||||
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
||||||
|
@ -82,6 +80,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||||
|
|
||||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||||
|
|
||||||
|
mVerifier->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
|
||||||
|
|
||||||
mVerifier->appendStage (new ScriptCheckStage (mDocument));
|
mVerifier->appendStage (new ScriptCheckStage (mDocument));
|
||||||
|
|
||||||
mVerifier->appendStage(
|
mVerifier->appendStage(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
#include "cell.hpp"
|
||||||
|
#include "idcollection.hpp"
|
||||||
#include "pathgrid.hpp"
|
#include "pathgrid.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
|
|
||||||
#include <components/esm/loadpgrd.hpp>
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
|
||||||
#include "idcollection.hpp"
|
|
||||||
#include "cell.hpp"
|
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
|
struct Cell;
|
||||||
|
template<typename T, typename AT>
|
||||||
|
class IdCollection;
|
||||||
|
|
||||||
/// \brief Wrapper for Pathgrid record
|
/// \brief Wrapper for Pathgrid record
|
||||||
///
|
///
|
||||||
/// \attention The mData.mX and mData.mY fields of the ESM::Pathgrid struct are not used.
|
/// \attention The mData.mX and mData.mY fields of the ESM::Pathgrid struct are not used.
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
#ifndef CSM_WOLRD_SUBCOLLECTION_H
|
#ifndef CSM_WOLRD_SUBCOLLECTION_H
|
||||||
#define CSM_WOLRD_SUBCOLLECTION_H
|
#define CSM_WOLRD_SUBCOLLECTION_H
|
||||||
|
|
||||||
#include "idcollection.hpp"
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
|
struct Cell;
|
||||||
|
template<typename T, typename AT>
|
||||||
|
class IdCollection;
|
||||||
|
|
||||||
/// \brief Single type collection of top level records that are associated with cells
|
/// \brief Single type collection of top level records that are associated with cells
|
||||||
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
|
||||||
class SubCellCollection : public IdCollection<ESXRecordT, IdAccessorT>
|
class SubCellCollection : public IdCollection<ESXRecordT, IdAccessorT>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
@ -72,8 +73,11 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
||||||
{
|
{
|
||||||
boost::filesystem::path path (name.toUtf8().data());
|
boost::filesystem::path path (name.toUtf8().data());
|
||||||
|
|
||||||
bool isLegacyPath = (path.extension() == ".esm" ||
|
std::string extension = path.extension().string();
|
||||||
path.extension() == ".esp");
|
boost::algorithm::to_lower(extension);
|
||||||
|
|
||||||
|
bool isLegacyPath = (extension == ".esm" ||
|
||||||
|
extension == ".esp");
|
||||||
|
|
||||||
bool isFilePathChanged = (path.parent_path().string() != mLocalData.string());
|
bool isFilePathChanged = (path.parent_path().string() != mLocalData.string());
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ QWidget *CSVDoc::StartupDialogue::createTools()
|
||||||
|
|
||||||
CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2)
|
CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2)
|
||||||
{
|
{
|
||||||
setWindowTitle ("Open CS");
|
setWindowTitle ("OpenMW-CS");
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout (this);
|
QVBoxLayout *layout = new QVBoxLayout (this);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
#ifndef Q_MOC_RUN
|
||||||
#include <components/terrain/terraingrid.hpp>
|
#include <components/terrain/terraingrid.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#ifndef Q_MOC_RUN
|
||||||
#include <components/nifogre/ogrenifloader.hpp>
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ add_openmw_dir (mwgui
|
||||||
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||||
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
||||||
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
|
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
|
||||||
draganddrop
|
draganddrop timeadvancer jailscreen
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
|
|
@ -108,12 +108,15 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
MWBase::StateManager::State_Running)
|
MWBase::StateManager::State_Running)
|
||||||
{
|
{
|
||||||
if (!paused)
|
if (!paused)
|
||||||
|
{
|
||||||
|
if (MWBase::Environment::get().getWorld()->getScriptsEnabled())
|
||||||
{
|
{
|
||||||
// local scripts
|
// local scripts
|
||||||
executeLocalScripts();
|
executeLocalScripts();
|
||||||
|
|
||||||
// global scripts
|
// global scripts
|
||||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
|
||||||
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
||||||
}
|
}
|
||||||
|
@ -170,7 +173,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
|
|
||||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
: mOgre (0)
|
: mOgre (0)
|
||||||
, mFpsLevel(0)
|
|
||||||
, mVerboseScripts (false)
|
, mVerboseScripts (false)
|
||||||
, mSkipMenu (false)
|
, mSkipMenu (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
|
@ -292,16 +294,10 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed.");
|
||||||
|
|
||||||
// load user settings if they exist, otherwise just load the default settings as user settings
|
// load user settings if they exist
|
||||||
const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg";
|
const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg";
|
||||||
if (boost::filesystem::exists(settingspath))
|
if (boost::filesystem::exists(settingspath))
|
||||||
settings.loadUser(settingspath);
|
settings.loadUser(settingspath);
|
||||||
else if (boost::filesystem::exists(localdefault))
|
|
||||||
settings.loadUser(localdefault);
|
|
||||||
else if (boost::filesystem::exists(globaldefault))
|
|
||||||
settings.loadUser(globaldefault);
|
|
||||||
|
|
||||||
mFpsLevel = settings.getInt("fps", "HUD");
|
|
||||||
|
|
||||||
// load nif overrides
|
// load nif overrides
|
||||||
NifOverrides::Overrides nifOverrides;
|
NifOverrides::Overrides nifOverrides;
|
||||||
|
@ -349,6 +345,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
addResourcesDirectory(mResDir / "mygui");
|
addResourcesDirectory(mResDir / "mygui");
|
||||||
addResourcesDirectory(mResDir / "water");
|
addResourcesDirectory(mResDir / "water");
|
||||||
addResourcesDirectory(mResDir / "shadows");
|
addResourcesDirectory(mResDir / "shadows");
|
||||||
|
addResourcesDirectory(mResDir / "materials");
|
||||||
|
|
||||||
OEngine::Render::WindowSettings windowSettings;
|
OEngine::Render::WindowSettings windowSettings;
|
||||||
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
||||||
|
@ -397,7 +394,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mEnvironment.setInputManager (input);
|
mEnvironment.setInputManager (input);
|
||||||
|
|
||||||
MWGui::WindowManager* window = new MWGui::WindowManager(
|
MWGui::WindowManager* window = new MWGui::WindowManager(
|
||||||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
mExtensions, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
||||||
mEnvironment.setWindowManager (window);
|
mEnvironment.setWindowManager (window);
|
||||||
|
|
||||||
|
@ -598,11 +595,6 @@ void OMW::Engine::setSoundUsage(bool soundUsage)
|
||||||
mUseSound = soundUsage;
|
mUseSound = soundUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::showFPS(int level)
|
|
||||||
{
|
|
||||||
mFpsLevel = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
|
|
|
@ -71,7 +71,6 @@ namespace OMW
|
||||||
OEngine::Render::OgreRenderer *mOgre;
|
OEngine::Render::OgreRenderer *mOgre;
|
||||||
std::string mCellName;
|
std::string mCellName;
|
||||||
std::vector<std::string> mContentFiles;
|
std::vector<std::string> mContentFiles;
|
||||||
int mFpsLevel;
|
|
||||||
bool mVerboseScripts;
|
bool mVerboseScripts;
|
||||||
bool mSkipMenu;
|
bool mSkipMenu;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
|
@ -151,9 +150,6 @@ namespace OMW
|
||||||
*/
|
*/
|
||||||
void addContentFile(const std::string& file);
|
void addContentFile(const std::string& file);
|
||||||
|
|
||||||
/// Enable fps counter
|
|
||||||
void showFPS(int level);
|
|
||||||
|
|
||||||
/// Enable or disable verbose script output
|
/// Enable or disable verbose script output
|
||||||
void setScriptsVerbosity(bool scriptsVerbosity);
|
void setScriptsVerbosity(bool scriptsVerbosity);
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
->default_value(true), "enable script blacklisting")
|
->default_value(true), "enable script blacklisting")
|
||||||
|
|
||||||
("load-savegame", bpo::value<std::string>()->default_value(""),
|
("load-savegame", bpo::value<std::string>()->default_value(""),
|
||||||
"load a save game file on game startup")
|
"load a save game file on game startup (specify an absolute filename or a filename relative to the current working directory)")
|
||||||
|
|
||||||
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "skip main menu on game startup")
|
->default_value(false), "skip main menu on game startup")
|
||||||
|
@ -190,29 +190,23 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
bpo::store(valid_opts, variables);
|
bpo::store(valid_opts, variables);
|
||||||
bpo::notify(variables);
|
bpo::notify(variables);
|
||||||
|
|
||||||
bool run = true;
|
|
||||||
|
|
||||||
if (variables.count ("help"))
|
if (variables.count ("help"))
|
||||||
{
|
{
|
||||||
std::cout << desc << std::endl;
|
std::cout << desc << std::endl;
|
||||||
run = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variables.count ("version"))
|
std::cout << "OpenMW version " << OPENMW_VERSION;
|
||||||
{
|
|
||||||
std::cout << "OpenMW version " << OPENMW_VERSION << std::endl;
|
|
||||||
|
|
||||||
std::string rev = OPENMW_VERSION_COMMITHASH;
|
std::string rev = OPENMW_VERSION_COMMITHASH;
|
||||||
std::string tag = OPENMW_VERSION_TAGHASH;
|
std::string tag = OPENMW_VERSION_TAGHASH;
|
||||||
if (!rev.empty() && !tag.empty())
|
if (!rev.empty() && !tag.empty())
|
||||||
{
|
{
|
||||||
rev = rev.substr(0, 10);
|
rev = rev.substr(0, 10);
|
||||||
std::cout << "Revision " << rev << std::endl;
|
std::cout << " (revision " << rev << ")";
|
||||||
}
|
|
||||||
run = false;
|
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (!run)
|
if (variables.count ("version"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cfgMgr.readConfiguration(variables, desc);
|
cfgMgr.readConfiguration(variables, desc);
|
||||||
|
@ -396,12 +390,12 @@ int main(int argc, char**argv)
|
||||||
catch (std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
if (isatty(fileno(stdin)))
|
if (!isatty(fileno(stdin)))
|
||||||
std::cerr << "\nERROR: " << e.what() << std::endl;
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
||||||
|
|
||||||
|
std::cerr << "\nERROR: " << e.what() << std::endl;
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef GAME_BASE_INVIRONMENT_H
|
#ifndef GAME_BASE_ENVIRONMENT_H
|
||||||
#define GAME_BASE_INVIRONMENT_H
|
#define GAME_BASE_ENVIRONMENT_H
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define GAME_MWBASE_INPUTMANAGER_H
|
#define GAME_MWBASE_INPUTMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
#include <components/settings/settings.hpp>
|
#include <vector>
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void changeInputMode(bool guiMode) = 0;
|
virtual void changeInputMode(bool guiMode) = 0;
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
|
||||||
|
|
||||||
virtual void setDragDrop(bool dragDrop) = 0;
|
virtual void setDragDrop(bool dragDrop) = 0;
|
||||||
|
|
||||||
|
|
|
@ -129,16 +129,15 @@ namespace MWBase
|
||||||
/// @return false if the attack was considered a "friendly hit" and forgiven
|
/// @return false if the attack was considered a "friendly hit" and forgiven
|
||||||
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
|
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
|
||||||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0;
|
/// @param container The container the item is in; may be empty for an item in the world
|
||||||
|
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||||
|
int count) = 0;
|
||||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
||||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||||
/// @return was it illegal, and someone saw you doing it?
|
/// @return was it illegal, and someone saw you doing it?
|
||||||
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0;
|
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0;
|
||||||
|
|
||||||
/// @return is \a ptr allowed to take/use \a item or is it a crime?
|
|
||||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim) = 0;
|
|
||||||
|
|
||||||
enum PersuasionType
|
enum PersuasionType
|
||||||
{
|
{
|
||||||
PT_Admire,
|
PT_Admire,
|
||||||
|
@ -203,6 +202,15 @@ namespace MWBase
|
||||||
virtual void keepPlayerAlive() = 0;
|
virtual void keepPlayerAlive() = 0;
|
||||||
|
|
||||||
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
|
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
|
||||||
|
virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0;
|
||||||
|
|
||||||
|
/// List the owners that the player has stolen this item from (the owner can be an NPC or a faction).
|
||||||
|
/// <Owner, item count>
|
||||||
|
virtual std::vector<std::pair<std::string, int> > getStolenItemOwners(const std::string& itemid) = 0;
|
||||||
|
|
||||||
|
/// Has the player stolen this item from the given owner?
|
||||||
|
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
#define GAME_MWBASE_SOUNDMANAGER_H
|
#define GAME_MWBASE_SOUNDMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <set>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
|
@ -74,7 +72,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual ~SoundManager() {}
|
virtual ~SoundManager() {}
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& settings) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& settings) = 0;
|
||||||
|
|
||||||
virtual void stopMusic() = 0;
|
virtual void stopMusic() = 0;
|
||||||
///< Stops music if it's playing
|
///< Stops music if it's playing
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
#ifndef GAME_MWBASE_WINDOWMANAGER_H
|
#ifndef GAME_MWBASE_WINDOWMANAGER_H
|
||||||
#define GAME_MWBASE_WINDOWMANAGER_H
|
#define GAME_MWBASE_WINDOWMANAGER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
#include <components/translation/translation.hpp>
|
|
||||||
|
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
|
||||||
|
|
||||||
#include "../mwmechanics/stat.hpp"
|
|
||||||
|
|
||||||
#include "../mwgui/mode.hpp"
|
#include "../mwgui/mode.hpp"
|
||||||
|
|
||||||
|
namespace Loading
|
||||||
|
{
|
||||||
|
class Listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Translation
|
||||||
|
{
|
||||||
|
class Storage;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MyGUI
|
namespace MyGUI
|
||||||
{
|
{
|
||||||
class Gui;
|
class Gui;
|
||||||
|
@ -35,6 +39,15 @@ namespace ESM
|
||||||
struct Class;
|
struct Class;
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
class ESMWriter;
|
class ESMWriter;
|
||||||
|
struct CellId;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
class AttributeValue;
|
||||||
|
template<typename T>
|
||||||
|
class DynamicStat;
|
||||||
|
class SkillValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
|
@ -58,6 +71,7 @@ namespace MWGui
|
||||||
class ContainerWindow;
|
class ContainerWindow;
|
||||||
class DialogueWindow;
|
class DialogueWindow;
|
||||||
class WindowModal;
|
class WindowModal;
|
||||||
|
class JailScreen;
|
||||||
|
|
||||||
enum ShowInDialogueMode {
|
enum ShowInDialogueMode {
|
||||||
ShowInDialogueMode_IfPossible,
|
ShowInDialogueMode_IfPossible,
|
||||||
|
@ -109,6 +123,8 @@ namespace MWBase
|
||||||
virtual void removeGuiMode (MWGui::GuiMode mode) = 0;
|
virtual void removeGuiMode (MWGui::GuiMode mode) = 0;
|
||||||
///< can be anywhere in the stack
|
///< can be anywhere in the stack
|
||||||
|
|
||||||
|
virtual void goToJail(int days) = 0;
|
||||||
|
|
||||||
virtual void updatePlayer() = 0;
|
virtual void updatePlayer() = 0;
|
||||||
|
|
||||||
virtual MWGui::GuiMode getMode() const = 0;
|
virtual MWGui::GuiMode getMode() const = 0;
|
||||||
|
@ -266,7 +282,7 @@ namespace MWBase
|
||||||
*/
|
*/
|
||||||
virtual std::string getGameSettingString(const std::string &id, const std::string &default_) = 0;
|
virtual std::string getGameSettingString(const std::string &id, const std::string &default_) = 0;
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& changed) = 0;
|
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed) = 0;
|
||||||
|
|
||||||
virtual void windowResized(int x, int y) = 0;
|
virtual void windowResized(int x, int y) = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,24 +3,23 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/esm/cellid.hpp>
|
||||||
|
|
||||||
#include "../mwworld/globals.hpp"
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Vector2;
|
class Vector2;
|
||||||
class Vector3;
|
class Vector3;
|
||||||
|
class Quaternion;
|
||||||
|
class Image;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OEngine
|
namespace Loading
|
||||||
{
|
{
|
||||||
namespace Physic
|
class Listener;
|
||||||
{
|
|
||||||
class PhysicEngine;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
|
@ -33,7 +32,6 @@ namespace ESM
|
||||||
struct Potion;
|
struct Potion;
|
||||||
struct Spell;
|
struct Spell;
|
||||||
struct NPC;
|
struct NPC;
|
||||||
struct CellId;
|
|
||||||
struct Armor;
|
struct Armor;
|
||||||
struct Weapon;
|
struct Weapon;
|
||||||
struct Clothing;
|
struct Clothing;
|
||||||
|
@ -92,6 +90,7 @@ namespace MWBase
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
float x, y; // world position
|
float x, y; // world position
|
||||||
|
ESM::CellId dest;
|
||||||
};
|
};
|
||||||
|
|
||||||
World() {}
|
World() {}
|
||||||
|
@ -269,6 +268,8 @@ namespace MWBase
|
||||||
virtual MWWorld::Ptr getFacedObject() = 0;
|
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||||
|
|
||||||
|
virtual float getMaxActivationDistance() = 0;
|
||||||
|
|
||||||
/// Returns a pointer to the object the provided object would hit (if within the
|
/// Returns a pointer to the object the provided object would hit (if within the
|
||||||
/// specified distance), and the point where the hit occurs. This will attempt to
|
/// specified distance), and the point where the hit occurs. This will attempt to
|
||||||
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
|
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
|
||||||
|
@ -388,7 +389,7 @@ namespace MWBase
|
||||||
virtual bool canPlaceObject (float cursorX, float cursorY) = 0;
|
virtual bool canPlaceObject (float cursorX, float cursorY) = 0;
|
||||||
///< @return true if it is possible to place on object at specified cursor location
|
///< @return true if it is possible to place on object at specified cursor location
|
||||||
|
|
||||||
virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
|
virtual void processChangedSettings (const std::set< std::pair<std::string, std::string> >& settings) = 0;
|
||||||
|
|
||||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
||||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
||||||
|
@ -453,6 +454,7 @@ namespace MWBase
|
||||||
|
|
||||||
/// \todo Probably shouldn't be here
|
/// \todo Probably shouldn't be here
|
||||||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
||||||
|
virtual void reattachPlayerCamera() = 0;
|
||||||
|
|
||||||
/// \todo this does not belong here
|
/// \todo this does not belong here
|
||||||
virtual void frameStarted (float dt, bool paused) = 0;
|
virtual void frameStarted (float dt, bool paused) = 0;
|
||||||
|
@ -489,6 +491,9 @@ namespace MWBase
|
||||||
|
|
||||||
virtual bool toggleGodMode() = 0;
|
virtual bool toggleGodMode() = 0;
|
||||||
|
|
||||||
|
virtual bool toggleScripts() = 0;
|
||||||
|
virtual bool getScriptsEnabled() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief startSpellCast attempt to start casting a spell. Might fail immediately if conditions are not met.
|
* @brief startSpellCast attempt to start casting a spell. Might fail immediately if conditions are not met.
|
||||||
* @param actor
|
* @param actor
|
||||||
|
@ -548,7 +553,7 @@ namespace MWBase
|
||||||
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const Ogre::Vector3& worldPos) = 0;
|
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const Ogre::Vector3& worldPos) = 0;
|
||||||
|
|
||||||
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
|
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, int rangeType, const std::string& id, const std::string& sourceName) = 0;
|
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0;
|
||||||
|
|
||||||
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,10 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
|
||||||
|
// setting ownership not needed, since taking items from a container inherits the
|
||||||
|
// container's owner automatically
|
||||||
data->mContainerStore.fill(
|
data->mContainerStore.fill(
|
||||||
ref->mBase->mInventory, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank(), MWBase::Environment::get().getWorld()->getStore());
|
ref->mBase->mInventory, "");
|
||||||
|
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData (data.release());
|
ptr.getRefData().setCustomData (data.release());
|
||||||
|
@ -82,7 +84,10 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
|
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), ptr.getCellRef().getFactionRank());
|
|
||||||
|
// setting ownership not needed, since taking items from a container inherits the
|
||||||
|
// container's owner automatically
|
||||||
|
store.restock(list, ptr, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
|
|
@ -139,8 +139,7 @@ namespace MWClass
|
||||||
// store
|
// store
|
||||||
ptr.getRefData().setCustomData(data.release());
|
ptr.getRefData().setCustomData(data.release());
|
||||||
|
|
||||||
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "", -1,
|
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr));
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
|
||||||
|
|
||||||
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
||||||
getInventoryStore(ptr).autoEquip(ptr);
|
getInventoryStore(ptr).autoEquip(ptr);
|
||||||
|
@ -228,18 +227,7 @@ namespace MWClass
|
||||||
weapon = *weaponslot;
|
weapon = *weaponslot;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce fatigue
|
MWMechanics::applyFatigueLoss(ptr, weapon);
|
||||||
// somewhat of a guess, but using the weapon weight makes sense
|
|
||||||
const float fFatigueAttackBase = gmst.find("fFatigueAttackBase")->getFloat();
|
|
||||||
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
|
||||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
|
||||||
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
|
||||||
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
|
||||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
|
||||||
if (!weapon.isEmpty())
|
|
||||||
fatigueLoss += weapon.getClass().getWeight(weapon) * stats.getAttackStrength() * fWeaponFatigueMult;
|
|
||||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
|
||||||
stats.setFatigue(fatigue);
|
|
||||||
|
|
||||||
// TODO: where is the distance defined?
|
// TODO: where is the distance defined?
|
||||||
float dist = 200.f;
|
float dist = 200.f;
|
||||||
|
@ -897,7 +885,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
|
store.restock(list, ptr, ptr.getCellRef().getRefId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
|
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace MWClass
|
||||||
registerClass (typeid (ESM::CreatureLevList).name(), instance);
|
registerClass (typeid (ESM::CreatureLevList).name(), instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureLevList::insertObjectRendering(const MWWorld::Ptr &ptr, MWRender::RenderingInterface &renderingInterface) const
|
void CreatureLevList::insertObjectRendering(const MWWorld::Ptr &ptr, const std::string& model, MWRender::RenderingInterface &renderingInterface) const
|
||||||
{
|
{
|
||||||
ensureCustomData(ptr);
|
ensureCustomData(ptr);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace MWClass
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||||
|
|
|
@ -93,9 +93,6 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::Door> *ref =
|
MWWorld::LiveCellRef<ESM::Door> *ref =
|
||||||
ptr.get<ESM::Door>();
|
ptr.get<ESM::Door>();
|
||||||
|
|
||||||
if (ptr.getCellRef().getTeleport() && !ptr.getCellRef().getDestCell().empty()) // TODO doors that lead to exteriors
|
|
||||||
return ptr.getCellRef().getDestCell();
|
|
||||||
|
|
||||||
return ref->mBase->mName;
|
return ref->mBase->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
|
|
|
@ -296,25 +296,6 @@ namespace MWClass
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
|
||||||
// NPC stats
|
|
||||||
if (!ref->mBase->mFaction.empty())
|
|
||||||
{
|
|
||||||
std::string faction = ref->mBase->mFaction;
|
|
||||||
if (const ESM::Faction* fact = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().search(faction))
|
|
||||||
{
|
|
||||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
|
||||||
{
|
|
||||||
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt52.mRank);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt12.mRank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cerr << "Warning: ignoring nonexistent faction '" << faction << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// creature stats
|
// creature stats
|
||||||
int gold=0;
|
int gold=0;
|
||||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||||
|
@ -371,13 +352,13 @@ namespace MWClass
|
||||||
std::cerr << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
|
std::cerr << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->mNpcStats.getFactionRanks().size())
|
if (!ref->mBase->mFaction.empty())
|
||||||
{
|
{
|
||||||
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iAutoRepFacMod")->getInt();
|
.find("iAutoRepFacMod")->getInt();
|
||||||
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iAutoRepLevMod")->getInt();
|
.find("iAutoRepLevMod")->getInt();
|
||||||
int rank = data->mNpcStats.getFactionRanks().begin()->second;
|
int rank = ref->mBase->getFactionRank();
|
||||||
|
|
||||||
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
|
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
|
||||||
}
|
}
|
||||||
|
@ -403,8 +384,8 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
// inventory
|
// inventory
|
||||||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", -1,
|
// setting ownership is used to make the NPC auto-equip his initial equipment only, and not bartered items
|
||||||
MWBase::Environment::get().getWorld()->getStore());
|
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr));
|
||||||
|
|
||||||
data->mNpcStats.setGoldPool(gold);
|
data->mNpcStats.setGoldPool(gold);
|
||||||
|
|
||||||
|
@ -505,18 +486,7 @@ namespace MWClass
|
||||||
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||||
weapon = MWWorld::Ptr();
|
weapon = MWWorld::Ptr();
|
||||||
|
|
||||||
// Reduce fatigue
|
MWMechanics::applyFatigueLoss(ptr, weapon);
|
||||||
// somewhat of a guess, but using the weapon weight makes sense
|
|
||||||
const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat();
|
|
||||||
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
|
||||||
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
|
||||||
MWMechanics::DynamicStat<float> fatigue = getCreatureStats(ptr).getFatigue();
|
|
||||||
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
|
||||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
|
||||||
if (!weapon.isEmpty())
|
|
||||||
fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult;
|
|
||||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
|
||||||
getCreatureStats(ptr).setFatigue(fatigue);
|
|
||||||
|
|
||||||
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
||||||
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
||||||
|
@ -1358,7 +1328,7 @@ namespace MWClass
|
||||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
const ESM::InventoryList& list = ref->mBase->mInventory;
|
const ESM::InventoryList& list = ref->mBase->mInventory;
|
||||||
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
MWWorld::ContainerStore& store = getContainerStore(ptr);
|
||||||
store.restock(list, ptr, ptr.getCellRef().getRefId(), "", -1);
|
store.restock(list, ptr, ptr.getCellRef().getRefId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
|
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -1371,4 +1341,16 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Npc::getPrimaryFaction (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
return ref->mBase->mFaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Npc::getPrimaryFactionRank (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
return ref->mBase->getFactionRank();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,9 @@ namespace MWClass
|
||||||
virtual void restock (const MWWorld::Ptr& ptr) const;
|
virtual void restock (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
|
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual std::string getPrimaryFaction(const MWWorld::Ptr &ptr) const;
|
||||||
|
virtual int getPrimaryFactionRank(const MWWorld::Ptr &ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,9 +189,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Longblade Up");
|
return std::string("Item Weapon Longblade Up");
|
||||||
}
|
}
|
||||||
// Shortblade and thrown weapons
|
// Shortblade
|
||||||
// thrown weapons may not be entirely correct
|
if (type == 0)
|
||||||
if (type == 0 || type == 11)
|
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Shortblade Up");
|
return std::string("Item Weapon Shortblade Up");
|
||||||
}
|
}
|
||||||
|
@ -200,8 +199,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Spear Up");
|
return std::string("Item Weapon Spear Up");
|
||||||
}
|
}
|
||||||
// Blunts and Axes
|
// Blunts, Axes and Thrown weapons
|
||||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8)
|
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Blunt Up");
|
return std::string("Item Weapon Blunt Up");
|
||||||
}
|
}
|
||||||
|
@ -235,9 +234,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Longblade Down");
|
return std::string("Item Weapon Longblade Down");
|
||||||
}
|
}
|
||||||
// Shortblade and thrown weapons
|
// Shortblade
|
||||||
// thrown weapons may not be entirely correct
|
if (type == 0)
|
||||||
if (type == 0 || type == 11)
|
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Shortblade Down");
|
return std::string("Item Weapon Shortblade Down");
|
||||||
}
|
}
|
||||||
|
@ -246,8 +244,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Spear Down");
|
return std::string("Item Weapon Spear Down");
|
||||||
}
|
}
|
||||||
// Blunts and Axes
|
// Blunts, Axes and Thrown weapons
|
||||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8)
|
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
|
||||||
{
|
{
|
||||||
return std::string("Item Weapon Blunt Down");
|
return std::string("Item Weapon Blunt Down");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include <components/esm/loaddial.hpp>
|
#include <components/esm/loaddial.hpp>
|
||||||
#include <components/esm/loadinfo.hpp>
|
#include <components/esm/loadinfo.hpp>
|
||||||
|
@ -78,7 +79,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
void DialogueManager::addTopic (const std::string& topic)
|
void DialogueManager::addTopic (const std::string& topic)
|
||||||
{
|
{
|
||||||
mKnownTopics[Misc::StringUtils::lowerCase(topic)] = true;
|
mKnownTopics.insert( Misc::StringUtils::lowerCase(topic) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::parseText (const std::string& text)
|
void DialogueManager::parseText (const std::string& text)
|
||||||
|
@ -102,8 +103,8 @@ namespace MWDialogue
|
||||||
if (tok->isImplicitKeyword() && mTranslationDataStorage.hasTranslation())
|
if (tok->isImplicitKeyword() && mTranslationDataStorage.hasTranslation())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (std::find(mActorKnownTopics.begin(), mActorKnownTopics.end(), topicId) != mActorKnownTopics.end())
|
if (mActorKnownTopics.count( topicId ))
|
||||||
mKnownTopics[topicId] = true;
|
mKnownTopics.insert( topicId );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTopics();
|
updateTopics();
|
||||||
|
@ -341,10 +342,10 @@ namespace MWDialogue
|
||||||
if (filter.responseAvailable (*iter))
|
if (filter.responseAvailable (*iter))
|
||||||
{
|
{
|
||||||
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
|
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
|
||||||
mActorKnownTopics.push_back (lower);
|
mActorKnownTopics.insert (lower);
|
||||||
|
|
||||||
//does the player know the topic?
|
//does the player know the topic?
|
||||||
if (mKnownTopics.find (lower) != mKnownTopics.end())
|
if (mKnownTopics.count(lower))
|
||||||
{
|
{
|
||||||
keywordList.push_back (iter->mId);
|
keywordList.push_back (iter->mId);
|
||||||
}
|
}
|
||||||
|
@ -635,10 +636,11 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
ESM::DialogueState state;
|
ESM::DialogueState state;
|
||||||
|
|
||||||
for (std::map<std::string, bool>::const_iterator iter (mKnownTopics.begin());
|
for (std::set<std::string>::const_iterator iter (mKnownTopics.begin());
|
||||||
iter!=mKnownTopics.end(); ++iter)
|
iter!=mKnownTopics.end(); ++iter)
|
||||||
if (iter->second)
|
{
|
||||||
state.mKnownTopics.push_back (iter->first);
|
state.mKnownTopics.push_back (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
state.mChangedFactionReaction = mChangedFactionReaction;
|
state.mChangedFactionReaction = mChangedFactionReaction;
|
||||||
|
|
||||||
|
@ -659,7 +661,7 @@ namespace MWDialogue
|
||||||
for (std::vector<std::string>::const_iterator iter (state.mKnownTopics.begin());
|
for (std::vector<std::string>::const_iterator iter (state.mKnownTopics.begin());
|
||||||
iter!=state.mKnownTopics.end(); ++iter)
|
iter!=state.mKnownTopics.end(); ++iter)
|
||||||
if (store.get<ESM::Dialogue>().search (*iter))
|
if (store.get<ESM::Dialogue>().search (*iter))
|
||||||
mKnownTopics.insert (std::make_pair (*iter, true));
|
mKnownTopics.insert (*iter);
|
||||||
|
|
||||||
mChangedFactionReaction = state.mChangedFactionReaction;
|
mChangedFactionReaction = state.mChangedFactionReaction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <set>
|
||||||
|
|
||||||
#include <components/compiler/streamerrorhandler.hpp>
|
#include <components/compiler/streamerrorhandler.hpp>
|
||||||
#include <components/translation/translation.hpp>
|
#include <components/translation/translation.hpp>
|
||||||
|
@ -23,13 +23,13 @@ namespace MWDialogue
|
||||||
class DialogueManager : public MWBase::DialogueManager
|
class DialogueManager : public MWBase::DialogueManager
|
||||||
{
|
{
|
||||||
std::map<std::string, ESM::Dialogue> mDialogueMap;
|
std::map<std::string, ESM::Dialogue> mDialogueMap;
|
||||||
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
|
std::set<std::string> mKnownTopics;// Those are the topics the player knows.
|
||||||
|
|
||||||
// Modified faction reactions. <Faction1, <Faction2, Difference> >
|
// Modified faction reactions. <Faction1, <Faction2, Difference> >
|
||||||
typedef std::map<std::string, std::map<std::string, int> > ModFactionReactionMap;
|
typedef std::map<std::string, std::map<std::string, int> > ModFactionReactionMap;
|
||||||
ModFactionReactionMap mChangedFactionReaction;
|
ModFactionReactionMap mChangedFactionReaction;
|
||||||
|
|
||||||
std::list<std::string> mActorKnownTopics;
|
std::set<std::string> mActorKnownTopics;
|
||||||
|
|
||||||
Translation::Storage& mTranslationDataStorage;
|
Translation::Storage& mTranslationDataStorage;
|
||||||
MWScript::CompilerContext mCompilerContext;
|
MWScript::CompilerContext mCompilerContext;
|
||||||
|
|
|
@ -67,14 +67,11 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
if (isCreature)
|
if (isCreature)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor);
|
if (!Misc::StringUtils::ciEqual(mActor.getClass().getPrimaryFaction(mActor), info.mFaction))
|
||||||
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find ( Misc::StringUtils::lowerCase (info.mFaction));
|
|
||||||
|
|
||||||
if (iter==stats.getFactionRanks().end())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check rank
|
// check rank
|
||||||
if (iter->second < info.mData.mRank)
|
if (mActor.getClass().getPrimaryFactionRank(mActor) < info.mData.mRank)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (info.mData.mRank != -1)
|
else if (info.mData.mRank != -1)
|
||||||
|
@ -83,13 +80,8 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Rank requirement, but no faction given. Use the actor's faction, if there is one.
|
// Rank requirement, but no faction given. Use the actor's faction, if there is one.
|
||||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor);
|
|
||||||
|
|
||||||
if (!stats.getFactionRanks().size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check rank
|
// check rank
|
||||||
if (stats.getFactionRanks().begin()->second < info.mData.mRank)
|
if (mActor.getClass().getPrimaryFactionRank(mActor) < info.mData.mRank)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,12 +328,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
|
|
||||||
case SelectWrapper::Function_RankRequirement:
|
case SelectWrapper::Function_RankRequirement:
|
||||||
{
|
{
|
||||||
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
std::string faction = mActor.getClass().getPrimaryFaction(mActor);
|
||||||
|
if (faction.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::string faction =
|
|
||||||
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first;
|
|
||||||
|
|
||||||
int rank = getFactionRank (player, faction);
|
int rank = getFactionRank (player, faction);
|
||||||
|
|
||||||
if (rank>=9)
|
if (rank>=9)
|
||||||
|
@ -376,15 +366,14 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
|
|
||||||
case SelectWrapper::Function_FactionRankDiff:
|
case SelectWrapper::Function_FactionRankDiff:
|
||||||
{
|
{
|
||||||
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
std::string faction = mActor.getClass().getPrimaryFaction(mActor);
|
||||||
|
|
||||||
|
if (faction.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const std::pair<std::string, int> faction =
|
int rank = getFactionRank (player, faction);
|
||||||
*mActor.getClass().getNpcStats (mActor).getFactionRanks().begin();
|
int npcRank = mActor.getClass().getPrimaryFactionRank(mActor);
|
||||||
|
return rank-npcRank;
|
||||||
int rank = getFactionRank (player, faction.first);
|
|
||||||
|
|
||||||
return rank-faction.second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectWrapper::Function_WerewolfKills:
|
case SelectWrapper::Function_WerewolfKills:
|
||||||
|
@ -396,11 +385,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
{
|
{
|
||||||
bool low = select.getFunction()==SelectWrapper::Function_RankLow;
|
bool low = select.getFunction()==SelectWrapper::Function_RankLow;
|
||||||
|
|
||||||
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
std::string factionId = mActor.getClass().getPrimaryFaction(mActor);
|
||||||
return 0;
|
|
||||||
|
|
||||||
std::string factionId =
|
if (factionId.empty())
|
||||||
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first;
|
return 0;
|
||||||
|
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
|
@ -454,7 +442,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_NotFaction:
|
case SelectWrapper::Function_NotFaction:
|
||||||
|
|
||||||
return !Misc::StringUtils::ciEqual(mActor.get<ESM::NPC>()->mBase->mFaction, select.getName());
|
return !Misc::StringUtils::ciEqual(mActor.getClass().getPrimaryFaction(mActor), select.getName());
|
||||||
|
|
||||||
case SelectWrapper::Function_NotClass:
|
case SelectWrapper::Function_NotClass:
|
||||||
|
|
||||||
|
@ -494,8 +482,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_SameFaction:
|
case SelectWrapper::Function_SameFaction:
|
||||||
|
|
||||||
return mActor.getClass().getNpcStats (mActor).isSameFaction (
|
return player.getClass().getNpcStats (player).isInFaction(mActor.getClass().getPrimaryFaction(mActor));
|
||||||
player.getClass().getNpcStats (player));
|
|
||||||
|
|
||||||
case SelectWrapper::Function_PcCommonDisease:
|
case SelectWrapper::Function_PcCommonDisease:
|
||||||
|
|
||||||
|
@ -512,11 +499,10 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
|
|
||||||
case SelectWrapper::Function_PcExpelled:
|
case SelectWrapper::Function_PcExpelled:
|
||||||
{
|
{
|
||||||
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
std::string faction = mActor.getClass().getPrimaryFaction(mActor);
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string faction =
|
if (faction.empty())
|
||||||
mActor.getClass().getNpcStats (mActor).getFactionRanks().begin()->first;
|
return false;
|
||||||
|
|
||||||
return player.getClass().getNpcStats(player).getExpelled(faction);
|
return player.getClass().getNpcStats(player).getExpelled(faction);
|
||||||
}
|
}
|
||||||
|
@ -561,7 +547,7 @@ int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::st
|
||||||
{
|
{
|
||||||
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats (actor);
|
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats (actor);
|
||||||
|
|
||||||
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
|
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase(factionId));
|
||||||
|
|
||||||
if (iter==stats.getFactionRanks().end())
|
if (iter==stats.getFactionRanks().end())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
|
for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin());
|
||||||
iter!=dialogue->mInfo.end(); ++iter)
|
iter!=dialogue->mInfo.end(); ++iter)
|
||||||
if (iter->mData.mDisposition==index) /// \todo cleanup info structure
|
if (iter->mData.mJournalIndex==index)
|
||||||
{
|
{
|
||||||
return iter->mId;
|
return iter->mId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,12 @@ namespace MWDialogue
|
||||||
record.load (reader);
|
record.load (reader);
|
||||||
|
|
||||||
if (isThere (record.mTopic))
|
if (isThere (record.mTopic))
|
||||||
mQuests.insert (std::make_pair (record.mTopic, record));
|
{
|
||||||
|
std::pair<TQuestContainer::iterator, bool> result = mQuests.insert (std::make_pair (record.mTopic, record));
|
||||||
|
// reapply quest index, this is to handle users upgrading from only
|
||||||
|
// Morrowind.esm (no quest states) to Morrowind.esm + Tribunal.esm
|
||||||
|
result.first->second.setIndex(record.mState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
while (matches.size())
|
while (matches.size())
|
||||||
{
|
{
|
||||||
int longestKeywordSize = 0;
|
int longestKeywordSize = 0;
|
||||||
typename std::vector<Match>::iterator longestKeyword;
|
typename std::vector<Match>::iterator longestKeyword = matches.begin();
|
||||||
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
|
for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
|
||||||
{
|
{
|
||||||
int size = it->mEnd - it->mBeg;
|
int size = it->mEnd - it->mBeg;
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace MWDialogue
|
||||||
iter!=dialogue->mInfo.end(); ++iter)
|
iter!=dialogue->mInfo.end(); ++iter)
|
||||||
if (iter->mId == entry.mInfoId)
|
if (iter->mId == entry.mInfoId)
|
||||||
{
|
{
|
||||||
index = iter->mData.mDisposition; /// \todo cleanup info structure
|
index = iter->mData.mJournalIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "scripttest.hpp"
|
#include "scripttest.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
void BackgroundImage::setBackgroundImage (const std::string& image, bool fixedRatio, bool correct)
|
void BackgroundImage::setBackgroundImage (const std::string& image, bool fixedRatio, bool stretch)
|
||||||
{
|
{
|
||||||
if (mChild)
|
if (mChild)
|
||||||
{
|
{
|
||||||
MyGUI::Gui::getInstance().destroyWidget(mChild);
|
MyGUI::Gui::getInstance().destroyWidget(mChild);
|
||||||
mChild = NULL;
|
mChild = NULL;
|
||||||
}
|
}
|
||||||
if (correct)
|
if (!stretch)
|
||||||
{
|
{
|
||||||
setImageTexture("black.png");
|
setImageTexture("black.png");
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@ namespace MWGui
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param fixedRatio Use a fixed ratio of 4:3, regardless of the image dimensions
|
* @param fixedRatio Use a fixed ratio of 4:3, regardless of the image dimensions
|
||||||
* @param correct Add black bars?
|
* @param stretch Stretch to fill the whole screen, or add black bars?
|
||||||
*/
|
*/
|
||||||
void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool correct=true);
|
void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool stretch=true);
|
||||||
|
|
||||||
virtual void setSize (const MyGUI::IntSize &_value);
|
virtual void setSize (const MyGUI::IntSize &_value);
|
||||||
virtual void setCoord (const MyGUI::IntCoord &_value);
|
virtual void setCoord (const MyGUI::IntCoord &_value);
|
||||||
|
|
|
@ -195,8 +195,20 @@ struct TypesetBookImpl : TypesetBook
|
||||||
|
|
||||||
struct TypesetBookImpl::Typesetter : BookTypesetter
|
struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
{
|
{
|
||||||
|
struct PartialText {
|
||||||
|
StyleImpl *mStyle;
|
||||||
|
Utf8Stream::Point mBegin;
|
||||||
|
Utf8Stream::Point mEnd;
|
||||||
|
int mWidth;
|
||||||
|
|
||||||
|
PartialText( StyleImpl *style, Utf8Stream::Point begin, Utf8Stream::Point end, int width) :
|
||||||
|
mStyle(style), mBegin(begin), mEnd(end), mWidth(width)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
typedef TypesetBookImpl Book;
|
typedef TypesetBookImpl Book;
|
||||||
typedef boost::shared_ptr <Book> BookPtr;
|
typedef boost::shared_ptr <Book> BookPtr;
|
||||||
|
typedef std::vector<PartialText>::const_iterator PartialTextConstIterator;
|
||||||
|
|
||||||
int mPageWidth;
|
int mPageWidth;
|
||||||
int mPageHeight;
|
int mPageHeight;
|
||||||
|
@ -207,6 +219,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
Run * mRun;
|
Run * mRun;
|
||||||
|
|
||||||
std::vector <Alignment> mSectionAlignment;
|
std::vector <Alignment> mSectionAlignment;
|
||||||
|
std::vector <PartialText> mPartialWhitespace;
|
||||||
|
std::vector <PartialText> mPartialWord;
|
||||||
|
|
||||||
Book::Content const * mCurrentContent;
|
Book::Content const * mCurrentContent;
|
||||||
Alignment mCurrentAlignment;
|
Alignment mCurrentAlignment;
|
||||||
|
@ -273,6 +287,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
|
|
||||||
intptr_t addContent (Utf8Span text, bool select)
|
intptr_t addContent (Utf8Span text, bool select)
|
||||||
{
|
{
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
Contents::iterator i = mBook->mContents.insert (mBook->mContents.end (), Content (text.first, text.second));
|
Contents::iterator i = mBook->mContents.insert (mBook->mContents.end (), Content (text.first, text.second));
|
||||||
|
|
||||||
if (select)
|
if (select)
|
||||||
|
@ -283,6 +299,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
|
|
||||||
void selectContent (intptr_t contentHandle)
|
void selectContent (intptr_t contentHandle)
|
||||||
{
|
{
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
mCurrentContent = reinterpret_cast <Content const *> (contentHandle);
|
mCurrentContent = reinterpret_cast <Content const *> (contentHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,12 +320,16 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
{
|
{
|
||||||
assert (margin == 0); //TODO: figure out proper behavior here...
|
assert (margin == 0); //TODO: figure out proper behavior here...
|
||||||
|
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
mRun = NULL;
|
mRun = NULL;
|
||||||
mLine = NULL;
|
mLine = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sectionBreak (float margin)
|
void sectionBreak (float margin)
|
||||||
{
|
{
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
if (mBook->mSections.size () > 0)
|
if (mBook->mSections.size () > 0)
|
||||||
{
|
{
|
||||||
mRun = NULL;
|
mRun = NULL;
|
||||||
|
@ -321,6 +343,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
|
|
||||||
void setSectionAlignment (Alignment sectionAlignment)
|
void setSectionAlignment (Alignment sectionAlignment)
|
||||||
{
|
{
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
if (mSection != NULL)
|
if (mSection != NULL)
|
||||||
mSectionAlignment.back () = sectionAlignment;
|
mSectionAlignment.back () = sectionAlignment;
|
||||||
mCurrentAlignment = sectionAlignment;
|
mCurrentAlignment = sectionAlignment;
|
||||||
|
@ -331,6 +355,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
int curPageStart = 0;
|
int curPageStart = 0;
|
||||||
int curPageStop = 0;
|
int curPageStop = 0;
|
||||||
|
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
std::vector <Alignment>::iterator sa = mSectionAlignment.begin ();
|
std::vector <Alignment>::iterator sa = mSectionAlignment.begin ();
|
||||||
for (Sections::iterator i = mBook->mSections.begin (); i != mBook->mSections.end (); ++i, ++sa)
|
for (Sections::iterator i = mBook->mSections.begin (); i != mBook->mSections.end (); ++i, ++sa)
|
||||||
{
|
{
|
||||||
|
@ -415,23 +441,23 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
|
|
||||||
void writeImpl (StyleImpl * style, Utf8Stream::Point _begin, Utf8Stream::Point _end)
|
void writeImpl (StyleImpl * style, Utf8Stream::Point _begin, Utf8Stream::Point _end)
|
||||||
{
|
{
|
||||||
int line_height = style->mFont->getDefaultHeight ();
|
|
||||||
|
|
||||||
Utf8Stream stream (_begin, _end);
|
Utf8Stream stream (_begin, _end);
|
||||||
|
|
||||||
while (!stream.eof ())
|
while (!stream.eof ())
|
||||||
{
|
{
|
||||||
if (ucsLineBreak (stream.peek ()))
|
if (ucsLineBreak (stream.peek ()))
|
||||||
{
|
{
|
||||||
|
add_partial_text();
|
||||||
stream.consume ();
|
stream.consume ();
|
||||||
mLine = NULL, mRun = NULL;
|
mLine = NULL, mRun = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ucsBreakingSpace (stream.peek ()) && !mPartialWord.empty())
|
||||||
|
add_partial_text();
|
||||||
|
|
||||||
int word_width = 0;
|
int word_width = 0;
|
||||||
int word_height = 0;
|
|
||||||
int space_width = 0;
|
int space_width = 0;
|
||||||
int character_count = 0;
|
|
||||||
|
|
||||||
Utf8Stream::Point lead = stream.current ();
|
Utf8Stream::Point lead = stream.current ();
|
||||||
|
|
||||||
|
@ -450,8 +476,6 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
||||||
if (gi)
|
if (gi)
|
||||||
word_width += gi->advance + gi->bearingX;
|
word_width += gi->advance + gi->bearingX;
|
||||||
word_height = line_height;
|
|
||||||
++character_count;
|
|
||||||
stream.consume ();
|
stream.consume ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,21 +484,57 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||||
if (lead == extent)
|
if (lead == extent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ( lead != origin )
|
||||||
|
mPartialWhitespace.push_back (PartialText (style, lead, origin, space_width));
|
||||||
|
if ( origin != extent )
|
||||||
|
mPartialWord.push_back (PartialText (style, origin, extent, word_width));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_partial_text ()
|
||||||
|
{
|
||||||
|
if (mPartialWhitespace.empty() && mPartialWord.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int space_width = 0;
|
||||||
|
int word_width = 0;
|
||||||
|
|
||||||
|
for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i)
|
||||||
|
space_width += i->mWidth;
|
||||||
|
for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i)
|
||||||
|
word_width += i->mWidth;
|
||||||
|
|
||||||
int left = mLine ? mLine->mRect.right : 0;
|
int left = mLine ? mLine->mRect.right : 0;
|
||||||
|
|
||||||
if (left + space_width + word_width > mPageWidth)
|
if (left + space_width + word_width > mPageWidth)
|
||||||
{
|
{
|
||||||
mLine = NULL, mRun = NULL;
|
mLine = NULL, mRun = NULL, left = 0;
|
||||||
|
|
||||||
append_run (style, origin, extent, extent - origin, word_width, mBook->mRect.bottom + word_height);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i)
|
||||||
{
|
{
|
||||||
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
|
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
|
||||||
|
int line_height = i->mStyle->mFont->getDefaultHeight ();
|
||||||
|
|
||||||
append_run (style, lead, extent, extent - origin, left + space_width + word_width, top + word_height);
|
append_run ( i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + line_height);
|
||||||
|
|
||||||
|
left = mLine->mRect.right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i)
|
||||||
|
{
|
||||||
|
int top = mLine ? mLine->mRect.top : mBook->mRect.bottom;
|
||||||
|
int line_height = i->mStyle->mFont->getDefaultHeight ();
|
||||||
|
|
||||||
|
append_run (i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + line_height);
|
||||||
|
|
||||||
|
left = mLine->mRect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPartialWhitespace.clear();
|
||||||
|
mPartialWord.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_run (StyleImpl * style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom)
|
void append_run (StyleImpl * style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom)
|
||||||
|
|
|
@ -3,6 +3,22 @@
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void modifyProfit(const MWWorld::Ptr& actor, int diff)
|
||||||
|
{
|
||||||
|
std::string script = actor.getClass().getScript(actor);
|
||||||
|
if (!script.empty())
|
||||||
|
{
|
||||||
|
int profit = actor.getRefData().getLocals().getIntVar(script, "minimumprofit");
|
||||||
|
profit += diff;
|
||||||
|
actor.getRefData().getLocals().setVarByInt(script, "minimumprofit", profit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
CompanionItemModel::CompanionItemModel(const MWWorld::Ptr &actor)
|
CompanionItemModel::CompanionItemModel(const MWWorld::Ptr &actor)
|
||||||
|
@ -12,23 +28,25 @@ namespace MWGui
|
||||||
|
|
||||||
MWWorld::Ptr CompanionItemModel::copyItem (const ItemStack& item, size_t count, bool setNewOwner=false)
|
MWWorld::Ptr CompanionItemModel::copyItem (const ItemStack& item, size_t count, bool setNewOwner=false)
|
||||||
{
|
{
|
||||||
if (mActor.getClass().isNpc())
|
if (hasProfit(mActor))
|
||||||
{
|
modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count);
|
||||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor);
|
|
||||||
stats.modifyProfit(item.mBase.getClass().getValue(item.mBase) * count);
|
|
||||||
}
|
|
||||||
|
|
||||||
return InventoryItemModel::copyItem(item, count, setNewOwner);
|
return InventoryItemModel::copyItem(item, count, setNewOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
|
void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
|
||||||
{
|
{
|
||||||
if (mActor.getClass().isNpc())
|
if (hasProfit(mActor))
|
||||||
{
|
modifyProfit(mActor, -item.mBase.getClass().getValue(item.mBase) * count);
|
||||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor);
|
|
||||||
stats.modifyProfit(-item.mBase.getClass().getValue(item.mBase) * count);
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryItemModel::removeItem(item, count);
|
InventoryItemModel::removeItem(item, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CompanionItemModel::hasProfit(const MWWorld::Ptr &actor)
|
||||||
|
{
|
||||||
|
std::string script = actor.getClass().getScript(actor);
|
||||||
|
if (script.empty())
|
||||||
|
return false;
|
||||||
|
return actor.getRefData().getLocals().hasVar(script, "minimumprofit");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ namespace MWGui
|
||||||
|
|
||||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner);
|
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner);
|
||||||
virtual void removeItem (const ItemStack& item, size_t count);
|
virtual void removeItem (const ItemStack& item, size_t count);
|
||||||
|
|
||||||
|
bool hasProfit(const MWWorld::Ptr& actor);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,21 @@
|
||||||
#include "draganddrop.hpp"
|
#include "draganddrop.hpp"
|
||||||
#include "countdialog.hpp"
|
#include "countdialog.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
int getProfit(const MWWorld::Ptr& actor)
|
||||||
|
{
|
||||||
|
std::string script = actor.getClass().getScript(actor);
|
||||||
|
if (!script.empty())
|
||||||
|
{
|
||||||
|
return actor.getRefData().getLocals().getIntVar(script, "minimumprofit");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -116,13 +131,12 @@ void CompanionWindow::updateEncumbranceBar()
|
||||||
float encumbrance = mPtr.getClass().getEncumbrance(mPtr);
|
float encumbrance = mPtr.getClass().getEncumbrance(mPtr);
|
||||||
mEncumbranceBar->setValue(encumbrance, capacity);
|
mEncumbranceBar->setValue(encumbrance, capacity);
|
||||||
|
|
||||||
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
|
if (mModel && mModel->hasProfit(mPtr))
|
||||||
mProfitLabel->setCaption("");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
MWMechanics::NpcStats& stats = mPtr.getClass().getNpcStats(mPtr);
|
mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(getProfit(mPtr)));
|
||||||
mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(stats.getProfit()));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mProfitLabel->setCaption("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
@ -132,7 +146,7 @@ void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
|
||||||
void CompanionWindow::exit()
|
void CompanionWindow::exit()
|
||||||
{
|
{
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && mPtr.getClass().getNpcStats(mPtr).getProfit() < 0)
|
if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0)
|
||||||
{
|
{
|
||||||
std::vector<std::string> buttons;
|
std::vector<std::string> buttons;
|
||||||
buttons.push_back("#{sCompanionWarningButtonOne}");
|
buttons.push_back("#{sCompanionWarningButtonOne}");
|
||||||
|
@ -148,9 +162,6 @@ void CompanionWindow::onMessageBoxButtonClicked(int button)
|
||||||
{
|
{
|
||||||
if (button == 0)
|
if (button == 0)
|
||||||
{
|
{
|
||||||
mPtr.getRefData().getLocals().setVarByInt(mPtr.getClass().getScript(mPtr),
|
|
||||||
"minimumprofit", mPtr.getClass().getNpcStats(mPtr).getProfit());
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
|
||||||
// Important for Calvus' contract script to work properly
|
// Important for Calvus' contract script to work properly
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
|
|
|
@ -290,6 +290,7 @@ namespace MWGui
|
||||||
|
|
||||||
// Add the command to the history, and set the current pointer to
|
// Add the command to the history, and set the current pointer to
|
||||||
// the end of the list
|
// the end of the list
|
||||||
|
if (mCommandHistory.empty() || mCommandHistory.back() != cm)
|
||||||
mCommandHistory.push_back(cm);
|
mCommandHistory.push_back(cm);
|
||||||
mCurrent = mCommandHistory.end();
|
mCurrent = mCommandHistory.end();
|
||||||
mEditString.clear();
|
mEditString.clear();
|
||||||
|
|
|
@ -154,8 +154,6 @@ namespace MWGui
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
|
||||||
|
|
||||||
// Careful here. setTitle may cause size updates, causing itemview redraw, so make sure to do it last
|
|
||||||
// or we end up using a possibly invalid model.
|
|
||||||
setTitle(container.getClass().getName(container));
|
setTitle(container.getClass().getName(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +285,7 @@ namespace MWGui
|
||||||
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count);
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,8 @@ namespace MWGui
|
||||||
for (int i=0; i<2; ++i)
|
for (int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
||||||
if (Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
|
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(),
|
||||||
|
mPtr.getCellRef().getRefId()))
|
||||||
{
|
{
|
||||||
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
|
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <MyGUI_ScrollView.h>
|
#include <MyGUI_ScrollView.h>
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
@ -182,6 +183,10 @@ namespace MWGui
|
||||||
|
|
||||||
HUD::~HUD()
|
HUD::~HUD()
|
||||||
{
|
{
|
||||||
|
mMainWidget->eventMouseLostFocus.clear();
|
||||||
|
mMainWidget->eventMouseMove.clear();
|
||||||
|
mMainWidget->eventMouseButtonClick.clear();
|
||||||
|
|
||||||
delete mSpellIcons;
|
delete mSpellIcons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,4 +671,14 @@ namespace MWGui
|
||||||
mEnemyHealthTimer = -1;
|
mEnemyHealthTimer = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HUD::customMarkerCreated(MyGUI::Widget *marker)
|
||||||
|
{
|
||||||
|
marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HUD::doorMarkerCreated(MyGUI::Widget *marker)
|
||||||
|
{
|
||||||
|
marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue