1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-29 18:32:36 +00:00
OpenMW/apps/openmw/mwmechanics/aipackage.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

180 lines
6.6 KiB
C++
Raw Normal View History

#ifndef GAME_MWMECHANICS_AIPACKAGE_H
#define GAME_MWMECHANICS_AIPACKAGE_H
2020-06-01 15:36:14 +02:00
#include <memory>
#include <components/detournavigator/areatype.hpp>
#include "aipackagetypeid.hpp"
#include "aistatefwd.hpp"
#include "aitimer.hpp"
#include "obstacle.hpp"
2016-06-17 23:07:16 +09:00
#include "pathfinding.hpp"
#include "../mwworld/ptr.hpp"
2014-06-12 23:27:04 +02:00
namespace ESM
{
struct Cell;
2014-06-12 23:27:04 +02:00
namespace AiSequence
{
struct AiSequence;
2014-06-12 23:27:04 +02:00
}
}
namespace MWMechanics
{
class CharacterController;
class PathgridGraph;
/// \brief Base class for AI packages
class AiPackage
{
public:
struct Options
2022-09-22 21:26:05 +03:00
{
unsigned int mPriority = 0;
bool mUseVariableSpeed = false;
bool mSideWithTarget = false;
bool mFollowTargetThroughDoors = false;
bool mCanCancel = true;
bool mShouldCancelPreviousAi = true;
bool mRepeat = false;
bool mAlwaysActive = false;
2022-09-22 21:26:05 +03:00
constexpr Options withRepeat(bool value)
{
mRepeat = value;
return *this;
}
2022-09-22 21:26:05 +03:00
constexpr Options withShouldCancelPreviousAi(bool value)
{
mShouldCancelPreviousAi = value;
return *this;
}
2022-09-22 21:26:05 +03:00
};
AiPackage(AiPackageTypeId typeId, const Options& options);
2020-06-01 15:36:14 +02:00
virtual ~AiPackage() = default;
static constexpr Options makeDefaultOptions() { return Options{}; }
/// Clones the package
virtual std::unique_ptr<AiPackage> clone() const = 0;
/// Updates and runs the package (Should run every frame)
/// \return Package completed?
virtual bool execute(
const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
= 0;
/// Returns the TypeID of the AiPackage
/// \see enum TypeId
AiPackageTypeId getTypeId() const { return mTypeId; }
2014-06-12 23:27:04 +02:00
/// Higher number is higher priority (0 being the lowest)
unsigned int getPriority() const { return mOptions.mPriority; }
/// Check if package use movement with variable speed
bool useVariableSpeed() const { return mOptions.mUseVariableSpeed; }
2016-02-16 19:17:04 +01:00
virtual void writeState(ESM::AiSequence::AiSequence& sequence) const {}
/// Simulates the passing of time
virtual void fastForward(const MWWorld::Ptr& actor, AiState& state) {}
/// Get the target actor the AI is targeted at (not applicable to all AI packages, default return empty Ptr)
virtual MWWorld::Ptr getTarget() const;
/// Get the destination point of the AI package (not applicable to all AI packages, default return (0, 0, 0))
2022-10-05 23:45:17 +02:00
virtual osg::Vec3f getDestination(const MWWorld::Ptr& actor) const { return osg::Vec3f(0, 0, 0); }
/// Return true if having this AiPackage makes the actor side with the target in fights (default false)
bool sideWithTarget() const { return mOptions.mSideWithTarget; }
/// Return true if the actor should follow the target through teleport doors (default false)
bool followTargetThroughDoors() const { return mOptions.mFollowTargetThroughDoors; }
/// Can this Ai package be canceled? (default true)
bool canCancel() const { return mOptions.mCanCancel; }
2020-02-11 12:33:22 +03:00
/// Upon adding this Ai package, should the Ai Sequence attempt to cancel previous Ai packages (default true)?
bool shouldCancelPreviousAi() const { return mOptions.mShouldCancelPreviousAi; }
/// Return true if this package should repeat.
bool getRepeat() const { return mOptions.mRepeat; }
virtual osg::Vec3f getDestination() const { return osg::Vec3f(0, 0, 0); }
/// Return true if any loaded actor with this AI package must be active.
bool alwaysActive() const { return mOptions.mAlwaysActive; }
/// Reset pathfinding state
void reset();
/// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise
/// actor should rotate while standing.
static bool isReachableRotatingOnTheRun(const MWWorld::Ptr& actor, const osg::Vec3f& dest);
osg::Vec3f getNextPathPoint(const osg::Vec3f& destination) const;
float getNextPathPointTolerance(float speed, float duration, const osg::Vec3f& halfExtents) const;
protected:
/// Handles path building and shortcutting with obstacles avoiding
/** \return If the actor has arrived at his destination **/
bool pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& dest, float duration, float destTolerance = 0.0f,
float endTolerance = 0.0f, PathType pathType = PathType::Full);
/// Check if there aren't any obstacles along the path to make shortcut possible
/// If a shortcut is possible then path will be cleared and filled with the destination point.
/// \param destInLOS If not nullptr function will return ray cast check result
/// \return If can shortcut the path
bool shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor,
bool* destInLOS, bool isPathClear);
2015-06-11 18:28:31 +12:00
2018-08-18 18:41:48 +03:00
/// Check if the way to the destination is clear, taking into account actor speed
bool checkWayIsClearForActor(
2018-08-18 18:41:48 +03:00
const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor);
2018-08-18 18:26:00 +03:00
bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const;
void evadeObstacles(const MWWorld::Ptr& actor);
void openDoors(const MWWorld::Ptr& actor);
const PathgridGraph& getPathGridGraph(const ESM::Pathgrid* pathgrid) const;
DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const;
DetourNavigator::AreaCosts getAreaCosts(const MWWorld::Ptr& actor) const;
const AiPackageTypeId mTypeId;
const Options mOptions;
2014-06-12 23:27:04 +02:00
// TODO: all this does not belong here, move into temporary storage
PathFinder mPathFinder;
ObstacleCheck mObstacleCheck;
AiReactionTimer mReaction;
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
ESM::RefId mTargetActorRefId;
mutable int mTargetActorId;
mutable MWWorld::Ptr mCachedTarget;
short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility
2022-09-22 21:26:05 +03:00
bool mIsShortcutting; // if shortcutting at the moment
bool mShortcutProhibited; // shortcutting may be prohibited after unsuccessful attempt
osg::Vec3f mShortcutFailPos; // position of last shortcut fail
float mLastDestinationTolerance = 0;
2022-09-22 21:26:05 +03:00
private:
2018-09-04 00:10:58 +03:00
bool isNearInactiveCell(osg::Vec3f position);
};
}
#endif