2014-05-13 17:07:27 +00:00
|
|
|
#include "aiavoiddoor.hpp"
|
2015-07-24 23:48:34 +00:00
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
#include "../mwbase/environment.hpp"
|
2015-05-28 13:44:58 +00:00
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
2016-06-17 14:07:16 +00:00
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
#include "../mwworld/class.hpp"
|
2016-06-17 14:07:16 +00:00
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
#include "creaturestats.hpp"
|
|
|
|
#include "movement.hpp"
|
2015-08-21 09:12:39 +00:00
|
|
|
#include "actorutil.hpp"
|
2014-05-13 17:07:27 +00:00
|
|
|
#include "steering.hpp"
|
|
|
|
|
2015-12-19 14:57:37 +00:00
|
|
|
MWMechanics::AiAvoidDoor::AiAvoidDoor(const MWWorld::ConstPtr& doorPtr)
|
2015-05-01 00:24:27 +00:00
|
|
|
: AiPackage(), mDuration(1), mDoorPtr(doorPtr), mAdjAngle(0)
|
2014-05-13 17:07:27 +00:00
|
|
|
{
|
2014-05-14 17:38:10 +00:00
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
}
|
|
|
|
|
2015-06-26 15:47:04 +00:00
|
|
|
bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
2014-05-13 17:07:27 +00:00
|
|
|
{
|
2014-05-14 17:38:10 +00:00
|
|
|
|
|
|
|
ESM::Position pos = actor.getRefData().getPosition();
|
2014-05-14 18:11:34 +00:00
|
|
|
if(mDuration == 1) //If it just started, get the actor position as the stuck detection thing
|
2014-05-14 17:38:10 +00:00
|
|
|
mLastPos = pos;
|
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
mDuration -= duration; //Update timer
|
|
|
|
|
2014-05-14 17:38:10 +00:00
|
|
|
if(mDuration < 0) {
|
|
|
|
float x = pos.pos[0] - mLastPos.pos[0];
|
|
|
|
float y = pos.pos[1] - mLastPos.pos[1];
|
|
|
|
float z = pos.pos[2] - mLastPos.pos[2];
|
2015-03-08 04:42:07 +00:00
|
|
|
float distance = x * x + y * y + z * z;
|
2014-05-14 17:38:10 +00:00
|
|
|
if(distance < 10 * 10) { //Got stuck, didn't move
|
|
|
|
if(mAdjAngle == 0) //Try going in various directions
|
|
|
|
mAdjAngle = 1.57079632679f; //pi/2
|
|
|
|
else if (mAdjAngle == 1.57079632679f)
|
2015-03-08 04:42:07 +00:00
|
|
|
mAdjAngle = -1.57079632679f;
|
2014-05-14 17:38:10 +00:00
|
|
|
else
|
|
|
|
mAdjAngle = 0;
|
|
|
|
mDuration = 1; //reset timer
|
|
|
|
}
|
|
|
|
else //Not stuck
|
|
|
|
return true; // We have tried backing up for more than one second, we've probably cleared it
|
|
|
|
}
|
2014-05-13 17:07:27 +00:00
|
|
|
|
2014-05-14 23:58:44 +00:00
|
|
|
if (!mDoorPtr.getClass().getDoorState(mDoorPtr))
|
2014-05-13 17:07:27 +00:00
|
|
|
return true; //Door is no longer opening
|
|
|
|
|
|
|
|
ESM::Position tPos = mDoorPtr.getRefData().getPosition(); //Position of the door
|
|
|
|
float x = pos.pos[0] - tPos.pos[0];
|
|
|
|
float y = pos.pos[1] - tPos.pos[1];
|
|
|
|
|
2014-08-11 02:21:04 +00:00
|
|
|
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
|
2014-05-13 17:07:27 +00:00
|
|
|
|
2014-08-11 02:21:04 +00:00
|
|
|
// Turn away from the door and move when turn completed
|
2015-06-03 17:41:19 +00:00
|
|
|
if (zTurn(actor, std::atan2(x,y) + mAdjAngle, osg::DegreesToRadians(5.f)))
|
2014-08-11 02:21:04 +00:00
|
|
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
|
|
|
else
|
|
|
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
|
|
|
actor.getClass().getMovementSettings(actor).mPosition[0] = 0;
|
|
|
|
|
|
|
|
// Make all nearby actors also avoid the door
|
2014-05-14 08:05:18 +00:00
|
|
|
std::vector<MWWorld::Ptr> actors;
|
2015-06-01 19:41:13 +00:00
|
|
|
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(),100,actors);
|
2014-09-26 15:12:48 +00:00
|
|
|
for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) {
|
2015-08-21 09:12:39 +00:00
|
|
|
if(*it != getPlayer()) { //Not the player
|
2014-05-22 18:37:22 +00:00
|
|
|
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
|
2014-05-14 08:05:18 +00:00
|
|
|
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) { //Only add it once
|
|
|
|
seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr),*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-13 17:07:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MWMechanics::AiAvoidDoor *MWMechanics::AiAvoidDoor::clone() const
|
|
|
|
{
|
|
|
|
return new AiAvoidDoor(*this);
|
|
|
|
}
|
|
|
|
|
2014-06-12 21:27:04 +00:00
|
|
|
int MWMechanics::AiAvoidDoor::getTypeId() const
|
2014-05-13 17:07:27 +00:00
|
|
|
{
|
|
|
|
return TypeIdAvoidDoor;
|
|
|
|
}
|
|
|
|
|
2014-06-12 21:27:04 +00:00
|
|
|
unsigned int MWMechanics::AiAvoidDoor::getPriority() const
|
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|