Merge branch 'master' into NonTableFields

This commit is contained in:
cc9cii 2015-04-02 20:43:48 +11:00
commit 851effb0e3
32 changed files with 159 additions and 132 deletions

View file

@ -21,6 +21,14 @@ addons:
build_command_prepend: "cmake ." build_command_prepend: "cmake ."
build_command: "make -j3" build_command: "make -j3"
branch_pattern: coverity_scan 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: before_install:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi - 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 - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
script: script:
- cd ./build - 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 - if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
after_script: after_script:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi

View file

@ -1,7 +1,12 @@
#!/bin/sh #!/bin/sh
export CXX=g++ if [ "${ANALYZE}" ]; then
export CC=gcc 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 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 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 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 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 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 sudo mkdir /usr/src/gtest/build
cd /usr/src/gtest/build cd /usr/src/gtest/build
sudo cmake .. -DBUILD_SHARED_LIBS=1 sudo cmake .. -DBUILD_SHARED_LIBS=1

View file

@ -2,4 +2,6 @@
mkdir build mkdir build
cd 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

View file

@ -353,6 +353,14 @@ endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) 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") 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 execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION) 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) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)

View file

@ -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 object have owner, check if that owner reference is valid
if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1) if (!cellRef.mOwner.empty() && mReferencables.searchId(cellRef.mOwner) == -1)
messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner)); messages.push_back(std::make_pair(id, " has non existing owner " + cellRef.mOwner));

View file

@ -153,11 +153,13 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool)
if (isNew) if (isNew)
success = success && !(name.isEmpty()); success = success && !(name.isEmpty());
else else if (success)
{ {
ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();
mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); mAdjusterWidget->setName (file->filePath(), !file->isGameFile());
} }
else
mAdjusterWidget->setName ("", true);
ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success);
} }

View file

@ -20,7 +20,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
: mDocument (document), mAborted (false), mMessages (0), mTotalRecords (0) : 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); setMinimumWidth (400);

View file

@ -26,7 +26,7 @@ void CSVDoc::SubView::updateUserSetting (const QString &, const QStringList &)
void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
{ {
mUniversalId = id; mUniversalId = id;
setWindowTitle (mUniversalId.toString().c_str()); setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str()));
} }
void CSVDoc::SubView::closeEvent (QCloseEvent *event) void CSVDoc::SubView::closeEvent (QCloseEvent *event)

View file

@ -324,7 +324,7 @@ void CSVDoc::View::updateTitle()
if (hideTitle) if (hideTitle)
stream << " - " << mSubViews.at (0)->getTitle(); stream << " - " << mSubViews.at (0)->getTitle();
setWindowTitle (stream.str().c_str()); setWindowTitle (QString::fromUtf8(stream.str().c_str()));
} }
void CSVDoc::View::updateSubViewIndicies(SubView *view) 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())) (!isReferenceable && id == sb->getUniversalId()))
{ {
sb->setFocus(); sb->setFocus();
if (!hint.empty())
sb->useHint (hint);
return; return;
} }
} }
@ -515,8 +517,6 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
assert(view); assert(view);
view->setParent(this); view->setParent(this);
mSubViews.append(view); // only after assert mSubViews.append(view); // only after assert
if (!hint.empty())
view->useHint (hint);
int minWidth = userSettings.setting ("window/minimum-width", QString("325")).toInt(); int minWidth = userSettings.setting ("window/minimum-width", QString("325")).toInt();
view->setMinimumWidth(minWidth); view->setMinimumWidth(minWidth);
@ -538,6 +538,9 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
this, SLOT (updateSubViewIndicies (SubView *))); this, SLOT (updateSubViewIndicies (SubView *)));
view->show(); view->show();
if (!hint.empty())
view->useHint (hint);
} }
void CSVDoc::View::newView() void CSVDoc::View::newView()

View file

@ -248,7 +248,7 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view)
QMessageBox messageBox(view); QMessageBox messageBox(view);
CSMDoc::Document *document = view->getDocument(); 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.setText ("The document has been modified.");
messageBox.setInformativeText ("Do you want to save your changes?"); messageBox.setInformativeText ("Do you want to save your changes?");
messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);

View file

