diff --git a/.travis.yml b/.travis.yml index 1be8aa59cc..1fc85dca38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,14 @@ addons: build_command_prepend: "cmake ." build_command: "make -j3" branch_pattern: coverity_scan +matrix: + include: + - os: linux + env: + ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 " + compiler: clang + allow_failures: + - env: ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 " before_install: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi @@ -30,7 +38,7 @@ before_script: - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi script: - cd ./build - - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j4; fi + - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j4; fi - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi after_script: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi diff --git a/CI/before_install.linux.sh b/CI/before_install.linux.sh index 998c285db2..27cb714638 100755 --- a/CI/before_install.linux.sh +++ b/CI/before_install.linux.sh @@ -1,7 +1,12 @@ #!/bin/sh -export CXX=g++ -export CC=gcc +if [ "${ANALYZE}" ]; then + if [ $(lsb_release -sc) = "precise" ]; then + echo "yes" | sudo apt-add-repository ppa:ubuntu-toolchain-r/test + fi + echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main" + wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - +fi echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse" echo "yes" | sudo apt-add-repository ppa:openmw/openmw @@ -10,6 +15,7 @@ sudo apt-get install -qq libgtest-dev google-mock sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev +if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi sudo mkdir /usr/src/gtest/build cd /usr/src/gtest/build sudo cmake .. -DBUILD_SHARED_LIBS=1 diff --git a/CI/before_script.linux.sh b/CI/before_script.linux.sh index b4889c9e17..71ddd20407 100755 --- a/CI/before_script.linux.sh +++ b/CI/before_script.linux.sh @@ -2,4 +2,6 @@ mkdir build cd build -cmake .. -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DUSE_SYSTEM_TINYXML=TRUE +export CODE_COVERAGE=1 +if [ "${CC}" = "clang" ]; then export CODE_COVERAGE=0; fi +${ANALYZE}cmake .. -DBUILD_WITH_CODE_COVERAGE=${CODE_COVERAGE} -DBUILD_UNITTESTS=1 -DCMAKE_INSTALL_PREFIX=/usr -DBINDIR=/usr/games -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DUSE_SYSTEM_TINYXML=TRUE diff --git a/CMakeLists.txt b/CMakeLists.txt index 342fb7e390..07fffd5776 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,6 +353,14 @@ endif() if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long") + if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE) + execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE CLANG_VERSION) + string(REGEX REPLACE ".*version ([0-9\\.]*).*" "\\1" CLANG_VERSION ${CLANG_VERSION}) + if ("${CLANG_VERSION}" VERSION_GREATER 3.6 OR "${CLANG_VERSION}" VERSION_EQUAL 3.6) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression") + endif ("${CLANG_VERSION}" VERSION_GREATER 3.6 OR "${CLANG_VERSION}" VERSION_EQUAL 3.6) + endif(CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE) + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index 68de87d80c..198c3627f4 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -48,10 +48,6 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message } } - // Check if referenced object is in valid cell - if (mCells.searchId(cellRef.mCell) == -1) - messages.push_back(std::make_pair(id, " is referencing object from non existing cell " + cellRef.mCell)); - // If object have owner, check if that owner reference is valid if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1) messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner)); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 8dd83f24a3..1b3196112d 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -153,11 +153,13 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) if (isNew) success = success && !(name.isEmpty()); - else + else if (success) { ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); } + else + mAdjusterWidget->setName ("", true); ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); } diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 046eb5229f..30235d0f5c 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -20,7 +20,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) : mDocument (document), mAborted (false), mMessages (0), mTotalRecords (0) { - setWindowTitle (("Opening " + document->getSavePath().filename().string()).c_str()); + setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str())); setMinimumWidth (400); diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index a399b5b5bf..df1e7ee492 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -26,7 +26,7 @@ void CSVDoc::SubView::updateUserSetting (const QString &, const QStringList &) void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) { mUniversalId = id; - setWindowTitle (mUniversalId.toString().c_str()); + setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str())); } void CSVDoc::SubView::closeEvent (QCloseEvent *event) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 211f741873..cf2940b999 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -324,7 +324,7 @@ void CSVDoc::View::updateTitle() if (hideTitle) stream << " - " << mSubViews.at (0)->getTitle(); - setWindowTitle (stream.str().c_str()); + setWindowTitle (QString::fromUtf8(stream.str().c_str())); } void CSVDoc::View::updateSubViewIndicies(SubView *view) @@ -485,6 +485,8 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin (!isReferenceable && id == sb->getUniversalId())) { sb->setFocus(); + if (!hint.empty()) + sb->useHint (hint); return; } } @@ -515,8 +517,6 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin assert(view); view->setParent(this); mSubViews.append(view); // only after assert - if (!hint.empty()) - view->useHint (hint); int minWidth = userSettings.setting ("window/minimum-width", QString("325")).toInt(); view->setMinimumWidth(minWidth); @@ -538,6 +538,9 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin this, SLOT (updateSubViewIndicies (SubView *))); view->show(); + + if (!hint.empty()) + view->useHint (hint); } void CSVDoc::View::newView() diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 5f6b6b46a4..9fee260789 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -248,7 +248,7 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view) QMessageBox messageBox(view); CSMDoc::Document *document = view->getDocument(); - messageBox.setWindowTitle (document->getSavePath().filename().string().c_str()); + messageBox.setWindowTitle (QString::fromUtf8(document->getSavePath().filename().string().c_str())); messageBox.setText ("The document has been modified."); messageBox.setInformativeText ("Do you want to save your changes?"); messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index ae2fad95ad..a030ea11f8 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -10,6 +10,7 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" +#include "../../model/world/refcollection.hpp" #include "../world/physicssystem.hpp" #include "elements.hpp" @@ -30,26 +31,19 @@ bool CSVRender::Cell::removeObject (const std::string& id) bool CSVRender::Cell::addObjects (int start, int end) { - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); - - int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); - int stateColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); - bool modified = false; + const CSMWorld::RefCollection& collection = mData.getReferences(); + for (int i=start; i<=end; ++i) { - std::string cell = Misc::StringUtils::lowerCase (references.data ( - references.index (i, cellColumn)).toString().toUtf8().constData()); + std::string cell = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mCell); - int state = references.data (references.index (i, stateColumn)).toInt(); + CSMWorld::RecordBase::State state = collection.getRecord (i).mState; if (cell==mId && state!=CSMWorld::RecordBase::State_Deleted) { - std::string id = Misc::StringUtils::lowerCase (references.data ( - references.index (i, idColumn)).toString().toUtf8().constData()); + std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId); mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); modified = true; diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 9b50a61f89..211462a263 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -68,6 +68,7 @@ void CSVWorld::ScriptSubView::useHint (const std::string& hint) if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); + mEditor->setFocus(); mEditor->setTextCursor (cursor); } } diff --git a/apps/openmw/android_commandLine.cpp b/apps/openmw/android_commandLine.cpp index bb95a05342..ebfff28ca2 100644 --- a/apps/openmw/android_commandLine.cpp +++ b/apps/openmw/android_commandLine.cpp @@ -1,18 +1,27 @@ #include "android_commandLine.h" #include "string.h" - const char *argvData[15]; - int argcData; +const char **argvData; +int argcData; + +extern "C" void releaseArgv(); + +void releaseArgv() { + delete[] argvData; +} JNIEXPORT void JNICALL Java_ui_activity_GameActivity_commandLine(JNIEnv *env, jobject obj, jint argc, jobjectArray stringArray) { jboolean iscopy; argcData = (int) argc; - argvData[0]="openmw"; - for (int i = 0; i < argcData; i++) { - jstring string = (jstring) (*env).GetObjectArrayElement(stringArray, i); - argvData[i+1] = (env)->GetStringUTFChars(string, &iscopy); + argvData = new const char *[argcData + 1]; + argvData[0] = "openmw"; + for (int i = 1; i < argcData + 1; i++) { + jstring string = (jstring) (env)->GetObjectArrayElement(stringArray, + i - 1); + argvData[i] = (env)->GetStringUTFChars(string, &iscopy); + (env)->DeleteLocalRef(string); } - + (env)->DeleteLocalRef(stringArray); } diff --git a/apps/openmw/android_main.c b/apps/openmw/android_main.c index 0cfb8dcfac..1b28395199 100644 --- a/apps/openmw/android_main.c +++ b/apps/openmw/android_main.c @@ -12,7 +12,8 @@ extern void SDL_Android_Init(JNIEnv* env, jclass cls); extern int argcData; -extern const char *argvData[15]; +extern const char **argvData; +void releaseArgv(); int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) { @@ -26,7 +27,7 @@ int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, int status; status = main(argcData+1, argvData); - + releaseArgv(); /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* exit(status); */ diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 97dbfbafcc..f908a9dd0d 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -142,13 +142,13 @@ namespace MWGui for (unsigned int i=0; i 1) diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index f933767798..52a975320d 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -86,7 +86,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po //************************ /// Checks if you aren't moving; attempts to unstick you //************************ - if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) //Path finished? + if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1])) //Path finished? return true; else if(mStuckTimer>0.5) //Every half second see if we need to take action to avoid something { diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index a46fe72968..2824e2c6ce 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -100,7 +100,7 @@ namespace MWMechanics mPathFinder.buildPath(start, dest, actor.getCell(), true); } - if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1])) { movement.mPosition[1] = 0; return true; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index b791ff3a9d..560e756ce2 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -31,6 +31,18 @@ namespace MWMechanics static const int GREETING_SHOULD_START = 4; //how many reaction intervals should pass before NPC can greet player static const int GREETING_SHOULD_END = 10; + const std::string AiWander::sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1] = + { + std::string("idle2"), + std::string("idle3"), + std::string("idle4"), + std::string("idle5"), + std::string("idle6"), + std::string("idle7"), + std::string("idle8"), + std::string("idle9"), + }; + /// \brief This class holds the variables AiWander needs which are deleted if the package becomes inactive. struct AiWanderStorage : AiTemporaryBase { @@ -205,7 +217,7 @@ namespace MWMechanics // Are we there yet? bool& chooseAction = storage.mChooseAction; if(walking && - storage.mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2], 64.f)) + storage.mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], 64.f)) { stopWalking(actor, storage); moveNow = false; @@ -580,44 +592,24 @@ namespace MWMechanics void AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) { - if(idleSelect == 2) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle2", 0, 1); - else if(idleSelect == 3) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); - else if(idleSelect == 4) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle4", 0, 1); - else if(idleSelect == 5) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle5", 0, 1); - else if(idleSelect == 6) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle6", 0, 1); - else if(idleSelect == 7) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle7", 0, 1); - else if(idleSelect == 8) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle8", 0, 1); - else if(idleSelect == 9) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle9", 0, 1); + if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle)) + { + const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle]; + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, groupName, 0, 1); + } } bool AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) { - if(idleSelect == 2) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle2"); - else if(idleSelect == 3) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle3"); - else if(idleSelect == 4) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle4"); - else if(idleSelect == 5) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle5"); - else if(idleSelect == 6) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle6"); - else if(idleSelect == 7) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle7"); - else if(idleSelect == 8) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle8"); - else if(idleSelect == 9) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle9"); + if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle)) + { + const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle]; + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, groupName); + } else + { return false; + } } void AiWander::setReturnPosition(const Ogre::Vector3& position) @@ -694,7 +686,8 @@ namespace MWMechanics // If there is no path this actor doesn't go anywhere. See: // https://forum.openmw.org/viewtopic.php?t=1556 // http://www.fliggerty.com/phpBB3/viewtopic.php?f=30&t=5833 - if(!pathgrid || pathgrid->mPoints.empty()) + // Note: In order to wander, need at least two points. + if(!pathgrid || (pathgrid->mPoints.size() < 2)) mDistance = 0; // A distance value passed into the constructor indicates how far the @@ -738,12 +731,37 @@ namespace MWMechanics } mCurrentNode = mAllowedNodes[index]; mAllowedNodes.erase(mAllowedNodes.begin() + index); - - mStoredAvailableNodes = true; // set only if successful in finding allowed nodes } + + // In vanilla Morrowind, sometimes distance is too small to include at least two points, + // in which case, we will take the two closest points regardless of the wander distance + // This is a backup option, as std::sort is potentially O(n^2) in time. + if (mAllowedNodes.empty()) + { + // Start with list of PathGrid nodes, sorted by distance from actor + std::vector nodeDistances; + for (unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++) + { + float distance = npcPos.squaredDistance(PathFinder::MakeOgreVector3(pathgrid->mPoints[counter])); + nodeDistances.push_back(std::make_pair(distance, &pathgrid->mPoints.at(counter))); + } + std::sort(nodeDistances.begin(), nodeDistances.end(), sortByDistance); + + // make closest node the current node + mCurrentNode = *nodeDistances[0].second; + + // give Actor a 2nd node to walk to + mAllowedNodes.push_back(*nodeDistances[1].second); + } + mStoredAvailableNodes = true; // set only if successful in finding allowed nodes } } + bool AiWander::sortByDistance(const PathDistance& left, const PathDistance& right) + { + return left.first < right.first; + } + void AiWander::writeState(ESM::AiSequence::AiSequence &sequence) const { std::auto_ptr wander(new ESM::AiSequence::AiWander()); diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 54e215cb9c..7f8fc5088a 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -113,7 +113,22 @@ namespace MWMechanics float mDoorCheckDuration; int mStuckCount; + // constants for converting idleSelect values into groupNames + enum GroupIndex + { + GroupIndex_MinIdle = 2, + GroupIndex_MaxIdle = 9 + }; + /// lookup table for converting idleSelect value to groupName + static const std::string sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1]; + + /// record distances of pathgrid point nodes to actor + /// first value is distance between actor and node, second value is PathGrid node + typedef std::pair PathDistance; + + /// used to sort array of PathDistance objects into ascending order + static bool sortByDistance(const PathDistance& left, const PathDistance& right); }; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index e8abb9e988..5795f818af 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -90,12 +90,11 @@ namespace namespace MWMechanics { - float sqrDistanceZCorrected(ESM::Pathgrid::Point point, float x, float y, float z) + float sqrDistanceIgnoreZ(ESM::Pathgrid::Point point, float x, float y) { x -= point.mX; y -= point.mY; - z -= point.mZ; - return (x * x + y * y + 0.1f * z * z); + return (x * x + y * y); } float distance(ESM::Pathgrid::Point point, float x, float y, float z) @@ -283,13 +282,13 @@ namespace MWMechanics return Ogre::Math::ATan2(directionX,directionY).valueDegrees(); } - bool PathFinder::checkPathCompleted(float x, float y, float z, float tolerance) + bool PathFinder::checkPathCompleted(float x, float y, float tolerance) { if(mPath.empty()) return true; ESM::Pathgrid::Point nextPoint = *mPath.begin(); - if(sqrDistanceZCorrected(nextPoint, x, y, z) < tolerance*tolerance) + if (sqrDistanceIgnoreZ(nextPoint, x, y) < tolerance*tolerance) { mPath.pop_front(); if(mPath.empty()) diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 490cf9b884..f48de6624c 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -41,7 +41,7 @@ namespace MWMechanics void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, const MWWorld::CellStore* cell, bool allowShortcuts = true); - bool checkPathCompleted(float x, float y, float z, float tolerance=32.f); + bool checkPathCompleted(float x, float y, float tolerance=32.f); ///< \Returns true if we are within \a tolerance units of the last path point. float getZAngleToNext(float x, float y) const; diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index 0d60f4cf0f..3bf73ede27 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -111,7 +111,7 @@ void BSAFile::readHeader() // Each file must take up at least 21 bytes of data in the bsa. So // if files*21 overflows the file size then we are guaranteed that // the archive is corrupt. - if((filenum*21 > fsize -12) || (dirsize+8*filenum > fsize -12) ) + if((filenum*21 > unsigned(fsize -12)) || (dirsize+8*filenum > unsigned(fsize -12)) ) fail("Directory information larger than entire archive"); // Read the offset info into a temporary buffer diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 3dc02af21f..62f6d90141 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -449,7 +449,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) ToUTF8::Utf8Encoder encoder = ToUTF8::calculateEncoding(mEncoding.toStdString()); fileReader.setEncoder(&encoder); - fileReader.open(dir.absoluteFilePath(path).toStdString()); + fileReader.open(std::string(dir.absoluteFilePath(path).toUtf8().constData())); EsmFile *file = new EsmFile(path); diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index 54b18aeaf3..d90a3444dd 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace ESM { diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index ebbc935f6f..2df2a86b31 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -2,7 +2,7 @@ #define OPENMW_ESM_READER_H #include -#include +#include #include #include #include diff --git a/components/files/androidpath.cpp b/components/files/androidpath.cpp index 009bd98a2c..84886f4734 100644 --- a/components/files/androidpath.cpp +++ b/components/files/androidpath.cpp @@ -31,6 +31,7 @@ JNIEXPORT void JNICALL Java_ui_activity_GameActivity_getPathToJni(JNIEnv *env, j { jboolean iscopy; Buffer::setData((env)->GetStringUTFChars(prompt, &iscopy)); + (env)->DeleteLocalRef(prompt); } namespace diff --git a/components/files/macospath.cpp b/components/files/macospath.cpp index 3e53f53061..6e794796f9 100644 --- a/components/files/macospath.cpp +++ b/components/files/macospath.cpp @@ -7,10 +7,6 @@ #include #include -/** - * FIXME: Someone with MacOS system should check this and correct if necessary - */ - namespace { boost::filesystem::path getUserHome() @@ -49,9 +45,8 @@ boost::filesystem::path MacOsPath::getUserConfigPath() const boost::filesystem::path MacOsPath::getUserDataPath() const { - // TODO: probably wrong? boost::filesystem::path userPath (getUserHome()); - userPath /= "Library/Preferences/"; + userPath /= "Library/Application Support/"; return userPath / mName; } diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index 1da8cf6956..f566a54997 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -12,6 +12,8 @@ #include "runtime.hpp" #include "defines.hpp" +#include + namespace Interpreter { inline std::string formatMessage (const std::string& message, Runtime& runtime) @@ -140,15 +142,13 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - double r = static_cast (std::rand()) / RAND_MAX; // [0, 1) - Type_Integer limit = runtime[0].mInteger; if (limit<0) throw std::runtime_error ( "random: argument out of range (Don't be so negative!)"); - Type_Integer value = static_cast (r*limit); // [o, limit) + Type_Integer value = OEngine::Misc::Rng::rollDice(limit); // [o, limit) runtime[0].mInteger = value; } diff --git a/components/nif/node.cpp b/components/nif/node.cpp index fb68da548d..d99d157ae2 100644 --- a/components/nif/node.cpp +++ b/components/nif/node.cpp @@ -38,7 +38,10 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop, wireprop = static_cast(pr); else if (pr->recType == Nif::RC_NiStencilProperty) stencilprop = static_cast(pr); - else + // the following are unused by the MW engine + else if (pr->recType != Nif::RC_NiFogProperty + && pr->recType != Nif::RC_NiDitherProperty + && pr->recType != Nif::RC_NiShadeProperty) std::cerr<< "Unhandled property type: "<recName < -#endif - -#include -#if (defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070) || defined(__MINGW32__) -// need our own implementation of strnlen -#ifdef __MINGW32__ -static size_t strnlen(const char *s, size_t n) -{ - const char *p = (const char *)memchr(s, 0, n); - return(p ? p-s : n); -} -#elif (defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070) -static size_t mw_strnlen(const char *s, size_t n) -{ - if (strnlen != NULL) { - return strnlen(s, n); - } - else { - const char *p = (const char *)memchr(s, 0, n); - return(p ? p-s : n); - } -} -#define strnlen mw_strnlen -#endif - -#endif - -#endif