mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 17:49:41 +00:00
Merge pull request #107 from OpenMW/master
Add OpenMW commits up to 20 Nov, part 2
This commit is contained in:
commit
f9ca98498d
7 changed files with 35 additions and 26 deletions
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class Spell;
|
struct Spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
|
|
@ -226,7 +226,7 @@ namespace MWMechanics
|
||||||
return 1 - resistance / 100.f;
|
return 1 - resistance / 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the given affect can be applied to the target. If \a castByPlayer, emits a message box on failure.
|
/// Check if the given effect can be applied to the target. If \a castByPlayer, emits a message box on failure.
|
||||||
bool checkEffectTarget (int effectId, const MWWorld::Ptr& target, const MWWorld::Ptr& caster, bool castByPlayer)
|
bool checkEffectTarget (int effectId, const MWWorld::Ptr& target, const MWWorld::Ptr& caster, bool castByPlayer)
|
||||||
{
|
{
|
||||||
switch (effectId)
|
switch (effectId)
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace MWMechanics
|
||||||
float getEffectMultiplier(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster,
|
float getEffectMultiplier(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster,
|
||||||
const ESM::Spell* spell = NULL, const MagicEffects* effects = NULL);
|
const ESM::Spell* spell = NULL, const MagicEffects* effects = NULL);
|
||||||
|
|
||||||
|
bool checkEffectTarget (int effectId, const MWWorld::Ptr& target, const MWWorld::Ptr& caster, bool castByPlayer);
|
||||||
|
|
||||||
int getEffectiveEnchantmentCastCost (float castCost, const MWWorld::Ptr& actor);
|
int getEffectiveEnchantmentCastCost (float castCost, const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
void effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const MWMechanics::EffectKey& effectKey, float magnitude);
|
void effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const MWMechanics::EffectKey& effectKey, float magnitude);
|
||||||
|
|
|
@ -985,6 +985,18 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr &actor, const float waterlevel)
|
||||||
|
{
|
||||||
|
const Actor* physicActor = getActor(actor);
|
||||||
|
const float halfZ = physicActor->getHalfExtents().z();
|
||||||
|
const osg::Vec3f actorPosition = physicActor->getPosition();
|
||||||
|
const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ);
|
||||||
|
const osg::Vec3f destinationPosition(actorPosition.x(), actorPosition.y(), waterlevel + halfZ);
|
||||||
|
ActorTracer tracer;
|
||||||
|
tracer.doTrace(physicActor->getCollisionObject(), startingPosition, destinationPosition, mCollisionWorld);
|
||||||
|
return (tracer.mFraction >= 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::ConstPtr &actor) const
|
osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::ConstPtr &actor) const
|
||||||
{
|
{
|
||||||
const Actor* physactor = getActor(actor);
|
const Actor* physactor = getActor(actor);
|
||||||
|
@ -1326,25 +1338,10 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
if (!world->isUnderwater(iter->first.getCell(), osg::Vec3f(iter->first.getRefData().getPosition().asVec3())))
|
if (!world->isUnderwater(iter->first.getCell(), osg::Vec3f(iter->first.getRefData().getPosition().asVec3())))
|
||||||
waterCollision = true;
|
waterCollision = true;
|
||||||
else if (physicActor->getCollisionMode())
|
else if (physicActor->getCollisionMode() && canMoveToWaterSurface(iter->first, waterlevel))
|
||||||
{
|
{
|
||||||
const float halfZ = physicActor->getHalfExtents().z();
|
|
||||||
const osg::Vec3f actorPosition = physicActor->getPosition();
|
const osg::Vec3f actorPosition = physicActor->getPosition();
|
||||||
const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ);
|
physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel));
|
||||||
const osg::Vec3f destinationPosition(actorPosition.x(), actorPosition.y(), waterlevel + halfZ);
|
|
||||||
ActorTracer tracer;
|
|
||||||
tracer.doTrace(physicActor->getCollisionObject(), startingPosition, destinationPosition, mCollisionWorld);
|
|
||||||
if (tracer.mFraction >= 1.0f)
|
|
||||||
{
|
|
||||||
waterCollision = true;
|
|
||||||
physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Remove the effect to remove the performance hit of casting in a weird spot
|
|
||||||
//probably makes that Tribunal quest where the water rises a bit safer
|
|
||||||
iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().purgeEffect(ESM::MagicEffect::WaterWalking);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physicActor->setCanWaterWalk(waterCollision);
|
physicActor->setCanWaterWalk(waterCollision);
|
||||||
|
|
|
@ -123,6 +123,8 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool isOnGround (const MWWorld::Ptr& actor);
|
bool isOnGround (const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
bool canMoveToWaterSurface (const MWWorld::ConstPtr &actor, const float waterlevel);
|
||||||
|
|
||||||
/// Get physical half extents (scaled) of the given actor.
|
/// Get physical half extents (scaled) of the given actor.
|
||||||
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor) const;
|
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor) const;
|
||||||
|
|
||||||
|
|
|
@ -521,8 +521,8 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor)
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
||||||
effectIt->mEffectID);
|
effectIt->mEffectID);
|
||||||
|
|
||||||
// Fully resisted?
|
// Fully resisted or can't be applied to target?
|
||||||
if (params[i].mMultiplier == 0)
|
if (params[i].mMultiplier == 0 || !MWMechanics::checkEffectTarget(effectIt->mEffectID, actor, actor, actor == MWMechanics::getPlayer()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params[i].mRandom;
|
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params[i].mRandom;
|
||||||
|
@ -776,6 +776,9 @@ void MWWorld::InventoryStore::visitEffectSources(MWMechanics::EffectSourceVisito
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin());
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin());
|
||||||
effectIt!=enchantment.mEffects.mList.end(); ++effectIt)
|
effectIt!=enchantment.mEffects.mList.end(); ++effectIt)
|
||||||
{
|
{
|
||||||
|
// Don't get spell icon display information for enchantments that weren't actually applied
|
||||||
|
if (mMagicEffects.get(MWMechanics::EffectKey(*effectIt)).getMagnitude() == 0)
|
||||||
|
continue;
|
||||||
const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().getRefId()][i];
|
const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().getRefId()][i];
|
||||||
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom;
|
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom;
|
||||||
magnitude *= params.mMultiplier;
|
magnitude *= params.mMultiplier;
|
||||||
|
|
|
@ -2108,11 +2108,16 @@ namespace MWWorld
|
||||||
if (!cell->getCell()->hasWater())
|
if (!cell->getCell()->hasWater())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Based on observations from the original engine, the depth
|
float waterlevel = cell->getWaterLevel();
|
||||||
// limit at which water walking can still be cast on a target
|
|
||||||
// in water appears to be the same as what the highest swimmable
|
// SwimHeightScale affects the upper z position an actor can swim to
|
||||||
// z position would be with SwimHeightScale + 1.
|
// while in water. Based on observation from the original engine,
|
||||||
return !isUnderwater(target, mSwimHeightScale + 1);
|
// the upper z position you get with a +1 SwimHeightScale is the depth
|
||||||
|
// limit for being able to cast water walking on an underwater target.
|
||||||
|
if (isUnderwater(target, mSwimHeightScale + 1) || (isUnderwater(cell, target.getRefData().getPosition().asVec3()) && !mPhysics->canMoveToWaterSurface(target, waterlevel)))
|
||||||
|
return false; // not castable if too deep or if not enough room to move actor to surface
|
||||||
|
else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
||||||
|
|
Loading…
Reference in a new issue