diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 66d9d5090..a64ab1ed4 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -61,7 +61,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells - activespells npcstats + activespells npcstats aipackage aisequence ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp new file mode 100644 index 000000000..8193a670b --- /dev/null +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -0,0 +1,4 @@ + +#include "aipackage.hpp" + +MWMechanics::AiPackage::~AiPackage() {} diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp new file mode 100644 index 000000000..d286fbba8 --- /dev/null +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -0,0 +1,29 @@ +#ifndef GAME_MWMECHANICS_AIPACKAGE_H +#define GAME_MWMECHANICS_AIPACKAGE_H + +namespace MWWorld +{ + class Ptr; +} + +namespace MWMechanics +{ + /// \brief Base class for AI packages + class AiPackage + { + public: + + virtual ~AiPackage(); + + virtual AiPackage *clone() const = 0; + + virtual bool execute (const MWWorld::Ptr& actor) = 0; + ///< \return Package completed? + + virtual int getTypeId() const = 0; + ///< 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate + }; +} + +#endif + diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp new file mode 100644 index 000000000..c4dcf89af --- /dev/null +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -0,0 +1,79 @@ + +#include "aisequence.hpp" + +#include "aipackage.hpp" + +void MWMechanics::AiSequence::copy (const AiSequence& sequence) +{ + for (std::list::const_iterator iter (sequence.mPackages.begin()); + iter!=sequence.mPackages.end(); ++iter) + mPackages.push_back ((*iter)->clone()); +} + +MWMechanics::AiSequence::AiSequence() : mDone (false) {} + +MWMechanics::AiSequence::AiSequence (const AiSequence& sequence) : mDone (false) +{ + copy (sequence); +} + +MWMechanics::AiSequence& MWMechanics::AiSequence::operator= (const AiSequence& sequence) +{ + if (this!=&sequence) + { + clear(); + copy (sequence); + } + + return *this; +} + +MWMechanics::AiSequence::~AiSequence() +{ + clear(); +} + +int MWMechanics::AiSequence::getTypeId() const +{ + if (mPackages.empty()) + return -1; + + return mPackages.front()->getTypeId(); +} + +bool MWMechanics::AiSequence::isPackageDone() const +{ + return mDone; +} + +void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor) +{ + if (!mPackages.empty()) + { + if (mPackages.front()->execute (actor)) + { + mPackages.erase (mPackages.begin()); + mDone = true; + } + else + mDone = false; + } +} + +void MWMechanics::AiSequence::clear() +{ + for (std::list::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter) + delete *iter; + + mPackages.clear(); +} + +void MWMechanics::AiSequence::stack (const AiPackage& package) +{ + mPackages.push_front (package.clone()); +} + +void MWMechanics::AiSequence::queue (const AiPackage& package) +{ + mPackages.push_back (package.clone()); +} diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp new file mode 100644 index 000000000..b9ec9d615 --- /dev/null +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -0,0 +1,54 @@ +#ifndef GAME_MWMECHANICS_AISEQUENCE_H +#define GAME_MWMECHANICS_AISEQUENCE_H + +#include + +namespace MWWorld +{ + class Ptr; +} + +namespace MWMechanics +{ + class AiPackage; + + /// \brief Sequence of AI-packages for a single actor + class AiSequence + { + std::list mPackages; + bool mDone; + + void copy (const AiSequence& sequence); + + public: + + AiSequence(); + + AiSequence (const AiSequence& sequence); + + AiSequence& operator= (const AiSequence& sequence); + + virtual ~AiSequence(); + + int getTypeId() const; + ///< -1: None, 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate + + bool isPackageDone() const; + ///< Has a package been completed during the last update? + + void execute (const MWWorld::Ptr& actor); + ///< Execute package. + + void clear(); + ///< Remove all packages. + + void stack (const AiPackage& package); + ///< Add \a package to the front of the sequence (suspends current package) + + void queue (const AiPackage& package); + ///< Add \a package to the end of the sequence (executed after all other packages have been + /// completed) + }; +} + +#endif