From 9353f4d14f9b96fffe23b92eaa75a974fb061fb6 Mon Sep 17 00:00:00 2001 From: gus Date: Wed, 25 Sep 2013 18:01:36 +0200 Subject: [PATCH] WIP AI combat --- apps/openmw/mwmechanics/aicombat.cpp | 87 ++++++++++++++++++++++++++ apps/openmw/mwmechanics/aicombat.hpp | 39 ++++++++++++ apps/openmw/mwmechanics/aisequence.cpp | 71 +++++++++++++-------- apps/openmw/mwmechanics/aisequence.hpp | 3 + 4 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 apps/openmw/mwmechanics/aicombat.cpp create mode 100644 apps/openmw/mwmechanics/aicombat.hpp diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp new file mode 100644 index 0000000000..071aa50e39 --- /dev/null +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -0,0 +1,87 @@ +#include "aicombat.hpp" + +#include "movement.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" +#include "../mwworld/timestamp.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" + + +namespace MWMechanics +{ + + AiCombat::AiCombat(const std::string &targetId) + :mTargetId(targetId) + { + } + + bool AiCombat::execute (const MWWorld::Ptr& actor) + { + const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();//MWBase::Environment::get().getWorld()->getPtr(mTargetId, false); + + MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState(); + if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) + MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); + MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); + + ESM::Position pos = actor.getRefData().getPosition(); + const ESM::Pathgrid *pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + + int cellX = actor.getCell()->mCell->mData.mX; + int cellY = actor.getCell()->mCell->mData.mY; + float xCell = 0; + float yCell = 0; + + if (actor.getCell()->mCell->isExterior()) + { + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + } + + ESM::Pathgrid::Point dest; + dest.mX = target.getRefData().getPosition().pos[0]; + dest.mY = target.getRefData().getPosition().pos[1]; + dest.mZ = target.getRefData().getPosition().pos[2]; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + std::cout << start.mX << " " << dest.mX << "\n"; + + mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, true); + + if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + } + + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + std::cout << zAngle; + MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + + if(dest.mX - start.mX < 100) + { + //MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(false); + } + + return false; + } + + int AiCombat::getTypeId() const + { + return 2; + } + + AiCombat *MWMechanics::AiCombat::clone() const + { + return new AiCombat(*this); + } +} + diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp new file mode 100644 index 0000000000..3b2ae6fc0b --- /dev/null +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -0,0 +1,39 @@ +#ifndef GAME_MWMECHANICS_AICOMBAT_H +#define GAME_MWMECHANICS_AICOMBAT_H + +#include "aipackage.hpp" + +#include "pathfinding.hpp" + + +#include "..\mwworld\class.hpp" +#include "creaturestats.hpp" +#include "npcstats.hpp" +#include "..\mwbase\environment.hpp" +#include "..\mwbase\world.hpp" +#include "..\mwworld\player.hpp" + +#include "movement.hpp" + +namespace MWMechanics +{ + class AiCombat : public AiPackage + { + public: + AiCombat(const std::string &targetId); + + virtual AiCombat *clone() const; + + virtual bool execute (const MWWorld::Ptr& actor); + ///< \return Package completed? + + virtual int getTypeId() const; + + private: + std::string mTargetId; + + PathFinder mPathFinder; + }; +} + +#endif \ No newline at end of file diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index 79ecf1586c..d02f03e18d 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -8,6 +8,7 @@ #include "aitravel.hpp" #include "aifollow.hpp" #include "aiactivate.hpp" +#include "aicombat.hpp" #include "..\mwworld\class.hpp" #include "creaturestats.hpp" @@ -21,9 +22,11 @@ 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()); + mCombat = sequence.mCombat; + mCombatPackage = sequence.mCombatPackage; } -MWMechanics::AiSequence::AiSequence() : mDone (false) {} +MWMechanics::AiSequence::AiSequence() : mDone (false), mCombat (false), mCombatPackage (0) {} MWMechanics::AiSequence::AiSequence (const AiSequence& sequence) : mDone (false) { @@ -61,16 +64,27 @@ bool MWMechanics::AiSequence::isPackageDone() const void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor) { - /*if(actor != MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) + if(actor != MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) { - MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState(); - if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) - MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); - MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); + if(mCombat) + { + //mCombatPackage->execute(actor); + } + else + { + //mCombat = true; + //mCombatPackage = new AiCombat("player"); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - ESM::Position pos = actor.getRefData().getPosition(); - const ESM::Pathgrid *pathgrid = + /*if(actor != MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) + { + MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState(); + if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) + MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); + MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position pos = actor.getRefData().getPosition(); + const ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); int cellX = actor.getCell()->mCell->mData.mX; @@ -80,8 +94,8 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor) if (actor.getCell()->mCell->isExterior()) { - xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; - yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; } ESM::Pathgrid::Point dest; @@ -96,24 +110,26 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor) PathFinder mPathFinder; mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, true); - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - if(dest.mX - start.mX < 100) - { + if(dest.mX - start.mX < 100) + { MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(false); + } + }*/ + if (!mPackages.empty()) + { + if (mPackages.front()->execute (actor)) + { + mPackages.erase (mPackages.begin()); + mDone = true; + } + else + mDone = false; + } } - }*/ - if (!mPackages.empty()) - { - if (mPackages.front()->execute (actor)) - { - mPackages.erase (mPackages.begin()); - mDone = true; - } - else - mDone = false; } } @@ -121,7 +137,8 @@ void MWMechanics::AiSequence::clear() { for (std::list::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter) delete *iter; - + + if(mCombatPackage) delete mCombatPackage; mPackages.clear(); } diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index 9f70daeb83..37084a1e5b 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -18,6 +18,9 @@ namespace MWMechanics class AiSequence { std::list mPackages; + AiPackage* mCombatPackage; + bool mCombat; + bool mDone; void copy (const AiSequence& sequence);