Fix production bug in objects.c.
[vms-empire.git] / empire.c
1 /*
2  *    Copyright (C) 1987, 1988 Chuck Simmons
3  * 
4  * See the file COPYING, distributed with empire, for restriction
5  * and warranty information.
6  */
7
8 /*
9 empire.c -- this file contains initialization code, the main command
10 parser, and the simple commands.
11 */
12
13 #include <stdio.h>
14 #include "empire.h"
15 #include "extern.h"
16
17 void c_examine(void), c_movie(void);
18
19 /*
20  * 03a 01Apr88 aml .Hacked movement algorithms for computer.
21  * 02b 01Jun87 aml .First round of bug fixes.
22  * 02a 01Jan87 aml .Translated to C.
23  * 01b 27May85 cal .Fixed round number update bug. Made truename simple.
24  * 01a 01Sep83 cal .Taken from a Decus tape
25  */
26
27 void
28 empire(void)
29 {
30     void do_command(char);
31     void print_zoom();
32
33     char order;
34     int turn = 0;
35
36     ttinit (); /* init tty */
37     rndini (); /* init random number generator */
38
39     clear_screen (); /* nothing on screen */
40     pos_str (7, 0, "EMPIRE, Version 5.00 site Amdahl 1-Apr-1988");
41     pos_str (8, 0, "Detailed directions are in EMPIRE.DOC\n");
42     (void) redisplay ();
43
44     if (!restore_game ()) /* try to restore previous game */
45         init_game (); /* otherwise init a new game */
46
47     /* Command loop starts here. */
48
49     for (;;) { /* until user quits */
50         if (automove) { /* don't ask for cmd in auto mode */
51             user_move ();
52             comp_move (1);
53             if (++turn % save_interval == 0)
54                 save_game ();
55         }
56         else {
57             prompt (""); /* blank top line */
58             redisplay();
59             prompt ("Your orders? ");
60             order = get_chx (); /* get a command */
61             do_command (order);
62         }
63     }
64 }
65
66 /*
67 Execute a command.
68 */
69
70 void
71 do_command(char orders)
72 {
73     void c_debug(char order), c_quit(void), c_sector(void), c_map(void);
74     void c_give(void);
75
76     char e;
77     int ncycle;
78
79     switch (orders) {
80     case 'A': /* turn on auto move mode */
81         automove = true;
82         error ("Now in Auto-Mode");
83         user_move ();
84         comp_move (1);
85         save_game ();
86         break;
87
88     case 'C': /* give a city to the computer */
89         c_give ();
90         break;
91         
92     case 'D': /* display round number */
93         error ("Round #%d", date);
94         break;
95
96     case 'E': /* examine enemy map */
97         if (resigned) c_examine ();
98         else huh (); /* illegal command */
99         break;
100
101     case 'F': /* print map to file */
102         c_map ();
103         break;
104
105     case 'G': /* give one free enemy move */
106         comp_move (1);
107         break;
108
109     case 'H': /* help */
110         help (help_cmd, cmd_lines);
111         break;
112
113     case 'J': /* edit mode */
114         ncycle = cur_sector ();
115         if (ncycle == -1) ncycle = 0;
116         edit (sector_loc (ncycle));
117         break;
118
119     case 'M': /* move */
120         user_move ();
121         comp_move (1);
122         save_game ();
123         break;
124
125     case 'N': /* give enemy free moves */
126         ncycle = getint ("Number of free enemy moves: ");
127         comp_move (ncycle);
128         save_game ();
129         break;
130
131     case 'P': /* print a sector */
132         c_sector ();
133         break;
134
135     case '\026': /* some interrupt */
136     case 'Q': /* quit */
137         c_quit ();
138         break;
139
140     case 'R': /* restore game */
141         clear_screen ();
142         e = restore_game ();
143         break;
144
145     case 'S': /* save game */
146         save_game ();
147         break;
148         
149     case 'T': /* trace: toggle save_movie flag */
150         save_movie = !save_movie;
151         if (save_movie) comment ("Saving movie screens to 'empmovie.dat'.");
152         else comment ("No longer saving movie screens.");
153         break;
154
155     case 'W': /* watch movie */
156         if (resigned || debug) replay_movie ();
157         else error ("You cannot watch movie until computer resigns.");
158         break;
159
160     case 'Z': /* print compressed map */
161         print_zoom (user_map);
162         break;
163
164     case '\014': /* redraw the screen */
165         redraw ();
166         break;
167
168     case '+': /* change debug state */
169         e = get_chx();
170         if ( e  ==  '+' )
171             debug = true;
172         else if ( e  ==  '-' )
173             debug = false;
174         else huh ();
175         break;
176
177     default:
178         if (debug)
179             c_debug (orders); /* debug */
180         else
181             huh (); /* illegal command */
182         break;
183     }
184 }
185
186 /*
187 Give an unowned city (if any) to the computer.  We make
188 a list of unowned cities, choose one at random, and mark
189 it as the computers.
190 */
191
192 void
193 c_give(void)
194 {
195     int unowned[NUM_CITY];
196     count_t i, count;
197
198     count = 0; /* nothing in list yet */
199     for (i = 0; i < NUM_CITY; i++) {
200         if (city[i].owner == UNOWNED) {
201             unowned[count] = i; /* remember this city */
202             count += 1;
203         }
204     }
205     if (count == 0) {
206         error ("There are no unowned cities.");
207         ksend ("There are no unowned cities.");
208         return;
209     }
210     i = irand (count);
211     i = unowned[i]; /* get city index */
212     city[i].owner = COMP;
213     city[i].prod = NOPIECE;
214     city[i].work = 0;
215     scan (comp_map, city[i].loc);
216 }
217
218 /*
219 Debugging commands should be implemented here.  
220 The order cannot be any legal command.
221 */
222
223 void
224 c_debug(char order)
225 {
226     char e;
227
228     switch (order) {
229     case '#' : c_examine (); break;
230     case '%' : c_movie (); break;
231         
232     case '@': /* change trace state */
233         e = get_chx();
234         if ( e  ==  '+' )
235             trace_pmap = true;
236         else if ( e  ==  '-' )
237             trace_pmap = false;
238         else
239             huh ();
240         break;
241
242     case '$': /* change print_debug state */
243         e = get_chx();
244         if ( e  ==  '+' )
245             print_debug = true;
246         else if ( e  ==  '-' )
247             print_debug = false;
248         else
249             huh ();
250         break;
251
252     case '&': /* change print_vmap state */
253         print_vmap = get_chx();
254         break;
255
256     default: huh (); break;
257     }
258 }
259
260 /*
261 The quit command.  Make sure the user really wants to quit.
262 */
263
264 void
265 c_quit(void)
266 {
267     if (getyn ("QUIT - Are you sure? ")) {
268         empend ();
269     }
270 }
271
272 /*
273 Print a sector.  Read the sector number from the user
274 and print it.
275 */
276
277 void
278 c_sector(void)
279 {
280     int num;
281
282     num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
283     print_sector_u (num);
284 }
285
286 /*
287 Print the map to a file.  We ask for a filename, attempt to open the
288 file, and if successful, print out the user's information to the file.
289 We print the map sideways to make it easier for the user to print
290 out the map.
291 */
292
293 void
294 c_map(void)
295 {
296     FILE *f;
297     int i, j;
298     char line[MAP_HEIGHT+2];
299
300     prompt ("Filename? ");
301     get_str (jnkbuf, STRSIZE);
302
303     f = fopen (jnkbuf, "w");
304     if (f == NULL) {
305         error ("I can't open that file.");
306         return;
307     }
308     for (i = 0; i < MAP_WIDTH; i++) { /* for each column */
309         for (j = MAP_HEIGHT-1; j >= 0; j--) { /* for each row */
310             line[MAP_HEIGHT-1-j] = user_map[row_col_loc(j,i)].contents;
311         }
312         j = MAP_HEIGHT-1;
313         while (j >= 0 && line[j] == ' ') /* scan off trailing blanks */
314             j -= 1;
315                         
316         line[++j] = '\n';
317         line[++j] = 0; /* trailing null */
318         (void) fputs (line, f);
319     }
320     (void) fclose (f);
321 }
322
323 /*
324 Allow user to examine the computer's map.
325 */
326
327 void
328 c_examine(void)
329 {
330     int num;
331
332     num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
333     print_sector_c (num);
334 }
335
336 /*
337 We give the computer lots of free moves and
338 Print a "zoomed" version of the computer's map.
339 */
340
341 void
342 c_movie(void)
343 {
344     for (;;) {
345         comp_move (1);
346         print_zoom (comp_map);
347         save_game ();
348 #ifdef PROFILE
349         if (date == 125) empend();
350 #endif
351     }
352 }
353
354 /* end */