summaryrefslogtreecommitdiff
path: root/src/ai/ai.cpp
diff options
context:
space:
mode:
authortruebrain <truebrain@openttd.org>2009-01-12 17:11:45 +0000
committertruebrain <truebrain@openttd.org>2009-01-12 17:11:45 +0000
commita3dd7506d377b1434f913bd65c019eed52b64b6e (patch)
treeced1a262eb143ad6e64ec02f4a4c89835c0c32fd /src/ai/ai.cpp
parent9294f9616866b9778c22076c19b5a32b4f85f788 (diff)
downloadopenttd-a3dd7506d377b1434f913bd65c019eed52b64b6e.tar.xz
(svn r15027) -Merge: tomatos and bananas left to be, here is NoAI for all to see.
NoAI is an API (a framework) to build your own AIs in. See: http://wiki.openttd.org/wiki/index.php/AI:Main_Page With many thanks to: - glx and Rubidium for their syncing, feedback and hard work - Yexo for his feedback, patches, and AIs which tested the system very deep - Morloth for his feedback and patches - TJIP for hosting a challenge which kept NoAI on track - All AI authors for testing our AI API, and all other people who helped in one way or another -Remove: all old AIs and their cheats/hacks
Diffstat (limited to 'src/ai/ai.cpp')
-rw-r--r--src/ai/ai.cpp244
1 files changed, 0 insertions, 244 deletions
diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp
deleted file mode 100644
index 01c8dcd68..000000000
--- a/src/ai/ai.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/* $Id$ */
-
-/** @file ai.cpp Base for all AIs. */
-
-#include "../stdafx.h"
-#include "../openttd.h"
-#include "../variables.h"
-#include "../command_func.h"
-#include "../network/network.h"
-#include "../core/alloc_func.hpp"
-#include "../company_func.h"
-#include "../company_base.h"
-#include "ai.h"
-#include "default/default.h"
-#include "trolly/trolly.h"
-#include "../signal_func.h"
-
-AIStruct _ai;
-AICompany _ai_company[MAX_COMPANIES];
-
-/**
- * Dequeues commands put in the queue via AI_PutCommandInQueue.
- */
-static void AI_DequeueCommands(CompanyID company)
-{
- AICommand *com, *entry_com;
-
- entry_com = _ai_company[company].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_company[company].queue = NULL;
- _ai_company[company].queue_tail = NULL;
-
- /* Dequeue all commands */
- while ((com = entry_com) != NULL) {
- _current_company = company;
-
- DoCommandP(com->tile, com->p1, com->p2, com->cmd, com->callback, com->text);
-
- /* 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(CompanyID company, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text = NULL)
-{
- AICommand *com;
-
- if (_ai_company[company].queue_tail == NULL) {
- /* There is no item in the queue yet, create the queue */
- _ai_company[company].queue = MallocT<AICommand>(1);
- _ai_company[company].queue_tail = _ai_company[company].queue;
- } else {
- /* Add an item at the end */
- _ai_company[company].queue_tail->next = MallocT<AICommand>(1);
- _ai_company[company].queue_tail = _ai_company[company].queue_tail->next;
- }
-
- /* This is our new item */
- com = _ai_company[company].queue_tail;
-
- /* Assign the info */
- com->tile = tile;
- com->p1 = p1;
- com->p2 = p2;
- com->cmd = cmd;
- com->callback = callback;
- com->next = NULL;
- com->text = text == NULL ? NULL : strdup(text);
-}
-
-/**
- * Executes a raw DoCommand for the AI.
- */
-CommandCost AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint32 cmd, CommandCallback *callback, const char *text)
-{
- CompanyID old_local_company;
- CommandCost res;
-
- /* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
- * person.. should we check for those funny jokes?
- */
-
- /* First, do a test-run to see if we can do this */
- res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, cmd, text);
- /* 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;
- }
-
- /* NetworkSend_Command needs _local_company to be set correctly, so
- * adjust it, and put it back right after the function */
- old_local_company = _local_company;
- _local_company = _current_company;
-
-#ifdef ENABLE_NETWORK
- /* Send the command */
- if (_networking) {
- /* Network is easy, send it to his handler */
- NetworkSend_Command(tile, p1, p2, cmd, callback, text);
- } 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_company, tile, p1, p2, cmd, callback, text);
- }
-
- /* Set _local_company back */
- _local_company = old_local_company;
-
- return res;
-}
-
-
-CommandCost AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint32 cmd, const char *text)
-{
- return AI_DoCommandCc(tile, p1, p2, flags, cmd, NULL, text);
-}
-
-
-/**
- * Run 1 tick of the AI. Don't overdo it, keep it realistic.
- */
-static void AI_RunTick(CompanyID company)
-{
- extern void AiNewDoGameLoop(Company *c);
-
- Company *c = GetCompany(company);
- _current_company = company;
-
- if (_settings_game.ai.ainew_active) {
- AiNewDoGameLoop(c);
- } else {
- /* Enable all kind of cheats the old AI needs in order to operate correctly... */
- _is_old_ai_company = true;
- AiDoGameLoop(c);
- _is_old_ai_company = false;
- }
-
- /* AI could change some track, so update signals */
- UpdateSignalsInBuffer();
-}
-
-
-/**
- * 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 || !_settings_game.ai.ai_in_multiplayer)) return;
-
- /* New tick */
- _ai.tick++;
-
- /* Make sure the AI follows the difficulty rule.. */
- assert(_settings_game.difficulty.competitor_speed <= 4);
- if ((_ai.tick & ((1 << (4 - _settings_game.difficulty.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 Company *c;
-
- FOR_ALL_COMPANIES(c) {
- if (c->is_ai) {
- /* This should always be true, else something went wrong... */
- assert(_ai_company[c->index].active);
-
- /* Run the script */
- AI_DequeueCommands(c->index);
- AI_RunTick(c->index);
- }
- }
- }
-
- _current_company = OWNER_NONE;
-}
-
-/**
- * A new AI sees the day of light. You can do here what ever you think is needed.
- */
-void AI_StartNewAI(CompanyID company)
-{
- assert(IsValidCompanyID(company));
-
- /* Called if a new AI is booted */
- _ai_company[company].active = true;
-}
-
-/**
- * This AI company died. Give it some chance to make a final puf.
- */
-void AI_CompanyDied(CompanyID company)
-{
- /* Called if this AI died */
- _ai_company[company].active = false;
-
- if (_companies_ainew[company].pathfinder == NULL) return;
-
- AyStarMain_Free(_companies_ainew[company].pathfinder);
- delete _companies_ainew[company].pathfinder;
- _companies_ainew[company].pathfinder = NULL;
-
-}
-
-/**
- * Initialize some AI-related stuff.
- */
-void AI_Initialize()
-{
- /* First, make sure all AIs are DEAD! */
- AI_Uninitialize();
-
- memset(&_ai, 0, sizeof(_ai));
- memset(&_ai_company, 0, sizeof(_ai_company));
-
- _ai.enabled = true;
-}
-
-/**
- * Deinitializer for AI-related stuff.
- */
-void AI_Uninitialize()
-{
- for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) AI_CompanyDied(c);
-}