From c59513c30c8a6815b04b926b6e626d7a893a33f7 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 1 Dec 2018 17:12:27 +0300 Subject: [PATCH 01/52] Revert unnecessary case changes for fallback records --- apps/openmw/mwworld/store.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index ec9965a6c..70f8cf44f 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -1059,11 +1059,11 @@ namespace MWWorld { // Load default marker definitions, if game files do not have them for some reason std::pair markers[] = { - std::make_pair("DivineMarker", "marker_divine.nif"), - std::make_pair("DoorMarker", "marker_arrow.nif"), - std::make_pair("NorthMarker", "marker_north.nif"), - std::make_pair("TempleMarker", "marker_temple.nif"), - std::make_pair("TravelMarker", "marker_travel.nif") + std::make_pair("divinemarker", "marker_divine.nif"), + std::make_pair("doormarker", "marker_arrow.nif"), + std::make_pair("northmarker", "marker_north.nif"), + std::make_pair("templemarker", "marker_temple.nif"), + std::make_pair("travelmarker", "marker_travel.nif") }; for (const std::pair marker : markers) @@ -1085,7 +1085,7 @@ namespace MWWorld { // Load default Door type marker definitions std::pair markers[] = { - std::make_pair("PrisonMarker", "marker_prison.nif") + std::make_pair("prisonmarker", "marker_prison.nif") }; for (const std::pair marker : markers) From 7b5932a49da34c156d013b0e65319bb0050a362a Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 1 Dec 2018 18:14:51 +0300 Subject: [PATCH 02/52] Add Invert X Axis option (feature #3610) --- CHANGELOG.md | 1 + apps/openmw/mwinput/inputmanagerimp.cpp | 8 ++++++-- apps/openmw/mwinput/inputmanagerimp.hpp | 1 + .../reference/modding/settings/input.rst | 14 ++++++++++++++ files/mygui/openmw_settings_window.layout | 18 ++++++++++++++---- files/settings-default.cfg | 3 +++ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f44e83b3..a791e0d40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Bug #4723: ResetActors command works incorrectly Feature #2229: Improve pathfinding AI Feature #3442: Default values for fallbacks from ini file + Feature #3610: Option to invert X axis Feature #4673: Weapon sheathing Task #4686: Upgrade media decoder to a more current FFmpeg API diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 0d017ba90..d8b4fd831 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -52,6 +52,7 @@ namespace MWInput , mUserFile(userFile) , mDragDrop(false) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) + , mInvertX (Settings::Manager::getBool("invert x axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mControlsDisabled(false) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) @@ -467,7 +468,7 @@ namespace MWInput float rot[3]; rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; rot[1] = 0.0f; - rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f); + rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); // Only actually turn player when we're not in vanity mode if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot)) @@ -646,6 +647,9 @@ namespace MWInput for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { + if (it->first == "Input" && it->second == "invert x axis") + mInvertX = Settings::Manager::getBool("invert x axis", "Input"); + if (it->first == "Input" && it->second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); @@ -827,7 +831,7 @@ namespace MWInput { resetIdleTime(); - float x = arg.xrel * mCameraSensitivity * (1.0f/256.f); + float x = arg.xrel * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; float rot[3]; diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index bc62ef7dc..361babec4 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -175,6 +175,7 @@ namespace MWInput bool mGrabCursor; + bool mInvertX; bool mInvertY; bool mControlsDisabled; diff --git a/docs/source/reference/modding/settings/input.rst b/docs/source/reference/modding/settings/input.rst index 36c8fa41a..321c28afd 100644 --- a/docs/source/reference/modding/settings/input.rst +++ b/docs/source/reference/modding/settings/input.rst @@ -94,6 +94,20 @@ meaning that it should remain set at 1.0 unless the player desires to have diffe This setting can only be configured by editing the settings configuration file. +invert x axis +------------- + +:Type: boolean +:Range: True/False +:Default: False + + +Invert the horizontal axis while not in GUI mode. +If this setting is true, moving the mouse to the left will cause the view to rotate counter-clockwise, +while moving it to the right will cause the view to rotate clockwise. This setting does not affect cursor movement in GUI mode. + +This setting can be toggled in game with the Invert X Axis button in the Controls panel of the Options menu. + invert y axis ------------- diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 3c2664857..8062980ff 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -214,6 +214,16 @@ + + + + + + + + + + @@ -223,10 +233,10 @@ - + - + @@ -236,11 +246,11 @@ - + - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index dad915cbb..71a93d1a2 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -333,6 +333,9 @@ camera sensitivity = 1.0 # (>0.0, Because it's a multiplier values should be near 1.0) camera y multiplier = 1.0 +# Invert the horizontal axis while not in GUI mode. +invert x axis = false + # Invert the vertical axis while not in GUI mode. invert y axis = false From 9de6c630f2eda9ab6111179511fd014ab49eb3fe Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Sat, 1 Dec 2018 21:27:43 +0100 Subject: [PATCH 03/52] fix moc achieving to reach unparsable boost code --- apps/launcher/maindialog.hpp | 4 ++-- apps/opencs/view/doc/filedialog.hpp | 4 ++++ apps/opencs/view/render/terraintexturemode.hpp | 2 ++ apps/opencs/view/tools/merge.hpp | 2 ++ apps/opencs/view/widget/scenetooltexturebrush.hpp | 2 ++ apps/opencs/view/world/creator.hpp | 2 ++ apps/opencs/view/world/dialoguesubview.hpp | 2 ++ apps/opencs/view/world/util.hpp | 3 +++ apps/wizard/mainwizard.hpp | 3 ++- 9 files changed, 21 insertions(+), 3 deletions(-) diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index 6d3871b7c..75fe5ab89 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -6,7 +6,7 @@ #ifndef Q_MOC_RUN #include -#endif + #include @@ -14,7 +14,7 @@ #include #include - +#endif #include "ui_mainwindow.h" class QListWidgetItem; diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 69acfac3d..bec2c6869 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,6 +4,8 @@ #include #include +#ifndef Q_MOC_RUN + #include #include "adjusterwidget.hpp" @@ -12,6 +14,8 @@ Q_DECLARE_METATYPE (boost::filesystem::path) #endif +#endif + #include "ui_filedialog.h" namespace ContentSelectorView diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index e1538e243..5184f0f73 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -8,6 +8,7 @@ #include #include +#ifndef Q_MOC_RUN #include "../../model/world/data.hpp" #include "../../model/world/land.hpp" @@ -15,6 +16,7 @@ #include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/landtexture.hpp" +#endif namespace CSVWidget { diff --git a/apps/opencs/view/tools/merge.hpp b/apps/opencs/view/tools/merge.hpp index d4ed7e34b..e332b799f 100644 --- a/apps/opencs/view/tools/merge.hpp +++ b/apps/opencs/view/tools/merge.hpp @@ -3,7 +3,9 @@ #include +#ifndef Q_MOC_RUN #include +#endif class QPushButton; class QListWidget; diff --git a/apps/opencs/view/widget/scenetooltexturebrush.hpp b/apps/opencs/view/widget/scenetooltexturebrush.hpp index 4669f432e..80e9a9382 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.hpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.hpp @@ -14,9 +14,11 @@ #include #include +#ifndef Q_MOC_RUN #include "scenetool.hpp" #include "../../model/doc/document.hpp" +#endif class QTableWidget; diff --git a/apps/opencs/view/world/creator.hpp b/apps/opencs/view/world/creator.hpp index 0020fd3c8..f50333e4e 100644 --- a/apps/opencs/view/world/creator.hpp +++ b/apps/opencs/view/world/creator.hpp @@ -5,10 +5,12 @@ #include +#ifndef Q_MOC_RUN #include "../../model/doc/document.hpp" #include "../../model/world/scope.hpp" #include "../../model/world/universalid.hpp" +#endif namespace CSMDoc { diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index cbcb9b210..52d3d8da5 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -8,11 +8,13 @@ #include #include +#ifndef Q_MOC_RUN #include "../doc/subview.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/commanddispatcher.hpp" #include "../../model/world/universalid.hpp" +#endif class QDataWidgetMapper; class QSize; diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 766d72958..ebd5c0ad7 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -6,8 +6,11 @@ #include #include + +#ifndef Q_MOC_RUN #include "../../model/world/columnbase.hpp" #include "../../model/doc/document.hpp" +#endif class QUndoStack; diff --git a/apps/wizard/mainwizard.hpp b/apps/wizard/mainwizard.hpp index 7f6e48a87..a05013d98 100644 --- a/apps/wizard/mainwizard.hpp +++ b/apps/wizard/mainwizard.hpp @@ -9,9 +9,10 @@ #ifndef Q_MOC_RUN #include -#endif + #include #include +#endif namespace Wizard { From 832870dc798e78787b60a1f4b7c96cf67de91c12 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 2 Dec 2018 15:48:25 +0300 Subject: [PATCH 04/52] esmtool cleanup --- apps/esmtool/esmtool.cpp | 46 +++--- apps/esmtool/labels.cpp | 24 ++-- apps/esmtool/record.cpp | 299 ++++++++++++++++++--------------------- 3 files changed, 168 insertions(+), 201 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 699ff855c..4734e1c56 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -406,13 +406,10 @@ int load(Arguments& info) } catch(std::exception &e) { std::cout << "\nERROR:\n\n " << e.what() << std::endl; - typedef std::deque RecStore; - RecStore &store = info.data.mRecords; - for (RecStore::iterator it = store.begin(); it != store.end(); ++it) - { - delete *it; - } - store.clear(); + for (const EsmTool::RecordBase* record : info.data.mRecords) + delete record; + + info.data.mRecords.clear(); return 1; } @@ -444,15 +441,12 @@ int clone(Arguments& info) std::cout << "Loaded " << recordCount << " records:" << std::endl << std::endl; int i = 0; - typedef std::map Stats; - Stats &stats = info.data.mRecordStats; - for (Stats::iterator it = stats.begin(); it != stats.end(); ++it) + for (std::pair stat : info.data.mRecordStats) { ESM::NAME name; - name.intval = it->first; - int amount = it->second; + name.intval = stat.first; + int amount = stat.second; std::cout << std::setw(digitCount) << amount << " " << name.toString() << " "; - if (++i % 3 == 0) std::cout << std::endl; } @@ -470,18 +464,18 @@ int clone(Arguments& info) esm.setVersion(info.data.version); esm.setRecordCount (recordCount); - for (std::vector::iterator it = info.data.masters.begin(); it != info.data.masters.end(); ++it) - esm.addMaster(it->name, it->size); + for (const ESM::Header::MasterData &master : info.data.masters) + esm.addMaster(master.name, master.size); std::fstream save(info.outname.c_str(), std::fstream::out | std::fstream::binary); esm.save(save); int saved = 0; - typedef std::deque Records; - Records &records = info.data.mRecords; - for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it) + for (EsmTool::RecordBase* record : info.data.mRecords) { - EsmTool::RecordBase *record = *it; + if (i <= 0) + break; + const ESM::NAME& typeName = record->getType(); esm.startRecord(typeName.toString(), record->getFlags()); @@ -489,13 +483,10 @@ int clone(Arguments& info) record->save(esm); if (typeName.intval == ESM::REC_CELL) { ESM::Cell *ptr = &record->cast()->get(); - if (!info.data.mCellRefs[ptr].empty()) { - typedef std::deque > RefList; - RefList &refs = info.data.mCellRefs[ptr]; - for (RefList::iterator refIt = refs.begin(); refIt != refs.end(); ++refIt) - { - refIt->first.save(esm, refIt->second); - } + if (!info.data.mCellRefs[ptr].empty()) + { + for (std::pair &ref : info.data.mCellRefs[ptr]) + ref.first.save(esm, ref.second); } } @@ -558,8 +549,5 @@ int comp(Arguments& info) return 1; } - - - return 0; } diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index ea7b50129..bee2a3565 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -651,7 +651,7 @@ std::string ruleFunction(int idx) std::string bodyPartFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable "; @@ -665,7 +665,7 @@ std::string bodyPartFlags(int flags) std::string cellFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::Cell::HasWater) properties += "HasWater "; if (flags & ESM::Cell::Interior) properties += "Interior "; @@ -686,7 +686,7 @@ std::string cellFlags(int flags) std::string containerFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::Container::Unknown) properties += "Unknown "; if (flags & ESM::Container::Organic) properties += "Organic "; @@ -702,7 +702,7 @@ std::string containerFlags(int flags) std::string creatureFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::Creature::None) properties += "All "; if (flags & ESM::Creature::Walks) properties += "Walks "; @@ -732,7 +732,7 @@ std::string creatureFlags(int flags) std::string landFlags(int flags) { - std::string properties = ""; + std::string properties; // The ESM component says that this first four bits are used, but // only the first three bits are used as far as I can tell. // There's also no enumeration of the bit in the ESM component. @@ -747,7 +747,7 @@ std::string landFlags(int flags) std::string itemListFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels "; if (flags & ESM::ItemLevList::Each) properties += "Each "; @@ -761,7 +761,7 @@ std::string itemListFlags(int flags) std::string creatureListFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels "; int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels); @@ -800,7 +800,7 @@ std::string lightFlags(int flags) std::string magicEffectFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute "; if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill "; @@ -826,7 +826,7 @@ std::string magicEffectFlags(int flags) std::string npcFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; // Mythicmods and the ESM component differ. Mythicmods says // 0x8=None and 0x10=AutoCalc, while our code previously defined @@ -860,7 +860,7 @@ std::string npcFlags(int flags) std::string raceFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; // All races have the playable flag set in Bethesda files. if (flags & ESM::Race::Playable) properties += "Playable "; @@ -875,7 +875,7 @@ std::string raceFlags(int flags) std::string spellFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc "; if (flags & ESM::Spell::F_PCStart) properties += "PCStart "; @@ -891,7 +891,7 @@ std::string spellFlags(int flags) std::string weaponFlags(int flags) { - std::string properties = ""; + std::string properties; if (flags == 0) properties += "[None] "; // The interpretation of the flags are still unclear to me. // Apparently you can't be Silver without being Magical? Many of diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 089a25c93..6cd32077c 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -49,7 +49,7 @@ void printAIPackage(ESM::AIPackage p) std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl; } - if (p.mCellName != "") + if (!p.mCellName.empty()) std::cout << " Cell Name: " << p.mCellName << std::endl; } @@ -130,43 +130,41 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss) void printEffectList(ESM::EffectList effects) { int i = 0; - std::vector::iterator eit; - for (eit = effects.mList.begin(); eit != effects.mList.end(); ++eit) - { - std::cout << " Effect[" << i << "]: " << magicEffectLabel(eit->mEffectID) - << " (" << eit->mEffectID << ")" << std::endl; - if (eit->mSkill != -1) - std::cout << " Skill: " << skillLabel(eit->mSkill) - << " (" << (int)eit->mSkill << ")" << std::endl; - if (eit->mAttribute != -1) - std::cout << " Attribute: " << attributeLabel(eit->mAttribute) - << " (" << (int)eit->mAttribute << ")" << std::endl; - std::cout << " Range: " << rangeTypeLabel(eit->mRange) - << " (" << eit->mRange << ")" << std::endl; + for (const ESM::ENAMstruct& effect : effects.mList) + { + std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mEffectID) + << " (" << effect.mEffectID << ")" << std::endl; + if (effect.mSkill != -1) + std::cout << " Skill: " << skillLabel(effect.mSkill) + << " (" << (int)effect.mSkill << ")" << std::endl; + if (effect.mAttribute != -1) + std::cout << " Attribute: " << attributeLabel(effect.mAttribute) + << " (" << (int)effect.mAttribute << ")" << std::endl; + std::cout << " Range: " << rangeTypeLabel(effect.mRange) + << " (" << effect.mRange << ")" << std::endl; // Area is always zero if range type is "Self" - if (eit->mRange != ESM::RT_Self) - std::cout << " Area: " << eit->mArea << std::endl; - std::cout << " Duration: " << eit->mDuration << std::endl; - std::cout << " Magnitude: " << eit->mMagnMin << "-" << eit->mMagnMax << std::endl; + if (effect.mRange != ESM::RT_Self) + std::cout << " Area: " << effect.mArea << std::endl; + std::cout << " Duration: " << effect.mDuration << std::endl; + std::cout << " Magnitude: " << effect.mMagnMin << "-" << effect.mMagnMax << std::endl; i++; } } void printTransport(const std::vector& transport) { - std::vector::const_iterator dit; - for (dit = transport.begin(); dit != transport.end(); ++dit) + for (const ESM::Transport::Dest& dest : transport) { std::cout << " Destination Position: " - << boost::format("%12.3f") % dit->mPos.pos[0] << "," - << boost::format("%12.3f") % dit->mPos.pos[1] << "," - << boost::format("%12.3f") % dit->mPos.pos[2] << ")" << std::endl; + << boost::format("%12.3f") % dest.mPos.pos[0] << "," + << boost::format("%12.3f") % dest.mPos.pos[1] << "," + << boost::format("%12.3f") % dest.mPos.pos[2] << ")" << std::endl; std::cout << " Destination Rotation: " - << boost::format("%9.6f") % dit->mPos.rot[0] << "," - << boost::format("%9.6f") % dit->mPos.rot[1] << "," - << boost::format("%9.6f") % dit->mPos.rot[2] << ")" << std::endl; - if (dit->mCellName != "") - std::cout << " Destination Cell: " << dit->mCellName << std::endl; + << boost::format("%9.6f") % dest.mPos.rot[0] << "," + << boost::format("%9.6f") % dest.mPos.rot[1] << "," + << boost::format("%9.6f") % dest.mPos.rot[2] << ")" << std::endl; + if (!dest.mCellName.empty()) + std::cout << " Destination Cell: " << dest.mCellName << std::endl; } } @@ -414,7 +412,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -429,9 +427,9 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; - if (mData.mEnchant != "") + if (!mData.mEnchant.empty()) std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << armorTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; @@ -440,15 +438,15 @@ void Record::print() std::cout << " Health: " << mData.mData.mHealth << std::endl; std::cout << " Armor: " << mData.mData.mArmor << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - std::vector::iterator pit; - for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit) + for (const ESM::PartReference &part : mData.mParts.mParts) { - std::cout << " Body Part: " << bodyPartLabel(pit->mPart) - << " (" << (int)(pit->mPart) << ")" << std::endl; - std::cout << " Male Name: " << pit->mMale << std::endl; - if (pit->mFemale != "") - std::cout << " Female Name: " << pit->mFemale << std::endl; + std::cout << " Body Part: " << bodyPartLabel(part.mPart) + << " (" << (int)(part.mPart) << ")" << std::endl; + std::cout << " Male Name: " << part.mMale << std::endl; + if (!part.mFemale.empty()) + std::cout << " Female Name: " << part.mFemale << std::endl; } + std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -487,9 +485,9 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; - if (mData.mEnchant != "") + if (!mData.mEnchant.empty()) std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -516,9 +514,8 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; - std::vector::iterator pit; - for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit) - std::cout << " Power: " << *pit << std::endl; + for (const std::string &power : mData.mPowers.mList) + std::cout << " Power: " << power << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -526,9 +523,9 @@ template<> void Record::print() { // None of the cells have names... - if (mData.mName != "") + if (!mData.mName.empty()) std::cout << " Name: " << mData.mName << std::endl; - if (mData.mRegion != "") + if (!mData.mRegion.empty()) std::cout << " Region: " << mData.mRegion << std::endl; std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; @@ -580,23 +577,22 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; - if (mData.mEnchant != "") + if (!mData.mEnchant.empty()) std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - std::vector::iterator pit; - for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit) + for (const ESM::PartReference &part : mData.mParts.mParts) { - std::cout << " Body Part: " << bodyPartLabel(pit->mPart) - << " (" << (int)(pit->mPart) << ")" << std::endl; - std::cout << " Male Name: " << pit->mMale << std::endl; - if (pit->mFemale != "") - std::cout << " Female Name: " << pit->mFemale << std::endl; + std::cout << " Body Part: " << bodyPartLabel(part.mPart) + << " (" << (int)(part.mPart) << ")" << std::endl; + std::cout << " Male Name: " << part.mMale << std::endl; + if (!part.mFemale.empty()) + std::cout << " Female Name: " << part.mFemale << std::endl; } std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -606,14 +602,13 @@ void Record::print() { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl; - std::vector::iterator cit; - for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + for (const ESM::ContItem &item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount + << " Item: " << item.mItem.toString() << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -656,14 +651,12 @@ void Record::print() << "-" << mData.mData.mAttack[5] << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl; - std::vector::iterator cit; - for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + for (const ESM::ContItem &item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount + << " Item: " << item.mItem.toString() << std::endl; - std::vector::iterator sit; - for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) - std::cout << " Spell: " << *sit << std::endl; + for (const std::string &spell : mData.mSpells.mList) + std::cout << " Spell: " << spell << std::endl; printTransport(mData.getTransport()); @@ -678,9 +671,8 @@ void Record::print() std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; - std::vector::iterator pit; - for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit) - printAIPackage(*pit); + for (const ESM::AIPackage &package : mData.mAiPackage.mList) + printAIPackage(package); std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -693,9 +685,8 @@ void Record::print() // Sadly, there are no DialInfos, because the loader dumps as it // loads, rather than loading and then dumping. :-( Anyone mind if // I change this? - ESM::Dialogue::InfoContainer::iterator iit; - for (iit = mData.mInfo.begin(); iit != mData.mInfo.end(); ++iit) - std::cout << "INFO!" << iit->mId << std::endl; + for (const ESM::DialInfo &info : mData.mInfo) + std::cout << "INFO!" << info.mId << std::endl; } template<> @@ -735,7 +726,7 @@ void Record::print() std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) << " (" << mData.mData.mSkills[i] << ")" << std::endl; for (int i = 0; i != 10; i++) - if (mData.mRanks[i] != "") + if (!mData.mRanks[i].empty()) { std::cout << " Rank: " << mData.mRanks[i] << std::endl; std::cout << " Attribute1 Requirement: " @@ -749,9 +740,8 @@ void Record::print() std::cout << " Faction Reaction: " << mData.mData.mRankData[i].mFactReaction << std::endl; } - std::map::iterator rit; - for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit) - std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl; + for (const std::pair &reaction : mData.mReactions) + std::cout << " Reaction: " << reaction.second << " = " << reaction.first << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -772,34 +762,34 @@ template<> void Record::print() { std::cout << " Id: " << mData.mId << std::endl; - if (mData.mPrev != "") + if (!mData.mPrev.empty()) std::cout << " Previous ID: " << mData.mPrev << std::endl; - if (mData.mNext != "") + if (!mData.mNext.empty()) std::cout << " Next ID: " << mData.mNext << std::endl; std::cout << " Text: " << mData.mResponse << std::endl; - if (mData.mActor != "") + if (!mData.mActor.empty()) std::cout << " Actor: " << mData.mActor << std::endl; - if (mData.mRace != "") + if (!mData.mRace.empty()) std::cout << " Race: " << mData.mRace << std::endl; - if (mData.mClass != "") + if (!mData.mClass.empty()) std::cout << " Class: " << mData.mClass << std::endl; std::cout << " Factionless: " << mData.mFactionLess << std::endl; - if (mData.mFaction != "") + if (!mData.mFaction.empty()) std::cout << " NPC Faction: " << mData.mFaction << std::endl; if (mData.mData.mRank != -1) std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; - if (mData.mPcFaction != "") + if (!mData.mPcFaction.empty()) std::cout << " PC Faction: " << mData.mPcFaction << std::endl; // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) if (mData.mData.mPCrank != -1) std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; - if (mData.mCell != "") + if (!mData.mCell.empty()) std::cout << " Cell: " << mData.mCell << std::endl; if (mData.mData.mDisposition > 0) std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl; if (mData.mData.mGender != ESM::DialInfo::NA) std::cout << " Gender: " << mData.mData.mGender << std::endl; - if (mData.mSound != "") + if (!mData.mSound.empty()) std::cout << " Sound File: " << mData.mSound << std::endl; @@ -808,11 +798,10 @@ void Record::print() std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; - std::vector::iterator sit; - for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); ++sit) - std::cout << " Select Rule: " << ruleString(*sit) << std::endl; + for (const ESM::DialInfo::SelectStruct &rule : mData.mSelects) + std::cout << " Select Rule: " << ruleString(rule) << std::endl; - if (mData.mResultScript != "") + if (!mData.mResultScript.empty()) { if (mPrintPlain) { @@ -835,7 +824,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -877,10 +866,9 @@ void Record::print() std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; - std::vector::iterator iit; - for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit) - std::cout << " Creature: Level: " << iit->mLevel - << " Creature: " << iit->mId << std::endl; + for (const ESM::LevelledListBase::LevelItem &item : mData.mList) + std::cout << " Creature: Level: " << item.mLevel + << " Creature: " << item.mId << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -890,23 +878,22 @@ void Record::print() std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl; - std::vector::iterator iit; - for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit) - std::cout << " Inventory: Level: " << iit->mLevel - << " Item: " << iit->mId << std::endl; + for (const ESM::LevelledListBase::LevelItem &item : mData.mList) + std::cout << " Inventory: Level: " << item.mLevel + << " Item: " << item.mId << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } template<> void Record::print() { - if (mData.mName != "") + if (!mData.mName.empty()) std::cout << " Name: " << mData.mName << std::endl; - if (mData.mModel != "") + if (!mData.mModel.empty()) std::cout << " Model: " << mData.mModel << std::endl; - if (mData.mIcon != "") + if (!mData.mIcon.empty()) std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; @@ -924,7 +911,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -939,7 +926,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -954,7 +941,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -981,21 +968,21 @@ void Record::print() std::cout << " Icon: " << mData.mIcon << std::endl; std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; std::cout << " Particle Texture: " << mData.mParticle << std::endl; - if (mData.mCasting != "") + if (!mData.mCasting.empty()) std::cout << " Casting Static: " << mData.mCasting << std::endl; - if (mData.mCastSound != "") + if (!mData.mCastSound.empty()) std::cout << " Casting Sound: " << mData.mCastSound << std::endl; - if (mData.mBolt != "") + if (!mData.mBolt.empty()) std::cout << " Bolt Static: " << mData.mBolt << std::endl; - if (mData.mBoltSound != "") + if (!mData.mBoltSound.empty()) std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; - if (mData.mHit != "") + if (!mData.mHit.empty()) std::cout << " Hit Static: " << mData.mHit << std::endl; - if (mData.mHitSound != "") + if (!mData.mHitSound.empty()) std::cout << " Hit Sound: " << mData.mHitSound << std::endl; - if (mData.mArea != "") + if (!mData.mArea.empty()) std::cout << " Area Static: " << mData.mArea << std::endl; - if (mData.mAreaSound != "") + if (!mData.mAreaSound.empty()) std::cout << " Area Sound: " << mData.mAreaSound << std::endl; std::cout << " School: " << schoolLabel(mData.mData.mSchool) << " (" << mData.mData.mSchool << ")" << std::endl; @@ -1015,7 +1002,7 @@ void Record::print() std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl; @@ -1032,9 +1019,9 @@ void Record::print() std::cout << " Head Model: " << mData.mHead << std::endl; std::cout << " Race: " << mData.mRace << std::endl; std::cout << " Class: " << mData.mClass << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; - if (mData.mFaction != "") + if (!mData.mFaction.empty()) std::cout << " Faction: " << mData.mFaction << std::endl; std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl; @@ -1083,14 +1070,12 @@ void Record::print() std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; } - std::vector::iterator cit; - for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit) - std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount - << " Item: " << cit->mItem.toString() << std::endl; + for (const ESM::ContItem &item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << boost::format("%4d") % item.mCount + << " Item: " << item.mItem.toString() << std::endl; - std::vector::iterator sit; - for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit) - std::cout << " Spell: " << *sit << std::endl; + for (const std::string &spell : mData.mSpells.mList) + std::cout << " Spell: " << spell << std::endl; printTransport(mData.getTransport()); @@ -1105,9 +1090,8 @@ void Record::print() std::cout << " AI U4:" << (int)mData.mAiData.mU4 << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; - std::vector::iterator pit; - for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit) - printAIPackage(*pit); + for (const ESM::AIPackage &package : mData.mAiPackage.mList) + printAIPackage(package); std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -1124,23 +1108,22 @@ void Record::print() std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; int i = 0; - ESM::Pathgrid::PointList::iterator pit; - for (pit = mData.mPoints.begin(); pit != mData.mPoints.end(); ++pit) + for (const ESM::Pathgrid::Point &point : mData.mPoints) { std::cout << " Point[" << i << "]:" << std::endl; - std::cout << " Coordinates: (" << pit->mX << "," - << pit->mY << "," << pit->mZ << ")" << std::endl; - std::cout << " Auto-Generated: " << (int)pit->mAutogenerated << std::endl; - std::cout << " Connections: " << (int)pit->mConnectionNum << std::endl; - std::cout << " Unknown: " << pit->mUnknown << std::endl; + std::cout << " Coordinates: (" << point.mX << "," + << point.mY << "," << point.mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl; + std::cout << " Connections: " << (int)point.mConnectionNum << std::endl; + std::cout << " Unknown: " << point.mUnknown << std::endl; i++; } + i = 0; - ESM::Pathgrid::EdgeList::iterator eit; - for (eit = mData.mEdges.begin(); eit != mData.mEdges.end(); ++eit) + for (const ESM::Pathgrid::Edge &edge : mData.mEdges) { - std::cout << " Edge[" << i << "]: " << eit->mV0 << " -> " << eit->mV1 << std::endl; - if (eit->mV0 >= mData.mData.mS2 || eit->mV1 >= mData.mData.mS2) + std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl; + if (edge.mV0 >= mData.mData.mS2 || edge.mV1 >= mData.mData.mS2) std::cout << " BAD POINT IN EDGE!" << std::endl; i++; } @@ -1183,9 +1166,8 @@ void Record::print() << " (" << mData.mData.mBonus[i].mSkill << ") = " << mData.mData.mBonus[i].mBonus << std::endl; - std::vector::iterator sit; - for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit) - std::cout << " Power: " << *sit << std::endl; + for (const std::string &power : mData.mPowers.mList) + std::cout << " Power: " << power << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -1207,11 +1189,10 @@ void Record::print() std::cout << " UnknownA: " << (int)mData.mData.mA << std::endl; std::cout << " UnknownB: " << (int)mData.mData.mB << std::endl; std::cout << " Map Color: " << mData.mMapColor << std::endl; - if (mData.mSleepList != "") + if (!mData.mSleepList.empty()) std::cout << " Sleep List: " << mData.mSleepList << std::endl; - std::vector::iterator sit; - for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); ++sit) - std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; + for (const ESM::Region::SoundRef &soundref : mData.mSoundList) + std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound.toString() << std::endl; } template<> @@ -1225,15 +1206,12 @@ void Record::print() std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; - - std::vector::iterator vit; - for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); ++vit) - std::cout << " Variable: " << *vit << std::endl; + for (const std::string &variable : mData.mVarNames) + std::cout << " Variable: " << variable << std::endl; std::cout << " ByteCode: "; - std::vector::iterator cit; - for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); ++cit) - std::cout << boost::format("%02X") % (int)(*cit); + for (const unsigned char &byte : mData.mScriptData) + std::cout << boost::format("%02X") % (int)(byte); std::cout << std::endl; if (mPrintPlain) @@ -1268,7 +1246,8 @@ void Record::print() template<> void Record::print() { - std::cout << " Creature: " << mData.mCreature << std::endl; + if (!mData.mCreature.empty()) + std::cout << " Creature: " << mData.mCreature << std::endl; std::cout << " Sound: " << mData.mSound << std::endl; std::cout << " Type: " << soundTypeLabel(mData.mType) << " (" << mData.mType << ")" << std::endl; @@ -1316,15 +1295,15 @@ template<> void Record::print() { // No names on VFX bolts - if (mData.mName != "") + if (!mData.mName.empty()) std::cout << " Name: " << mData.mName << std::endl; std::cout << " Model: " << mData.mModel << std::endl; // No icons on VFX bolts or magic bolts - if (mData.mIcon != "") + if (!mData.mIcon.empty()) std::cout << " Icon: " << mData.mIcon << std::endl; - if (mData.mScript != "") + if (!mData.mScript.empty()) std::cout << " Script: " << mData.mScript << std::endl; - if (mData.mEnchant != "") + if (!mData.mEnchant.empty()) std::cout << " Enchantment: " << mData.mEnchant << std::endl; std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; @@ -1356,25 +1335,25 @@ std::string Record::getId() const template<> std::string Record::getId() const { - return ""; // No ID for Land record + return std::string(); // No ID for Land record } template<> std::string Record::getId() const { - return ""; // No ID for MagicEffect record + return std::string(); // No ID for MagicEffect record } template<> std::string Record::getId() const { - return ""; // No ID for Pathgrid record + return std::string(); // No ID for Pathgrid record } template<> std::string Record::getId() const { - return ""; // No ID for Skill record + return std::string(); // No ID for Skill record } } // end namespace From 7a85e10d2f6cbb9afd7672b2d7a64ca35a521855 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Sun, 2 Dec 2018 23:36:27 +0100 Subject: [PATCH 05/52] fix a rig bug visible with OSG_VERTEX_BUFFER_HINT=VAO --- components/sceneutil/morphgeometry.cpp | 1 + components/sceneutil/riggeometry.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/components/sceneutil/morphgeometry.cpp b/components/sceneutil/morphgeometry.cpp index 1b7e4ca93..18b9dc1fd 100644 --- a/components/sceneutil/morphgeometry.cpp +++ b/components/sceneutil/morphgeometry.cpp @@ -30,6 +30,7 @@ void MorphGeometry::setSourceGeometry(osg::ref_ptr sourceGeom) for (unsigned int i=0; i<2; ++i) { mGeometry[i] = new osg::Geometry(*mSourceGeometry, osg::CopyOp::SHALLOW_COPY); + mGeometry[i]->setDataVariance(osg::Object::DYNAMIC); const osg::Geometry& from = *mSourceGeometry; osg::Geometry& to = *mGeometry[i]; diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 30a3f076c..73d05a292 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -63,6 +63,7 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr sourceGeometry) { const osg::Geometry& from = *sourceGeometry; mGeometry[i] = new osg::Geometry(from, osg::CopyOp::SHALLOW_COPY); + mGeometry[i]->setDataVariance(osg::Object::DYNAMIC); osg::Geometry& to = *mGeometry[i]; to.setSupportsDisplayList(false); to.setUseVertexBufferObjects(true); From 5c8c079718ad6179d79fc29b4fd1b9c0f4993d01 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 4 Dec 2018 16:47:47 +0300 Subject: [PATCH 06/52] Fix incorrect event argument which messed with hidden light pointers --- apps/openmw/mwworld/inventorystore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 6fe1d0c73..8b35d8dcc 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -150,7 +150,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, } if (mListener) - mListener->itemAdded(itemPtr, count); + mListener->itemAdded(*retVal, count); return retVal; } From 7cae0017acd4e1f96807e49a9f2b6723a5a0cbf5 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 5 Dec 2018 17:25:26 +0300 Subject: [PATCH 07/52] Display Ambient, Sunlight and Fog field values as colors (bug #4745) --- CHANGELOG.md | 1 + apps/opencs/model/world/data.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f44e83b3..371ce4d4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Bug #4715: "Cannot get class of an empty object" exception after pressing ESC in the dialogue mode Bug #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation Bug #4723: ResetActors command works incorrectly + Bug #4745: Editor: Interior cell lighting field values are not displayed as colors Feature #2229: Improve pathfinding AI Feature #3442: Default values for fallbacks from ini file Feature #4673: Weapon sheathing diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 63c7a52a8..53bd04147 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -326,11 +326,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float)); mCells.getNestableColumn(index)->addColumn( From 7b33838b3383cdf73fc56d1824b196e83abbc47e Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 5 Dec 2018 23:28:26 +0300 Subject: [PATCH 08/52] Don't consider non-solid actors truly levitating (bug #4746) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/aipackage.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 3 ++- apps/openmw/mwmechanics/character.cpp | 11 ++++++----- apps/openmw/mwworld/worldimp.cpp | 8 ++++---- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f44e83b3..cee5137d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Bug #4715: "Cannot get class of an empty object" exception after pressing ESC in the dialogue mode Bug #4720: Inventory avatar has shield with two-handed weapon during [un]equipping animation Bug #4723: ResetActors command works incorrectly + Bug #4746: Non-solid player can't run or sneak Feature #2229: Improve pathfinding AI Feature #3442: Default values for fallbacks from ini file Feature #4673: Weapon sheathing diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index c2e5c9afb..4646875fd 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -413,5 +413,5 @@ DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld:: bool MWMechanics::AiPackage::canActorMoveByZAxis(const MWWorld::Ptr& actor) const { MWBase::World* world = MWBase::Environment::get().getWorld(); - return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor); + return (actor.getClass().canSwim(actor) && world->isSwimming(actor)) || world->isFlying(actor) || !world->isActorCollisionEnabled(actor); } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 129d1347b..837d49f38 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -209,7 +209,8 @@ namespace MWMechanics } bool actorCanMoveByZ = (actor.getClass().canSwim(actor) && MWBase::Environment::get().getWorld()->isSwimming(actor)) - || MWBase::Environment::get().getWorld()->isFlying(actor); + || MWBase::Environment::get().getWorld()->isFlying(actor) + || !MWBase::Environment::get().getWorld()->isActorCollisionEnabled(actor); if(actorCanMoveByZ && mDistance > 0) { // Typically want to idle for a short time before the next wander diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index b0bd7d01d..07a6aa3b1 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1886,6 +1886,7 @@ void CharacterController::update(float duration, bool animationOnly) bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown()); bool inwater = world->isSwimming(mPtr); bool flying = world->isFlying(mPtr); + bool solid = world->isActorCollisionEnabled(mPtr); // Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed) bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying; bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying; @@ -1894,7 +1895,7 @@ void CharacterController::update(float duration, bool animationOnly) //Force Jump Logic bool isMoving = (std::abs(cls.getMovementSettings(mPtr).mPosition[0]) > .5 || std::abs(cls.getMovementSettings(mPtr).mPosition[1]) > .5); - if(!inwater && !flying) + if(!inwater && !flying && solid) { //Force Jump if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)) @@ -2002,12 +2003,12 @@ void CharacterController::update(float duration, bool animationOnly) cls.getCreatureStats(mPtr).setFatigue(fatigue); } - if(sneak || inwater || flying || incapacitated) + if(sneak || inwater || flying || incapacitated || !solid) vec.z() = 0.0f; bool inJump = true; bool playLandingSound = false; - if(!onground && !flying && !inwater) + if(!onground && !flying && !inwater && solid) { // In the air (either getting up —ascending part of jump— or falling). @@ -2060,7 +2061,7 @@ void CharacterController::update(float duration, bool animationOnly) } } } - else if(mJumpState == JumpState_InAir && !inwater && !flying) + else if(mJumpState == JumpState_InAir && !inwater && !flying && solid) { forcestateupdate = true; jumpstate = JumpState_Landing; @@ -2099,7 +2100,7 @@ void CharacterController::update(float duration, bool animationOnly) } else { - if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying) + if(mPtr.getClass().isNpc() && mJumpState == JumpState_InAir && !flying && solid) playLandingSound = true; jumpstate = mAnimation->isPlaying(mCurrentJump) ? JumpState_Landing : JumpState_None; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6fd11c2af..8a5e23ed9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1385,7 +1385,7 @@ namespace MWWorld pos.z() += 20; // place slightly above. will snap down to ground with code below - if (force || !isFlying(ptr)) + if (force || !ptr.getClass().isActor() || (!isFlying(ptr) && isActorCollisionEnabled(ptr))) { osg::Vec3f traced = mPhysics->traceDown(ptr, pos, Constants::CellSizeInUnits); if (traced.z() < pos.z()) @@ -2229,11 +2229,11 @@ namespace MWWorld bool World::isFlying(const MWWorld::Ptr &ptr) const { - const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); - if(!ptr.getClass().isActor()) return false; + const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); + if (stats.isDead()) return false; @@ -2245,7 +2245,7 @@ namespace MWWorld return true; const MWPhysics::Actor* actor = mPhysics->getActor(ptr); - if(!actor || !actor->getCollisionMode()) + if(!actor) return true; return false; From 59d96d808e9473fc82e0b342dba988e363d19f0d Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 7 Dec 2018 04:23:52 +0100 Subject: [PATCH 09/52] fix missing include --- extern/osg-ffmpeg-videoplayer/videostate.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/extern/osg-ffmpeg-videoplayer/videostate.hpp b/extern/osg-ffmpeg-videoplayer/videostate.hpp index 2fdb98da5..a60d6032f 100644 --- a/extern/osg-ffmpeg-videoplayer/videostate.hpp +++ b/extern/osg-ffmpeg-videoplayer/videostate.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include From 14fcb9158fa88775ec4d764ac8eb4408ff53ea9c Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 7 Dec 2018 14:46:32 +0000 Subject: [PATCH 10/52] Add NMake support to the Windows prebuild script. --- CI/before_script.msvc.sh | 55 ++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index b0d4a1ae1..3c4f00335 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -31,6 +31,7 @@ SKIP_EXTRACT="" KEEP="" UNITY_BUILD="" VS_VERSION="" +NMAKE="" PLATFORM="" CONFIGURATION="" @@ -66,6 +67,9 @@ while [ $# -gt 0 ]; do VS_VERSION=$1 shift ;; + n ) + NMAKE=true ;; + p ) PLATFORM=$1 shift ;; @@ -94,6 +98,8 @@ Options: Configure for unity builds. -v <2013/2015/2017> Choose the Visual Studio version to use. + -n + Produce NMake makefiles instead of a Visual Studio solution. -V Run verbosely EOF @@ -108,6 +114,10 @@ EOF done done +if [ -n $NMAKE ]; then + command -v nmake -? >/dev/null 2>&1 || { echo "Error: nmake (NMake) is not on the path. Make sure you have the necessary environment variables set for command-line C++ development (for example, by starting from a Developer Command Prompt)."; exit 1; } +fi + if [ -z $VERBOSE ]; then STRIP="> /dev/null 2>&1" fi @@ -267,18 +277,12 @@ case $PLATFORM in ARCHNAME="x86-64" ARCHSUFFIX="64" BITS="64" - - BASE_OPTS="-G\"$GENERATOR Win64\"" - add_cmake_opts "-G\"$GENERATOR Win64\"" ;; x32|x86|i686|i386|win32|Win32 ) ARCHNAME="x86" ARCHSUFFIX="86" BITS="32" - - BASE_OPTS="-G\"$GENERATOR\"" - add_cmake_opts "-G\"$GENERATOR\"" ;; * ) @@ -304,14 +308,24 @@ case $CONFIGURATION in ;; esac -if ! [ -z $UNITY_BUILD ]; then - add_cmake_opts "-DOPENMW_UNITY_BUILD=True" -fi - if [ ${BITS} -eq 64 ]; then GENERATOR="${GENERATOR} Win64" fi +if [ -n $NMAKE ]; then + GENERATOR="NMake Makefiles" +fi + +add_cmake_opts "-G\"$GENERATOR\"" + +if [ -n $NMAKE ]; then + add_cmake_opts "-DCMAKE_BUILD_TYPE=${BUILD_CONFIG}" +fi + +if ! [ -z $UNITY_BUILD ]; then + add_cmake_opts "-DOPENMW_UNITY_BUILD=True" +fi + echo echo "===================================" echo "Starting prebuild on MSVC${MSVC_DISPLAY_YEAR} WIN${BITS}" @@ -387,6 +401,11 @@ cd .. #/.. # Set up dependencies BUILD_DIR="MSVC${MSVC_DISPLAY_YEAR}_${BITS}" + +if [ -n $NMAKE ]; then + BUILD_DIR="${BUILD_DIR}_NMake_${BUILD_CONFIG}" +fi + if [ -z $KEEP ]; then echo echo "(Re)Creating build directory." @@ -696,7 +715,11 @@ fi # NOTE: Disable this when/if we want to run test cases #if [ -z $CI ]; then echo "- Copying Runtime DLLs..." - mkdir -p $BUILD_CONFIG + DLL_PREFIX="" + if [ -z $NMAKE ]; then + mkdir -p $BUILD_CONFIG + DLL_PREFIX="$BUILD_CONFIG/" + fi for DLL in $RUNTIME_DLLS; do TARGET="$(basename "$DLL")" if [[ "$DLL" == *":"* ]]; then @@ -705,21 +728,21 @@ fi TARGET=${SPLIT[1]} fi echo " ${TARGET}." - cp "$DLL" "$BUILD_CONFIG/$TARGET" + cp "$DLL" "${DLL_PREFIX}$TARGET" done echo echo "- OSG Plugin DLLs..." - mkdir -p $BUILD_CONFIG/osgPlugins-3.4.1 + mkdir -p ${DLL_PREFIX}osgPlugins-3.4.1 for DLL in $OSG_PLUGINS; do echo " $(basename $DLL)." - cp "$DLL" $BUILD_CONFIG/osgPlugins-3.4.1 + cp "$DLL" ${DLL_PREFIX}osgPlugins-3.4.1 done echo echo "- Qt Platform DLLs..." - mkdir -p ${BUILD_CONFIG}/platforms + mkdir -p ${DLL_PREFIX}platforms for DLL in $QT_PLATFORMS; do echo " $(basename $DLL)" - cp "$DLL" "${BUILD_CONFIG}/platforms" + cp "$DLL" "${DLL_PREFIX}platforms" done echo #fi From 2a2d9f0006f4383d7986b7b230d0d93caec0f429 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 7 Dec 2018 15:03:36 +0000 Subject: [PATCH 11/52] Fix if statements --- CI/before_script.msvc.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 3c4f00335..4fd352f7d 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -114,7 +114,7 @@ EOF done done -if [ -n $NMAKE ]; then +if [ -n "$NMAKE" ]; then command -v nmake -? >/dev/null 2>&1 || { echo "Error: nmake (NMake) is not on the path. Make sure you have the necessary environment variables set for command-line C++ development (for example, by starting from a Developer Command Prompt)."; exit 1; } fi @@ -312,13 +312,13 @@ if [ ${BITS} -eq 64 ]; then GENERATOR="${GENERATOR} Win64" fi -if [ -n $NMAKE ]; then +if [ -n "$NMAKE" ]; then GENERATOR="NMake Makefiles" fi add_cmake_opts "-G\"$GENERATOR\"" -if [ -n $NMAKE ]; then +if [ -n "$NMAKE" ]; then add_cmake_opts "-DCMAKE_BUILD_TYPE=${BUILD_CONFIG}" fi @@ -402,7 +402,7 @@ cd .. #/.. # Set up dependencies BUILD_DIR="MSVC${MSVC_DISPLAY_YEAR}_${BITS}" -if [ -n $NMAKE ]; then +if [ -n "$NMAKE" ]; then BUILD_DIR="${BUILD_DIR}_NMake_${BUILD_CONFIG}" fi From 64e960aa22d2bdc1a6d589b344010408c7cc735c Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 8 Dec 2018 01:29:14 +0100 Subject: [PATCH 12/52] enable win32 debug console when launching from console --- components/CMakeLists.txt | 2 +- components/debug/debugging.cpp | 5 +++ components/debug/debugging.hpp | 3 ++ components/debug/win32.cpp | 56 ++++++++++++++++++++++++++++++++++ components/debug/win32.hpp | 5 +++ 5 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 components/debug/win32.cpp create mode 100644 components/debug/win32.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7a88dc18e..e34a95396 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -90,7 +90,7 @@ add_component_dir (misc ) add_component_dir (debug - debugging debuglog + debugging debuglog win32 ) IF(NOT WIN32 AND NOT APPLE) diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index e89a65956..9798950b9 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -52,6 +52,11 @@ namespace Debug int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], const std::string& appName) { +#if defined _WIN32 + // grab a console window if we don't have one + (void)Debug::attachParentConsole(); +#endif + // Some objects used to redirect cout and cerr // Scope must be here, so this still works inside the catch block for logging exceptions std::streambuf* cout_rdbuf = std::cout.rdbuf (); diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index 361f321cb..440e8fa47 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -9,6 +9,9 @@ #include #include "debuglog.hpp" +#if defined _WIN32 +# include "win32.hpp" +#endif namespace Debug { diff --git a/components/debug/win32.cpp b/components/debug/win32.cpp new file mode 100644 index 000000000..9b038343c --- /dev/null +++ b/components/debug/win32.cpp @@ -0,0 +1,56 @@ +#include "win32.hpp" + +#undef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS + +#include +#include + +#include + +namespace Debug { + +bool attachParentConsole() +{ + // we already have a console window + if (GetConsoleWindow() != nullptr) + return true; + + // our parent window has a console we can use + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { + // start with consistent state + fflush(stdin); + fflush(stderr); + std::cout.flush(); + std::cerr.flush(); + + // fix fprintf(3) and fwprintf(3) + // this looks strange, but nothing is ever simple on Windows. + _wfreopen(L"CON", L"w", stdout); + _wfreopen(L"CON", L"w", stderr); + _wfreopen(L"CON", L"r", stdin); + freopen("CON", "w", stdout); + freopen("CON", "w", stderr); + freopen("CON", "w", stderr); + + // it can be verified that input/output works as expected. +#if 0 + fprintf(stdout, "ascii stdout\n"); + fwprintf(stdout, L"wide stdout\n"); + fprintf(stderr, "ascii stderr\n"); + fwprintf(stderr, L"wide stderr\n"); + + std::cout << "ascii cout\n"; + std::cout << L"wide cout\n"; + std::cerr << "ascii cerr\n"; + std::cerr << L"wide cerr\n"; +#endif + + return true; + } + + return false; +} + +} // ns Debug diff --git a/components/debug/win32.hpp b/components/debug/win32.hpp new file mode 100644 index 000000000..5a103cce5 --- /dev/null +++ b/components/debug/win32.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace Debug { + bool attachParentConsole(); +} From 44e60b708be5aedfa12e71615861144ba3eaeb89 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 8 Dec 2018 03:13:18 +0100 Subject: [PATCH 13/52] fix missing _WIN32 guard --- components/debug/win32.cpp | 4 ++++ components/debug/win32.hpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/components/debug/win32.cpp b/components/debug/win32.cpp index 9b038343c..976d5a4b0 100644 --- a/components/debug/win32.cpp +++ b/components/debug/win32.cpp @@ -1,3 +1,5 @@ +#ifdef _WIN32 + #include "win32.hpp" #undef _CRT_SECURE_NO_WARNINGS @@ -54,3 +56,5 @@ bool attachParentConsole() } } // ns Debug + +#endif diff --git a/components/debug/win32.hpp b/components/debug/win32.hpp index 5a103cce5..d3c8d4094 100644 --- a/components/debug/win32.hpp +++ b/components/debug/win32.hpp @@ -1,5 +1,9 @@ #pragma once +#ifdef _WIN32 + namespace Debug { bool attachParentConsole(); } + +#endif From 56d79bd4e0c1ca1b4a00846e61a2dd165068cf95 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 8 Dec 2018 20:57:50 +0100 Subject: [PATCH 14/52] fix typo --- components/debug/win32.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/debug/win32.cpp b/components/debug/win32.cpp index 976d5a4b0..1d5657d25 100644 --- a/components/debug/win32.cpp +++ b/components/debug/win32.cpp @@ -22,7 +22,7 @@ bool attachParentConsole() if (AttachConsole(ATTACH_PARENT_PROCESS)) { // start with consistent state - fflush(stdin); + fflush(stdout); fflush(stderr); std::cout.flush(); std::cerr.flush(); @@ -34,7 +34,7 @@ bool attachParentConsole() _wfreopen(L"CON", L"r", stdin); freopen("CON", "w", stdout); freopen("CON", "w", stderr); - freopen("CON", "w", stderr); + freopen("CON", "r", stdin); // it can be verified that input/output works as expected. #if 0 From 6083e5ed4b4e18417f7c655a3d505ba1cc423727 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 10 Dec 2018 00:04:12 +0300 Subject: [PATCH 15/52] Don't interrupt sneak and swim idles in first person view (bug #4750) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/character.cpp | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bcf6f1d2..b346f22d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Bug #4723: ResetActors command works incorrectly Bug #4745: Editor: Interior cell lighting field values are not displayed as colors Bug #4746: Non-solid player can't run or sneak + Bug #4750: Sneaking doesn't work in first person view if the player is in attack ready state Feature #2229: Improve pathfinding AI Feature #3442: Default values for fallbacks from ini file Feature #3610: Option to invert X axis diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07a6aa3b1..57f97aaca 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1622,11 +1622,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle) } } - // We should reset player's idle animation in the first-person mode. - if (resetIdle && mPtr == player && MWBase::Environment::get().getWorld()->isFirstPerson()) - idle = CharState_None; - - // In other cases we should not break swim and sneak animations + // We should not break swim and sneak animations if (resetIdle && idle != CharState_IdleSneak && idle != CharState_IdleSwim && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) From aab7f2e8b9971ec4693f12cf2fee235c0486bfe1 Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 10 Dec 2018 23:44:47 +0300 Subject: [PATCH 16/52] Don't check for equality in move assignment Assume it is undefined behavior to move-assing value to itself. --- components/detournavigator/navmeshtilescache.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/detournavigator/navmeshtilescache.hpp b/components/detournavigator/navmeshtilescache.hpp index 45c0a6bb3..23033cce4 100644 --- a/components/detournavigator/navmeshtilescache.hpp +++ b/components/detournavigator/navmeshtilescache.hpp @@ -69,9 +69,6 @@ namespace DetourNavigator Value& operator =(Value&& other) { - if (mIterator == other.mIterator) - return *this; - if (mIterator != ItemIterator()) mOwner->releaseItem(mIterator); From da431135fa17c12efdf4532fe1a88000adf5e35d Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 10 Dec 2018 23:51:15 +0300 Subject: [PATCH 17/52] Use pointer to check is NavMeshTilesCache::Value initialized --- components/detournavigator/navmeshtilescache.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/detournavigator/navmeshtilescache.hpp b/components/detournavigator/navmeshtilescache.hpp index 23033cce4..7418c4d3a 100644 --- a/components/detournavigator/navmeshtilescache.hpp +++ b/components/detournavigator/navmeshtilescache.hpp @@ -56,12 +56,12 @@ namespace DetourNavigator Value(Value&& other) : mOwner(other.mOwner), mIterator(other.mIterator) { - other.mIterator = ItemIterator(); + other.mOwner = nullptr; } ~Value() { - if (mIterator != ItemIterator()) + if (mOwner) mOwner->releaseItem(mIterator); } @@ -69,13 +69,13 @@ namespace DetourNavigator Value& operator =(Value&& other) { - if (mIterator != ItemIterator()) + if (mOwner) mOwner->releaseItem(mIterator); mOwner = other.mOwner; mIterator = other.mIterator; - other.mIterator = ItemIterator(); + other.mOwner = nullptr; return *this; } @@ -87,7 +87,7 @@ namespace DetourNavigator operator bool() const { - return mIterator != ItemIterator(); + return mOwner; } private: From fc10adb608841710db4f32efdc604b96af970a82 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 11 Dec 2018 21:30:37 +0100 Subject: [PATCH 18/52] makes openmw.appdata.xml a template that accepts @OPENMW_VERSION@ so we do not have to update it all the time; fix deprecated warning for boost header; un-ignore openmw.appdata.xml --- .gitignore | 1 - CMakeLists.txt | 5 ++++- apps/launcher/graphicspage.cpp | 2 +- files/openmw.appdata.xml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 827c0a072..0ee4a6399 100644 --- a/.gitignore +++ b/.gitignore @@ -81,5 +81,4 @@ moc_*.cxx *ui_playpage.h *.[ao] *.so -openmw.appdata.xml venv/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7628e65eb..8699ec91d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -344,7 +344,10 @@ endif (APPLE) # Other files configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg - "${OpenMW_BINARY_DIR}" "settings-default.cfg") + "${OpenMW_BINARY_DIR}" "settings-default.cfg") + +configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml + "${OpenMW_BINARY_DIR}" "openmw.appdata.xml") if (NOT APPLE) configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 072f1f36f..5d9d69edf 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -1,6 +1,6 @@ #include "graphicspage.hpp" -#include +#include #include #include #include diff --git a/files/openmw.appdata.xml b/files/openmw.appdata.xml index 5c093e3c4..05654d9b9 100644 --- a/files/openmw.appdata.xml +++ b/files/openmw.appdata.xml @@ -43,7 +43,7 @@ Copyright 2017 Bret Curtis RolePlaying - + https://openmw.org https://bugs.openmw.org/ From 6596c400f355c42ea0e58c411b87023a0176217e Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 11 Dec 2018 21:34:11 +0100 Subject: [PATCH 19/52] indentation --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8699ec91d..dbe00729d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -344,10 +344,10 @@ endif (APPLE) # Other files configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg - "${OpenMW_BINARY_DIR}" "settings-default.cfg") + "${OpenMW_BINARY_DIR}" "settings-default.cfg") configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml - "${OpenMW_BINARY_DIR}" "openmw.appdata.xml") + "${OpenMW_BINARY_DIR}" "openmw.appdata.xml") if (NOT APPLE) configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local From 74955555b938088b5294991a8ba16350a36feafe Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 11 Dec 2018 23:52:18 +0100 Subject: [PATCH 20/52] remove verbose comments and example --- components/debug/debugging.cpp | 1 - components/debug/win32.cpp | 19 +------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index 9798950b9..caef1e1dc 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -53,7 +53,6 @@ namespace Debug int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, char *argv[], const std::string& appName) { #if defined _WIN32 - // grab a console window if we don't have one (void)Debug::attachParentConsole(); #endif diff --git a/components/debug/win32.cpp b/components/debug/win32.cpp index 1d5657d25..16a264a0b 100644 --- a/components/debug/win32.cpp +++ b/components/debug/win32.cpp @@ -14,21 +14,17 @@ namespace Debug { bool attachParentConsole() { - // we already have a console window if (GetConsoleWindow() != nullptr) return true; - // our parent window has a console we can use if (AttachConsole(ATTACH_PARENT_PROCESS)) { - // start with consistent state fflush(stdout); fflush(stderr); std::cout.flush(); std::cerr.flush(); - // fix fprintf(3) and fwprintf(3) - // this looks strange, but nothing is ever simple on Windows. + // this looks dubious but is really the right way _wfreopen(L"CON", L"w", stdout); _wfreopen(L"CON", L"w", stderr); _wfreopen(L"CON", L"r", stdin); @@ -36,19 +32,6 @@ bool attachParentConsole() freopen("CON", "w", stderr); freopen("CON", "r", stdin); - // it can be verified that input/output works as expected. -#if 0 - fprintf(stdout, "ascii stdout\n"); - fwprintf(stdout, L"wide stdout\n"); - fprintf(stderr, "ascii stderr\n"); - fwprintf(stderr, L"wide stderr\n"); - - std::cout << "ascii cout\n"; - std::cout << L"wide cout\n"; - std::cerr << "ascii cerr\n"; - std::cerr << L"wide cerr\n"; -#endif - return true; } From f6c8842457184405348846fc7f9e1be67e83af7b Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 11 Dec 2018 23:58:46 +0100 Subject: [PATCH 21/52] move to debugging.[ch]pp --- components/CMakeLists.txt | 2 +- components/debug/debugging.cpp | 28 ++++++++++++++++++++++ components/debug/debugging.hpp | 7 +++--- components/debug/win32.cpp | 43 ---------------------------------- components/debug/win32.hpp | 9 ------- 5 files changed, 33 insertions(+), 56 deletions(-) delete mode 100644 components/debug/win32.cpp delete mode 100644 components/debug/win32.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index e34a95396..7a88dc18e 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -90,7 +90,7 @@ add_component_dir (misc ) add_component_dir (debug - debugging debuglog win32 + debugging debuglog ) IF(NOT WIN32 AND NOT APPLE) diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index caef1e1dc..7aa7a127a 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -4,6 +4,34 @@ namespace Debug { +#ifdef _WIN32 + bool attachParentConsole() + { + if (GetConsoleWindow() != nullptr) + return true; + + if (AttachConsole(ATTACH_PARENT_PROCESS)) + { + fflush(stdout); + fflush(stderr); + std::cout.flush(); + std::cerr.flush(); + + // this looks dubious but is really the right way + _wfreopen(L"CON", L"w", stdout); + _wfreopen(L"CON", L"w", stderr); + _wfreopen(L"CON", L"r", stdin); + freopen("CON", "w", stdout); + freopen("CON", "w", stderr); + freopen("CON", "r", stdin); + + return true; + } + + return false; + } +#endif + std::streamsize DebugOutputBase::write(const char *str, std::streamsize size) { // Skip debug level marker diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index 440e8fa47..bf9fbd38c 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -9,9 +9,6 @@ #include #include "debuglog.hpp" -#if defined _WIN32 -# include "win32.hpp" -#endif namespace Debug { @@ -46,6 +43,10 @@ namespace Debug } }; +#ifdef _WIN32 + bool attachParentConsole(); +#endif + #if defined(_WIN32) && defined(_DEBUG) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 diff --git a/components/debug/win32.cpp b/components/debug/win32.cpp deleted file mode 100644 index 16a264a0b..000000000 --- a/components/debug/win32.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef _WIN32 - -#include "win32.hpp" - -#undef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS - -#include -#include - -#include - -namespace Debug { - -bool attachParentConsole() -{ - if (GetConsoleWindow() != nullptr) - return true; - - if (AttachConsole(ATTACH_PARENT_PROCESS)) - { - fflush(stdout); - fflush(stderr); - std::cout.flush(); - std::cerr.flush(); - - // this looks dubious but is really the right way - _wfreopen(L"CON", L"w", stdout); - _wfreopen(L"CON", L"w", stderr); - _wfreopen(L"CON", L"r", stdin); - freopen("CON", "w", stdout); - freopen("CON", "w", stderr); - freopen("CON", "r", stdin); - - return true; - } - - return false; -} - -} // ns Debug - -#endif diff --git a/components/debug/win32.hpp b/components/debug/win32.hpp deleted file mode 100644 index d3c8d4094..000000000 --- a/components/debug/win32.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#ifdef _WIN32 - -namespace Debug { - bool attachParentConsole(); -} - -#endif From c5c160870d439eae9e7c95a2d1ffa55ed3481c26 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 12 Dec 2018 00:12:13 +0100 Subject: [PATCH 22/52] fix accidental header namespace inclusion --- components/debug/debugging.cpp | 6 ++++++ components/debug/debugging.hpp | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index 7aa7a127a..2d05fbc55 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -2,6 +2,12 @@ #include +#ifdef _WIN32 +# undef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# include +#endif + namespace Debug { #ifdef _WIN32 diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index bf9fbd38c..81b01d055 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -10,6 +10,12 @@ #include "debuglog.hpp" +#if defined _WIN32 && defined _DEBUG +# undef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# include +#endif + namespace Debug { // ANSI colors for terminal @@ -47,11 +53,7 @@ namespace Debug bool attachParentConsole(); #endif -#if defined(_WIN32) && defined(_DEBUG) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif // !WIN32_LEAN_AND_MEAN -#include +#if defined _WIN32 && defined _DEBUG class DebugOutput : public DebugOutputBase { public: From b8b1a5221665c1fb32ffb0015ff50095270c82b9 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 12 Dec 2018 10:27:09 +0100 Subject: [PATCH 23/52] add commit date; revert boost as we are not breaking anything yet --- CMakeLists.txt | 9 +++++++++ apps/launcher/graphicspage.cpp | 2 +- files/openmw.appdata.xml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe00729d..4cfc7ed92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ set(OPENMW_VERSION_RELEASE 0) set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_TAGHASH "") +set(OPENMW_VERSION_COMMITDATE "") set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") @@ -73,6 +74,14 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) endif(GIT_FOUND) endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) +execute_process ( + COMMAND ${GIT_EXECUTABLE} log -1 --format='%aI' + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE EXITCODE3 + OUTPUT_VARIABLE COMMITDATE + OUTPUT_STRIP_TRAILING_WHITESPACE) +string(SUBSTRING ${COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE) + # Macros include(OpenMWMacros) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 5d9d69edf..54ddfd0c9 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -1,6 +1,6 @@ #include "graphicspage.hpp" -#include +#include #include #include #include diff --git a/files/openmw.appdata.xml b/files/openmw.appdata.xml index 05654d9b9..fd8ad8176 100644 --- a/files/openmw.appdata.xml +++ b/files/openmw.appdata.xml @@ -43,7 +43,7 @@ Copyright 2017 Bret Curtis RolePlaying - + https://openmw.org https://bugs.openmw.org/ From 83e346e1e624e806b0461ccb5f482d1fd0b55202 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 12 Dec 2018 16:18:49 +0100 Subject: [PATCH 24/52] add new bugtracker --- files/openmw.appdata.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/openmw.appdata.xml b/files/openmw.appdata.xml index fd8ad8176..39504070c 100644 --- a/files/openmw.appdata.xml +++ b/files/openmw.appdata.xml @@ -1,7 +1,7 @@ org.openmw.desktop @@ -46,6 +46,6 @@ Copyright 2017 Bret Curtis https://openmw.org - https://bugs.openmw.org/ + https://gitlab.com/OpenMW/openmw/issues https://openmw.org/faq/ From f4c863a7300bc7ca1c66335e13b11f3cf45e1056 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 12 Dec 2018 16:19:07 +0100 Subject: [PATCH 25/52] Update graphicspage.cpp --- apps/launcher/graphicspage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 54ddfd0c9..072f1f36f 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -1,6 +1,6 @@ #include "graphicspage.hpp" -#include +#include #include #include #include From c31fa3074e642bb254f999feeef6e9743d13c18c Mon Sep 17 00:00:00 2001 From: terrabyte25 <23338617+terabyte25@users.noreply.github.com> Date: Wed, 12 Dec 2018 14:40:15 -0600 Subject: [PATCH 26/52] Sanity check for text input in toggleWalking --- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index d8b4fd831..be1301aac 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -1173,7 +1173,7 @@ namespace MWInput void InputManager::toggleWalking() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return; mAlwaysRunActive = !mAlwaysRunActive; Settings::Manager::setBool("always run", "Input", mAlwaysRunActive); From 9067731a96cb83702b25f69677afba1d209cb9d4 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 13 Dec 2018 02:08:35 +0000 Subject: [PATCH 27/52] Adapt to CMake 3.13's new meaning of OSGDB_LIBRARY (i.e. that it can now be a list) while allowing for the possibility that the found libraries may be in different directories when debug and optimised versions exist. --- CMakeLists.txt | 31 +++++++++++++++++++++++-------- cmake/FindOSGPlugins.cmake | 19 +++++++++++-------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7628e65eb..b499988c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,8 +256,14 @@ set(USED_OSG_PLUGINS osgdb_tga ) -get_filename_component(OSG_LIB_DIR ${OSGDB_LIBRARY} DIRECTORY) -set(OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}") +set(OSGPlugins_LIB_DIR "") +foreach(OSGDB_LIB ${OSGDB_LIBRARY}) + # Skip library type names + if(EXISTS ${OSGDB_LIB}) + get_filename_component(OSG_LIB_DIR ${OSGDB_LIB} DIRECTORY) + list(APPEND OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}") + endif() +endforeach(OSGDB_LIB) if(OSG_STATIC) add_definitions(-DOSG_LIBRARY_STATIC) @@ -807,15 +813,24 @@ if (OPENMW_OSX_DEPLOYMENT AND APPLE AND DESIRED_QT_VERSION MATCHES 5) set(ABSOLUTE_PLUGINS "") + set(OSGPlugins_DONT_FIND_DEPENDENCIES 1) + find_package(OSGPlugins REQUIRED COMPONENTS ${USED_OSG_PLUGINS}) + foreach (PLUGIN_NAME ${USED_OSG_PLUGINS}) - set(PLUGIN_ABS "${OSGPlugins_LIB_DIR}/${PLUGIN_NAME}.so") - set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS}) + string(TOUPPER ${PLUGIN_NAME} PLUGIN_NAME_UC) + if(${PLUGIN_NAME_UC}_LIBRARY_RELEASE) + set(PLUGIN_ABS ${${PLUGIN_NAME_UC}_LIBRARY_RELEASE}) + elseif(${PLUGIN_NAME_UC}_LIBRARY) + set(PLUGIN_ABS ${${PLUGIN_NAME_UC}_LIBRARY}) + else() + message(FATAL_ERROR "Can't find library file for ${PLUGIN_NAME}") + # We used to construct the path manually from OSGPlugins_LIB_DIR and the plugin name. + # Maybe that could be restored as a fallback? + endif() + set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS}) endforeach () - get_filename_component(OSG_PLUGIN_PREFIX_DIR "${OSGPlugins_LIB_DIR}" NAME) - if (NOT OSG_PLUGIN_PREFIX_DIR) - message(FATAL_ERROR "Can't get directory name for OSG plugins from '${OSGPlugins_LIB_DIR}'") - endif() + set(OSG_PLUGIN_PREFIX_DIR "osgPlugins-${OPENSCENEGRAPH_VERSION}") # installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX}) # and returns list of install paths for all installed plugins diff --git a/cmake/FindOSGPlugins.cmake b/cmake/FindOSGPlugins.cmake index 8220f33d4..f8c16921f 100644 --- a/cmake/FindOSGPlugins.cmake +++ b/cmake/FindOSGPlugins.cmake @@ -1,5 +1,6 @@ # This module accepts the following env variable # OSGPlugins_LIB_DIR - /lib/osgPlugins- , path to search plugins +# OSGPlugins_DONT_FIND_DEPENDENCIES - Set to skip also finding png, zlib and jpeg # # Once done this will define # OSGPlugins_FOUND - System has the all required components. @@ -27,10 +28,10 @@ foreach(_library ${OSGPlugins_FIND_COMPONENTS}) set(_component OSGPlugins_${_library}) set(${_library_uc}_DIR ${OSGPlugins_LIB_DIR}) # to help function osg_find_library - set(_saved_lib_prefix ${CMAKE_FIND_LIBRARY_PREFIXES}) # save CMAKE_FIND_LIBRARY_PREFIXES - set(CMAKE_FIND_LIBRARY_PREFIXES "") # search libraries with no prefix + #set(_saved_lib_prefix ${CMAKE_FIND_LIBRARY_PREFIXES}) # save CMAKE_FIND_LIBRARY_PREFIXES + #set(CMAKE_FIND_LIBRARY_PREFIXES "") # search libraries with no prefix osg_find_library(${_library_uc} ${_library}) # find it into ${_library_uc}_LIBRARIES - set(CMAKE_FIND_LIBRARY_PREFIXES ${_saved_lib_prefix}) # restore prefix + #set(CMAKE_FIND_LIBRARY_PREFIXES ${_saved_lib_prefix}) # restore prefix if (${_library_uc}_LIBRARIES) set(${_component}_LIBRARY ${${_library_uc}_LIBRARIES}) # fake as if we call find_library @@ -41,10 +42,12 @@ foreach(_library ${OSGPlugins_FIND_COMPONENTS}) list(APPEND OSGPlugins_PROCESS_LIBS ${_component}_LIBRARY) endforeach() -foreach(_dependency PNG ZLIB JPEG) # needed by osgdb_png or osgdb_jpeg - libfind_package(OSGPlugins ${_dependency}) - set(${_dependency}_LIBRARY_OPTS ${_dependency}_LIBRARY) - #list(APPEND OSGPlugins_PROCESS_LIBS ${_dependency}_LIBRARY) -endforeach() +if(NOT DEFINED OSGPlugins_DONT_FIND_DEPENDENCIES) + foreach(_dependency PNG ZLIB JPEG) # needed by osgdb_png or osgdb_jpeg + libfind_package(OSGPlugins ${_dependency}) + set(${_dependency}_LIBRARY_OPTS ${_dependency}_LIBRARY) + #list(APPEND OSGPlugins_PROCESS_LIBS ${_dependency}_LIBRARY) + endforeach() +endif() libfind_process(OSGPlugins) From fc19c842cf1356906a490d82e4759817f82b1a27 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Thu, 13 Dec 2018 20:09:46 +0100 Subject: [PATCH 28/52] Revert "fix a rig bug visible with OSG_VERTEX_BUFFER_HINT=VAO" --- components/sceneutil/morphgeometry.cpp | 1 - components/sceneutil/riggeometry.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/components/sceneutil/morphgeometry.cpp b/components/sceneutil/morphgeometry.cpp index 18b9dc1fd..1b7e4ca93 100644 --- a/components/sceneutil/morphgeometry.cpp +++ b/components/sceneutil/morphgeometry.cpp @@ -30,7 +30,6 @@ void MorphGeometry::setSourceGeometry(osg::ref_ptr sourceGeom) for (unsigned int i=0; i<2; ++i) { mGeometry[i] = new osg::Geometry(*mSourceGeometry, osg::CopyOp::SHALLOW_COPY); - mGeometry[i]->setDataVariance(osg::Object::DYNAMIC); const osg::Geometry& from = *mSourceGeometry; osg::Geometry& to = *mGeometry[i]; diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 73d05a292..30a3f076c 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -63,7 +63,6 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr sourceGeometry) { const osg::Geometry& from = *sourceGeometry; mGeometry[i] = new osg::Geometry(from, osg::CopyOp::SHALLOW_COPY); - mGeometry[i]->setDataVariance(osg::Object::DYNAMIC); osg::Geometry& to = *mGeometry[i]; to.setSupportsDisplayList(false); to.setUseVertexBufferObjects(true); From a53333c3d5a608a9e8d450b061c5006a99a0e074 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 22 Sep 2018 12:57:50 +0400 Subject: [PATCH 29/52] Native animated containers support (feature #4730) --- CHANGELOG.md | 1 + apps/openmw/mwbase/mechanicsmanager.hpp | 3 ++ apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwgui/container.cpp | 2 + apps/openmw/mwmechanics/character.cpp | 39 +++++++++++++++++++ apps/openmw/mwmechanics/character.hpp | 3 ++ .../mwmechanics/mechanicsmanagerimp.cpp | 14 +++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 ++ apps/openmw/mwmechanics/objects.cpp | 36 +++++++++++++++++ apps/openmw/mwmechanics/objects.hpp | 3 ++ apps/openmw/mwphysics/physicssystem.cpp | 7 ++++ apps/openmw/mwphysics/physicssystem.hpp | 2 + apps/openmw/mwworld/actionopen.cpp | 4 ++ apps/openmw/mwworld/worldimp.cpp | 5 +++ apps/openmw/mwworld/worldimp.hpp | 2 + 15 files changed, 126 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bcf6f1d2..557fdda45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Feature #3442: Default values for fallbacks from ini file Feature #3610: Option to invert X axis Feature #4673: Weapon sheathing + Feature #4730: Native animated containers support Task #4686: Upgrade media decoder to a more current FFmpeg API 0.45.0 diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 056628211..1bdd8f8b5 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -237,6 +237,9 @@ namespace MWBase virtual float getActorsProcessingRange() const = 0; + virtual bool onOpen(const MWWorld::Ptr& ptr) = 0; + virtual void onClose(const MWWorld::Ptr& ptr) = 0; + /// Check if the target actor was detected by an observer /// If the observer is a non-NPC, check all actors in AI processing distance as observers virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index ffacb267c..dfae5700b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -303,6 +303,8 @@ namespace MWBase ///< Queues movement for \a ptr (in local space), to be applied in the next call to /// doPhysics. + virtual void updateAnimatedCollisionShape(const MWWorld::Ptr &ptr) = 0; + virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; ///< cast a Ray and return true if there is an object in the ray path. diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 2f9643f74..51c0603ca 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -162,6 +162,8 @@ namespace MWGui if (mModel) mModel->onClose(); + + MWBase::Environment::get().getMechanicsManager()->onClose(mPtr); } void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07a6aa3b1..0a1a9810a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -419,6 +419,43 @@ void CharacterController::refreshJumpAnims(const WeaponInfo* weap, JumpingState } } +bool CharacterController::onOpen() +{ + if (mPtr.getTypeName() == typeid(ESM::Container).name()) + { + if (!mAnimation->hasAnimation("containeropen")) + return true; + + if (mAnimation->isPlaying("containeropen")) + return false; + + if (mAnimation->isPlaying("containerclose")) + return false; + + mAnimation->play("containeropen", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.f, 0); + if (mAnimation->isPlaying("containeropen")) + return false; + } + + return true; +} + +void CharacterController::onClose() +{ + if (mPtr.getTypeName() == typeid(ESM::Container).name()) + { + if (!mAnimation->hasAnimation("containerclose")) + return; + + float complete, startPoint = 0.f; + bool animPlaying = mAnimation->getInfo("containeropen", &complete); + if (animPlaying) + startPoint = 1.f - complete; + + mAnimation->play("containerclose", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, 0); + } +} + void CharacterController::refreshMovementAnims(const WeaponInfo* weap, CharacterState movement, CharacterState& idle, bool force) { if (movement == mMovementState && idle == mIdleState && !force) @@ -1079,6 +1116,8 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: else if (groupname == "shield" && evt.compare(off, len, "block hit") == 0) mPtr.getClass().block(mPtr); + else if (groupname == "containeropen" && evt.compare(off, len, "loot") == 0) + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, mPtr); } void CharacterController::updatePtr(const MWWorld::Ptr &ptr) diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0f4b3aa90..7e6e82c07 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -259,6 +259,9 @@ public: void update(float duration, bool animationOnly=false); + bool onOpen(); + void onClose(); + void persistAnimationState(); void unpersistAnimationState(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index a907fb89f..43a082348 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -845,6 +845,20 @@ namespace MWMechanics return false; } + bool MechanicsManager::onOpen(const MWWorld::Ptr& ptr) + { + if(ptr.getClass().isActor()) + return true; + else + return mObjects.onOpen(ptr); + } + + void MechanicsManager::onClose(const MWWorld::Ptr& ptr) + { + if(!ptr.getClass().isActor()) + mObjects.onClose(ptr); + } + void MechanicsManager::persistAnimationStates() { mActors.persistAnimationStates(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 7b6bbc636..a1fce4fa9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -182,6 +182,9 @@ namespace MWMechanics virtual void playerLoaded() override; + virtual bool onOpen(const MWWorld::Ptr& ptr) override; + virtual void onClose(const MWWorld::Ptr& ptr) override; + virtual int countSavedGameRecords() const override; virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override; diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index e95c0a704..726508161 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -1,8 +1,10 @@ #include "objects.hpp" #include +#include #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "movement.hpp" @@ -77,6 +79,40 @@ void Objects::update(float duration, bool paused) for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter) iter->second->update(duration); } + else + { + // We still should play container opening animation in the Container GUI mode. + MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); + if(mode != MWGui::GM_Container) + return; + + for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter) + { + if (iter->first.getTypeName() != typeid(ESM::Container).name()) + continue; + + if (iter->second->isAnimPlaying("containeropen")) + { + iter->second->update(duration); + MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(iter->first); + } + } + } +} + +bool Objects::onOpen(const MWWorld::Ptr& ptr) +{ + PtrControllerMap::iterator iter = mObjects.find(ptr); + if(iter != mObjects.end()) + return iter->second->onOpen(); + return false; +} + +void Objects::onClose(const MWWorld::Ptr& ptr) +{ + PtrControllerMap::iterator iter = mObjects.find(ptr); + if(iter != mObjects.end()) + iter->second->onClose(); } bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) diff --git a/apps/openmw/mwmechanics/objects.hpp b/apps/openmw/mwmechanics/objects.hpp index 1efebafbe..81b95baf8 100644 --- a/apps/openmw/mwmechanics/objects.hpp +++ b/apps/openmw/mwmechanics/objects.hpp @@ -38,6 +38,9 @@ namespace MWMechanics void update(float duration, bool paused); ///< Update object animations + bool onOpen(const MWWorld::Ptr& ptr); + void onClose(const MWWorld::Ptr& ptr); + bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false); void skipAnimation(const MWWorld::Ptr& ptr); void persistAnimationStates(); diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 57b6d348b..836370255 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1363,6 +1363,13 @@ namespace MWPhysics #endif } + void PhysicsSystem::updateAnimatedCollisionShape(const MWWorld::Ptr& object) + { + ObjectMap::iterator found = mObjects.find(object); + if (found != mObjects.end()) + found->second->animateCollisionShapes(mCollisionWorld); + } + void PhysicsSystem::debugDraw() { if (mDebugDrawer.get()) diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index d4829f623..7d7f5a33c 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -178,6 +178,8 @@ namespace MWPhysics bool isOnSolidGround (const MWWorld::Ptr& actor) const; + void updateAnimatedCollisionShape(const MWWorld::Ptr& object); + template void forEachAnimatedObject(Function&& function) const { diff --git a/apps/openmw/mwworld/actionopen.cpp b/apps/openmw/mwworld/actionopen.cpp index 7ff6dd068..f678037ce 100644 --- a/apps/openmw/mwworld/actionopen.cpp +++ b/apps/openmw/mwworld/actionopen.cpp @@ -1,6 +1,7 @@ #include "actionopen.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwmechanics/disease.hpp" @@ -20,6 +21,9 @@ namespace MWWorld if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return; + if (!MWBase::Environment::get().getMechanicsManager()->onOpen(getTarget())) + return; + MWMechanics::diseaseContact(actor, getTarget()); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, getTarget()); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8a5e23ed9..cb5ded593 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1527,6 +1527,11 @@ namespace MWWorld mPhysics->queueObjectMovement(ptr, velocity); } + void World::updateAnimatedCollisionShape(const Ptr &ptr) + { + mPhysics->updateAnimatedCollisionShape(ptr); + } + void World::doPhysics(float duration) { mPhysics->stepSimulation(duration); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 8b3be2013..51953cd40 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -412,6 +412,8 @@ namespace MWWorld ///< Queues movement for \a ptr (in local space), to be applied in the next call to /// doPhysics. + void updateAnimatedCollisionShape(const Ptr &ptr) override; + bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) override; ///< cast a Ray and return true if there is an object in the ray path. From dcbca4b90bd63a2640f38ea30fbe222ab5a74ad5 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 14 Dec 2018 14:30:56 +0000 Subject: [PATCH 30/52] Use if(EXISTS ${OSGDB_LIB} AND NOT IS_DIRECTORY ${OSGDB_LIB}) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b499988c5..933893550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ set(USED_OSG_PLUGINS set(OSGPlugins_LIB_DIR "") foreach(OSGDB_LIB ${OSGDB_LIBRARY}) # Skip library type names - if(EXISTS ${OSGDB_LIB}) + if(EXISTS ${OSGDB_LIB} AND NOT IS_DIRECTORY ${OSGDB_LIB}) get_filename_component(OSG_LIB_DIR ${OSGDB_LIB} DIRECTORY) list(APPEND OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}") endif() From 76d380e852e171173152373aad20860482fa8c3f Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 16 Dec 2018 20:58:14 +0100 Subject: [PATCH 31/52] if unable to run git at this moment, use empty string --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cfc7ed92..bbd2e0165 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,9 +78,9 @@ execute_process ( COMMAND ${GIT_EXECUTABLE} log -1 --format='%aI' WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE EXITCODE3 - OUTPUT_VARIABLE COMMITDATE + OUTPUT_VARIABLE OPENMW_VERSION_COMMITDATE OUTPUT_STRIP_TRAILING_WHITESPACE) -string(SUBSTRING ${COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE) +string(SUBSTRING ${OPENMW_VERSION_COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE) # Macros include(OpenMWMacros) From 44a408635aeb29f0093fca160f57caf2845e247f Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Mon, 17 Dec 2018 16:30:12 +0100 Subject: [PATCH 32/52] wrap git command in gitfound --- CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bbd2e0165..282f58250 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,15 +72,19 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) else(GIT_FOUND) message(WARNING "Git executable not found") endif(GIT_FOUND) -endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) -execute_process ( - COMMAND ${GIT_EXECUTABLE} log -1 --format='%aI' - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - RESULT_VARIABLE EXITCODE3 - OUTPUT_VARIABLE OPENMW_VERSION_COMMITDATE - OUTPUT_STRIP_TRAILING_WHITESPACE) -string(SUBSTRING ${OPENMW_VERSION_COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE) + if(GIT_FOUND) + execute_process ( + COMMAND ${GIT_EXECUTABLE} log -1 --format='%aI' + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + RESULT_VARIABLE EXITCODE3 + OUTPUT_VARIABLE OPENMW_VERSION_COMMITDATE + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT EXITCODE3) + string(SUBSTRING ${OPENMW_VERSION_COMMITDATE} 1 10 OPENMW_VERSION_COMMITDATE) + endif(NOT EXITCODE3) + endif(GIT_FOUND) +endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) # Macros include(OpenMWMacros) From 922f696aaf4b483d0d2d8cd8d7393f11e65f0048 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Mon, 17 Dec 2018 16:52:49 +0100 Subject: [PATCH 33/52] bump bullet version for gitlab-ci --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 06fab6cce..6be563e9e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,8 +15,8 @@ Debian: - apt-get update -yq - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev # - apt-get install -y libmygui-dev libbullet-dev # to be updated to latest below because stretch is too old - - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet-dev_2.87+dfsg-2_amd64.deb -o libbullet-dev_2.87+dfsg-2_amd64.deb - - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet2.87_2.87+dfsg-2_amd64.deb -o libbullet2.87_2.87+dfsg-2_amd64.deb + - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet-dev_2.87+dfsg-3_amd64.deb -o libbullet-dev_2.87+dfsg-3_amd64.deb + - curl -L http://ftp.us.debian.org/debian/pool/main/b/bullet/libbullet2.87_2.87+dfsg-3_amd64.deb -o libbullet2.87_2.87+dfsg-3_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb -o libmygui.openglplatform0debian1v5_3.2.2+dfsg-1_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb -o libmyguiengine3debian1v5_3.2.2+dfsg-1_amd64.deb - curl -L https://http.kali.org/pool/main/m/mygui/libmygui-dev_3.2.2+dfsg-1_amd64.deb -o libmygui-dev_3.2.2+dfsg-1_amd64.deb From a58a8db03072b5f9dca667137cb302f3400d0d22 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 18 Dec 2018 18:42:20 +0000 Subject: [PATCH 34/52] Uncomment commented lines --- cmake/FindOSGPlugins.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/FindOSGPlugins.cmake b/cmake/FindOSGPlugins.cmake index f8c16921f..c210466c0 100644 --- a/cmake/FindOSGPlugins.cmake +++ b/cmake/FindOSGPlugins.cmake @@ -28,10 +28,10 @@ foreach(_library ${OSGPlugins_FIND_COMPONENTS}) set(_component OSGPlugins_${_library}) set(${_library_uc}_DIR ${OSGPlugins_LIB_DIR}) # to help function osg_find_library - #set(_saved_lib_prefix ${CMAKE_FIND_LIBRARY_PREFIXES}) # save CMAKE_FIND_LIBRARY_PREFIXES - #set(CMAKE_FIND_LIBRARY_PREFIXES "") # search libraries with no prefix + set(_saved_lib_prefix ${CMAKE_FIND_LIBRARY_PREFIXES}) # save CMAKE_FIND_LIBRARY_PREFIXES + set(CMAKE_FIND_LIBRARY_PREFIXES "") # search libraries with no prefix osg_find_library(${_library_uc} ${_library}) # find it into ${_library_uc}_LIBRARIES - #set(CMAKE_FIND_LIBRARY_PREFIXES ${_saved_lib_prefix}) # restore prefix + set(CMAKE_FIND_LIBRARY_PREFIXES ${_saved_lib_prefix}) # restore prefix if (${_library_uc}_LIBRARIES) set(${_component}_LIBRARY ${${_library_uc}_LIBRARIES}) # fake as if we call find_library From 53188f61fcec55150046dad4bd4a1cd5ec68a3c6 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 18 Dec 2018 19:44:30 +0000 Subject: [PATCH 35/52] Fix animation bug with VAOs --- components/sceneutil/morphgeometry.cpp | 6 ++++++ components/sceneutil/riggeometry.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/components/sceneutil/morphgeometry.cpp b/components/sceneutil/morphgeometry.cpp index 1b7e4ca93..01bb35c45 100644 --- a/components/sceneutil/morphgeometry.cpp +++ b/components/sceneutil/morphgeometry.cpp @@ -2,6 +2,8 @@ #include +#include + namespace SceneUtil { @@ -176,6 +178,10 @@ void MorphGeometry::cull(osg::NodeVisitor *nv) positionDst->dirty(); +#if OSG_MIN_VERSION_REQUIRED(3, 5, 6) + geom.dirtyGLObjects(); +#endif + nv->pushOntoNodePath(&geom); nv->apply(geom); nv->popFromNodePath(); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 30a3f076c..b086cf628 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include #include "skeleton.hpp" @@ -235,6 +237,10 @@ void RigGeometry::cull(osg::NodeVisitor* nv) if (tangentDst) tangentDst->dirty(); +#if OSG_MIN_VERSION_REQUIRED(3, 5, 6) + geom.dirtyGLObjects(); +#endif + nv->pushOntoNodePath(&geom); nv->apply(geom); nv->popFromNodePath(); From 2681435857a65387df3ef250dd3df6fe687bea22 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 20 Dec 2018 19:32:16 +0300 Subject: [PATCH 36/52] Editor: handle AI settings, regional sound and levelled list "none" chances as shorts (bug #2987) --- CHANGELOG.md | 1 + .../opencs/model/tools/referenceablecheck.cpp | 19 +++++++++++++++++++ apps/opencs/model/tools/regioncheck.cpp | 6 ++++++ apps/opencs/model/world/data.cpp | 2 +- apps/opencs/model/world/refidcollection.cpp | 10 +++++----- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d28da21ce..1256da340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ 0.46.0 ------ + Bug #2987: Editor: some chance and AI data fields can overflow Bug #3623: Fix HiDPI on Windows Bug #4540: Rain delay when exiting water Bug #4701: PrisonMarker record is not hardcoded like other markers diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index fdbab7fd0..73c28f564 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -470,6 +470,13 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( if (creature.mData.mSoul < 0) messages.add(id, "Soul value is negative", "", CSMDoc::Message::Severity_Error); + if (creature.mAiData.mAlarm > 100) + messages.add(id, "Alarm rating is over 100", "", CSMDoc::Message::Severity_Warning); + if (creature.mAiData.mFight > 100) + messages.add(id, "Fight rating is over 100", "", CSMDoc::Message::Severity_Warning); + if (creature.mAiData.mFlee > 100) + messages.add(id, "Flee rating is over 100", "", CSMDoc::Message::Severity_Warning); + for (int i = 0; i < 6; ++i) { if (creature.mData.mAttack[i] < 0) @@ -700,6 +707,13 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( if (level <= 0) messages.add(id, "Level is non-positive", "", CSMDoc::Message::Severity_Warning); + if (npc.mAiData.mAlarm > 100) + messages.add(id, "Alarm rating is over 100", "", CSMDoc::Message::Severity_Warning); + if (npc.mAiData.mFight > 100) + messages.add(id, "Fight rating is over 100", "", CSMDoc::Message::Severity_Warning); + if (npc.mAiData.mFlee > 100) + messages.add(id, "Flee rating is over 100", "", CSMDoc::Message::Severity_Warning); + if (gold < 0) messages.add(id, "Gold count is negative", "", CSMDoc::Message::Severity_Error); @@ -1014,6 +1028,11 @@ template void CSMTools::ReferenceableCheckStage::toolCheck ( template void CSMTools::ReferenceableCheckStage::listCheck ( const List& someList, CSMDoc::Messages& messages, const std::string& someID) { + if (someList.mChanceNone > 100) + { + messages.add(someID, "Chance that no object is used is over 100 percent", "", CSMDoc::Message::Severity_Warning); + } + for (unsigned i = 0; i < someList.mList.size(); ++i) { if (mReferencables.searchId(someList.mList[i].mId).first == -1) diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 0b6537d7f..1e6f64786 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -42,5 +42,11 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) if (chances != 100) messages.add(id, "Weather chances do not add up to 100", "", CSMDoc::Message::Severity_Error); + for (const ESM::Region::SoundRef& sound : region.mSoundList) + { + if (sound.mChance > 100) + messages.add(id, "Chance of '" + sound.mSound.toString() + "' sound to play is over 100 percent", "", CSMDoc::Message::Severity_Warning); + } + /// \todo check data members that can't be edited in the table view } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 53bd04147..3f18e8bd6 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -205,7 +205,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat mRegions.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_Sound)); mRegions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_UnsignedInteger8)); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 272722f64..89d346204 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -128,13 +128,13 @@ CSMWorld::RefIdCollection::RefIdCollection() ActorColumns actorsColumns (nameColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiHello, ColumnBase::Display_Integer)); + mColumns.push_back (RefIdColumn (Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger8)); actorsColumns.mHello = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFlee, ColumnBase::Display_Integer)); + mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8)); actorsColumns.mFlee = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFight, ColumnBase::Display_Integer)); + mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8)); actorsColumns.mFight = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer)); + mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8)); actorsColumns.mAlarm = &mColumns.back(); // Nested table @@ -645,7 +645,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); From f98a454ec15c62d98340c735fe6dcf71729d796e Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 16 Dec 2018 09:25:09 +0100 Subject: [PATCH 37/52] Add a script to verify macOS package contents --- .travis.yml | 1 + CI/check_package.osx.sh | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100755 CI/check_package.osx.sh diff --git a/.travis.yml b/.travis.yml index ef0a945a5..3d426d753 100644 --- a/.travis.yml +++ b/.travis.yml @@ -90,6 +90,7 @@ script: - cd ./build - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - cd "${TRAVIS_BUILD_DIR}" diff --git a/CI/check_package.osx.sh b/CI/check_package.osx.sh new file mode 100755 index 000000000..f5da5c273 --- /dev/null +++ b/CI/check_package.osx.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +hdiutil attach ./*.dmg -mountpoint "${TRAVIS_BUILD_DIR}/openmw-package" > /dev/null || echo "hdutil has failed" + +EXPECTED_PACKAGE_FILES=('Applications' 'OpenMW-CS.app' 'OpenMW.app') +PACKAGE_FILES=$(ls "${TRAVIS_BUILD_DIR}/openmw-package" | LC_ALL=C sort) + +DIFF=$(diff <(printf "%s\n" "${EXPECTED_PACKAGE_FILES[@]}") <(printf "%s\n" "${PACKAGE_FILES[@]}")) +DIFF_STATUS=$? + +if [[ $DIFF_STATUS -ne 0 ]]; then + echo "The package should only contain an Applications symlink and two applications, see the following diff for details." >&2 + echo "$DIFF" >&2 + exit 1 +fi From c3a2a2d73f3bc7bad90a271d9dfcfc3e8d6364aa Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 20 Dec 2018 19:53:51 +0100 Subject: [PATCH 38/52] Do not package Recastnavigation headers and static libs --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22b28a062..48df24774 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -604,7 +604,7 @@ set(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Do not build RecastDemo") set(RECASTNAVIGATION_STATIC ON CACHE BOOL "Build recastnavigation static libraries") set(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Do not build recastnavigation tests") -add_subdirectory (extern/recastnavigation) +add_subdirectory (extern/recastnavigation EXCLUDE_FROM_ALL) add_subdirectory (extern/osg-ffmpeg-videoplayer) add_subdirectory (extern/oics) if (BUILD_OPENCS) From e0161bb2bf1ac8b3f0e0d63179c0be0bb0967c52 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 20 Dec 2018 21:20:56 +0100 Subject: [PATCH 39/52] Update macOS dependencies, use Xcode 10.1 --- .travis.yml | 4 ++-- CI/before_install.osx.sh | 2 +- CI/before_script.osx.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef0a945a5..843fcb655 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,9 +37,9 @@ addons: build_command: "make VERBOSE=1 -j3" matrix: include: - - name: OpenMW (all) on MacOS xcode9.4 + - name: OpenMW (all) on macOS Xcode 10.1 os: osx - osx_image: xcode9.4 + osx_image: xcode10.1 if: branch != coverity_scan - name: OpenMW (all) on Ubuntu Xenial GCC-5 os: linux diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index d75ee3be5..722c1ad8c 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -6,5 +6,5 @@ brew outdated cmake || brew upgrade cmake brew outdated pkgconfig || brew upgrade pkgconfig brew install qt -curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-7cf2789.zip -o ~/openmw-deps.zip +curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-55c27b1.zip -o ~/openmw-deps.zip unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 16f461639..d3994a7ae 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -11,7 +11,7 @@ cd build cmake \ -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ --D CMAKE_OSX_SYSROOT="macosx10.13" \ +-D CMAKE_OSX_SYSROOT="macosx10.14" \ -D CMAKE_BUILD_TYPE=Release \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D DESIRED_QT_VERSION=5 \ From 09585b7208d6317c52980be47bc73c2e9e2a2176 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Sat, 22 Dec 2018 22:21:26 -0500 Subject: [PATCH 40/52] android_main.c: Replace nullptr back to NULL since there are no nullptr in C --- apps/openmw/android_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/android_main.c b/apps/openmw/android_main.c index 9a7b6bc50..d234a369d 100644 --- a/apps/openmw/android_main.c +++ b/apps/openmw/android_main.c @@ -20,14 +20,14 @@ void releaseArgv(); int Java_org_libsdl_app_SDLActivity_getMouseX(JNIEnv *env, jclass cls, jobject obj) { int ret = 0; - SDL_GetMouseState(&ret, nullptr); + SDL_GetMouseState(&ret, NULL); return ret; } int Java_org_libsdl_app_SDLActivity_getMouseY(JNIEnv *env, jclass cls, jobject obj) { int ret = 0; - SDL_GetMouseState(nullptr, &ret); + SDL_GetMouseState(NULL, &ret); return ret; } From 0bbcc0e787a12fd5ec3dfc940b503ca814eab57c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 23 Dec 2018 13:39:35 +0300 Subject: [PATCH 41/52] Avoid falling height reset if onGround state didn't change (bug #4411) --- CHANGELOG.md | 1 + apps/openmw/mwphysics/physicssystem.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1256da340..190ba3692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Bug #2987: Editor: some chance and AI data fields can overflow Bug #3623: Fix HiDPI on Windows + Bug #4411: Reloading a saved game while falling prevents damage in some cases Bug #4540: Rain delay when exiting water Bug #4701: PrisonMarker record is not hardcoded like other markers Bug #4714: Crash upon game load in the repair menu while the "Your repair failed!" message is active diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 836370255..a4fd2c1ca 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1339,7 +1339,7 @@ namespace MWPhysics float heightDiff = position.z() - oldHeight; MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); - if ((wasOnGround && physicActor->getOnGround()) || flying || world->isSwimming(iter->first) || slowFall < 1) + if ((numSteps > 0 && wasOnGround && physicActor->getOnGround()) || flying || world->isSwimming(iter->first) || slowFall < 1) stats.land(iter->first == player); else if (heightDiff < 0) stats.addToFallHeight(-heightDiff); From 98b2c044044b60089bb647aa0a67ad9bddabb1b0 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Sun, 1 Apr 2018 18:45:43 -0400 Subject: [PATCH 42/52] android: Add a method so that we can send relative mouse movements from java. --- apps/openmw/android_main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/openmw/android_main.c b/apps/openmw/android_main.c index d234a369d..393d48d77 100644 --- a/apps/openmw/android_main.c +++ b/apps/openmw/android_main.c @@ -35,6 +35,17 @@ int Java_org_libsdl_app_SDLActivity_isMouseShown(JNIEnv *env, jclass cls, jobjec return SDL_ShowCursor(SDL_QUERY); } +extern SDL_Window *Android_Window; +int SDL_SendMouseMotion(SDL_Window * window, int mouseID, int relative, int x, int y); +void Java_org_libsdl_app_SDLActivity_sendRelativeMouseMotion(JNIEnv *env, jclass cls, int x, int y) { + SDL_SendMouseMotion(Android_Window, 0, 1, x, y); +} + +int SDL_SendMouseButton(SDL_Window * window, int mouseID, Uint8 state, Uint8 button); +void Java_org_libsdl_app_SDLActivity_sendMouseButton(JNIEnv *env, jclass cls, int state, int button) { + SDL_SendMouseButton(Android_Window, 0, state, button); +} + int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) { setenv("OPENMW_DECOMPRESS_TEXTURES", "1", 1); From 8e7c01b5615f295611530e7cda61c5b10083370a Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Mon, 24 Dec 2018 01:50:58 -0500 Subject: [PATCH 43/52] loadingscreen: Fix UaF in loading screen. When the CopyFramebufferToTextureCallback callback is called, in its operator() it resets setInitialDrawCallback by providing a NULL pointer. However, this causes the callback to get deleted. In turn, the "this" pointer is invalidated. When execution returns to DrawCallback::run, it accesses a _nestedCallback member of deleted "this" which is UB. --- apps/openmw/mwgui/loadingscreen.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 7f641d408..68cf0439a 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -141,10 +141,6 @@ namespace MWGui int w = renderInfo.getCurrentCamera()->getViewport()->width(); int h = renderInfo.getCurrentCamera()->getViewport()->height(); mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h); - - // Callback removes itself when done - if (renderInfo.getCurrentCamera()) - renderInfo.getCurrentCamera()->setInitialDrawCallback(nullptr); } private: @@ -308,6 +304,8 @@ namespace MWGui mGuiTexture.reset(new osgMyGUI::OSGTexture(mTexture)); } + // Notice that the next time this is called, the current CopyFramebufferToTextureCallback will be deleted + // so there's no memory leak as at most one object of type CopyFramebufferToTextureCallback is allocated at a time. mViewer->getCamera()->setInitialDrawCallback(new CopyFramebufferToTextureCallback(mTexture)); mBackgroundImage->setBackgroundImage(""); From 07e9ce84b3480a8634c5da8b97fec609326c1ec2 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Mon, 24 Dec 2018 02:49:36 -0500 Subject: [PATCH 44/52] Replace volatile bools with std::atomic --- apps/openmw/mwsound/openal_output.cpp | 5 +++-- apps/openmw/mwworld/cellpreloader.cpp | 6 ++++-- components/sceneutil/workqueue.hpp | 3 ++- extern/osg-ffmpeg-videoplayer/videostate.hpp | 11 ++++++----- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 39e872b0c..ccb3f22b5 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -279,7 +280,7 @@ private: std::unique_ptr mLoudnessAnalyzer; - volatile bool mIsFinished; + std::atomic mIsFinished; void updateAll(bool local); @@ -313,7 +314,7 @@ struct OpenAL_Output::StreamThread : public OpenThreads::Thread { typedef std::vector StreamVec; StreamVec mStreams; - volatile bool mQuitNow; + std::atomic mQuitNow; OpenThreads::Mutex mMutex; OpenThreads::Condition mCondVar; diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index a06c208b5..3bf66a5a1 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -1,5 +1,7 @@ #include "cellpreloader.hpp" +#include + #include #include #include @@ -159,7 +161,7 @@ namespace MWWorld MWRender::LandManager* mLandManager; bool mPreloadInstances; - volatile bool mAbort; + std::atomic mAbort; osg::ref_ptr mTerrainView; @@ -392,7 +394,7 @@ namespace MWWorld } private: - volatile bool mAbort; + std::atomic mAbort; std::vector > mTerrainViews; Terrain::World* mWorld; std::vector mPreloadPositions; diff --git a/components/sceneutil/workqueue.hpp b/components/sceneutil/workqueue.hpp index 2084df328..0b16db0e7 100644 --- a/components/sceneutil/workqueue.hpp +++ b/components/sceneutil/workqueue.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace SceneUtil @@ -87,7 +88,7 @@ namespace SceneUtil private: WorkQueue* mWorkQueue; - volatile bool mActive; + std::atomic mActive; }; diff --git a/extern/osg-ffmpeg-videoplayer/videostate.hpp b/extern/osg-ffmpeg-videoplayer/videostate.hpp index a60d6032f..6abaa64cd 100644 --- a/extern/osg-ffmpeg-videoplayer/videostate.hpp +++ b/extern/osg-ffmpeg-videoplayer/videostate.hpp @@ -2,6 +2,7 @@ #define VIDEOPLAYER_VIDEOSTATE_H #include +#include #include #include #include @@ -78,7 +79,7 @@ struct PacketQueue { { clear(); } AVPacketList *first_pkt, *last_pkt; - volatile bool flushing; + std::atomic flushing; int nb_packets; int size; @@ -169,12 +170,12 @@ struct VideoState { std::unique_ptr parse_thread; std::unique_ptr video_thread; - volatile bool mSeekRequested; + std::atomic mSeekRequested; uint64_t mSeekPos; - volatile bool mVideoEnded; - volatile bool mPaused; - volatile bool mQuit; + std::atomic mVideoEnded; + std::atomic mPaused; + std::atomic mQuit; }; } From 1bdec2399fab05dcd18b8bc8ec3423c9ab26b354 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 25 Dec 2018 11:56:24 -0500 Subject: [PATCH 45/52] Make sure CopyFramebufferToTextureCallback is only called once and not every frame --- apps/openmw/mwgui/loadingscreen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 68cf0439a..a9480f261 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -133,11 +133,15 @@ namespace MWGui public: CopyFramebufferToTextureCallback(osg::Texture2D* texture) : mTexture(texture) + , oneshot(true) { } virtual void operator () (osg::RenderInfo& renderInfo) const { + if (!oneshot) + return; + oneshot = false; int w = renderInfo.getCurrentCamera()->getViewport()->width(); int h = renderInfo.getCurrentCamera()->getViewport()->height(); mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h); @@ -145,6 +149,7 @@ namespace MWGui private: osg::ref_ptr mTexture; + mutable bool oneshot; }; class DontComputeBoundCallback : public osg::Node::ComputeBoundingSphereCallback From 956934911a3053442ae8876b8ae735eb2b551e07 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Tue, 25 Dec 2018 21:04:21 +0100 Subject: [PATCH 46/52] [macOS, CI] Use CMake 3.12.4 See https://gitlab.com/OpenMW/openmw/issues/4767 for details. --- CI/before_install.osx.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 722c1ad8c..43102356e 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -1,8 +1,9 @@ #!/bin/sh -e brew update - -brew outdated cmake || brew upgrade cmake +brew unlink cmake || true +brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/a3b64391ebace30b84de8e7997665a1621c0b2c0/Formula/cmake.rb +brew switch cmake 3.12.4 brew outdated pkgconfig || brew upgrade pkgconfig brew install qt From 2306d904c779ff6154cf3d1cfcfb2d8da71702f9 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Wed, 26 Dec 2018 16:57:10 +0100 Subject: [PATCH 47/52] [macOS] Fail CMake when trying to use CMake 3.13 for macOS packaging --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48df24774..f34e3c83c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -795,6 +795,10 @@ endif() # Apple bundling if (OPENMW_OSX_DEPLOYMENT AND APPLE AND DESIRED_QT_VERSION MATCHES 5) + if (${CMAKE_MAJOR_VERSION} STREQUAL "3" AND ${CMAKE_MINOR_VERSION} STREQUAL "13") + message(FATAL_ERROR "macOS packaging is broken in CMake 3.13.*, see https://gitlab.com/OpenMW/openmw/issues/4767. Please use an older version like 3.12.4") + endif () + get_property(QT_COCOA_PLUGIN_PATH TARGET Qt5::QCocoaIntegrationPlugin PROPERTY LOCATION_RELEASE) get_filename_component(QT_COCOA_PLUGIN_DIR "${QT_COCOA_PLUGIN_PATH}" DIRECTORY) get_filename_component(QT_COCOA_PLUGIN_GROUP "${QT_COCOA_PLUGIN_DIR}" NAME) From 7155e787b4615c2db0981ab633088b8ad632cbdf Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 27 Dec 2018 23:20:58 +0300 Subject: [PATCH 48/52] Clean up fallback record creation --- apps/opencs/model/world/data.cpp | 14 ++++++++++---- apps/openmw/mwworld/store.cpp | 27 +++++++++++++++------------ components/esm/attr.hpp | 7 ------- components/esm/loaddoor.hpp | 15 --------------- components/esm/loadstat.hpp | 10 ---------- 5 files changed, 25 insertions(+), 48 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 3f18e8bd6..9e9447c5a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -989,23 +989,29 @@ void CSMWorld::Data::loadFallbackEntries() std::make_pair("PrisonMarker", "marker_prison.nif") }; - for (const std::pair marker : staticMarkers) + for (const std::pair &marker : staticMarkers) { if (mReferenceables.searchId (marker.first)==-1) { + ESM::Static newMarker; + newMarker.mId = marker.first; + newMarker.mModel = marker.second; CSMWorld::Record record; - record.mBase = ESM::Static(marker.first, marker.second); + record.mBase = newMarker; record.mState = CSMWorld::RecordBase::State_BaseOnly; mReferenceables.appendRecord (record, CSMWorld::UniversalId::Type_Static); } } - for (const std::pair marker : doorMarkers) + for (const std::pair &marker : doorMarkers) { if (mReferenceables.searchId (marker.first)==-1) { + ESM::Door newMarker; + newMarker.mId = marker.first; + newMarker.mModel = marker.second; CSMWorld::Record record; - record.mBase = ESM::Door(marker.first, std::string(), marker.second, std::string(), std::string(), std::string()); + record.mBase = newMarker; record.mState = CSMWorld::RecordBase::State_BaseOnly; mReferenceables.appendRecord (record, CSMWorld::UniversalId::Type_Door); } diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 70f8cf44f..7df61bec3 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -1007,14 +1007,13 @@ namespace MWWorld } void Store::setUp() { - for (int i = 0; i < ESM::Attribute::Length; ++i) { - mStatic.push_back( - ESM::Attribute( - ESM::Attribute::sAttributeIds[i], - ESM::Attribute::sGmstAttributeIds[i], - ESM::Attribute::sGmstAttributeDescIds[i] - ) - ); + for (int i = 0; i < ESM::Attribute::Length; ++i) + { + ESM::Attribute newAttribute; + newAttribute.mId = ESM::Attribute::sAttributeIds[i]; + newAttribute.mName = ESM::Attribute::sGmstAttributeIds[i]; + newAttribute.mDescription = ESM::Attribute::sGmstAttributeDescIds[i]; + mStatic.push_back(newAttribute); } } size_t Store::getSize() const @@ -1066,11 +1065,13 @@ namespace MWWorld std::make_pair("travelmarker", "marker_travel.nif") }; - for (const std::pair marker : markers) + for (const std::pair &marker : markers) { if (search(marker.first) == 0) { - ESM::Static newMarker = ESM::Static(marker.first, marker.second); + ESM::Static newMarker; + newMarker.mId = marker.first; + newMarker.mModel = marker.second; std::pair ret = mStatic.insert(std::make_pair(marker.first, newMarker)); if (ret.first != mStatic.end()) { @@ -1088,11 +1089,13 @@ namespace MWWorld std::make_pair("prisonmarker", "marker_prison.nif") }; - for (const std::pair marker : markers) + for (const std::pair &marker : markers) { if (search(marker.first) == 0) { - ESM::Door newMarker = ESM::Door(marker.first, std::string(), marker.second, std::string(), std::string(), std::string()); + ESM::Door newMarker; + newMarker.mId = marker.first; + newMarker.mModel = marker.second; std::pair ret = mStatic.insert(std::make_pair(marker.first, newMarker)); if (ret.first != mStatic.end()) { diff --git a/components/esm/attr.hpp b/components/esm/attr.hpp index 993de6ccb..c0a54c659 100644 --- a/components/esm/attr.hpp +++ b/components/esm/attr.hpp @@ -32,13 +32,6 @@ struct Attribute static const std::string sGmstAttributeIds[Length]; static const std::string sGmstAttributeDescIds[Length]; static const std::string sAttributeIcons[Length]; - - Attribute(AttributeID id, const std::string &name, const std::string &description) - : mId(id) - , mName(name) - , mDescription(description) - { - } }; } #endif diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index 955abec89..3afe5d5e4 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -22,21 +22,6 @@ struct Door void blank(); ///< Set record to default state (does not touch the ID). - - Door(const std::string id, const std::string name, const std::string &model, - const std::string script, const std::string opensound, const std::string closesound) - : mId(id) - , mName(name) - , mModel(model) - , mScript(script) - , mOpenSound(opensound) - , mCloseSound(closesound) - { - } - - Door() - { - } }; } #endif diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index f80875b65..3d9144040 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -33,16 +33,6 @@ struct Static void blank(); ///< Set record to default state (does not touch the ID). - - Static(const std::string id, const std::string &model) - : mId(id) - , mModel(model) - { - } - - Static() - { - } }; } #endif From 467724d5e8b5ede4e8b71b7d8ee4aac49747ba9d Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 28 Dec 2018 23:49:06 +0300 Subject: [PATCH 49/52] Improve fallback numerical value handling (bug #4768) --- CHANGELOG.md | 1 + components/fallback/fallback.cpp | 84 +++++++++++++++++++------------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1256da340..f4fa6ecfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Bug #4745: Editor: Interior cell lighting field values are not displayed as colors Bug #4746: Non-solid player can't run or sneak Bug #4750: Sneaking doesn't work in first person view if the player is in attack ready state + Bug #4768: Fallback numerical value recovery chokes on invalid arguments Feature #2229: Improve pathfinding AI Feature #3442: Default values for fallbacks from ini file Feature #3610: Option to invert X axis diff --git a/components/fallback/fallback.cpp b/components/fallback/fallback.cpp index edc3f2678..70ee2f681 100644 --- a/components/fallback/fallback.cpp +++ b/components/fallback/fallback.cpp @@ -1,70 +1,86 @@ #include "fallback.hpp" -#include - +#include namespace Fallback { - bool stob(std::string const& s) { - return s != "0"; - } - Map::Map(const std::map& fallback):mFallbackMap(fallback) {} std::string Map::getFallbackString(const std::string& fall) const { std::map::const_iterator it; - if((it = mFallbackMap.find(fall)) == mFallbackMap.end()) + if ((it = mFallbackMap.find(fall)) == mFallbackMap.end()) { - return ""; + return std::string(); } return it->second; } float Map::getFallbackFloat(const std::string& fall) const { - std::string fallback=getFallbackString(fall); - if (fallback.empty()) - return 0; - else - return boost::lexical_cast(fallback); + std::string fallback = getFallbackString(fall); + if (!fallback.empty()) + { + try + { + return std::stof(fallback); + } + catch (const std::invalid_argument&) + { + Log(Debug::Error) << "Error: '" << fall << "' setting value (" << fallback << ") is not a valid number, using 0 as a fallback"; + } + } + + return 0; } int Map::getFallbackInt(const std::string& fall) const { - std::string fallback=getFallbackString(fall); - if (fallback.empty()) - return 0; - else - return std::stoi(fallback); + std::string fallback = getFallbackString(fall); + if (!fallback.empty()) + { + try + { + return std::stoi(fallback); + } + catch (const std::invalid_argument&) + { + Log(Debug::Error) << "Error: '" << fall << "' setting value (" << fallback << ") is not a valid number, using 0 as a fallback"; + } + } + + return 0; } bool Map::getFallbackBool(const std::string& fall) const { - std::string fallback=getFallbackString(fall); - if (fallback.empty()) - return false; - else - return stob(fallback); + return getFallbackString(fall) != "0"; } osg::Vec4f Map::getFallbackColour(const std::string& fall) const { - std::string sum=getFallbackString(fall); - if (sum.empty()) - return osg::Vec4f(0.5f,0.5f,0.5f,1.f); - else + std::string sum = getFallbackString(fall); + if (!sum.empty()) { - std::string ret[3]; - unsigned int j=0; - for(unsigned int i=0;i Date: Sat, 29 Dec 2018 15:18:26 +0300 Subject: [PATCH 50/52] Revert to lexical_cast, catch out-of-range exceptions --- components/fallback/fallback.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/components/fallback/fallback.cpp b/components/fallback/fallback.cpp index 70ee2f681..473d10ba4 100644 --- a/components/fallback/fallback.cpp +++ b/components/fallback/fallback.cpp @@ -2,6 +2,8 @@ #include +#include + namespace Fallback { Map::Map(const std::map& fallback):mFallbackMap(fallback) @@ -24,9 +26,11 @@ namespace Fallback { try { - return std::stof(fallback); + // We have to rely on Boost because std::stof from C++11 + // uses the current locale for separators which we don't want and often silently ignores parsing errors. + return boost::lexical_cast(fallback); } - catch (const std::invalid_argument&) + catch (boost::bad_lexical_cast&) { Log(Debug::Error) << "Error: '" << fall << "' setting value (" << fallback << ") is not a valid number, using 0 as a fallback"; } @@ -48,6 +52,10 @@ namespace Fallback { Log(Debug::Error) << "Error: '" << fall << "' setting value (" << fallback << ") is not a valid number, using 0 as a fallback"; } + catch (const std::out_of_range&) + { + Log(Debug::Error) << "Error: '" << fall << "' setting value (" << fallback << ") is out of range, using 0 as a fallback"; + } } return 0; From a9619dbe036721b05ac1665b2f510714277f9d87 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 30 Dec 2018 17:04:25 +0300 Subject: [PATCH 51/52] Update Fonts documentation --- docs/source/reference/modding/font.rst | 63 +++++++++++++++++++++----- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/docs/source/reference/modding/font.rst b/docs/source/reference/modding/font.rst index 213cdf760..cae320633 100644 --- a/docs/source/reference/modding/font.rst +++ b/docs/source/reference/modding/font.rst @@ -4,9 +4,8 @@ Fonts Morrowind .fnt fonts -------------------- -Morrowind uses a custom ``.fnt`` file format. It is not compatible with the Windows Font File ``.fnt`` format, -nor compatible with ``.fnt`` formats from any other Bethesda games. To our knowledge, -the format is undocumented and no tools for viewing or editing these fonts exist. +Morrowind uses a custom ``.fnt`` file format. It is not compatible with the Windows Font File ``.fnt`` format. +To our knowledge, the format is undocumented. OpenMW can load this format and convert it on the fly into something usable (see font loader `source code `_). @@ -16,20 +15,62 @@ In OpenMW 0.32, an --export-fonts command line option was added to write the con TrueType fonts -------------- -Unlike vanilla Morrowind, OpenMW directly supports TrueType (``.ttf``) fonts. -This is the recommended way to create new fonts. +Unlike vanilla Morrowind, OpenMW directly supports TrueType (``.ttf``) fonts. + +0.45.0+ way +----------- +This is the recommended way to install replacement fonts. + +- To replace the primary "Magic Cards" font: + + #. Download `Pelagiad `_ by Isak Larborn (aka Isaskar). + #. Create ``Fonts`` folder at the location of your ``openmw.cfg``. + #. Copy ``openmw_font.xml`` and ``Pelagiad.ttf`` files into the folder. + #. If desired, you can now delete the original ``Magic_Cards.*`` files from your ``Data Files/Fonts`` directory. + #. Pelagiad glyphs may appear to be pretty small, so open ``openmw.cfg`` and adjust the following settings as you deem necessary:: + + [GUI] + font size = 17 + ttf resolution = 96 + +- You can also replace the Daedric font: + + #. Download `Ayembedt `_ by Georg Duffner. + #. Install ``OMWAyembedt.otf`` into the ``Fonts`` folder. + #. Add the following lines into ``openmw_font.xml``:: + + + + + + + + + + + + + + #. This font is missing a few glyphs (mostly punctuation), but it has all the primary glyphs. If desired, you can now delete the original ``daedric.*`` files from your ``Data Files/Fonts`` directory. + +Any Resolution or Size properties in the file have no effect because the engine settings override them. + +The engine automatically takes UI scaling factor into account, so don't account for it when tweaking the settings. + +Pre-0.45.0 way +-------------- - To replace the primary "Magic Cards" font: #. Download `Pelagiad `_ by Isak Larborn (aka Isaskar). #. Install the ``openmw_font.xml`` file into ``resources/mygui/openmw_font.xml`` in your OpenMW installation. #. Copy ``Pelagiad.ttf`` into ``resources/mygui/`` as well. - #. If desired, you can now delete the original ``Magic_Cards.*`` files from your Data Files/Fonts directory. + #. If desired, you can now delete the original ``Magic_Cards.*`` files from your ``Data Files/Fonts`` directory. - You can also replace the Daedric font: #. Download `Ayembedt `_ by Georg Duffner. #. Install ``OMWAyembedt.otf`` into ``/resources/mygui/`` folder in your OpenMW installation. - #. Add the following lines to openmw_font.xml:: + #. Add the following lines to ``openmw_font.xml``:: @@ -45,12 +86,12 @@ This is the recommended way to create new fonts. - #. This font is missing a few glyphs (mostly punctuation), but is complete in the primary glyphs. If desired, you can now delete the original ``daedric.*`` files from your Data Files/Fonts directory. + #. This font is missing a few glyphs (mostly punctuation), but it has all the primary glyphs. If desired, you can now delete the original ``daedric.*`` files from your ``Data Files/Fonts`` directory. - Another replacement for the Daedric font is `Oblivion `_ by Dongle. - #. Install the ``Oblivion.ttf`` file resources/mygui/. - #. The openmw_fonts.xml entry is:: + #. Install the ``Oblivion.ttf`` file into ``resources/mygui/``. + #. The ``openmw_font.xml`` entry is:: @@ -80,7 +121,7 @@ This is the recommended way to create new fonts. Bitmap fonts ------------ -Morrowind ``.fnt`` files are essentially a bitmap font, but using them is discouraged because of no Unicode support. +Morrowind ``.fnt`` files are essentially a bitmap font, but using them is discouraged because they don't have Unicode support. MyGUI has its own format for bitmap fonts. An example can be seen by using the --export-fonts command line option (see above), which converts Morrowind ``.fnt`` to a MyGUI bitmap font. This is the recommended format to use if you wish to edit Morrowind's bitmap font or create a new bitmap font. From ee2560edc3b73949502ab4b4720d2e04262c52b8 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 31 Dec 2018 14:47:00 +0300 Subject: [PATCH 52/52] Fix constant raining --- components/fallback/fallback.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/fallback/fallback.cpp b/components/fallback/fallback.cpp index 473d10ba4..9e64d5fea 100644 --- a/components/fallback/fallback.cpp +++ b/components/fallback/fallback.cpp @@ -63,7 +63,8 @@ namespace Fallback bool Map::getFallbackBool(const std::string& fall) const { - return getFallbackString(fall) != "0"; + std::string fallback = getFallbackString(fall); + return !fallback.empty() && fallback != "0"; } osg::Vec4f Map::getFallbackColour(const std::string& fall) const