summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ai/ai.c15
-rw-r--r--ai/ai.h2
-rw-r--r--ai/default/default.c18
-rw-r--r--ai/trolly/trolly.c28
-rw-r--r--economy.c2
-rw-r--r--network_client.c23
-rw-r--r--openttd.c17
-rw-r--r--players.c16
8 files changed, 64 insertions, 57 deletions
diff --git a/ai/ai.c b/ai/ai.c
index b3d3af123..b7271d2ce 100644
--- a/ai/ai.c
+++ b/ai/ai.c
@@ -87,7 +87,7 @@ int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
/* First, do a test-run to see if we can do this */
res = DoCommandByTile(tile, p1, p2, flags & ~DC_EXEC, procc);
/* The command failed, or you didn't want to execute, or you are quering, return */
- if ((res & CMD_ERROR) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST))
+ if ((CmdFailed(res)) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST))
return res;
/* If we did a DC_EXEC, and the command did not return an error, execute it
@@ -162,10 +162,10 @@ void AI_RunGameLoop(void)
return;
/* Check for AI-client (so joining a network with an AI) */
- if (_ai.network_client) {
+ if (_ai.network_client && _ai_player[_ai.network_playas].active) {
/* Run the script */
- AI_DequeueCommands(_ai.network_player);
- AI_RunTick(_ai.network_player);
+ AI_DequeueCommands(_ai.network_playas);
+ AI_RunTick(_ai.network_playas);
} else if (!_networking || _network_server) {
/* Check if we want to run AIs (server or SP only) */
Player *p;
@@ -199,6 +199,9 @@ void AI_StartNewAI(PlayerID player)
*/
void AI_PlayerDied(PlayerID player)
{
+ if (_ai.network_client && _ai.network_playas == player)
+ _ai.network_playas = OWNER_SPECTATOR;
+
/* Called if this AI died */
_ai_player[player].active = false;
}
@@ -208,9 +211,13 @@ void AI_PlayerDied(PlayerID player)
*/
void AI_Initialize(void)
{
+ bool ai_network_client = _ai.network_client;
+
memset(&_ai, 0, sizeof(_ai));
memset(&_ai_player, 0, sizeof(_ai_player));
+ _ai.network_client = ai_network_client;
+ _ai.network_playas = OWNER_SPECTATOR;
_ai.enabled = true;
}
diff --git a/ai/ai.h b/ai/ai.h
index 174cf287c..910e050b1 100644
--- a/ai/ai.h
+++ b/ai/ai.h
@@ -31,7 +31,7 @@ typedef struct AIStruct {
/* For network-clients (a OpenTTD client who acts as an AI connected to a server) */
bool network_client; //! Are we a network_client?
- uint8 network_player; //! The current network player we are connected as
+ uint8 network_playas; //! The current network player we are connected as
} AIStruct;
VARDEF AIStruct _ai;
diff --git a/ai/default/default.c b/ai/default/default.c
index 4f4283f1a..b8648dbe2 100644
--- a/ai/default/default.c
+++ b/ai/default/default.c
@@ -3938,24 +3938,6 @@ void AiDoGameLoop(Player *p)
AiAdjustLoan(p);
AiBuildCompanyHQ(p);
- if (_opt.diff.competitor_speed == 4) {
- /* ultraspeed */
- _ai_actions[p->ai.state](p);
- if (p->bankrupt_asked != 0)
- return;
- } else if (_opt.diff.competitor_speed != 3) {
- p->ai.tick++;
- if (!(p->ai.tick&1))
- return;
- if (_opt.diff.competitor_speed != 2) {
- if (!(p->ai.tick&2))
- return;
- if (_opt.diff.competitor_speed == 0) {
- if (!(p->ai.tick&4))
- return;
- }
- }
- }
#if 0
{
static byte old_state = 99;
diff --git a/ai/trolly/trolly.c b/ai/trolly/trolly.c
index 21a5ee582..2ddd8fb58 100644
--- a/ai/trolly/trolly.c
+++ b/ai/trolly/trolly.c
@@ -44,7 +44,7 @@ static void AiNew_State_FirstTime(Player *p)
assert(p->ainew.state == AI_STATE_FIRST_TIME);
// We first have to init some things
- if (_current_player == 1) {
+ if (_current_player == 1 || _ai.network_client) {
ShowErrorMessage(-1, TEMP_AI_IN_PROGRESS, 0, 0);
}
@@ -1347,9 +1347,6 @@ static void AiNew_OnTick(Player *p)
void AiNewDoGameLoop(Player *p)
{
- // If it is a human player, it is not an AI, so bubye!
- if (IS_HUMAN_PLAYER(_current_player)) return;
-
if (p->ainew.state == AI_STATE_STARTUP) {
// The AI just got alive!
p->ainew.state = AI_STATE_FIRST_TIME;
@@ -1362,29 +1359,6 @@ void AiNewDoGameLoop(Player *p)
// We keep a ticker. We use it for competitor_speed
p->ainew.tick++;
- // See what the speed is
- switch (_opt.diff.competitor_speed) {
- case 0: // Very slow
- if (!(p->ainew.tick&8)) return;
- break;
-
- case 1: // Slow
- if (!(p->ainew.tick&4)) return;
- break;
-
- case 2:
- if (!(p->ainew.tick&2)) return;
- break;
-
- case 3:
- if (!(p->ainew.tick&1)) return;
- break;
-
- case 4: // Very fast
- default: // Cool, a new speed setting.. ;) VERY fast ;)
- break;
- }
-
// If we come here, we can do a tick.. do so!
AiNew_OnTick(p);
}
diff --git a/economy.c b/economy.c
index d595d13f4..a15fe2195 100644
--- a/economy.c
+++ b/economy.c
@@ -477,6 +477,8 @@ static void PlayersCheckBankrupt(Player *p)
if (!IS_HUMAN_PLAYER(owner) && (!_networking || _network_server) && _ai.enabled)
AI_PlayerDied(owner);
+ if (IS_HUMAN_PLAYER(owner) && owner == _local_player && _ai.network_client)
+ AI_PlayerDied(owner);
}
}
}
diff --git a/network_client.c b/network_client.c
index 6da4b0618..0f552f4a3 100644
--- a/network_client.c
+++ b/network_client.c
@@ -19,6 +19,7 @@
#include "settings.h"
#include "console.h"
#include "variables.h"
+#include "ai/ai.h"
// This file handles all the client-commands
@@ -342,9 +343,18 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
return NETWORK_RECV_STATUS_CONN_LOST;
/* Do we receive a change of data? Most likely we changed playas */
- if (index == _network_own_client_index)
+ if (index == _network_own_client_index) {
_network_playas = playas;
+ /* Are we a ai-network-client? */
+ if (_ai.network_client) {
+ if (_ai.network_playas == OWNER_SPECTATOR)
+ AI_StartNewAI(playas - 1);
+
+ _ai.network_playas = playas - 1;
+ }
+ }
+
ci = NetworkFindClientInfoFromIndex(index);
if (ci != NULL) {
if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
@@ -532,6 +542,17 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP)
_patches.autorenew_money = GetPlayer(_local_player)->engine_renew_money;
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
}
+
+ /* Check if we are an ai-network-client, and if so, disable GUI */
+ if (_ai.network_client) {
+ _ai.network_playas = _local_player;
+ _local_player = OWNER_SPECTATOR;
+
+ if (_ai.network_playas != OWNER_SPECTATOR) {
+ /* If we didn't join the game as a spectator, activate the AI */
+ AI_StartNewAI(_ai.network_playas);
+ }
+ }
}
return NETWORK_RECV_STATUS_OKAY;
diff --git a/openttd.c b/openttd.c
index cc4732df7..e26bb7e0f 100644
--- a/openttd.c
+++ b/openttd.c
@@ -330,9 +330,9 @@ int ttd_main(int argc, char* argv[])
// a ':' behind it means: it need a param (e.g.: -m<driver>)
// a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
- optformat = "m:s:v:hDfn::l:eit:d::r:g::G:p:c:";
+ optformat = "bm:s:v:hDfn::l:eit:d::r:g::G:p:c:";
#else
- optformat = "m:s:v:hDn::l:eit:d::r:g::G:p:c:"; // no fork option
+ optformat = "bm:s:v:hDn::l:eit:d::r:g::G:p:c:"; // no fork option
#endif
MyGetOptInit(&mgo, argc-1, argv+1, optformat);
@@ -358,6 +358,7 @@ int ttd_main(int argc, char* argv[])
else
network_conn = NULL;
} break;
+ case 'b': _ai.network_client = true; break;
case 'r': ParseResolution(resolution, mgo.opt); break;
case 'l': language = mgo.opt; break;
case 't': startdate = atoi(mgo.opt); break;
@@ -395,12 +396,17 @@ int ttd_main(int argc, char* argv[])
}
}
+ if (_ai.network_client && !network) {
+ _ai.network_client = false;
+ DEBUG(ai, 0)("[AI] Can't enable network-AI, because '-n' is not used\n");
+ }
+
DeterminePaths();
CheckExternalFiles();
#ifdef GPMI
/* Set the debug proc */
- gpmi_debug_proc = &gpmi_debug_openttd;
+ gpmi_debug_proc = &gpmi_debug_openttd;
/* Initialize GPMI */
gpmi_init();
@@ -531,6 +537,11 @@ int ttd_main(int argc, char* argv[])
/* stop the AI */
AI_Uninitialize();
+#ifdef GPMI
+ /* Uninitialize GPMI */
+ gpmi_uninit();
+#endif /* GPMI */
+
/* Close all and any open filehandles */
FioCloseAll();
UnInitializeGame();
diff --git a/players.c b/players.c
index ecb54aeee..b53ea1c27 100644
--- a/players.c
+++ b/players.c
@@ -806,10 +806,20 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2)
#endif /* ENABLE_NETWORK */
if (p != NULL) {
- if (_local_player == OWNER_SPECTATOR) {
+ if (_local_player == OWNER_SPECTATOR && (!_ai.network_client || _ai.network_playas == OWNER_SPECTATOR)) {
/* Check if we do not want to be a spectator in network */
- if (!_networking || (_network_server && !_network_dedicated) || _network_playas != OWNER_SPECTATOR) {
- _local_player = p->index;
+ if (!_networking || (_network_server && !_network_dedicated) || _network_playas != OWNER_SPECTATOR || _ai.network_client) {
+ if (_ai.network_client) {
+ /* As ai-network-client, we have our own rulez (disable GUI and stuff) */
+ _ai.network_playas = p->index;
+ _local_player = OWNER_SPECTATOR;
+ if (_ai.network_playas != OWNER_SPECTATOR) {
+ /* If we didn't join the game as a spectator, activate the AI */
+ AI_StartNewAI(_ai.network_playas);
+ }
+ } else {
+ _local_player = p->index;
+ }
MarkWholeScreenDirty();
}
} else if (p->index == _local_player) {