@ -10,6 +10,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/refcollection.hpp"
#include "../world/physicssystem.hpp" #include "../world/physicssystem.hpp"
#include "elements.hpp" #include "elements.hpp"
@ -30,26 +31,19 @@ bool CSVRender::Cell::removeObject (const std::string& id)
bool CSVRender::Cell::addObjects (int start, int end) bool CSVRender::Cell::addObjects (int start, int end)
{ {
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*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; bool modified = false;
const CSMWorld::RefCollection& collection = mData.getReferences();
for (int i=start; i<=end; ++i) for (int i=start; i<=end; ++i)
{ {
std::string cell = Misc::StringUtils::lowerCase (references.data ( std::string cell = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mCell);
references.index (i, cellColumn)).toString().toUtf8().constData());
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) if (cell==mId && state!=CSMWorld::RecordBase::State_Deleted)
{ {
std::string id = Misc::StringUtils::lowerCase (references.data ( std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
references.index (i, idColumn)).toString().toUtf8().constData());
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics)));
modified = true; modified = true;

View file

@ -68,6 +68,7 @@ void CSVWorld::ScriptSubView::useHint (const std::string& hint)
if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line))
cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column);
mEditor->setFocus();
mEditor->setTextCursor (cursor); mEditor->setTextCursor (cursor);
} }
} }

View file

@ -1,18 +1,27 @@
#include "android_commandLine.h" #include "android_commandLine.h"
#include "string.h" #include "string.h"
const char *argvData[15]; const char **argvData;
int argcData; int argcData;
extern "C" void releaseArgv();
void releaseArgv() {
delete[] argvData;
}
JNIEXPORT void JNICALL Java_ui_activity_GameActivity_commandLine(JNIEnv *env, JNIEXPORT void JNICALL Java_ui_activity_GameActivity_commandLine(JNIEnv *env,
jobject obj, jint argc, jobjectArray stringArray) { jobject obj, jint argc, jobjectArray stringArray) {
jboolean iscopy; jboolean iscopy;
argcData = (int) argc; argcData = (int) argc;
argvData[0]="openmw"; argvData = new const char *[argcData + 1];
for (int i = 0; i < argcData; i++) { argvData[0] = "openmw";
jstring string = (jstring) (*env).GetObjectArrayElement(stringArray, i); for (int i = 1; i < argcData + 1; i++) {
argvData[i+1] = (env)->GetStringUTFChars(string, &iscopy); jstring string = (jstring) (env)->GetObjectArrayElement(stringArray,
i - 1);
argvData[i] = (env)->GetStringUTFChars(string, &iscopy);
(env)->DeleteLocalRef(string);
} }
(env)->DeleteLocalRef(stringArray);
} }

View file

@ -12,7 +12,8 @@
extern void SDL_Android_Init(JNIEnv* env, jclass cls); extern void SDL_Android_Init(JNIEnv* env, jclass cls);
extern int argcData; 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, int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls,
jobject obj) { jobject obj) {
@ -26,7 +27,7 @@ int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls,
int status; int status;
status = main(argcData+1, argvData); status = main(argcData+1, argvData);
releaseArgv();
/* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
/* exit(status); */ /* exit(status); */

View file

@ -142,13 +142,13 @@ namespace MWGui
for (unsigned int i=0; i<mAvailableHeads.size(); ++i) for (unsigned int i=0; i<mAvailableHeads.size(); ++i)
{ {
if (mAvailableHeads[i] == proto.mHead) if (Misc::StringUtils::ciEqual(mAvailableHeads[i], proto.mHead))
mFaceIndex = i; mFaceIndex = i;
} }
for (unsigned int i=0; i<mAvailableHairs.size(); ++i) for (unsigned int i=0; i<mAvailableHairs.size(); ++i)
{ {
if (mAvailableHairs[i] == proto.mHair) if (Misc::StringUtils::ciEqual(mAvailableHairs[i], proto.mHair))
mHairIndex = i; mHairIndex = i;
} }

View file

@ -581,7 +581,7 @@ namespace MWMechanics
buildNewPath(actor, target); //may fail to build a path, check before use buildNewPath(actor, target); //may fail to build a path, check before use
//delete visited path node //delete visited path node
mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]); mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1]);
// This works on the borders between the path grid and areas with no waypoints. // This works on the borders between the path grid and areas with no waypoints.
if(inLOS && mPathFinder.getPath().size() > 1) if(inLOS && mPathFinder.getPath().size() > 1)

View file

