--- a/projects/openttd.vcproj Tue Mar 13 13:07:17 2007 +0000
+++ b/projects/openttd.vcproj Tue Mar 13 15:47:26 2007 +0000
@@ -895,7 +895,22 @@
Name="AI Files"
Filter="">
<File
- RelativePath=".\..\src\ai\ai.cpp">
+ RelativePath=".\..\src\ai\core\ai.cpp">
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\ai.h">
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\ai_base.hpp">
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\base\random.cpp">
+ </File>
+ <File
+ RelativePath=".\..\src\ai\NoAI\NoAI.cpp">
+ </File>
+ <File
+ RelativePath=".\..\src\ai\NoAI\NoAI.hpp">
</File>
</Filter>
<Filter
--- a/projects/openttd_vs80.vcproj Tue Mar 13 13:07:17 2007 +0000
+++ b/projects/openttd_vs80.vcproj Tue Mar 13 15:47:26 2007 +0000
@@ -1416,7 +1416,27 @@
Name="AI Files"
>
<File
- RelativePath=".\..\src\ai\ai.cpp"
+ RelativePath=".\..\src\ai\core\ai.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\ai.h"
+ >
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\ai_base.hpp"
+ >
+ </File>
+ <File
+ RelativePath=".\..\src\ai\core\base\random.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\..\src\ai\NoAI\NoAI.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\..\src\ai\NoAI\NoAI.hpp"
>
</File>
</Filter>
--- a/source.list Tue Mar 13 13:07:17 2007 +0000
+++ b/source.list Tue Mar 13 15:47:26 2007 +0000
@@ -268,7 +268,12 @@
table/water_land.h
# AI Files
-ai/ai.cpp
+ai/core/ai.cpp
+ai/core/ai.h
+ai/core/ai_base.hpp
+ai/core/base/random.cpp
+ai/NoAI/NoAI.cpp
+ai/NoAI/NoAI.hpp
# NewGRF
newgrf.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/NoAI/NoAI.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+/** @file NoAI.cpp a simple C++ AI that will never be an AI */
+
+#include "../../stdafx.h"
+#include "NoAI.hpp"
+
+/* virtual */ void NoAI::GameLoop()
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/NoAI/NoAI.hpp Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,16 @@
+/* $Id$ */
+
+/** @file NoAI.hpp declarations of the class for a simple C++ AI that will never be an AI */
+
+#ifndef NOAI_HPP
+#define NOAI_HPP
+
+#include "../core/ai_base.hpp"
+
+class NoAI: public AIBase
+{
+public:
+ /* virtual */ void GameLoop();
+};
+
+#endif /* NOAI_HPP */
--- a/src/ai/ai.cpp Tue Mar 13 13:07:17 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/* $Id$ */
-
-#include "../stdafx.h"
-#include "../openttd.h"
-#include "../variables.h"
-#include "../command.h"
-#include "../network/network.h"
-#include "../helpers.hpp"
-#include "ai.h"
-
-/**
- * Dequeues commands put in the queue via AI_PutCommandInQueue.
- */
-static void AI_DequeueCommands(PlayerID player)
-{
- AICommand *com, *entry_com;
-
- entry_com = _ai_player[player].queue;
-
- /* It happens that DoCommandP issues a new DoCommandAI which adds a new command
- * to this very same queue (don't argue about this, if it currently doesn't
- * happen I can tell you it will happen with AIScript -- TrueLight). If we
- * do not make the queue NULL, that commands will be dequeued immediatly.
- * Therefor we safe the entry-point to entry_com, and make the queue NULL, so
- * the new queue can be safely built up. */
- _ai_player[player].queue = NULL;
- _ai_player[player].queue_tail = NULL;
-
- /* Dequeue all commands */
- while ((com = entry_com) != NULL) {
- _current_player = player;
-
- _cmd_text = com->text;
- DoCommandP(com->tile, com->p1, com->p2, com->callback, com->procc);
-
- /* Free item */
- entry_com = com->next;
- free(com->text);
- free(com);
- }
-}
-
-/**
- * Needed for SP; we need to delay DoCommand with 1 tick, because else events
- * will make infinite loops (AIScript).
- */
-static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCallback* callback)
-{
- AICommand *com;
-
- if (_ai_player[player].queue_tail == NULL) {
- /* There is no item in the queue yet, create the queue */
- _ai_player[player].queue = MallocT<AICommand>(1);
- _ai_player[player].queue_tail = _ai_player[player].queue;
- } else {
- /* Add an item at the end */
- _ai_player[player].queue_tail->next = MallocT<AICommand>(1);
- _ai_player[player].queue_tail = _ai_player[player].queue_tail->next;
- }
-
- /* This is our new item */
- com = _ai_player[player].queue_tail;
-
- /* Assign the info */
- com->tile = tile;
- com->p1 = p1;
- com->p2 = p2;
- com->procc = procc;
- com->callback = callback;
- com->next = NULL;
- com->text = NULL;
-
- /* Copy the cmd_text, if needed */
- if (_cmd_text != NULL) {
- com->text = strdup(_cmd_text);
- _cmd_text = NULL;
- }
-}
-
-/**
- * Executes a raw DoCommand for the AI.
- */
-int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback)
-{
- PlayerID old_lp;
- int32 res = 0;
- const char* tmp_cmdtext;
-
- /* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
- * person.. should we check for those funny jokes?
- */
-
- /* The test already resets _cmd_text, so backup the pointer */
- tmp_cmdtext = _cmd_text;
-
- /* First, do a test-run to see if we can do this */
- res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
- /* The command failed, or you didn't want to execute, or you are quering, return */
- if (CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
- return res;
- }
-
- /* Restore _cmd_text */
- _cmd_text = tmp_cmdtext;
-
- /* If we did a DC_EXEC, and the command did not return an error, execute it
- * over the network */
- if (flags & DC_AUTO) procc |= CMD_AUTO;
- if (flags & DC_NO_WATER) procc |= CMD_NO_WATER;
-
- /* NetworkSend_Command needs _local_player to be set correctly, so
- * adjust it, and put it back right after the function */
- old_lp = _local_player;
- _local_player = _current_player;
-
-#ifdef ENABLE_NETWORK
- /* Send the command */
- if (_networking) {
- /* Network is easy, send it to his handler */
- NetworkSend_Command(tile, p1, p2, procc, callback);
- } else {
-#else
- {
-#endif
- /* If we execute BuildCommands directly in SP, we have a big problem with events
- * so we need to delay is for 1 tick */
- AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
- }
-
- /* Set _local_player back */
- _local_player = old_lp;
-
- return res;
-}
-
-
-int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
-{
- return AI_DoCommandCc(tile, p1, p2, flags, procc, NULL);
-}
-
-
-/**
- * Run 1 tick of the AI. Don't overdo it, keep it realistic.
- */
-static void AI_RunTick(PlayerID player)
-{
- extern void AiNewDoGameLoop(Player *p);
-
-// Player *p = GetPlayer(player);
- _current_player = player;
-
- /* TODO -- Call the AI here */
-}
-
-
-/**
- * The gameloop for AIs.
- * Handles one tick for all the AIs.
- */
-void AI_RunGameLoop()
-{
- /* Don't do anything if ai is disabled */
- if (!_ai.enabled) return;
-
- /* Don't do anything if we are a network-client, or the AI has been disabled */
- if (_networking && (!_network_server || !_patches.ai_in_multiplayer)) return;
-
- /* New tick */
- _ai.tick++;
-
- /* Make sure the AI follows the difficulty rule.. */
- assert(_opt.diff.competitor_speed <= 4);
- if ((_ai.tick & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0) return;
-
- /* Check for AI-client (so joining a network with an AI) */
- if (!_networking || _network_server) {
- /* Check if we want to run AIs (server or SP only) */
- const Player* p;
-
- FOR_ALL_PLAYERS(p) {
- if (p->is_active && p->is_ai) {
- /* This should always be true, else something went wrong... */
- assert(_ai_player[p->index].active);
-
- /* Run the script */
- AI_DequeueCommands(p->index);
- AI_RunTick(p->index);
- }
- }
- }
-
- _current_player = OWNER_NONE;
-}
-
-/**
- * A new AI sees the day of light. You can do here what ever you think is needed.
- */
-void AI_StartNewAI(PlayerID player)
-{
- assert(IsValidPlayer(player));
-
- /* Called if a new AI is booted */
- _ai_player[player].active = true;
-}
-
-/**
- * This AI player died. Give it some chance to make a final puf.
- */
-void AI_PlayerDied(PlayerID player)
-{
- /* Called if this AI died */
- _ai_player[player].active = false;
-}
-
-/**
- * Initialize some AI-related stuff.
- */
-void AI_Initialize()
-{
- /* First, make sure all AIs are DEAD! */
- AI_Uninitialize();
-
- memset(&_ai, 0, sizeof(_ai));
- memset(&_ai_player, 0, sizeof(_ai_player));
-
- _ai.enabled = true;
-}
-
-/**
- * Deinitializer for AI-related stuff.
- */
-void AI_Uninitialize()
-{
- const Player* p;
-
- FOR_ALL_PLAYERS(p) {
- if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
- }
-}
--- a/src/ai/ai.h Tue Mar 13 13:07:17 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-#ifndef AI_H
-#define AI_H
-
-#include "../functions.h"
-#include "../network/network.h"
-#include "../player.h"
-#include "../command.h"
-
-/* How DoCommands look like for an AI */
-struct AICommand {
- uint32 tile;
- uint32 p1;
- uint32 p2;
- uint32 procc;
- CommandCallback* callback;
-
- char *text;
- uint uid;
-
- AICommand *next;
-};
-
-/* The struct for an AIScript Player */
-struct AIPlayer {
- bool active; ///< Is this AI active?
- AICommand *queue; ///< The commands that he has in his queue
- AICommand *queue_tail; ///< The tail of this queue
-};
-
-/* The struct to keep some data about the AI in general */
-struct AIStruct {
- /* General */
- bool enabled; ///< Is AI enabled?
- uint tick; ///< The current tick (something like _frame_counter, only for AIs)
-};
-
-VARDEF AIStruct _ai;
-VARDEF AIPlayer _ai_player[MAX_PLAYERS];
-
-// ai.c
-void AI_StartNewAI(PlayerID player);
-void AI_PlayerDied(PlayerID player);
-void AI_RunGameLoop();
-void AI_Initialize();
-void AI_Uninitialize();
-int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
-int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback);
-
-/** Is it allowed to start a new AI.
- * This function checks some boundries to see if we should launch a new AI.
- * @return True if we can start a new AI.
- */
-static inline bool AI_AllowNewAI()
-{
- /* If disabled, no AI */
- if (!_ai.enabled)
- return false;
-
- /* If in network, but no server, no AI */
- if (_networking && !_network_server)
- return false;
-
- /* If in network, and server, possible AI */
- if (_networking && _network_server) {
- /* Do we want AIs in multiplayer? */
- if (!_patches.ai_in_multiplayer)
- return false;
- }
-
- return true;
-}
-
-#define AI_CHANCE16(a,b) ((uint16) AI_Random() <= (uint16)((65536 * a) / b))
-#define AI_CHANCE16R(a,b,r) ((uint16)(r = AI_Random()) <= (uint16)((65536 * a) / b))
-
-/**
- * The random-function that should be used by ALL AIs.
- */
-static inline uint AI_RandomRange(uint max)
-{
- /* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
- * but we pick InteractiveRandomRange if we are a network_server or network-client.
- */
- if (_networking)
- return InteractiveRandomRange(max);
- else
- return RandomRange(max);
-}
-
-/**
- * The random-function that should be used by ALL AIs.
- */
-static inline uint32 AI_Random()
-{
-/* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
- * but we pick InteractiveRandomRange if we are a network_server or network-client.
- */
- if (_networking)
- return InteractiveRandom();
- else
- return Random();
-}
-
-#endif /* AI_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/core/ai.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,291 @@
+/* $Id$ */
+
+/** @file ai.cpp handles the communication between the AI layer and the OpenTTD core */
+
+#include "../../stdafx.h"
+#include "../../openttd.h"
+#include "../../variables.h"
+#include "../../command.h"
+#include "../../network/network.h"
+#include "../../helpers.hpp"
+#include "ai.h"
+#include "ai_base.hpp"
+#include "../NoAI/NoAI.hpp"
+
+/**
+ * How DoCommands-struct look like for an AI.
+ */
+struct AICommand {
+ uint32 tile;
+ uint32 p1;
+ uint32 p2;
+ uint32 procc;
+ CommandCallback* callback;
+
+ char *text;
+ uint uid;
+
+ AICommand *next;
+};
+
+/* The struct for an AIScript Player */
+struct AIPlayer {
+ AICommand *queue; ///< The commands that he has in his queue
+ AICommand *queue_tail; ///< The tail of this queue
+ AIBase *object; ///< The class object for this AI
+};
+
+static AIPlayer _ai_player[MAX_PLAYERS];
+static uint _ai_frame_counter;
+static bool _ai_enabled;
+
+/**
+ * Dequeues commands put in the queue via AI_PutCommandInQueue.
+ */
+static void AI_DequeueCommands(PlayerID player)
+{
+ AICommand *com, *entry_com;
+
+ entry_com = _ai_player[player].queue;
+
+ /* It happens that DoCommandP issues a new DoCommandAI which adds a new command
+ * to this very same queue (don't argue about this, if it currently doesn't
+ * happen I can tell you it will happen with AIScript -- TrueLight). If we
+ * do not make the queue NULL, that commands will be dequeued immediatly.
+ * Therefor we safe the entry-point to entry_com, and make the queue NULL, so
+ * the new queue can be safely built up. */
+ _ai_player[player].queue = NULL;
+ _ai_player[player].queue_tail = NULL;
+
+ /* Dequeue all commands */
+ while ((com = entry_com) != NULL) {
+ _current_player = player;
+
+ _cmd_text = com->text;
+ DoCommandP(com->tile, com->p1, com->p2, com->callback, com->procc);
+
+ /* Free item */
+ entry_com = com->next;
+ free(com->text);
+ free(com);
+ }
+}
+
+/**
+ * Needed for SP; we need to delay DoCommand with 1 tick, because else events
+ * will make infinite loops (AIScript).
+ */
+static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCallback* callback)
+{
+ AICommand *com;
+
+ if (_ai_player[player].queue_tail == NULL) {
+ /* There is no item in the queue yet, create the queue */
+ _ai_player[player].queue = MallocT<AICommand>(1);
+ _ai_player[player].queue_tail = _ai_player[player].queue;
+ } else {
+ /* Add an item at the end */
+ _ai_player[player].queue_tail->next = MallocT<AICommand>(1);
+ _ai_player[player].queue_tail = _ai_player[player].queue_tail->next;
+ }
+
+ /* This is our new item */
+ com = _ai_player[player].queue_tail;
+
+ /* Assign the info */
+ com->tile = tile;
+ com->p1 = p1;
+ com->p2 = p2;
+ com->procc = procc;
+ com->callback = callback;
+ com->next = NULL;
+ com->text = NULL;
+
+ /* Copy the cmd_text, if needed */
+ if (_cmd_text != NULL) {
+ com->text = strdup(_cmd_text);
+ _cmd_text = NULL;
+ }
+}
+
+/**
+ * Executes a raw DoCommand for the AI.
+ */
+int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback)
+{
+ PlayerID old_lp;
+ int32 res = 0;
+ const char* tmp_cmdtext;
+
+ /* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
+ * person.. should we check for those funny jokes?
+ */
+
+ /* The test already resets _cmd_text, so backup the pointer */
+ tmp_cmdtext = _cmd_text;
+
+ /* First, do a test-run to see if we can do this */
+ res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
+ /* The command failed, or you didn't want to execute, or you are quering, return */
+ if (CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
+ return res;
+ }
+
+ /* Restore _cmd_text */
+ _cmd_text = tmp_cmdtext;
+
+ /* If we did a DC_EXEC, and the command did not return an error, execute it
+ * over the network */
+ if (flags & DC_AUTO) procc |= CMD_AUTO;
+ if (flags & DC_NO_WATER) procc |= CMD_NO_WATER;
+
+ /* NetworkSend_Command needs _local_player to be set correctly, so
+ * adjust it, and put it back right after the function */
+ old_lp = _local_player;
+ _local_player = _current_player;
+
+#ifdef ENABLE_NETWORK
+ /* Send the command */
+ if (_networking) {
+ /* Network is easy, send it to his handler */
+ NetworkSend_Command(tile, p1, p2, procc, callback);
+ } else {
+#else
+ {
+#endif
+ /* If we execute BuildCommands directly in SP, we have a big problem with events
+ * so we need to delay is for 1 tick */
+ AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
+ }
+
+ /* Set _local_player back */
+ _local_player = old_lp;
+
+ return res;
+}
+
+
+int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
+{
+ return AI_DoCommandCc(tile, p1, p2, flags, procc, NULL);
+}
+
+
+/**
+ * Run 1 tick of the AI. Don't overdo it, keep it realistic.
+ */
+static void AI_RunTick(PlayerID player)
+{
+ _current_player = player;
+
+ _ai_player[player].object->IncreaseTick();
+ _ai_player[player].object->GameLoop();
+}
+
+
+/**
+ * The gameloop for AIs.
+ * Handles one tick for all the AIs.
+ */
+void AI_RunGameLoop()
+{
+ /* Don't do anything if ai is disabled */
+ if (!_ai_enabled) return;
+
+ /* Don't do anything if we are a network-client, or the AI has been disabled */
+ if (_networking && (!_network_server || !_patches.ai_in_multiplayer)) return;
+
+ /* New tick */
+ _ai_frame_counter++;
+
+ /* Make sure the AI follows the difficulty rule.. */
+ assert(_opt.diff.competitor_speed <= 4);
+ if ((_ai_frame_counter & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0) return;
+
+ /* Check for AI-client (so joining a network with an AI) */
+ if (!_networking || _network_server) {
+ /* Check if we want to run AIs (server or SP only) */
+ const Player* p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->is_ai) {
+ /* Run the script */
+ AI_DequeueCommands(p->index);
+ AI_RunTick(p->index);
+ }
+ }
+ }
+
+ _current_player = OWNER_NONE;
+}
+
+/**
+ * A new AI sees the day of light. You can do here what ever you think is needed.
+ */
+void AI_StartNewAI(PlayerID player)
+{
+ assert(IsValidPlayer(player));
+ if (!_ai_enabled) return;
+ if (_networking && !_network_server) return;
+
+ /* Called if a new AI is booted */
+ _ai_player[player].object = new NoAI();
+}
+
+/**
+ * This AI player died. Give it some chance to make a final puf.
+ */
+void AI_PlayerDied(PlayerID player)
+{
+ if (!_ai_enabled) return;
+
+ /* Called if this AI died */
+ delete _ai_player[player].object;
+}
+
+/**
+ * Initialize some AI-related stuff.
+ */
+void AI_Initialize()
+{
+ /* First, make sure all AIs are DEAD! */
+ AI_Uninitialize();
+
+ memset(&_ai_player, 0, sizeof(_ai_player));
+ _ai_frame_counter = 0;
+ _ai_enabled = true;
+}
+
+/**
+ * Deinitializer for AI-related stuff.
+ */
+void AI_Uninitialize()
+{
+ const Player* p;
+
+ FOR_ALL_PLAYERS(p) {
+ if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
+ }
+}
+
+/**
+ * Is it allowed to start a new AI.
+ * This function checks some boundries to see if we should launch a new AI.
+ * @return True if we can start a new AI.
+ */
+bool AI_AllowNewAI()
+{
+ /* If disabled, no AI */
+ if (!_ai_enabled) return false;
+
+ /* If in network, but no server, no AI */
+ if (_networking && !_network_server) return false;
+
+ /* If in network, and server, possible AI */
+ if (_networking && _network_server) {
+ /* Do we want AIs in multiplayer? */
+ if (!_patches.ai_in_multiplayer) return false;
+ }
+
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/core/ai.h Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,16 @@
+/* $Id$ */
+
+/** @file declaration of functions for the AI system */
+
+#ifndef AI_H
+#define AI_H
+
+// ai.c
+void AI_StartNewAI(PlayerID player);
+void AI_PlayerDied(PlayerID player);
+void AI_RunGameLoop();
+void AI_Initialize();
+void AI_Uninitialize();
+bool AI_AllowNewAI();
+
+#endif /* AI_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/core/ai_base.hpp Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,51 @@
+/* $Id$ */
+
+/** @file deceleration of class for AIBase class */
+
+#ifndef AI_BASE_HPP
+#define AI_BASE_HPP
+
+class AIBase {
+protected:
+ uint tick;
+
+public:
+ AIBase() :
+ tick(0)
+ {}
+
+ virtual ~AIBase() { }
+
+ /**
+ * This function is called every tick.
+ */
+ virtual void GameLoop() = 0;
+
+ /**
+ * Increase the internal ticker.
+ */
+ void IncreaseTick() { this->tick++; }
+
+ /**
+ * Get a random value.
+ * @return A random value between 0 and MAX(uint32)
+ */
+ uint32 Random();
+
+ /**
+ * Get a random value in a range.
+ * @param max The maximum value it will return.
+ * @return A random value between 0 .. max.
+ */
+ uint32 RandomRange(uint max);
+
+ /**
+ * Take a chance of 'out' out of 'max'.
+ * @param out How many times is should return true.
+ * @param max What the max value of 'out' can be.
+ * @return True if the chance worked out.
+ */
+ bool Chance(uint out, uint max);
+};
+
+#endif /* AI_BASE_HPP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/core/base/random.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/** @file random.cpp handles the random functions of the AIBase class */
+
+#include "../../../stdafx.h"
+#include "../../../openttd.h"
+#include "../../../variables.h"
+#include "../../../functions.h"
+#include "../ai_base.hpp"
+
+uint32 AIBase::Random()
+{
+ /* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
+ * but we pick InteractiveRandomRange if we are a network_server or network-client. */
+ if (_networking) return InteractiveRandom();
+ return Random();
+}
+
+uint32 AIBase::RandomRange(uint max)
+{
+ /* We pick RandomRange if we are in SP (so when saved, we do the same over and over)
+ * but we pick InteractiveRandomRange if we are a network_server or network-client. */
+ if (_networking) return InteractiveRandomRange(max);
+ return RandomRange(max);
+}
+
+bool AIBase::Chance(uint out, uint max)
+{
+ return this->Random() <= (uint16)((65536 * out) / max);
+}
--- a/src/economy.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/economy.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -27,7 +27,7 @@
#include "network/network_data.h"
#include "variables.h"
#include "vehicle_gui.h"
-#include "ai/ai.h"
+#include "ai/core/ai.h"
#include "train.h"
#include "aircraft.h"
#include "newgrf_engine.h"
@@ -471,8 +471,7 @@
/* Register the player as not-active */
p->is_active = false;
- if (!IsHumanPlayer(owner) && (!_networking || _network_server) && _ai.enabled)
- AI_PlayerDied(owner);
+ if (!IsHumanPlayer(owner)) AI_PlayerDied(owner);
}
}
}
--- a/src/misc.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/misc.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -17,7 +17,7 @@
#include "engine.h"
#include "vehicle_gui.h"
#include "variables.h"
-#include "ai/ai.h"
+#include "ai/core/ai.h"
#include "date.h"
#include "cargotype.h"
--- a/src/network/network_client.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/network/network_client.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -19,7 +19,6 @@
#include "../window.h"
#include "../console.h"
#include "../variables.h"
-#include "../ai/ai.h"
#include "../helpers.hpp"
// This file handles all the client-commands
--- a/src/oldloader.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/oldloader.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -17,7 +17,7 @@
#include "debug.h"
#include "depot.h"
#include "network/network.h"
-#include "ai/ai.h"
+#include "ai/core/ai.h"
#include "date.h"
enum {
@@ -834,8 +834,7 @@
if (p->location_of_house == 0xFFFF)
p->location_of_house = 0;
- if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
- AI_StartNewAI(p->index);
+ if (p->is_ai) AI_StartNewAI(p->index);
return true;
}
--- a/src/openttd.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/openttd.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -47,7 +47,7 @@
#include "signs.h"
#include "depot.h"
#include "waypoint.h"
-#include "ai/ai.h"
+#include "ai/core/ai.h"
#include "train.h"
#include "yapf/yapf.h"
#include "settings.h"
--- a/src/players.cpp Tue Mar 13 13:07:17 2007 +0000
+++ b/src/players.cpp Tue Mar 13 15:47:26 2007 +0000
@@ -23,7 +23,7 @@
#include "network/network.h"
#include "variables.h"
#include "engine.h"
-#include "ai/ai.h"
+#include "ai/core/ai.h"
#include "date.h"
#include "window.h"
#include "player_face.h"
@@ -485,8 +485,7 @@
InvalidateWindow(WC_TOOLBAR_MENU, 0);
InvalidateWindow(WC_CLIENT_LIST, 0);
- if (is_ai && (!_networking || _network_server) && _ai.enabled)
- AI_StartNewAI(p->index);
+ if (is_ai) AI_StartNewAI(p->index);
memset(p->num_engines, 0, sizeof(p->num_engines));
@@ -1264,8 +1263,7 @@
UpdatePlayerMoney32(p);
/* This is needed so an AI is attached to a loaded AI */
- if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
- AI_StartNewAI(p->index);
+ if (p->is_ai) AI_StartNewAI(p->index);
}
}