1 /* General Xconq initialization.
2 Copyright (C) 1987-1989, 1991-2000 Stanley T. Shebs.
3 Copyright (C) 2004-2005 Eric A. McDonald.
4
5 Xconq is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version. See the file COPYING. */
9
10 /* Initialization is complicated, because Xconq needs lots of setup
11 for maps, units, sides, and the like. The data must also be able
12 to come from saved games, scenarios, bare maps in files, type
13 definitions, or be synthesized if necessary. */
14
15 /* The general theory is that everything gets set to a known empty
16 state, then all files are read, then all the synthesis methods get
17 run. Files/readers and synth methods are each responsible for
18 preventing fatal conflicts. */
19
20 #include "conq.h"
21 #include "kernel.h"
22 #include "version.h"
23
24 static void check_occs_on_completion(void);
25 static int advance_is_part_of_advance_cycle(int a, int *alist, int alistsz);
26 static void init_advances_synopsis(void);
27 static void disallow_more_types(void);
28 static void cache_possible_types(void);
29 static void kill_excess_units(void);
30 static void trial_assign_player(int i, Player *player);
31 static void patch_object_references(void);
32 static void init_view_cell(int x, int y);
33 static void maybe_init_view_cell(int x, int y);
34 static int adj_seen_terrain(int x, int y, Side *side);
35 static void init_ranged_views(void);
36 static void init_side_advantage(Side *side);
37 static int make_random_date(int calls, int runs);
38 static int make_weather(int calls, int runs);
39 static void configure_sides(void);
40 static void init_all_views(void);
41 static int make_initial_materials(int calls, int runs);
42 static void init_side_balance(void);
43 static void check_consistency(void);
44
45 /* This is true after the game is totally synthesized, but players may
46 not all be in the game yet. */
47
48 int gamedefined = FALSE;
49
50 enum setup_stage current_stage = initial_stage;
51
52 /* These are handy tmp vars, usually used with function args. */
53
54 short tmputype;
55 short tmpmtype;
56 short tmpttype;
57 short tmpatype;
58
59 /* The array of player/side matchups. */
60
61 Assign *assignments = NULL;
62
63 /* True when no AIs should be set up at game start. */
64
65 short initially_no_ai;
66
67 /* The name of the default game module. */
68
69 char *standard_game_name;
70
71 /* This is the main string printing buffer. It is statically allocated
72 because it is used even before the main data structures are inited. */
73
74 char spbuf[BUFSIZE];
75
76 /* This is an auxiliary buffer. Also needs to be statically allocated. */
77
78 char tmpbuf[BUFSIZE];
79
80 /* This is true if the interface was requested to put up a new game
81 dialog (kind of a random file for this, but *is* init-related). */
82
83 int option_popup_new_game_dialog;
84
85 /* Used by any code that is concerned with automatic reactions to a change
86 in Xconq, such as an unit entering a cell. */
87
88 namespace Xconq {
89 int suppress_reactions = FALSE;
90 }
91
92 #ifdef DESIGNERS
93
94 /* This is true if all sides with displays should become designers
95 automatically. */
96
97 int allbedesigners = FALSE;
98
99 /* This is the current count of how many sides are designers. */
100
101 int numdesigners = 0;
102
103 #endif /* DESIGNERS */
104
105 int max_zoc_range;
106
107 short *u_possible;
108
109 /* The table of all available synthesis methods. */
110
111 struct synthtype {
112 int key;
113 int (*fn)(int calls, int runs);
114 int dflt;
115 int calls;
116 int runs;
117 } synthmethods[] = {
118 { K_MAKE_FRACTAL_PTILE_TERRAIN, make_fractal_terrain, TRUE, 0, 0 },
119 { K_MAKE_RANDOM_TERRAIN, make_random_terrain, FALSE, 0, 0 },
120 { K_MAKE_EARTHLIKE_TERRAIN, make_earthlike_terrain, FALSE, 0, 0 },
121 { K_MAKE_MAZE_TERRAIN, make_maze_terrain, FALSE, 0, 0 },
122 { K_MAKE_RIVERS, make_rivers, TRUE, 0, 0 },
123 { K_MAKE_COUNTRIES, make_countries, TRUE, 0, 0 },
124 { K_MAKE_INDEPENDENT_UNITS, make_independent_units, TRUE, 0, 0 },
125 { K_MAKE_INITIAL_MATERIALS, make_initial_materials, TRUE, 0, 0 },
126 { K_NAME_UNITS_RANDOMLY, name_units_randomly, TRUE, 0, 0 },
127 { K_NAME_GEOGRAPHICAL_FEATURES, name_geographical_features, TRUE, 0, 0 },
128 { K_MAKE_ROADS, make_roads, TRUE, 0, 0 },
129 { K_MAKE_WEATHER, make_weather, TRUE, 0, 0 },
130 { K_MAKE_RANDOM_DATE, make_random_date, FALSE, 0, 0 },
131 { -1, NULL, 0, 0, 0 }
132 };
133
134 /* Allow environment vars to override compiled-in library and game. */
135
136 void
init_library_path(char * path)137 init_library_path(char *path)
138 {
139 char *xconqlib;
140 LibraryPath *image_path;
141
142 xconqlib = getenv("XCONQLIB");
143 if (empty_string(xconqlib)) {
144 if (!empty_string(path)) {
145 xconqlib = path;
146 } else {
147 xconqlib = default_library_pathname();
148 }
149 }
150 xconq_libs = (LibraryPath *) xmalloc(sizeof(LibraryPath));
151 xconq_libs->path = copy_string(xconqlib);
152 /* Add the pathname to the binary images directory, as an
153 alternate place to look. */
154 image_path = (LibraryPath *) xmalloc(sizeof(LibraryPath));
155 image_path->path = copy_string(default_images_pathname(xconqlib));
156 xconq_libs->next = image_path;
157 last_user_xconq_lib = NULL;
158 standard_game_name = getenv("XCONQSTANDARDGAME");
159 if (empty_string(standard_game_name))
160 standard_game_name = STANDARD_GAME;
161 }
162
163 void
add_library_path(char * path)164 add_library_path(char *path)
165 {
166 LibraryPath *lib;
167
168 /* A NULL path indicates that all the existing paths should go away. */
169 if (path == NULL) {
170 xconq_libs = last_user_xconq_lib = NULL;
171 return;
172 }
173 lib = (LibraryPath *) xmalloc(sizeof(LibraryPath));
174 lib->path = copy_string(path);
175 /* Insert this after the previous user-specified library, if there
176 was any, but before the default library places. */
177 if (last_user_xconq_lib != NULL) {
178 lib->next = last_user_xconq_lib->next;
179 last_user_xconq_lib->next = lib;
180 } else {
181 lib->next = xconq_libs;
182 xconq_libs = lib;
183 }
184 last_user_xconq_lib = lib;
185 }
186
187 /* This is a general init that prepares data structures to be filled in
188 by a game definition. It should run *before* command line parsing. */
189
190 void
init_data_structures(void)191 init_data_structures(void)
192 {
193 init_xrandom(-1);
194 init_lisp();
195 init_types();
196 init_globals();
197 init_namers();
198 init_world();
199 init_history();
200 init_sides();
201 #if 0
202 init_agreements();
203 #endif
204 init_units();
205 init_nlang();
206 init_help();
207 init_scorekeepers();
208 init_actions();
209 init_tasks();
210 init_ai_types();
211 init_write();
212 curdatestr = (char *)xmalloc(BUFSIZE);
213 }
214
215 /* Build the default list of synthesis methods. */
216
217 Obj *
g_synth_methods_default(void)218 g_synth_methods_default(void)
219 {
220 int i;
221 Obj *synthlist = lispnil, *synthlistend = lispnil, *tmp;
222
223 for (i = 0; synthmethods[i].key >= 0; ++i) {
224 if (synthmethods[i].dflt) {
225 tmp = cons(intern_symbol(keyword_name(
226 (enum keywords)synthmethods[i].key)),
227 lispnil);
228 if (synthlist == lispnil) {
229 synthlist = synthlistend = tmp;
230 } else {
231 set_cdr(synthlistend, tmp);
232 synthlistend = tmp;
233 }
234 }
235 }
236 #if (0)
237 /* Now alter the global variable to contain this list. */
238 set_g_synth_methods(synthlist);
239 #endif
240 return synthlist;
241 }
242
243 /* Game setup happens in several stages. */
244
245 void
start_game_load_stage(void)246 start_game_load_stage(void)
247 {
248 current_stage = game_load_stage;
249 /* Advance everybody else to this stage. */
250 if (my_rid > 0 && my_rid == master_rid)
251 broadcast_start_game_load();
252 }
253
254 /* Advance to variant setting. */
255
256 void
start_variant_setup_stage(void)257 start_variant_setup_stage(void)
258 {
259 current_stage = variant_setup_stage;
260 /* Advance everybody else to this stage. */
261 if (my_rid > 0 && my_rid == master_rid)
262 broadcast_start_variant_setup();
263 }
264
265 void
start_player_pre_setup_stage(void)266 start_player_pre_setup_stage(void)
267 {
268 do_module_variants(mainmodule, lispnil);
269 /* Stop accepting variant settings. */
270 current_stage = player_pre_setup_stage;
271 if (my_rid > 0 && my_rid == master_rid)
272 broadcast_variants_chosen();
273 }
274
275 void
start_player_setup_stage(void)276 start_player_setup_stage(void)
277 {
278 make_trial_assignments();
279 /* Start accepting player settings. */
280 current_stage = player_setup_stage;
281 /* Advance everybody else to this stage. */
282 if (my_rid > 0 && my_rid == master_rid)
283 broadcast_start_player_setup();
284 }
285
286 void
start_game_ready_stage(void)287 start_game_ready_stage(void)
288 {
289 /* Stop accepting player settings. */
290 current_stage = game_ready_stage;
291 /* Advance everybody else to this stage. */
292 if (my_rid > 0 && my_rid == master_rid)
293 broadcast_players_assigned();
294 }
295
296 static void
check_occs_on_completion(void)297 check_occs_on_completion(void)
298 {
299 int u = NONUTYPE, u2 = NONUTYPE, u3 = NONUTYPE;
300 int updated = TRUE;
301 int **pregnancies = NULL;
302
303 pregnancies = (int **)xmalloc(numutypes * sizeof(int *));
304 for_all_unit_types(u) {
305 pregnancies[u] = (int *)xmalloc(numutypes * sizeof(int));
306 for_all_unit_types(u2) {
307 pregnancies[u][u2] = uu_complete_occs_on_completion(u, u2);
308 #if (0) // Not necessary, since we start them with 0 instead of 1 CP now.
309 if (1 == u_cp(u2))
310 pregnancies[u][u2] += uu_incomplete_occs_on_completion(u, u2);
311 #endif
312 }
313 }
314 while (updated) {
315 updated = FALSE;
316 for_all_unit_types(u) {
317 for_all_unit_types(u2) {
318 if (pregnancies[u][u2]) {
319 // Cycle found.
320 if (u == u2) {
321 init_error(
322 "Cycle detected in occs-on-completion graph. %s is an ancestor of itself",
323 u_type_name(u));
324 return;
325 }
326 // Inherit pregnancies.
327 for_all_unit_types(u3) {
328 if (pregnancies[u2][u3] && !pregnancies[u][u3]) {
329 pregnancies[u][u3] = TRUE;
330 updated = TRUE;
331 }
332 }
333 if (updated)
334 break;
335 }
336 }
337 if (updated)
338 break;
339 }
340 }
341 }
342
343 /* Determine if a given advance is part of a cycle. Construct list of
344 "touched" advances. Check list before adding another to it. If the
345 advance is already in the list, then we have a cycle. */
346
347 int G_advances_graph_has_cycles = FALSE;
348 PackedBoolTable *G_advances_synopsis = NULL;
349
350 static void
init_advances_synopsis(void)351 init_advances_synopsis(void)
352 {
353 int a = NONATYPE, a2 = NONATYPE, a3 = NONATYPE;
354 int updated = TRUE;
355
356 G_advances_synopsis = create_packed_bool_table(numatypes, numatypes);
357 init_packed_bool_table(G_advances_synopsis);
358 for_all_advance_types(a) {
359 for_all_advance_types(a2) {
360 set_packed_bool(G_advances_synopsis, a, a2,
361 aa_needed_to_research(a, a2));
362 }
363 }
364 while (updated) {
365 updated = FALSE;
366 for_all_advance_types(a) {
367 for_all_advance_types(a2) {
368 if (get_packed_bool(G_advances_synopsis, a, a2)) {
369 if (a == a2) {
370 G_advances_graph_has_cycles = TRUE;
371 init_warning(
372 "Cycle detected in advances graph. %s is an ancestor of itself",
373 a_type_name(a));
374 return;
375 }
376 for_all_advance_types(a3) {
377 if (get_packed_bool(G_advances_synopsis, a2, a3)
378 && !get_packed_bool(G_advances_synopsis, a, a3)) {
379 set_packed_bool(G_advances_synopsis, a, a3, TRUE);
380 updated = TRUE;
381 }
382 }
383 if (updated)
384 break;
385 }
386 }
387 if (updated)
388 break;
389 }
390 }
391 }
392
393 static int
advance_is_part_of_advance_cycle(int a,int * alist,int alistsz)394 advance_is_part_of_advance_cycle(int a, int *alist, int alistsz)
395 {
396 int i = -1, a2 = NONATYPE, cyclefound = FALSE;
397 int *alist2 = NULL;
398
399 if (alistsz >= numatypes)
400 return FALSE;
401 for_all_advance_types(a2) {
402 if (aa_needed_to_research(a, a2)) {
403 for (i = 0; i < alistsz; ++i) {
404 /* If cycle detected, then immediately pull out. */
405 if (alist[i] == a2)
406 return TRUE;
407 }
408 alist2 = (int *)xmalloc((alistsz + 1) * sizeof(int));
409 memcpy(alist2, alist, alistsz * sizeof(int));
410 alist2[alistsz] = a2;
411 cyclefound = advance_is_part_of_advance_cycle(a2, alist2,
412 alistsz + 1);
413 free(alist2);
414 if (cyclefound)
415 return TRUE;
416 }
417 }
418 return FALSE;
419 }
420
421 /* Run a doublecheck on plausibility of game parameters. Additional
422 checks are performed elsewhere as needed, for instance during
423 random generation. Serious mistakes exit now, since they can cause
424 all sorts of strange behavior and core dumps. It's a little more
425 friendly to only exit at the end of the tests, so all the mistakes
426 can be found at once. */
427
428 /* In theory, if a game passes these tests, then Xconq will never crash. */
429
430 void
check_game_validity(void)431 check_game_validity(void)
432 {
433 int failed = FALSE, movers = FALSE, actors = FALSE;
434 int u1, u2, t1, t2, i, methkey, found, a = NONATYPE;
435 Obj *synthlist = g_synth_methods(), *methods, *method;
436
437 /* No more types allowed after this point. */
438 disallow_more_types();
439 /* See if any cycles exist in the advances graph. */
440 if (numatypes)
441 init_advances_synopsis();
442 /* Patch all cross-references. */
443 patch_object_references();
444 /* We must have at least one kind of unit. */
445 if (numutypes < 1) {
446 init_error("no unit types have been defined");
447 failed = TRUE;
448 }
449 check_occs_on_completion();
450 /* OK not to have any types of materials. */
451 /* We must have at least one kind of terrain. */
452 if (numttypes < 1) {
453 init_error("no terrain types have been defined");
454 failed = TRUE;
455 }
456 /* Make sure inter-country distances relate correctly. */
457 if (g_separation_min() >= 0
458 && g_separation_max() >= 0
459 && !(g_separation_min() <= g_separation_max())) {
460 init_warning("country separations %d to %d screwed up",
461 g_separation_min(), g_separation_max());
462 }
463 /* Check all method names in the synthesis list. */
464 for_all_list(synthlist, methods) {
465 method = car(methods);
466 found = FALSE;
467 if (symbolp(method)) {
468 methkey = keyword_code(c_string(method));
469 for (i = 0; synthmethods[i].key >= 0; ++i) {
470 if (methkey == synthmethods[i].key) {
471 found = TRUE;
472 break;
473 }
474 }
475 }
476 if (!found) {
477 sprintlisp(spbuf, method, BUFSIZE);
478 init_warning("bad synthesis method `%s', ignoring", spbuf);
479 }
480 }
481 /* (Need more general game checks.) */
482 max_zoc_range = -1;
483 /* Check that all the unit names and chars are distinct. */
484 for_all_unit_types(u1) {
485 for_all_unit_types(u2) {
486 #if 0 /* It may be desirable to have several unit types with the same
487 name, e.g. to make it possible to use different unit images for
488 different sides. */
489
490 /* Only do "upper triangle" of utype x utype matrix. */
491 if (u1 < u2) {
492 if (strcmp(u_type_name(u1), u_type_name(u2)) == 0) {
493 init_warning(
494 "unit types %d and %d are both named \"%s\"",
495 u1, u2, u_type_name(u1));
496 /* This is bad but not disastrous, so don't fail. */
497 }
498 }
499 #endif
500 if (uu_zoc_range(u1, u2) > max_zoc_range) {
501 max_zoc_range = uu_zoc_range(u1, u2);
502 }
503 }
504 }
505 /* (Eventually check material types also.) */
506 /* Check that all terrain names and chars are distinct. */
507 for_all_terrain_types(t1) {
508 for_all_terrain_types(t2) {
509 /* Only do "upper triangle" of ttype x ttype matrix. */
510 if (t1 < t2) {
511 if (strcmp(t_type_name(t1), t_type_name(t2)) == 0) {
512 init_warning(
513 "terrain types %d and %d are both named \"%s\"",
514 t1, t2, t_type_name(t1));
515 /* This is bad but not disastrous, so don't fail. */
516 }
517 /* Should check that colors are different from each other
518 and from builtin colors? */
519 }
520 }
521 }
522 /* Check various unit type properties. */
523 for_all_unit_types(u1) {
524 /* Can't make use of this yet, so error out if anybody tries. */
525 if (u_available(u1) != 1) {
526 init_error("unit type %d must always be available", u1);
527 failed = TRUE;
528 }
529 /* should be part of general bounds check */
530 if (u_cp(u1) < 0) {
531 init_error("unit type %d has nonpositive cp", u1);
532 failed = TRUE;
533 }
534 if (u_hp(u1) <= 0) {
535 init_error("unit type %d has nonpositive hp", u1);
536 failed = TRUE;
537 }
538 if (u_parts(u1) <= 0) {
539 init_error("unit type %d has nonpositive part count.", u1);
540 failed = TRUE;
541 }
542 if (u_parts(u1) > 0 && u_hp(u1) % u_parts(u1) != 0) {
543 init_error("unit type %d hp not a multiple of its parts.", u1);
544 failed = TRUE;
545 }
546 if (u_speed(u1) > 0) {
547 movers = TRUE;
548 }
549 if (u_acp(u1) > 0) {
550 actors = TRUE;
551 }
552 if (u_wrecked_type(u1) == u1) {
553 init_error("unit type %d wrecks to same type.", u1);
554 failed = TRUE;
555 }
556 }
557 /* If nothing can move and nothing can build, this will probably be
558 a really dull game, but there may be such games, do don't say
559 anything normally. */
560 if (numutypes > 0 && !actors) {
561 Dprintf("No actors have been defined.\n");
562 }
563 if (numutypes > 0 && !movers) {
564 Dprintf("No movers have been defined.\n");
565 }
566 if (numttypes > 0 && numcelltypes == 0) {
567 init_error("no terrain type has been allowed for cells");
568 failed = TRUE;
569 }
570 /* This is a really bad game definition, leave before we crash.
571 This would only be executed on systems where init_error doesn't
572 exit immediately. */
573 if (failed) {
574 exit(0);
575 }
576 Dprintf("Finished checking game design.\n");
577 Dprintf("It defines %d unit types, %d material types, %d terrain types",
578 numutypes, nummtypes, numttypes);
579 Dprintf(", %d advance types.\n", numatypes);
580 }
581
582 /* Finalize the scorekeepers. */
583
584 void
finalize_scorekeepers(void)585 finalize_scorekeepers(void)
586 {
587 Scorekeeper *sk = NULL;
588 SideMask whomask = NOSIDES, knowntomask = NOSIDES;
589 Side *side = NULL;
590 ParamBoxSide paramboxs;
591
592 for_all_scorekeepers(sk) {
593 /* If scorekeeper only applies to certain side classes,
594 then generate an appropriate 'whomask'. */
595 whomask = knowntomask = NOSIDES;
596 if (sk->who != lispnil) {
597 for_all_sides(side) {
598 paramboxs.side = side;
599 if (eval_boolean_expression(sk->who,
600 fn_test_side_in_sideclass,
601 FALSE, (ParamBox*)¶mboxs))
602 whomask = add_side_to_set(side, whomask);
603 }
604 sk->whomask = whomask;
605 }
606 /* If scorekeeper only is visible to certain side classes,
607 then generate an appropriate 'knowntomask'. */
608 if (sk->knownto != lispnil) {
609 for_all_sides(side) {
610 paramboxs.side = side;
611 if (eval_boolean_expression(sk->knownto,
612 fn_test_side_in_sideclass,
613 FALSE, (ParamBox*)¶mboxs))
614 knowntomask = add_side_to_set(side, knowntomask);
615 }
616 sk->knowntomask = knowntomask;
617 }
618 }
619 }
620
621 /* Calculate the values of global variables that are used everywhere. */
622
623 void
calculate_globals(void)624 calculate_globals(void)
625 {
626 using namespace Xconq;
627
628 int u1, u2;
629 Side *side;
630
631 /* The game is now completely defined; no further user-specified
632 changes (such as variants or player choices) can occur. */
633 gamedefined = TRUE;
634 /* Now that all sides are in place, finalize the scorekeepers. */
635 finalize_scorekeepers();
636 /* Calculate globals pertaining to the world and area. */
637 calculate_world_globals();
638 /* This needs to be precalculated instead of as-needed, since
639 range can be validly both negative and positive, so no way to
640 distinguish uninitialized. */
641 {
642 int u1, u2, range;
643 extern int max_detonate_on_approach_range;
644
645 max_detonate_on_approach_range = -1;
646 for_all_unit_types(u1) {
647 for_all_unit_types(u2) {
648 range = uu_detonate_approach_range(u1, u2);
649 max_detonate_on_approach_range =
650 max(range, max_detonate_on_approach_range);
651 }
652 }
653 }
654 /* Set up the cache of what each side can build. We do it here
655 because if it's too early, type_allowed_on_side will get filled
656 in with values that don't reflect side props such as its class. */
657 for_all_sides(side) {
658 update_canbuild_vector(side);
659 update_cancarry_vector(side);
660 if (numatypes > 0) {
661 update_canresearch_vector(side);
662 }
663 }
664 /* Set up other caches. */
665 cache__type_max_night_acp_from_any_terrains = NULL;
666 type_max_night_acp_from_any_terrains(0);
667 cache__type_max_acp_from_any_occs = NULL;
668 type_max_acp_from_any_occs(0);
669 cache__type_max_acp = NULL;
670 type_max_acp(0);
671 cache__type_max_speed_from_any_occs = NULL;
672 type_max_speed_from_any_occs(0);
673 cache__type_max_speed = NULL;
674 type_max_speed(0);
675 // Do we need to run auto-repair code?
676 for_all_unit_types(u1) {
677 for_all_unit_types(u2) {
678 if (could_auto_repair(u2, u1)) {
679 any_auto_repair = TRUE;
680 break;
681 }
682 }
683 if (0 < u_hp_recovery(u1))
684 any_hp_recovery = TRUE;
685 if (any_auto_repair || any_hp_recovery)
686 break;
687 }
688 Dprintf("Any auto repair: %d\n", any_auto_repair);
689 // Precalculate some useful info regarding auto-repair.
690 if (!cv__could_be_auto_repaired) {
691 cv__could_be_auto_repaired =
692 (short *)xmalloc(numutypes * sizeof(short));
693 cv__auto_repaired_range_max =
694 (short *) xmalloc(numutypes * sizeof(short));
695 for_all_unit_types(u1) {
696 cv__could_be_auto_repaired[u1] = FALSE;
697 cv__auto_repaired_range_max[u1] = -1;
698 }
699 }
700 if (any_auto_repair) {
701 for_all_unit_types(u1) {
702 for_all_unit_types(u2) {
703 if (uu_auto_repair(u2, u1) > 0) {
704 cv__could_be_auto_repaired[u1] = TRUE;
705 cv__auto_repaired_range_max[u1] =
706 max(cv__auto_repaired_range_max[u1],
707 uu_auto_repair_range(u2, u1));
708 }
709 }
710 }
711 }
712 /* Find out if any unit types could automatically change type to
713 others. */
714 for_all_unit_types(u1) {
715 if (is_unit_type(u_auto_upgrade_to(u1))) {
716 any_auto_change_types = TRUE;
717 break;
718 }
719 }
720 }
721
722 static void
disallow_more_types(void)723 disallow_more_types(void)
724 {
725 /* Turn off the addition of more types in case read_forms
726 failed to do that. */
727 if (canaddttype) {
728 disallow_more_terrain_types();
729 }
730 if (canaddutype) {
731 disallow_more_unit_types();
732 }
733 if (canaddmtype) {
734 disallow_more_material_types();
735 }
736 if (canaddatype) {
737 disallow_more_advance_types();
738 }
739 }
740
741 /* Clean up all the objects and cross-references. NOTE: this may be
742 called multiple times! It should not have any additional effects
743 if called more than once. */
744
745 static void
patch_object_references(void)746 patch_object_references(void)
747 {
748 Unit *unit, *transport, *occ;
749 UnitView *uview;
750 Obj *utref, *utorig;
751 Side *side;
752 int id;
753
754 /* This cannot be called as part of prealloc_debug(), since that
755 can occur before any types are defined. This should happen
756 after all unit types have been defined but before a first save;
757 this is as good a place as any. */
758 shortest_unique_name(0);
759 /* Use read-in ids to fill in side slots that point to other objects. */
760 for_all_sides(side) {
761 if (side->playerid >= 0) {
762 side->player = find_player(side->playerid);
763 }
764 if (side->controlled_by_id >= 0) {
765 side->controlled_by = side_n(side->controlled_by_id);
766 }
767 if (side->self_unit_id > 0) {
768 side->self_unit = find_unit(side->self_unit_id);
769 }
770 }
771 for_all_units(unit) {
772 /* It's possible that dead units got read in, so check. */
773 if (alive(unit)) {
774 if (unit->transport_id != lispnil) {
775 transport = NULL;
776 utref = utorig = unit->transport_id;
777 /* We have a Lisp object; use it to identify a particular
778 unit as the transport. */
779 if (symbolp(utref) && boundp(utref)) {
780 utref = symbol_value(utref);
781 }
782 if (numberp(utref)) {
783 transport = find_unit(c_number(utref));
784 if (transport == NULL)
785 init_warning("could not find a transport id %d for %s",
786 c_number(utref), unit_desig(unit));
787 } else if (stringp(utref)) {
788 transport = find_unit_by_name(c_string(utref));
789 if (transport == NULL)
790 init_warning(
791 "could not find a transport named \"%s\" for %s",
792 c_string(utref), unit_desig(unit));
793 } else if (symbolp(utref)) {
794 transport = find_unit_by_symbol(utref);
795 if (transport == NULL)
796 init_warning(
797 "could not find a transport with sym \"%s\" for %s",
798 c_string(utref), unit_desig(unit));
799 } else {
800 /* not a recognized way to refer to a unit */
801 sprintlisp(tmpbuf, utorig, BUFSIZE);
802 init_warning("could not find transport %s for %s",
803 tmpbuf, unit_desig(unit));
804 }
805 /* It is important to make sure that unit->x, and
806 unit->y are negative at this point. Otherwise, the
807 coverage will be messed up for units put into
808 transports that have not yet been placed. They
809 will be covered for entering the cell, and again
810 when the transport enters the cell. */
811 if (transport != NULL) {
812 if (transport != unit->transport) {
813 if (unit->transport != NULL) {
814 leave_transport(unit);
815 }
816 /* (also check that this is a valid transport type?) */
817 enter_transport(unit, transport);
818 }
819 } else {
820 /* (could let the unit enter the cell,
821 or could make it infinitely postponed) */
822 }
823 } else {
824 /* Check that the unit's location is meaningful. */
825 if (!inside_area(unit->x, unit->y)) {
826 if (inside_area(unit->prevx, unit->prevy)) {
827 /* First try to just drop the unit in the cell. */
828 if (type_can_occupy_cell(unit->type,
829 unit->prevx, unit->prevy)
830 && type_survives_in_cell(unit->type,
831 unit->prevx,
832 unit->prevy)) {
833 enter_cell(unit, unit->prevx, unit->prevy);
834 /* There was no room in the terrain. */
835 } else {
836 /* Search for a transport that unit can enter. */
837 for_all_stack(unit->prevx, unit->prevy, transport) {
838 /* The important question is if the putative
839 transport trusts unit, and not if unit
840 trust the transport. */
841 if (unit_trusts_unit(transport, unit)
842 && can_occupy(unit, transport)) {
843 enter_transport(unit, transport);
844 break;
845 }
846 }
847 /* We didn't find a transport. Try to load as
848 many units as possible from this cell into unit,
849 and then try to enter the cell again. */
850 if (!inside_area(unit->x, unit->y)) {
851 /* Note: we cannot iterate over
852 for_all_stack here since occ entering unit
853 will break the nexthere link. */
854 for_all_units(occ) {
855 if (occ->x == unit->prevx
856 && occ->y == unit->prevy
857 /* We are only interested in top-level
858 units. */
859 && occ->transport == NULL
860 /* The important question is if unit
861 trust the putative occ, and not if
862 the occ trust unit. */
863 && unit_trusts_unit(unit, occ)
864 && can_occupy(occ, unit)) {
865 leave_cell(occ);
866 enter_transport(occ, unit);
867 }
868 }
869 /* Now try to enter the cell again. */
870 enter_cell(unit, unit->prevx, unit->prevy);
871 }
872 if (!inside_area(unit->x, unit->y)) {
873 init_warning("Can't put %s at %d,%d (%s)",
874 unit_desig(unit),
875 unit->prevx, unit->prevy,
876 (type_can_occupy_cell(unit->type,
877 unit->prevx,
878 unit->prevy)
879 ? "deadly terrain" : "no room"));
880 }
881 }
882 /* This prevents attempts to do a second enter_cell
883 during initialization. */
884 unit->prevx = unit->prevy = -1;
885 } else if (unit->prevx == -1 && unit->prevy == -1) {
886 /* This will be left alone - should have pos
887 filled in later. */
888 } else if (unit->cp >= 0) {
889 /* Warn, but only if there's no good reason
890 for the unit to have an offworld
891 position. */
892 if (area.fullwidth == 0) {
893 init_warning(
894 "%s is at offworld location, left there",
895 unit_desig(unit));
896 }
897 /* This will make it be a reinforcement. */
898 unit->cp = -1;
899 }
900 }
901 }
902 /* Make sure that side numbering will use only new numbers. */
903 if (unit->side != NULL) {
904 if (unit->number > 0) {
905 (unit->side->counts)[unit->type] =
906 max((unit->side->counts)[unit->type], 1 + unit->number);
907 }
908 } else {
909 /* Trash the numbers on indep units. */
910 unit->number = 0;
911 }
912 if (completed(unit)) {
913 if (unit->act == NULL)
914 init_unit_actorstate(unit, TRUE);
915 /* Restore acp that wasn't written out because it was
916 the most normal value. */
917 if (unit->act && unit->act->acp < u_acp_min(unit->type))
918 unit->act->acp = u_acp(unit->type);
919 /* Restore initacp that wasn't written out because it
920 was the normal value. */
921 if (unit->act && unit->act->initacp < u_acp_min(unit->type))
922 unit->act->initacp = u_acp(unit->type);
923 /* Might already have a plan, leave alone if so. */
924 if (unit->plan == NULL) {
925 init_unit_plan(unit);
926 }
927 }
928 /* Maybe fill in a formation's leader with a unit. */
929 if (unit->plan != NULL
930 && unit->plan->formation != NULL) {
931 id = unit->plan->formation->args[0];
932 if (id > 0) {
933 unit->plan->funit = find_unit(id);
934 if (unit->plan->funit == NULL) {
935 init_warning(
936 "%s missing leader #%d, cancelling formation",
937 unit_desig(unit), id);
938 unit->plan->formation = NULL;
939 }
940 }
941 }
942 } else {
943 /* Dead units need to be disentangled from anything that
944 might have been done to them. For instance, a module
945 might include a standard collection of units, but then
946 follow up by removing some of those units, and can do
947 it by setting hp == 0. We want this to work
948 consistently and reliably. */
949 /* Null this out, any possible unit reference is useless. */
950 unit->transport = NULL;
951 if (inside_area(unit->x, unit->y)) {
952 leave_cell(unit);
953 }
954 }
955 }
956 /* Unit views are read in before units (with the sides) so we
957 must also patch the uview->unit links. */
958 for_all_unit_views(uview) {
959 uview->unit = find_unit(uview->id);
960 }
961 }
962
963 /* Make up a proposed side/player assignment, creating sides and players
964 as necessary. Lock down any assignments that should not be changed,
965 but leave everything to be changed as desired. */
966
967 /* (when does locking get done?) */
968
969 void
make_trial_assignments(void)970 make_trial_assignments(void)
971 {
972 int i = 0;
973 Side *side;
974 Player *player;
975
976 Dprintf("Making trial side/player assignments\n");
977 /* Fill in the sides' predefined default and range of initial
978 advantage. */
979 for_all_sides(side) {
980 init_side_advantage(side);
981 }
982 /* Quick check to make sure we don't have more peers than available
983 sides. */
984 /*! \note We must ensure elsewhere that that numremotes is not allowed
985 g_sides_max(). */
986 if (numremotes > g_sides_max())
987 init_warning(
988 "A total of %d peers are networked, but only %d sides are available",
989 numremotes, g_sides_max());
990 /* Ensure that we have the minimal required number of sides. Only
991 real sides increment numsides, so it will equal g_sides_min or
992 numremotes when we are done. However, the total number of
993 sides including indepside (numtotsides) will equal g_sides_min + 1 or
994 numremotes + 1. */
995 while (numsides < max(g_sides_min(), numremotes)) {
996 make_up_a_side();
997 }
998 /* Continue to add sides up to the wanted default number, but don't
999 exceed g_sides_max in case we are using a default g_sides_wanted
1000 which is higher than g_sides_max. */
1001 while (numsides < min(g_sides_wanted(), g_sides_max())) {
1002 make_up_a_side();
1003 }
1004 /* Keep adding sides if we have unassigned players up to the limit
1005 set by g_sides_max. Note: numplayers - 1 since the indepside now
1006 has a player. */
1007 while (numsides < min(numplayers - 1, g_sides_max())) {
1008 make_up_a_side();
1009 }
1010 /* Kick indepside out of the game if it is unnecessary. */
1011 if (!indepside_needed())
1012 indepside->ingame = FALSE;
1013
1014 /* Put in all the sides. */
1015 for_all_sides(side) {
1016 assignments[i++].side = side;
1017 }
1018 /* First create a player to handle indepside if necessary. */
1019 if (numplayers < indepside->ingame) {
1020 add_player();
1021 }
1022 /* Add remote players. */
1023 if (numremotes > 0) {
1024 add_remote_players();
1025 }
1026 /* If only one player (the indepside player) has been created so
1027 far, make one that is human-run, presumably by the person who
1028 started up this program. */
1029 if (numplayers == indepside->ingame) {
1030 add_default_player();
1031 }
1032 if (numtotsides < numplayers) {
1033 /* We have too many players. */
1034 init_warning("too many players (%d) for %d sides, ignoring extra",
1035 numplayers, numtotsides);
1036 }
1037 /* Make any prespecified assignments. */
1038 for (i = 0; i < numtotsides; ++i) {
1039 if (assignments[i].side != NULL
1040 && assignments[i].side->player != NULL
1041 && assignments[i].player == NULL) {
1042 trial_assign_player(i, assignments[i].side->player);
1043 /* (should this assignment be locked?) */
1044 }
1045 }
1046 /* Assign any remaining players. */
1047 player = playerlist;
1048 for (i = 0; i < numtotsides; ++i) {
1049 if (assignments[i].side != NULL
1050 && assignments[i].side->ingame
1051 && assignments[i].player == NULL) {
1052 for (; player != NULL; player = player->next) {
1053 if (player->side == NULL) {
1054 trial_assign_player(i, player);
1055 break;
1056 }
1057 }
1058 }
1059 }
1060 /* Add default players for sides with none (in separate loop so player
1061 creation doesn't confuse player list traversal above). Don't
1062 add for any sides not actually participating in the game. */
1063 for (i = 0; i < numtotsides; ++i) {
1064 if (assignments[i].side != NULL
1065 && assignments[i].side->ingame
1066 && assignments[i].player == NULL) {
1067 player = add_player();
1068 /* Default players are always AIs (at least for now). */
1069 if (!initially_no_ai)
1070 player->aitypename = "mplayer";
1071 trial_assign_player(i, player);
1072 }
1073 }
1074 /* Finally set the indepside AI type correctly. */
1075 if (indepside->ingame) {
1076 if (indepside->player->aitypename) {
1077 /* If a player already was assigned, do nothing. */
1078 } else if (g_indepside_has_ai()) {
1079 /* Use iplayer by default if indepside should have an AI. */
1080 indepside->player->aitypename = "iplayer";
1081 } else {
1082 /* Else set the AI to NULL. */
1083 indepside->player->aitypename = NULL;
1084 }
1085 /* Hoist the Jolly Roger if indepside has an AI and does
1086 not already have a flag that was read from the module. */
1087 if (indepside->player->aitypename
1088 && strcmp("none", indepside->emblemname) == 0) {
1089 indepside->emblemname = "flag-pirate";
1090 }
1091 }
1092 /* This warning can happen if there are more players than active
1093 sides. */
1094 for_all_players(player) {
1095 if (player->side == NULL) {
1096 init_warning("Player %s not given a side", player_desig(player));
1097 }
1098 }
1099 /* At this point, we have matching sides and players, ready to be
1100 rearranged if desired. */
1101 }
1102
1103
1104 /* Returns true if indepside already has units or may get units made. */
1105
1106 int
indepside_needed(void)1107 indepside_needed(void)
1108 {
1109 Unit *unit;
1110 int u, t;
1111
1112 /* First check what the game designer thought about this. */
1113 if (g_no_indepside_ingame())
1114 return FALSE;
1115 /* Then check existing (preassigned) units. */
1116 for_all_units(unit) {
1117 if (unit->side == indepside)
1118 return TRUE;
1119 }
1120 /* Then check if independent units will ever be made. */
1121 for_all_unit_types(u) {
1122 if (u_indep_growth(u) > 0 || u_indep_near_start(u) > 0)
1123 return TRUE;
1124 for_all_terrain_types(t) {
1125 if (ut_indep_density(u, t) > 0
1126 && ut_vanishes_on(u, t) != TRUE) {
1127 return TRUE;
1128 }
1129 }
1130 }
1131 return FALSE;
1132 }
1133
1134 static void
trial_assign_player(int i,Player * player)1135 trial_assign_player(int i, Player *player)
1136 {
1137 assignments[i].player = player;
1138 player->side = assignments[i].side;
1139 (assignments[i].side)->player = player;
1140 /* Set the player's advantage to be the side's advantage, if defined. */
1141 if (assignments[i].player != NULL
1142 && assignments[i].player->advantage == 0) {
1143 assignments[i].player->advantage = assignments[i].side->advantage;
1144 }
1145 Dprintf("Tentatively assigned %s to %s%s\n",
1146 side_desig(assignments[i].side),
1147 player_desig(assignments[i].player),
1148 (assignments[i].locked ? " (locked)" : ""));
1149 }
1150
1151 /* Create a random side with default characteristics. */
1152
1153 Side *
make_up_a_side(void)1154 make_up_a_side(void)
1155 {
1156 extern Obj *side_defaults;
1157
1158 Side *side = create_side();
1159
1160 if (side == NULL) {
1161 run_error("could not create a side");
1162 return NULL;
1163 }
1164 fill_in_side(side, side_defaults, FALSE);
1165 make_up_side_name(side);
1166 init_side_advantage(side);
1167 Dprintf("Made up a side %s\n", side_desig(side));
1168 return side;
1169 }
1170
1171 /* If undefined, seed a side's advantage and allowable range from the
1172 global values. */
1173
1174 void
init_side_advantage(Side * side)1175 init_side_advantage(Side *side)
1176 {
1177 /* Set up the default and range of initial advantages. */
1178 if (side->advantage == 0)
1179 side->advantage = g_advantage_default();
1180 if (side->minadvantage == 0)
1181 side->minadvantage = g_advantage_min();
1182 if (side->maxadvantage == 0)
1183 side->maxadvantage = g_advantage_max();
1184 if (side->maxadvantage == 0) {
1185 int i, methkey, found = FALSE;
1186 Obj *synthlist = g_synth_methods(), *methods, *method;
1187
1188 for_all_list(synthlist, methods) {
1189 method = car(methods);
1190 if (symbolp(method)) {
1191 methkey = keyword_code(c_string(method));
1192 for (i = 0; synthmethods[i].key >= 0; ++i) {
1193 if (methkey == synthmethods[i].key) {
1194 found = TRUE;
1195 break;
1196 }
1197 }
1198 }
1199 if (found) {
1200 if (synthmethods[i].key == K_MAKE_COUNTRIES) {
1201 int u, var = FALSE;
1202
1203 for_all_unit_types(u) {
1204 if (u_start_with(u) > 0) {
1205 var = TRUE;
1206 break;
1207 }
1208 }
1209 if (var)
1210 side->maxadvantage = 10;
1211 }
1212 }
1213 }
1214 }
1215 /* If we're not getting any guidance from global defaults, just
1216 set to 1. */
1217 if (side->minadvantage == 0)
1218 side->minadvantage = 1;
1219 if (side->maxadvantage == 0)
1220 side->maxadvantage = side->minadvantage;
1221 }
1222
1223 /* Add a side and a player to go with it (used by interfaces). */
1224
1225 int
add_side_and_player(void)1226 add_side_and_player(void)
1227 {
1228 int n;
1229 Side *side;
1230 Player *player;
1231
1232 side = make_up_a_side();
1233 if (side == NULL)
1234 return -1;
1235 n = numtotsides - 1;
1236 assignments[n].side = side;
1237 player = add_player();
1238 player->aitypename = next_ai_type_name(NULL);
1239 assignments[n].player = player;
1240 player->side = assignments[n].side;
1241 (assignments[n].side)->player = player;
1242 /* Set the player's advantage to be the side's advantage, if not
1243 already set. */
1244 if (player->advantage == 0) {
1245 player->advantage = side->advantage;
1246 }
1247 /* Return the new side's position in the assignment array. */
1248 return n;
1249 }
1250
1251 void
set_player_advantage(int n,int newadv)1252 set_player_advantage(int n, int newadv)
1253 {
1254 Player *player;
1255
1256 player = assignments[n].player;
1257 if (player != NULL)
1258 player->advantage = newadv;
1259 /* (should complain otherwise) */
1260 /* (should check limits) */
1261 }
1262
1263 void
rename_side_for_player(int n,int which)1264 rename_side_for_player(int n, int which)
1265 {
1266 Obj *entry;
1267 Side *side;
1268
1269 /* Don't rename indepside. */
1270 if (n == 0)
1271 return;
1272 side = assignments[n].side;
1273 side->name = side->noun = side->pluralnoun = side->adjective = NULL;
1274 if (which >= 0) {
1275 entry = elt(g_side_lib(), which);
1276 /* Take away the optional weighting number. */
1277 if (numberp(car(entry)))
1278 entry = cdr(entry);
1279 fill_in_side(side, entry, FALSE);
1280 } else {
1281 make_up_side_name(side);
1282 }
1283 }
1284
1285 /* Given the name of an AI type, assign it to the player at the given
1286 position in the assignments array. */
1287
1288 void
set_ai_for_player(int n,char * aitype)1289 set_ai_for_player(int n, char *aitype)
1290 {
1291 Player *player;
1292
1293 player = assignments[n].player;
1294 if (player == NULL)
1295 return;
1296 if (empty_string(aitype) || find_ai_type(aitype) > 0) {
1297 player->aitypename = aitype;
1298 if (player->side == indepside) {
1299 /* Toggle the Jolly Roger on or off if the indepside gains or loses
1300 control by a human or an ai. However, always keep a flag that was
1301 assigned by the game module. */
1302 if (empty_string(aitype)
1303 && empty_string(player->displayname)
1304 && strcmp("flag-pirate", indepside->emblemname) == 0) {
1305 indepside->emblemname = "none";
1306 /* Otherwise, we fly the Jolly Roger. */
1307 } else if (strcmp("none", indepside->emblemname) == 0) {
1308 indepside->emblemname = "flag-pirate";
1309 }
1310 }
1311 /* Needed to flush out any existing AIs in saved games. */
1312 set_side_ai(player->side, aitype);
1313 } else {
1314 init_warning("\"%s\" is not a known AI type name", aitype);
1315 }
1316 }
1317
1318 /* This can be used by interfaces to exchange players between one side and
1319 another. */
1320
1321 int
exchange_players(int n,int n2)1322 exchange_players(int n, int n2)
1323 {
1324 int i;
1325 Player *tmpplayer = assignments[n].player;
1326
1327 if (n < 0)
1328 n = 0;
1329 if (n2 < 0) {
1330 for (i = n + 1; i <= numtotsides + n; ++i) {
1331 n2 = i % numtotsides;
1332 if (assignments[n2].side && (assignments[n2].side)->ingame)
1333 break;
1334 }
1335 /* No sides to exchange with, return. */
1336 if (i == numtotsides + n)
1337 return -1;
1338 }
1339
1340 #if 0
1341 /* Don't switch with the indepside player. */
1342 if (n2 == 0)
1343 n2 = 1;
1344 #endif
1345
1346 assignments[n].player = assignments[n2].player;
1347 assignments[n2].player = tmpplayer;
1348 /* Doesn't seem like these should be needed, but they are. */
1349 assignments[n].player->side = assignments[n].side;
1350 assignments[n].side->player = assignments[n].player;
1351 assignments[n2].player->side = assignments[n2].side;
1352 assignments[n2].side->player = assignments[n2].player;
1353 /* Toggle the Jolly Roger on or off if the indepside gains or loses
1354 control by a human or an ai. However, always keep a flag that was
1355 assigned by the game module. */
1356 if (indepside->player) {
1357 if (empty_string(indepside->player->aitypename)
1358 && empty_string(indepside->player->displayname)
1359 && strcmp("flag-pirate", indepside->emblemname) == 0) {
1360 indepside->emblemname = "none";
1361 }
1362 if ((!empty_string(indepside->player->aitypename)
1363 || !empty_string(indepside->player->displayname))
1364 && strcmp("none", indepside->emblemname) == 0) {
1365 indepside->emblemname = "flag-pirate";
1366 }
1367 }
1368 return n2;
1369 }
1370
1371 extern int nextsideid, nextplayerid; /* From side.c. */
1372 extern void return_default_colorname(Side *side); /* Ditto. */
1373
1374 int
remove_side_and_player(int s)1375 remove_side_and_player(int s)
1376 {
1377 Side * side, *side2;
1378 Player *player;
1379 Unit *unit;
1380 int n;
1381
1382 side = side_n(s);
1383 /* We are trying to remove a side that does not exist. */
1384 if (!side) {
1385 Dprintf("Trying to remove non-existing side %d.\n", s);
1386 return FALSE;
1387 }
1388 /* We cannot remove a side that is assigned to a human player. */
1389 if (side->player->displayname)
1390 return FALSE;
1391 /* Nor can we remove the indepside. */
1392 if (side == indepside)
1393 return FALSE;
1394 /* We need a minimum number of sides. */
1395 if (numsides == g_sides_min())
1396 return FALSE;
1397
1398 /* Give back the default color so that it can be used by a new side. */
1399 return_default_colorname(side);
1400
1401 /* Give any units to indepside if ingame, or else kill them. */
1402 for_all_units(unit) {
1403 /* Can't use for_all_side_units this early during startup. */
1404 if (unit->side == side) {
1405 if (indepside->ingame) {
1406 change_unit_side(unit, indepside, H_SIDE_LOST, NULL);
1407 } else {
1408 kill_unit(unit, -1);
1409 }
1410 }
1411 }
1412 /* First assign a new player list head if required. This is not necessary
1413 for the side list, since indepside (which we cannot delete) always is the
1414 list head. However, it is possible to delete the first side in a game where
1415 the indepside has no player, in which case the deleted side's player is the
1416 player list head. */
1417 if (playerlist == side->player) {
1418 if (side->player->next) {
1419 playerlist = side->player->next;
1420 /* It should not be possible to delete a side if its player is the only
1421 player since this player should always be a human player but a buggy
1422 interface might try. */
1423 } else {
1424 Dprintf("Trying to remove dside (interface bug).\n");
1425 return FALSE;
1426 }
1427 }
1428 /* Patch up the side list and the assignments array. */
1429 for_all_sides(side2) {
1430 n = side2->id;
1431 if (side2->next && side2->next == side) {
1432 /* If the removed side was the last side in the list we make
1433 the side before it the new last side. */
1434 if (side == lastside) {
1435 lastside = side2;
1436 side2->next = NULL;
1437 /* else we make the side before it point to the side after it. */
1438 } else {
1439 side2->next = side->next;
1440 }
1441 }
1442 /* Decrement assignments and side numbers for all sides after the
1443 removed side by 1. */
1444 if (n > side->id) {
1445 assignments[n - 1].side = side2;
1446 assignments[n - 1].player = side2->player;
1447 side2->id--;
1448 }
1449 }
1450 /* The patch up the player list. */
1451 for_all_players(player) {
1452 if (player->next && player->next == side->player) {
1453 /* If the removed side's player was the last player in the list,
1454 we make the player before it the last player. */
1455 if (side->player == last_player) {
1456 last_player = player;
1457 player->next = NULL;
1458 /* else we make the player before it point to the player after it. */
1459 } else {
1460 player->next = side->player->next;
1461 }
1462 }
1463 /* Decrement the ids of all players after the removed side's player by 1. */
1464 if (player->id > side->player->id) {
1465 player->id--;
1466 }
1467 }
1468 /* Decrement various globals by 1. */
1469 --numsides;
1470 --numtotsides;
1471 --numplayers;
1472 --nextsideid;
1473 --nextplayerid;
1474
1475 /* Reclaim some memory. Not everything can be freed. For example, there is
1476 no support for deallocating lisp objects, so the game will crash if you do.
1477 Nor can the default doctrine be freed. */
1478
1479 free(side->trusts);
1480 free(side->trades);
1481 free(side->counts);
1482 free(side->tech);
1483 free(side->inittech);
1484 free(side->numunits);
1485 free(side->gaincounts);
1486 free(side->losscounts);
1487 free(side->atkstats);
1488 free(side->hitstats);
1489 free(side->advance);
1490 free(side->canresearch);
1491 free(side->treasury);
1492 free(side->c_rates);
1493 free(side->unitnamers);
1494 free(side->startwith);
1495 free(side->action_priorities);
1496 free(side->already_seen);
1497 free(side->already_seen_indep);
1498 free(side->udoctrine);
1499 free(side->orders);
1500 free(side->last_order);
1501 free(side->terrview);
1502 free(side->auxterrview);
1503 free(side->auxterrviewdate);
1504 free(side->terrviewdate);
1505 free(side->unit_views);
1506 free(side->materialview);
1507 free(side->materialviewdate);
1508 free(side->tempview);
1509 free(side->tempviewdate);
1510 free(side->cloudview);
1511 free(side->cloudbottomview);
1512 free(side->cloudheightview);
1513 free(side->cloudviewdate);
1514 free(side->windview);
1515 free(side->windviewdate);
1516 free(side->curactor);
1517 free(side->ai);
1518
1519 free(player);
1520 free(side);
1521
1522 /* Don't leave any bogus pointers around. */
1523 player = NULL;
1524 side = NULL;
1525
1526 return TRUE;
1527 }
1528
1529 /* Synthesis methods fill in whatever is not fixed by game modules or by
1530 the player(s). */
1531
1532 void
run_synth_methods(void)1533 run_synth_methods(void)
1534 {
1535 int i, methkey, found, rslt;
1536 Obj *restlist, *done, *synthlist, *methods, *method, *donelist;
1537
1538 /* Restore any saved state for synthmethods. */
1539 if (!gameinited) {
1540 for_all_list(g_synth_done(), restlist) {
1541 done = car(restlist);
1542 method = car(done);
1543 found = FALSE;
1544 if (symbolp(method)) {
1545 methkey = keyword_code(c_string(method));
1546 for (i = 0; synthmethods[i].key >= 0; ++i) {
1547 if (methkey == synthmethods[i].key) {
1548 found = TRUE;
1549 synthmethods[i].calls = c_number(cadr(done));
1550 synthmethods[i].runs = c_number(caddr(done));
1551 break;
1552 }
1553 }
1554 } else {
1555 init_warning("non-symbol in synthesis list");
1556 }
1557 if (!found) {
1558 sprintlisp(spbuf, method, BUFSIZE);
1559 init_warning("bad synthesis method %s, ignoring", spbuf);
1560 }
1561 }
1562 }
1563 /* Make sure no dead units get saved. */
1564 flush_dead_units();
1565 /* Make a consistent ordering of units. */
1566 sort_units(TRUE);
1567 synthlist = g_synth_methods();
1568 Dprintf("Will run syntheses ");
1569 Dprintlisp(synthlist);
1570 Dprintf("\n");
1571 donelist = lispnil;
1572 for_all_list(synthlist, methods) {
1573 method = car(methods);
1574 found = FALSE;
1575 if (symbolp(method)) {
1576 methkey = keyword_code(c_string(method));
1577 for (i = 0; synthmethods[i].key >= 0; ++i) {
1578 if (methkey == synthmethods[i].key) {
1579 found = TRUE;
1580 if (!gameinited && synthmethods[i].calls == 0) {
1581 rslt = (*synthmethods[i].fn)(synthmethods[i].calls,
1582 synthmethods[i].runs);
1583 ++(synthmethods[i].calls);
1584 if (rslt)
1585 ++(synthmethods[i].runs);
1586 }
1587 break;
1588 }
1589 }
1590 donelist = cons(cons(method,
1591 cons(new_number(synthmethods[i].calls),
1592 cons(new_number(synthmethods[i].runs),
1593 lispnil))),
1594 donelist);
1595 } else {
1596 init_warning("non-symbol in synthesis list");
1597 }
1598 if (!found) {
1599 sprintlisp(spbuf, method, BUFSIZE);
1600 init_warning("bad synthesis method %s, ignoring", spbuf);
1601 }
1602 }
1603 set_g_synth_done(reverse(donelist));
1604 }
1605
1606 int
get_synth_method_uses(int methkey,int * calls,int * runs)1607 get_synth_method_uses(int methkey, int *calls, int *runs)
1608 {
1609 int i;
1610
1611 for (i = 0; synthmethods[i].key >= 0; ++i) {
1612 if (methkey == synthmethods[i].key) {
1613 *calls = synthmethods[i].calls;
1614 *runs = synthmethods[i].runs;
1615 return TRUE;
1616 }
1617 }
1618 return FALSE;
1619 }
1620
1621 int
make_weather(int calls,int runs)1622 make_weather(int calls, int runs)
1623 {
1624 int x, y, winddir, t, var;
1625 extern int maxclouds;
1626
1627 if (maxclouds > 0) {
1628 if (!clouds_defined()) {
1629 allocate_area_clouds();
1630 for_all_cells(x, y) {
1631 t = terrain_at(x, y);
1632 /* Vary the cloud cover randomly across the range of possibilities. */
1633 var = t_clouds_max(t) - t_clouds_min(t);
1634 if (var > 0)
1635 var = xrandom(var + 1);
1636 set_raw_cloud_at(x, y, t_clouds_min(t) + var);
1637 }
1638 }
1639 }
1640 if (maxwindforce > 0) {
1641 if (!winds_defined()) {
1642 allocate_area_winds();
1643 if (g_wind_mix_range() > 0) {
1644 /* Make all winds start in the same direction. */
1645 /* Initial variation will randomize. */
1646 winddir = random_dir();
1647 for_all_cells(x, y) {
1648 set_wind_at(x, y, winddir,
1649 t_wind_force_avg(terrain_at(x, y)));
1650 }
1651 } else {
1652 for_all_cells(x, y) {
1653 set_wind_at(x, y, random_dir(),
1654 t_wind_force_avg(terrain_at(x, y)));
1655 }
1656 }
1657 }
1658 }
1659 return TRUE;
1660 }
1661
1662 /* Set the starting date/time to a random value within a given range. */
1663
1664 int
make_random_date(int calls,int runs)1665 make_random_date(int calls, int runs)
1666 {
1667 int n;
1668
1669 /* Don't bother if the initial date has been set explicitly. */
1670 if (!empty_string(g_initial_date()))
1671 return FALSE;
1672 if (empty_string(g_initial_date_min()))
1673 return FALSE;
1674 if (empty_string(g_initial_date_max()))
1675 return FALSE;
1676 /* Use the low end of the date range as a starting place for date
1677 calculations. */
1678 set_initial_date(g_initial_date_min());
1679 n = turns_between(g_initial_date_min(), g_initial_date_max());
1680 /* Now bump the starting date to its random place. */
1681 set_initial_date(absolute_date_string(xrandom(n) + 1));
1682 return TRUE;
1683 }
1684
1685 /* The final init cleans up various stuff. */
1686
1687 void
final_init(void)1688 final_init(void)
1689 {
1690 Side *side;
1691
1692 /* Fill in any empty doctrines. */
1693 for_all_sides(side) {
1694 init_doctrine(side);
1695 }
1696 /* Make sure each side has a self-unit if it needs one. */
1697 for_all_sides(side) {
1698 init_self_unit(side);
1699 }
1700 /* At this point we should be ready to roll. Any inconsistencies
1701 hereafter will be fatal. */
1702 check_consistency();
1703 cache_possible_types();
1704 kill_excess_units();
1705 /* Count the units initially present. */
1706 init_side_balance();
1707 /* Fix up garbled view data. */
1708 init_all_views();
1709 configure_sides();
1710 /* Check again, just to be sure. */
1711 check_consistency();
1712 create_game_help_nodes();
1713 /* Set up the scores to be attached to each side. */
1714 init_scores();
1715 final_init_world();
1716 init_run();
1717 /* Start the recording of history. */
1718 start_history();
1719 /* Compute and cache AI/planning data. */
1720 ai_init_shared();
1721 #ifdef DEBUGGING
1722 /* Make sure that any debugging-related allocation is done. */
1723 if (Debug || DebugG || DebugM)
1724 prealloc_debug();
1725 /* Report on memory consumption. */
1726 Dprintf("One side is %d bytes.\n", sizeof(Side));
1727 Dprintf("One unit is %d bytes, one plan is %d bytes.\n",
1728 sizeof(Unit), sizeof(Plan));
1729 Dprintf("One task is %d bytes.\n", sizeof(Task));
1730 Dprintf("One unit view is %d bytes.\n", sizeof(UnitView));
1731 Dprintf("One hist event is %d bytes, one past unit is %d bytes.\n",
1732 sizeof(HistEvent), sizeof(PastUnit));
1733 if (Debug)
1734 report_malloc();
1735 #endif /* DEBUGGING */
1736 }
1737
1738 static void
kill_excess_units(void)1739 kill_excess_units(void)
1740 {
1741 Unit *unit;
1742
1743 for_all_units(unit) {
1744 /* Offworld units with no scheduled appearance should evaporate. */
1745 if (!inside_area(unit->x, unit->y)
1746 && unit_appear_turn(unit) < 0) {
1747 kill_unit(unit, -1);
1748 }
1749 }
1750 /* Make the units' storage available. */
1751 flush_dead_units();
1752 }
1753
1754 /* Load up any player-specified configuration data. */
1755
1756 void
configure_sides(void)1757 configure_sides(void)
1758 {
1759 Side *side;
1760
1761 for_all_sides(side) {
1762 load_side_config(side);
1763 }
1764 }
1765
1766 /* Calculate what each side knows about the world. */
1767
1768 void
init_all_views(void)1769 init_all_views(void)
1770 {
1771 int x, y, i = 0, todo = max(1, numtotsides * area.numcells);
1772 int terrainset;
1773 Side *side;
1774 extern int suppress_see_wakeup;
1775
1776 suppress_see_wakeup = TRUE;
1777 /* Set up the basic view structures for all sides first. */
1778 for_all_sides(side) {
1779 side->see_all = g_see_all();
1780 terrainset = init_view(side);
1781 calc_coverage(side);
1782 tmpside = side;
1783 if (g_terrain_seen() || side->see_all) {
1784 for_all_cells(x, y) {
1785 init_view_cell(x, y);
1786 }
1787 } else {
1788 for_all_cells(x, y) {
1789 if (!terrainset) {
1790 set_terrain_view(side, x, y, UNSEEN);
1791 }
1792 /* (should do already-seen down below?) */
1793 if (terrain_view(side, x, y) != UNSEEN) {
1794 init_view_cell(x, y);
1795 }
1796 }
1797 }
1798 /* We're not normally allowed to choose whether to display all
1799 or not. */
1800 side->may_set_show_all = FALSE;
1801 /* Display appearance normally matches viewing abilities. */
1802 side->show_all = side->see_all;
1803 /* Can't think of any other place to put this... */
1804 calc_start_xy(side);
1805 }
1806 /* Possibly nothing more to do here. */
1807 if (g_see_all())
1808 return;
1809 /* Now we go to computing the actual view of the units in each
1810 cell, as well as the view coverage count (really?). */
1811 announce_lengthy_process("Computing current view at each location");
1812 for_all_sides(side) {
1813 for_all_cells(x, y) {
1814 ++i;
1815 if (i % 100 == 0)
1816 announce_progress((100 * i) / todo);
1817 see_cell(side, x, y);
1818 }
1819 }
1820 finish_lengthy_process();
1821 init_ranged_views();
1822 suppress_see_wakeup = FALSE;
1823 }
1824
1825 /* This is a helper routine. The helper is applied to each cell,
1826 decides what is visible in that cell. */
1827
1828 /* This only works from already_seen, does not account for coverage. */
1829
1830 /* (should only be run once/cell/side, use a scratch layer to keep track?) */
1831
1832 static void
init_view_cell(int x,int y)1833 init_view_cell(int x, int y)
1834 {
1835 int u, chance;
1836 Unit *unit;
1837
1838 /* Guaranteed to see the terrain accurately. */
1839 set_terrain_view(tmpside, x, y, buildtview(terrain_at(x, y)));
1840 /* If this cell is under observation, don't need to do anything special. */
1841 if (cover(tmpside, x, y) > 0)
1842 return;
1843 /* Scan all the units here to see if any are visible. */
1844 for_all_stack(x, y, unit) {
1845 if (in_play(unit)) {
1846 u = unit->type;
1847 if (u_see_always(u)) {
1848 see_exact(tmpside, x, y);
1849 /* or flag unit as spotted? */
1850 set_cover(tmpside, x, y, 1);
1851 return;
1852 }
1853 /* Only check already-seen if we didn't read in a set of
1854 unit views already. */
1855 if (!tmpside->unit_view_restored) {
1856 chance = already_seen_chance(tmpside, unit);
1857 if (probability(chance)) {
1858 add_unit_view(tmpside, unit);
1859 }
1860 }
1861 }
1862 }
1863 /* We get to see the weather conditions here. */
1864 if (winds_defined())
1865 set_wind_view(tmpside, x, y, raw_wind_at(x, y));
1866 }
1867
1868 /* Get the already-seen chance from either the side, if defined, or
1869 from the unit type. */
1870
1871 int
already_seen_chance(Side * side,Unit * unit)1872 already_seen_chance(Side *side, Unit *unit)
1873 {
1874 int u = unit->type, val;
1875
1876 if (indep(unit)) {
1877 if (side != NULL
1878 && side->already_seen_indep != NULL) {
1879 val = side->already_seen_indep[u];
1880 if (val >= 0)
1881 return val;
1882 }
1883 return u_already_seen_indep(u);
1884 } else {
1885 if (side != NULL
1886 && side->already_seen != NULL) {
1887 val = side->already_seen[u];
1888 if (val >= 0)
1889 return val;
1890 }
1891 return u_already_seen(u);
1892 }
1893 }
1894
1895 static void
maybe_init_view_cell(int x,int y)1896 maybe_init_view_cell(int x, int y)
1897 {
1898 int dir, x1, y1;
1899
1900 if (adj_seen_terrain(x, y, tmpside) && flip_coin()) {
1901 init_view_cell(x, y);
1902 for_all_directions(dir) {
1903 if (point_in_dir(x, y, dir, &x1, &y1)) {
1904 init_view_cell(x1, y1);
1905 }
1906 }
1907 }
1908 }
1909
1910 static int
adj_seen_terrain(int x,int y,Side * side)1911 adj_seen_terrain(int x, int y, Side *side)
1912 {
1913 int dir, x1, y1;
1914
1915 if (!inside_area(x, y))
1916 return FALSE;
1917 for_all_directions(dir) {
1918 if (point_in_dir(x, y, dir, &x1, &y1)) {
1919 if (terrain_view(side, x1, y1) != UNSEEN)
1920 return TRUE;
1921 }
1922 }
1923 return FALSE;
1924 }
1925
1926 /* Do ranged initial views from units. */
1927
1928 static void
init_ranged_views(void)1929 init_ranged_views(void)
1930 {
1931 int rad, x, y, pop, dir, x1, y1, i = 0;
1932 Unit *unit;
1933 Side *side, *side2;
1934
1935 /* Don't run if nothing exists to look at. */
1936 if (!terrain_defined())
1937 return;
1938 /* Skip if everything already known, side creation got these cases. */
1939 if (g_see_all() || g_terrain_seen())
1940 return;
1941 announce_lengthy_process("Computing ranged and people views");
1942 /* Compute the view for each side. */
1943 for_all_sides(side) {
1944 /* Set this so the helper fn has a side to use. */
1945 tmpside = side;
1946 /* View from our own and other units. */
1947 for_all_units(unit) {
1948 if (trusted_side(unit->side, side)) {
1949 /* The unit always sees itself. */
1950 see_exact(side, unit->x, unit->y);
1951 /* It may also see things nearby. */
1952 rad = u_seen_radius(unit->type);
1953 if (rad >= area.maxdim) {
1954 /* Special optimization - view the whole area. */
1955 for_all_cells(x, y) {
1956 init_view_cell(x, y);
1957 }
1958 /* Note that we're not done; other units may be able to
1959 supply more exact views of their vicinities than
1960 would init_view_cell from a distant unit. */
1961 } else if (rad >= 0) {
1962 apply_to_area(unit->x, unit->y, rad, init_view_cell);
1963 }
1964 }
1965 }
1966 /* The people see everything in the cells that they are in, plus the
1967 normally visible things in adjacent cells. */
1968 if (people_sides_defined()) {
1969 for_all_interior_cells(x, y) {
1970 pop = people_side_at(x, y);
1971 side2 = side_n(pop);
1972 if (pop != NOBODY && trusted_side(side2, side)) {
1973 see_exact(side, x, y);
1974 for_all_directions(dir) {
1975 if (point_in_dir(x, y, dir, &x1, &y1)) {
1976 init_view_cell(x1, y1);
1977 }
1978 }
1979 }
1980 }
1981 }
1982 if (side->finalradius > 0) {
1983 /* (should also view terrain adj to each of these cells, since the
1984 viewing represents exploration) */
1985 apply_to_ring(side->startx, side->starty,
1986 1, side->finalradius - 1,
1987 init_view_cell);
1988 apply_to_ring(side->startx, side->starty,
1989 side->finalradius - 2, side->finalradius + 2,
1990 maybe_init_view_cell);
1991 }
1992 announce_progress((100 * i++) / numtotsides);
1993 }
1994 finish_lengthy_process();
1995 }
1996
1997 /* Method to give all units and terrain a basic stockpile of supply. */
1998
1999 int
make_initial_materials(int calls,int runs)2000 make_initial_materials(int calls, int runs)
2001 {
2002 int m, t, doany, x, y, didany = FALSE;
2003
2004 /* Go over each material and terrain type, looking for nonzero
2005 material in terrain possibilities, then alloc and fill in layers
2006 as needed. */
2007 for_all_material_types(m) {
2008 doany = FALSE;
2009 for_all_terrain_types(t) {
2010 tmp_t_array[t] = min(tm_storage_x(t, m), tm_initial(t, m));
2011 if (tmp_t_array[t] > 0)
2012 doany = TRUE;
2013 }
2014 if (doany) {
2015 allocate_area_material(m);
2016 for_all_cells(x, y) {
2017 t = terrain_at(x, y);
2018 set_material_at(x, y, m, tmp_t_array[t]);
2019 }
2020 didany = TRUE;
2021 }
2022 }
2023 return didany;
2024 }
2025
2026 /* Give the unit what it is declared to have stockpiled
2027 at the start of a game. */
2028
2029 void
init_supply(Unit * unit)2030 init_supply(Unit *unit)
2031 {
2032 int m, u = unit->type;
2033
2034 for_all_material_types(m) {
2035 unit->supply[m] = min(um_storage_x(u, m), um_initial(u, m));
2036 }
2037 }
2038
2039 /* Count all the initial units in each side's balance sheet, but only
2040 if all the balance sheets are completely blank. */
2041
2042 void
init_side_balance(void)2043 init_side_balance(void)
2044 {
2045 int u;
2046 Unit *unit;
2047 Side *side;
2048
2049 for_all_sides(side) {
2050 for_all_unit_types(u) {
2051 if (total_gain(side, u) > 0)
2052 return;
2053 }
2054 }
2055 for_all_units(unit) {
2056 count_gain(unit->side, unit->type, initial_gain);
2057 }
2058 }
2059
2060 /* This routine does a set of checks to make sure that Xconq's data
2061 is in a valid state. This is particularly important after init,
2062 since the combination of files and synthesis methods may have
2063 caused some sort of disaster. */
2064
2065 void
check_consistency(void)2066 check_consistency(void)
2067 {
2068 int x, y;
2069
2070 /* If no terrain, make a flat area of all ttype 0. */
2071 if (!terrain_defined()) {
2072 init_warning("No terrain defined, substituting type 0");
2073 allocate_area_terrain();
2074 for_all_cells(x, y) {
2075 if (inside_area(x, y)) {
2076 set_terrain_at(x, y, 0);
2077 }
2078 }
2079 add_edge_terrain();
2080 }
2081 if (numtotsides <= 0) {
2082 init_error("There are no player sides at all in this game");
2083 } else if (numtotsides < numplayers) {
2084 init_warning("Only made %d of the %d sides requested",
2085 numtotsides, numplayers);
2086 }
2087 /* Need any kind of unit checks? */
2088 }
2089
2090 /* Build a vector of unit types that can possibly appear in the
2091 current game. */
2092 /* (This vector does not account for every exotic game design, but
2093 this vector is currently only used when formatting the final
2094 statistics table.) */
2095
2096 static void
cache_possible_types(void)2097 cache_possible_types(void)
2098 {
2099 int u, u2, rescan;
2100 Unit *unit;
2101
2102 u_possible = (short *) xmalloc(numutypes * sizeof(short));
2103 for_all_units(unit) {
2104 u_possible[unit->type] = TRUE;
2105 }
2106 rescan = TRUE;
2107 while (rescan) {
2108 rescan = FALSE;
2109 for_all_unit_types(u) {
2110 if (u_possible[u]) {
2111 for_all_unit_types(u2) {
2112 if (could_create(u, u2)
2113 && !u_possible[u2]) {
2114 u_possible[u2] = TRUE;
2115 rescan = TRUE;
2116 }
2117 }
2118 }
2119 }
2120 }
2121 }
2122
2123 /* This does the actual assignment of players to sides, and initializes the
2124 side structures appropriately. */
2125
2126 void
assign_players_to_sides(void)2127 assign_players_to_sides(void)
2128 {
2129 int i, numdisplays = 0, numdisplayswanted = 0, numais = 0, n = 0;
2130 Side *side;
2131 Player *player;
2132
2133 announce_lengthy_process("Assigning players to sides");
2134 for (i = 0; i < numtotsides; ++i) {
2135 announce_progress((100 * i) / numtotsides);
2136 side = assignments[i].side;
2137 player = assignments[i].player;
2138 if (player == NULL)
2139 continue;
2140 canonicalize_player(player);
2141 /* Fix any mistaken advantages. */
2142 /* This is a warning here because properly-done interfaces shouldn't
2143 allow any mistaken advantages to get this far. */
2144 if (player->advantage < side->minadvantage) {
2145 init_warning("Requested advantage of %d for %s is too low, will be set to %d",
2146 player->advantage, player_desig(player), side->minadvantage);
2147 player->advantage = side->minadvantage;
2148 }
2149 if (player->advantage > side->maxadvantage) {
2150 init_warning("Requested advantage of %d for %s is too high, will be set to %d",
2151 player->advantage, player_desig(player), side->maxadvantage);
2152 player->advantage = side->maxadvantage;
2153 }
2154 /* Call the interface code to initialize the side's display, if
2155 it wants to use one (the interface has to decide). */
2156 if (side_wants_display(side)) {
2157 ++numdisplayswanted;
2158 if (player->rid == my_rid) {
2159 init_ui(side);
2160 } else {
2161 init_remote_ui(side);
2162 }
2163 }
2164 if (side_has_display(side)) {
2165 ++numdisplays;
2166 }
2167 /* Count the desired AIs, for setup below. */
2168 if (side_wants_ai(side)) {
2169 ++numais;
2170 }
2171 Dprintf("Assigned %s to %s\n",
2172 side_desig(side), player_desig(player));
2173 }
2174 finish_lengthy_process();
2175 if (numdisplays < numdisplayswanted) {
2176 if (numdisplays < 1) {
2177 init_warning("None of the %d requested displays opened",
2178 numdisplayswanted);
2179 } else {
2180 init_warning("Only %d of %d requested displays opened",
2181 numdisplays, numdisplayswanted);
2182 }
2183 } else if (numdisplays == 0) {
2184 init_warning("Need at least one local or remote display to run");
2185 }
2186 #ifdef DESIGNERS
2187 /* Make each displayed side into a designer if it was requested. */
2188 if (allbedesigners) {
2189 for_all_sides(side) {
2190 if (side_has_display(side)) {
2191 become_designer(side);
2192 }
2193 }
2194 }
2195 #endif /* DESIGNERS */
2196 if (numais > 0) {
2197 announce_lengthy_process("Setting up AIs");
2198 for (i = 0; i < numtotsides; ++i) {
2199 if (numais > 1)
2200 announce_progress((100 * n++) / numais);
2201 side = assignments[i].side;
2202 if (side_wants_ai(side)) {
2203 init_ai(side);
2204 }
2205 }
2206 finish_lengthy_process();
2207 }
2208 }
2209
2210 /* Make sure any debugging I/O routines have allocated their space.
2211 Usually routines like side_desig allocate their working space on
2212 demand, but if the first demand occurs during a game being saved
2213 because allocation fails, then we're in big trouble. So this
2214 routine, which need only be be called when debugging is turned
2215 on, calls allocation-needing things in such a way to cause them
2216 to allocate their working space. */
2217
2218 void
prealloc_debug(void)2219 prealloc_debug(void)
2220 {
2221 side_desig(NULL);
2222 player_desig(NULL);
2223 unit_desig(NULL);
2224 }
2225
2226 /* Return the program version. */
2227
2228 char *
version_string(void)2229 version_string(void)
2230 {
2231 return VERSION;
2232 }
2233
2234 /* Return the copyright notice. */
2235
2236 char *
copyright_string(void)2237 copyright_string(void)
2238 {
2239 return COPYRIGHT;
2240 }
2241
2242 /* Return the license string. */
2243
2244 char *
license_string(void)2245 license_string(void)
2246 {
2247 return "\
2248 Xconq is free software and you are welcome to distribute copies of it\n\
2249 under certain conditions; type \"o copying\" to see the conditions.\n\
2250 There is absolutely no warranty for Xconq; type \"o warranty\" for details.\n\
2251 ";
2252 }
2253
2254 /* This comment is a fake reference to K_NO_X, which is a keyword used
2255 to clear the subtype-x property of terrain, but is not actually
2256 mentioned in the code - besides here anyway. :-) */
2257