mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-24 02:39:42 +00:00
Draft how to move temporary package state to CharacterController.
Example for a few values shown in AiWander.
This commit is contained in:
parent
9ab8d0a8e6
commit
0871d45790
22 changed files with 184 additions and 29 deletions
|
@ -25,6 +25,7 @@
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
|
#include "character.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
@ -1153,7 +1154,7 @@ namespace MWMechanics
|
||||||
updateCrimePersuit(iter->first, duration);
|
updateCrimePersuit(iter->first, duration);
|
||||||
|
|
||||||
if (iter->first != player)
|
if (iter->first != player)
|
||||||
iter->first.getClass().getCreatureStats(iter->first).getAiSequence().execute(iter->first, duration);
|
iter->first.getClass().getCreatureStats(iter->first).getAiSequence().execute(iter->first,iter->second->getAiState(), duration);
|
||||||
|
|
||||||
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
||||||
if(!stats.isDead())
|
if(!stats.isDead())
|
||||||
|
|
|
@ -21,7 +21,7 @@ MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||||
{
|
{
|
||||||
return new AiActivate(*this);
|
return new AiActivate(*this);
|
||||||
}
|
}
|
||||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
||||||
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow
|
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace MWMechanics
|
||||||
AiActivate(const ESM::AiSequence::AiActivate* activate);
|
AiActivate(const ESM::AiSequence::AiActivate* activate);
|
||||||
|
|
||||||
virtual AiActivate *clone() const;
|
virtual AiActivate *clone() const;
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
virtual void writeState(ESM::AiSequence::AiSequence& sequence) const;
|
virtual void writeState(ESM::AiSequence::AiSequence& sequence) const;
|
||||||
|
|
|
@ -18,7 +18,7 @@ MWMechanics::AiAvoidDoor::AiAvoidDoor(const MWWorld::Ptr& doorPtr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
|
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiAvoidDoor *clone() const;
|
virtual AiAvoidDoor *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace MWMechanics
|
||||||
* Use the Observer Pattern to co-ordinate attacks, provide intelligence on
|
* Use the Observer Pattern to co-ordinate attacks, provide intelligence on
|
||||||
* whether the target was hit, etc.
|
* whether the target was hit, etc.
|
||||||
*/
|
*/
|
||||||
bool AiCombat::execute (const MWWorld::Ptr& actor,float duration)
|
bool AiCombat::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
//General description
|
//General description
|
||||||
if(actor.getClass().getCreatureStats(actor).isDead())
|
if(actor.getClass().getCreatureStats(actor).isDead())
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiCombat *clone() const;
|
virtual AiCombat *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace MWMechanics
|
||||||
return new AiEscort(*this);
|
return new AiEscort(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AiEscort::execute (const MWWorld::Ptr& actor,float duration)
|
bool AiEscort::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
// If AiEscort has ran for as long or longer then the duration specified
|
// If AiEscort has ran for as long or longer then the duration specified
|
||||||
// and the duration is not infinite, the package is complete.
|
// and the duration is not infinite, the package is complete.
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiEscort *clone() const;
|
virtual AiEscort *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr target = getTarget();
|
MWWorld::Ptr target = getTarget();
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiFollow *clone() const;
|
virtual AiFollow *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "obstacle.hpp"
|
#include "obstacle.hpp"
|
||||||
|
#include "aistate.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -20,8 +21,10 @@ namespace ESM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
/// \brief Base class for AI packages
|
/// \brief Base class for AI packages
|
||||||
class AiPackage
|
class AiPackage
|
||||||
{
|
{
|
||||||
|
@ -50,7 +53,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
/// Updates and runs the package (Should run every frame)
|
/// Updates and runs the package (Should run every frame)
|
||||||
/// \return Package completed?
|
/// \return Package completed?
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration) = 0;
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration) = 0;
|
||||||
|
|
||||||
/// Returns the TypeID of the AiPackage
|
/// Returns the TypeID of the AiPackage
|
||||||
/// \see enum TypeId
|
/// \see enum TypeId
|
||||||
|
|
|
@ -30,7 +30,7 @@ AiPursue *MWMechanics::AiPursue::clone() const
|
||||||
{
|
{
|
||||||
return new AiPursue(*this);
|
return new AiPursue(*this);
|
||||||
}
|
}
|
||||||
bool AiPursue::execute (const MWWorld::Ptr& actor, float duration)
|
bool AiPursue::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
if(actor.getClass().getCreatureStats(actor).isDead())
|
if(actor.getClass().getCreatureStats(actor).isDead())
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace MWMechanics
|
||||||
AiPursue(const ESM::AiSequence::AiPursue* pursue);
|
AiPursue(const ESM::AiSequence::AiPursue* pursue);
|
||||||
|
|
||||||
virtual AiPursue *clone() const;
|
virtual AiPursue *clone() const;
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
MWWorld::Ptr getTarget() const;
|
MWWorld::Ptr getTarget() const;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "aisequence.hpp"
|
#include "aisequence.hpp"
|
||||||
|
|
||||||
#include "aipackage.hpp"
|
#include "aipackage.hpp"
|
||||||
|
#include "aistate.hpp"
|
||||||
|
|
||||||
#include "aiwander.hpp"
|
#include "aiwander.hpp"
|
||||||
#include "aiescort.hpp"
|
#include "aiescort.hpp"
|
||||||
|
@ -146,7 +147,7 @@ bool AiSequence::isPackageDone() const
|
||||||
return mDone;
|
return mDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiSequence::execute (const MWWorld::Ptr& actor,float duration)
|
void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float duration)
|
||||||
{
|
{
|
||||||
if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr()
|
if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr()
|
||||||
&& !actor.getClass().getCreatureStats(actor).getKnockedDown())
|
&& !actor.getClass().getCreatureStats(actor).getKnockedDown())
|
||||||
|
@ -208,7 +209,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor,float duration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package->execute (actor,duration))
|
if (package->execute (actor,state,duration))
|
||||||
{
|
{
|
||||||
// To account for the rare case where AiPackage::execute() queued another AI package
|
// To account for the rare case where AiPackage::execute() queued another AI package
|
||||||
// (e.g. AiPursue executing a dialogue script that uses startCombat)
|
// (e.g. AiPursue executing a dialogue script that uses startCombat)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
|
//#include "aistate.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -18,10 +19,16 @@ namespace ESM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< class Base > class DerivedClassStorage;
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
class AiPackage;
|
class AiPackage;
|
||||||
|
|
||||||
|
|
||||||
|
class AiTemporaryBase;
|
||||||
|
typedef DerivedClassStorage<AiTemporaryBase> AiState;
|
||||||
|
|
||||||
/// \brief Sequence of AI-packages for a single actor
|
/// \brief Sequence of AI-packages for a single actor
|
||||||
/** The top-most AI package is run each frame. When completed, it is removed from the stack. **/
|
/** The top-most AI package is run each frame. When completed, it is removed from the stack. **/
|
||||||
class AiSequence
|
class AiSequence
|
||||||
|
@ -88,7 +95,7 @@ namespace MWMechanics
|
||||||
void stopPursuit();
|
void stopPursuit();
|
||||||
|
|
||||||
/// Execute current package, switching if needed.
|
/// Execute current package, switching if needed.
|
||||||
void execute (const MWWorld::Ptr& actor,float duration);
|
void execute (const MWWorld::Ptr& actor, MWMechanics::AiState& state, float duration);
|
||||||
|
|
||||||
/// Remove all packages.
|
/// Remove all packages.
|
||||||
void clear();
|
void clear();
|
||||||
|
|
120
apps/openmw/mwmechanics/aistate.hpp
Normal file
120
apps/openmw/mwmechanics/aistate.hpp
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
#ifndef AISTATE_H
|
||||||
|
#define AISTATE_H
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
// c++11 replacement
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief stores an object of any class derived from Base
|
||||||
|
template< class Base >
|
||||||
|
class DerivedClassStorage
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Base* mStorage;
|
||||||
|
|
||||||
|
// assert that Derived is derived from Base.
|
||||||
|
template< class Derived >
|
||||||
|
void assert_derived()
|
||||||
|
{
|
||||||
|
// c++11:
|
||||||
|
// static_assert( std::is_base_of<Base,Derived> , "DerivedClassStorage may only store derived classes" );
|
||||||
|
|
||||||
|
// boost:
|
||||||
|
BOOST_STATIC_ASSERT(boost::is_base_of<Base,Derived>::value);//,"DerivedClassStorage may only store derived classes");
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedClassStorage( const DerivedClassStorage& );
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief returns reference to stored object or deletes it and creates a fitting
|
||||||
|
template< class Derived >
|
||||||
|
Derived& get()
|
||||||
|
{
|
||||||
|
assert_derived<Derived>();
|
||||||
|
|
||||||
|
Derived* result = dynamic_cast<Derived*>(mStorage);
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
if(mStorage)
|
||||||
|
delete mStorage;
|
||||||
|
mStorage = result = new Derived();
|
||||||
|
}
|
||||||
|
|
||||||
|
//return a reference to the (new allocated) object
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Derived >
|
||||||
|
void store( const Derived& payload )
|
||||||
|
{
|
||||||
|
assert_derived<Derived>();
|
||||||
|
if(mStorage)
|
||||||
|
delete mStorage;
|
||||||
|
mStorage = new Derived(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief takes ownership of the passed object
|
||||||
|
template< class Derived >
|
||||||
|
void moveIn( Derived* p )
|
||||||
|
{
|
||||||
|
assert_derived<Derived>();
|
||||||
|
if(mStorage)
|
||||||
|
delete mStorage;
|
||||||
|
mStorage = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief gives away ownership of object. Throws exception if storage does not contain Derived or is empty.
|
||||||
|
template< class Derived >
|
||||||
|
Derived* moveOut()
|
||||||
|
{
|
||||||
|
assert_derived<Derived>();
|
||||||
|
|
||||||
|
|
||||||
|
if(!mStorage)
|
||||||
|
throw std::runtime_error("Cant move out: empty storage.");
|
||||||
|
|
||||||
|
Derived* result = dynamic_cast<Derived*>(mStorage);
|
||||||
|
|
||||||
|
if(!mStorage)
|
||||||
|
throw std::runtime_error("Cant move out: wrong type requested.");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return mStorage == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& getType() const
|
||||||
|
{
|
||||||
|
return typeid(mStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DerivedClassStorage():mStorage(NULL){};
|
||||||
|
~DerivedClassStorage()
|
||||||
|
{
|
||||||
|
if(mStorage)
|
||||||
|
delete mStorage;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
/// \brief base class for the temporary storage of AiPackages
|
||||||
|
struct AiTemporaryBase
|
||||||
|
{
|
||||||
|
virtual ~AiTemporaryBase(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Container for AI package status
|
||||||
|
typedef DerivedClassStorage<AiTemporaryBase> AiState;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // AISTATE_H
|
|
@ -37,7 +37,7 @@ namespace MWMechanics
|
||||||
return new AiTravel(*this);
|
return new AiTravel(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AiTravel::execute (const MWWorld::Ptr& actor,float duration)
|
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiTravel *clone() const;
|
virtual AiTravel *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "steering.hpp"
|
#include "steering.hpp"
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
static const int COUNT_BEFORE_RESET = 200; // TODO: maybe no longer needed
|
static const int COUNT_BEFORE_RESET = 200; // TODO: maybe no longer needed
|
||||||
|
@ -45,9 +47,9 @@ namespace MWMechanics
|
||||||
mStuckCount = 0;// TODO: maybe no longer needed
|
mStuckCount = 0;// TODO: maybe no longer needed
|
||||||
mDoorCheckDuration = 0;
|
mDoorCheckDuration = 0;
|
||||||
mTrimCurrentNode = false;
|
mTrimCurrentNode = false;
|
||||||
mReaction = 0;
|
// mReaction = 0;
|
||||||
mRotate = false;
|
// mRotate = false;
|
||||||
mTargetAngle = 0;
|
// mTargetAngle = 0;
|
||||||
mSaidGreeting = Greet_None;
|
mSaidGreeting = Greet_None;
|
||||||
mGreetingTimer = 0;
|
mGreetingTimer = 0;
|
||||||
mHasReturnPosition = false;
|
mHasReturnPosition = false;
|
||||||
|
@ -125,8 +127,13 @@ namespace MWMechanics
|
||||||
* actors will enter combat (i.e. no longer wandering) and different pathfinding
|
* actors will enter combat (i.e. no longer wandering) and different pathfinding
|
||||||
* will kick in.
|
* will kick in.
|
||||||
*/
|
*/
|
||||||
bool AiWander::execute (const MWWorld::Ptr& actor,float duration)
|
bool AiWander::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
|
AiWanderStorage& storage = state.get<AiWanderStorage>();
|
||||||
|
float& mTargetAngle = storage.mTargetAngle;
|
||||||
|
bool& mRotate = storage.mRotate;
|
||||||
|
float& mReaction = storage.mReaction;
|
||||||
|
|
||||||
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
||||||
if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
||||||
return true; // Don't bother with dead actors
|
return true; // Don't bother with dead actors
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#include "../mwworld/timestamp.hpp"
|
#include "../mwworld/timestamp.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "aistate.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
namespace AiSequence
|
namespace AiSequence
|
||||||
|
@ -22,6 +25,17 @@ namespace ESM
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
/// \brief Temporary values used by AiWander
|
||||||
|
struct AiWanderStorage : AiTemporaryBase
|
||||||
|
{
|
||||||
|
// the z rotation angle (degrees) we want to reach
|
||||||
|
// used every frame when mRotate is true
|
||||||
|
float mTargetAngle;
|
||||||
|
bool mRotate;
|
||||||
|
float mReaction; // update some actions infrequently
|
||||||
|
AiWanderStorage():mTargetAngle(0),mRotate(false),mReaction(0){};
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief Causes the Actor to wander within a specified range
|
/// \brief Causes the Actor to wander within a specified range
|
||||||
class AiWander : public AiPackage
|
class AiWander : public AiPackage
|
||||||
{
|
{
|
||||||
|
@ -41,7 +55,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual AiPackage *clone() const;
|
virtual AiPackage *clone() const;
|
||||||
|
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor, AiState& state, float duration);
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
@ -109,11 +123,7 @@ namespace MWMechanics
|
||||||
float mDoorCheckDuration;
|
float mDoorCheckDuration;
|
||||||
int mStuckCount;
|
int mStuckCount;
|
||||||
|
|
||||||
// the z rotation angle (degrees) we want to reach
|
|
||||||
// used every frame when mRotate is true
|
|
||||||
float mTargetAngle;
|
|
||||||
bool mRotate;
|
|
||||||
float mReaction; // update some actions infrequently
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <components/esm/loadmgef.hpp>
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
#include "aistate.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -139,6 +140,9 @@ class CharacterController
|
||||||
MWWorld::Ptr mPtr;
|
MWWorld::Ptr mPtr;
|
||||||
MWRender::Animation *mAnimation;
|
MWRender::Animation *mAnimation;
|
||||||
|
|
||||||
|
//
|
||||||
|
AiState mAiState;
|
||||||
|
|
||||||
typedef std::deque<std::pair<std::string,size_t> > AnimationQueue;
|
typedef std::deque<std::pair<std::string,size_t> > AnimationQueue;
|
||||||
AnimationQueue mAnimQueue;
|
AnimationQueue mAnimQueue;
|
||||||
|
|
||||||
|
@ -218,6 +222,8 @@ public:
|
||||||
{ return mDeathState != CharState_None; }
|
{ return mDeathState != CharState_None; }
|
||||||
|
|
||||||
void forceStateUpdate();
|
void forceStateUpdate();
|
||||||
|
|
||||||
|
AiState& getAiState() { return mAiState; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void getWeaponGroup(WeaponType weaptype, std::string &group);
|
void getWeaponGroup(WeaponType weaptype, std::string &group);
|
||||||
|
|
Loading…
Reference in a new issue