- 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 <ctime>
|
||||
#include "ai_interface.h"
|
||||
#include "ai_rule.h"
|
||||
#include "unit_type.h"
|
||||
#include "unit.h"
|
||||
#include "program.h"
|
||||
#include "config.h"
|
||||
//#include <limits>
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace Shared::Graphics;
|
||||
using namespace Shared::Util;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
namespace Glest { namespace Game {
|
||||
|
||||
// =====================================================
|
||||
// class ProduceTask
|
||||
|
@ -111,42 +107,50 @@ string UpgradeTask::toString() const{
|
|||
// class Ai
|
||||
// =====================================================
|
||||
|
||||
void Ai::init(AiInterface *aiInterface){
|
||||
void Ai::init(AiInterface *aiInterface, int useStartLocation) {
|
||||
this->aiInterface= aiInterface;
|
||||
startLoc= random.randRange(0, aiInterface->getMapMaxPlayers()-1);
|
||||
upgradeCount= 0;
|
||||
if(useStartLocation == -1) {
|
||||
startLoc = random.randRange(0, aiInterface->getMapMaxPlayers()-1);
|
||||
}
|
||||
else {
|
||||
startLoc = useStartLocation;
|
||||
}
|
||||
minWarriors= minMinWarriors;
|
||||
randomMinWarriorsReached= false;
|
||||
//add ai rules
|
||||
aiRules.resize(14);
|
||||
aiRules[0]= new AiRuleWorkerHarvest(this);
|
||||
aiRules[1]= new AiRuleRefreshHarvester(this);
|
||||
aiRules[2]= new AiRuleScoutPatrol(this);
|
||||
aiRules[3]= new AiRuleReturnBase(this);
|
||||
aiRules[4]= new AiRuleMassiveAttack(this);
|
||||
aiRules[5]= new AiRuleAddTasks(this);
|
||||
aiRules[6]= new AiRuleProduceResourceProducer(this);
|
||||
aiRules[7]= new AiRuleBuildOneFarm(this);
|
||||
aiRules[8]= new AiRuleProduce(this);
|
||||
aiRules[9]= new AiRuleBuild(this);
|
||||
aiRules[10]= new AiRuleUpgrade(this);
|
||||
aiRules[11]= new AiRuleExpand(this);
|
||||
aiRules[12]= new AiRuleRepair(this);
|
||||
aiRules[13]= new AiRuleRepair(this);
|
||||
aiRules.clear();
|
||||
aiRules.push_back(new AiRuleWorkerHarvest(this));
|
||||
aiRules.push_back(new AiRuleRefreshHarvester(this));
|
||||
aiRules.push_back(new AiRuleScoutPatrol(this));
|
||||
aiRules.push_back(new AiRuleReturnBase(this));
|
||||
aiRules.push_back(new AiRuleMassiveAttack(this));
|
||||
aiRules.push_back(new AiRuleAddTasks(this));
|
||||
aiRules.push_back(new AiRuleProduceResourceProducer(this));
|
||||
aiRules.push_back(new AiRuleBuildOneFarm(this));
|
||||
aiRules.push_back(new AiRuleProduce(this));
|
||||
aiRules.push_back(new AiRuleBuild(this));
|
||||
aiRules.push_back(new AiRuleUpgrade(this));
|
||||
aiRules.push_back(new AiRuleExpand(this));
|
||||
aiRules.push_back(new AiRuleRepair(this));
|
||||
aiRules.push_back(new AiRuleRepair(this));
|
||||
}
|
||||
|
||||
Ai::~Ai(){
|
||||
Ai::~Ai() {
|
||||
deleteValues(tasks.begin(), tasks.end());
|
||||
deleteValues(aiRules.begin(), aiRules.end());
|
||||
}
|
||||
|
||||
void Ai::update(){
|
||||
void Ai::update() {
|
||||
//process ai rules
|
||||
for(AiRules::iterator it= aiRules.begin(); it!=aiRules.end(); ++it){
|
||||
if((aiInterface->getTimer() % ((*it)->getTestInterval()*GameConstants::updateFps/1000))==0){
|
||||
if((*it)->test()){
|
||||
aiInterface->printLog(3, intToStr(1000*aiInterface->getTimer()/GameConstants::updateFps) + ": Executing rule: " + (*it)->getName() + '\n');
|
||||
(*it)->execute();
|
||||
for(int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) {
|
||||
AiRule *rule = aiRules[ruleIdx];
|
||||
if(rule == NULL) {
|
||||
throw runtime_error("rule == NULL");
|
||||
}
|
||||
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
|
||||
// ===============================
|
||||
|
||||
class Ai{
|
||||
class Ai {
|
||||
private:
|
||||
static const int harvesterPercent= 30;
|
||||
static const int maxBuildRadius= 40;
|
||||
|
@ -123,7 +123,7 @@ private:
|
|||
static const int villageRadius= 15;
|
||||
|
||||
public:
|
||||
enum ResourceUsage{
|
||||
enum ResourceUsage {
|
||||
ruHarvester,
|
||||
ruWarrior,
|
||||
ruBuilding,
|
||||
|
@ -131,7 +131,8 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
typedef vector<AiRule*> AiRules;
|
||||
//typedef vector<AiRule*> AiRules;
|
||||
typedef vector<AiRule *> AiRules;
|
||||
typedef list<const Task*> Tasks;
|
||||
typedef deque<Vec2i> Positions;
|
||||
|
||||
|
@ -140,7 +141,6 @@ private:
|
|||
AiRules aiRules;
|
||||
int startLoc;
|
||||
bool randomMinWarriorsReached;
|
||||
int upgradeCount;
|
||||
Tasks tasks;
|
||||
Positions expansionPositions;
|
||||
RandomGen random;
|
||||
|
@ -148,12 +148,12 @@ private:
|
|||
public:
|
||||
int minWarriors;
|
||||
~Ai();
|
||||
void init(AiInterface *aiInterface);
|
||||
void init(AiInterface *aiInterface,int useStartLocation=-1);
|
||||
void update();
|
||||
|
||||
//state requests
|
||||
AiInterface *getAiInterface() const {return aiInterface;}
|
||||
RandomGen* getRandom() {return &random;}
|
||||
RandomGen* getRandom() {return &random;}
|
||||
int getCountOfType(const UnitType *ut);
|
||||
|
||||
int getCountOfClass(UnitClass uc);
|
||||
|
|
|
@ -31,7 +31,7 @@ using namespace Shared::Graphics;
|
|||
|
||||
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__);
|
||||
|
||||
this->world= game.getWorld();
|
||||
|
@ -44,7 +44,7 @@ AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex){
|
|||
timer= 0;
|
||||
|
||||
//init ai
|
||||
ai.init(this);
|
||||
ai.init(this,useStartLocation);
|
||||
|
||||
//config
|
||||
logLevel= Config::getInstance().getInt("AiLog");
|
||||
|
|
|
@ -48,7 +48,7 @@ private:
|
|||
int logLevel;
|
||||
|
||||
public:
|
||||
AiInterface(Game &game, int factionIndex, int teamIndex);
|
||||
AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation=-1);
|
||||
|
||||
//main
|
||||
void update();
|
||||
|
|
|
@ -633,15 +633,18 @@ 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());
|
||||
|
||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
||||
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
||||
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();
|
||||
Renderer &renderer= Renderer::getInstance();
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
||||
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
||||
NetworkRole role = networkManager.getNetworkRole();
|
||||
|
||||
//AiInterface
|
||||
for(int i = 0; i < world.getFactionCount(); ++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) chrono.start();
|
||||
|
||||
Renderer &renderer= Renderer::getInstance();
|
||||
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) 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(){
|
||||
gameCamera.update();
|
||||
}
|
||||
|
|
|
@ -186,6 +186,8 @@ private:
|
|||
|
||||
void renderWorker();
|
||||
static int ErrorDisplayMessage(const char *msg, bool exitApp);
|
||||
|
||||
void ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role);
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -141,6 +141,8 @@ public:
|
|||
void incResourceAmount(const ResourceType *rt, int amount);
|
||||
void setResourceBalance(const ResourceType *rt, int balance);
|
||||
|
||||
void setControlType(ControlType value) { control = value; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue