(svn r3229) -Add: add more GPMI support. Now GPMI-based AIs can be loaded (doesn't change a thing if you didn't enable GPMI)
authortruelight
Tue, 22 Nov 2005 22:32:42 +0000
changeset 2687 eb2443a14a74
parent 2686 a3e667057607
child 2688 ef9861cdd745
(svn r3229) -Add: add more GPMI support. Now GPMI-based AIs can be loaded (doesn't change a thing if you didn't enable GPMI)
ai/ai.c
ai/ai.h
lang/english.txt
openttd.c
settings.c
settings_gui.c
--- a/ai/ai.c	Tue Nov 22 22:30:35 2005 +0000
+++ b/ai/ai.c	Tue Nov 22 22:32:42 2005 +0000
@@ -5,6 +5,7 @@
 #include "../variables.h"
 #include "../command.h"
 #include "../network.h"
+#include "../debug.h"
 #include "ai.h"
 #include "default/default.h"
 
@@ -120,18 +121,28 @@
  */
 static void AI_RunTick(PlayerID player)
 {
-	extern void AiNewDoGameLoop(Player *p);
-
-	Player *p = GetPlayer(player);
 	_current_player = player;
 
-	if (_patches.ainew_active) {
-		AiNewDoGameLoop(p);
-	} else {
-		/* Enable all kind of cheats the old AI needs in order to operate correctly... */
-		_is_old_ai_player = true;
-		AiDoGameLoop(p);
-		_is_old_ai_player = false;
+#ifdef GPMI
+	if (_ai.gpmi) {
+		gpmi_call_RunTick(_ai_player[player].module, _frame_counter);
+		return;
+	}
+#endif /* GPMI */
+
+	{
+		extern void AiNewDoGameLoop(Player *p);
+
+		Player *p = GetPlayer(player);
+
+		if (_patches.ainew_active) {
+			AiNewDoGameLoop(p);
+		} else {
+			/* Enable all kind of cheats the old AI needs in order to operate correctly... */
+			_is_old_ai_player = true;
+			AiDoGameLoop(p);
+			_is_old_ai_player = false;
+		}
 	}
 }
 
@@ -171,10 +182,7 @@
 		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);
-
+			if (p->is_active && p->is_ai && _ai_player[p->index].active) {
 				/* Run the script */
 				AI_DequeueCommands(p->index);
 				AI_RunTick(p->index);
@@ -190,6 +198,21 @@
  */
 void AI_StartNewAI(PlayerID player)
 {
+#ifdef GPMI
+	char library[80];
+	char params[80];
+
+	/* XXX -- Todo, make a nice assign for library and params from a nice GUI :) */
+	snprintf(library, sizeof(library), "php");
+	snprintf(params,  sizeof(params),  "daeb");
+
+	_ai_player[player].module = gpmi_mod_load(library, params);
+	if (_ai_player[player].module == NULL) {
+		DEBUG(ai, 0)("[AI] Failed to load AI, aborting..");
+		return;
+	}
+#endif /* GPMI */
+
 	/* Called if a new AI is booted */
 	_ai_player[player].active = true;
 }
@@ -204,6 +227,10 @@
 
 	/* Called if this AI died */
 	_ai_player[player].active = false;
+
+#ifdef GPMI
+	gpmi_mod_unload(_ai_player[player].module);
+#endif /* GPMI */
 }
 
 /**
@@ -211,14 +238,20 @@
  */
 void AI_Initialize(void)
 {
-	bool ai_network_client = _ai.network_client;
+	bool tmp_ai_network_client = _ai.network_client;
+#ifdef GPMI
+	bool tmp_ai_gpmi = _ai.gpmi;
+#endif /* GPMI */
 
 	memset(&_ai, 0, sizeof(_ai));
 	memset(&_ai_player, 0, sizeof(_ai_player));
 
-	_ai.network_client = ai_network_client;
+	_ai.network_client = tmp_ai_network_client;
 	_ai.network_playas = OWNER_SPECTATOR;
 	_ai.enabled = true;
+#ifdef GPMI
+	_ai.gpmi = tmp_ai_gpmi;
+#endif /* GPMI */
 }
 
 /**
@@ -229,6 +262,6 @@
 	Player* p;
 
 	FOR_ALL_PLAYERS(p) {
-		if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
+		if (p->is_active && p->is_ai && _ai_player[p->index].active) AI_PlayerDied(p->index);
 	}
 }
--- a/ai/ai.h	Tue Nov 22 22:30:35 2005 +0000
+++ b/ai/ai.h	Tue Nov 22 22:32:42 2005 +0000
@@ -3,6 +3,9 @@
 
 #include "../functions.h"
 #include "../network.h"
+#ifdef GPMI
+#include <gpmi.h>
+#endif /* GPMI */
 
 /* How DoCommands look like for an AI */
 typedef struct AICommand {
@@ -21,6 +24,9 @@
 	bool active;            //! Is this AI active?
 	AICommand *queue;       //! The commands that he has in his queue
 	AICommand *queue_tail;  //! The tail of this queue
+#ifdef GPMI
+	gpmi_module *module;    //! The link to the GPMI module
+#endif /* GPMI */
 } AIPlayer;
 
 /* The struct to keep some data about the AI in general */
