#pragma once #ifndef AI_TACTICS_HPP #define AI_TACTICS_HPP #include #pragma warning (push) #include #include #pragma warning (pop) #include "AI_Behavior.hpp" #include 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 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& most_recent_tactics) const; Tactic& GetTactic(TacticID id) const; private: int m_RefCount; static Registrar* instance; typedef Stuff::Auto_Container > 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