From dac1290597eb1af50854314ac7b8a8abe34a5b11 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Jan 2015 22:59:38 +0100 Subject: [PATCH 01/35] Reduce size of water plane and increase subdivisions (Fixes #969) --- apps/openmw/mwrender/renderingmanager.cpp | 1 + apps/openmw/mwrender/water.cpp | 10 +++------- files/materials/water.shader | 11 ++++++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 149080d930..3ffd787c71 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -409,6 +409,7 @@ void RenderingManager::update (float duration, bool paused) mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); + mWater->changeCell(player.getCell()->getCell()); mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam)); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index fd790b363a..9960b7b21c 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -210,10 +210,10 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend) : mWaterPlane = Plane(Vector3::UNIT_Z, 0); - int waterScale = 300; + int waterScale = 30; MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, - CELL_SIZE*5*waterScale, CELL_SIZE*5*waterScale, 10, 10, true, 1, 3*waterScale,3*waterScale, Vector3::UNIT_Y); + CELL_SIZE*5*waterScale, CELL_SIZE*5*waterScale, 40, 40, true, 1, 3*waterScale,3*waterScale, Vector3::UNIT_Y); mWater = mSceneMgr->createEntity("water"); mWater->setVisibilityFlags(RV_Water); @@ -305,11 +305,7 @@ Water::~Water() void Water::changeCell(const ESM::Cell* cell) { - mTop = cell->mWater; - - setHeight(mTop); - - if(!(cell->mData.mFlags & cell->Interior)) + if(cell->isExterior()) mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY)); } diff --git a/files/materials/water.shader b/files/materials/water.shader index a6f49e0a1a..4dec57276d 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -71,8 +71,6 @@ SH_BEGIN_PROGRAM shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) - shVertexInput(float2, uv0) - shOutput(float2, UV) shOutput(float3, screenCoordsPassthrough) shOutput(float4, position) @@ -98,7 +96,6 @@ SH_START_PROGRAM { shOutputPosition = shMatrixMult(wvp, shInputPosition); - UV = uv0; #if !SH_GLSL @@ -187,7 +184,6 @@ } SH_BEGIN_PROGRAM - shInput(float2, UV) shInput(float3, screenCoordsPassthrough) shInput(float4, position) shInput(float, depthPassthrough) @@ -206,9 +202,10 @@ shSampler2D(depthMap) shSampler2D(normalMap) + shUniform(float4x4, wMat) @shAutoConstant(wMat, world_matrix) + #if RIPPLES shSampler2D(rippleNormalMap) - shUniform(float4x4, wMat) @shAutoConstant(wMat, world_matrix) #endif shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) @@ -251,6 +248,10 @@ SH_START_PROGRAM { + float3 worldPos = shMatrixMult (wMat, position).xyz; + float2 UV = worldPos.xy / (8192.0*5.0) * 3.0; + UV.y *= -1.0; + #if SHADOWS float shadow = depthShadowPCF (shadowMap0, lightSpacePos0, invShadowmapSize0); #endif From e0d0997409bfb63ab888327dd7b358e6805b53a0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 00:07:18 +0100 Subject: [PATCH 02/35] Rename omwlauncher -> openmw-launcher, mwiniimport -> openmw-iniimporter --- CMakeLists.txt | 16 ++++++++-------- apps/launcher/CMakeLists.txt | 6 +++--- apps/launcher/settingspage.cpp | 2 +- apps/mwiniimporter/CMakeLists.txt | 6 +++--- apps/mwiniimporter/main.cpp | 2 +- apps/wizard/mainwizard.cpp | 2 +- files/openmw.desktop | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3def1381c..f316034606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -408,7 +408,7 @@ IF(NOT WIN32 AND NOT APPLE) # Install binaries INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" ) IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-launcher" DESTINATION "${BINDIR}" ) ENDIF(BUILD_LAUNCHER) IF(BUILD_BSATOOL) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" ) @@ -417,7 +417,7 @@ IF(NOT WIN32 AND NOT APPLE) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) ENDIF(BUILD_ESMTOOL) IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-iniimporter" DESTINATION "${BINDIR}" ) ENDIF(BUILD_MWINIIMPORTER) IF(BUILD_ESSIMPORTER) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-essimporter" DESTINATION "${BINDIR}" ) @@ -476,10 +476,10 @@ if(WIN32) DESTINATION ".") 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) 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) IF(BUILD_ESSIMPORTER) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION ".") @@ -506,7 +506,7 @@ if(WIN32) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW") 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) IF(BUILD_OPENCS) SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set") @@ -525,7 +525,7 @@ if(WIN32) SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}") SET(CPACK_NSIS_HELP_LINK "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_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico") SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") @@ -699,7 +699,7 @@ if (WIN32) set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}") set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") 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) set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") if (BUILD_BSATOOL) @@ -717,7 +717,7 @@ if (WIN32) set_target_properties(opencs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS}) endif (BUILD_OPENCS) 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(MSVC) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index ba330f70c6..0de79f8f6b 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -78,7 +78,7 @@ if(NOT WIN32) endif(NOT WIN32) # Main executable -add_executable(omwlauncher +add_executable(openmw-launcher ${GUI_TYPE} ${LAUNCHER} ${LAUNCHER_HEADER} @@ -87,7 +87,7 @@ add_executable(omwlauncher ${UI_HDRS} ) -target_link_libraries(omwlauncher +target_link_libraries(openmw-launcher ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} @@ -99,6 +99,6 @@ target_link_libraries(omwlauncher if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) - target_link_libraries(omwlauncher gcov) + target_link_libraries(openmw-launcher gcov) endif() diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index ace8f43103..71ab8f7f32 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -140,7 +140,7 @@ void Launcher::SettingsPage::on_importerButton_clicked() qDebug() << "arguments " << arguments; - if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false)) + if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false)) return; } diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt index deab88ce28..790d47dc47 100644 --- a/apps/mwiniimporter/CMakeLists.txt +++ b/apps/mwiniimporter/CMakeLists.txt @@ -9,16 +9,16 @@ set(MWINIIMPORT_HEADER source_group(launcher FILES ${MWINIIMPORT} ${MWINIIMPORT_HEADER}) -add_executable(mwiniimport +add_executable(openmw-iniimporter ${MWINIIMPORT} ) -target_link_libraries(mwiniimport +target_link_libraries(openmw-iniimporter ${Boost_LIBRARIES} components ) if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) - target_link_libraries(mwiniimport gcov) + target_link_libraries(openmw-iniimporter gcov) endif() diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index 316737c1dc..f108678f3f 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -59,7 +59,7 @@ int wmain(int argc, wchar_t *wargv[]) { try { - bpo::options_description desc("Syntax: mwiniimporter inifile configfile\nAllowed options"); + bpo::options_description desc("Syntax: openmw-iniimporter inifile configfile\nAllowed options"); bpo::positional_options_description p_desc; desc.add_options() ("help,h", "produce help message") diff --git a/apps/wizard/mainwizard.cpp b/apps/wizard/mainwizard.cpp index 9a8ec2056b..a1370b1253 100644 --- a/apps/wizard/mainwizard.cpp +++ b/apps/wizard/mainwizard.cpp @@ -281,7 +281,7 @@ void Wizard::MainWizard::runSettingsImporter() arguments.append(QLatin1String("--cfg")); arguments.append(userPath + QLatin1String("openmw.cfg")); - if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false)) + if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false)) return qApp->quit(); } diff --git a/files/openmw.desktop b/files/openmw.desktop index 709304cb9c..6d64c5a7c4 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -4,8 +4,8 @@ Name=OpenMW Launcher GenericName=Role Playing Game Comment=An engine replacement for The Elder Scrolls III: Morrowind Keywords=Morrowind;Reimplementation Mods;esm;bsa; -TryExec=omwlauncher -Exec=omwlauncher +TryExec=openmw-launcher +Exec=openmw-launcher Icon=openmw Categories=Game;RolePlaying; From 417f60f467a9b6b91655fbeedfa18ae6300109e2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 00:51:12 +0100 Subject: [PATCH 03/35] Use the mooncircle textures (Fixes #1624, Fixes #1743) --- apps/openmw/mwrender/sky.cpp | 8 ++++++++ files/materials/moon.shader | 16 +++++++--------- files/materials/sky.mat | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 0b9dc091e5..454ed88209 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -187,6 +187,8 @@ Moon::Moon( const String& textureName, { setVisibility(1.0); + mMaterial->setProperty("alphatexture", sh::makeProperty(new sh::StringValue(textureName + "_alpha"))); + mPhase = Moon::Phase_Full; } @@ -215,9 +217,15 @@ void Moon::setPhase(const Moon::Phase& phase) textureName += ".dds"; if (mType == Moon::Type_Secunda) + { sh::Factory::getInstance ().setTextureAlias ("secunda_texture", textureName); + sh::Factory::getInstance ().setTextureAlias ("secunda_texture_alpha", "textures\\tx_mooncircle_full_s.dds"); + } else + { sh::Factory::getInstance ().setTextureAlias ("masser_texture", textureName); + sh::Factory::getInstance ().setTextureAlias ("masser_texture_alpha", "textures\\tx_mooncircle_full_m.dds"); + } mPhase = phase; } diff --git a/files/materials/moon.shader b/files/materials/moon.shader index eb7243d3f2..0e1a4ffc8d 100644 --- a/files/materials/moon.shader +++ b/files/materials/moon.shader @@ -38,16 +38,14 @@ shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) SH_START_PROGRAM { - - float4 tex = shSample(diffuseMap, UV); - - shOutputColour(0) = float4(materialEmissive.xyz, 1) * tex; - - shOutputColour(0).a = shSample(alphaMap, UV).a * materialDiffuse.a; - - shOutputColour(0).rgb += (1.0-tex.a) * shOutputColour(0).a * atmosphereColour.rgb; //fill dark side of moon with atmosphereColour - shOutputColour(0).rgb += (1.0-materialDiffuse.a) * atmosphereColour.rgb; //fade bump + float4 phaseTex = shSample(diffuseMap, UV); + float4 fullCircleTex = shSample(alphaMap, UV); + + shOutputColour(0).a = max(phaseTex.a, fullCircleTex.a) * materialDiffuse.a; + shOutputColour(0).xyz = fullCircleTex.xyz * atmosphereColour.xyz; + shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, phaseTex.xyz, phaseTex.a); + shOutputColour(0).xyz *= materialEmissive.xyz; } #endif diff --git a/files/materials/sky.mat b/files/materials/sky.mat index ccf2a8053c..c2e8ddeb09 100644 --- a/files/materials/sky.mat +++ b/files/materials/sky.mat @@ -50,7 +50,7 @@ material openmw_moon texture_unit alphaMap { - direct_texture textures\tx_secunda_full.dds + texture_alias $alphatexture } } } From 081c8c86157ac0ed0cef5c35cb51c52240e94978 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 15:11:27 +0100 Subject: [PATCH 04/35] ESSImport: convert to utf8, based on encoding setting in openmw.cfg --- apps/essimporter/importer.cpp | 9 ++++++--- apps/essimporter/importer.hpp | 3 ++- apps/essimporter/main.cpp | 23 +++++++++++++++-------- components/esm/cellref.cpp | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 8f6563dee6..bd994cf486 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -21,6 +21,8 @@ #include #include +#include + #include "importercontext.hpp" #include "converter.hpp" @@ -44,9 +46,10 @@ namespace 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) , mOutFile(outfile) + , mEncoding(encoding) { } @@ -188,10 +191,10 @@ namespace ESSImport Ogre::LogManager logman; 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.open(mEssFile); + esm.setEncoder(&encoder); Context context; diff --git a/apps/essimporter/importer.hpp b/apps/essimporter/importer.hpp index eb199b6dfb..ccacd7972d 100644 --- a/apps/essimporter/importer.hpp +++ b/apps/essimporter/importer.hpp @@ -9,7 +9,7 @@ namespace ESSImport class Importer { 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(); @@ -18,6 +18,7 @@ namespace ESSImport private: std::string mEssFile; std::string mOutFile; + std::string mEncoding; }; } diff --git a/apps/essimporter/main.cpp b/apps/essimporter/main.cpp index d467e053ec..ae4b36ecdd 100644 --- a/apps/essimporter/main.cpp +++ b/apps/essimporter/main.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "importer.hpp" namespace bpo = boost::program_options; @@ -23,31 +25,36 @@ int main(int argc, char** argv) ("mwsave,m", bpo::value(), "morrowind .ess save file") ("output,o", bpo::value(), "output file (.omwsave)") ("compare,c", "compare two .ess files") + ("encoding", boost::program_options::value()->default_value("win1252"), "encoding of the save file") ; 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) .options(desc) .positional(p_desc) .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; return 0; } - bpo::notify(vm); + bpo::notify(variables); + + Files::ConfigurationManager cfgManager; + cfgManager.readConfiguration(variables, desc); - std::string essFile = vm["mwsave"].as(); - std::string outputFile = vm["output"].as(); + std::string essFile = variables["mwsave"].as(); + std::string outputFile = variables["output"].as(); + std::string encoding = variables["encoding"].as(); - ESSImport::Importer importer(essFile, outputFile); + ESSImport::Importer importer(essFile, outputFile, encoding); - if (vm.count("compare")) + if (variables.count("compare")) importer.compare(); else { diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index dfc3052ee5..0dd2987b5c 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -153,7 +153,7 @@ void ESM::CellRef::blank() mLockLevel = 0; mKey.clear(); mTrap.clear(); - mReferenceBlocked = 0; + mReferenceBlocked = -1; mTeleport = false; for (int i=0; i<3; ++i) From 7e3843de42c3a1d48beb54a430f96556ebda626d Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 16:14:53 +0100 Subject: [PATCH 05/35] ESSImport: convert Attacked flag --- apps/essimporter/convertacdt.cpp | 1 + apps/essimporter/importacdt.cpp | 2 +- apps/essimporter/importacdt.hpp | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/essimporter/convertacdt.cpp b/apps/essimporter/convertacdt.cpp index 496eab9e99..d3b70d1f58 100644 --- a/apps/essimporter/convertacdt.cpp +++ b/apps/essimporter/convertacdt.cpp @@ -29,6 +29,7 @@ namespace ESSImport } cStats.mGoldPool = acdt.mGoldPool; cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer; + cStats.mAttacked = acdt.mFlags & Attacked; } void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats) diff --git a/apps/essimporter/importacdt.cpp b/apps/essimporter/importacdt.cpp index 9a062484b3..4cd994b927 100644 --- a/apps/essimporter/importacdt.cpp +++ b/apps/essimporter/importacdt.cpp @@ -24,7 +24,7 @@ namespace ESSImport esm.getHNOT(mACDT, "ACDT"); ACSC acsc; - esm.getHNOT(acsc, "ACSC"); + esm.getHNOT(acsc, "ACSC"); // skill progress? esm.getHNOT(acsc, "ACSL"); if (esm.isNextSub("CSTN")) diff --git a/apps/essimporter/importacdt.hpp b/apps/essimporter/importacdt.hpp index 53783a3644..4876602bcd 100644 --- a/apps/essimporter/importacdt.hpp +++ b/apps/essimporter/importacdt.hpp @@ -17,7 +17,8 @@ namespace ESSImport enum ACDTFlags { - TalkedToPlayer = 0x4 + TalkedToPlayer = 0x4, + Attacked = 0x100 }; /// Actor data, shared by (at least) REFR and CellRef @@ -28,8 +29,7 @@ namespace ESSImport // Note, not stored at *all*: // - Level changes are lost on reload, except for the player (there it's in the NPC record). unsigned char mUnknown[12]; - unsigned char mFlags; // ACDTFlags - unsigned char mUnknown1[3]; + unsigned int mFlags; float mBreathMeter; // Seconds left before drowning unsigned char mUnknown2[20]; float mDynamic[3][2]; From 5a9b30a8ca0189bea17ddd2b52c27a6199e7e402 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 21:36:00 +0100 Subject: [PATCH 06/35] Don't show VFX on the map (Fixes #2324) --- apps/openmw/mwrender/animation.cpp | 3 +-- apps/openmw/mwrender/effectmanager.cpp | 3 +-- apps/openmw/mwrender/refraction.cpp | 2 +- apps/openmw/mwrender/renderconst.hpp | 31 +++++++++++++---------- apps/openmw/mwrender/water.cpp | 1 + apps/openmw/mwworld/projectilemanager.cpp | 2 +- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 117830c093..ec53983092 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1272,8 +1272,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con else params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model); - // TODO: turn off shadow casting - setRenderProperties(params.mObjects, RV_Misc, + setRenderProperties(params.mObjects, RV_Effects, RQG_Main, RQG_Alpha, 0.f, false, NULL); params.mLoop = loop; diff --git a/apps/openmw/mwrender/effectmanager.cpp b/apps/openmw/mwrender/effectmanager.cpp index a48dea8d57..503a0223e8 100644 --- a/apps/openmw/mwrender/effectmanager.cpp +++ b/apps/openmw/mwrender/effectmanager.cpp @@ -25,8 +25,7 @@ void EffectManager::addEffect(const std::string &model, std::string textureOverr NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model); - // TODO: turn off shadow casting - MWRender::Animation::setRenderProperties(scene, RV_Misc, + MWRender::Animation::setRenderProperties(scene, RV_Effects, RQG_Main, RQG_Alpha, 0.f, false, NULL); for(size_t i = 0;i < scene->mControllers.size();i++) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 164380866a..6cc49089ae 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -33,7 +33,7 @@ namespace MWRender Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera); vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); - vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky + RV_FirstPerson); + vp->setVisibilityMask(RV_Refraction); vp->setMaterialScheme("water_refraction"); vp->setBackgroundColour (Ogre::ColourValue(0.090195, 0.115685, 0.12745)); mRenderTarget->setAutoUpdated(true); diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 44599ebee2..4ac21ad510 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -30,39 +30,44 @@ enum RenderQueueGroups enum VisibilityFlags { // Terrain - RV_Terrain = 1, + RV_Terrain = (1<<0), // Statics (e.g. trees, houses) - RV_Statics = 2, + RV_Statics = (1<<1), // Small statics - RV_StaticsSmall = 4, + RV_StaticsSmall = (1<<2), // Water - RV_Water = 8, + RV_Water = (1<<3), // Actors (npcs, creatures) - RV_Actors = 16, + RV_Actors = (1<<4), // Misc objects (containers, dynamic objects) - RV_Misc = 32, + RV_Misc = (1<<5), - RV_Sky = 64, + // VFX, don't appear on map and don't cast shadows + RV_Effects = (1<<6), + + RV_Sky = (1<<7), // not visible in reflection - RV_NoReflection = 128, + RV_NoReflection = (1<<8), - RV_OcclusionQuery = 256, + RV_OcclusionQuery = (1<<9), - RV_Debug = 512, + RV_Debug = (1<<10), // overlays, we only want these on the main render target - RV_Overlay = 1024, + RV_Overlay = (1<<11), // First person meshes do not cast shadows - RV_FirstPerson = 2048, + RV_FirstPerson = (1<<12), + + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water, - RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water + RV_Refraction = RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Effects + RV_Sky + RV_FirstPerson }; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 9960b7b21c..44e1842696 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -420,6 +420,7 @@ void Water::applyVisibilityMask() mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + (RV_Statics + RV_StaticsSmall + RV_Misc) * Settings::Manager::getBool("reflect statics", "Water") + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + + RV_Effects + RV_Sky; if (mReflection) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 41fbfea9f8..7af51fd28f 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -44,7 +44,7 @@ namespace MWWorld state.mObject->mControllers[i].setSource(Ogre::SharedPtr (new MWRender::EffectAnimationTime())); } - MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Misc, + MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Effects, MWRender::RQG_Main, MWRender::RQG_Alpha, 0.f, false, NULL); } From e7056b4e274440107945e91daef2110a4f33e7f9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 22:07:21 +0100 Subject: [PATCH 07/35] ESSImport: convert Dead flag --- apps/essimporter/convertacdt.cpp | 5 +++++ apps/essimporter/convertacdt.hpp | 1 + apps/essimporter/converter.cpp | 16 ++++++++++++---- apps/essimporter/converter.hpp | 5 +++-- apps/essimporter/importacdt.cpp | 20 +++++++++++++++----- apps/essimporter/importacdt.hpp | 26 ++++++++++++++++++-------- apps/essimporter/importercontext.hpp | 6 ++++++ 7 files changed, 60 insertions(+), 19 deletions(-) diff --git a/apps/essimporter/convertacdt.cpp b/apps/essimporter/convertacdt.cpp index d3b70d1f58..718403a8c3 100644 --- a/apps/essimporter/convertacdt.cpp +++ b/apps/essimporter/convertacdt.cpp @@ -32,6 +32,11 @@ namespace ESSImport 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) { for (int i=0; imCreatures/mNpcs + if (!isIndexedRefId(cellref.mIndexedRefId)) { // non-indexed RefNum, i.e. no CREC/NPCC/CNTC record associated with it @@ -309,9 +311,12 @@ namespace ESSImport objstate.blank(); objstate.mRef = out; 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 - convertACDT(cellref.mACDT, objstate.mCreatureStats); + if (cellref.mHasACDT) + convertACDT(cellref.mACDT, objstate.mCreatureStats); + if (cellref.mHasACSC) + convertACSC(cellref.mACSC, objstate.mCreatureStats); convertNpcData(cellref, objstate.mNpcStats); convertNPCC(npccIt->second, objstate); convertCellRef(cellref, objstate); @@ -343,9 +348,12 @@ namespace ESSImport objstate.blank(); objstate.mRef = out; objstate.mRef.mRefID = idLower; - convertACDT(cellref.mACDT, objstate.mCreatureStats); - // 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 + if (cellref.mHasACDT) + convertACDT(cellref.mACDT, objstate.mCreatureStats); + if (cellref.mHasACSC) + convertACSC(cellref.mACSC, objstate.mCreatureStats); convertCREC(crecIt->second, objstate); convertCellRef(cellref, objstate); esm.writeHNT ("OBJE", ESM::REC_CREA); diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index c80ccb951a..886983aab3 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -104,10 +104,10 @@ public: npc.load(esm); if (id != "player") { - // TODO: - // this should handle changes to the NPC struct, but since there is no index here + // Handles 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 // "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 { @@ -139,6 +139,7 @@ public: ESM::Creature creature; std::string id = esm.getHNString("NAME"); creature.load(esm); + mContext->mCreatures[Misc::StringUtils::lowerCase(id)] = creature; } }; diff --git a/apps/essimporter/importacdt.cpp b/apps/essimporter/importacdt.cpp index 4cd994b927..9d881515dd 100644 --- a/apps/essimporter/importacdt.cpp +++ b/apps/essimporter/importacdt.cpp @@ -20,12 +20,22 @@ namespace ESSImport ESM::CellRef::loadData(esm); - // FIXME: not all actors have this, add flag - esm.getHNOT(mACDT, "ACDT"); + mHasACDT = false; + if (esm.isNextSub("ACDT")) + { + mHasACDT = true; + esm.getHT(mACDT); + } + + mHasACSC = false; + if (esm.isNextSub("ACSC")) + { + mHasACSC = true; + esm.getHT(mACSC); + } - ACSC acsc; - esm.getHNOT(acsc, "ACSC"); // skill progress? - esm.getHNOT(acsc, "ACSL"); + if (esm.isNextSub("ACSL")) + esm.skipHSubSize(112); if (esm.isNextSub("CSTN")) esm.skipHSub(); // "PlayerSaveGame", link to some object? diff --git a/apps/essimporter/importacdt.hpp b/apps/essimporter/importacdt.hpp index 4876602bcd..1e0317049d 100644 --- a/apps/essimporter/importacdt.hpp +++ b/apps/essimporter/importacdt.hpp @@ -18,7 +18,12 @@ namespace ESSImport enum ACDTFlags { TalkedToPlayer = 0x4, - Attacked = 0x100 + Attacked = 0x100, + Unknown = 0x200 + }; + enum ACSCFlags + { + Dead = 0x2 }; /// Actor data, shared by (at least) REFR and CellRef @@ -35,16 +40,27 @@ namespace ESSImport float mDynamic[3][2]; unsigned char mUnknown3[16]; 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 char mUnknown5[4]; }; + struct ACSC + { + unsigned char mUnknown1[17]; + unsigned char mFlags; // ACSCFlags + unsigned char mUnknown2[94]; + }; #pragma pack(pop) struct ActorData : public ESM::CellRef { + bool mHasACDT; ACDT mACDT; + bool mHasACSC; + ACSC mACSC; + int mSkills[27][2]; // creature combat stats, base and modified @@ -60,12 +76,6 @@ namespace ESSImport void load(ESM::ESMReader& esm); }; - /// Unknown, shared by (at least) REFR and CellRef - struct ACSC - { - unsigned char unknown[112]; - }; - } #endif diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index a466770d0d..3b010cb8ff 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "importnpcc.hpp" #include "importcrec.hpp" @@ -15,6 +17,7 @@ + namespace ESSImport { @@ -42,6 +45,9 @@ namespace ESSImport std::map, NPCC> mNpcChanges; std::map, CNTC> mContainerChanges; + std::map mCreatures; + std::map mNpcs; + Context() { mPlayer.mAutoMove = 0; From ef3ba12cb6a27cd668ec86840b78bd0184d0df32 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 22:11:26 +0100 Subject: [PATCH 08/35] Add silent mode to ConfigurationManager, used by essimporter --- apps/essimporter/main.cpp | 2 +- components/files/configurationmanager.cpp | 12 ++++++++---- components/files/configurationmanager.hpp | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/essimporter/main.cpp b/apps/essimporter/main.cpp index ae4b36ecdd..a4ad114ec1 100644 --- a/apps/essimporter/main.cpp +++ b/apps/essimporter/main.cpp @@ -45,7 +45,7 @@ int main(int argc, char** argv) bpo::notify(variables); - Files::ConfigurationManager cfgManager; + Files::ConfigurationManager cfgManager(true); cfgManager.readConfiguration(variables, desc); std::string essFile = variables["mwsave"].as(); diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 942f47d4e1..e321b58143 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -27,8 +27,9 @@ const char* const localToken = "?local?"; const char* const userDataToken = "?userdata?"; const char* const globalToken = "?global?"; -ConfigurationManager::ConfigurationManager() +ConfigurationManager::ConfigurationManager(bool silent) : mFixedPath(applicationName) + , mSilent(silent) { setupTokensMapping(); @@ -129,7 +130,8 @@ void ConfigurationManager::loadConfig(const boost::filesystem::path& path, cfgFile /= std::string(openmwCfgFile); if (boost::filesystem::is_regular_file(cfgFile)) { - std::cout << "Loading config file: " << cfgFile.string() << "... "; + if (!mSilent) + std::cout << "Loading config file: " << cfgFile.string() << "... "; boost::filesystem::ifstream configFileStream(cfgFile); if (configFileStream.is_open()) @@ -137,11 +139,13 @@ void ConfigurationManager::loadConfig(const boost::filesystem::path& path, boost::program_options::store(boost::program_options::parse_config_file( configFileStream, description, true), variables); - std::cout << "done." << std::endl; + if (!mSilent) + std::cout << "done." << std::endl; } else { - std::cout << "failed." << std::endl; + if (!mSilent) + std::cout << "failed." << std::endl; } } } diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 35144fe04f..b0b7fea9a9 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -25,7 +25,7 @@ namespace Files */ struct ConfigurationManager { - ConfigurationManager(); + ConfigurationManager(bool silent=false); /// @param silent Emit log messages to cout? virtual ~ConfigurationManager(); void readConfiguration(boost::program_options::variables_map& variables, @@ -69,6 +69,8 @@ struct ConfigurationManager boost::filesystem::path mLogPath; TokensMappingContainer mTokensMapping; + + bool mSilent; }; } /* namespace Cfg */ From b9acf437fd007e13e98da605e06a0484be6b8aaf Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 22:22:47 +0100 Subject: [PATCH 09/35] Remove friendly hits from the save file The vanilla engine does not store friendly hits in the save file. Since there's no other mechanism that ever resets the friendly hits (at least not to my knowledge) this should be regarded a feature rather than a bug. --- apps/openmw/mwmechanics/creaturestats.cpp | 6 ++++-- components/esm/creaturestats.cpp | 8 ++------ components/esm/creaturestats.hpp | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index c61cc9697a..ac35fc2ea1 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -495,7 +495,10 @@ namespace MWMechanics state.mDead = mDead; state.mDied = mDied; state.mMurdered = mMurdered; - state.mFriendlyHits = mFriendlyHits; + // The vanilla engine does not store friendly hits in the save file. Since there's no other mechanism + // that ever resets the friendly hits (at least not to my knowledge) this should be regarded a feature + // rather than a bug. + //state.mFriendlyHits = mFriendlyHits; state.mTalkedTo = mTalkedTo; state.mAlarmed = mAlarmed; state.mAttacked = mAttacked; @@ -544,7 +547,6 @@ namespace MWMechanics mDead = state.mDead; mDied = state.mDied; mMurdered = state.mMurdered; - mFriendlyHits = state.mFriendlyHits; mTalkedTo = state.mTalkedTo; mAlarmed = state.mAlarmed; mAttacked = state.mAttacked; diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp index cac5cc0a6a..75c1c28bc2 100644 --- a/components/esm/creaturestats.cpp +++ b/components/esm/creaturestats.cpp @@ -24,8 +24,8 @@ void ESM::CreatureStats::load (ESMReader &esm) mMurdered = false; esm.getHNOT (mMurdered, "MURD"); - mFriendlyHits = 0; - esm.getHNOT (mFriendlyHits, "FRHT"); + if (esm.isNextSub("FRHT")) + esm.skipHSub(); // Friendly hits, no longer used mTalkedTo = false; esm.getHNOT (mTalkedTo, "TALK"); @@ -140,9 +140,6 @@ void ESM::CreatureStats::save (ESMWriter &esm) const if (mMurdered) esm.writeHNT ("MURD", mMurdered); - if (mFriendlyHits) - esm.writeHNT ("FRHT", mFriendlyHits); - if (mTalkedTo) esm.writeHNT ("TALK", mTalkedTo); @@ -235,7 +232,6 @@ void ESM::CreatureStats::blank() mDead = false; mDied = false; mMurdered = false; - mFriendlyHits = 0; mTalkedTo = false; mAlarmed = false; mAttacked = false; diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp index 91ee983332..2a03136d08 100644 --- a/components/esm/creaturestats.hpp +++ b/components/esm/creaturestats.hpp @@ -42,7 +42,6 @@ namespace ESM bool mDead; bool mDied; bool mMurdered; - int mFriendlyHits; bool mTalkedTo; bool mAlarmed; bool mAttacked; From 2e4b5858e75e546f45c9d737391de2022d0db6fb Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 22:55:18 +0100 Subject: [PATCH 10/35] ESSImport: add ANSI color code highlighting for --compare switch --- apps/essimporter/importer.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index bd994cf486..d5ed43b8a0 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -170,14 +170,30 @@ namespace ESSImport std::cout << "Data 1:" << std::endl; for (unsigned int k=0; 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] << " "; + if (different) + std::cout << "\033[0m"; } std::cout << std::endl; std::cout << "Data 2:" << std::endl; for (unsigned int k=0; 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] << " "; + if (different) + std::cout << "\033[0m"; } std::cout << std::endl; } From f3c79c0aa0c831d85c28630d2eadcde3d35987fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 22:56:03 +0100 Subject: [PATCH 11/35] ESSImport: convert player DrawState, cleanup --- apps/essimporter/CMakeLists.txt | 1 + apps/essimporter/converter.hpp | 22 ++----------------- apps/essimporter/convertplayer.cpp | 34 ++++++++++++++++++++++++++++++ apps/essimporter/convertplayer.hpp | 15 +++++++++++++ apps/essimporter/importplayer.hpp | 9 +++++++- 5 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 apps/essimporter/convertplayer.cpp create mode 100644 apps/essimporter/convertplayer.hpp diff --git a/apps/essimporter/CMakeLists.txt b/apps/essimporter/CMakeLists.txt index 76fc9aa94a..72ef364ee6 100644 --- a/apps/essimporter/CMakeLists.txt +++ b/apps/essimporter/CMakeLists.txt @@ -25,6 +25,7 @@ set(ESSIMPORTER_FILES convertcntc.cpp convertscri.cpp convertscpt.cpp + convertplayer.cpp ) add_executable(openmw-essimporter diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 886983aab3..bbafd5ba95 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -35,6 +35,7 @@ #include "convertacdt.hpp" #include "convertnpcc.hpp" #include "convertscpt.hpp" +#include "convertplayer.hpp" namespace ESSImport { @@ -265,26 +266,7 @@ public: PCDT pcdt; pcdt.load(esm); - mContext->mPlayer.mBirthsign = pcdt.mBirthsign; - mContext->mPlayer.mObject.mNpcStats.mBounty = pcdt.mBounty; - for (std::vector::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; - mContext->mPlayer.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(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::const_iterator it = pcdt.mKnownDialogueTopics.begin(); - it != pcdt.mKnownDialogueTopics.end(); ++it) - { - mContext->mDialogueState.mKnownTopics.push_back(Misc::StringUtils::lowerCase(*it)); - } - + convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics); } }; diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp new file mode 100644 index 0000000000..fb225284ee --- /dev/null +++ b/apps/essimporter/convertplayer.cpp @@ -0,0 +1,34 @@ +#include "convertplayer.hpp" + +namespace ESSImport +{ + + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics) + { + out.mBirthsign = pcdt.mBirthsign; + out.mObject.mNpcStats.mBounty = pcdt.mBounty; + for (std::vector::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]; + 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; + + for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); + it != pcdt.mKnownDialogueTopics.end(); ++it) + { + outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it)); + } + } + +} diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp new file mode 100644 index 0000000000..a4541c7aa8 --- /dev/null +++ b/apps/essimporter/convertplayer.hpp @@ -0,0 +1,15 @@ +#ifndef OPENMW_ESSIMPORT_CONVERTPLAYER_H +#define OPENMW_ESSIMPORT_CONVERTPLAYER_H + +#include "importplayer.hpp" + +#include + +namespace ESSImport +{ + + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics); + +} + +#endif diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 64ceddfd79..fb2cb95fd0 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -38,6 +38,12 @@ struct PCDT std::vector mKnownDialogueTopics; + enum DrawState_ + { + DrawState_Weapon = 0x80, + DrawState_Spell = 0x100 + }; + #pragma pack(push) #pragma pack(1) struct FNAM @@ -49,9 +55,10 @@ struct PCDT unsigned char mUnknown2[3]; ESM::NAME32 mFactionName; }; + struct PNAM { - unsigned char mUnknown1[4]; + int mDrawState; // DrawState unsigned char mLevelProgress; unsigned char mUnknown2[111]; unsigned char mSkillIncreases[8]; // number of skill increases for each attribute From c4038f7021040a8483b8752e0e53053e3e0d7f10 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 23:10:39 +0100 Subject: [PATCH 12/35] ESSImport: convert camera first/third person state --- apps/essimporter/converter.hpp | 12 +++++++++++- apps/essimporter/convertplayer.cpp | 4 +++- apps/essimporter/convertplayer.hpp | 2 +- apps/essimporter/importplayer.hpp | 8 +++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index bbafd5ba95..80b8e2e3bb 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -261,13 +261,23 @@ private: class ConvertPCDT : public Converter { public: + ConvertPCDT() : mFirstPersonCam(true) {} + virtual void read(ESM::ESMReader &esm) { PCDT pcdt; pcdt.load(esm); - convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics); + convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam); } + virtual void write(ESM::ESMWriter &esm) + { + esm.startRecord(ESM::REC_CAM_); + esm.writeHNT("FIRS", mFirstPersonCam); + esm.endRecord(ESM::REC_CAM_); + } +private: + bool mFirstPersonCam; }; class ConvertCNTC : public Converter diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index fb225284ee..19cec2a28d 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -3,7 +3,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics) + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam) { out.mBirthsign = pcdt.mBirthsign; out.mObject.mNpcStats.mBounty = pcdt.mBounty; @@ -24,6 +24,8 @@ namespace ESSImport if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell) out.mObject.mCreatureStats.mDrawState = 2; + firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson); + for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); it != pcdt.mKnownDialogueTopics.end(); ++it) { diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index a4541c7aa8..f6731eed76 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -8,7 +8,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics); + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam); } diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index fb2cb95fd0..4e68834cf0 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -43,6 +43,11 @@ struct PCDT DrawState_Weapon = 0x80, DrawState_Spell = 0x100 }; + enum CameraState + { + CameraState_FirstPerson = 0x8, + CameraState_ThirdPerson = 0xa + }; #pragma pack(push) #pragma pack(1) @@ -58,7 +63,8 @@ struct PCDT struct PNAM { - int mDrawState; // DrawState + short mDrawState; // DrawState + short mCameraState; // CameraState unsigned char mLevelProgress; unsigned char mUnknown2[111]; unsigned char mSkillIncreases[8]; // number of skill increases for each attribute From 51c05264b09b5b1ee72fb35eaff1537b0d359194 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Jan 2015 23:31:00 +0100 Subject: [PATCH 13/35] ESSImport: note where skill progress is stored (not converted yet) --- apps/essimporter/converter.hpp | 2 +- apps/essimporter/convertplayer.cpp | 3 +++ apps/essimporter/importplayer.hpp | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 80b8e2e3bb..7759956058 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -409,7 +409,7 @@ private: /// Seen responses for a dialogue topic? /// 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. /// - 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. diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 19cec2a28d..ef22660f56 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -24,6 +24,9 @@ namespace ESSImport if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell) out.mObject.mCreatureStats.mDrawState = 2; + // TODO: convert PNAM.mSkillProgress, needs to be converted to uniform scale + // (or change openmw to accept non-uniform skill progress) + firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson); for (std::vector::const_iterator it = pcdt.mKnownDialogueTopics.begin(); diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 4e68834cf0..bc6b94be28 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -65,8 +65,8 @@ struct PCDT { short mDrawState; // DrawState short mCameraState; // CameraState - unsigned char mLevelProgress; - 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 mUnknown3[88]; }; From d1b5956a988fb73aff05ccfec1f9637e7a2ff516 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 01:31:41 +0100 Subject: [PATCH 14/35] Fix crash on exit --- apps/openmw/mwgui/windowmanagerimp.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index cf46792872..8c397b9f1a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -352,6 +352,9 @@ namespace MWGui WindowManager::~WindowManager() { + MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear(); + MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear(); + delete mConsole; delete mMessageBoxManager; delete mHud; @@ -385,7 +388,6 @@ namespace MWGui delete mMerchantRepair; delete mRepair; delete mSoulgemDialog; - delete mCursorManager; delete mRecharge; delete mCompanionWindow; delete mHitFader; @@ -394,6 +396,8 @@ namespace MWGui delete mBlindnessFader; delete mDebugWindow; + delete mCursorManager; + cleanupGarbage(); delete mGuiManager; From bd0a0e64a9d441c235c8320f28ec3aa82b296cd1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 01:44:49 +0100 Subject: [PATCH 15/35] Fix overwriting script records not working --- apps/openmw/mwworld/store.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 929ff62a23..a155a37609 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -360,6 +360,8 @@ namespace MWWorld std::pair inserted = mStatic.insert(std::make_pair(scpt.mId, scpt)); if (inserted.second) mShared.push_back(&inserted.first->second); + else + inserted.first->second = scpt; } template <> @@ -371,6 +373,8 @@ namespace MWWorld std::pair inserted = mStatic.insert(std::make_pair(s.mId, s)); if (inserted.second) mShared.push_back(&inserted.first->second); + else + inserted.first->second = s; } template <> From 2346c3528d5b7e7db98c55f08837f16d77e9039a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 02:08:37 +0100 Subject: [PATCH 16/35] Remove NpcStats::mProfit and store it in the script instead Also use the Profit label when the "minimumProfit" script variable exists, rather than hardcoding to NPCs. --- apps/openmw/mwgui/companionitemmodel.cpp | 38 +++++++++++++++++------- apps/openmw/mwgui/companionitemmodel.hpp | 2 ++ apps/openmw/mwgui/companionwindow.cpp | 29 ++++++++++++------ apps/openmw/mwmechanics/npcstats.cpp | 13 -------- apps/openmw/mwmechanics/npcstats.hpp | 6 ---- apps/openmw/mwscript/locals.cpp | 15 ++++++++++ apps/openmw/mwscript/locals.hpp | 8 +++-- components/esm/npcstats.cpp | 13 ++++---- components/esm/npcstats.hpp | 1 - 9 files changed, 76 insertions(+), 49 deletions(-) diff --git a/apps/openmw/mwgui/companionitemmodel.cpp b/apps/openmw/mwgui/companionitemmodel.cpp index b8be9dcb82..983ef50173 100644 --- a/apps/openmw/mwgui/companionitemmodel.cpp +++ b/apps/openmw/mwgui/companionitemmodel.cpp @@ -3,6 +3,22 @@ #include "../mwmechanics/npcstats.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 { 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) { - if (mActor.getClass().isNpc()) - { - MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor); - stats.modifyProfit(item.mBase.getClass().getValue(item.mBase) * count); - } + if (hasProfit(mActor)) + modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count); return InventoryItemModel::copyItem(item, count, setNewOwner); } void CompanionItemModel::removeItem (const ItemStack& item, size_t count) { - if (mActor.getClass().isNpc()) - { - MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor); - stats.modifyProfit(-item.mBase.getClass().getValue(item.mBase) * count); - } + if (hasProfit(mActor)) + modifyProfit(mActor, -item.mBase.getClass().getValue(item.mBase) * 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"); + } } diff --git a/apps/openmw/mwgui/companionitemmodel.hpp b/apps/openmw/mwgui/companionitemmodel.hpp index 172fa9508a..4c77ee12fa 100644 --- a/apps/openmw/mwgui/companionitemmodel.hpp +++ b/apps/openmw/mwgui/companionitemmodel.hpp @@ -15,6 +15,8 @@ namespace MWGui virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner); virtual void removeItem (const ItemStack& item, size_t count); + + bool hasProfit(const MWWorld::Ptr& actor); }; } diff --git a/apps/openmw/mwgui/companionwindow.cpp b/apps/openmw/mwgui/companionwindow.cpp index 53b14691b5..8f709ec8da 100644 --- a/apps/openmw/mwgui/companionwindow.cpp +++ b/apps/openmw/mwgui/companionwindow.cpp @@ -17,6 +17,21 @@ #include "draganddrop.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 { @@ -116,13 +131,12 @@ void CompanionWindow::updateEncumbranceBar() float encumbrance = mPtr.getClass().getEncumbrance(mPtr); mEncumbranceBar->setValue(encumbrance, capacity); - if (mPtr.getTypeName() != typeid(ESM::NPC).name()) - mProfitLabel->setCaption(""); - else + if (mModel && mModel->hasProfit(mPtr)) { - MWMechanics::NpcStats& stats = mPtr.getClass().getNpcStats(mPtr); - mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(stats.getProfit())); + mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(getProfit(mPtr))); } + else + mProfitLabel->setCaption(""); } void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) @@ -132,7 +146,7 @@ void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) 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 buttons; buttons.push_back("#{sCompanionWarningButtonOne}"); @@ -148,9 +162,6 @@ void CompanionWindow::onMessageBoxButtonClicked(int button) { if (button == 0) { - mPtr.getRefData().getLocals().setVarByInt(mPtr.getClass().getScript(mPtr), - "minimumprofit", mPtr.getClass().getNpcStats(mPtr).getProfit()); - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); // Important for Calvus' contract script to work properly MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue); diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index c3a4d23127..c517b4df8a 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -31,7 +31,6 @@ MWMechanics::NpcStats::NpcStats() , mReputation(0) , mCrimeId(-1) , mWerewolfKills (0) -, mProfit(0) , mTimeToStartDrowning(20.0) { mSkillIncreases.resize (ESM::Attribute::Length, 0); @@ -448,16 +447,6 @@ void MWMechanics::NpcStats::addWerewolfKill() ++mWerewolfKills; } -int MWMechanics::NpcStats::getProfit() const -{ - return mProfit; -} - -void MWMechanics::NpcStats::modifyProfit(int diff) -{ - mProfit += diff; -} - float MWMechanics::NpcStats::getTimeToStartDrowning() const { return mTimeToStartDrowning; @@ -501,7 +490,6 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const state.mReputation = mReputation; state.mWerewolfKills = mWerewolfKills; - state.mProfit = mProfit; state.mLevelProgress = mLevelProgress; for (int i=0; igetLocals(script); + int index = locals.getIndex(var); + return (index != -1); + } + catch (const Compiler::SourceException&) + { + return false; + } + } + int Locals::getIntVar(const std::string &script, const std::string &var) { const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp index 9fa4214acc..bd95835ac1 100644 --- a/apps/openmw/mwscript/locals.hpp +++ b/apps/openmw/mwscript/locals.hpp @@ -24,11 +24,15 @@ namespace MWScript bool isEmpty() const; void configure (const ESM::Script& script); + /// @note var needs to be in lowercase bool setVarByInt(const std::string& script, const std::string& var, int val); - int getIntVar (const std::string& script, const std::string& var); - ///< if var does not exist, returns 0 + + bool hasVar(const std::string& script, const std::string& var); + + /// if var does not exist, returns 0 /// @note var needs to be in lowercase + int getIntVar (const std::string& script, const std::string& var); void write (ESM::Locals& locals, const std::string& script) const; diff --git a/components/esm/npcstats.cpp b/components/esm/npcstats.cpp index e305ddab09..cc1d6b3ddc 100644 --- a/components/esm/npcstats.cpp +++ b/components/esm/npcstats.cpp @@ -57,12 +57,13 @@ void ESM::NpcStats::load (ESMReader &esm) mWerewolfKills = 0; esm.getHNOT (mWerewolfKills, "WKIL"); - mProfit = 0; - esm.getHNOT (mProfit, "PROF"); + // No longer used + if (esm.isNextSub("PROF")) + esm.skipHSub(); // int profit // No longer used. Now part of CreatureStats. - float attackStrength = 0; - esm.getHNOT (attackStrength, "ASTR"); + if (esm.isNextSub("ASTR")) + esm.skipHSub(); // attackStrength mLevelProgress = 0; esm.getHNOT (mLevelProgress, "LPRO"); @@ -132,9 +133,6 @@ void ESM::NpcStats::save (ESMWriter &esm) const if (mWerewolfKills) esm.writeHNT ("WKIL", mWerewolfKills); - if (mProfit) - esm.writeHNT ("PROF", mProfit); - if (mLevelProgress) esm.writeHNT ("LPRO", mLevelProgress); @@ -158,7 +156,6 @@ void ESM::NpcStats::blank() mBounty = 0; mReputation = 0; mWerewolfKills = 0; - mProfit = 0; mLevelProgress = 0; for (int i=0; i<8; ++i) mSkillIncrease[i] = 0; diff --git a/components/esm/npcstats.hpp b/components/esm/npcstats.hpp index 1eb1a3d1af..0138ab2098 100644 --- a/components/esm/npcstats.hpp +++ b/components/esm/npcstats.hpp @@ -40,7 +40,6 @@ namespace ESM int mBounty; int mReputation; int mWerewolfKills; - int mProfit; int mLevelProgress; int mSkillIncrease[8]; std::vector mUsedIds; // lower case IDs From 0497a40d091c6eb2228022f91cecacaf93a47e0b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 15:24:22 +0100 Subject: [PATCH 17/35] Fix incorrect sound for thrown weapons --- apps/openmw/mwclass/weapon.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 122c8eeaef..d1a44fd0e3 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -189,9 +189,8 @@ namespace MWClass { return std::string("Item Weapon Longblade Up"); } - // Shortblade and thrown weapons - // thrown weapons may not be entirely correct - if (type == 0 || type == 11) + // Shortblade + if (type == 0) { return std::string("Item Weapon Shortblade Up"); } @@ -200,8 +199,8 @@ namespace MWClass { return std::string("Item Weapon Spear Up"); } - // Blunts and Axes - if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8) + // Blunts, Axes and Thrown weapons + if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11) { return std::string("Item Weapon Blunt Up"); } @@ -235,9 +234,8 @@ namespace MWClass { return std::string("Item Weapon Longblade Down"); } - // Shortblade and thrown weapons - // thrown weapons may not be entirely correct - if (type == 0 || type == 11) + // Shortblade + if (type == 0) { return std::string("Item Weapon Shortblade Down"); } @@ -246,8 +244,8 @@ namespace MWClass { return std::string("Item Weapon Spear Down"); } - // Blunts and Axes - if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8) + // Blunts, Axes and Thrown weapons + if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11) { return std::string("Item Weapon Blunt Down"); } From 326eaea8a6d86fb1ec565eee16242667b646c63d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 15:28:57 +0100 Subject: [PATCH 18/35] Add missing sound for drawing throwing weapons (Fixes #2308) --- apps/openmw/mwrender/weaponanimation.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 8af4d637a2..d75c0ce5a3 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -7,6 +7,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" @@ -45,7 +46,15 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor) MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); MWWorld::ContainerStoreIterator weaponSlot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); if (weaponSlot != inv.end() && weaponSlot->get()->mBase->mData.mType == ESM::Weapon::MarksmanThrown) + { + std::string soundid = weaponSlot->getClass().getUpSoundId(*weaponSlot); + if(!soundid.empty()) + { + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->playSound3D(actor, soundid, 1.0f, 1.0f); + } showWeapon(true); + } else { NifOgre::ObjectScenePtr weapon = getWeapon(); From bdcc3a403611ada58c9a396b99160bd98a3c892c Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 15:37:16 +0100 Subject: [PATCH 19/35] Add missing swish sound for thrown weapons --- apps/openmw/mwmechanics/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 8d438c7031..91b3757146 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1126,7 +1126,7 @@ bool CharacterController::updateWeaponState() attackStrength = std::min(1.f, 0.1f + std::rand() / float(RAND_MAX)); } - if(mAttackType != "shoot") + if(mWeaponType != WeapType_Crossbow && mWeaponType != WeapType_BowAndArrow) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); From c093e284d9ac9759e082d1590e2d91b49ae627fe Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 16:26:15 +0100 Subject: [PATCH 20/35] Delegate cleanup --- apps/openmw/mwgui/hud.cpp | 4 ++++ apps/openmw/mwgui/windowmanagerimp.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index b4312dc401..13a5c559c1 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -182,6 +182,10 @@ namespace MWGui HUD::~HUD() { + mMainWidget->eventMouseLostFocus.clear(); + mMainWidget->eventMouseMove.clear(); + mMainWidget->eventMouseButtonClick.clear(); + delete mSpellIcons; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8c397b9f1a..975ee6c29f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -352,8 +352,11 @@ namespace MWGui WindowManager::~WindowManager() { + MyGUI::LanguageManager::getInstance().eventRequestTag.clear(); MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear(); MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear(); + MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear(); + MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear(); delete mConsole; delete mMessageBoxManager; From 54e79c8c98a092c2da7f7febad28c2557354fc98 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 16:26:34 +0100 Subject: [PATCH 21/35] Use mouse pressed event for pin button instead of mouse click --- apps/openmw/mwgui/windowpinnablebase.cpp | 9 ++++++--- apps/openmw/mwgui/windowpinnablebase.hpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/windowpinnablebase.cpp b/apps/openmw/mwgui/windowpinnablebase.cpp index 7307ece2d6..a6984b5a48 100644 --- a/apps/openmw/mwgui/windowpinnablebase.cpp +++ b/apps/openmw/mwgui/windowpinnablebase.cpp @@ -12,7 +12,7 @@ namespace MWGui ExposedWindow* window = mMainWidget->castType(); mPinButton = window->getSkinWidget ("Button"); - mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked); + mPinButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonPressed); MyGUI::Button* button = NULL; MyGUI::VectorWidgetPtr widgets = window->getSkinWidgetsByName("Action"); @@ -26,8 +26,11 @@ namespace MWGui button->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &WindowPinnableBase::onDoubleClick); } - void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender) + void WindowPinnableBase::onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id) { + if (id != MyGUI::MouseButton::Left) + return; + mPinned = !mPinned; if (mPinned) @@ -46,7 +49,7 @@ namespace MWGui void WindowPinnableBase::setPinned(bool pinned) { if (pinned != mPinned) - onPinButtonClicked(mPinButton); + onPinButtonPressed(mPinButton, 0, 0, MyGUI::MouseButton::Left); } void WindowPinnableBase::setPinButtonVisible(bool visible) diff --git a/apps/openmw/mwgui/windowpinnablebase.hpp b/apps/openmw/mwgui/windowpinnablebase.hpp index 8b7bbefaf9..c085bebf2e 100644 --- a/apps/openmw/mwgui/windowpinnablebase.hpp +++ b/apps/openmw/mwgui/windowpinnablebase.hpp @@ -16,7 +16,7 @@ namespace MWGui void setPinButtonVisible(bool visible); private: - void onPinButtonClicked(MyGUI::Widget* _sender); + void onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id); void onDoubleClick(MyGUI::Widget* _sender); protected: From efbbe73c2a5a6459330f3e1ce5ce91ca56e03aa1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 31 Jan 2015 16:28:03 +0100 Subject: [PATCH 22/35] Fix pinned window caption --- files/mygui/openmw_resources.xml | 15 +++++++++++++++ files/mygui/openmw_windows.skin.xml | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/files/mygui/openmw_resources.xml b/files/mygui/openmw_resources.xml index 7d7ba07b6e..423281a621 100644 --- a/files/mygui/openmw_resources.xml +++ b/files/mygui/openmw_resources.xml @@ -137,4 +137,19 @@ + + + + + + + + + + + + + + diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index ebbc77bef6..2854401c89 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -804,7 +804,7 @@ - +