@@ -32,6 +38,10 @@
 	/* 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_playas;   //! The current network player we are connected as
+
+#ifdef GPMI
+	bool gpmi;              //! True if we want GPMI AIs
+#endif /* GPMI */
 } AIStruct;
 
 VARDEF AIStruct _ai;
--- a/lang/english.txt	Tue Nov 22 22:30:35 2005 +0000
+++ b/lang/english.txt	Tue Nov 22 22:32:42 2005 +0000
@@ -1012,6 +1012,7 @@
 
 STR_CONFIG_PATCHES_AINEW_ACTIVE                                 :{LTBLUE}Enable new AI (alpha): {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER                            :{LTBLUE}Allow AIs in multiplayer (experimental): {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_AI_GPMI                                      :{LTBLUE}Enable GPMI-driven AIs: {ORANGE}{STRING1}
 
 STR_CONFIG_PATCHES_SERVINT_TRAINS                               :{LTBLUE}Default service interval for trains: {ORANGE}{STRING1} days/%
 STR_CONFIG_PATCHES_SERVINT_TRAINS_DISABLED                      :{LTBLUE}Default service interval for trains: {ORANGE}disabled
--- a/openttd.c	Tue Nov 22 22:30:35 2005 +0000
+++ b/openttd.c	Tue Nov 22 22:32:42 2005 +0000
@@ -408,12 +408,15 @@
 	/* Set the debug proc */
 	gpmi_debug_proc = &gpmi_debug_openttd;
 
+	/* Set the script-path (GPMI doesn't support multiple paths, yet!) */
+	gpmi_path_scripts = strdup("ai/scripts");
+
 	/* Initialize GPMI */
 	gpmi_init();
 
 	/* Add our paths so we can find our own packages */
-	gpmi_path_append(&gpmi_path_modules, "gpmi/modules");
-	gpmi_path_append(&gpmi_path_packages, "gpmi/packages");
+	gpmi_path_append(&gpmi_path_modules,  "ai/modules");
+	gpmi_path_append(&gpmi_path_packages, "ai/packages");
 #endif /* GPMI */
 
 #if defined(UNIX) && !defined(__MORPHOS__)
--- a/settings.c	Tue Nov 22 22:30:35 2005 +0000
+++ b/settings.c	Tue Nov 22 22:32:42 2005 +0000
@@ -11,6 +11,9 @@
 #include "variables.h"
 #include "network.h"
 #include "settings.h"
+#ifdef GPMI
+#include "ai/ai.h"
+#endif /* GPMI */
 
 typedef struct IniFile IniFile;
 typedef struct IniItem IniItem;
@@ -943,6 +946,9 @@
 
 	{"ainew_active",				SDT_BOOL,		(void*)false, &_patches.ainew_active,					NULL},
 	{"ai_in_multiplayer",		SDT_BOOL,		(void*)false, &_patches.ai_in_multiplayer,		NULL},
+#ifdef GPMI
+	{"ai_gpmi",							SDT_BOOL,		(void*)true,	&_ai.gpmi,											NULL},
+#endif /* GPMI */
 
 	{"map_x", SDT_UINT32, (void*)8, &_patches.map_x, NULL},
 	{"map_y", SDT_UINT32, (void*)8, &_patches.map_y, NULL},
--- a/settings_gui.c	Tue Nov 22 22:30:35 2005 +0000
+++ b/settings_gui.c	Tue Nov 22 22:32:42 2005 +0000
@@ -19,6 +19,9 @@
 #include "console.h"
 #include "town.h"
 #include "variables.h"
+#ifdef GPMI
+#include "ai/ai.h"
+#endif /* GPMI */
 
 static uint32 _difficulty_click_a;
 static uint32 _difficulty_click_b;
@@ -760,6 +763,9 @@
 static const PatchEntry _patches_ai[] = {
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_AINEW_ACTIVE, "ainew_active", &_patches.ainew_active, 0, 1, 1, &AiNew_PatchActive_Warning},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER, "ai_in_multiplayer", &_patches.ai_in_multiplayer, 0, 1, 1, &Ai_In_Multiplayer_Warning},
+#ifdef GPMI
+	{PE_BOOL,		0, STR_CONFIG_PATCHES_AI_GPMI, "ai_gpmi", &_ai.gpmi, 0, 1, 1, NULL},
+#endif /* GPMI */
 
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_AI_BUILDS_TRAINS, "ai_disable_veh_train", &_patches.ai_disable_veh_train,			0,  0,  0, NULL},
 	{PE_BOOL,		0, STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH,"ai_disable_veh_roadveh",&_patches.ai_disable_veh_roadveh,		0,  0,  0, NULL},