1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-27 09:41:16 +00:00
OpenMW/apps/openmw/mwmechanics/aifollow.hpp
florent.teppe 65cdd489fb create a specific esm reader function for RefID to avoid allocation for string and then again for RefId
Fixed some types

removed useless header

applied clang format

fixed compile tests

fixed clang tidy, and closer to logic before this MR

Removed hardcoded refids

unless there is a returned value we don't use static RefIds
can use == between RefId and hardcoded string

Fix clang format

Fixed a few instances where std::string was used, when only const std::string& was needed

removed unused variable
2022-12-27 19:15:57 +01:00

105 lines
3.1 KiB
C++

#ifndef GAME_MWMECHANICS_AIFOLLOW_H
#define GAME_MWMECHANICS_AIFOLLOW_H
#include "aitemporarybase.hpp"
#include "typedaipackage.hpp"
#include <string>
#include <string_view>
#include <components/esm/defs.hpp>
#include "../mwworld/ptr.hpp"
namespace ESM::AiSequence
{
struct AiFollow;
}
namespace MWMechanics
{
struct AiFollowStorage : AiTemporaryBase
{
float mTimer;
bool mMoving;
float mTargetAngleRadians;
bool mTurnActorToTarget;
AiFollowStorage()
: mTimer(0.f)
, mMoving(false)
, mTargetAngleRadians(0.f)
, mTurnActorToTarget(false)
{
}
};
/// \brief AiPackage for an actor to follow another actor/the PC
/** The AI will follow the target until a condition (time, or position) are set. Both can be disabled to cause the
*actor to follow the other indefinitely
**/
class AiFollow final : public TypedAiPackage<AiFollow>
{
public:
/// Follow Actor for duration or until you arrive at a world position
AiFollow(const ESM::RefId& actorId, float duration, float x, float y, float z, bool repeat);
/// Follow Actor for duration or until you arrive at a position in a cell
AiFollow(const ESM::RefId& actorId, const ESM::RefId& cellId, float duration, float x, float y, float z,
bool repeat);
/// Follow Actor indefinitively
AiFollow(const MWWorld::Ptr& actor, bool commanded = false);
AiFollow(const ESM::AiSequence::AiFollow* follow);
bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state,
float duration) override;
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; }
static constexpr Options makeDefaultOptions()
{
AiPackage::Options options;
options.mUseVariableSpeed = true;
options.mSideWithTarget = true;
options.mFollowTargetThroughDoors = true;
return options;
}
/// Returns the actor being followed
ESM::RefId getFollowedActor();
void writeState(ESM::AiSequence::AiSequence& sequence) const override;
bool isCommanded() const;
int getFollowIndex() const;
void fastForward(const MWWorld::Ptr& actor, AiState& state) override;
osg::Vec3f getDestination() const override
{
MWWorld::Ptr target = getTarget();
if (target.isEmpty())
return osg::Vec3f(0, 0, 0);
return target.getRefData().getPosition().asVec3();
}
private:
/// This will make the actor always follow.
/** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/
const bool mAlwaysFollow;
const float mDuration; // Hours
float mRemainingDuration; // Hours
const float mX;
const float mY;
const float mZ;
const ESM::RefId mCellId;
bool mActive; // have we spotted the target?
const int mFollowIndex;
static int mFollowIndexCounter;
};
}
#endif