Reindent the code.
[vms-empire.git] / edit.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 edit.c -- Routines to handle edit mode commands.
10 */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <curses.h>
15 #include <ctype.h>
16 #include "empire.h"
17 #include "extern.h"
18
19 void e_move(loc_t *path_start, loc_t loc);
20 extern int get_piece_name(void);
21
22 void
23 edit(loc_t edit_cursor)
24 {
25     char e_cursor();
26     void e_leave(), e_print(), e_random();
27     void e_stasis(), e_end(), e_wake(), e_sleep();
28     void e_info(), e_prod(), e_help(), e_explore();
29     void e_fill(), e_land(), e_city_func(), e_transport();
30     void e_attack(), e_repair();
31
32     loc_t path_start;
33     int path_type;
34     char e;
35         
36     path_start = -1; /* not building a path yet */
37         
38     for (;;) { /* until user gives command to leave */
39         display_loc_u (edit_cursor); /* position cursor */
40         e = e_cursor (&edit_cursor); /* handle cursor movement */
41
42         switch (e) {
43         case 'B': /* change city production */
44             e_prod (edit_cursor);
45             break;
46         case 'F': /* fill */
47             e_fill (edit_cursor);
48             break;
49         case 'G': /* explore */
50             e_explore (edit_cursor);
51             break;
52         case 'H': /* help */
53             e_help ();
54             break;
55         case 'I': /* directional stasis */
56             e_stasis (edit_cursor);
57             break;
58         case 'K': /* wake up anything and everything */
59             e_wake (edit_cursor);
60             break;
61         case 'L': /* land plane */
62             e_land (edit_cursor);
63             break;
64         case 'M': /* start move to location */
65             path_type = NOPIECE;
66             e_move (&path_start, edit_cursor);
67             break;
68         case 'N': /* end move to location */
69             e_end (&path_start, edit_cursor, path_type);
70             break;
71         case 'O': /* leave display mode */
72             e_leave ();
73             return;
74         case 'P': /* print new sector */
75             e_print (&edit_cursor);
76             break;
77         case 'R': /* make piece move randomly */
78             e_random (edit_cursor);
79             break;
80         case 'S': /* sleep */
81             e_sleep (edit_cursor);
82             break;
83         case 'T': /* transport army */
84             e_transport (edit_cursor);
85             break;
86         case 'U': /* repair ship */
87             e_repair (edit_cursor);
88             break;
89         case 'V': /* set city function */
90             e_city_func (&path_start, edit_cursor, &path_type);
91             break;
92         case 'Y': /* set army func to attack */
93             e_attack (edit_cursor);
94             break;
95         case '?': /* request info */
96             e_info (edit_cursor);
97             break;
98         case '\014': /* control-L */
99             redraw ();
100             break;
101         default: /* bad command? */
102             huh ();
103             break;
104         }
105     }
106 }
107
108 /*
109 Get the next command.  We handle cursor movement here.
110 This routine is an attempt to make cursor movement reasonably
111 fast.
112 */
113
114 char
115 e_cursor(loc_t *edit_cursor)
116 {
117     chtype e;
118     int p;
119         
120     /* set up terminal */
121     (void) crmode ();
122     (void) refresh ();
123     e = getch ();
124     topini (); /* clear any error messages */
125
126     for (;;) {
127         p = direction (e);
128         if (p == -1) break;
129
130         if (!move_cursor (edit_cursor, dir_offset[p]))
131             (void) beep ();
132                 
133         (void) refresh ();
134         e = getch ();
135     }
136     (void) nocrmode (); /* reset terminal */
137     return toupper(e);
138 }
139
140 /*
141 Leave edit mode.
142 */
143
144 void
145 e_leave(void)
146 {
147 }
148
149 /*
150 Print new sector.
151 */
152
153 void
154 e_print(loc_t *edit_cursor)
155 {
156     int sector;
157         
158     sector = get_range ("New Sector? ", 0, NUM_SECTORS-1);
159
160     /* position cursor at center of sector */
161     *edit_cursor = sector_loc (sector);
162     sector_change (); /* allow change of sector */
163 }
164
165 /*
166 Set the function of a piece.
167 */
168
169 void
170 e_set_func(loc_t loc, long func)
171 {
172     piece_info_t *obj;
173     obj = find_obj_at_loc (loc);
174     if (obj != NULL && obj->owner == USER) {
175         obj->func = func;
176         return;
177     }
178     huh (); /* no object here */
179 }
180         
181 /* Set the function of a city for some piece. */
182
183 void
184 e_set_city_func(city_info_t *cityp, int type, long func)
185 {
186     cityp->func[type] = func;
187 }
188
189 /*
190 Set a piece to move randomly.
191 */
192
193 void
194 e_random(loc_t loc)
195 {
196     e_set_func (loc, RANDOM);
197 }
198
199 void
200 e_city_random(city_info_t *cityp, int type)
201 {
202     e_set_city_func (cityp, type, RANDOM);
203 }
204
205 /*
206 Put a ship in fill mode.
207 */
208
209 void
210 e_fill(loc_t loc)
211 {
212     if (user_map[loc].contents == 'T' || user_map[loc].contents == 'C')
213         e_set_func (loc, FILL);
214     else huh ();
215 }
216
217 void
218 e_city_fill(city_info_t *cityp, int type)
219 {
220     if (type == TRANSPORT || type == CARRIER)
221         e_set_city_func (cityp, type, FILL);
222     else huh ();
223 }
224
225 /*
226 Set a piece to explore.
227 */
228
229 void
230 e_explore(loc_t loc)
231 {
232     e_set_func (loc, EXPLORE);
233 }
234
235 void
236 e_city_explore(city_info_t *cityp, loc_t type)
237 {
238     e_set_city_func (cityp, type, EXPLORE);
239 }
240
241 /*
242 Set a fighter to land.
243 */
244
245 void
246 e_land(loc_t loc)
247 {
248     if (user_map[loc].contents == 'F')
249         e_set_func (loc, LAND);
250     else huh ();
251 }
252
253 /*
254 Set an army's function to TRANSPORT.
255 */
256
257 void
258 e_transport(loc_t loc)
259 {
260     if (user_map[loc].contents == 'A')
261         e_set_func (loc, WFTRANSPORT);
262     else huh ();
263 }
264
265 /*
266 Set an army's function to ATTACK.
267 */
268
269 void
270 e_attack(loc_t loc)
271 {
272     if (user_map[loc].contents == 'A')
273         e_set_func (loc, ARMYATTACK);
274     else huh ();
275 }
276
277 void
278 e_city_attack(city_info_t *cityp, int type)
279 {
280     if (type == ARMY)
281         e_set_city_func (cityp, type, ARMYATTACK);
282     else huh ();
283 }
284
285 /*
286 Set a ship's function to REPAIR.
287 */
288
289 void
290 e_repair(loc_t loc)
291 {
292     if (strchr ("PDSTBC", user_map[loc].contents))
293         e_set_func (loc, REPAIR);
294     else huh ();
295 }
296
297 void
298 e_city_repair(city_info_t *cityp, int type)
299 {
300         if (type == ARMY || type == FIGHTER || type == SATELLITE)
301                 huh ();
302         else e_set_city_func (cityp, type, REPAIR);
303 }
304
305 /*
306 Set object to move in a direction.
307 */
308
309 static char dirs[] = "WEDCXZAQ";
310  
311 void
312 e_stasis(loc_t loc)
313 {
314     char e;
315     char *p;
316         
317     if (!isupper (user_map[loc].contents))
318         huh (); /* no object here */
319     else if (user_map[loc].contents == 'X')
320         huh ();
321     else {
322         e = get_chx(); /* get a direction */
323         p = strchr (dirs, e);
324
325         if (p == NULL)
326             huh ();
327         else
328             e_set_func (loc, (long)(MOVE_N - (p - dirs)));
329     }
330 }
331
332 void
333 e_city_stasis(city_info_t *cityp, int type)
334 {
335     char e;
336     char *p;
337         
338     e = get_chx(); /* get a direction */
339     p = strchr (dirs, e);
340
341     if (p == NULL)
342         huh ();
343     else
344         e_set_city_func (cityp, type, (long)(MOVE_N - (p - dirs)));
345 }
346
347 /*
348 Wake up anything and everything.
349 */
350
351 void
352 e_wake(loc_t loc)
353 {
354     city_info_t *cityp;
355     piece_info_t *obj;
356     int i;
357
358     cityp = find_city (loc);
359     if (cityp != NULL) {
360         for (i = 0; i < NUM_OBJECTS; i++)
361             cityp->func[i] = NOFUNC;
362     }
363     for (obj = map[loc].objp; obj != NULL; obj = obj->loc_link.next)
364         obj->func = NOFUNC;
365 }
366
367 void
368 e_city_wake(city_info_t *cityp, int type)
369 {
370     e_set_city_func (cityp, type, NOFUNC);
371 }
372
373 /*
374 Set a city's function.  We get the piece type to set, then
375 the function itself.
376 */
377
378 void
379 e_city_func(loc_t *path_start, loc_t loc, int *path_type)
380 {
381     int type;
382     char e;
383     city_info_t *cityp;
384
385     cityp = find_city (loc);
386     if (!cityp || cityp->owner != USER) {
387         huh ();
388         return;
389     }
390
391     type = get_piece_name();
392     if (type == NOPIECE) {
393         huh ();
394         return;
395     }
396         
397     e = get_chx ();
398         
399     switch (e) {
400     case 'F': /* fill */
401         e_city_fill (cityp, type);
402         break;
403     case 'G': /* explore */
404         e_city_explore (cityp, type);
405         break;
406     case 'I': /* directional stasis */
407         e_city_stasis (cityp, type);
408         break;
409     case 'K': /* turn off function */
410         e_city_wake (cityp, type);
411         break;
412     case 'M': /* start move to location */
413         *path_type = type;
414         e_move (path_start, loc);
415         break;
416     case 'R': /* make piece move randomly */
417         e_city_random (cityp, type);
418         break;
419     case 'U': /* repair ship */
420         e_city_repair (cityp, type);
421         break;
422     case 'Y': /* set army func to attack */
423         e_city_attack (cityp, type);
424         break;
425     default: /* bad command? */
426         huh ();
427         break;
428     }
429 }
430
431 /*
432 Beginning of move to location.
433 */
434
435 void
436 e_move(loc_t *path_start, loc_t loc)
437 {
438     if (!isupper(user_map[loc].contents)) huh (); /* nothing there? */
439     else if (user_map[loc].contents == 'X') huh (); /* enemy city? */
440     else *path_start = loc;
441 }
442
443 /*
444 End of move to location.
445 */
446
447 void
448 e_end(loc_t *path_start, loc_t loc, int path_type)
449 {
450     city_info_t *cityp;
451         
452     if (*path_start == -1) huh (); /* no path started? */
453     else if (path_type == NOPIECE) e_set_func (*path_start, loc);
454     else {
455         cityp = find_city (*path_start);
456         ASSERT (cityp);
457         e_set_city_func (cityp, path_type, loc);
458     }
459
460     *path_start = -1; /* remember no path in progress */
461 }
462
463 /*
464 Put a piece to sleep.
465 */
466
467 void
468 e_sleep(loc_t loc)
469 {
470     if (user_map[loc].contents == 'O') huh (); /* can't sleep a city */
471     else e_set_func (loc, SENTRY);
472 }
473
474 /*
475 Print out information about a piece.
476 */
477
478 void
479 e_info(loc_t edit_cursor)
480 {
481     void e_city_info(loc_t), e_piece_info(loc_t edit_cursor, char ab);
482
483     char ab;
484
485     ab = user_map[edit_cursor].contents;
486
487     if (ab == 'O')
488         e_city_info (edit_cursor);
489     else if (ab == 'X' && debug)
490         e_city_info (edit_cursor);
491     else if ((ab >= 'A') && (ab <= 'T'))
492         e_piece_info (edit_cursor, ab);
493     else if ((ab >= 'a') && (ab <= 't') && (debug))
494         e_piece_info (edit_cursor, ab);
495     else
496         huh ();
497 }
498
499 /*
500 Print info about a piece.
501 */
502
503 void
504 e_piece_info(loc_t edit_cursor, char ab)
505 {
506     piece_info_t *obj;
507     int type;
508     char *p;
509
510     ab = toupper (ab);
511     p = strchr (type_chars, ab);
512     type = p - type_chars;
513
514     obj = find_obj (type, edit_cursor);
515     ASSERT (obj != NULL);
516     describe_obj (obj);
517 }
518
519 /*
520 Display info on a city.
521 */
522
523 void
524 e_city_info(loc_t edit_cursor)
525 {
526     piece_info_t *obj;
527     city_info_t *cityp;
528     int f, s;
529     char func_buf[STRSIZE];
530     char temp_buf[STRSIZE];
531     char junk_buf2[STRSIZE];
532
533     error (""); /* clear line */
534
535     f = 0; /* no fighters counted yet */
536     for (obj = map[edit_cursor].objp; obj != NULL;
537          obj = obj->loc_link.next)
538         if (obj->type == FIGHTER) f++;
539
540     s = 0; /* no ships counted yet */
541     for (obj = map[edit_cursor].objp; obj != NULL;
542          obj = obj->loc_link.next)
543         if (obj->type >= DESTROYER) s++;
544
545     if (f == 1 && s == 1) 
546         (void) sprintf (jnkbuf, "1 fighter landed, 1 ship docked");
547     else if (f == 1)
548         (void) sprintf (jnkbuf, "1 fighter landed, %d ships docked", s);
549     else if (s == 1)
550         (void) sprintf (jnkbuf, "%d fighters landed, 1 ship docked", f);
551     else
552         (void) sprintf (jnkbuf, "%d fighters landed, %d ships docked", f, s);
553
554     cityp = find_city (edit_cursor);
555     ASSERT (cityp != NULL);
556
557     *func_buf = 0; /* nothing in buffer */
558     for (s = 0; s < NUM_OBJECTS; s++) { /* for each piece */
559         if (cityp->func[s] < 0)
560             (void) sprintf (temp_buf, "%c:%s; ",
561                             piece_attr[s].sname,
562                             func_name[FUNCI(cityp->func[s])]);
563         else (void) sprintf (temp_buf, "%c: %d;",
564                              piece_attr[s].sname,
565                              loc_disp(cityp->func[s]));
566                 
567         (void) strcat (func_buf, temp_buf);
568     }
569
570     (void) sprintf (junk_buf2,
571                     "City at location %d will complete %s on round %ld",
572                     loc_disp(cityp->loc),
573                     piece_attr[(int)cityp->prod].article,
574                     date + piece_attr[(int)cityp->prod].build_time - cityp->work);
575
576     info (junk_buf2, jnkbuf, func_buf);
577 }
578
579 /*
580 Change city production.
581 */
582
583 void
584 e_prod(loc_t loc)
585 {
586     city_info_t *cityp;
587         
588     cityp = find_city (loc);
589
590     if (cityp == NULL) huh (); /* no city? */
591     else set_prod (cityp);
592 }
593
594 /*
595 get help
596 */
597
598 void
599 e_help(void)
600 {
601     help (help_edit, edit_lines);
602     prompt ("Press any key to continue: ");
603     (void) get_chx ();
604 }
605
606 /* end */