2014-01-24 18:16:50 +00:00
# include "aifollow.hpp"
2012-11-15 21:32:15 +00:00
# include <iostream>
2014-01-11 11:06:36 +00:00
# include "../mwbase/world.hpp"
# include "../mwbase/environment.hpp"
# include "../mwworld/class.hpp"
2014-03-29 17:36:32 +00:00
# include "../mwworld/cellstore.hpp"
2014-04-23 06:57:48 +00:00
# include "creaturestats.hpp"
2014-01-11 11:06:36 +00:00
# include "movement.hpp"
2014-01-24 18:13:23 +00:00
# include <OgreMath.h>
2014-01-29 19:29:07 +00:00
# include "steering.hpp"
2014-05-16 10:11:34 +00:00
MWMechanics : : AiFollow : : AiFollow ( const std : : string & actorId , float duration , float x , float y , float z )
: mAlwaysFollow ( false ) , mDuration ( duration ) , mX ( x ) , mY ( y ) , mZ ( z ) , mActorId ( actorId ) , mCellId ( " " ) , AiPackage ( )
2014-01-29 19:29:07 +00:00
{
}
2014-05-16 10:11:34 +00:00
MWMechanics : : AiFollow : : AiFollow ( const std : : string & actorId , const std : : string & cellId , float duration , float x , float y , float z )
: mAlwaysFollow ( false ) , mDuration ( duration ) , mX ( x ) , mY ( y ) , mZ ( z ) , mActorId ( actorId ) , mCellId ( cellId ) , AiPackage ( )
2014-03-05 10:24:39 +00:00
{
}
2014-05-16 10:11:34 +00:00
MWMechanics : : AiFollow : : AiFollow ( const std : : string & actorId )
: mAlwaysFollow ( true ) , mDuration ( 0 ) , mX ( 0 ) , mY ( 0 ) , mZ ( 0 ) , mActorId ( actorId ) , mCellId ( " " ) , AiPackage ( )
2014-01-29 19:29:07 +00:00
{
}
2012-11-15 21:32:15 +00:00
2014-01-12 10:38:58 +00:00
bool MWMechanics : : AiFollow : : execute ( const MWWorld : : Ptr & actor , float duration )
2012-11-15 21:32:15 +00:00
{
2014-05-16 10:11:34 +00:00
const MWWorld : : Ptr target = MWBase : : Environment : : get ( ) . getWorld ( ) - > searchPtr ( mActorId , false ) ; //The target to follow
2014-01-11 11:06:36 +00:00
2014-04-23 06:57:48 +00:00
if ( target = = MWWorld : : Ptr ( ) ) return true ; //Target doesn't exist
2014-01-11 11:06:36 +00:00
2014-04-23 06:57:48 +00:00
ESM : : Position pos = actor . getRefData ( ) . getPosition ( ) ; //position of the actor
if ( ! mAlwaysFollow ) //Update if you only follow for a bit
2014-01-12 10:38:58 +00:00
{
2014-04-23 06:57:48 +00:00
if ( mTotalTime > mDuration & & mDuration ! = 0 ) //Check if we've run out of time
2014-03-05 10:24:39 +00:00
return true ;
if ( ( pos . pos [ 0 ] - mX ) * ( pos . pos [ 0 ] - mX ) +
( pos . pos [ 1 ] - mY ) * ( pos . pos [ 1 ] - mY ) +
2014-04-23 06:57:48 +00:00
( pos . pos [ 2 ] - mZ ) * ( pos . pos [ 2 ] - mZ ) < 100 * 100 ) //Close-ish to final position
2014-01-12 10:38:58 +00:00
{
2014-04-23 06:57:48 +00:00
if ( actor . getCell ( ) - > isExterior ( ) ) //Outside?
2014-03-05 10:24:39 +00:00
{
2014-04-23 06:57:48 +00:00
if ( mCellId = = " " ) //No cell to travel to
2014-03-05 10:24:39 +00:00
return true ;
}
else
{
2014-04-23 06:57:48 +00:00
if ( mCellId = = actor . getCell ( ) - > getCell ( ) - > mName ) //Cell to travel to
2014-03-05 10:24:39 +00:00
return true ;
}
2014-01-12 10:38:58 +00:00
}
}
2014-01-11 11:06:36 +00:00
2014-04-23 06:57:48 +00:00
//Set the target desition from the actor
2014-05-13 01:05:32 +00:00
ESM : : Pathgrid : : Point dest = target . getRefData ( ) . getPosition ( ) . pos ;
2014-01-11 11:06:36 +00:00
2014-05-13 01:05:32 +00:00
if ( distance ( dest , pos . pos [ 0 ] , pos . pos [ 1 ] , pos . pos [ 2 ] ) < 100 ) //Stop when you get close
2014-01-29 19:29:07 +00:00
actor . getClass ( ) . getMovementSettings ( actor ) . mPosition [ 1 ] = 0 ;
2014-05-14 18:11:34 +00:00
else {
pathTo ( actor , dest , duration ) ; //Go to the destination
}
2014-01-11 11:06:36 +00:00
2014-04-23 06:57:48 +00:00
//Check if you're far away
2014-05-13 01:05:32 +00:00
if ( distance ( dest , pos . pos [ 0 ] , pos . pos [ 1 ] , pos . pos [ 2 ] ) > 1000 )
2014-04-23 06:57:48 +00:00
actor . getClass ( ) . getCreatureStats ( actor ) . setMovementFlag ( MWMechanics : : CreatureStats : : Flag_Run , true ) ; //Make NPC run
2014-05-13 01:05:32 +00:00
else if ( distance ( dest , pos . pos [ 0 ] , pos . pos [ 1 ] , pos . pos [ 2 ] ) < 800 ) //Have a bit of a dead zone, otherwise npc will constantly flip between running and not when right on the edge of the running threshhold
2014-04-23 06:57:48 +00:00
actor . getClass ( ) . getCreatureStats ( actor ) . setMovementFlag ( MWMechanics : : CreatureStats : : Flag_Run , false ) ; //make NPC walk
2014-01-11 11:06:36 +00:00
return false ;
2012-11-15 21:32:15 +00:00
}
2014-01-12 13:02:40 +00:00
std : : string MWMechanics : : AiFollow : : getFollowedActor ( )
{
2014-05-16 10:11:34 +00:00
return mActorId ;
2014-01-12 13:02:40 +00:00
}
2014-01-24 18:16:50 +00:00
2014-01-29 19:29:07 +00:00
MWMechanics : : AiFollow * MWMechanics : : AiFollow : : clone ( ) const
{
return new AiFollow ( * this ) ;
}
int MWMechanics : : AiFollow : : getTypeId ( ) const
{
return TypeIdFollow ;
2014-01-24 18:16:50 +00:00
}