# include "aipursue.hpp"
# include <components/esm/aisequence.hpp>
# include <components/esm/loadmgef.hpp>
# include "../mwbase/environment.hpp"
# include "../mwworld/class.hpp"
# include "../mwworld/action.hpp"
/*
Start of tes3mp addition
Include additional headers for multiplayer purposes
*/
# include <components/openmw-mp/Log.hpp>
# include "../mwgui/windowmanagerimp.hpp"
# include "../mwmp/Main.hpp"
# include "../mwmp/LocalPlayer.hpp"
/*
End of tes3mp addition
*/
# include "movement.hpp"
# include "creaturestats.hpp"
namespace MWMechanics
{
AiPursue : : AiPursue ( const MWWorld : : Ptr & actor )
{
mTargetActorId = actor . getClass ( ) . getCreatureStats ( actor ) . getActorId ( ) ;
}
AiPursue : : AiPursue ( const ESM : : AiSequence : : AiPursue * pursue )
{
mTargetActorId = pursue - > mTargetActorId ;
}
AiPursue * MWMechanics : : AiPursue : : clone ( ) const
{
return new AiPursue ( * this ) ;
}
bool AiPursue : : execute ( const MWWorld : : Ptr & actor , CharacterController & characterController , AiState & state , float duration )
{
if ( actor . getClass ( ) . getCreatureStats ( actor ) . isDead ( ) )
return true ;
const MWWorld : : Ptr target = MWBase : : Environment : : get ( ) . getWorld ( ) - > searchPtrViaActorId ( mTargetActorId ) ; //The target to follow
if ( target = = MWWorld : : Ptr ( ) | | ! target . getRefData ( ) . getCount ( ) | | ! target . getRefData ( ) . isEnabled ( ) // Really we should be checking whether the target is currently registered
// with the MechanicsManager
)
return true ; //Target doesn't exist
if ( isTargetMagicallyHidden ( target ) )
return true ;
if ( target . getClass ( ) . getCreatureStats ( target ) . isDead ( ) )
return true ;
/*
Start of tes3mp addition
Because multiplayer does not pause the game , prevent infinite arrest loops by ignoring
players already engaged in dialogue
Additionally , do not arrest players who are currently jailed
*/
if ( target = = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayerPtr ( ) )
{
if ( MWBase : : Environment : : get ( ) . getWindowManager ( ) - > containsMode ( MWGui : : GM_Dialogue ) | |
MWBase : : Environment : : get ( ) . getWindowManager ( ) - > containsMode ( MWGui : : GM_Jail ) )
{
return true ;
}
}
/*
End of tes3mp addition
*/
actor . getClass ( ) . getCreatureStats ( actor ) . setDrawState ( DrawState_Nothing ) ;
//Set the target desition from the actor
ESM : : Pathgrid : : Point dest = target . getRefData ( ) . getPosition ( ) . pos ;
ESM : : Position aPos = actor . getRefData ( ) . getPosition ( ) ;
float pathTolerance = 100.0 ;
if ( pathTo ( actor , dest , duration , pathTolerance ) & &
std : : abs ( dest . mZ - aPos . pos [ 2 ] ) < pathTolerance ) // check the true distance in case the target is far away in Z-direction
{
/*
Start of tes3mp addition
Record that the player has not died since the last attempt to arrest them
Close the player ' s inventory or open container and cancel any drag and drops
*/
LOG_MESSAGE_SIMPLE ( Log : : LOG_INFO , " After being pursued by %s, diedSinceArrestAttempt is now false " , actor . getCellRef ( ) . getRefId ( ) . c_str ( ) ) ;
mwmp : : Main : : get ( ) . getLocalPlayer ( ) - > diedSinceArrestAttempt = false ;
mwmp : : Main : : get ( ) . getLocalPlayer ( ) - > closeInventoryWindows ( ) ;
/*
End of tes3mp addition
*/
target . getClass ( ) . activate ( target , actor ) . get ( ) - > execute ( actor ) ; //Arrest player when reached
return true ;
}
actor . getClass ( ) . getCreatureStats ( actor ) . setMovementFlag ( MWMechanics : : CreatureStats : : Flag_Run , true ) ; //Make NPC run
return false ;
}
int AiPursue : : getTypeId ( ) const
{
return TypeIdPursue ;
}
MWWorld : : Ptr AiPursue : : getTarget ( ) const
{
return MWBase : : Environment : : get ( ) . getWorld ( ) - > searchPtrViaActorId ( mTargetActorId ) ;
}
void AiPursue : : writeState ( ESM : : AiSequence : : AiSequence & sequence ) const
{
std : : unique_ptr < ESM : : AiSequence : : AiPursue > pursue ( new ESM : : AiSequence : : AiPursue ( ) ) ;
pursue - > mTargetActorId = mTargetActorId ;
ESM : : AiSequence : : AiPackageContainer package ;
package . mType = ESM : : AiSequence : : Ai_Pursue ;
package . mPackage = pursue . release ( ) ;
sequence . mPackages . push_back ( package ) ;
}
} // namespace MWMechanics