Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

256 lines
7.5 KiB
C++

#pragma once
#ifndef AI_TACTICS_HPP
#define AI_TACTICS_HPP
#include <stuff\auto_container.hpp>
#pragma warning (push)
#include <stlport\string>
#include <stlport\vector>
#pragma warning (pop)
#include "AI_Behavior.hpp"
#include <Stuff\Scalar.hpp>
namespace Stuff { class Point3D; }
namespace MechWarrior4 { class Vehicle; }
namespace MW4AI
{
namespace Tactics
{
enum TacticID
{
// NOTE: The keywords and constants here must exactly match those in MWCONST.ABI
TACTIC_PICK_BEST = 2000, // update TACTIC_FIRST if you change this
TACTIC_STOP_AND_FIRE = 2001,
TACTIC_RAM = 2002,
TACTIC_JOUST = 2003,
TACTIC_RUSH = 2004,
TACTIC_HIT_AND_RUN = 2005,
TACTIC_FRONT = 2006,
TACTIC_REAR = 2007,
TACTIC_CIRCLE_OF_DEATH = 2008,
TACTIC_BACK_UP_AND_FIRE = 2009,
TACTIC_RETREAT = 2010,
TACTIC_CIRCLE_HOVER = 2011,
TACTIC_STRAFE = 2012,
TACTIC_STAND_GROUND = 2013,
TACTIC_JUMP_AND_SHOOT = 2014,
TACTIC_SNIPE = 2015,
TACTIC_SHOOT_ONLY = 2016,
TACTIC_DEFEND = 2017,
TACTIC_LOCAL_PATROL = 2018,
TACTIC_SURRENDER = 2019,
TACTIC_AMBUSH = 2020,
TACTIC_DEATH_FROM_ABOVE = 2021,
TACTIC_HELI_POPUP = 2022,
TACTIC_DIVE_BOMB = 2023,
TACTIC_FAST_CIRCLE = 2024,
TACTIC_STARE = 2025 // update TACTIC_LAST if you change this
};
class Tactic
{
public:
virtual void Update(TacticInterface& i);
virtual TacticID GetID() const = 0;
virtual std::string GetName() const = 0;
Tactic();
virtual ~Tactic();
virtual bool CanBeSelectedAutomatically(TacticInterface& iface) const;
virtual bool ShouldIgnoreLOS() const;
void SetExplicit(bool is_explicit);
bool GetExplicit() const;
bool ShouldAbandon(TacticInterface& i) const;
virtual bool ShouldAbandonImmediately() const = 0;
virtual Stuff::Scalar Evaluate(TacticInterface& iface) const;
void SetIgnoreExplicitTactic(TacticID tactic);
TacticID GetIgnoreExplicitTactic() const;
bool Finished() const;
void UpdateSatisfaction();
private:
Stuff::Scalar GetDuration() const;
bool IsIneffective() const;
Stuff::Scalar m_CreationTime;
Stuff::Scalar m_CreationMood;
mutable bool m_Explicit;
Stuff::Scalar m_Satisfaction;
Stuff::Time m_LastSatisfactionUpdate;
Stuff::Scalar m_AutoEndTime;
TacticID m_TacticToIgnore;
protected:
virtual bool IsHappy() const = 0;
};
enum
{
TACTIC_FIRST = TACTIC_PICK_BEST,
TACTIC_LAST = TACTIC_STARE
};
void VerifyTactic(TacticID id);
Stuff::Auto_Ptr<Tactic> CreateTactic(TacticInterface& i, TacticID id);
class Registrar
{
public:
static void IncrementRefCount(TacticInterface& i);
static void DecrementRefCount();
static Registrar& GetInstance();
Registrar(TacticInterface& i);
~Registrar();
TacticID SelectTactic(TacticInterface& i, const std::vector<TacticID>& most_recent_tactics) const;
Tactic& GetTactic(TacticID id) const;
private:
int m_RefCount;
static Registrar* instance;
typedef Stuff::Auto_Container<Tactic,std::vector<Tactic*> > tactic_container;
tactic_container m_Tactics;
};
#define BEGINDEF_TACTIC(classname,id,string_name,behavior_type) \
class classname: \
public Tactic \
{ \
protected: \
TacticID GetID() const { return (id); } \
std::string GetName() const { return (string_name); } \
bool ShouldAbandonImmediately() const { return (m_Implementation.ShouldStopImmediately()); } \
void Update(TacticInterface& i) \
{ \
Tactic::Update(i); \
m_Implementation.Execute(i); \
} \
bool IsHappy() const { return (m_Implementation.IsHappy()); } \
private: \
behavior_type m_Implementation;
#define ENDDEF_TACTIC };
BEGINDEF_TACTIC(StopAndFire,TACTIC_STOP_AND_FIRE,"Stop and Fire",MW4AI::Behaviors::StopAndFire)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Ram,TACTIC_RAM,"Ram",MW4AI::Behaviors::Ram)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Joust,TACTIC_JOUST,"Joust",MW4AI::Behaviors::Joust);
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(Rush,TACTIC_RUSH,"Rush",MW4AI::Behaviors::Rush)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(HitAndRun,TACTIC_HIT_AND_RUN,"Hit and Run",MW4AI::Behaviors::HitAndRun)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(Front,TACTIC_FRONT,"Front",MW4AI::Behaviors::Front)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Rear,TACTIC_REAR,"Rear",MW4AI::Behaviors::Rear)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(Circle,TACTIC_CIRCLE_OF_DEATH,"Circle",MW4AI::Behaviors::CircleOfDeath)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(Retreat,TACTIC_RETREAT,"Retreat",MW4AI::Behaviors::Retreat)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(BackUpAndFire,TACTIC_BACK_UP_AND_FIRE,"Back Up and Fire",MW4AI::Behaviors::BackUpAndFire)
ENDDEF_TACTIC
BEGINDEF_TACTIC(CircleHover,TACTIC_CIRCLE_HOVER,"Circle Hover",MW4AI::Behaviors::CircleHover)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Strafe,TACTIC_STRAFE,"Strafe",MW4AI::Behaviors::Strafe)
virtual bool ShouldIgnoreLOS() const
{
return (true);
}
ENDDEF_TACTIC
BEGINDEF_TACTIC(StandGround,TACTIC_STAND_GROUND,"Stand Ground",MW4AI::Behaviors::StandGround)
ENDDEF_TACTIC
BEGINDEF_TACTIC(JumpAndShoot,TACTIC_JUMP_AND_SHOOT,"Jump and Shoot",MW4AI::Behaviors::JumpAndShoot)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Snipe,TACTIC_SNIPE,"Snipe",MW4AI::Behaviors::Snipe)
ENDDEF_TACTIC
BEGINDEF_TACTIC(ShootOnly,TACTIC_SHOOT_ONLY,"ShootOnly",MW4AI::Behaviors::ShootOnly)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Defend,TACTIC_DEFEND,"Defend",MW4AI::Behaviors::Defend)
ENDDEF_TACTIC
BEGINDEF_TACTIC(LocalPatrol,TACTIC_LOCAL_PATROL,"Local Patrol",MW4AI::Behaviors::LocalPatrol)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Surrender,TACTIC_SURRENDER,"Surrender",MW4AI::Behaviors::Surrender)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Ambush,TACTIC_AMBUSH,"Ambush",MW4AI::Behaviors::Ambush)
ENDDEF_TACTIC
BEGINDEF_TACTIC(DeathFromAbove,TACTIC_DEATH_FROM_ABOVE,"Death From Above",MW4AI::Behaviors::DeathFromAbove)
public:
bool CanBeSelectedAutomatically(TacticInterface& iface) const;
Stuff::Scalar Evaluate(TacticInterface& iface) const;
ENDDEF_TACTIC
BEGINDEF_TACTIC(HeliPopup,TACTIC_HELI_POPUP,"Heli Popup",MW4AI::Behaviors::HeliPopup)
ENDDEF_TACTIC
BEGINDEF_TACTIC(DiveBomb,TACTIC_DIVE_BOMB,"Dive Bomb",MW4AI::Behaviors::DiveBomb)
ENDDEF_TACTIC
BEGINDEF_TACTIC(FastCircle,TACTIC_FAST_CIRCLE,"Fast Circle",MW4AI::Behaviors::FastCircle)
ENDDEF_TACTIC
BEGINDEF_TACTIC(Stare,TACTIC_STARE,"Stare",MW4AI::Behaviors::Stare)
ENDDEF_TACTIC
#undef BEGINDEF_TACTIC
#undef ENDDEF_TACTIC
};
};
#endif AI_TACTICS_HPP