2018-02-01 13:39:41 -06:00

432 lines
8.5 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 = 20;
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