1 | /*
2 | ** $Log: ml_list.c,v $
3 | ** Revision 1.10 2003/07/28 14:23:09 millis
4 | ** Fix bug 205
5 | **
6 | ** Revision 1.9 2003/01/14 13:51:37 millis
7 | ** Merges from USTV
8 | **
9 | ** Revision 1.8 2002/08/27 22:27:54 millis
10 | ** Updated for automake/autoconf functionality
11 | **
12 | ** Revision 1.7 2002/04/18 04:44:32 greg
13 | ** Added the following commands:
14 | ** - unstart
15 | ** - set secret
16 | ** - set [prflist|prfrand|prfboth]
17 | **
18 | ** Fixed Set Absence so that "to" is not case sensitive
19 | **
20 | ** Fixed Quiet games so that new players are announced
21 | ** before the game starts
22 | **
23 | ** Fixed ascii_to_ded.c so thatit no longer generates an
24 | ** error when compiled
25 | **
26 | ** Revision 1.6 2001/07/15 09:17:15 greg
27 | ** added support for game directories in a sub directory
28 | **
29 | ** Revision 1.5 2001/05/13 17:18:42 greg
30 | ** took off ")" at line 224
31 | **
32 | ** Revision 1.4 2001/05/12 07:42:55 greg
33 | ** minor bug fixes proposed by Mario Becroft & Philippe Lalande
34 | ** to display zero dedications in listing and problems with
35 | ** user's dedication
36 | **
37 | ** Revision 1.3 2001/04/15 21:21:22 miller
38 | ** Add use of GetMaxCountryStrlen() to space out properly for big country names
39 | **
40 | ** Revision 1.2 2000/11/14 14:27:37 miller
41 | ** Various changes including:
42 | ** - Adjust display for blind games
43 | ** - Display Late Count if enabled
44 | ** - Display to master who is whatching press
45 | ** - Show new flags
46 | ** - Different message if game has quota but has XF_MANUALSTART set
47 | **
48 | ** Revision 1.1 1998/02/28 17:49:42 david
49 | ** Initial revision
50 | **
51 | ** Revision 1.2 1997/02/16 20:43:18 davidn
52 | ** Additions to dipent structure and associated code, to allow duplex variants.
53 | ** Command is "set players n".
54 | **
55 | ** Revision 1.1 1996/10/20 12:29:45 rpaar
56 | ** Morrolan v9.0
57 | **
58 | */
59 |
60 | /* ml_list.c -- Generate listings of game parameters.
61 | **
62 | ** Copyright 1987, Lowe.
63 | **
64 | ** Diplomacy is a trademark of the Avalon Hill Game Company, Baltimore,
65 | ** Maryland, all rights reserved; used with permission.
66 | **
67 | ** Redistribution and use in source and binary forms are permitted
68 | ** provided that it is for non-profit purposes, that this and the
69 | ** above notices are preserved and that due credit is given to Mr.
70 | ** Lowe.
71 | **
72 | ** DATE NAME REASON
73 | ** ----------- ------------ -----------------------------------------
74 | ** ?? ??? 1987 Ken Lowe He wrote it
75 | ** 30 Dec 1996 David Norman Additions for dipent.no_of_players
76 | ** 18 Nov 1999 Millis Miller Changed display for a non-started, terminated
77 | game
78 | ** 26 Nov 1999 Millis Miller Added Display if in Shrthand mode
79 | */
80 |
81 | #include <string.h>
82 | #include <time.h>
83 |
84 | #include "config.h"
85 | #include "functions.h"
86 | #include "dip.h"
87 | #include "mail.h"
88 |
89 |
90 | /***************************************************************************/
91 |
92 | void mail_listit(void)
93 | {
94 |
95 | /* List out current status of the game */
96 |
97 | int i, f, n;
98 | int ccount;
99 | char *s, line[150];
100 | long now;
101 | FILE *fp;
102 | int ok_for_blind = 0;
103 |
104 | /* If it's not blind, ok to show everything */
105 | if (!(dipent.flags & F_BLIND)) ok_for_blind = 1;
106 |
107 | time(&now);
108 |
109 | if (dipent.phase[6] == 'X' && dipent.seq[0] == 'x') {
110 | fprintf(rfp, "Game '%s' is already terminated before starting.\n",
111 | dipent.name);
112 | }
113 | else if (dipent.seq[0] == 'x') {
114 |
115 | n = dipent.no_of_players - (dipent.seq[1] - '0');
116 |
117 | if (!(dipent.flags & F_QUIET)) {
118 | fprintf(rfp, "Game '%s' is waiting for %d%s player%s to sign on.\n",
119 | dipent.name, n, n == dipent.no_of_players ? "" : " more",
120 | n == 1 ? "" : "s");
121 | }
122 |
123 | } else if (dipent.phase[6] == 'X') {
124 | ok_for_blind = 1; /* Game over, so ok to show all for blind */
125 |
126 | for (i = 0; i < dipent.n; i++) {
127 | if (dipent.players[i].power < 0)
128 | continue;
129 |
130 | if (dipent.players[i].centers >= dipent.vp) {
131 | fprintf(rfp, "Game '%s' completed in %4.4s.\n",
132 | dipent.name, &dipent.phase[1]);
133 | break;
134 | }
135 | }
136 | if (i == dipent.n) {
137 | fprintf(rfp, "Game '%s' was terminated in %s of %4.4s.\n", dipent.name,
138 | dipent.phase[1] == 'F' ? "fall" :
139 | dipent.phase[1] == 'U' ? "summer" :
140 | "spring", &dipent.phase[1]);
141 | }
142 | } else {
143 |
144 | fprintf(rfp, "Game '%s' order #%s (%s) has a deadline of %s.\n",
145 | dipent.name, dipent.seq, dipent.phase, ptime(&dipent.deadline));
146 | if (now < dipent.start)
147 | fprintf(rfp, "The earliest orders will be processed is %s.\n",
148 | ptime(&dipent.start));
149 | if (now < dipent.deadline) {
150 | for (i = 0; i < dipent.n; i++) {
151 | if (dipent.players[i].power < 0)
152 | continue;
153 |
154 | if (WAITING(dipent.players[i].status)) {
155 | fprintf(rfp, "One or more players have not gotten their orders in.\n");
156 | break;
157 | }
158 | }
159 | for (i = 0; i < dipent.n; i++) {
160 | if (dipent.players[i].power < 0)
161 | continue;
162 |
163 | if ((dipent.players[i].status &
164 | (SF_ABAND | SF_CD | SF_WAIT)) == SF_WAIT) {
165 | fprintf(rfp, "One or more players have requested that orders not be ");
166 | fprintf(rfp, "processed\nuntil the deadline.\n");
167 | break;
168 | }
169 | }
170 | }
171 | fprintf(rfp, "Those who haven't gotten their orders in will be %s if ",
172 | dipent.flags & F_NONMR ? "abandoned" : "CD");
173 | fprintf(rfp, "nothing\nis received by %s.\n", ptime(&dipent.grace));
174 | }
175 |
176 | fprintf(rfp, "\nThe parameters for '%s' are as follows:\n", dipent.name);
177 | params(rfp);
178 |
179 | sprintf(line, "%s%s/info", GAME_DIR, dipent.name);
180 | if ((fp = fopen(line, "r"))) {
181 | fputc('\n', rfp);
182 | while (fgets(line, sizeof(line), fp))
183 | fputs(line, rfp);
184 | fclose(fp);
185 | }
186 | if (dipent.n) {
187 |
188 | int lates, abandons;
189 | fprintf(rfp, "\nThe following players are signed up for game '%s':\n",
190 | dipent.name);
191 | lates = abandons = 0;
192 |
193 | for (i = 0; i < dipent.n; i++) {
194 | if (dipent.players[i].power < 0)
195 | continue;
196 |
197 | f = dipent.players[i].status;
198 | s = "";
199 |
200 | if (f & (SF_CD | SF_ABAND))
201 | abandons++;
202 |
203 | if (now > dipent.deadline && WAITING(f))
204 | lates++;
205 |
206 | if (dipent.flags & F_QUIET && (!signedon ||
207 | (player != i && dipent.players[player].power != MASTER))) {
208 | if (f & SF_MOVE && ok_for_blind) {
209 | s = "move";
210 | }
211 | } else if (f & SF_CD) {
212 | s = "CD";
213 | } else if (f & SF_ABAND) {
214 | s = "abandon";
215 | } else if (f & SF_MOVE && ok_for_blind) {
216 | s = "move";
217 | if (now > dipent.deadline && WAITING(f)) {
218 | s = f & SF_PART ? "part" : "late";
219 | }
220 | }
221 |
222 | sprintf(line, " %-*.*s %-7.7s", GetMaxCountryStrlen(), GetMaxCountryStrlen(), powers[dipent.players[i].power], s);
223 |
224 | /* fprintf(rfp, " %-*.*s %-7.7s", GetMaxCountryStrlen(), GetMaxCountryStrlen(), powers[dipent.players[i].power], s);*/
225 | if (ok_for_blind &&
226 | (dipent.players[i].units || dipent.players[i].centers)) {
227 | ccount = dipent.players[i].centers-dipent.players[i].centres_blockaded;
228 | sprintf(line, "%s%2d/%d%s",
229 | line,
230 | dipent.players[i].units,
231 | ccount,
232 | dipent.players[i].centers < 10 ? " " : "");
233 |
234 | /*
235 | * fprintf(rfp, "%2d/%d%s",
236 | * dipent.players[i].units,
237 | * ccount,
238 | * dipent.players[i].centers < 10 ? " " : "");
239 | */
240 | } else
241 | strcat(line, " ");
242 | /* fputs(" ", rfp); */
243 |
244 | /* Now display late count if either master or not quiet/late_count */
245 | if ((dipent.xflags & XF_LATECOUNT) ) {
246 | if ((dipent.players[i].power >= 0 && dipent.players[i].power < WILD_PLAYER) &&
247 | ((signedon && (dipent.players[player].power == MASTER || player == i)) || (!(dipent.flags & F_QUIET))))
248 | sprintf(line, "%s %2d ", line, dipent.players[i].late_count);
249 | /* fprintf(rfp, " %2d ", dipent.players[i].late_count); */
250 | else
251 | strcat(line, " ");
252 | /* fprintf(rfp, " "); */
253 | }
254 | else
255 | strcat(line, " ");
256 | /* fprintf(rfp, " "); */
257 |
258 | if (signedon && (dipent.players[player].power == MASTER || player == i)) {
259 | if (dipent.players[i].status & SF_PRESS)
260 | strcat(line, "*");
261 | /* fprintf(rfp,"*"); */
262 | else
263 | strcat(line, " ");
264 | /* fprintf(rfp, " "); */
265 | } else {
266 | strcat(line, " ");
267 | /* fprintf(rfp, " "); */
268 | }
269 |
270 |
271 | if ( (!(dipent.flags & F_GUNBOAT)
272 | && 0 < dipent.players[i].userid
273 | && dipent.players[i].userid <= nded)
274 | /* && ded[dipent.players[i].userid].r */
275 | && (0 != strcmp(dipent.players[i].password,GONE_PWD)))
276 | sprintf(line, "%s%4d", line, ded[dipent.players[i].userid].r);
277 | /* fprintf(rfp, "%4d", ded[dipent.players[i].userid].r); */
278 | else
279 | strcat(line, " ");
280 | /* fputs(" ", rfp); */
281 |
282 | if (dipent.flags & F_GUNBOAT
283 | && dipent.players[i].power != MASTER
284 | && (!signedon || dipent.players[player].power != MASTER)
285 | && ((signedon && player != i)
286 | || strcasecmp(raddr, dipent.players[i].address)))
287 | sprintf(line, "%s %s\n", line, someone);
288 | /* fprintf(rfp, " %s\n", someone); */
289 | else
290 | sprintf(line, "%s %s\n", line, dipent.players[i].address);
291 | /* fprintf(rfp, " %s\n", dipent.players[i].address); */
292 |
293 | if (!(dipent.x2flags & X2F_SECRET) ||
294 | (dipent.seq[0] != 'x') ||
295 | (signedon && dipent.players[player].power == MASTER) ||
296 | (dipent.players[i].power == MASTER) ||
297 | !(strcasecmp(raddr, dipent.players[i].address)))
298 | fprintf(rfp, line);
299 |
300 | }
301 |
302 | if ((dipent.seq[0] == 'x') &&
303 | (dipent.x2flags & X2F_SECRET) &&
304 | !(signedon && dipent.players[player].power == MASTER)) {
305 | fprintf(rfp, "\n Other players kept secret.\n");
306 | }
307 |
308 | if (dipent.flags & F_QUIET && (lates || abandons)) {
309 | fputs("\n", rfp);
310 | if (lates) {
311 | if (dipent.x2flags & X2F_SECRET)
312 | fprintf(rfp, "One or more powers are late.\n");
313 | else
314 | fprintf(rfp, "%d power%s late.\n", lates, lates == 1 ? " is" : "s are");
315 | }
316 | if (abandons) {
317 | if (dipent.x2flags & X2F_SECRET)
318 | fprintf(rfp, "One or more powers are abandoned.\n");
319 | else
320 | fprintf(rfp, "%d power%s abandoned.\n", abandons, abandons == 1 ? " is" : "s are");
321 | }
322 |
323 | /* fputs("\n", rfp); */
324 | }
325 | }
326 |
327 |
328 | fputs("\n", rfp);
329 |
330 | }
331 |
332 |
333 | /***************************************************************************/
334 |
335 | void mail_listbrief(void)
336 | {
337 |
338 | /* List out current status of the game briefly */
339 |
340 | int i, n;
341 | char *s;
342 | static int count = 0;
343 |
344 |
345 | if (!count++) {
346 | fprintf(rfp, "Name Phase Variant/Options\n");
347 | fprintf(rfp, "------- ------ ---------------\n");
348 | }
349 | fprintf(rfp, "%-10.10s%-9.9s", dipent.name, dipent.phase);
350 |
351 | fprintf(rfp, "%c%s",
352 | toupper(*variants[dipent.variant]), variants[dipent.variant] + 1);
353 |
354 | if (dipent.flags & F_GUNBOAT)
355 | fprintf(rfp, ", Gunboat");
356 |
357 | if (dipent.flags & F_BLIND)
358 | fprintf(rfp, ", Blind");
359 |
360 | if (dipent.flags & F_AFRULES)
361 | fprintf(rfp, ", A/F");
362 |
363 | if (dipent.flags & F_SHORTHAND)
364 | fprintf(rfp, ", Shorthand");
365 |
366 | if (dipent.flags & F_WINGS)
367 | fprintf(rfp, ", Wings");
368 |
369 | if (!(dipent.flags & F_NONMR))
370 | fprintf(rfp, ", NMR");
371 |
372 | if ((i = (int) dipent.movement.next) < 72)
373 | fprintf(rfp, ", %d hrs", i);
374 |
375 | if (dipent.access == A_ANY)
376 | fprintf(rfp, ", Any-site");
377 |
378 | if (dipent.access == A_SAME)
379 | fprintf(rfp, ", Same-site");
380 |
381 | if (dipent.flags & F_MODERATE) {
382 | fprintf(rfp, ", Moderated (");
383 | for (i = 0; i < dipent.n; i++) {
384 | if (dipent.players[i].power == MASTER) {
385 | for (n = 0, s = dipent.players[i].address; *s && *s != '@'; s++)
386 | fputc(!n++ && islower(*s) ? toupper(*s) : *s, rfp);
387 | break;
388 | }
389 | }
390 | fputc(')', rfp);
391 | }
392 | /* Comment this out to not display press in brief listing *RV* */
393 | /* Comment until the next "*RV*" */
394 |
395 | fprintf(rfp, ", Press:");
396 |
397 | if (dipent.flags & F_NOWHITE)
398 | fprintf(rfp, "-");
399 | else
400 | fprintf(rfp, "W");
401 |
402 | if (dipent.flags & F_GREY)
403 | fprintf(rfp, "G");
404 | else
405 | fprintf(rfp, "-");
406 |
407 | if (dipent.flags & F_NOPARTIAL || dipent.flags & F_NOWHITE)
408 | fprintf(rfp, "-");
409 | else
410 | fprintf(rfp, "P");
411 |
412 | if (dipent.flags & F_FAKE)
413 | fprintf(rfp, "F");
414 | else
415 | fprintf(rfp, "-");
416 |
417 | /* *RV* */
418 |
419 | if (dipent.flags & F_NORATE)
420 | fprintf(rfp, ", Unrated");
421 |
422 | /* Uncomment this for a display of Winning Centres in brief listing */
423 | /* fprintf(rfp,", Win=%d",dipent.vp); */
424 |
425 | if (dipent.phase[6] == 'X') {
426 | for (i = 0; i < dipent.n; i++) {
427 | if (dipent.players[i].power < 0)
428 | continue;
429 |
430 | if (dipent.players[i].centers >= dipent.vp) {
431 | fprintf(rfp, ", Completed");
432 | break;
433 | }
434 | }
435 | if (i == dipent.n) {
436 | fprintf(rfp, ", Terminated");
437 | }
438 | }
439 | fputs(".\n", rfp);
440 |
441 | if ((n = strlen(dipent.comment))) {
442 | if (n < 60)
443 | n = 20;
444 | else if (n < 69)
445 | n = 11;
446 | else
447 | n = 79 - n;
448 | fprintf(rfp, "%*s%s\n", n, "", dipent.comment);
449 | }
450 |
451 | if (dipent.phase[6] != 'X' && dipent.seq[0] == 'x') {
452 | n = dipent.np - (dipent.seq[1] - '0');
453 | if (n == 0) fprintf(rfp, "%21.21sFormed: waiting to be started.\n","");
454 | else if (dipent.x2flags & X2F_SECRET) {
455 | fprintf(rfp, "%21.21sForming: more players needed.\n", "" );
456 | } else {
457 | fprintf(rfp, "%21.21sForming: %d%s player%s needed.\n", "",
458 | n, n == dipent.np ? "" : " more", n == 1 ? "" : "s");
459 | }
460 | } else if (dipent.phase[6] != 'X') {
461 | n = 0;
462 | for (i = 0; i < dipent.n; i++) {
463 | if (dipent.players[i].power < 0)
464 | continue;
465 |
466 | if ((dipent.players[i].status & (SF_CD | SF_ABAND)
467 | || *dipent.players[i].address == '*') &&
468 | (dipent.players[i].status & SF_MOVE
469 | || dipent.players[i].centers != 0)) {
470 |
471 | if (!n++)
472 | fprintf(rfp, "%21.21sOpenings: ", "");
473 | else
474 | fputs(", ", rfp);
475 |
476 | fprintf(rfp, "%s", powers[dipent.players[i].power]);
477 | if (!(dipent.flags & F_BLIND))
478 | fprintf(rfp, " (%d/%d)",
479 | dipent.players[i].units,
480 | dipent.players[i].centers-dipent.players[i].centres_blockaded);
481 | }
482 | }
483 | if (n)
484 | fputs("\n", rfp);
485 | }
486 | }
487 |
488 |
489 | /***************************************************************************/