diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index b4476de11..6593bbf89 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -473,14 +473,9 @@ namespace MWMechanics { Ogre::Vector3 dir = playerPos - actorPos; - Ogre::Radian faceAngle = Ogre::Math::ATan2(dir.x,dir.y); - Ogre::Radian actorAngle = actor.getRefData().getBaseNodeOld()->getOrientation().getRoll(); - // an attempt at reducing the turning animation glitch - if( Ogre::Math::Abs( faceAngle - actorAngle ) >= Ogre::Degree(5) ) // TODO: is there a better way? - { - targetAngle = faceAngle; - rotate = true; - } + float faceAngleRadians = std::atan2(dir.x, dir.y); + targetAngle = faceAngleRadians; + rotate = true; } if (greetingTimer >= GREETING_SHOULD_END) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 9feb831c9..a8a6f74aa 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -816,26 +816,12 @@ void CharacterController::handleTextKey(const std::string &groupname, const std: else if (evt.compare(off, len, "shoot follow attach") == 0) mAnimation->attachArrow(); - else if (groupname == "spellcast" && evt.substr(evt.size()-7, 7) == "release") + else if (groupname == "spellcast" && evt.substr(evt.size()-7, 7) == "release" + // Make sure this key is actually for the RangeType we are casting. The flame atronach has + // the same animation for all range types, so there are 3 "release" keys on the same time, one for each range type. + && evt.compare(off, len, mAttackType + " release") == 0) { - // Make sure this key is actually for the RangeType we are casting. The flame atronach has - // the same animation for all range types, so there are 3 "release" keys on the same time, one for each range type. - // FIXME: compare with mCurrentWeapon instead - const std::string& spellid = mPtr.getClass().getCreatureStats(mPtr).getSpells().getSelectedSpell(); - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellid); - const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); - int range = 0; - if (evt.compare(off, len, "self release") == 0) - range = 0; - else if (evt.compare(off, len, "touch release") == 0) - range = 1; - else if (evt.compare(off, len, "target release") == 0) - range = 2; - if (effectentry.mRange == range) - { - MWBase::Environment::get().getWorld()->castSpell(mPtr); - } - std::cout << "current attack: " << mCurrentWeapon << std::endl; + MWBase::Environment::get().getWorld()->castSpell(mPtr); } else if (groupname == "shield" && evt.compare(off, len, "block hit") == 0) diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 97dea7341..ee48d124f 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -1,6 +1,6 @@ #include "combat.hpp" -#include +#include #include @@ -23,12 +23,9 @@ namespace { -Ogre::Radian signedAngle(Ogre::Vector3 v1, Ogre::Vector3 v2, Ogre::Vector3 normal) +float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg::Vec3f& normal) { - return Ogre::Math::ATan2( - normal.dotProduct( v1.crossProduct(v2) ), - v1.dotProduct(v2) - ); + return std::atan2((normal * (v1 ^ v2)), (v1 * v2)); } bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const Ogre::Vector3& hitPosition) @@ -74,13 +71,19 @@ namespace MWMechanics if (shield == inv.end() || shield->getTypeName() != typeid(ESM::Armor).name()) return false; - Ogre::Degree angle = signedAngle (Ogre::Vector3(attacker.getRefData().getPosition().pos) - Ogre::Vector3(blocker.getRefData().getPosition().pos), - blocker.getRefData().getBaseNodeOld()->getOrientation().yAxis(), Ogre::Vector3(0,0,1)); + if (!blocker.getRefData().getBaseNode()) + return false; // shouldn't happen + + float angleDegrees = osg::RadiansToDegrees( + signedAngleRadians ( + (attacker.getRefData().getPosition().asVec3() - blocker.getRefData().getPosition().asVec3()), + blocker.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0), + osg::Vec3f(0,0,1))); const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - if (angle.valueDegrees() < gmst.find("fCombatBlockLeftAngle")->getFloat()) + if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->getFloat()) return false; - if (angle.valueDegrees() > gmst.find("fCombatBlockRightAngle")->getFloat()) + if (angleDegrees > gmst.find("fCombatBlockRightAngle")->getFloat()) return false; MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 72a68e96b..0ae9395c5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1,6 +1,8 @@ - #include "mechanicsmanagerimp.hpp" -#include "npcstats.hpp" + +#include + +#include #include @@ -20,12 +22,9 @@ #include "../mwmechanics/aicombat.hpp" #include "../mwmechanics/aipursue.hpp" -#include - #include "spellcasting.hpp" #include "autocalcspell.hpp" - -#include +#include "npcstats.hpp" namespace { @@ -1332,8 +1331,6 @@ namespace MWMechanics bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) { - return false; - if (observer.getClass().getCreatureStats(observer).isDead() || !observer.getRefData().isEnabled()) return false; @@ -1369,9 +1366,9 @@ namespace MWMechanics static float fSneakDistBase = store.find("fSneakDistanceBase")->getFloat(); static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->getFloat(); - Ogre::Vector3 pos1 (ptr.getRefData().getPosition().pos); - Ogre::Vector3 pos2 (observer.getRefData().getPosition().pos); - float distTerm = fSneakDistBase + fSneakDistMult * pos1.distance(pos2); + osg::Vec3f pos1 (ptr.getRefData().getPosition().asVec3()); + osg::Vec3f pos2 (observer.getRefData().getPosition().asVec3()); + float distTerm = fSneakDistBase + fSneakDistMult * (pos1 - pos2).length(); float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon + invisibility; @@ -1388,12 +1385,15 @@ namespace MWMechanics static float fSneakNoViewMult = store.find("fSneakNoViewMult")->getFloat(); static float fSneakViewMult = store.find("fSneakViewMult")->getFloat(); float y = 0; - Ogre::Vector3 vec = pos1 - pos2; - Ogre::Radian angle = observer.getRefData().getBaseNodeOld()->getOrientation().yAxis().angleBetween(vec); - if (angle < Ogre::Degree(90)) - y = obsTerm * observerStats.getFatigueTerm() * fSneakNoViewMult; - else - y = obsTerm * observerStats.getFatigueTerm() * fSneakViewMult; + osg::Vec3f vec = pos1 - pos2; + if (observer.getRefData().getBaseNode()) + { + float angleRadians = std::acos((observer.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0)) * vec); + if (angleRadians < osg::DegreesToRadians(90.f)) + y = obsTerm * observerStats.getFatigueTerm() * fSneakNoViewMult; + else + y = obsTerm * observerStats.getFatigueTerm() * fSneakViewMult; + } float target = x - y; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index ff3d2fceb..8965d3b0d 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -19,7 +19,7 @@ #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" -//#include "../mwrender/animation.hpp" +#include "../mwrender/animation.hpp" #include "magiceffects.hpp" #include "npcstats.hpp" @@ -418,9 +418,9 @@ namespace MWMechanics absorbed = (Misc::Rng::roll0to99() < absorb); if (absorbed) { - //const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_Absorb"); - //MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect( - // "meshes\\" + absorbStatic->mModel, ESM::MagicEffect::SpellAbsorption, false, ""); + const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_Absorb"); + MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect( + "meshes\\" + absorbStatic->mModel, ESM::MagicEffect::SpellAbsorption, false, ""); // Magicka is increased by cost of spell DynamicStat magicka = target.getClass().getCreatureStats(target).getMagicka(); magicka.setCurrent(magicka.getCurrent() + spell->mData.mCost); @@ -466,9 +466,9 @@ namespace MWMechanics bool isReflected = (Misc::Rng::roll0to99() < reflect); if (isReflected) { - //const ESM::Static* reflectStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_Reflect"); - //MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect( - // "meshes\\" + reflectStatic->mModel, ESM::MagicEffect::Reflect, false, ""); + const ESM::Static* reflectStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_Reflect"); + MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect( + "meshes\\" + reflectStatic->mModel, ESM::MagicEffect::Reflect, false, ""); reflectedEffects.mList.push_back(*effectIt); magnitudeMult = 0; } @@ -565,7 +565,7 @@ namespace MWMechanics } // Add VFX - /*const ESM::Static* castStatic; + const ESM::Static* castStatic; if (!magicEffect->mHit.empty()) castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect->mHit); else @@ -577,7 +577,6 @@ namespace MWMechanics MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target); if (anim) anim->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, ""); - */ } } } diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index 221c67267..4140fd3c0 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -12,7 +12,7 @@ #include "../mwworld/manualref.hpp" #include "../mwworld/inventorystore.hpp" -//#include "../mwrender/animation.hpp" +#include "../mwrender/animation.hpp" #include "creaturestats.hpp" #include "aifollow.hpp" @@ -143,9 +143,8 @@ namespace MWMechanics summonedCreatureStats.getAiSequence().stack(package, ref.getPtr()); int creatureActorId = summonedCreatureStats.getActorId(); - /*MWWorld::Ptr placed = */MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos); + MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos); - /* MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(placed); if (anim) { @@ -154,7 +153,6 @@ namespace MWMechanics if (fx) anim->addEffect("meshes\\" + fx->mModel, -1, false); } - */ creatureMap.insert(std::make_pair(*it, creatureActorId)); } diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index b8ebf99d0..54860fc31 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -37,7 +37,7 @@ namespace MWWorld } RefData::RefData() - : mBaseNode(0), mBase(0), mDeleted(false), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false) + : mBaseNode(0), mDeleted(false), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false) { for (int i=0; i<3; ++i) { @@ -48,7 +48,7 @@ namespace MWWorld } RefData::RefData (const ESM::CellRef& cellRef) - : mBaseNode(0), mBase(0), mDeleted(false), mHasLocals (false), mEnabled (true), + : mBaseNode(0), mDeleted(false), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), mCustomData (0), mChanged(false) // Loading from ESM/ESP files -> assume unchanged @@ -59,7 +59,7 @@ namespace MWWorld } RefData::RefData (const ESM::ObjectState& objectState) - : mBaseNode (0), mBase(0), mDeleted(false), mHasLocals (false), + : mBaseNode(0), mDeleted(false), mHasLocals (false), mEnabled (objectState.mEnabled != 0), mCount (objectState.mCount), mPosition (objectState.mPosition), @@ -71,7 +71,7 @@ namespace MWWorld } RefData::RefData (const RefData& refData) - : mBaseNode(0), mBase(0), mCustomData (0) + : mBaseNode(0), mCustomData (0) { try { @@ -125,19 +125,14 @@ namespace MWWorld {} } - Ogre::SceneNode* RefData::getBaseNodeOld() - { - return mBaseNode; - } - void RefData::setBaseNode(osg::PositionAttitudeTransform *base) { - mBase = base; + mBaseNode = base; } osg::PositionAttitudeTransform* RefData::getBaseNode() { - return mBase; + return mBaseNode; } int RefData::getCount() const diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index b5b1f1560..61055aa73 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -7,11 +7,6 @@ #include -namespace Ogre -{ - class SceneNode; -} - namespace osg { class PositionAttitudeTransform; @@ -34,8 +29,7 @@ namespace MWWorld class RefData { - Ogre::SceneNode* mBaseNode; - osg::PositionAttitudeTransform* mBase; + osg::PositionAttitudeTransform* mBaseNode; MWScript::Locals mLocals; // if we find the overhead of heaving a locals // object in the refdata of refs without a script, @@ -81,10 +75,6 @@ namespace MWWorld RefData& operator= (const RefData& refData); - /// Return OGRE base node (can be a null pointer). - /// obsolete - Ogre::SceneNode* getBaseNodeOld(); - /// Return base node (can be a null pointer). osg::PositionAttitudeTransform* getBaseNode(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 427a41d64..08617d0d6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2385,7 +2385,7 @@ namespace MWWorld if(result.first == "") return true; */ - return false; + return true; } float World::getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist) diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp index 84fe6e896..0ef1356e7 100644 --- a/components/sceneutil/controller.hpp +++ b/components/sceneutil/controller.hpp @@ -36,6 +36,7 @@ namespace SceneUtil { public: Controller(); + virtual ~Controller() {} bool hasInput() const;