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 }