@ -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 /// 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; return true;
else if(mStuckTimer>0.5) //Every half second see if we need to take action to avoid something else if(mStuckTimer>0.5) //Every half second see if we need to take action to avoid something
{ {

View file

@ -100,7 +100,7 @@ namespace MWMechanics
mPathFinder.buildPath(start, dest, actor.getCell(), true); 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; movement.mPosition[1] = 0;
return true; return true;

View file

@ -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_START = 4; //how many reaction intervals should pass before NPC can greet player
static const int GREETING_SHOULD_END = 10; 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. /// \brief This class holds the variables AiWander needs which are deleted if the package becomes inactive.
struct AiWanderStorage : AiTemporaryBase struct AiWanderStorage : AiTemporaryBase
{ {
@ -205,7 +217,7 @@ namespace MWMechanics
// Are we there yet? // Are we there yet?
bool& chooseAction = storage.mChooseAction; bool& chooseAction = storage.mChooseAction;
if(walking && 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); stopWalking(actor, storage);
moveNow = false; moveNow = false;
@ -580,44 +592,24 @@ namespace MWMechanics
void AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) void AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
{ {
if(idleSelect == 2) if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle))
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle2", 0, 1); {
else if(idleSelect == 3) const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle];
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, groupName, 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);
} }
bool AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) bool AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
{ {
if(idleSelect == 2) if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle))
return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle2"); {
else if(idleSelect == 3) const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle];
return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle3"); return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, groupName);
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");
else else
{
return false; return false;
}
} }
void AiWander::setReturnPosition(const Ogre::Vector3& position) 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: // If there is no path this actor doesn't go anywhere. See:
// https://forum.openmw.org/viewtopic.php?t=1556 // https://forum.openmw.org/viewtopic.php?t=1556
// http://www.fliggerty.com/phpBB3/viewtopic.php?f=30&t=5833 // 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; mDistance = 0;
// A distance value passed into the constructor indicates how far the // A distance value passed into the constructor indicates how far the
@ -738,12 +731,37 @@ namespace MWMechanics
} }
mCurrentNode = mAllowedNodes[index]; mCurrentNode = mAllowedNodes[index];
mAllowedNodes.erase(mAllowedNodes.begin() + 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<PathDistance> 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 void AiWander::writeState(ESM::AiSequence::AiSequence &sequence) const
{ {
std::auto_ptr<ESM::AiSequence::AiWander> wander(new ESM::AiSequence::AiWander()); std::auto_ptr<ESM::AiSequence::AiWander> wander(new ESM::AiSequence::AiWander());

View file

@ -113,7 +113,22 @@ namespace MWMechanics
float mDoorCheckDuration; float mDoorCheckDuration;
int mStuckCount; 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<float, const ESM::Pathgrid::Point*> PathDistance;
/// used to sort array of PathDistance objects into ascending order
static bool sortByDistance(const PathDistance& left, const PathDistance& right);
}; };

View file

@ -90,12 +90,11 @@ namespace
namespace MWMechanics 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; x -= point.mX;
y -= point.mY; y -= point.mY;
z -= point.mZ; return (x * x + y * y);
return (x * x + y * y + 0.1f * z * z);
} }
float distance(ESM::Pathgrid::Point point, float x, float y, float z) 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(); 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()) if(mPath.empty())
return true; return true;
ESM::Pathgrid::Point nextPoint = *mPath.begin(); ESM::Pathgrid::Point nextPoint = *mPath.begin();
if(sqrDistanceZCorrected(nextPoint, x, y, z) < tolerance*tolerance) if (sqrDistanceIgnoreZ(nextPoint, x, y) < tolerance*tolerance)
{ {
mPath.pop_front(); mPath.pop_front();
if(mPath.empty()) if(mPath.empty())

View file

@ -41,7 +41,7 @@ namespace MWMechanics
void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint,
const MWWorld::CellStore* cell, bool allowShortcuts = true); 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. ///< \Returns true if we are within \a tolerance units of the last path point.
float getZAngleToNext(float x, float y) const; float getZAngleToNext(float x, float y) const;

View file

@ -111,7 +111,7 @@ void BSAFile::readHeader()
// Each file must take up at least 21 bytes of data in the bsa. So // 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 // if files*21 overflows the file size then we are guaranteed that
// the archive is corrupt. // 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"); fail("Directory information larger than entire archive");
// Read the offset info into a temporary buffer // Read the offset info into a temporary buffer

View file

@ -449,7 +449,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path)
ToUTF8::Utf8Encoder encoder = ToUTF8::Utf8Encoder encoder =
ToUTF8::calculateEncoding(mEncoding.toStdString()); ToUTF8::calculateEncoding(mEncoding.toStdString());
fileReader.setEncoder(&encoder); fileReader.setEncoder(&encoder);
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(std::string(dir.absoluteFilePath(path).toUtf8().constData()));
EsmFile *file = new EsmFile(path); EsmFile *file = new EsmFile(path);

