diff --git a/.travis.yml b/.travis.yml index 4f811ee0f4..3e98b1f961 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ os: - linux -# - osx -osx_image: xcode7.2 + - osx +osx_image: xcode7.3 language: cpp sudo: required dist: trusty @@ -15,6 +15,7 @@ env: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "jybGzAdUbqt9vWR/GEnRd96BgAi/7Zd1+2HK68j/i/8+/1YH2XxLOy4Jv/DUBhBlJIkxs/Xv8dRcUlFOclZDHX1d/9Qnsqd3oUVkD7k1y7cTOWy9TBQaE/v/kZo3LpzA3xPwwthrb0BvqIbOfIELi5fS5s8ba85WFRg3AX70wWE=" + - macos_qt_formula=qt@5.5 addons: apt: sources: @@ -62,9 +63,9 @@ script: - 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 notifications: - recipients: - - corrmage+travis-ci@gmail.com email: + recipients: + - corrmage+travis-ci@gmail.com on_success: change on_failure: always irc: diff --git a/AUTHORS.md b/AUTHORS.md index 83777df189..185b5ee665 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -78,6 +78,7 @@ Programmers Kurnevsky Evgeny (kurnevsky) Lars Söderberg (Lazaroth) lazydev + Leon Krieg (lkrieg) Leon Saunders (emoose) lohikaarme Lukasz Gromanowski (lgro) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 8a306186e2..a2ea720e53 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -5,7 +5,7 @@ brew update brew rm cmake || true brew rm pkgconfig || true brew rm qt5 || true -brew install cmake pkgconfig qt55 +brew install cmake pkgconfig $macos_qt_formula curl http://downloads.openmw.org/osx/dependencies/openmw-deps-263d4a8.zip -o ~/openmw-deps.zip unzip ~/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 00a948c652..6955825a40 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -4,7 +4,7 @@ export CXX=clang++ export CC=clang DEPENDENCIES_ROOT="/private/tmp/openmw-deps/openmw-deps" -QT_PATH="/usr/local/opt/qt55" +QT_PATH=`brew --prefix $macos_qt_formula` mkdir build cd build diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 9d82af022d..c363185ee0 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -47,6 +47,34 @@ namespace ESSImport controls.mVanityModeDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_VanityModeDisabled; controls.mWeaponDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_WeaponDrawingDisabled; controls.mSpellDrawingDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_SpellDrawingDisabled; + + if (pcdt.mHasMark) + { + out.mHasMark = 1; + + const PCDT::PNAM::MarkLocation& mark = pcdt.mPNAM.mMarkLocation; + + ESM::CellId cell; + cell.mWorldspace = ESM::CellId::sDefaultWorldspace; + cell.mPaged = true; + + cell.mIndex.mX = mark.mCellX; + cell.mIndex.mY = mark.mCellY; + + // TODO: Figure out a better way to detect interiors. (0, 0) is a valid exterior cell. + if (mark.mCellX == 0 && mark.mCellY == 0) + { + cell.mWorldspace = pcdt.mMNAM; + cell.mPaged = false; + } + + out.mMarkedCell = cell; + out.mMarkedPosition.pos[0] = mark.mX; + out.mMarkedPosition.pos[1] = mark.mY; + out.mMarkedPosition.pos[2] = mark.mZ; + out.mMarkedPosition.rot[0] = out.mMarkedPosition.rot[1] = 0.0f; + out.mMarkedPosition.rot[2] = mark.mRotZ; + } } } diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index fde247ebff..2288b149c2 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -63,7 +63,7 @@ namespace ESSImport playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0; mPlayer.mCellId = playerCellId; //mPlayer.mLastKnownExteriorPosition - mPlayer.mHasMark = 0; // TODO + mPlayer.mHasMark = 0; mPlayer.mCurrentCrimeId = 0; // TODO mPlayer.mObject.blank(); mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame diff --git a/apps/essimporter/importplayer.cpp b/apps/essimporter/importplayer.cpp index 9845ab072a..85a3c3fd5d 100644 --- a/apps/essimporter/importplayer.cpp +++ b/apps/essimporter/importplayer.cpp @@ -23,9 +23,12 @@ namespace ESSImport mKnownDialogueTopics.push_back(esm.getHString()); } + mHasMark = false; if (esm.isNextSub("MNAM")) - esm.skipHSub(); // If this field is here it seems to specify the interior cell the player is in, - // but it's not always here, so it's kinda useless + { + mHasMark = true; + mMNAM = esm.getHString(); + } esm.getHNT(mPNAM, "PNAM"); @@ -50,8 +53,12 @@ namespace ESSImport if (esm.isNextSub("NAM3")) esm.skipHSub(); + mHasENAM = false; if (esm.isNextSub("ENAM")) - esm.skipHSub(); + { + mHasENAM = true; + esm.getHT(mENAM); + } if (esm.isNextSub("LNAM")) esm.skipHSub(); diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 9f6b055c0e..7759944447 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -42,8 +42,11 @@ struct PCDT { PlayerFlags_ViewSwitchDisabled = 0x1, PlayerFlags_ControlsDisabled = 0x4, + PlayerFlags_Sleeping = 0x10, + PlayerFlags_Waiting = 0x40, PlayerFlags_WeaponDrawn = 0x80, PlayerFlags_SpellDrawn = 0x100, + PlayerFlags_InJail = 0x200, PlayerFlags_JumpingDisabled = 0x1000, PlayerFlags_LookingDisabled = 0x2000, PlayerFlags_VanityModeDisabled = 0x4000, @@ -68,19 +71,44 @@ struct PCDT struct PNAM { + struct MarkLocation + { + float mX, mY, mZ; // worldspace position + float mRotZ; // Z angle in radians + int mCellX, mCellY; // grid coordinates; for interior cells this is always (0, 0) + }; + int mPlayerFlags; // controls, camera and draw state unsigned int mLevelProgress; float mSkillProgress[27]; // skill progress, non-uniform scaled unsigned char mSkillIncreases[8]; // number of skill increases for each attribute - unsigned char mUnknown3[84]; + int mTelekinesisRangeBonus; // in units; seems redundant + float mVisionBonus; // range: <0.0, 1.0>; affected by light spells and Get/Mod/SetPCVisionBonus + int mDetectKeyMagnitude; // seems redundant + int mDetectEnchantmentMagnitude; // seems redundant + int mDetectAnimalMagnitude; // seems redundant + MarkLocation mMarkLocation; + unsigned char mUnknown3[40]; unsigned char mSpecIncreases[3]; // number of skill increases for each specialization unsigned char mUnknown4; }; + + struct ENAM + { + int mCellX; + int mCellY; + }; #pragma pack(pop) std::vector mFactions; PNAM mPNAM; + bool mHasMark; + std::string mMNAM; // mark cell name; can also be sDefaultCellname or region name + + bool mHasENAM; + ENAM mENAM; // last exterior cell + void load(ESM::ESMReader& esm); }; diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index a360ed104c..4dd3e1edf6 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -425,7 +425,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( //stats checks if (creature.mData.mLevel < 1) - messages.push_back (std::make_pair (id, creature.mId + " has non-postive level")); + messages.push_back (std::make_pair (id, creature.mId + " has non-positive level")); if (creature.mData.mStrength < 0) messages.push_back (std::make_pair (id, creature.mId + " has negative strength")); diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index c116ec4e50..028a759dc4 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -330,6 +330,8 @@ namespace CSMWorld { ColumnId_WeatherName, "Type" }, { ColumnId_WeatherChance, "Percent Chance" }, + { ColumnId_Text, "Text" }, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 05bedb77d5..e3899af731 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -329,6 +329,8 @@ namespace CSMWorld ColumnId_WeatherName = 295, ColumnId_WeatherChance = 296, + ColumnId_Text = 297, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 8c2f8a46d8..9faf64d711 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -65,7 +65,7 @@ namespace CSMWorld void setRecord (const std::string& id, const RecordBase& record, UniversalId::Type type = UniversalId::Type_None); - ///< Add record or overwrite existing recrod. + ///< Add record or overwrite existing record. const RecordBase& getRecord (const std::string& id) const; diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 79e93fc3df..1539bd4a20 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -8,9 +8,9 @@ /*! \brief * Class for holding the model. Uses typical qt table abstraction/interface for granting access * to the individiual fields of the records, Some records are holding nested data (for instance - * inventory list of the npc). In casses like this, table model offers interface to access + * inventory list of the npc). In cases like this, table model offers interface to access * nested data in the qt way - that is specify parent. Since some of those nested data require - * multiple columns to represent informations, single int (default way to index model in the + * multiple columns to represent information, single int (default way to index model in the * qmodelindex) is not sufficiant. Therefore tablemodelindex class can hold two ints for the * sake of indexing two dimensions of the table. This model does not support multiple levels of * the nested data. Vast majority of methods makes sense only for the top level data. diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index ba9da577de..116adb69a7 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -8,7 +8,7 @@ * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). * - * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having childs! + * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having children! */ class QVariant; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 5f48b4315e..086e95c340 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -301,9 +301,9 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& } CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *scroll, const RefIdColumn *skill) + const RefIdColumn *scroll, const RefIdColumn *skill, const RefIdColumn *text) : EnchantableRefIdAdapter (UniversalId::Type_Book, columns), - mScroll (scroll), mSkill (skill) + mScroll (scroll), mSkill (skill), mText (text) {} QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column, @@ -318,6 +318,9 @@ QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column, if (column==mSkill) return record.get().mData.mSkillID; + if (column==mText) + return QString::fromUtf8 (record.get().mText.c_str()); + return EnchantableRefIdAdapter::getData (column, data, index); } @@ -333,6 +336,8 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& book.mData.mIsScroll = value.toInt(); else if (column==mSkill) book.mData.mSkillID = value.toInt(); + else if (column==mText) + book.mText = value.toString().toUtf8().data(); else { EnchantableRefIdAdapter::setData (column, data, index, value); diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index e828a7f4ef..757a8ad77d 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -696,11 +696,12 @@ namespace CSMWorld { const RefIdColumn *mScroll; const RefIdColumn *mSkill; + const RefIdColumn *mText; public: BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *scroll, - const RefIdColumn *skill); + const RefIdColumn *skill, const RefIdColumn *text); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index c4c8f8605d..74867d6265 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -297,6 +297,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); const RefIdColumn *attribute = &mColumns.back(); + mColumns.push_back (RefIdColumn (Columns::ColumnId_Text, ColumnBase::Display_LongString)); + const RefIdColumn *text = &mColumns.back(); + mColumns.push_back (RefIdColumn (Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType)); const RefIdColumn *clothingType = &mColumns.back(); @@ -656,7 +659,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor, partRef))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new BookRefIdAdapter (enchantableColumns, scroll, attribute))); + new BookRefIdAdapter (enchantableColumns, scroll, attribute, text))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, new ClothingRefIdAdapter (enchantableColumns, clothingType, partRef))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, diff --git a/apps/openmw/doc.hpp b/apps/openmw/doc.hpp index ffeef94e1e..5f9065013e 100644 --- a/apps/openmw/doc.hpp +++ b/apps/openmw/doc.hpp @@ -41,4 +41,4 @@ /// \namespace MWScript /// \ingroup openmw -/// \brief MW-specific script extentions and integration of the script system into OpenMW +/// \brief MW-specific script extensions and integration of the script system into OpenMW diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 7494d2b43b..830ba258b9 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -231,7 +231,7 @@ namespace MWClass if(lockLevel!=0) ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, in positive else - ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the origional one + ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the original one } void Door::unlock (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index c26b925f6f..2251759799 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -122,7 +122,7 @@ namespace MWClass info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); - // hide effects the player doesnt know about + // hide effects the player doesn't know about MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); for (unsigned int i=0; iupdate(); MWBase::Environment::get().getWindowManager()->setDragDrop(true); + + mIsOnDragAndDrop = true; } void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 2a5995e0c2..23a6f497ff 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1271,8 +1271,6 @@ namespace MWMechanics stats.getActiveSpells().clear(); calculateCreatureStatModifiers(iter->first, 0); - MWBase::Environment::get().getWorld()->enableActorCollision(iter->first, false); - if (cls.isEssential(iter->first)) MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); } @@ -1290,6 +1288,11 @@ namespace MWMechanics //player's death animation is over MWBase::Environment::get().getStateManager()->askLoadRecent(); } + else + { + // NPC death animation is over, disable actor collision + MWBase::Environment::get().getWorld()->enableActorCollision(iter->first, false); + } // Play Death Music if it was the player dying if(iter->first == getPlayer()) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 21eaa0de5f..d8dae8b79a 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -157,7 +157,7 @@ namespace MWMechanics * * TODO: * - * Use the Observer Pattern to co-ordinate attacks, provide intelligence on + * Use the observer pattern to coordinate attacks, provide intelligence on * whether the target was hit, etc. */ diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 4960c14c33..5e23e085e5 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -32,7 +32,7 @@ namespace MWMechanics class AiPackage { public: - ///Enumerates the various AITypes availible. + ///Enumerates the various AITypes available enum TypeId { TypeIdNone = -1, TypeIdWander = 0, diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 2a591d768c..73ddce4b48 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -336,7 +336,7 @@ namespace MWMechanics { ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(mReturnPosition)); - // actor position is already in world co-ordinates + // actor position is already in world coordinates ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos)); // don't take shortcuts for wandering @@ -473,8 +473,8 @@ namespace MWMechanics void AiWander::onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage, ESM::Position& pos) { - // Are we there yet? - if (pathTo(actor, mPathFinder.getPath().back(), duration, DESTINATION_TOLERANCE)) + // Is there no destination or are we there yet? + if ((!mPathFinder.isPathConstructed()) || pathTo(actor, mPathFinder.getPath().back(), duration, DESTINATION_TOLERANCE)) { stopWalking(actor, storage); storage.setState(Wander_ChooseAction); @@ -649,7 +649,7 @@ namespace MWMechanics ESM::Pathgrid::Point dest(storage.mAllowedNodes[randNode]); ToWorldCoordinates(dest, storage.mCell->getCell()); - // actor position is already in world co-ordinates + // actor position is already in world coordinates ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actorPos)); // don't take shortcuts for wandering @@ -693,8 +693,8 @@ namespace MWMechanics ESM::Pathgrid::Point pt = paths.back(); for(unsigned int j = 0; j < nodes.size(); j++) { - // FIXME: doesn't hadle a door with the same X/Y - // co-ordinates but with a different Z + // FIXME: doesn't handle a door with the same X/Y + // coordinates but with a different Z if(nodes[j].mX == pt.mX && nodes[j].mY == pt.mY) { nodes.erase(nodes.begin() + j); @@ -828,7 +828,7 @@ namespace MWMechanics // ... pathgrids don't usually include water, so swimmers ignore them if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor)) { - // get NPC's position in local (i.e. cell) co-ordinates + // get NPC's position in local (i.e. cell) coordinates osg::Vec3f npcPos(mInitialActorPosition); CoordinateConverter(cell).toLocal(npcPos); @@ -837,7 +837,7 @@ namespace MWMechanics // mAllowedNodes for this actor with pathgrid point indexes based on mDistance // and if the point is connected to the closest current point - // NOTE: mPoints and mAllowedNodes are in local co-ordinates + // NOTE: mPoints and mAllowedNodes are in local coordinates int pointIndex = 0; for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++) { diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index da7553ca02..f9b03ca5ed 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -119,7 +119,7 @@ namespace MWMechanics GroupIndex_MaxIdle = 9 }; - /// convert point from local (i.e. cell) to world co-ordinates + /// convert point from local (i.e. cell) to world coordinates void ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell * cell); void SetCurrentNodeToClosestAllowedNode(osg::Vec3f npcPos, AiWanderStorage& storage); diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 0c7e9cdba7..b0bdce8f1b 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -139,7 +139,7 @@ namespace MWMechanics * NOTE: It may be desirable to simply go directly to the endPoint if for * example there are no pathgrids in this cell. * - * NOTE: startPoint & endPoint are in world co-ordinates + * NOTE: startPoint & endPoint are in world coordinates * * Updates mPath using aStarSearch() or ray test (if shortcut allowed). * mPath consists of pathgrid points, except the last element which is @@ -148,7 +148,7 @@ namespace MWMechanics * pathgrid point (e.g. wander) then it may be worth while to call * pop_back() to remove the redundant entry. * - * NOTE: co-ordinates must be converted prior to calling GetClosestPoint() + * NOTE: coordinates must be converted prior to calling GetClosestPoint() * * | * | cell @@ -164,8 +164,8 @@ namespace MWMechanics * +----------------------------- * * i = x value of cell itself (multiply by ESM::Land::REAL_SIZE to convert) - * j = @.x in local co-ordinates (i.e. within the cell) - * k = @.x in world co-ordinates + * j = @.x in local coordinates (i.e. within the cell) + * k = @.x in world coordinates */ void PathFinder::buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, @@ -188,7 +188,7 @@ namespace MWMechanics return; } - // NOTE: GetClosestPoint expects local co-ordinates + // NOTE: GetClosestPoint expects local coordinates CoordinateConverter converter(mCell->getCell()); // NOTE: It is possible that GetClosestPoint returns a pathgrind point index @@ -230,7 +230,7 @@ namespace MWMechanics { mPath = mCell->aStarSearch(startNode, endNode.first); - // convert supplied path to world co-ordinates + // convert supplied path to world coordinates for (std::list::iterator iter(mPath.begin()); iter != mPath.end(); ++iter) { converter.toWorld(*iter); diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 83c56ca7d9..945a7f9272 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -84,7 +84,7 @@ namespace MWMechanics /** Synchronize new path with old one to avoid visiting 1 waypoint 2 times @note BuildPath() takes closest PathGrid point to NPC as first point of path. - This is undesireable if NPC has just passed a Pathgrid point, as this + This is undesirable if NPC has just passed a Pathgrid point, as this makes the 2nd point of the new path == the 1st point of old path. Which results in NPC "running in a circle" back to the just passed waypoint. */ @@ -122,11 +122,11 @@ namespace MWMechanics return (MWMechanics::PathFinder::MakeOsgVec3(point) - pos).length2(); } - // Return the closest pathgrid point index from the specified position co - // -ordinates. NOTE: Does not check if there is a sensible way to get there + // Return the closest pathgrid point index from the specified position + // coordinates. NOTE: Does not check if there is a sensible way to get there // (e.g. a cliff in front). // - // NOTE: pos is expected to be in local co-ordinates, as is grid->mPoints + // NOTE: pos is expected to be in local coordinates, as is grid->mPoints // static int GetClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos) { diff --git a/apps/openmw/mwmechanics/pathgrid.cpp b/apps/openmw/mwmechanics/pathgrid.cpp index 871baecdc3..c557beadd0 100644 --- a/apps/openmw/mwmechanics/pathgrid.cpp +++ b/apps/openmw/mwmechanics/pathgrid.cpp @@ -225,7 +225,7 @@ namespace MWMechanics * Should be possible to make this MT safe. * * Returns path which may be empty. path contains pathgrid points in local - * cell co-ordinates (indoors) or world co-ordinates (external). + * cell coordinates (indoors) or world coordinates (external). * * Input params: * start, goal - pathgrid point indexes (for this cell) @@ -239,7 +239,7 @@ namespace MWMechanics * TODO: An intersting exercise might be to cache the paths created for a * start/goal pair. To cache the results the paths need to be in * pathgrid points form (currently they are converted to world - * co-ordinates). Essentially trading speed w/ memory. + * coordinates). Essentially trading speed w/ memory. */ std::list PathgridGraph::aStarSearch(const int start, const int goal) const @@ -312,7 +312,7 @@ namespace MWMechanics if(current != goal) return path; // for some reason couldn't build a path - // reconstruct path to return, using local co-ordinates + // reconstruct path to return, using local coordinates while(graphParent[current] != -1) { path.push_front(mPathgrid->mPoints[current]); diff --git a/apps/openmw/mwmechanics/pathgrid.hpp b/apps/openmw/mwmechanics/pathgrid.hpp index ab418ae78b..d90cb47cd5 100644 --- a/apps/openmw/mwmechanics/pathgrid.hpp +++ b/apps/openmw/mwmechanics/pathgrid.hpp @@ -30,7 +30,7 @@ namespace MWMechanics // the input parameters are pathgrid point indexes // the output list is in local (internal cells) or world (external - // cells) co-ordinates + // cells) coordinates // // NOTE: if start equals end an empty path is returned std::list aStarSearch(const int start, diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 61022da28c..9be34495ef 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -47,7 +47,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr updateScale(); updatePosition(); - updateCollisionMask(); + addCollisionMask(getCollisionMask()); } Actor::~Actor() @@ -70,15 +70,26 @@ void Actor::enableCollisionBody(bool collision) } } +void Actor::addCollisionMask(int collisionMask) +{ + mCollisionWorld->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); +} + void Actor::updateCollisionMask() { mCollisionWorld->removeCollisionObject(mCollisionObject.get()); + addCollisionMask(getCollisionMask()); +} + +int Actor::getCollisionMask() +{ int collisionMask = CollisionType_World | CollisionType_HeightMap; if (mExternalCollisionMode) collisionMask |= CollisionType_Actor | CollisionType_Projectile | CollisionType_Door; if (mCanWaterWalk) collisionMask |= CollisionType_Water; - mCollisionWorld->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); + return collisionMask; + } void Actor::updatePosition() diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index b238547e11..a0bf5bfc03 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -139,6 +139,8 @@ namespace MWPhysics private: /// Removes then re-adds the collision object to the dynamics world void updateCollisionMask(); + void addCollisionMask(int collisionMask); + int getCollisionMask(); bool mCanWaterWalk; bool mWalkingOnWater; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 1a97fc6ffd..544fb01996 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1349,7 +1349,8 @@ namespace MWPhysics else if (physicActor->getCollisionMode() && canMoveToWaterSurface(iter->first, waterlevel)) { const osg::Vec3f actorPosition = physicActor->getPosition(); - physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel)); + physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel)); + waterCollision = true; } } physicActor->setCanWaterWalk(waterCollision); @@ -1467,7 +1468,10 @@ namespace MWPhysics } if (!mWaterEnabled) + { + mWaterCollisionObject.reset(); return; + } mWaterCollisionObject.reset(new btCollisionObject()); mWaterCollisionShape.reset(new btStaticPlaneShape(btVector3(0,0,1), mWaterHeight)); diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 215355316b..d746318459 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -200,7 +200,7 @@ namespace MWPhysics typedef std::map CollisionMap; CollisionMap mStandingCollisions; - // replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value + // replaces all occurrences of 'old' in the map by 'updated', no matter if it's a key or value void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated); PtrVelocityList mMovementQueue; diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index a095d5dd42..36a0f4085a 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -110,8 +110,6 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item)); osg::ref_ptr attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename); mResourceSystem->getSceneManager()->notifyAttached(attached); - if (mSkeleton) - mSkeleton->markDirty(); scene.reset(new PartHolder(attached)); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index d9dd1a89eb..53eaf0996d 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -671,8 +671,6 @@ PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const st { osg::ref_ptr instance = mResourceSystem->getSceneManager()->getInstance(model); osg::ref_ptr attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename); - if (mSkeleton) - mSkeleton->markDirty(); mResourceSystem->getSceneManager()->notifyAttached(attached); if (enchantedGlow) addGlow(attached, *glowColor); diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 085eeb2be9..e047a9832f 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -211,7 +211,7 @@ namespace MWRender osg::Vec3f mStormDirection; - // remember some settings so we don't have to apply them again if they didnt change + // remember some settings so we don't have to apply them again if they didn't change std::string mClouds; std::string mNextClouds; float mCloudBlendFactor; diff --git a/apps/openmw/mwscript/compilercontext.hpp b/apps/openmw/mwscript/compilercontext.hpp index 010926f451..ca7efd77a1 100644 --- a/apps/openmw/mwscript/compilercontext.hpp +++ b/apps/openmw/mwscript/compilercontext.hpp @@ -11,7 +11,7 @@ namespace MWScript enum Type { - Type_Full, // global, local, targetted + Type_Full, // global, local, targeted Type_Dialogue, Type_Console }; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index d4dabd2f94..a0001d6fd9 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1159,10 +1159,11 @@ namespace NifOsg morphGeom->setUpdateCallback(NULL); morphGeom->setCullCallback(new UpdateMorphGeometry); morphGeom->setUseVertexBufferObjects(true); - morphGeom->getOrCreateVertexBufferObject()->setUsage(GL_DYNAMIC_DRAW_ARB); triShapeToGeometry(triShape, morphGeom, parentNode, composite, boundTextures, animflags); + morphGeom->getOrCreateVertexBufferObject()->setUsage(GL_DYNAMIC_DRAW_ARB); + const std::vector& morphs = morpher->data.getPtr()->mMorphs; if (morphs.empty()) return morphGeom; diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index 3af5176f4f..92780bfe98 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -120,13 +120,17 @@ void RigGeometry::setSourceGeometry(osg::ref_ptr sourceGeometry) setVertexArray(vertexArray); } - osg::ref_ptr normalArray = osg::clone(from.getNormalArray(), osg::CopyOp::DEEP_COPY_ALL); - if (normalArray) + if (osg::Array* normals = from.getNormalArray()) { - normalArray->setVertexBufferObject(vbo); - setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); + osg::ref_ptr normalArray = osg::clone(normals, osg::CopyOp::DEEP_COPY_ALL); + if (normalArray) + { + normalArray->setVertexBufferObject(vbo); + setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); + } } + if (osg::Vec4Array* tangents = dynamic_cast(from.getTexCoordArray(7))) { mSourceTangents = tangents; @@ -273,7 +277,8 @@ void RigGeometry::update(osg::NodeVisitor* nv) { unsigned short vertex = *vertexIt; (*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]); - (*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat); + if (normalDst) + (*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat); if (tangentDst) { osg::Vec4f srcTangent = (*tangentSrc)[vertex]; @@ -284,7 +289,8 @@ void RigGeometry::update(osg::NodeVisitor* nv) } positionDst->dirty(); - normalDst->dirty(); + if (normalDst) + normalDst->dirty(); if (tangentDst) tangentDst->dirty(); } @@ -314,11 +320,14 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) box.expandBy(bs); } - _boundingBox = box; - _boundingSphere = osg::BoundingSphere(_boundingBox); - _boundingSphereComputed = true; - for (unsigned int i=0; idirtyBound(); + if (box != _boundingBox) + { + _boundingBox = box; + _boundingSphere = osg::BoundingSphere(_boundingBox); + _boundingSphereComputed = true; + for (unsigned int i=0; idirtyBound(); + } } void RigGeometry::updateGeomToSkelMatrix(const osg::NodePath& nodePath) diff --git a/components/sceneutil/skeleton.cpp b/components/sceneutil/skeleton.cpp index 390a8e8235..f3c2aef77e 100644 --- a/components/sceneutil/skeleton.cpp +++ b/components/sceneutil/skeleton.cpp @@ -148,6 +148,8 @@ void Skeleton::markDirty() { mTraversedEvenFrame = false; mTraversedOddFrame = false; + mBoneCache.clear(); + mBoneCacheInit = false; } void Skeleton::traverse(osg::NodeVisitor& nv) @@ -160,6 +162,16 @@ void Skeleton::traverse(osg::NodeVisitor& nv) osg::Group::traverse(nv); } +void Skeleton::childInserted(unsigned int) +{ + markDirty(); +} + +void Skeleton::childRemoved(unsigned int, unsigned int) +{ + markDirty(); +} + Bone::Bone() : mNode(NULL) { diff --git a/components/sceneutil/skeleton.hpp b/components/sceneutil/skeleton.hpp index 764b7f6459..24dcc6b3f4 100644 --- a/components/sceneutil/skeleton.hpp +++ b/components/sceneutil/skeleton.hpp @@ -53,10 +53,12 @@ namespace SceneUtil bool getActive() const; - /// If a new RigGeometry is added after the Skeleton has already been rendered, you must call markDirty(). + void traverse(osg::NodeVisitor& nv); + void markDirty(); - void traverse(osg::NodeVisitor& nv); + virtual void childInserted(unsigned int); + virtual void childRemoved(unsigned int, unsigned int); private: // The root bone is not a "real" bone, it has no corresponding node in the scene graph. diff --git a/components/sdlutil/sdlinputwrapper.cpp b/components/sdlutil/sdlinputwrapper.cpp index 647a65005c..e8a0823f80 100644 --- a/components/sdlutil/sdlinputwrapper.cpp +++ b/components/sdlutil/sdlinputwrapper.cpp @@ -102,10 +102,17 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v if (evt.key.keysym.sym == SDLK_F3) mViewer->getEventQueue()->keyRelease(osgGA::GUIEventAdapter::KEY_F3); + break; + case SDL_TEXTEDITING: break; case SDL_TEXTINPUT: mKeyboardListener->textInput(evt.text); break; + +#if SDL_VERSION_ATLEAST(2, 0, 4) + case SDL_KEYMAPCHANGED: + break; +#endif case SDL_JOYHATMOTION: //As we manage everything with GameController, don't even bother with these. case SDL_JOYAXISMOTION: case SDL_JOYBUTTONDOWN: diff --git a/components/sdlutil/sdlinputwrapper.hpp b/components/sdlutil/sdlinputwrapper.hpp index a821b9012c..62d6a565cc 100644 --- a/components/sdlutil/sdlinputwrapper.hpp +++ b/components/sdlutil/sdlinputwrapper.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "OISCompat.hpp" #include "events.hpp" diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 9813cb166e..e17f0235ba 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -188,13 +188,13 @@ clamp lighting = true # If this option is enabled, normal maps are automatically recognized and used if they are named appropriately # (see 'normal map pattern', e.g. for a base texture foo.dds, the normal map texture would have to be named foo_n.dds). -# If this option is disabled, normal maps are only used if they are explicitely listed within the mesh file (.nif or .osg file). +# If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file (.nif or .osg file). # Affects objects. auto use object normal maps = false # If this option is enabled, specular maps are automatically recognized and used if they are named appropriately # (see 'specular map pattern', e.g. for a base texture foo.dds, the specular map texture would have to be named foo_spec.dds). -# If this option is disabled, normal maps are only used if they are explicitely listed within the mesh file (.osg file, not supported in .nif files). +# If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file (.osg file, not supported in .nif files). # Affects objects. auto use object specular maps = false