MegaGlest/source/glest_game/ai/ai.h

248 lines
6.3 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _GLEST_GAME_AI_H_
#define _GLEST_GAME_AI_H_
#include <vector>
#include <list>
#include "world.h"
#include "commander.h"
#include "command.h"
#include "randomgen.h"
#include "leak_dumper.h"
using std::deque;
using std::vector;
using std::list;
using Shared::Util::RandomGen;
namespace Glest{ namespace Game{
class AiInterface;
class AiRule;
// =====================================================
// class Task
//
/// An action that has to be performed by the IA
// =====================================================
enum TaskClass{
tcProduce,
tcBuild,
tcUpgrade
};
class Task{
protected:
TaskClass taskClass;
public:
Task();
virtual ~Task(){}
TaskClass getClass() const {return taskClass;}
virtual string toString() const= 0;
virtual void saveGame(XmlNode *rootNode) const = 0;
};
// ==================== ProduceTask ====================
class ProduceTask: public Task{
private:
UnitClass unitClass;
const UnitType *unitType;
const ResourceType *resourceType;
ProduceTask();
public:
explicit ProduceTask(UnitClass unitClass);
explicit ProduceTask(const UnitType *unitType);
explicit ProduceTask(const ResourceType *resourceType);
UnitClass getUnitClass() const {return unitClass;}
const UnitType *getUnitType() const {return unitType;}
const ResourceType *getResourceType() const {return resourceType;}
virtual string toString() const;
virtual void saveGame(XmlNode *rootNode) const;
static ProduceTask * loadGame(const XmlNode *rootNode, Faction *faction);
};
// ==================== BuildTask ====================
class BuildTask: public Task{
private:
const UnitType *unitType;
const ResourceType *resourceType;
bool forcePos;
Vec2i pos;
BuildTask();
public:
explicit BuildTask(const UnitType *unitType);
explicit BuildTask(const ResourceType *resourceType);
BuildTask(const UnitType *unitType, const Vec2i &pos);
const UnitType *getUnitType() const {return unitType;}
const ResourceType *getResourceType() const {return resourceType;}
bool getForcePos() const {return forcePos;}
Vec2i getPos() const {return pos;}
virtual string toString() const;
virtual void saveGame(XmlNode *rootNode) const;
static BuildTask * loadGame(const XmlNode *rootNode, Faction *faction);
};
// ==================== UpgradeTask ====================
class UpgradeTask: public Task{
private:
const UpgradeType *upgradeType;
UpgradeTask();
public:
explicit UpgradeTask(const UpgradeType *upgradeType);
const UpgradeType *getUpgradeType() const {return upgradeType;}
virtual string toString() const;
virtual void saveGame(XmlNode *rootNode) const;
static UpgradeTask * loadGame(const XmlNode *rootNode, Faction *faction);
};
// ===============================
// class AI
//
/// Main AI class
// ===============================
class Ai {
private:
int maxBuildRadius;
int minMinWarriors;
int minMinWarriorsExpandCpuEasy;
int minMinWarriorsExpandCpuMega;
int minMinWarriorsExpandCpuUltra;
int minMinWarriorsExpandCpuNormal;
int maxMinWarriors;
int maxExpansions;
int villageRadius;
int scoutResourceRange;
int minWorkerAttackersHarvesting;
int minBuildSpacing;
public:
enum ResourceUsage {
ruHarvester,
ruWarrior,
ruBuilding,
ruUpgrade
};
private:
typedef vector<AiRule *> AiRules;
typedef list<const Task*> Tasks;
typedef deque<Vec2i> Positions;
private:
AiInterface *aiInterface;
AiRules aiRules;
int startLoc;
bool randomMinWarriorsReached;
Tasks tasks;
Positions expansionPositions;
RandomGen random;
std::map<int,int> factionSwitchTeamRequestCount;
int minWarriors;
bool getAdjacentUnits(std::map<float, std::map<int, const Unit *> > &signalAdjacentUnits, const Unit *unit);
public:
Ai() {
// Defaults that used to be static which can now be overriden
maxBuildRadius = 40;
minMinWarriors = 7;
minMinWarriorsExpandCpuEasy = 1;
minMinWarriorsExpandCpuMega = 3;
minMinWarriorsExpandCpuUltra = 3;
minMinWarriorsExpandCpuNormal = 3;
maxMinWarriors = 20;
maxExpansions = 2;
villageRadius = 15;
scoutResourceRange = 20;
minWorkerAttackersHarvesting = 3;
minBuildSpacing = 1;
aiInterface = NULL;
startLoc = -1;
randomMinWarriorsReached = false;
minWarriors = 0;
}
~Ai();
void init(AiInterface *aiInterface,int useStartLocation=-1);
void update();
//state requests
AiInterface *getAiInterface() const {return aiInterface;}
RandomGen* getRandom();
int getCountOfType(const UnitType *ut);
int getMinWarriors() const { return minWarriors; }
int getCountOfClass(UnitClass uc,UnitClass *additionalUnitClassToExcludeFromCount=NULL);
float getRatioOfClass(UnitClass uc,UnitClass *additionalUnitClassToExcludeFromCount=NULL);
const ResourceType *getNeededResource(int unitIndex);
bool isStableBase();
bool findPosForBuilding(const UnitType* building, const Vec2i &searchPos, Vec2i &pos);
bool findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly);
bool findAbleUnit(int *unitIndex, CommandClass ability, CommandClass currentCommand);
//vector<int> findUnitsDoingCommand(CommandClass currentCommand);
vector<int> findUnitsHarvestingResourceType(const ResourceType *rt);
bool beingAttacked(Vec2i &pos, Field &field, int radius);
//tasks
void addTask(const Task *task);
void addPriorityTask(const Task *task);
bool anyTask();
const Task *getTask() const;
void removeTask(const Task *task);
void retryTask(const Task *task);
//expansions
void addExpansion(const Vec2i &pos);
Vec2i getRandomHomePosition();
//actions
void sendScoutPatrol();
void massiveAttack(const Vec2i &pos, Field field, bool ultraAttack= false);
void returnBase(int unitIndex);
void harvest(int unitIndex);
bool haveBlockedUnits();
void unblockUnits();
bool outputAIBehaviourToConsole() const;
void saveGame(XmlNode *rootNode) const;
void loadGame(const XmlNode *rootNode, Faction *faction);
};
}}//end namespace
#endif