From 632834ce1094fb5e0b56910797e049455e71cea4 Mon Sep 17 00:00:00 2001 From: gus Date: Wed, 5 Feb 2014 16:12:50 +0100 Subject: [PATCH] WIP --- apps/openmw/mwmechanics/aiactivate.cpp | 103 ++++++++++++++++++++++++- apps/openmw/mwmechanics/aiactivate.hpp | 6 ++ apps/openmw/mwmechanics/aitravel.cpp | 10 +-- apps/openmw/mwmechanics/aitravel.hpp | 4 +- 4 files changed, 113 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index 531ba55686..e751140c08 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -1,8 +1,24 @@ #include "aiactivate.hpp" #include +#include "movement.hpp" + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwworld/class.hpp" + +namespace +{ + float sgn(float a) + { + if(a > 0) + return 1.0; + return -1.0; + } +} + MWMechanics::AiActivate::AiActivate(const std::string &objectId) -: mObjectId(objectId) + : mObjectId(objectId) { } MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const @@ -11,8 +27,89 @@ MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const } bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) { - std::cout << "AiActivate completed.\n"; - return true; + MWBase::World *world = MWBase::Environment::get().getWorld(); + ESM::Position pos = actor.getRefData().getPosition(); + Movement &movement = actor.getClass().getMovementSettings(actor); + const ESM::Cell *cell = actor.getCell()->mCell; + + MWWorld::Ptr player = world->getPlayerPtr(); + if(cell->mData.mX != player.getCell()->mCell->mData.mX) + { + int sideX = sgn(cell->mData.mX - player.getCell()->mCell->mData.mX); + //check if actor is near the border of an inactive cell. If so, stop walking. + if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > + sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) + { + movement.mPosition[1] = 0; + return false; + } + } + if(cell->mData.mY != player.getCell()->mCell->mData.mY) + { + int sideY = sgn(cell->mData.mY - player.getCell()->mCell->mData.mY); + //check if actor is near the border of an inactive cell. If so, stop walking. + if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > + sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) + { + movement.mPosition[1] = 0; + return false; + } + } + + MWWorld::Ptr target = world->getPtr(mObjectId,false); + ESM::Position targetPos = target.getRefData().getPosition(); + + bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; + if(!mPathFinder.isPathConstructed() || cellChange) + { + mCellX = cell->mData.mX; + mCellY = cell->mData.mY; + float xCell = 0; + float yCell = 0; + + if(cell->isExterior()) + { + xCell = cell->mData.mX * ESM::Land::REAL_SIZE; + yCell = cell->mData.mY * ESM::Land::REAL_SIZE; + } + + ESM::Pathgrid::Point dest; + dest.mX = targetPos.pos[0]; + dest.mY = targetPos.pos[0]; + dest.mZ = targetPos.pos[0]; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start, dest, actor.getCell(), true); + } + + if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+ + (pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+ + (pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 200*200) + { + movement.mPosition[1] = 0; + MWWorld::Ptr target = world->getPtr(mObjectId,false); + MWWorld::Class::get(target).activate(target,actor); + return true; + } + + if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + { + movement.mPosition[1] = 0; + MWWorld::Ptr target = world->getPtr(mObjectId,false); + MWWorld::Class::get(target).activate(target,actor); + return true; + } + + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + // TODO: use movement settings instead of rotating directly + world->rotateObject(actor, 0, 0, zAngle, false); + movement.mPosition[1] = 1; + + return false; } int MWMechanics::AiActivate::getTypeId() const diff --git a/apps/openmw/mwmechanics/aiactivate.hpp b/apps/openmw/mwmechanics/aiactivate.hpp index f922e238c2..7c94c25896 100644 --- a/apps/openmw/mwmechanics/aiactivate.hpp +++ b/apps/openmw/mwmechanics/aiactivate.hpp @@ -4,6 +4,8 @@ #include "aipackage.hpp" #include +#include "pathfinding.hpp" + namespace MWMechanics { @@ -18,6 +20,10 @@ namespace MWMechanics private: std::string mObjectId; + + PathFinder mPathFinder; + int mCellX; + int mCellY; }; } #endif // GAME_MWMECHANICS_AIACTIVATE_H diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index ba75cb4186..377f9de0f8 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -20,8 +20,8 @@ namespace MWMechanics { AiTravel::AiTravel(float x, float y, float z) : mX(x),mY(y),mZ(z),mPathFinder() - , cellX(std::numeric_limits::max()) - , cellY(std::numeric_limits::max()) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) { } @@ -61,11 +61,11 @@ namespace MWMechanics } } - bool cellChange = cell->mData.mX != cellX || cell->mData.mY != cellY; + bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; if(!mPathFinder.isPathConstructed() || cellChange) { - cellX = cell->mData.mX; - cellY = cell->mData.mY; + mCellX = cell->mData.mX; + mCellY = cell->mData.mY; float xCell = 0; float yCell = 0; diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index b479dfd431..72f3e02983 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -23,8 +23,8 @@ namespace MWMechanics float mY; float mZ; - int cellX; - int cellY; + int mCellX; + int mCellY; PathFinder mPathFinder; };