- added initial code for switching dropped network players to AI (currently hard coded to normal CPU)
This commit is contained in:
parent
3d4ccb460c
commit
7564635643
|
@ -10,20 +10,16 @@
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
#include <ctime>
|
|
||||||
#include "ai_interface.h"
|
#include "ai_interface.h"
|
||||||
#include "ai_rule.h"
|
#include "ai_rule.h"
|
||||||
#include "unit_type.h"
|
#include "unit_type.h"
|
||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
#include "program.h"
|
|
||||||
#include "config.h"
|
|
||||||
//#include <limits>
|
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
using namespace Shared::Graphics;
|
using namespace Shared::Graphics;
|
||||||
using namespace Shared::Util;
|
using namespace Shared::Util;
|
||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest { namespace Game {
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class ProduceTask
|
// class ProduceTask
|
||||||
|
@ -111,42 +107,50 @@ string UpgradeTask::toString() const{
|
||||||
// class Ai
|
// class Ai
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
void Ai::init(AiInterface *aiInterface){
|
void Ai::init(AiInterface *aiInterface, int useStartLocation) {
|
||||||
this->aiInterface= aiInterface;
|
this->aiInterface= aiInterface;
|
||||||
startLoc= random.randRange(0, aiInterface->getMapMaxPlayers()-1);
|
if(useStartLocation == -1) {
|
||||||
upgradeCount= 0;
|
startLoc = random.randRange(0, aiInterface->getMapMaxPlayers()-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
startLoc = useStartLocation;
|
||||||
|
}
|
||||||
minWarriors= minMinWarriors;
|
minWarriors= minMinWarriors;
|
||||||
randomMinWarriorsReached= false;
|
randomMinWarriorsReached= false;
|
||||||
//add ai rules
|
//add ai rules
|
||||||
aiRules.resize(14);
|
aiRules.clear();
|
||||||
aiRules[0]= new AiRuleWorkerHarvest(this);
|
aiRules.push_back(new AiRuleWorkerHarvest(this));
|
||||||
aiRules[1]= new AiRuleRefreshHarvester(this);
|
aiRules.push_back(new AiRuleRefreshHarvester(this));
|
||||||
aiRules[2]= new AiRuleScoutPatrol(this);
|
aiRules.push_back(new AiRuleScoutPatrol(this));
|
||||||
aiRules[3]= new AiRuleReturnBase(this);
|
aiRules.push_back(new AiRuleReturnBase(this));
|
||||||
aiRules[4]= new AiRuleMassiveAttack(this);
|
aiRules.push_back(new AiRuleMassiveAttack(this));
|
||||||
aiRules[5]= new AiRuleAddTasks(this);
|
aiRules.push_back(new AiRuleAddTasks(this));
|
||||||
aiRules[6]= new AiRuleProduceResourceProducer(this);
|
aiRules.push_back(new AiRuleProduceResourceProducer(this));
|
||||||
aiRules[7]= new AiRuleBuildOneFarm(this);
|
aiRules.push_back(new AiRuleBuildOneFarm(this));
|
||||||
aiRules[8]= new AiRuleProduce(this);
|
aiRules.push_back(new AiRuleProduce(this));
|
||||||
aiRules[9]= new AiRuleBuild(this);
|
aiRules.push_back(new AiRuleBuild(this));
|
||||||
aiRules[10]= new AiRuleUpgrade(this);
|
aiRules.push_back(new AiRuleUpgrade(this));
|
||||||
aiRules[11]= new AiRuleExpand(this);
|
aiRules.push_back(new AiRuleExpand(this));
|
||||||
aiRules[12]= new AiRuleRepair(this);
|
aiRules.push_back(new AiRuleRepair(this));
|
||||||
aiRules[13]= new AiRuleRepair(this);
|
aiRules.push_back(new AiRuleRepair(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ai::~Ai(){
|
Ai::~Ai() {
|
||||||
deleteValues(tasks.begin(), tasks.end());
|
deleteValues(tasks.begin(), tasks.end());
|
||||||
deleteValues(aiRules.begin(), aiRules.end());
|
deleteValues(aiRules.begin(), aiRules.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ai::update(){
|
void Ai::update() {
|
||||||
//process ai rules
|
//process ai rules
|
||||||
for(AiRules::iterator it= aiRules.begin(); it!=aiRules.end(); ++it){
|
for(int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) {
|
||||||
if((aiInterface->getTimer() % ((*it)->getTestInterval()*GameConstants::updateFps/1000))==0){
|
AiRule *rule = aiRules[ruleIdx];
|
||||||
if((*it)->test()){
|
if(rule == NULL) {
|
||||||
aiInterface->printLog(3, intToStr(1000*aiInterface->getTimer()/GameConstants::updateFps) + ": Executing rule: " + (*it)->getName() + '\n');
|
throw runtime_error("rule == NULL");
|
||||||
(*it)->execute();
|
}
|
||||||
|
if((aiInterface->getTimer() % (rule->getTestInterval() * GameConstants::updateFps / 1000)) == 0){
|
||||||
|
if(rule->test()) {
|
||||||
|
aiInterface->printLog(3, intToStr(1000 * aiInterface->getTimer() / GameConstants::updateFps) + ": Executing rule: " + rule->getName() + '\n');
|
||||||
|
rule->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
/// Main AI class
|
/// Main AI class
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class Ai{
|
class Ai {
|
||||||
private:
|
private:
|
||||||
static const int harvesterPercent= 30;
|
static const int harvesterPercent= 30;
|
||||||
static const int maxBuildRadius= 40;
|
static const int maxBuildRadius= 40;
|
||||||
|
@ -123,7 +123,7 @@ private:
|
||||||
static const int villageRadius= 15;
|
static const int villageRadius= 15;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum ResourceUsage{
|
enum ResourceUsage {
|
||||||
ruHarvester,
|
ruHarvester,
|
||||||
ruWarrior,
|
ruWarrior,
|
||||||
ruBuilding,
|
ruBuilding,
|
||||||
|
@ -131,7 +131,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef vector<AiRule*> AiRules;
|
//typedef vector<AiRule*> AiRules;
|
||||||
|
typedef vector<AiRule *> AiRules;
|
||||||
typedef list<const Task*> Tasks;
|
typedef list<const Task*> Tasks;
|
||||||
typedef deque<Vec2i> Positions;
|
typedef deque<Vec2i> Positions;
|
||||||
|
|
||||||
|
@ -140,7 +141,6 @@ private:
|
||||||
AiRules aiRules;
|
AiRules aiRules;
|
||||||
int startLoc;
|
int startLoc;
|
||||||
bool randomMinWarriorsReached;
|
bool randomMinWarriorsReached;
|
||||||
int upgradeCount;
|
|
||||||
Tasks tasks;
|
Tasks tasks;
|
||||||
Positions expansionPositions;
|
Positions expansionPositions;
|
||||||
RandomGen random;
|
RandomGen random;
|
||||||
|
@ -148,7 +148,7 @@ private:
|
||||||
public:
|
public:
|
||||||
int minWarriors;
|
int minWarriors;
|
||||||
~Ai();
|
~Ai();
|
||||||
void init(AiInterface *aiInterface);
|
void init(AiInterface *aiInterface,int useStartLocation=-1);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
//state requests
|
//state requests
|
||||||
|
|
|
@ -31,7 +31,7 @@ using namespace Shared::Graphics;
|
||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex){
|
AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
this->world= game.getWorld();
|
this->world= game.getWorld();
|
||||||
|
@ -44,7 +44,7 @@ AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex){
|
||||||
timer= 0;
|
timer= 0;
|
||||||
|
|
||||||
//init ai
|
//init ai
|
||||||
ai.init(this);
|
ai.init(this,useStartLocation);
|
||||||
|
|
||||||
//config
|
//config
|
||||||
logLevel= Config::getInstance().getInt("AiLog");
|
logLevel= Config::getInstance().getInt("AiLog");
|
||||||
|
|
|
@ -48,7 +48,7 @@ private:
|
||||||
int logLevel;
|
int logLevel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AiInterface(Game &game, int factionIndex, int teamIndex);
|
AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation=-1);
|
||||||
|
|
||||||
//main
|
//main
|
||||||
void update();
|
void update();
|
||||||
|
|
|
@ -633,16 +633,19 @@ void Game::update() {
|
||||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
|
|
||||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||||
//update
|
|
||||||
for(int i = 0; i < updateLoops; ++i) {
|
|
||||||
chrono.start();
|
|
||||||
Renderer &renderer= Renderer::getInstance();
|
|
||||||
|
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
||||||
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
||||||
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
||||||
NetworkRole role = networkManager.getNetworkRole();
|
NetworkRole role = networkManager.getNetworkRole();
|
||||||
|
|
||||||
|
// Check to see if we are playing a network game and if any players
|
||||||
|
// have disconnected?
|
||||||
|
ReplaceDisconnectedNetworkPlayersWithAI(isNetworkGame, role);
|
||||||
|
|
||||||
|
//update
|
||||||
|
for(int i = 0; i < updateLoops; ++i) {
|
||||||
|
chrono.start();
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
//AiInterface
|
//AiInterface
|
||||||
for(int i = 0; i < world.getFactionCount(); ++i) {
|
for(int i = 0; i < world.getFactionCount(); ++i) {
|
||||||
Faction *faction = world.getFaction(i);
|
Faction *faction = world.getFaction(i);
|
||||||
|
@ -683,6 +686,7 @@ void Game::update() {
|
||||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [weather particle updating]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [weather particle updating]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
if(chrono.getMillis() > 0) chrono.start();
|
if(chrono.getMillis() > 0) chrono.start();
|
||||||
|
|
||||||
|
Renderer &renderer= Renderer::getInstance();
|
||||||
renderer.updateParticleManager(rsGame,avgRenderFps);
|
renderer.updateParticleManager(rsGame,avgRenderFps);
|
||||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [particle manager updating]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [particle manager updating]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
if(chrono.getMillis() > 0) chrono.start();
|
if(chrono.getMillis() > 0) chrono.start();
|
||||||
|
@ -726,6 +730,34 @@ void Game::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role) {
|
||||||
|
if(role == nrServer && isNetworkGame == true) {
|
||||||
|
Logger &logger= Logger::getInstance();
|
||||||
|
ServerInterface *server = NetworkManager::getInstance().getServerInterface();
|
||||||
|
|
||||||
|
for(int i = 0; i < world.getFactionCount(); ++i) {
|
||||||
|
Faction *faction = world.getFaction(i);
|
||||||
|
if( faction->getControlType() == ctNetwork ||
|
||||||
|
faction->getControlType() == ctNetworkCpuEasy ||
|
||||||
|
faction->getControlType() == ctNetworkCpu ||
|
||||||
|
faction->getControlType() == ctNetworkCpuUltra ||
|
||||||
|
faction->getControlType() == ctNetworkCpuMega) {
|
||||||
|
ConnectionSlot *slot = server->getSlot(i);
|
||||||
|
if(aiInterfaces[i] == NULL && (slot == NULL || slot->isConnected() == false)) {
|
||||||
|
|
||||||
|
faction->setControlType(ctCpu);
|
||||||
|
aiInterfaces[i] = new AiInterface(*this, i, faction->getTeam(), faction->getStartLocationIndex());
|
||||||
|
logger.add("Creating AI for faction " + intToStr(i), true);
|
||||||
|
|
||||||
|
char szBuf[255]="";
|
||||||
|
sprintf(szBuf,"Player #%d [%s] has disconnected, switching player to AI mode!",i+1,this->gameSettings.getNetworkPlayerName(i).c_str());
|
||||||
|
server->sendTextMessage(szBuf,-1,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Game::updateCamera(){
|
void Game::updateCamera(){
|
||||||
gameCamera.update();
|
gameCamera.update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,6 +186,8 @@ private:
|
||||||
|
|
||||||
void renderWorker();
|
void renderWorker();
|
||||||
static int ErrorDisplayMessage(const char *msg, bool exitApp);
|
static int ErrorDisplayMessage(const char *msg, bool exitApp);
|
||||||
|
|
||||||
|
void ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
|
@ -141,6 +141,8 @@ public:
|
||||||
void incResourceAmount(const ResourceType *rt, int amount);
|
void incResourceAmount(const ResourceType *rt, int amount);
|
||||||
void setResourceBalance(const ResourceType *rt, int balance);
|
void setResourceBalance(const ResourceType *rt, int balance);
|
||||||
|
|
||||||
|
void setControlType(ControlType value) { control = value; }
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user