#include "aipursue.hpp" #include #include #include "../mwbase/environment.hpp" #include "../mwworld/class.hpp" #include "../mwworld/action.hpp" #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; 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 { 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 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