View file

@ -5,7 +5,7 @@
#include <cstring> #include <cstring>
#include <stdint.h> #include <stdint.h>
#include <libs/platform/string.h> #include <string.h>
namespace ESM namespace ESM
{ {

View file

@ -2,7 +2,7 @@
#define OPENMW_ESM_READER_H #define OPENMW_ESM_READER_H
#include <stdint.h> #include <stdint.h>
#include <libs/platform/string.h> #include <string.h>
#include <cassert> #include <cassert>
#include <vector> #include <vector>
#include <sstream> #include <sstream>

View file

@ -31,6 +31,7 @@ JNIEXPORT void JNICALL Java_ui_activity_GameActivity_getPathToJni(JNIEnv *env, j
{ {
jboolean iscopy; jboolean iscopy;
Buffer::setData((env)->GetStringUTFChars(prompt, &iscopy)); Buffer::setData((env)->GetStringUTFChars(prompt, &iscopy));
(env)->DeleteLocalRef(prompt);
} }
namespace namespace

View file

@ -7,10 +7,6 @@
#include <unistd.h> #include <unistd.h>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
/**
* FIXME: Someone with MacOS system should check this and correct if necessary
*/
namespace namespace
{ {
boost::filesystem::path getUserHome() boost::filesystem::path getUserHome()
@ -49,9 +45,8 @@ boost::filesystem::path MacOsPath::getUserConfigPath() const
boost::filesystem::path MacOsPath::getUserDataPath() const boost::filesystem::path MacOsPath::getUserDataPath() const
{ {
// TODO: probably wrong?
boost::filesystem::path userPath (getUserHome()); boost::filesystem::path userPath (getUserHome());
userPath /= "Library/Preferences/"; userPath /= "Library/Application Support/";
return userPath / mName; return userPath / mName;
} }

View file

@ -12,6 +12,8 @@
#include "runtime.hpp" #include "runtime.hpp"
#include "defines.hpp" #include "defines.hpp"
#include <openengine/misc/rng.hpp>
namespace Interpreter namespace Interpreter
{ {
inline std::string formatMessage (const std::string& message, Runtime& runtime) inline std::string formatMessage (const std::string& message, Runtime& runtime)
@ -140,15 +142,13 @@ namespace Interpreter
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
Type_Integer limit = runtime[0].mInteger; Type_Integer limit = runtime[0].mInteger;
if (limit<0) if (limit<0)
throw std::runtime_error ( throw std::runtime_error (
"random: argument out of range (Don't be so negative!)"); "random: argument out of range (Don't be so negative!)");
Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit) Type_Integer value = OEngine::Misc::Rng::rollDice(limit); // [o, limit)
runtime[0].mInteger = value; runtime[0].mInteger = value;
} }

View file

@ -38,7 +38,10 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop,
wireprop = static_cast<const Nif::NiWireframeProperty*>(pr); wireprop = static_cast<const Nif::NiWireframeProperty*>(pr);
else if (pr->recType == Nif::RC_NiStencilProperty) else if (pr->recType == Nif::RC_NiStencilProperty)
stencilprop = static_cast<const Nif::NiStencilProperty*>(pr); stencilprop = static_cast<const Nif::NiStencilProperty*>(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: "<<pr->recName <<std::endl; std::cerr<< "Unhandled property type: "<<pr->recName <<std::endl;
} }
} }

View file

@ -26,4 +26,4 @@ namespace Misc {
} }
} }
} }

View file

@ -1,34 +0,0 @@
// Wrapper for string.h on Mac and MinGW
#ifndef _STRING_WRAPPER_H
#define _STRING_WRAPPER_H
#ifdef __APPLE__
#include <Availability.h>
#endif
#include <string.h>
#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