Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/misc.c @ 4:aa38447a4b21
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:03 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:cafa94d86546 | 4:aa38447a4b21 |
---|---|
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--------*/ |