Some miscellaneous updates to main help, for new features and otherwise.
[freeciv.git] / server / aiiface.c
blobdcb16c4daeb9eede4671b01da661f5c351c10b34
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #ifdef AI_MODULES
19 #include <ltdl.h>
20 #endif
22 /* utility */
23 #include "support.h"
25 /* common */
26 #include "ai.h"
27 #include "player.h"
29 /* server/advisors */
30 #include "autosettlers.h"
32 /* ai/classic */
33 #include "classicai.h"
35 #include "aiiface.h"
37 #ifdef AI_MOD_STATIC_THREADED
38 bool fc_ai_threaded_setup(struct ai_type *ai);
39 #endif
41 static struct ai_type *default_ai = NULL;
43 #ifdef AI_MODULES
44 /**************************************************************************
45 Return string describing module loading error. Never returns NULL.
46 **************************************************************************/
47 static const char *fc_module_error(void)
49 static char def_err[] = "Unknown error";
50 const char *errtxt = lt_dlerror();
52 if (errtxt == NULL) {
53 return def_err;
56 return errtxt;
59 /**************************************************************************
60 Load ai module from file.
61 **************************************************************************/
62 bool load_ai_module(const char *modname)
64 struct ai_type *ai = ai_type_alloc();
65 bool setup_success;
66 lt_dlhandle handle;
67 bool (*setup_func)(struct ai_type *ai);
68 const char *(*capstr_func)(void);
69 const char *capstr;
70 char buffer[2048];
71 char filename[1024];
73 if (ai == NULL) {
74 return FALSE;
77 init_ai(ai);
79 fc_snprintf(filename, sizeof(filename), "fc_ai_%s", modname);
80 fc_snprintf(buffer, sizeof(buffer), "%s", filename);
81 handle = lt_dlopenext(buffer);
82 if (handle == NULL) {
83 log_error(_("Cannot open AI module %s (%s)"), filename, fc_module_error());
84 return FALSE;
87 fc_snprintf(buffer, sizeof(buffer), "%s_capstr", filename);
88 capstr_func = lt_dlsym(handle, buffer);
89 if (capstr_func == NULL) {
90 log_error(_("Cannot find capstr function from ai module %s (%s)"),
91 filename, fc_module_error());
92 return FALSE;
95 capstr = capstr_func();
96 if (strcmp(FC_AI_MOD_CAPSTR, capstr)) {
97 log_error(_("Incompatible ai module %s:"), filename);
98 log_error(_(" Module options: %s"), capstr);
99 log_error(_(" Supported options: %s"), FC_AI_MOD_CAPSTR);
101 return FALSE;
104 fc_snprintf(buffer, sizeof(buffer), "%s_setup", filename);
105 setup_func = lt_dlsym(handle, buffer);
106 if (setup_func == NULL) {
107 log_error(_("Cannot find setup function from ai module %s (%s)"),
108 filename, fc_module_error());
109 return FALSE;
111 setup_success = setup_func(ai);
113 if (!setup_success) {
114 log_error(_("Setup of ai module %s failed."), filename);
115 return FALSE;
118 return TRUE;
120 #endif /* AI_MODULES */
122 /**************************************************************************
123 Initialize ai stuff
124 **************************************************************************/
125 void ai_init(void)
127 bool failure = FALSE;
128 #if !defined(AI_MODULES) || defined(AI_MOD_STATIC_CLASSIC) || defined(AI_MOD_STATIC_THREADED)
129 /* First !defined(AI_MODULES) case is for default ai support. */
130 struct ai_type *ai;
131 #endif
133 #ifdef AI_MODULES
134 if (lt_dlinit()) {
135 failure = TRUE;
137 if (!failure) {
139 #ifdef DEBUG
140 /* First search ai modules under directory ai/<module> under
141 current directory. This allows us to run freeciv without
142 installing it. */
143 const char *moduledirs[] = { "classic", "threaded", "stub", NULL };
144 int i;
146 for (i = 0; moduledirs[i] != NULL ; i++) {
147 char buf[2048];
149 fc_snprintf(buf, sizeof(buf), "ai/%s", moduledirs[i]);
150 lt_dladdsearchdir(buf);
152 #endif /* DEBUG */
154 /* Then search ai modules from their installation directory. */
155 lt_dladdsearchdir(AI_MODULEDIR);
157 #endif /* AI_MODULES */
159 #ifdef AI_MOD_STATIC_CLASSIC
160 ai = ai_type_alloc();
161 if (ai != NULL) {
162 init_ai(ai);
163 if (!fc_ai_classic_setup(ai)) {
164 log_error(_("Failed to setup \"%s\" AI module"), "classic");
165 ai_type_dealloc();
168 #endif /* AI_MOD_STATIC_CLASSIC */
170 #ifdef AI_MOD_STATIC_THREADED
171 ai = ai_type_alloc();
172 if (ai != NULL) {
173 init_ai(ai);
174 if (!fc_ai_threaded_setup(ai)) {
175 log_error(_("Failed to setup \"%s\" AI module"), "threaded");
176 ai_type_dealloc();
179 #endif /* AI_MOD_STATIC_THREADED */
181 default_ai = ai_type_by_name(AI_MOD_DEFAULT);
182 #ifdef AI_MODULES
183 if (default_ai == NULL) {
184 /* Wasn't among statically linked. Try to load dynamic module. */
185 if (!failure && !load_ai_module(AI_MOD_DEFAULT)) {
186 failure = TRUE;
188 if (!failure) {
189 default_ai = ai_type_by_name(AI_MOD_DEFAULT);
192 #endif /* AI_MODULES */
193 if (default_ai == NULL || failure) {
194 log_error(_("Failed to setup default AI module \"%s\", cannot continue."),
195 AI_MOD_DEFAULT);
196 exit(EXIT_FAILURE);
200 /**************************************************************************
201 Call incident function of victim.
202 **************************************************************************/
203 void call_incident(enum incident_type type, struct player *violator,
204 struct player *victim)
206 CALL_PLR_AI_FUNC(incident, victim, type, violator, victim);
209 /****************************************************************************
210 Call ai refresh() callback for all players.
211 ****************************************************************************/
212 void call_ai_refresh(void)
214 players_iterate(pplayer) {
215 CALL_PLR_AI_FUNC(refresh, pplayer, pplayer);
216 } players_iterate_end;
219 /**************************************************************************
220 Return name of default ai type.
221 **************************************************************************/
222 const char *default_ai_type_name(void)
224 return default_ai->name;