1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-09 21:42:13 +00:00
OpenMW/apps/openmw/mwmechanics/aiavoiddoor.cpp

94 lines
3.0 KiB
C++
Raw Normal View History

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)
: 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
}
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();
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];
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)
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
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];
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
2014-05-13 17:07:27 +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)))
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
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
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
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;
}