4
|
1 /*--------------------------------------------------------------------------
|
|
2 NETREK II -- Paradise
|
|
3
|
|
4 Permission to use, copy, modify, and distribute this software and its
|
|
5 documentation, or any derivative works thereof, for any NON-COMMERCIAL
|
|
6 purpose and without fee is hereby granted, provided that this copyright
|
|
7 notice appear in all copies. No representations are made about the
|
|
8 suitability of this software for any purpose. This software is provided
|
|
9 "as is" without express or implied warranty.
|
|
10
|
|
11 Xtrek Copyright 1986 Chris Guthrie
|
|
12 Netrek (Xtrek II) Copyright 1989 Kevin P. Smith
|
|
13 Scott Silvey
|
|
14 Paradise II (Netrek II) Copyright 1993 Larry Denys
|
|
15 Kurt Olsen
|
|
16 Brandon Gillespie
|
|
17 --------------------------------------------------------------------------*/
|
|
18
|
|
19 #include "config.h"
|
|
20
|
|
21 #include <stdio.h>
|
|
22 #include <stdlib.h>
|
|
23 #include <string.h>
|
|
24 #include <math.h>
|
|
25 #include <setjmp.h>
|
|
26
|
|
27 #include "defs.h"
|
|
28 #include "misc.h"
|
|
29 #include "struct.h"
|
|
30 #include "data.h"
|
|
31 #include "daemonII.h"
|
|
32 #include "planets.h"
|
|
33 #include "shmem.h"
|
|
34
|
|
35 /*------------------------------MODULE VARIABLES--------------------------*/
|
|
36
|
|
37 #define NMESSAGES 16
|
|
38 /* The list of messages that are sent when t-mode begins. */
|
|
39 char *warmessages[] = {
|
|
40 "A dark mood settles upon the galaxy as galactic superpowers seek",
|
|
41 "to colonize new territory. Border disputes errupt developing",
|
|
42 "into all out intergalactic WAR!!!",
|
|
43
|
|
44 "Slick Willy is elected president, the bottom falls out of the",
|
|
45 "economy, and the pressure to expand rises.",
|
|
46
|
|
47 "Clinton found with foreign emperor's wife!",
|
|
48 "All out war ensues.",
|
|
49
|
|
50 "Taxes on the rich raised to 80%.",
|
|
51 "The rich flee to neigboring empire.",
|
|
52 "Democrats demand extradition.",
|
|
53 "Foreign emporer refuses.",
|
|
54 "Hillary 'Rob Them' Clinton declares war!",
|
|
55 "Bill hides out in London.",
|
|
56
|
|
57 "INTERGALACTIC BEER SHORTAGE!",
|
|
58 "CHAOS LIKE IT HAS NEVER BEEN SEEN BEFORE ENSUES!",
|
|
59
|
|
60 "The American Gladiators hit as the number 1 show on the vid.",
|
|
61 "After a gruesome episode, the masses storm out their homes,",
|
|
62 "jump in their ships, make a quick stop at their local 7-11",
|
|
63 "to grab a few beers, then head out into the galaxy to ",
|
|
64 "KICK SOME ASS. WAR!!!!!!!!!!!!!!!!!!",
|
|
65
|
|
66 "Khan is resurrected in a bizzare experiment. Elected as head of",
|
|
67 "the Starfleet Council, he removes all pajama-wearing new-age",
|
|
68 "hippies from Starfleet. (And you thought the borg were bad news)",
|
|
69
|
|
70 "Several members of the computing support staff of the Galactic",
|
|
71 "Council are severely injured in a freak skydiving accident.",
|
|
72 "The rest are killed. The network collapses without their",
|
|
73 "guidance. Galactic chaos breaks out!",
|
|
74
|
|
75 /* oldies */
|
|
76 "A dark mood settles upon the galaxy",
|
|
77 "Political pressure to expand is rising",
|
|
78 "Border disputes break out as political tensions increase!",
|
|
79 "Galactic superpowers seek to colonize new territory!",
|
|
80 "'Manifest Destiny' becomes motive in galactic superpower conflict!",
|
|
81 "Diplomat insults foriegn emperor's mother and fighting breaks out!",
|
|
82 "Dan Quayle declares self as galactic emperor and chaos breaks out!",
|
|
83 "Peace parties have been demobilized, and fighting ensues.",
|
|
84 };
|
|
85
|
|
86
|
|
87 /*
|
|
88 * The starting index of the message series and the number of messages in
|
|
89 * series.
|
|
90 */
|
|
91 int warm[NMESSAGES][2] = {
|
|
92 {0, 3},
|
|
93 {3, 2},
|
|
94 {5, 2},
|
|
95 {7, 6},
|
|
96 {13, 2},
|
|
97 {15, 5},
|
|
98 {20, 3},
|
|
99 {23, 4},
|
|
100 {27, 1},
|
|
101 {28, 1},
|
|
102 {29, 1},
|
|
103 {30, 1},
|
|
104 {31, 1},
|
|
105 {32, 1},
|
|
106 {33, 1},
|
|
107 {34, 1},
|
|
108 };
|
|
109
|
|
110
|
|
111 /* The set of message series that are displayed when t-mode ends. */
|
|
112 char *peacemessages[] = {
|
|
113 "The expansionist pressure subsides, and temporary agreements are",
|
|
114 "reached in local border disputes.",
|
|
115 "Peace returns to the galaxy...",
|
|
116
|
|
117 "Wild mob storms the White House!",
|
|
118 "Clinton flees.",
|
|
119 "Order returns to the galaxy.",
|
|
120
|
|
121 "Slick Willy apologizes about incident with foreign emperor's wife.",
|
|
122 "Claims he did not penetrate.",
|
|
123 "Peace ensues.",
|
|
124
|
|
125 "The economy goes belly up. The Democrats are kicked",
|
|
126 "out of office, tarred and feathered, and sent to the",
|
|
127 "zoo on Rigel 4. Capitalism is implemented and order",
|
|
128 "returns to the empire.",
|
|
129
|
|
130 "Officials sieze hidden beer stockpiles at the Mackenzie brother's",
|
|
131 "house! The beer shortage is over. Peace breaks out.",
|
|
132
|
|
133 "The people decide they would rather sit home and watch",
|
|
134 "Al Bundy than fight. The war comes to an end.",
|
|
135
|
|
136 "Khan takes a fatal blow to the kidneys when Kirk returns from",
|
|
137 "retirement and whacks him in the back with his walker.",
|
|
138 "It looks like the hippies are back in control.",
|
|
139
|
|
140 "Sole survivors of the skydiving accident that took out the",
|
|
141 "rest of the computing support staff, Michael McLean and Brad",
|
|
142 "Spatz are released from intensive care and rebuild the",
|
|
143 "network. Peace is restored to the Galaxy.",
|
|
144
|
|
145 /* oldies */
|
|
146 "A new day dawns as the oppressive mood lifts",
|
|
147 "The expansionist pressure subsides",
|
|
148 "Temporary agreement is reached in local border disputes.",
|
|
149 "Galactic governments reduce colonization efforts.",
|
|
150 "'Manifest Destiny is no longer a fad.' says influential philosopher.",
|
|
151 "Diplomat apologizes to foreign emperor's mother and invasion is stopped!",
|
|
152 "Dan Quayle is locked up and order returns to the galaxy!",
|
|
153 "The peace party has reformed, and is rallying for peace",
|
|
154 };
|
|
155
|
|
156
|
|
157 /*
|
|
158 * The starting index of each message series and the number of messages in
|
|
159 * the series.
|
|
160 */
|
|
161 int peacem[NMESSAGES][2] = {
|
|
162 {0, 3},
|
|
163 {3, 3},
|
|
164 {6, 3},
|
|
165 {9, 4},
|
|
166 {13, 2},
|
|
167 {15, 2},
|
|
168 {17, 3},
|
|
169 {20, 4},
|
|
170 {24, 1},
|
|
171 {25, 1},
|
|
172 {26, 1},
|
|
173 {27, 1},
|
|
174 {28, 1},
|
|
175 {29, 1},
|
|
176 {30, 1},
|
|
177 {31, 1},
|
|
178 };
|
|
179
|
|
180
|
|
181 static int series = 0; /* the message series that was printed */
|
|
182 /* when t-mode started. */
|
|
183
|
|
184 /*------------------------------------------------------------------------*/
|
|
185
|
|
186
|
|
187
|
|
188
|
|
189
|
|
190
|
|
191
|
|
192
|
|
193 /*------------------------------VISIBLE FUNCTIONS-------------------------*/
|
|
194
|
|
195 /*---------------------------------WARMESSAGE----------------------------*/
|
|
196 /*
|
|
197 * This function is called when t-mode ensues. It chooses a message series
|
|
198 * and prints it out. It records the message series in the module's series
|
|
199 * variable so that the corresponding peace message series can be printed.
|
|
200 */
|
|
201
|
|
202
|
|
203 void
|
|
204 warmessage()
|
|
205 {
|
|
206 int i; /* to hold index */
|
|
207 int n; /* number of messages in a series */
|
|
208
|
|
209 i = lrand48() % NMESSAGES; /* choose message series */
|
|
210 series = i; /* record series number */
|
|
211 n = warm[i][1]; /* get number of messages in series */
|
|
212 i = warm[i][0]; /* get index of first message */
|
|
213 while (n > 0)
|
|
214 { /* print all messages */
|
|
215 pmessage(warmessages[i], 0, MALL, " WAR-> ");
|
|
216 n--; /* dec messages that need to be printed */
|
|
217 i++; /* on to next message */
|
|
218 }
|
|
219 }
|
|
220
|
|
221
|
|
222
|
|
223
|
|
224 /*-------------------------------PEACEMESSAGE-----------------------------*/
|
|
225 /*
|
|
226 * This function prints a peace message series. It uses the module variable
|
|
227 * series to decide which message series to print.
|
|
228 */
|
|
229
|
|
230 void
|
|
231 peacemessage()
|
|
232 {
|
|
233 int i; /* to hold index */
|
|
234 int n; /* number of messages in a series */
|
|
235
|
|
236 n = peacem[series][1]; /* get # messages in series */
|
|
237 i = peacem[series][0]; /* get starting index */
|
|
238 while (n > 0)
|
|
239 { /* print all messages */
|
|
240 pmessage(peacemessages[i], 0, MALL, " PEACE-> ");
|
|
241 n--; /* dec messages that need to be printed */
|
|
242 i++; /* on to next message */
|
|
243 }
|
|
244 }
|
|
245
|
|
246
|
|
247
|
|
248
|
|
249 /*-------------------------------REALNUMSHIPS-----------------------------*/
|
|
250 /*
|
|
251 * This function counts the number of ships on a team. If the race is the
|
|
252 * same and the slot is not free, then the ship is counted.
|
|
253 */
|
|
254
|
|
255 int
|
|
256 realNumShips(owner)
|
|
257 int owner;
|
|
258 {
|
|
259 int i, num; /* for looping and counting */
|
|
260 struct player *p; /* to point to a player */
|
|
261
|
|
262 num = 0; /* zero the count of ships */
|
|
263 for (i = 0, p = players; i < MAXPLAYER; i++, p++)
|
|
264 if ((p->p_status != PFREE) && (p->p_team == owner))
|
|
265 num++; /* found a ship on this team, inc count */
|
|
266 return (num); /* return number of ships */
|
|
267 }
|
|
268
|
|
269
|
|
270
|
|
271
|
|
272 /*------------------------------TOURNAMENTMODE------------------------------*/
|
|
273 /*
|
|
274 * This function counts the number of players on each team and sees if two or
|
|
275 * more teams have enough players for t-mode. It returns a 0 for no team
|
|
276 * mode.
|
|
277 */
|
|
278
|
|
279 int
|
|
280 tournamentMode()
|
|
281 {
|
|
282 #ifdef LEAGUE_SUPPORT
|
|
283 if (status2->league)
|
|
284 {
|
|
285 return status2->league > 2;
|
|
286 }
|
|
287 else
|
|
288 #endif
|
|
289 {
|
|
290 static int wt = -1; /* warning time due to team unbalance */
|
|
291 static int lct = -1; /* last check time (ie last pmessage) */
|
|
292 char buf[80]; /* temp buffer for tmode halt warning */
|
|
293 int i; /* looping vars */
|
|
294 int t[16]; /* to count players with */
|
|
295 int counts[4];
|
|
296 /* Even though teams go from 0-8, leave */
|
|
297 /* this at 16...or bad things might happen */
|
|
298 struct player *p; /* to point to players */
|
|
299
|
|
300 for (i = 0; i < 16; i++) /* clear the team players count array */
|
|
301 t[i] = 0;
|
|
302 for (i = 0, p = players; i < MAXPLAYER; i++, p++)
|
|
303 {
|
|
304 /* through all players */
|
|
305 if (p->p_flags & PFROBOT)
|
|
306 continue; /* robots don't count */
|
|
307 switch (p->p_status)
|
|
308 {
|
|
309 case PFREE: /* free slots obviously don't count */
|
|
310 case POBSERVE: /* and neither do observers */
|
|
311 break;
|
|
312
|
|
313 case PEXPLODE:
|
|
314 case PDEAD:
|
|
315 case PTQUEUE:
|
|
316 if (p->p_observer)
|
|
317 break; /* observers in these modes don't count */
|
|
318 /* we can fall through here */
|
|
319 case POUTFIT:
|
|
320 case PALIVE:
|
|
321 t[p->p_team]++;
|
|
322 break;
|
|
323 }
|
|
324 }
|
|
325
|
|
326 #if 0
|
|
327 /*
|
|
328 * If there hasnt been tmode recently (5 mins) clear all kills, and place
|
|
329 * any carried armies on the most valuble planet not yet finished.
|
|
330 */
|
|
331 if ((tourntimestamp - ticks) > 300)
|
|
332 {
|
|
333 int x;
|
|
334 for (x = 0; x < MAXPLAYER; x++)
|
|
335 {
|
|
336 if (players[x].p_status == PALIVE)
|
|
337 {
|
|
338 if (players[x].p_armies > 0)
|
|
339 PlaceLostArmies(players[x]);
|
|
340 players[x].p_kills = 0.00;
|
|
341 }
|
|
342 }
|
|
343 }
|
|
344 #endif
|
|
345
|
|
346 i = 0; /* zero count of # teams with tournplayers */
|
|
347 if (t[FED] >= configvals->tournplayers)
|
|
348 counts[i++] = t[FED];
|
|
349 if (t[ROM] >= configvals->tournplayers)
|
|
350 counts[i++] = t[ROM];
|
|
351 if (t[KLI] >= configvals->tournplayers)
|
|
352 counts[i++] = t[KLI];
|
|
353 if (t[ORI] >= configvals->tournplayers)
|
|
354 counts[i++] = t[ORI];
|
|
355 if (i > 1)
|
|
356 {
|
|
357 i = counts[0] - counts[1];
|
|
358 if (i < 0)
|
|
359 i = -i;
|
|
360 if (i > 2)
|
|
361 { /* Too big a team imbalance */
|
|
362 if (wt == -1)
|
|
363 {
|
|
364 wt = status->clock; /* make a timestamp */
|
|
365 lct = status->clock; /* used every time it sends the message */
|
|
366 }
|
|
367 if (((status->clock - wt) < 3) && (lct < status->clock))
|
|
368 {
|
|
369 /*
|
|
370 * teams are unblananced, and we havn't said anything for 1 minute,
|
|
371 * warn everybody Yes these are noisy strings, but I want people
|
|
372 * to notice.
|
|
373 */
|
|
374 pmessage("**************************!! Teams are unbalanced !!**************************", 0, MALL, "");
|
|
375 sprintf(buf, "********************* TMODE WILL BE HALTED IN %li MINUTES **********************", (wt - status->clock) + 3);
|
|
376 pmessage(buf, 0, MALL, "");
|
|
377 pmessage("************************ if this problem isn't fixed *************************", 0, MALL, "");
|
|
378 lct = status->clock;
|
|
379 return (1);
|
|
380 }
|
|
381 else if ((status->clock - wt) >= 3)
|
|
382 {
|
|
383 if (lct < status->clock)
|
|
384 {
|
|
385 pmessage("******************!! TMODE HALTED DUE TO TEAM IMBALANCE !!********************", 0, MALL, "");
|
|
386 pmessage("*********************** Balance teams to resume tmode ************************", 0, MALL, "");
|
|
387 lct = status->clock;
|
|
388 }
|
|
389 return (0); /* stop tmode */
|
|
390 }
|
|
391 }
|
|
392 else
|
|
393 {
|
|
394 wt = -1;
|
|
395 lct = -1;
|
|
396 }
|
|
397 return (1); /* return that we are in team mode */
|
|
398 }
|
|
399 return (0); /* we are NOT in T-mode */
|
|
400 }
|
|
401 }
|
|
402
|
|
403
|
|
404
|
|
405
|
|
406 /*------------------------------PMESSAGE----------------------------------*/
|
|
407 /*
|
|
408 * This function sens a message to the message board. It places the message
|
|
409 * in the next position of the array of messages. The message will ahve a
|
|
410 * header attached to the front of it.
|
|
411 */
|
|
412
|
|
413 void
|
|
414 pmessage(str, recip, group, address)
|
|
415 char *str; /* the message */
|
|
416 int recip; /* who is the recipient */
|
|
417 int group; /* group sent to and other flags */
|
|
418 char *address; /* the header attached to front */
|
|
419 {
|
|
420 struct message *cur; /* to pnt to where to put message */
|
|
421 int mesgnum; /* to hold index into array of messgs */
|
|
422
|
|
423 if ((mesgnum = ++(mctl->mc_current)) >= MAXMESSAGE)
|
|
424 {
|
|
425 mctl->mc_current = 0; /* move to next index in array and */
|
|
426 mesgnum = 0; /* warp around if necessart */
|
|
427 }
|
|
428 cur = &messages[mesgnum]; /* get addr of message struct */
|
|
429 cur->m_no = mesgnum; /* set the message number */
|
|
430 cur->m_flags = group; /* set the group and flags */
|
|
431 cur->m_recpt = recip; /* set the recipient */
|
|
432 cur->m_from = 255; /* message is from God */
|
|
433 (void) sprintf(cur->m_data, "%s %s", address, str);
|
|
434 cur->m_flags |= MVALID; /* mark message as valid */
|
|
435 }
|
|
436
|
|
437 /*
|
|
438 * send a message from god to a particular player number
|
|
439 */
|
|
440
|
|
441 void
|
|
442 god2player(str, pno)
|
|
443 char *str;
|
|
444 int pno;
|
|
445 {
|
|
446 struct message *cur; /* to pnt to where to put message */
|
|
447
|
|
448 if (++(mctl->mc_current) >= MAXMESSAGE)
|
|
449 mctl->mc_current = 0;
|
|
450 cur = &messages[mctl->mc_current];
|
|
451
|
|
452 cur->m_no = mctl->mc_current;
|
|
453 cur->m_flags = MINDIV;
|
|
454 cur->m_recpt = pno;
|
|
455 cur->m_from = 255;
|
|
456 sprintf(cur->m_data, "%s->%s %s", SERVNAME, twoletters(&players[pno]), str);
|
|
457 cur->m_flags |= MVALID;
|
|
458 }
|
|
459
|
|
460
|
|
461
|
|
462
|
|
463 /*-------------------------------LOG_MESSAGE------------------------------*/
|
|
464 /*
|
|
465 * This function writes a message into the logfile so the server god can look
|
|
466 * at it later. It is used to record messages to god.
|
|
467 */
|
|
468
|
|
469 void
|
|
470 log_message(msg)
|
|
471 char *msg; /* the string to record */
|
|
472 {
|
|
473 char *path; /* to hold path and name */
|
|
474 FILE *logfile; /* to open logfile with */
|
|
475
|
|
476 path = build_path(GODLOGFILE);
|
|
477 logfile = fopen(path, "a"); /* let's try to open this baby */
|
|
478 if (!logfile) /* Oops, could not open */
|
|
479 return; /* OUt of Dodge */
|
|
480 fputs(msg, logfile); /* write the string to log file */
|
|
481 fclose(logfile); /* close the sucker up */
|
|
482 }
|
|
483
|
|
484
|
|
485
|
|
486
|
|
487 /*-----------------------------PARSE_GODMESSAGES----------------------------*/
|
|
488 /*
|
|
489 * This function checks all the new messages in the message buffer to see if
|
|
490 * the keyword 'GOD' is at the first of the message. If it is, then the
|
|
491 * message is written to the logfile so the server god can read it.
|
|
492 */
|
|
493
|
|
494 void
|
|
495 parse_godmessages()
|
|
496 {
|
|
497 char buf[100]; /* bigger than message::m_data */
|
|
498 static int lastparsed = 0; /* keeps track of last message */
|
|
499
|
|
500 while (mctl->mc_current != lastparsed)
|
|
501 { /* Is there a new message? */
|
|
502 struct message *cur; /* to point to message struct */
|
|
503 char *s; /* to point to string */
|
|
504
|
|
505 if (++lastparsed >= MAXMESSAGE) /* rollover after end of */
|
|
506 lastparsed = 0; /* message buffer */
|
|
507 cur = &messages[lastparsed];/* get new message's struct */
|
|
508
|
|
509 s = cur->m_data + 1; /* get new message */
|
|
510 while ((*s != ' ') && (*s != 0)) /* go until first space */
|
|
511 s++;
|
|
512 while ((*s == ' ') && (*s != 0)) /* go past spaces */
|
|
513 s++;
|
|
514
|
|
515 if (!*s)
|
|
516 continue;
|
|
517 if (cur->m_flags & MGOD)
|
|
518 { /* if it's to god */
|
|
519 sprintf(buf, "%s says: %s\n",
|
|
520 (cur->m_from >= 0) ? players[cur->m_from].p_name : "who", s);
|
|
521 }
|
|
522 else
|
|
523 { /* or labeled to god */
|
|
524 if (strncmp(s, "GOD:", 4) != 0) /* check for 'GOD' keyword */
|
|
525 continue; /* not there, then next message */
|
|
526 sprintf(buf, "GOD: %s\n", s + 4);
|
|
527 }
|
|
528 log_message(buf); /* go record message */
|
|
529 }
|
|
530 }
|
|
531
|
|
532 /*------------------------------------------------------------------------*/
|
|
533 #if 0
|
|
534 /*--------------------------[ PLACE LOST ARMIES ]--------------------------*/
|
|
535 /*
|
|
536 * If for some reason or another the player looses armies they may be
|
|
537 * carrying (ghost busts, etc), this function is called, to place the armies
|
|
538 * safely on a planet.
|
|
539 */
|
|
540
|
|
541 void
|
|
542 PlaceLostArmies(victim)
|
|
543 struct player *victim;
|
|
544 {
|
|
545 char buf[80];
|
|
546 int i, startplanet;
|
|
547
|
|
548 ((startplanet = find_start_planet(me->p_team, PLSHIPYARD)) != -1
|
|
549 || (startplanet = find_start_planet(me->p_team, PLREPAIR)) != -1
|
|
550 || (startplanet = find_start_planet(me->p_team, PLAGRI)) != -1
|
|
551 || (startplanet = find_start_planet(me->p_team, PLFUEL)) != -1
|
|
552 || (startplanet = find_start_planet(me->p_team, PLHOME)) != -1
|
|
553 || (startplanet = find_start_planet(me->p_team, 0)) != -1);
|
|
554 planets[startplanet].pl_armies += victim->p_armies;
|
|
555 (void) sprintf(buf, "%s's %d armies placed on %s",
|
|
556 victim->p_name, victim->p_armies, planets[startplanet].pl_name);
|
|
557 pmessage(buf, 0, MALL | MGHOST, MSERVA);
|
|
558 }
|
|
559 #endif
|
|
560 /*------------------------------------------------------------------------*/
|
|
561
|
|
562 /*----------END OF FILE--------*/
|