Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/redraw.c @ 6:8c6d5731234d
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:04 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
5:054275999194 | 6:8c6d5731234d |
---|---|
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 #include <stdio.h> | |
21 #include <signal.h> | |
22 #include <setjmp.h> /* change 4/14/91 TC */ | |
23 #include <string.h> | |
24 #include <time.h> | |
25 | |
26 #include <math.h> | |
27 #include "defs.h" | |
28 #include "struct.h" | |
29 #include "data.h" | |
30 #include "packets.h" | |
31 #include "shmem.h" | |
32 | |
33 extern char start_login[], start_name[]; /* change 4/14/91 TC */ | |
34 extern int goAway; /* change 4/14/91 TC */ | |
35 extern jmp_buf env; /* change 4/14/91 TC */ | |
36 | |
37 | |
38 #ifdef AUTHORIZE | |
39 extern int makeReservedPacket(); | |
40 #endif | |
41 extern int sendClientPacket(); | |
42 #ifndef IRIX | |
43 extern int fprintf(); | |
44 #endif | |
45 extern void death(); | |
46 void auto_features(); | |
47 extern int set_speed(); | |
48 extern int orbit(); | |
49 extern int set_course(); | |
50 int newcourse(); | |
51 extern void imm_warning(); | |
52 | |
53 #ifdef AUTHORIZE | |
54 void | |
55 check_authentication() | |
56 { | |
57 /* if (!configvals->binconfirm) testtime=0; */ | |
58 if (testtime == -1) | |
59 { | |
60 struct reserved_spacket sp; | |
61 | |
62 #ifdef RSA_EXEMPTION_FILE | |
63 if (site_rsa_exempt()) | |
64 { | |
65 printf("site exempt from RSA authentication\n"); | |
66 strcpy(RSA_client_type, "site/player is RSA exempt"); | |
67 testtime = 0; | |
68 } | |
69 else | |
70 #endif /* RSA_EXEMPTION_FILE */ | |
71 { | |
72 /* | |
73 * Give reasonable period of time to respond to query (and test code if | |
74 * they need to) | |
75 */ | |
76 | |
77 testtime = 200; | |
78 makeReservedPacket(&sp); | |
79 memcpy(testdata, sp.data, KEY_SIZE); | |
80 sendClientPacket((struct player_spacket *) & sp); | |
81 } /* RSA EXEMPTION */ | |
82 } | |
83 else if (testtime != 0) | |
84 { | |
85 testtime--; | |
86 if (testtime == 0) | |
87 { | |
88 /* User failed to respond to verification query. Bye! */ | |
89 if (!configvals->binconfirm) | |
90 me->p_stats.st_flags |= ST_CYBORG; /* mark for reference 7/27/91 | |
91 * TC */ | |
92 else | |
93 { | |
94 me->p_explode = 10; | |
95 me->p_whydead = KQUIT; | |
96 me->p_status = PEXPLODE; | |
97 fprintf(stderr, "User binary failed to verify\n"); | |
98 if (RSA_Client == 1) | |
99 warning("No customized binaries. Please use a blessed one."); | |
100 else if (RSA_Client == 2) | |
101 warning("Wrong Client Version Number!"); | |
102 else | |
103 warning("You need a spiffy new RSA client for this server!"); | |
104 } | |
105 } | |
106 } | |
107 } | |
108 #endif /* AUTHORIZE */ | |
109 | |
110 void | |
111 intrupt() | |
112 { | |
113 #ifdef AUTHORIZE | |
114 check_authentication(); | |
115 #endif | |
116 | |
117 if (me->p_status == PFREE) | |
118 { | |
119 me->p_ghostbuster = 0; | |
120 me->p_status = PDEAD; | |
121 } | |
122 /* Change 4/14/91 TC: fixing 2 players/1 slot bug here, since this is */ | |
123 /* where the ghostbust check is */ | |
124 | |
125 #if 0 | |
126 if ((strcmp(me->p_login, start_login) != 0) || | |
127 (strcmp(me->p_name, start_name) != 0)) | |
128 { | |
129 struct pstatus_spacket pstatus; | |
130 goAway = 1; /* get rid of this client! */ | |
131 warning("Sorry, your slot has been taken by another player."); | |
132 pstatus.type = SP_PSTATUS; | |
133 pstatus.pnum = 0; | |
134 pstatus.status = PDEAD; | |
135 sendClientPacket(&pstatus); | |
136 longjmp(env, 0); | |
137 } | |
138 #endif | |
139 | |
140 if (me->p_status == PEXPLODE || me->p_status == PDEAD) | |
141 { | |
142 inputMask = 0; | |
143 } | |
144 if (((me->p_status == PDEAD) || (me->p_status == POUTFIT)) | |
145 && (me->p_ntorp <= 0) && (me->p_nplasmatorp <= 0)) | |
146 { | |
147 death(); | |
148 } | |
149 auto_features(); | |
150 updateClient(); | |
151 } | |
152 | |
153 | |
154 static void | |
155 selfdestruct_countdown() | |
156 { | |
157 char buf[180]; | |
158 if (!(me->p_flags & PFSELFDEST)) | |
159 return; | |
160 | |
161 if ((me->p_updates >= selfdest) || | |
162 ((me->p_flags & PFGREEN) && (me->p_damage == 0) | |
163 && (me->p_shield == me->p_ship.s_maxshield))) | |
164 { | |
165 me->p_flags &= ~PFSELFDEST; | |
166 me->p_explode = 10; | |
167 me->p_whydead = KQUIT; | |
168 me->p_status = PEXPLODE; | |
169 } | |
170 else | |
171 { | |
172 switch ((selfdest - me->p_updates) / 10) | |
173 { | |
174 case 5: | |
175 case 4: | |
176 imm_warning("You notice everyone on the bridge is staring at you."); | |
177 break; | |
178 default: | |
179 sprintf(buf, "Stand by ... Self destruct in %d seconds", | |
180 (selfdest - me->p_updates) / 10); | |
181 imm_warning(buf); | |
182 break; | |
183 } | |
184 } | |
185 } | |
186 | |
187 static void | |
188 warp_powerup() | |
189 { | |
190 static int sequence = 0; | |
191 int time = myship->s_warpinittime; | |
192 | |
193 if (me->p_warptime <= 0 && sequence == 0) | |
194 return; | |
195 | |
196 if (me->p_speed > myship->s_warpprepspeed && !(me->p_flags & PFWARP)) | |
197 { | |
198 if (sequence < 1) | |
199 { | |
200 warning("Prepping for warp jump"); | |
201 sequence = 1; | |
202 } | |
203 } | |
204 else if (me->p_warptime >= time * 9 / 10 /* 37 */ ) | |
205 { | |
206 if (sequence < 2) | |
207 { | |
208 warning("Starting power buildup for warp"); | |
209 sequence = 2; | |
210 } | |
211 } | |
212 else if (me->p_warptime >= time * 3 / 4 /* 30 */ ) | |
213 { | |
214 if (sequence < 3) | |
215 { | |
216 imm_warning("Warp power buildup at 30%"); | |
217 sequence = 3; | |
218 } | |
219 } | |
220 else if (me->p_warptime >= time * 3 / 5 /* 23 */ ) | |
221 { | |
222 if (sequence < 4) | |
223 { | |
224 imm_warning("Warp power buildup at 60%"); | |
225 sequence = 4; | |
226 } | |
227 } | |
228 else if (me->p_warptime >= time * 2 / 5 /* 16 */ ) | |
229 { | |
230 if (sequence < 5) | |
231 { | |
232 imm_warning("Warp power buildup at 90%"); | |
233 sequence = 5; | |
234 } | |
235 } | |
236 else if (me->p_warptime >= time * 1 / 5 /* 8 */ ) | |
237 { | |
238 if (sequence < 6) | |
239 { | |
240 imm_warning("Commander Hoek: `Prepare to surge to sub-light speed'"); | |
241 sequence = 6; | |
242 } | |
243 } | |
244 else if (me->p_warptime == 0) | |
245 { | |
246 warning((me->p_flags & PFWARP) ? "Engage" : "Warp drive aborted"); | |
247 sequence = 0; | |
248 } | |
249 } | |
250 | |
251 static void | |
252 refit_countdown() | |
253 { | |
254 char buf[120]; | |
255 static int lastRefitValue = 0;/* for smooth display */ | |
256 | |
257 if (!(me->p_flags & PFREFITTING)) | |
258 return; | |
259 | |
260 if (lastRefitValue != (rdelay - me->p_updates) / 10) | |
261 { | |
262 lastRefitValue = (rdelay - me->p_updates) / 10; /* CSE to the rescue? */ | |
263 switch (lastRefitValue) | |
264 { | |
265 case 3: | |
266 case 2: | |
267 sprintf(buf, "Engineering: Energizing transporters in %d seconds", lastRefitValue); | |
268 warning(buf); | |
269 break; | |
270 case 1: | |
271 warning("Engineering: Energize. [ SFX: chimes ]"); | |
272 break; | |
273 case 0: | |
274 switch (lrand48() % 5) | |
275 { | |
276 case 0: | |
277 warning("Wait, you forgot your toothbrush!"); | |
278 break; | |
279 case 1: | |
280 warning("Nothing like turning in a used ship for a new one."); | |
281 break; | |
282 case 2: | |
283 warning("First officer: Oh no, not you again... we're doomed!"); | |
284 break; | |
285 case 3: | |
286 warning("First officer: Uh, I'd better run diagnostics on the escape pods."); | |
287 break; | |
288 case 4: | |
289 warning("Shipyard controller: `This time, *please* be more careful, okay?'"); | |
290 break; | |
291 } | |
292 break; | |
293 } | |
294 } | |
295 } | |
296 | |
297 static void | |
298 backstab_countdown() | |
299 { | |
300 static int lastWarValue = 0; | |
301 | |
302 if (!(me->p_flags & PFWAR)) | |
303 return; | |
304 | |
305 if (lastWarValue != (delay - me->p_updates) / 10) | |
306 { | |
307 char *str = 0; | |
308 lastWarValue = (delay - me->p_updates) / 10; /* CSE to the rescue? */ | |
309 if (lastWarValue == 0) | |
310 { | |
311 static char buf[1024]; | |
312 static char *msgs[7] = { | |
313 "tires on the ether", | |
314 "Klingon bitmaps are ugly", | |
315 "Federation bitmaps are gay", | |
316 "all admirals have scummed", | |
317 "Mucus Pig exists", | |
318 "guests advance 5x faster", | |
319 "Iggy has infinite fuel", | |
320 }; | |
321 sprintf(buf, "First Officer: laws of the universe, like '%s'.", | |
322 msgs[lrand48() % 7]); | |
323 str = buf; | |
324 } | |
325 else if (lastWarValue <= 9) | |
326 { | |
327 static char *msgs[10] = { | |
328 "First Officer: Easy, big guy... it's just one of those mysterious", | |
329 "Weapons officer: Bah! [ bangs fist on inoperative console ]", | |
330 "Weapons officer: Just to twiddle a few bits of the ship's memory?", | |
331 "Weapons officer: ...the whole ship's computer is down?", | |
332 "Weapons officer: Not again! This is absurd...", | |
333 }; | |
334 str = msgs[(lastWarValue - 1) / 2]; | |
335 } | |
336 else | |
337 { | |
338 str = "urk"; | |
339 } | |
340 if (str) | |
341 { | |
342 warning(str); | |
343 } | |
344 } | |
345 } | |
346 | |
347 static void | |
348 bombing_info() | |
349 { | |
350 char buf[120]; | |
351 | |
352 if (!(me->p_flags & PFBOMB)) | |
353 return; | |
354 | |
355 if (planets[me->p_planet].pl_armies < 5) | |
356 { | |
357 if (configvals->facilitygrowth) | |
358 imm_warning("Weapons Officer: Bombing resources off planet, sir."); | |
359 else | |
360 { | |
361 sprintf(buf, "Weapons Officer: Bombing is ineffective. Sensor read %d armies left.", | |
362 planets[me->p_planet].pl_armies); | |
363 imm_warning(buf); | |
364 } | |
365 } | |
366 else | |
367 { | |
368 sprintf(buf, "Weapons Officer: Bombarding %s... Sensors read %d armies left.", | |
369 planets[me->p_planet].pl_name, | |
370 planets[me->p_planet].pl_armies); | |
371 imm_warning(buf); | |
372 } | |
373 } | |
374 | |
375 | |
376 static void | |
377 operate_transporters() | |
378 { | |
379 char buf[120]; | |
380 int troop_capacity = 0; | |
381 | |
382 if ((me->p_ship.s_nflags & SFNARMYNEEDKILL) && | |
383 (me->p_kills * myship->s_armyperkill) < myship->s_maxarmies) | |
384 { | |
385 troop_capacity = (int) (me->p_kills * myship->s_armyperkill); | |
386 } | |
387 else | |
388 troop_capacity = me->p_ship.s_maxarmies; | |
389 | |
390 if (me->p_flags & PFBEAMUP) | |
391 { | |
392 if (me->p_flags & PFORBIT) | |
393 { | |
394 if (planets[me->p_planet].pl_armies < 1) | |
395 { | |
396 sprintf(buf, "%s: Too few armies to beam up", | |
397 planets[me->p_planet].pl_name); | |
398 warning(buf); | |
399 me->p_flags &= ~PFBEAMUP; | |
400 } | |
401 else if ((planets[me->p_planet].pl_armies <= 4) && | |
402 (me->p_lastman != 2)) | |
403 { | |
404 strcpy(buf, "Hit beam again to beam up all armies."); | |
405 warning(buf); | |
406 me->p_flags &= ~PFBEAMUP; | |
407 } | |
408 else if (me->p_armies == troop_capacity) | |
409 { | |
410 sprintf(buf, "No more room on board for armies"); | |
411 warning(buf); | |
412 me->p_flags &= ~PFBEAMUP; | |
413 } | |
414 else | |
415 { | |
416 sprintf(buf, "Beaming up. (%d/%d)", me->p_armies, troop_capacity); | |
417 imm_warning(buf); | |
418 } | |
419 } | |
420 else if (me->p_flags & PFDOCK) | |
421 { | |
422 if (players[me->p_docked].p_armies == 0) | |
423 { | |
424 sprintf(buf, "Starbase %s: Too few armies to beam up", | |
425 players[me->p_docked].p_name); | |
426 warning(buf); | |
427 me->p_flags &= ~PFBEAMUP; | |
428 } | |
429 else if (me->p_armies >= troop_capacity) | |
430 { | |
431 sprintf(buf, "No more room on board for armies"); | |
432 warning(buf); | |
433 me->p_flags &= ~PFBEAMUP; | |
434 } | |
435 else | |
436 { | |
437 sprintf(buf, "Beaming up. (%d/%d)", me->p_armies, troop_capacity); | |
438 imm_warning(buf); | |
439 } | |
440 } | |
441 } | |
442 if (me->p_flags & PFBEAMDOWN) | |
443 { | |
444 if (me->p_armies == 0) | |
445 { | |
446 if (me->p_flags & PFDOCK) | |
447 { | |
448 sprintf(buf, "No more armies to beam down to Starbase %s.", | |
449 players[me->p_docked].p_name); | |
450 warning(buf); | |
451 } | |
452 else | |
453 { | |
454 sprintf(buf, "No more armies to beam down to %s.", | |
455 planets[me->p_planet].pl_name); | |
456 warning(buf); | |
457 } | |
458 me->p_flags &= ~PFBEAMDOWN; | |
459 } | |
460 else if (me->p_flags & PFORBIT) | |
461 { | |
462 sprintf(buf, "Beaming down. (%d/%d) %s has %d armies left", | |
463 me->p_armies, | |
464 troop_capacity, | |
465 planets[me->p_planet].pl_name, | |
466 planets[me->p_planet].pl_armies); | |
467 imm_warning(buf); | |
468 } | |
469 else if (me->p_flags & PFDOCK) | |
470 { | |
471 if (players[me->p_docked].p_armies == | |
472 players[me->p_docked].p_ship.s_maxarmies) | |
473 { | |
474 sprintf(buf, "Transporter Room: Starbase %s reports all troop bunkers are full!", | |
475 players[me->p_docked].p_name); | |
476 warning(buf); | |
477 me->p_flags &= ~PFBEAMDOWN; | |
478 } | |
479 else | |
480 { | |
481 sprintf(buf, "Transfering ground units. (%d/%d) Starbase %s has %d armies left", | |
482 me->p_armies, | |
483 troop_capacity, | |
484 players[me->p_docked].p_name, | |
485 players[me->p_docked].p_armies); | |
486 imm_warning(buf); | |
487 } | |
488 } | |
489 } | |
490 } | |
491 | |
492 #if 0 | |
493 static void | |
494 reduce_speed() | |
495 { | |
496 if (me->p_desspeed > myship->s_imp.maxspeed) | |
497 { | |
498 /* drop out of warp */ | |
499 me->p_desspeed = myship->s_imp.maxspeed + 1; | |
500 me->p_flags &= ~(PFWARP | PFAFTER); | |
501 warning("Approaching planet, dropping out of warp"); | |
502 } | |
503 set_speed(me->p_desspeed - 1, 0); | |
504 } | |
505 #endif | |
506 | |
507 static void | |
508 decelerate_at_range(dist) | |
509 int dist; | |
510 { | |
511 int speed; | |
512 int maximp = myship->s_imp.maxspeed; | |
513 | |
514 #define FUDGEFACT 1.15 | |
515 | |
516 if (me->p_flags & PFWARP) | |
517 { | |
518 if (configvals->warpdecel) | |
519 { | |
520 /* | |
521 * int impdist = 1000*(maximp*10*WARP1*maximp*10*WARP1)/ (2 * | |
522 * myship->s_imp.dec*10*10*warp1); | |
523 */ | |
524 | |
525 int impdist = FUDGEFACT * (maximp * maximp - 2 * 2) * 500 * WARP1 / myship->s_imp.dec; | |
526 | |
527 for (speed = maximp; | |
528 speed < me->p_desspeed && speed < me->p_speed; | |
529 speed++) | |
530 { | |
531 int decdist; | |
532 decdist = FUDGEFACT * 500 * ((speed * speed) - (maximp * maximp)) * WARP1 / | |
533 myship->s_warp.dec; | |
534 if (dist - impdist - ENTORBDIST < decdist) | |
535 break; | |
536 } | |
537 if (speed == maximp && speed < me->p_speed) | |
538 warning("Approaching planet, dropping out of warp"); | |
539 if (speed < me->p_desspeed && | |
540 speed < me->p_speed) | |
541 { | |
542 /* printf("(W) curr: %d, ideal %d\n", me->p_speed, speed); */ | |
543 me->p_desspeed = speed; | |
544 } | |
545 } | |
546 else | |
547 { | |
548 int impdist; | |
549 maximp = (3 * maximp + myship->s_warp.maxspeed) / 4; | |
550 impdist = FUDGEFACT * ((maximp) * (maximp) - 2 * 2) * | |
551 500 * WARP1 / myship->s_imp.dec; | |
552 if (dist - impdist - ENTORBDIST < 0) | |
553 me->p_flags &= ~PFWARP; | |
554 } | |
555 } | |
556 else | |
557 { | |
558 for (speed = 2; speed < me->p_desspeed && speed < me->p_speed; speed++) | |
559 { | |
560 int decdist; | |
561 decdist = FUDGEFACT * 500 * (speed * speed - 2 * 2) * WARP1 / myship->s_imp.dec; | |
562 if (dist - ENTORBDIST < decdist) | |
563 break; | |
564 } | |
565 if (speed < me->p_desspeed && | |
566 speed < me->p_speed) | |
567 { | |
568 /* printf("(I) curr: %d, ideal %d\n", me->p_speed, speed); */ | |
569 me->p_desspeed = speed; | |
570 } | |
571 } | |
572 } | |
573 | |
574 static void | |
575 follow_player() | |
576 { | |
577 struct player *pl; | |
578 int dist; | |
579 | |
580 if (!(me->p_flags & PFPLOCK)) | |
581 return; | |
582 | |
583 /* set course to player x */ | |
584 | |
585 pl = &players[me->p_playerl]; | |
586 if (pl->p_status != PALIVE) | |
587 me->p_flags &= ~PFPLOCK; | |
588 if (allows_docking(pl->p_ship)) | |
589 { | |
590 dist = ihypot(me->p_x - pl->p_x, me->p_y - pl->p_y); | |
591 | |
592 decelerate_at_range(dist); | |
593 | |
594 if ((dist < DOCKDIST) && (me->p_speed <= 2)) | |
595 { | |
596 orbit(); | |
597 me->p_flags &= ~PFPLOCK; | |
598 } | |
599 } | |
600 if (me->p_flags & PFPLOCK) | |
601 set_course(newcourse(pl->p_x, pl->p_y)); | |
602 | |
603 } | |
604 | |
605 static void | |
606 follow_planet() | |
607 { /* follow a planet? How silly. Will it | |
608 * perhaps outmaneuver you? */ | |
609 struct planet *pln; | |
610 int dist; | |
611 /* int speed = me->p_speed; */ | |
612 | |
613 if (!(me->p_flags & PFPLLOCK)) | |
614 return; | |
615 | |
616 /* set course to planet x */ | |
617 | |
618 pln = &planets[me->p_planet]; | |
619 dist = ihypot(me->p_x - pln->pl_x, me->p_y - pln->pl_y); | |
620 | |
621 decelerate_at_range(dist); | |
622 | |
623 if ((dist < ENTORBDIST) && (me->p_speed <= 2)) | |
624 { | |
625 orbit(); | |
626 me->p_flags &= ~PFPLLOCK; | |
627 } | |
628 else | |
629 { | |
630 int course = newcourse(pln->pl_x, pln->pl_y); | |
631 set_course(course); | |
632 } | |
633 } | |
634 | |
635 /* | |
636 * These are routines that need to be done on interrupts but don't belong in | |
637 * the redraw routine and particularly don't belong in the daemon. | |
638 */ | |
639 | |
640 void | |
641 auto_features() | |
642 { | |
643 selfdestruct_countdown(); | |
644 | |
645 warp_powerup(); | |
646 | |
647 /* provide a refit countdown 4/6/92 TC */ | |
648 refit_countdown(); | |
649 | |
650 /* provide a war declaration countdown 4/6/92 TC */ | |
651 backstab_countdown(); | |
652 | |
653 /* give certain information about bombing or beaming */ | |
654 bombing_info(); | |
655 | |
656 operate_transporters(); | |
657 | |
658 if (me->p_flags & PFREPAIR) | |
659 { | |
660 if ((me->p_damage == 0) && (me->p_shield == me->p_ship.s_maxshield)) | |
661 me->p_flags &= ~PFREPAIR; | |
662 } | |
663 if (me->p_status != POBSERVE) | |
664 { | |
665 /* these mess up the observer mode */ | |
666 follow_player(); | |
667 follow_planet(); | |
668 } | |
669 | |
670 #if defined(CLUECHECK1) || defined(CLUECHECK2) | |
671 if ( | |
672 #ifdef LEAGUE_SUPPORT | |
673 !status2->league && | |
674 #endif | |
675 configvals->cluecheck) | |
676 countdown_clue(); | |
677 #endif | |
678 } | |
679 | |
680 int | |
681 newcourse(x, y) | |
682 int x, y; | |
683 { | |
684 if (x == me->p_x && y == me->p_y) | |
685 return 0; | |
686 | |
687 return (int) (atan2((double) (x - me->p_x), | |
688 (double) (me->p_y - y)) / 3.14159 * 128.); | |
689 } |