1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00
OpenMW/apps/openmw/mwmechanics/aicombataction.hpp
2023-08-07 22:44:24 +02:00

112 lines
3.7 KiB
C++

#ifndef OPENMW_AICOMBAT_ACTION_H
#define OPENMW_AICOMBAT_ACTION_H
#include <memory>
#include "../mwworld/containerstore.hpp"
#include "../mwworld/ptr.hpp"
namespace MWMechanics
{
class Action
{
public:
virtual ~Action() {}
virtual void prepare(const MWWorld::Ptr& actor) = 0;
virtual float getCombatRange(bool& isRanged) const = 0;
virtual float getActionCooldown() const { return 0.f; }
virtual const ESM::Weapon* getWeapon() const { return nullptr; }
virtual bool isAttackingOrSpell() const { return true; }
virtual bool isFleeing() const { return false; }
};
class ActionFlee : public Action
{
public:
ActionFlee() {}
void prepare(const MWWorld::Ptr& actor) override {}
float getCombatRange(bool& isRanged) const override { return 0.0f; }
float getActionCooldown() const override { return 3.0f; }
bool isAttackingOrSpell() const override { return false; }
bool isFleeing() const override { return true; }
};
class ActionSpell : public Action
{
public:
ActionSpell(const ESM::RefId& spellId)
: mSpellId(spellId)
{
}
ESM::RefId mSpellId;
/// Sets the given spell as selected on the actor's spell list.
void prepare(const MWWorld::Ptr& actor) override;
float getCombatRange(bool& isRanged) const override;
};
class ActionEnchantedItem : public Action
{
public:
ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item)
: mItem(item)
{
}
MWWorld::ContainerStoreIterator mItem;
/// Sets the given item as selected enchanted item in the actor's InventoryStore.
void prepare(const MWWorld::Ptr& actor) override;
float getCombatRange(bool& isRanged) const override;
/// Since this action has no animation, apply a small cool down for using it
float getActionCooldown() const override { return 0.75f; }
};
class ActionPotion : public Action
{
public:
ActionPotion(const MWWorld::Ptr& potion)
: mPotion(potion)
{
}
MWWorld::Ptr mPotion;
/// Drinks the given potion.
void prepare(const MWWorld::Ptr& actor) override;
float getCombatRange(bool& isRanged) const override;
bool isAttackingOrSpell() const override { return false; }
/// Since this action has no animation, apply a small cool down for using it
float getActionCooldown() const override { return 0.75f; }
};
class ActionWeapon : public Action
{
private:
MWWorld::Ptr mAmmunition;
MWWorld::Ptr mWeapon;
public:
/// \a weapon may be empty for hand-to-hand combat
ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr())
: mAmmunition(ammo)
, mWeapon(weapon)
{
}
/// Equips the given weapon.
void prepare(const MWWorld::Ptr& actor) override;
float getCombatRange(bool& isRanged) const override;
const ESM::Weapon* getWeapon() const override;
};
std::unique_ptr<Action> prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
float getBestActionRating(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist = false);
float getMaxAttackDistance(const MWWorld::Ptr& actor);
bool canFight(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
float vanillaRateFlee(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy);
bool makeFleeDecision(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, float antiFleeRating);
}
#endif