From 632834ce1094fb5e0b56910797e049455e71cea4 Mon Sep 17 00:00:00 2001 From: gus Date: Wed, 5 Feb 2014 16:12:50 +0100 Subject: [PATCH 1/5] 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; }; From a315d5cc2b501d7c8b766ad7a603f80ce2366507 Mon Sep 17 00:00:00 2001 From: gus Date: Fri, 14 Feb 2014 12:55:14 +0100 Subject: [PATCH 2/5] aiactivate works. Bug when you try to use it on a reference that doesn't exist. Need to clran up door.cpp --- apps/openmw/mwclass/door.cpp | 8 ++++---- apps/openmw/mwmechanics/aiactivate.cpp | 19 +++++++------------ 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index f99cffe04a..a846a84923 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -117,19 +117,19 @@ namespace MWClass { // teleport door /// \todo remove this if clause once ActionTeleport can also support other actors - if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor) - { + //if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor) + //{ boost::shared_ptr action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); action->setSound(openSound); return action; - } + /*} else { // another NPC or a creature is using the door return boost::shared_ptr (new MWWorld::FailedAction); - } + }*/ } else { diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index e751140c08..667ebea889 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/action.hpp" namespace { @@ -64,19 +65,11 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) { 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]; + dest.mY = targetPos.pos[1]; + dest.mZ = targetPos.pos[2]; ESM::Pathgrid::Point start; start.mX = pos.pos[0]; @@ -92,7 +85,8 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) { movement.mPosition[1] = 0; MWWorld::Ptr target = world->getPtr(mObjectId,false); - MWWorld::Class::get(target).activate(target,actor); + MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); + std::cout << "activated"; return true; } @@ -100,7 +94,8 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) { movement.mPosition[1] = 0; MWWorld::Ptr target = world->getPtr(mObjectId,false); - MWWorld::Class::get(target).activate(target,actor); + MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); + std::cout << "activated"; return true; } From e5b19cf3c696b5c4b392112c2b785799e2b9a66a Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 17 Feb 2014 10:37:11 +0100 Subject: [PATCH 3/5] clean up --- apps/openmw/mwclass/door.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index a846a84923..e9ac39f1d1 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -115,21 +115,11 @@ namespace MWClass if (ref->mRef.mTeleport) { - // teleport door - /// \todo remove this if clause once ActionTeleport can also support other actors - //if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor) - //{ - boost::shared_ptr action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); + boost::shared_ptr action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); - action->setSound(openSound); + action->setSound(openSound); - return action; - /*} - else - { - // another NPC or a creature is using the door - return boost::shared_ptr (new MWWorld::FailedAction); - }*/ + return action; } else { From 6e1425321bba487587d7c4ba7e6e90154e085b36 Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 17 Feb 2014 10:43:09 +0100 Subject: [PATCH 4/5] remove cout spam --- apps/openmw/mwmechanics/aiactivate.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index 667ebea889..a22c2b9ba7 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -86,7 +86,6 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) movement.mPosition[1] = 0; MWWorld::Ptr target = world->getPtr(mObjectId,false); MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); - std::cout << "activated"; return true; } @@ -95,7 +94,6 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) movement.mPosition[1] = 0; MWWorld::Ptr target = world->getPtr(mObjectId,false); MWWorld::Class::get(target).activate(target,actor).get()->execute(actor); - std::cout << "activated"; return true; } From 84959eea288057e48374862b86452b70eab9e027 Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 17 Feb 2014 10:50:10 +0100 Subject: [PATCH 5/5] woops, thanks scrawl --- apps/openmw/mwmechanics/aiactivate.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index a22c2b9ba7..1f3c585216 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -8,6 +8,8 @@ #include "../mwworld/class.hpp" #include "../mwworld/action.hpp" +#include "steering.hpp" + namespace { float sgn(float a) @@ -98,8 +100,8 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) } 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); + zTurn(actor, Ogre::Degree(zAngle)); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; movement.mPosition[1] = 1; return false;