mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
Merge branch 'master' of github.com:OpenMW/openmw
This commit is contained in:
commit
ff74d54e98
37 changed files with 343 additions and 144 deletions
31
.travis.yml
31
.travis.yml
|
@ -1,37 +1,26 @@
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- /openmw-.*$/
|
- /openmw-.*$/
|
||||||
before_install:
|
before_install:
|
||||||
- pwd
|
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi
|
||||||
- echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_install.osx.sh; fi
|
||||||
- echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- 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
|
|
||||||
- sudo mkdir /usr/src/gtest/build
|
|
||||||
- cd /usr/src/gtest/build
|
|
||||||
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
|
||||||
- sudo make -j4
|
|
||||||
- sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
|
||||||
- sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
|
||||||
before_script:
|
before_script:
|
||||||
- cd -
|
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_script.linux.sh; fi
|
||||||
- mkdir build
|
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
|
||||||
- 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
|
|
||||||
script:
|
script:
|
||||||
|
- cd ./build
|
||||||
- make -j4
|
- make -j4
|
||||||
after_script:
|
after_script:
|
||||||
- ./openmw_test_suite
|
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||||
notifications:
|
notifications:
|
||||||
recipients:
|
recipients:
|
||||||
- lgromanowski+travis.ci@gmail.com
|
- lgromanowski+travis.ci@gmail.com
|
||||||
|
- corrmage+travis-ci@gmail.com
|
||||||
email:
|
email:
|
||||||
on_success: change
|
on_success: change
|
||||||
on_failure: always
|
on_failure: always
|
||||||
|
|
18
CI/before_install.linux.sh
Executable file
18
CI/before_install.linux.sh
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export CXX=g++
|
||||||
|
export CC=gcc
|
||||||
|
|
||||||
|
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
|
||||||
|
sudo apt-get update -qq
|
||||||
|
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
|
||||||
|
sudo mkdir /usr/src/gtest/build
|
||||||
|
cd /usr/src/gtest/build
|
||||||
|
sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||||
|
sudo make -j4
|
||||||
|
sudo ln -s /usr/src/gtest/build/libgtest.so /usr/lib/libgtest.so
|
||||||
|
sudo ln -s /usr/src/gtest/build/libgtest_main.so /usr/lib/libgtest_main.so
|
9
CI/before_install.osx.sh
Executable file
9
CI/before_install.osx.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export CXX=clang++
|
||||||
|
export CC=clang
|
||||||
|
|
||||||
|
brew tap openmw/openmw
|
||||||
|
brew update
|
||||||
|
brew unlink boost
|
||||||
|
brew install cmake openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg pkg-config qt unshield
|
5
CI/before_script.linux.sh
Executable file
5
CI/before_script.linux.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
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
|
5
CI/before_script.osx.sh
Executable file
5
CI/before_script.osx.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_FRAMEWORK_PATH="/usr/local/lib/macosx/Release" -DCMAKE_EXE_LINKER_FLAGS="-F/usr/local/lib/macosx/Release" -DCMAKE_CXX_FLAGS="-stdlib=libstdc++" -DCMAKE_BUILD_TYPE=Debug -DBUILD_MYGUI_PLUGIN=OFF -G"Unix Makefiles" ..
|
|
@ -541,6 +541,8 @@ namespace MWBase
|
||||||
|
|
||||||
/// Resets all actors in the current active cells to their original location within that cell.
|
/// Resets all actors in the current active cells to their original location within that cell.
|
||||||
virtual void resetActors() = 0;
|
virtual void resetActors() = 0;
|
||||||
|
|
||||||
|
virtual bool isWalkingOnWater (const MWWorld::Ptr& actor) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ namespace MWClass
|
||||||
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
||||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
||||||
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr);
|
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||||
if (!weapon.isEmpty())
|
if (!weapon.isEmpty())
|
||||||
fatigueLoss += weapon.getClass().getWeight(weapon) * stats.getAttackStrength() * fWeaponFatigueMult;
|
fatigueLoss += weapon.getClass().getWeight(weapon) * stats.getAttackStrength() * fWeaponFatigueMult;
|
||||||
|
@ -537,7 +537,7 @@ namespace MWClass
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
||||||
|
|
||||||
const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr);
|
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||||
|
|
||||||
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
||||||
|
|
||||||
|
@ -738,7 +738,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
if(world->isUnderwater(ptr.getCell(), pos))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return 2;
|
return 2;
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -748,7 +748,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
if(world->isUnderwater(ptr.getCell(), pos))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return 3;
|
return 3;
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -302,11 +302,11 @@ namespace MWClass
|
||||||
Misc::StringUtils::toLower(faction);
|
Misc::StringUtils::toLower(faction);
|
||||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||||
{
|
{
|
||||||
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank;
|
data->mNpcStats.setFactionRank(faction, (int)ref->mBase->mNpdt52.mRank);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt12.mRank;
|
data->mNpcStats.setFactionRank(faction, (int)ref->mBase->mNpdt12.mRank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ namespace MWClass
|
||||||
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
||||||
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
||||||
MWMechanics::DynamicStat<float> fatigue = getCreatureStats(ptr).getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = getCreatureStats(ptr).getFatigue();
|
||||||
const float normalizedEncumbrance = getEncumbrance(ptr) / getCapacity(ptr);
|
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||||
if (!weapon.isEmpty())
|
if (!weapon.isEmpty())
|
||||||
fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult;
|
fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult;
|
||||||
|
@ -914,7 +914,7 @@ namespace MWClass
|
||||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||||
|
|
||||||
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||||
|
|
||||||
bool sneaking = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
bool sneaking = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
||||||
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run);
|
||||||
|
@ -930,7 +930,7 @@ namespace MWClass
|
||||||
gmst.fAthleticsRunBonus->getFloat() + gmst.fBaseRunMultiplier->getFloat());
|
gmst.fAthleticsRunBonus->getFloat() + gmst.fBaseRunMultiplier->getFloat());
|
||||||
|
|
||||||
float moveSpeed;
|
float moveSpeed;
|
||||||
if(normalizedEncumbrance >= 1.0f)
|
if(getEncumbrance(ptr) > getCapacity(ptr))
|
||||||
moveSpeed = 0.0f;
|
moveSpeed = 0.0f;
|
||||||
else if(mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 &&
|
else if(mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 &&
|
||||||
world->isLevitationEnabled())
|
world->isLevitationEnabled())
|
||||||
|
@ -1225,7 +1225,7 @@ namespace MWClass
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
if(world->isSwimming(ptr))
|
if(world->isSwimming(ptr))
|
||||||
return "Swim Left";
|
return "Swim Left";
|
||||||
if(world->isUnderwater(ptr.getCell(), pos))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return "FootWaterLeft";
|
return "FootWaterLeft";
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
{
|
{
|
||||||
|
@ -1252,7 +1252,7 @@ namespace MWClass
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
if(world->isSwimming(ptr))
|
if(world->isSwimming(ptr))
|
||||||
return "Swim Right";
|
return "Swim Right";
|
||||||
if(world->isUnderwater(ptr.getCell(), pos))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return "FootWaterRight";
|
return "FootWaterRight";
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
{
|
{
|
||||||
|
@ -1277,7 +1277,7 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
if(world->isUnderwater(ptr.getCell(), pos))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return "DefaultLandWater";
|
return "DefaultLandWater";
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
return "Body Fall Medium";
|
return "Body Fall Medium";
|
||||||
|
|
|
@ -68,7 +68,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor);
|
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats (mActor);
|
||||||
std::map<std::string, int>::iterator iter = stats.getFactionRanks().find ( Misc::StringUtils::lowerCase (info.mFaction));
|
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find ( Misc::StringUtils::lowerCase (info.mFaction));
|
||||||
|
|
||||||
if (iter==stats.getFactionRanks().end())
|
if (iter==stats.getFactionRanks().end())
|
||||||
return false;
|
return false;
|
||||||
|
@ -112,7 +112,7 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
|
||||||
if (!info.mPcFaction.empty())
|
if (!info.mPcFaction.empty())
|
||||||
{
|
{
|
||||||
MWMechanics::NpcStats& stats = player.getClass().getNpcStats (player);
|
MWMechanics::NpcStats& stats = player.getClass().getNpcStats (player);
|
||||||
std::map<std::string,int>::iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (info.mPcFaction));
|
std::map<std::string,int>::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (info.mPcFaction));
|
||||||
|
|
||||||
if(iter==stats.getFactionRanks().end())
|
if(iter==stats.getFactionRanks().end())
|
||||||
return false;
|
return false;
|
||||||
|
@ -379,7 +379,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
||||||
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
if (mActor.getClass().getNpcStats (mActor).getFactionRanks().empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::pair<std::string, int> faction =
|
const std::pair<std::string, int> faction =
|
||||||
*mActor.getClass().getNpcStats (mActor).getFactionRanks().begin();
|
*mActor.getClass().getNpcStats (mActor).getFactionRanks().begin();
|
||||||
|
|
||||||
int rank = getFactionRank (player, faction.first);
|
int rank = getFactionRank (player, faction.first);
|
||||||
|
|
|
@ -333,7 +333,8 @@ namespace MWGui
|
||||||
float e1 = 0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
float e1 = 0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
float f1 = 0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified();
|
float f1 = 0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||||
|
|
||||||
float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
float dispositionTerm = gmst.find("fDispositionMod")->getFloat() * (clampedDisposition - 50);
|
||||||
|
float pcTerm = (dispositionTerm - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
||||||
float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
|
float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
|
||||||
float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat();
|
float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat();
|
||||||
if (buying)
|
if (buying)
|
||||||
|
|
|
@ -385,7 +385,7 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
mOverencumberedMessageDelay -= dt;
|
mOverencumberedMessageDelay -= dt;
|
||||||
if (player.getClass().getEncumbrance(player) >= player.getClass().getCapacity(player))
|
if (player.getClass().getEncumbrance(player) > player.getClass().getCapacity(player))
|
||||||
{
|
{
|
||||||
mPlayer->setAutoMove (false);
|
mPlayer->setAutoMove (false);
|
||||||
if (mOverencumberedMessageDelay <= 0)
|
if (mOverencumberedMessageDelay <= 0)
|
||||||
|
|
|
@ -445,9 +445,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||||
|
|
||||||
float capacity = ptr.getClass().getCapacity(ptr);
|
float normalizedEncumbrance = ptr.getClass().getNormalizedEncumbrance(ptr);
|
||||||
float encumbrance = ptr.getClass().getEncumbrance(ptr);
|
|
||||||
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
|
|
||||||
if (normalizedEncumbrance > 1)
|
if (normalizedEncumbrance > 1)
|
||||||
normalizedEncumbrance = 1;
|
normalizedEncumbrance = 1;
|
||||||
|
|
||||||
|
@ -1447,6 +1445,8 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
if (followTarget == actor)
|
if (followTarget == actor)
|
||||||
list.push_back(iter->first);
|
list.push_back(iter->first);
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if ((*it)->getTypeId() != MWMechanics::AiPackage::TypeIdCombat)
|
else if ((*it)->getTypeId() != MWMechanics::AiPackage::TypeIdCombat)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1428,7 +1428,9 @@ void CharacterController::update(float duration)
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||||
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
|
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
|
||||||
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
|
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
|
||||||
const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr);
|
float normalizedEncumbrance = mPtr.getClass().getNormalizedEncumbrance(mPtr);
|
||||||
|
if (normalizedEncumbrance > 1)
|
||||||
|
normalizedEncumbrance = 1;
|
||||||
const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult;
|
const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult;
|
||||||
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
|
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
|
||||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
|
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace MWMechanics
|
||||||
const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
|
const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
|
||||||
const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
|
const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
|
||||||
MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
|
||||||
float normalizedEncumbrance = blocker.getClass().getEncumbrance(blocker) / blocker.getClass().getCapacity(blocker);
|
float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker);
|
||||||
normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
|
normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
|
||||||
float fatigueLoss = fFatigueBlockBase + normalizedEncumbrance * fFatigueBlockMult;
|
float fatigueLoss = fFatigueBlockBase + normalizedEncumbrance * fFatigueBlockMult;
|
||||||
fatigueLoss += weapon.getClass().getWeight(weapon) * attackerStats.getAttackStrength() * fWeaponFatigueBlockMult;
|
fatigueLoss += weapon.getClass().getWeight(weapon) * attackerStats.getAttackStrength() * fWeaponFatigueBlockMult;
|
||||||
|
|
|
@ -69,9 +69,41 @@ const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
|
||||||
return mFactionRank;
|
return mFactionRank;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks()
|
void MWMechanics::NpcStats::raiseRank(const std::string &faction)
|
||||||
{
|
{
|
||||||
return mFactionRank;
|
const std::string lower = Misc::StringUtils::lowerCase(faction);
|
||||||
|
std::map<std::string, int>::iterator it = mFactionRank.find(lower);
|
||||||
|
if (it != mFactionRank.end())
|
||||||
|
{
|
||||||
|
// Does the next rank exist?
|
||||||
|
const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(lower);
|
||||||
|
if (it->second+1 < 10 && !faction->mRanks[it->second+1].empty())
|
||||||
|
it->second += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::lowerRank(const std::string &faction)
|
||||||
|
{
|
||||||
|
const std::string lower = Misc::StringUtils::lowerCase(faction);
|
||||||
|
std::map<std::string, int>::iterator it = mFactionRank.find(lower);
|
||||||
|
if (it != mFactionRank.end())
|
||||||
|
{
|
||||||
|
it->second = std::max(0, it->second-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::setFactionRank(const std::string &faction, int rank)
|
||||||
|
{
|
||||||
|
const std::string lower = Misc::StringUtils::lowerCase(faction);
|
||||||
|
mFactionRank[lower] = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWMechanics::NpcStats::joinFaction(const std::string& faction)
|
||||||
|
{
|
||||||
|
const std::string lower = Misc::StringUtils::lowerCase(faction);
|
||||||
|
std::map<std::string, int>::iterator it = mFactionRank.find(lower);
|
||||||
|
if (it == mFactionRank.end())
|
||||||
|
mFactionRank[lower] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::NpcStats::getExpelled(const std::string& factionID) const
|
bool MWMechanics::NpcStats::getExpelled(const std::string& factionID) const
|
||||||
|
|
|
@ -70,7 +70,15 @@ namespace MWMechanics
|
||||||
SkillValue& getSkill (int index);
|
SkillValue& getSkill (int index);
|
||||||
|
|
||||||
const std::map<std::string, int>& getFactionRanks() const;
|
const std::map<std::string, int>& getFactionRanks() const;
|
||||||
std::map<std::string, int>& getFactionRanks();
|
/// Increase the rank in this faction by 1, if such a rank exists.
|
||||||
|
void raiseRank(const std::string& faction);
|
||||||
|
/// Lower the rank in this faction by 1, if such a rank exists.
|
||||||
|
void lowerRank(const std::string& faction);
|
||||||
|
/// Join this faction, setting the initial rank to 0.
|
||||||
|
void joinFaction(const std::string& faction);
|
||||||
|
/// Warning: this function performs no check whether the rank exists,
|
||||||
|
/// and should be used in initial actor setup only.
|
||||||
|
void setFactionRank(const std::string& faction, int rank);
|
||||||
|
|
||||||
const std::set<std::string>& getExpelled() const { return mExpelled; }
|
const std::set<std::string>& getExpelled() const { return mExpelled; }
|
||||||
bool getExpelled(const std::string& factionID) const;
|
bool getExpelled(const std::string& factionID) const;
|
||||||
|
|
|
@ -774,7 +774,7 @@ namespace MWMechanics
|
||||||
static const float fFatigueSpellBase = store.get<ESM::GameSetting>().find("fFatigueSpellBase")->getFloat();
|
static const float fFatigueSpellBase = store.get<ESM::GameSetting>().find("fFatigueSpellBase")->getFloat();
|
||||||
static const float fFatigueSpellMult = store.get<ESM::GameSetting>().find("fFatigueSpellMult")->getFloat();
|
static const float fFatigueSpellMult = store.get<ESM::GameSetting>().find("fFatigueSpellMult")->getFloat();
|
||||||
DynamicStat<float> fatigue = stats.getFatigue();
|
DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
const float normalizedEncumbrance = mCaster.getClass().getEncumbrance(mCaster) / mCaster.getClass().getCapacity(mCaster);
|
const float normalizedEncumbrance = mCaster.getClass().getNormalizedEncumbrance(mCaster);
|
||||||
float fatigueLoss = spell->mData.mCost * (fFatigueSpellBase + normalizedEncumbrance * fFatigueSpellMult);
|
float fatigueLoss = spell->mData.mCost * (fFatigueSpellBase + normalizedEncumbrance * fFatigueSpellMult);
|
||||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); stats.setFatigue(fatigue);
|
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss); stats.setFatigue(fatigue);
|
||||||
|
|
||||||
|
|
|
@ -728,7 +728,7 @@ void Animation::handleTextKey(AnimState &state, const std::string &groupname, co
|
||||||
{
|
{
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
MWBase::SoundManager::PlayType type = MWBase::SoundManager::Play_TypeSfx;
|
MWBase::SoundManager::PlayType type = MWBase::SoundManager::Play_TypeSfx;
|
||||||
if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0)
|
if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0 || evt.compare(10, evt.size()-10, "land") == 0)
|
||||||
type = MWBase::SoundManager::Play_TypeFoot;
|
type = MWBase::SoundManager::Play_TypeFoot;
|
||||||
sndMgr->playSound3D(mPtr, sound, volume, pitch, type);
|
sndMgr->playSound3D(mPtr, sound, volume, pitch, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,6 @@ void RenderingManager::cellAdded (MWWorld::CellStore *store)
|
||||||
mObjects->buildStaticGeometry (*store);
|
mObjects->buildStaticGeometry (*store);
|
||||||
sh::Factory::getInstance().unloadUnreferencedMaterials();
|
sh::Factory::getInstance().unloadUnreferencedMaterials();
|
||||||
mDebugging->cellAdded(store);
|
mDebugging->cellAdded(store);
|
||||||
waterAdded(store);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::addObject (const MWWorld::Ptr& ptr){
|
void RenderingManager::addObject (const MWWorld::Ptr& ptr){
|
||||||
|
@ -421,18 +420,12 @@ void RenderingManager::postRenderTargetUpdate(const RenderTargetEvent &evt)
|
||||||
mOcclusionQuery->setActive(false);
|
mOcclusionQuery->setActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::waterAdded (MWWorld::CellStore *store)
|
void RenderingManager::setWaterEnabled(bool enable)
|
||||||
{
|
{
|
||||||
if (store->getCell()->mData.mFlags & ESM::Cell::HasWater)
|
mWater->setActive(enable);
|
||||||
{
|
|
||||||
mWater->changeCell (store->getCell());
|
|
||||||
mWater->setActive(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
removeWater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::setWaterHeight(const float height)
|
void RenderingManager::setWaterHeight(float height)
|
||||||
{
|
{
|
||||||
mWater->setHeight(height);
|
mWater->setHeight(height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,6 @@ public:
|
||||||
/// \todo this function should be removed later. Instead the rendering subsystems should track
|
/// \todo this function should be removed later. Instead the rendering subsystems should track
|
||||||
/// when rebatching is needed and update automatically at the end of each frame.
|
/// when rebatching is needed and update automatically at the end of each frame.
|
||||||
void cellAdded (MWWorld::CellStore *store);
|
void cellAdded (MWWorld::CellStore *store);
|
||||||
void waterAdded(MWWorld::CellStore *store);
|
|
||||||
|
|
||||||
/// Clear all savegame-specific data (i.e. fog of war textures)
|
/// Clear all savegame-specific data (i.e. fog of war textures)
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -121,7 +120,8 @@ public:
|
||||||
/// Updates an object's rotation
|
/// Updates an object's rotation
|
||||||
void rotateObject (const MWWorld::Ptr& ptr);
|
void rotateObject (const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
void setWaterHeight(const float height);
|
void setWaterHeight(float height);
|
||||||
|
void setWaterEnabled(bool enabled);
|
||||||
bool toggleWater();
|
bool toggleWater();
|
||||||
bool toggleWorld();
|
bool toggleWorld();
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
|
||||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
||||||
MWMechanics::CreatureStats& attackerStats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& attackerStats = actor.getClass().getCreatureStats(actor);
|
||||||
MWMechanics::DynamicStat<float> fatigue = attackerStats.getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = attackerStats.getFatigue();
|
||||||
const float normalizedEncumbrance = actor.getClass().getEncumbrance(actor) / actor.getClass().getCapacity(actor);
|
const float normalizedEncumbrance = actor.getClass().getNormalizedEncumbrance(actor);
|
||||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||||
if (!weapon->isEmpty())
|
if (!weapon->isEmpty())
|
||||||
fatigueLoss += weapon->getClass().getWeight(*weapon) * attackerStats.getAttackStrength() * fWeaponFatigueMult;
|
fatigueLoss += weapon->getClass().getWeight(*weapon) * attackerStats.getAttackStrength() * fWeaponFatigueMult;
|
||||||
|
|
|
@ -290,18 +290,15 @@ namespace MWScript
|
||||||
const std::string &name = runtime.getStringLiteral (runtime[0].mInteger);
|
const std::string &name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr);
|
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr);
|
||||||
for (MWWorld::ContainerStoreIterator it = invStore.begin(MWWorld::ContainerStore::Type_Miscellaneous);
|
for (MWWorld::ContainerStoreIterator it = invStore.begin(MWWorld::ContainerStore::Type_Miscellaneous);
|
||||||
it != invStore.end(); ++it)
|
it != invStore.end(); ++it)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), name))
|
if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), name))
|
||||||
{
|
++count;
|
||||||
runtime.push(1);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
runtime.push(count);
|
||||||
runtime.push(0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace MWScript
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCRank() const
|
std::string InterpreterContext::getNPCRank() const
|
||||||
{
|
{
|
||||||
std::map<std::string, int> ranks = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks();
|
const std::map<std::string, int>& ranks = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.begin();
|
std::map<std::string, int>::const_iterator it = ranks.begin();
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -348,7 +348,7 @@ namespace MWScript
|
||||||
|
|
||||||
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
||||||
|
|
||||||
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
||||||
int rank = -1;
|
int rank = -1;
|
||||||
if (it != ranks.end())
|
if (it != ranks.end())
|
||||||
|
@ -375,7 +375,7 @@ namespace MWScript
|
||||||
|
|
||||||
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
||||||
|
|
||||||
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
const std::map<std::string, int>& ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
||||||
int rank = -1;
|
int rank = -1;
|
||||||
if (it != ranks.end())
|
if (it != ranks.end())
|
||||||
|
|
|
@ -548,10 +548,7 @@ namespace MWScript
|
||||||
if(factionID != "")
|
if(factionID != "")
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) == player.getClass().getNpcStats(player).getFactionRanks().end())
|
player.getClass().getNpcStats(player).joinFaction(factionID);
|
||||||
{
|
|
||||||
player.getClass().getNpcStats(player).getFactionRanks()[factionID] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -585,13 +582,11 @@ namespace MWScript
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) == player.getClass().getNpcStats(player).getFactionRanks().end())
|
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) == player.getClass().getNpcStats(player).getFactionRanks().end())
|
||||||
{
|
{
|
||||||
player.getClass().getNpcStats(player).getFactionRanks()[factionID] = 0;
|
player.getClass().getNpcStats(player).joinFaction(factionID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player.getClass().getNpcStats(player).getFactionRanks()[factionID] =
|
player.getClass().getNpcStats(player).raiseRank(factionID);
|
||||||
std::min(player.getClass().getNpcStats(player).getFactionRanks()[factionID] +1,
|
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,11 +619,7 @@ namespace MWScript
|
||||||
if(factionID != "")
|
if(factionID != "")
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) != player.getClass().getNpcStats(player).getFactionRanks().end())
|
player.getClass().getNpcStats(player).lowerRank(factionID);
|
||||||
{
|
|
||||||
player.getClass().getNpcStats(player).getFactionRanks()[factionID] =
|
|
||||||
std::max(0, player.getClass().getNpcStats(player).getFactionRanks()[factionID]-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -668,7 +659,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) != player.getClass().getNpcStats(player).getFactionRanks().end())
|
if(player.getClass().getNpcStats(player).getFactionRanks().find(factionID) != player.getClass().getNpcStats(player).getFactionRanks().end())
|
||||||
{
|
{
|
||||||
runtime.push(player.getClass().getNpcStats(player).getFactionRanks()[factionID]);
|
runtime.push(player.getClass().getNpcStats(player).getFactionRanks().at(factionID));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1036,8 +1027,7 @@ namespace MWScript
|
||||||
if (ptr == player)
|
if (ptr == player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::map<std::string, int>& ranks = ptr.getClass().getNpcStats(ptr).getFactionRanks ();
|
ptr.getClass().getNpcStats(ptr).raiseRank(factionID);
|
||||||
ranks[factionID] = std::min(9, ranks[factionID]+1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1063,8 +1053,7 @@ namespace MWScript
|
||||||
if (ptr == player)
|
if (ptr == player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::map<std::string, int>& ranks = ptr.getClass().getNpcStats(ptr).getFactionRanks ();
|
ptr.getClass().getNpcStats(ptr).lowerRank(factionID);
|
||||||
ranks[factionID] = std::max(0, ranks[factionID]-1);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,23 @@
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void getFollowers (const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out)
|
||||||
|
{
|
||||||
|
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
|
||||||
|
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
||||||
|
{
|
||||||
|
if (out.insert(*it).second)
|
||||||
|
{
|
||||||
|
getFollowers(*it, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
ActionTeleport::ActionTeleport (const std::string& cellName,
|
ActionTeleport::ActionTeleport (const std::string& cellName,
|
||||||
|
@ -16,8 +33,9 @@ namespace MWWorld
|
||||||
void ActionTeleport::executeImp (const Ptr& actor)
|
void ActionTeleport::executeImp (const Ptr& actor)
|
||||||
{
|
{
|
||||||
//find any NPC that is following the actor and teleport him too
|
//find any NPC that is following the actor and teleport him too
|
||||||
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
|
std::set<MWWorld::Ptr> followers;
|
||||||
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
getFollowers(actor, followers);
|
||||||
|
for(std::set<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
||||||
{
|
{
|
||||||
teleport(*it);
|
teleport(*it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,4 +420,13 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
throw std::runtime_error("this is not a door");
|
throw std::runtime_error("this is not a door");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Class::getNormalizedEncumbrance(const Ptr &ptr) const
|
||||||
|
{
|
||||||
|
float capacity = getCapacity(ptr);
|
||||||
|
if (capacity == 0)
|
||||||
|
return 1.f;
|
||||||
|
|
||||||
|
return getEncumbrance(ptr) / capacity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,9 @@ namespace MWWorld
|
||||||
/// effects). Throws an exception, if the object can't hold other objects.
|
/// effects). Throws an exception, if the object can't hold other objects.
|
||||||
/// (default implementation: throws an exception)
|
/// (default implementation: throws an exception)
|
||||||
|
|
||||||
|
virtual float getNormalizedEncumbrance (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Returns encumbrance re-scaled to capacity
|
||||||
|
|
||||||
virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id,
|
virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id,
|
||||||
const MWWorld::Ptr& actor) const;
|
const MWWorld::Ptr& actor) const;
|
||||||
///< Apply \a id on \a ptr.
|
///< Apply \a id on \a ptr.
|
||||||
|
|
|
@ -68,6 +68,7 @@ MWWorld::InventoryStore::InventoryStore()
|
||||||
, mUpdatesEnabled (true)
|
, mUpdatesEnabled (true)
|
||||||
, mFirstAutoEquip(true)
|
, mFirstAutoEquip(true)
|
||||||
, mListener(NULL)
|
, mListener(NULL)
|
||||||
|
, mRechargingItemsUpToDate(false)
|
||||||
{
|
{
|
||||||
initSlots (mSlots);
|
initSlots (mSlots);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +81,7 @@ MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
|
||||||
, mListener(store.mListener)
|
, mListener(store.mListener)
|
||||||
, mUpdatesEnabled(store.mUpdatesEnabled)
|
, mUpdatesEnabled(store.mUpdatesEnabled)
|
||||||
, mPermanentMagicEffectMagnitudes(store.mPermanentMagicEffectMagnitudes)
|
, mPermanentMagicEffectMagnitudes(store.mPermanentMagicEffectMagnitudes)
|
||||||
|
, mRechargingItemsUpToDate(false)
|
||||||
{
|
{
|
||||||
copySlots (store);
|
copySlots (store);
|
||||||
}
|
}
|
||||||
|
@ -90,6 +92,7 @@ MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStor
|
||||||
mMagicEffects = store.mMagicEffects;
|
mMagicEffects = store.mMagicEffects;
|
||||||
mFirstAutoEquip = store.mFirstAutoEquip;
|
mFirstAutoEquip = store.mFirstAutoEquip;
|
||||||
mPermanentMagicEffectMagnitudes = store.mPermanentMagicEffectMagnitudes;
|
mPermanentMagicEffectMagnitudes = store.mPermanentMagicEffectMagnitudes;
|
||||||
|
mRechargingItemsUpToDate = false;
|
||||||
ContainerStore::operator= (store);
|
ContainerStore::operator= (store);
|
||||||
mSlots.clear();
|
mSlots.clear();
|
||||||
copySlots (store);
|
copySlots (store);
|
||||||
|
@ -110,8 +113,6 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
|
||||||
autoEquip(actorPtr);
|
autoEquip(actorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRechargingItems();
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,8 +486,6 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
|
||||||
mSelectedEnchantItem = end();
|
mSelectedEnchantItem = end();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRechargingItems();
|
|
||||||
|
|
||||||
return retCount;
|
return retCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,6 +605,11 @@ void MWWorld::InventoryStore::updateRechargingItems()
|
||||||
|
|
||||||
void MWWorld::InventoryStore::rechargeItems(float duration)
|
void MWWorld::InventoryStore::rechargeItems(float duration)
|
||||||
{
|
{
|
||||||
|
if (!mRechargingItemsUpToDate)
|
||||||
|
{
|
||||||
|
updateRechargingItems();
|
||||||
|
mRechargingItemsUpToDate = true;
|
||||||
|
}
|
||||||
for (TRechargingItems::iterator it = mRechargingItems.begin(); it != mRechargingItems.end(); ++it)
|
for (TRechargingItems::iterator it = mRechargingItems.begin(); it != mRechargingItems.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->first->getCellRef().getEnchantmentCharge() == -1
|
if (it->first->getCellRef().getEnchantmentCharge() == -1
|
||||||
|
|
|
@ -102,6 +102,8 @@ namespace MWWorld
|
||||||
typedef std::vector<std::pair<ContainerStoreIterator, float> > TRechargingItems;
|
typedef std::vector<std::pair<ContainerStoreIterator, float> > TRechargingItems;
|
||||||
TRechargingItems mRechargingItems;
|
TRechargingItems mRechargingItems;
|
||||||
|
|
||||||
|
bool mRechargingItemsUpToDate;
|
||||||
|
|
||||||
void copySlots (const InventoryStore& store);
|
void copySlots (const InventoryStore& store);
|
||||||
|
|
||||||
void initSlots (TSlots& slots_);
|
void initSlots (TSlots& slots_);
|
||||||
|
|
|
@ -278,8 +278,10 @@ namespace MWWorld
|
||||||
if (!ptr.getClass().canWalk(ptr) && !ptr.getClass().canFly(ptr) && !ptr.getClass().canSwim(ptr))
|
if (!ptr.getClass().canWalk(ptr) && !ptr.getClass().canFly(ptr) && !ptr.getClass().canSwim(ptr))
|
||||||
return position;
|
return position;
|
||||||
|
|
||||||
/* Anything to collide with? */
|
|
||||||
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
||||||
|
// Reset per-frame data
|
||||||
|
physicActor->setWalkingOnWater(false);
|
||||||
|
/* Anything to collide with? */
|
||||||
if(!physicActor || !physicActor->getCollisionMode())
|
if(!physicActor || !physicActor->getCollisionMode())
|
||||||
{
|
{
|
||||||
return position + (Ogre::Quaternion(Ogre::Radian(refpos.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
return position + (Ogre::Quaternion(Ogre::Radian(refpos.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
||||||
|
@ -307,9 +309,6 @@ namespace MWWorld
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OEngine::Physic::ActorTracer tracer;
|
OEngine::Physic::ActorTracer tracer;
|
||||||
bool isOnGround = physicActor->getOnGround();
|
|
||||||
if (movement.z > 0.f)
|
|
||||||
isOnGround = false;
|
|
||||||
Ogre::Vector3 inertia(0.0f);
|
Ogre::Vector3 inertia(0.0f);
|
||||||
Ogre::Vector3 velocity;
|
Ogre::Vector3 velocity;
|
||||||
|
|
||||||
|
@ -426,8 +425,6 @@ namespace MWWorld
|
||||||
if((ptr.getClass().canSwim(ptr) && !ptr.getClass().canWalk(ptr))
|
if((ptr.getClass().canSwim(ptr) && !ptr.getClass().canWalk(ptr))
|
||||||
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
||||||
newPosition = oldPosition;
|
newPosition = oldPosition;
|
||||||
else // Only on the ground if there's gravity
|
|
||||||
isOnGround = !(newPosition.z < waterlevel || isFlying);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -444,10 +441,11 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(inertia.z > 0.f) && !(newPosition.z < waterlevel || isFlying))
|
bool isOnGround = false;
|
||||||
|
if (!(inertia.z > 0.f) && !(newPosition.z < waterlevel))
|
||||||
{
|
{
|
||||||
Ogre::Vector3 from = newPosition;
|
Ogre::Vector3 from = newPosition;
|
||||||
Ogre::Vector3 to = newPosition - (isOnGround ?
|
Ogre::Vector3 to = newPosition - (physicActor->getOnGround() ?
|
||||||
Ogre::Vector3(0,0,sStepSize+2.f) : Ogre::Vector3(0,0,2.f));
|
Ogre::Vector3(0,0,sStepSize+2.f) : Ogre::Vector3(0,0,2.f));
|
||||||
tracer.doTrace(colobj, from, to, engine);
|
tracer.doTrace(colobj, from, to, engine);
|
||||||
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
||||||
|
@ -457,7 +455,10 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
|
standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
|
||||||
}
|
}
|
||||||
|
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == OEngine::Physic::CollisionType_Water)
|
||||||
|
physicActor->setWalkingOnWater(true);
|
||||||
|
|
||||||
|
if (!isFlying)
|
||||||
newPosition.z = tracer.mEndPos.z + 1.0f;
|
newPosition.z = tracer.mEndPos.z + 1.0f;
|
||||||
|
|
||||||
isOnGround = true;
|
isOnGround = true;
|
||||||
|
@ -485,7 +486,7 @@ namespace MWWorld
|
||||||
|
|
||||||
|
|
||||||
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
|
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
|
||||||
mRender(_rend), mEngine(0), mTimeAccum(0.0f)
|
mRender(_rend), mEngine(0), mTimeAccum(0.0f), mWaterEnabled(false), mWaterHeight(0)
|
||||||
{
|
{
|
||||||
// Create physics. shapeLoader is deleted by the physic engine
|
// Create physics. shapeLoader is deleted by the physic engine
|
||||||
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
||||||
|
@ -494,6 +495,8 @@ namespace MWWorld
|
||||||
|
|
||||||
PhysicsSystem::~PhysicsSystem()
|
PhysicsSystem::~PhysicsSystem()
|
||||||
{
|
{
|
||||||
|
if (mWaterCollisionObject.get())
|
||||||
|
mEngine->mDynamicsWorld->removeCollisionObject(mWaterCollisionObject.get());
|
||||||
delete mEngine;
|
delete mEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,9 +664,9 @@ namespace MWWorld
|
||||||
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
||||||
handleToMesh[node->getName()] = mesh;
|
handleToMesh[node->getName()] = mesh;
|
||||||
mEngine->createAndAdjustRigidBody(
|
mEngine->createAndAdjustRigidBody(
|
||||||
mesh, node->getName(), node->getScale().x, node->getPosition(), node->getOrientation(), 0, 0, false, placeable);
|
mesh, node->getName(), ptr.getCellRef().getScale(), node->getPosition(), node->getOrientation(), 0, 0, false, placeable);
|
||||||
mEngine->createAndAdjustRigidBody(
|
mEngine->createAndAdjustRigidBody(
|
||||||
mesh, node->getName(), node->getScale().x, node->getPosition(), node->getOrientation(), 0, 0, true, placeable);
|
mesh, node->getName(), ptr.getCellRef().getScale(), node->getPosition(), node->getOrientation(), 0, 0, true, placeable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addActor (const Ptr& ptr)
|
void PhysicsSystem::addActor (const Ptr& ptr)
|
||||||
|
@ -855,14 +858,10 @@ namespace MWWorld
|
||||||
Ogre::Vector3(iter->first.getRefData().getPosition().pos)))
|
Ogre::Vector3(iter->first.getRefData().getPosition().pos)))
|
||||||
waterCollision = true;
|
waterCollision = true;
|
||||||
|
|
||||||
btStaticPlaneShape planeShape(btVector3(0,0,1), waterlevel);
|
OEngine::Physic::PhysicActor *physicActor = mEngine->getCharacter(iter->first.getRefData().getHandle());
|
||||||
btCollisionObject object;
|
if (!physicActor) // actor was already removed from the scene
|
||||||
object.setCollisionShape(&planeShape);
|
continue;
|
||||||
|
physicActor->setCanWaterWalk(waterCollision);
|
||||||
// TODO: this seems to have a slight performance impact
|
|
||||||
if (waterCollision)
|
|
||||||
mEngine->mDynamicsWorld->addCollisionObject(&object,
|
|
||||||
0xff, OEngine::Physic::CollisionType_Actor);
|
|
||||||
|
|
||||||
// 100 points of slowfall reduce gravity by 90% (this is just a guess)
|
// 100 points of slowfall reduce gravity by 90% (this is just a guess)
|
||||||
float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).getMagnitude() / 100.f) * 0.9f), 0.9f);
|
float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).getMagnitude() / 100.f) * 0.9f), 0.9f);
|
||||||
|
@ -871,9 +870,6 @@ namespace MWWorld
|
||||||
world->isFlying(iter->first),
|
world->isFlying(iter->first),
|
||||||
waterlevel, slowFall, mEngine, mCollisions, mStandingCollisions);
|
waterlevel, slowFall, mEngine, mCollisions, mStandingCollisions);
|
||||||
|
|
||||||
if (waterCollision)
|
|
||||||
mEngine->mDynamicsWorld->removeCollisionObject(&object);
|
|
||||||
|
|
||||||
float heightDiff = newpos.z - oldHeight;
|
float heightDiff = newpos.z - oldHeight;
|
||||||
|
|
||||||
if (heightDiff < 0)
|
if (heightDiff < 0)
|
||||||
|
@ -949,4 +945,48 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::disableWater()
|
||||||
|
{
|
||||||
|
if (mWaterEnabled)
|
||||||
|
{
|
||||||
|
mWaterEnabled = false;
|
||||||
|
updateWater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::enableWater(float height)
|
||||||
|
{
|
||||||
|
if (!mWaterEnabled || mWaterHeight != height)
|
||||||
|
{
|
||||||
|
mWaterEnabled = true;
|
||||||
|
mWaterHeight = height;
|
||||||
|
updateWater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::setWaterHeight(float height)
|
||||||
|
{
|
||||||
|
if (mWaterHeight != height)
|
||||||
|
{
|
||||||
|
mWaterHeight = height;
|
||||||
|
updateWater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::updateWater()
|
||||||
|
{
|
||||||
|
if (mWaterCollisionObject.get())
|
||||||
|
{
|
||||||
|
mEngine->mDynamicsWorld->removeCollisionObject(mWaterCollisionObject.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mWaterEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mWaterCollisionObject.reset(new btCollisionObject());
|
||||||
|
mWaterCollisionShape.reset(new btStaticPlaneShape(btVector3(0,0,1), mWaterHeight));
|
||||||
|
mWaterCollisionObject->setCollisionShape(mWaterCollisionShape.get());
|
||||||
|
mEngine->mDynamicsWorld->addCollisionObject(mWaterCollisionObject.get(), OEngine::Physic::CollisionType_Water,
|
||||||
|
OEngine::Physic::CollisionType_Actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef GAME_MWWORLD_PHYSICSSYSTEM_H
|
#ifndef GAME_MWWORLD_PHYSICSSYSTEM_H
|
||||||
#define GAME_MWWORLD_PHYSICSSYSTEM_H
|
#define GAME_MWWORLD_PHYSICSSYSTEM_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
|
@ -32,6 +34,10 @@ namespace MWWorld
|
||||||
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
||||||
~PhysicsSystem ();
|
~PhysicsSystem ();
|
||||||
|
|
||||||
|
void enableWater(float height);
|
||||||
|
void setWaterHeight(float height);
|
||||||
|
void disableWater();
|
||||||
|
|
||||||
void addObject (const MWWorld::Ptr& ptr, bool placeable=false);
|
void addObject (const MWWorld::Ptr& ptr, bool placeable=false);
|
||||||
|
|
||||||
void addActor (const MWWorld::Ptr& ptr);
|
void addActor (const MWWorld::Ptr& ptr);
|
||||||
|
@ -108,6 +114,8 @@ namespace MWWorld
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void updateWater();
|
||||||
|
|
||||||
OEngine::Render::OgreRenderer &mRender;
|
OEngine::Render::OgreRenderer &mRender;
|
||||||
OEngine::Physic::PhysicEngine* mEngine;
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
std::map<std::string, std::string> handleToMesh;
|
std::map<std::string, std::string> handleToMesh;
|
||||||
|
@ -124,6 +132,12 @@ namespace MWWorld
|
||||||
|
|
||||||
float mTimeAccum;
|
float mTimeAccum;
|
||||||
|
|
||||||
|
float mWaterHeight;
|
||||||
|
float mWaterEnabled;
|
||||||
|
|
||||||
|
std::auto_ptr<btCollisionObject> mWaterCollisionObject;
|
||||||
|
std::auto_ptr<btCollisionShape> mWaterCollisionShape;
|
||||||
|
|
||||||
PhysicsSystem (const PhysicsSystem&);
|
PhysicsSystem (const PhysicsSystem&);
|
||||||
PhysicsSystem& operator= (const PhysicsSystem&);
|
PhysicsSystem& operator= (const PhysicsSystem&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -153,6 +153,7 @@ namespace MWWorld
|
||||||
Ogre::Vector3 pos(it->mNode->getPosition());
|
Ogre::Vector3 pos(it->mNode->getPosition());
|
||||||
Ogre::Vector3 newPos = pos + direction * duration * speed;
|
Ogre::Vector3 newPos = pos + direction * duration * speed;
|
||||||
|
|
||||||
|
if (it->mSound.get())
|
||||||
it->mSound->setPosition(newPos);
|
it->mSound->setPosition(newPos);
|
||||||
|
|
||||||
it->mNode->setPosition(newPos);
|
it->mNode->setPosition(newPos);
|
||||||
|
@ -163,7 +164,8 @@ namespace MWWorld
|
||||||
// TODO: use a proper btRigidBody / btGhostObject?
|
// TODO: use a proper btRigidBody / btGhostObject?
|
||||||
btVector3 from(pos.x, pos.y, pos.z);
|
btVector3 from(pos.x, pos.y, pos.z);
|
||||||
btVector3 to(newPos.x, newPos.y, newPos.z);
|
btVector3 to(newPos.x, newPos.y, newPos.z);
|
||||||
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to);
|
|
||||||
|
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile);
|
||||||
bool hit=false;
|
bool hit=false;
|
||||||
|
|
||||||
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
||||||
|
@ -239,7 +241,7 @@ namespace MWWorld
|
||||||
// TODO: use a proper btRigidBody / btGhostObject?
|
// TODO: use a proper btRigidBody / btGhostObject?
|
||||||
btVector3 from(pos.x, pos.y, pos.z);
|
btVector3 from(pos.x, pos.y, pos.z);
|
||||||
btVector3 to(newPos.x, newPos.y, newPos.z);
|
btVector3 to(newPos.x, newPos.y, newPos.z);
|
||||||
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to);
|
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile);
|
||||||
bool hit=false;
|
bool hit=false;
|
||||||
|
|
||||||
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
||||||
|
@ -408,6 +410,7 @@ namespace MWWorld
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f,
|
state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f,
|
||||||
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
|
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
|
||||||
|
state.mSoundId = esm.mSound;
|
||||||
|
|
||||||
mMagicBolts.push_back(state);
|
mMagicBolts.push_back(state);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -83,7 +83,12 @@ namespace
|
||||||
ptr.getClass().insertObject (ptr, mPhysics);
|
ptr.getClass().insertObject (ptr, mPhysics);
|
||||||
|
|
||||||
updateObjectLocalRotation(ptr, mPhysics, mRendering);
|
updateObjectLocalRotation(ptr, mPhysics, mRendering);
|
||||||
MWBase::Environment::get().getWorld()->scaleObject (ptr, ptr.getCellRef().getScale());
|
if (ptr.getRefData().getBaseNode())
|
||||||
|
{
|
||||||
|
float scale = ptr.getCellRef().getScale();
|
||||||
|
ptr.getClass().adjustScale(ptr, scale);
|
||||||
|
mRendering.scaleObject(ptr, Ogre::Vector3(scale));
|
||||||
|
}
|
||||||
ptr.getClass().adjustPosition (ptr, false);
|
ptr.getClass().adjustPosition (ptr, false);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
|
@ -233,6 +238,15 @@ namespace MWWorld
|
||||||
insertCell (*cell, true, loadingListener);
|
insertCell (*cell, true, loadingListener);
|
||||||
|
|
||||||
mRendering.cellAdded (cell);
|
mRendering.cellAdded (cell);
|
||||||
|
bool waterEnabled = cell->getCell()->hasWater();
|
||||||
|
mRendering.setWaterEnabled(waterEnabled);
|
||||||
|
if (waterEnabled)
|
||||||
|
{
|
||||||
|
mPhysics->enableWater(cell->getWaterLevel());
|
||||||
|
mRendering.setWaterHeight(cell->getWaterLevel());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mPhysics->disableWater();
|
||||||
|
|
||||||
mRendering.configureAmbient(*cell);
|
mRendering.configureAmbient(*cell);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1660,6 +1660,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::setWaterHeight(const float height)
|
void World::setWaterHeight(const float height)
|
||||||
{
|
{
|
||||||
|
mPhysics->setWaterHeight(height);
|
||||||
mRendering->setWaterHeight(height);
|
mRendering->setWaterHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1994,7 +1995,7 @@ namespace MWWorld
|
||||||
Ogre::Vector3 playerPos(refdata.getPosition().pos);
|
Ogre::Vector3 playerPos(refdata.getPosition().pos);
|
||||||
|
|
||||||
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||||
if((!physactor->getOnGround()&&physactor->getCollisionMode()) || isUnderwater(currentCell, playerPos))
|
if((!physactor->getOnGround()&&physactor->getCollisionMode()) || isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||||
return 2;
|
return 2;
|
||||||
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
|
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
|
||||||
player.getClass().getNpcStats(player).isWerewolf())
|
player.getClass().getNpcStats(player).isWerewolf())
|
||||||
|
@ -3073,4 +3074,12 @@ namespace MWWorld
|
||||||
cellstore->forEach(functor);
|
cellstore->forEach(functor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool World::isWalkingOnWater(const Ptr &actor)
|
||||||
|
{
|
||||||
|
OEngine::Physic::PhysicActor* physicActor = mPhysEngine->getCharacter(actor.getRefData().getHandle());
|
||||||
|
if (physicActor && physicActor->isWalkingOnWater())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -615,6 +615,8 @@ namespace MWWorld
|
||||||
|
|
||||||
/// Resets all actors in the current active cells to their original location within that cell.
|
/// Resets all actors in the current active cells to their original location within that cell.
|
||||||
virtual void resetActors();
|
virtual void resetActors();
|
||||||
|
|
||||||
|
virtual bool isWalkingOnWater (const MWWorld::Ptr& actor);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace Physic
|
||||||
, mExternalCollisionMode(true)
|
, mExternalCollisionMode(true)
|
||||||
, mForce(0.0f)
|
, mForce(0.0f)
|
||||||
, mScale(scale)
|
, mScale(scale)
|
||||||
|
, mWalkingOnWater(false)
|
||||||
|
, mCanWaterWalk(false)
|
||||||
{
|
{
|
||||||
if (!NifBullet::getBoundingBox(mMesh, mHalfExtents, mMeshTranslation, mMeshOrientation))
|
if (!NifBullet::getBoundingBox(mMesh, mHalfExtents, mMeshTranslation, mMeshOrientation))
|
||||||
{
|
{
|
||||||
|
@ -103,8 +105,7 @@ namespace Physic
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
setRotation(rotation);
|
setRotation(rotation);
|
||||||
|
|
||||||
mEngine->mDynamicsWorld->addRigidBody(mBody, CollisionType_Actor,
|
updateCollisionMask();
|
||||||
CollisionType_Actor|CollisionType_World|CollisionType_HeightMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicActor::~PhysicActor()
|
PhysicActor::~PhysicActor()
|
||||||
|
@ -123,10 +124,22 @@ namespace Physic
|
||||||
|
|
||||||
void PhysicActor::enableCollisionBody(bool collision)
|
void PhysicActor::enableCollisionBody(bool collision)
|
||||||
{
|
{
|
||||||
assert(mBody);
|
if (mExternalCollisionMode != collision)
|
||||||
if(collision && !mExternalCollisionMode) enableCollisionBody();
|
{
|
||||||
if(!collision && mExternalCollisionMode) disableCollisionBody();
|
|
||||||
mExternalCollisionMode = collision;
|
mExternalCollisionMode = collision;
|
||||||
|
updateCollisionMask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicActor::updateCollisionMask()
|
||||||
|
{
|
||||||
|
mEngine->mDynamicsWorld->removeRigidBody(mBody);
|
||||||
|
int collisionMask = CollisionType_World | CollisionType_HeightMap;
|
||||||
|
if (mExternalCollisionMode)
|
||||||
|
collisionMask |= CollisionType_Actor | CollisionType_Projectile;
|
||||||
|
if (mCanWaterWalk)
|
||||||
|
collisionMask |= CollisionType_Water;
|
||||||
|
mEngine->mDynamicsWorld->addRigidBody(mBody, CollisionType_Actor, collisionMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Ogre::Vector3& PhysicActor::getPosition() const
|
const Ogre::Vector3& PhysicActor::getPosition() const
|
||||||
|
@ -178,18 +191,23 @@ namespace Physic
|
||||||
mOnGround = grounded;
|
mOnGround = grounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::disableCollisionBody()
|
bool PhysicActor::isWalkingOnWater() const
|
||||||
{
|
{
|
||||||
mEngine->mDynamicsWorld->removeRigidBody(mBody);
|
return mWalkingOnWater;
|
||||||
mEngine->mDynamicsWorld->addRigidBody(mBody, CollisionType_Actor,
|
|
||||||
CollisionType_World|CollisionType_HeightMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::enableCollisionBody()
|
void PhysicActor::setWalkingOnWater(bool walkingOnWater)
|
||||||
{
|
{
|
||||||
mEngine->mDynamicsWorld->removeRigidBody(mBody);
|
mWalkingOnWater = walkingOnWater;
|
||||||
mEngine->mDynamicsWorld->addRigidBody(mBody, CollisionType_Actor,
|
}
|
||||||
CollisionType_Actor|CollisionType_World|CollisionType_HeightMap);
|
|
||||||
|
void PhysicActor::setCanWaterWalk(bool waterWalk)
|
||||||
|
{
|
||||||
|
if (waterWalk != mCanWaterWalk)
|
||||||
|
{
|
||||||
|
mCanWaterWalk = waterWalk;
|
||||||
|
updateCollisionMask();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -381,7 +399,7 @@ namespace Physic
|
||||||
mHeightFieldMap [name] = hf;
|
mHeightFieldMap [name] = hf;
|
||||||
|
|
||||||
mDynamicsWorld->addRigidBody(body,CollisionType_HeightMap,
|
mDynamicsWorld->addRigidBody(body,CollisionType_HeightMap,
|
||||||
CollisionType_Actor|CollisionType_Raycasting);
|
CollisionType_Actor|CollisionType_Raycasting|CollisionType_Projectile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicEngine::removeHeightField(int x, int y)
|
void PhysicEngine::removeHeightField(int x, int y)
|
||||||
|
@ -494,7 +512,7 @@ namespace Physic
|
||||||
{
|
{
|
||||||
assert (mRaycastingObjectMap.find(name) == mRaycastingObjectMap.end());
|
assert (mRaycastingObjectMap.find(name) == mRaycastingObjectMap.end());
|
||||||
mRaycastingObjectMap[name] = body;
|
mRaycastingObjectMap[name] = body;
|
||||||
mDynamicsWorld->addRigidBody(body,CollisionType_Raycasting,CollisionType_Raycasting);
|
mDynamicsWorld->addRigidBody(body,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_Projectile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
|
@ -800,10 +818,10 @@ namespace Physic
|
||||||
return std::make_pair(false, 1);
|
return std::make_pair(false, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(const btVector3& from, const btVector3& to)
|
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(const btVector3& from, const btVector3& to, int filterGroup)
|
||||||
{
|
{
|
||||||
MyRayResultCallback resultCallback1;
|
MyRayResultCallback resultCallback1;
|
||||||
resultCallback1.m_collisionFilterGroup = 0xff;
|
resultCallback1.m_collisionFilterGroup = filterGroup;
|
||||||
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting|CollisionType_Actor|CollisionType_HeightMap;
|
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting|CollisionType_Actor|CollisionType_HeightMap;
|
||||||
mDynamicsWorld->rayTest(from, to, resultCallback1);
|
mDynamicsWorld->rayTest(from, to, resultCallback1);
|
||||||
std::vector< std::pair<float, const btCollisionObject*> > results = resultCallback1.results;
|
std::vector< std::pair<float, const btCollisionObject*> > results = resultCallback1.results;
|
||||||
|
|
|
@ -46,7 +46,9 @@ namespace Physic
|
||||||
CollisionType_World = 1<<0, //<Collide with world objects
|
CollisionType_World = 1<<0, //<Collide with world objects
|
||||||
CollisionType_Actor = 1<<1, //<Collide sith actors
|
CollisionType_Actor = 1<<1, //<Collide sith actors
|
||||||
CollisionType_HeightMap = 1<<2, //<collide with heightmap
|
CollisionType_HeightMap = 1<<2, //<collide with heightmap
|
||||||
CollisionType_Raycasting = 1<<3 //Still used?
|
CollisionType_Raycasting = 1<<3,
|
||||||
|
CollisionType_Projectile = 1<<4,
|
||||||
|
CollisionType_Water = 1<<5
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,9 +132,20 @@ namespace Physic
|
||||||
return mBody;
|
return mBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Sets whether this actor should be able to collide with the water surface
|
||||||
|
void setCanWaterWalk(bool waterWalk);
|
||||||
|
|
||||||
|
/// Sets whether this actor has been walking on the water surface in the last frame
|
||||||
|
void setWalkingOnWater(bool walkingOnWater);
|
||||||
|
bool isWalkingOnWater() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void disableCollisionBody();
|
/// Removes then re-adds the collision body to the dynamics world
|
||||||
void enableCollisionBody();
|
void updateCollisionMask();
|
||||||
|
|
||||||
|
bool mCanWaterWalk;
|
||||||
|
bool mWalkingOnWater;
|
||||||
|
|
||||||
boost::shared_ptr<btCollisionShape> mShape;
|
boost::shared_ptr<btCollisionShape> mShape;
|
||||||
|
|
||||||
|
@ -288,7 +301,7 @@ namespace Physic
|
||||||
/**
|
/**
|
||||||
* Return all objects hit by a ray.
|
* Return all objects hit by a ray.
|
||||||
*/
|
*/
|
||||||
std::vector< std::pair<float, std::string> > rayTest2(const btVector3 &from, const btVector3 &to);
|
std::vector< std::pair<float, std::string> > rayTest2(const btVector3 &from, const btVector3 &to, int filterGroup=0xff);
|
||||||
|
|
||||||
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
|
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
|
||||||
///< @return (hit, relative distance)
|
///< @return (hit, relative distance)
|
||||||
|
|
Loading…
Reference in a new issue