mirror of
https://github.com/1dot13/source.git
synced 2026-09-09 14:46:05 +02:00
Added missing from ModularizedTacticalAI :/
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6019 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CROW_PLAN_H_
|
||||||
|
#define CROW_PLAN_H_
|
||||||
|
|
||||||
|
#include "Plan.h"
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
/**@class CrowSeekCorpsePlan
|
||||||
|
* @brief Component/Concrete Product. Let a crow seek a corpse within 4 tiles radius, and go towards it.
|
||||||
|
*/
|
||||||
|
class CrowSeekCorpsePlan : public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// The location of the corpse the crow shall go to
|
||||||
|
int corpse_grid_;
|
||||||
|
public:
|
||||||
|
CrowSeekCorpsePlan(SOLDIERTYPE* npc);
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
/// The plan is marked as 'done' when the 'sweet spot' near the corpse is reached
|
||||||
|
virtual bool done() const;
|
||||||
|
int get_corpse_grid() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**@class CrowPeckPlan
|
||||||
|
* @brief Component/Concrete Product. Let a crow sitting next to a corpse peck.
|
||||||
|
*/
|
||||||
|
class CrowPeckPlan : public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int corpse_grid_;
|
||||||
|
public:
|
||||||
|
CrowPeckPlan(SOLDIERTYPE* npc, int corpse_grid);
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
/// The plan never ends without interrupt/plan update, pecking can take forever
|
||||||
|
virtual bool done() const {return false;}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**@class CrowFlyAwayPlan
|
||||||
|
* @brief Component/Concrete Product. Let a crow leave the tactical screen.
|
||||||
|
*/
|
||||||
|
class CrowFlyAwayPlan : public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
CrowFlyAwayPlan(SOLDIERTYPE* npc);
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
/// The plan is deleted with the crow once it leaves; 'done' is meaningless, flying away cannot be interrupted
|
||||||
|
virtual bool done() const {return false;}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LEGACY_CREATURE_PLAN_H_
|
||||||
|
#define LEGACY_CREATURE_PLAN_H_
|
||||||
|
|
||||||
|
#include "Plan.h"
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
/**@class LegacyCreaturePlan
|
||||||
|
* @brief Component/Concrete Product. Wrapper/Re-Write of CreatureDecideAction()
|
||||||
|
*
|
||||||
|
* This plan began as a simple forwarding object for CreatureDecideAction(), and will, in the course of the AI redesign,
|
||||||
|
* be split into elementary NPC actions. It is as such only a intermediate product used to bring structure where
|
||||||
|
* the is currently none.
|
||||||
|
*/
|
||||||
|
class LegacyCreaturePlan: public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
LegacyCreaturePlan(SOLDIERTYPE* npc);
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
virtual bool done() const {return false;}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LEGACY_ZOMBIE_PLAN_H_
|
||||||
|
#define LEGACY_ZOMBIE_PLAN_H_
|
||||||
|
|
||||||
|
#include "Plan.h"
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
/**@class LegacyZombiePlan
|
||||||
|
* @brief Component/Concrete Product. Wrapper/Re-Write of ZombieDecideAction()
|
||||||
|
*
|
||||||
|
* This plan began as a simple forwarding object for ZombieDecideAction(), and will, in the course of the AI redesign,
|
||||||
|
* be split into elementary NPC actions. It is as such only a intermediate product used to bring structure where
|
||||||
|
* the is currently none.
|
||||||
|
*/
|
||||||
|
class LegacyZombiePlan: public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
LegacyZombiePlan(SOLDIERTYPE* npc);
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
virtual bool done() const {return false;}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef PLAN_LIST_H_
|
||||||
|
#define PLAN_LIST_H_
|
||||||
|
|
||||||
|
#include "Plan.h"
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
/**@class PlanList
|
||||||
|
* @brief Composition/Abstract Product. Used to concatenate plans.
|
||||||
|
*
|
||||||
|
* Plan lists can comprise an arbitrary number of sub-plans, executed in the order they were added via
|
||||||
|
* add_subplan(), and switched to the next one once the done()-flag of a sub-plan becomes true.
|
||||||
|
*/
|
||||||
|
class PlanList : public Plan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// The sub-plan sequence
|
||||||
|
std::deque<Plan*> subplans_;
|
||||||
|
public:
|
||||||
|
PlanList(SOLDIERTYPE* npc);
|
||||||
|
/// Add a plan to the list of sub-plans
|
||||||
|
virtual void add_subplan(Plan* P);
|
||||||
|
/// Execute the next plan in the list
|
||||||
|
virtual void execute(PlanInputData& environment);
|
||||||
|
/// Done will be set once the last plan is marked as done()
|
||||||
|
virtual bool done() const;
|
||||||
|
virtual ~PlanList();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include "../include/AbstractPlanFactory.h"
|
||||||
|
#include "../../Tactical/Soldier Control.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
AIInputData::AIInputData(Auditive , int noise_maker, int grid_no, int level, int volume, int type)
|
||||||
|
: noise_maker_(noise_maker),
|
||||||
|
grid_no_(grid_no),
|
||||||
|
level_(level),
|
||||||
|
volume_(volume),
|
||||||
|
type_(type)
|
||||||
|
{
|
||||||
|
event_type_ = auditive_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIInputData::AIInputData(Visual, SOLDIERTYPE* opponent, int grid_no, int level, int caller1, int caller2)
|
||||||
|
: opponent_(opponent),
|
||||||
|
grid_no_(grid_no),
|
||||||
|
level_(level),
|
||||||
|
caller1_(caller1),
|
||||||
|
caller2_(caller2)
|
||||||
|
{
|
||||||
|
event_type_ = visual_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIInputData::AIInputData()
|
||||||
|
: event_type_(no_event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const AIInputData& i)
|
||||||
|
{
|
||||||
|
if(i.event_type_ == AIInputData::no_event)
|
||||||
|
return os<<"no_event";
|
||||||
|
if(i.event_type_ == AIInputData::auditive_event)
|
||||||
|
return os<<"sound: "<<i.noise_maker_<<" made a sound at "<<i.grid_no_<<", lvl "<<i.level_<<" vol "<<i.volume_<<" type "<<i.type_;
|
||||||
|
if(i.event_type_ == AIInputData::visual_event)
|
||||||
|
return os<<"visual: "<<(int)i.opponent_->ubID<<" was seen at "<<i.grid_no_<<", lvl "<<i.level_<<" caller1 "<<i.caller1_<<" caller2 "<<i.caller2_;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/CrowPlan.h"
|
||||||
|
#include "../../Tactical/Soldier Control.h" // defines SOLDIERTYPE
|
||||||
|
#include "../../Tactical/Animation Control.h" // defines CROW_FLY
|
||||||
|
#include "../../Tactical/Soldier Add.h" // FindGridNoFromSweetSpot()
|
||||||
|
#include "../../TacticalAI/ai.h" // AI_ACTION_...
|
||||||
|
#include "../../TacticalAI/AIInternals.h" // AIDEBUGMSG
|
||||||
|
#include "../../Tactical/Rotting Corpses.h" // FindNearestRottingCorpse()
|
||||||
|
#include "../../TileEngine/Isometric Utils.h" // TileIsOutOfBounds()
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
CrowFlyAwayPlan::CrowFlyAwayPlan(SOLDIERTYPE* npc)
|
||||||
|
: Plan(npc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrowFlyAwayPlan::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
CrowsFlyAway( get_npc()->bTeam );
|
||||||
|
}
|
||||||
|
|
||||||
|
CrowSeekCorpsePlan::CrowSeekCorpsePlan(SOLDIERTYPE* npc)
|
||||||
|
: Plan(npc),
|
||||||
|
corpse_grid_(FindNearestRottingCorpse(npc))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrowSeekCorpsePlan::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
get_npc()->aiData.bAction = AI_ACTION_NONE;
|
||||||
|
if(TileIsOutOfBounds(corpse_grid_))
|
||||||
|
return;
|
||||||
|
// Walk to nearest corpse
|
||||||
|
UINT8 unused;
|
||||||
|
get_npc()->aiData.usActionData = FindGridNoFromSweetSpot( get_npc(), corpse_grid_, 4, &unused);
|
||||||
|
if(TileIsOutOfBounds(get_npc()->aiData.usActionData))
|
||||||
|
return;
|
||||||
|
get_npc()->aiData.bAction = AI_ACTION_GET_CLOSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CrowSeekCorpsePlan::done() const
|
||||||
|
{
|
||||||
|
return SpacesAway( get_npc()->sGridNo, corpse_grid_ ) < 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CrowSeekCorpsePlan::get_corpse_grid() const
|
||||||
|
{
|
||||||
|
return corpse_grid_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CrowPeckPlan::CrowPeckPlan(SOLDIERTYPE* npc, int corpse_grid)
|
||||||
|
: Plan(npc), corpse_grid_(corpse_grid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrowPeckPlan::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
get_npc()->aiData.bAction = AI_ACTION_NONE;
|
||||||
|
INT16 sFacingDir;
|
||||||
|
if (TileIsOutOfBounds(corpse_grid_))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Change facing
|
||||||
|
sFacingDir = GetDirectionFromGridNo( corpse_grid_, get_npc() );
|
||||||
|
if ( sFacingDir != get_npc()->ubDirection )
|
||||||
|
{
|
||||||
|
get_npc()->aiData.usActionData = sFacingDir;
|
||||||
|
get_npc()->aiData.bAction = AI_ACTION_CHANGE_FACING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!environment.turn_based())
|
||||||
|
{
|
||||||
|
get_npc()->aiData.usActionData = 30000;
|
||||||
|
get_npc()->aiData.bAction = AI_ACTION_WAIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tactical
|
||||||
|
} // namespace AI
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/LegacyCreaturePlan.h"
|
||||||
|
#include "../../Tactical/Soldier Control.h"
|
||||||
|
|
||||||
|
INT8 CreatureDecideAction( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
LegacyCreaturePlan::LegacyCreaturePlan(SOLDIERTYPE* npc)
|
||||||
|
: Plan(npc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LegacyCreaturePlan::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
get_npc()->aiData.bAction = CreatureDecideAction( get_npc() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author feynman (bears-pit.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/LegacyZombiePlan.h"
|
||||||
|
#include "../../Tactical/Soldier Control.h" // definition of SOLDIERTYPE
|
||||||
|
|
||||||
|
INT8 ZombieDecideAction( SOLDIERTYPE *pSoldier ); // defined in DecideAction.cpp
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
LegacyZombiePlan::LegacyZombiePlan(SOLDIERTYPE* npc)
|
||||||
|
: Plan(npc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LegacyZombiePlan::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
get_npc()->aiData.bAction = ZombieDecideAction(get_npc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include "../include/Plan.h"
|
||||||
|
|
||||||
|
#include "../../TacticalAI/ai.h"
|
||||||
|
#include "../../TacticalAI/AIInternals.h" // ACTING_ON_SCHEDULE
|
||||||
|
#include "../../TacticalAI/NPC.h" // NPCReachedDestination
|
||||||
|
#include "../../Tactical/Animation Control.h" // defines ANIM_...
|
||||||
|
#include "../../Tactical/Soldier Macros.h" // CREATURE_OR_BLOODCAT
|
||||||
|
#include "../../Tactical/opplist.h" // EndMuzzleFlash
|
||||||
|
#include "../../Tactical/Dialogue Control.h" // DialogueQueueIsEmpty
|
||||||
|
#include "../../TileEngine/Isometric Utils.h" // defines NOWHERE
|
||||||
|
#include "../../Utils/Debug Control.h" // LiveMessage
|
||||||
|
#include "../../Utils/Font Control.h" // ScreenMsg about deadlock
|
||||||
|
#include "../../Utils/message.h" // ditto
|
||||||
|
#include "../../TileEngine/Render Fun.h" // defines InARoom
|
||||||
|
#include "../../Strategic/quests.h" // IN_BROTHEL
|
||||||
|
|
||||||
|
// FIXME uagh, these need to go
|
||||||
|
extern BOOLEAN gfUIInDeadlock;
|
||||||
|
extern UINT8 gUIDeadlockedSoldier;
|
||||||
|
|
||||||
|
void HandleAITacticalTraversal(SOLDIERTYPE* pSoldier); // defined in TacticalAI/AIMain.cpp
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
PlanInputData::PlanInputData(bool turn_based, const TacticalStatusType& tactical_status)
|
||||||
|
: turn_based_(turn_based),
|
||||||
|
tactical_status_(tactical_status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Plan::Plan(SOLDIERTYPE* npc)
|
||||||
|
: npc_(npc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#include "../include/PlanList.h"
|
||||||
|
#include "../../TacticalAI/AIInternals.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace AI
|
||||||
|
{
|
||||||
|
namespace tactical
|
||||||
|
{
|
||||||
|
PlanList::PlanList(SOLDIERTYPE* npc)
|
||||||
|
: Plan(npc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PlanList::~PlanList()
|
||||||
|
{
|
||||||
|
for(std::deque<Plan*>::iterator subplan_iter(subplans_.begin()); subplan_iter != subplans_.end(); ++subplan_iter)
|
||||||
|
delete *subplan_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanList::add_subplan(Plan* p)
|
||||||
|
{
|
||||||
|
if(!p)
|
||||||
|
throw std::logic_error("No empty plans in PlanList allowed");
|
||||||
|
subplans_.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanList::execute(PlanInputData& environment)
|
||||||
|
{
|
||||||
|
while(!subplans_.empty() && subplans_.front()->done())
|
||||||
|
{
|
||||||
|
delete subplans_.front();
|
||||||
|
subplans_.pop_front();
|
||||||
|
DEBUGAIMSG("Plan done, switching to next...");
|
||||||
|
}
|
||||||
|
if(subplans_.empty())
|
||||||
|
return;
|
||||||
|
subplans_.front()->execute(environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlanList::done() const
|
||||||
|
{
|
||||||
|
return subplans_.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user