comparison src/snakemove.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
23 #ifdef apollo
24 #include <limits.h>
25 #define MAXINT INT_MAX
26 #else
27 #include <values.h>
28 #endif
29
30 #include <math.h>
31 #include <time.h>
32 #include "defs.h"
33 #include "struct.h"
34 #include "data.h"
35 #include "planets.h"
36 #include "shmem.h"
37
38 #define SYSWIDTH (GWIDTH/5)/* width of a system */
39
40 /* distance on either side of center */
41 #define EYEWIDTH 100 /* 100 */
42 /* which torp the eyes are positioned alongside */
43 #define EYETORP 0 /* 0 */
44 /* angle from EYETORP */
45 #define EYEANGLE 64 /* 64 */
46 #define TORPSEP WARP1*12
47 #define PLANRAD 900
48 #define PLANRATE 16
49
50 /* threshold to avoid galactic boundaries */
51 #define MD 4500
52 /* overlap threshold on team boundaries */
53 #define TMD 2250
54
55 /* how often to check for bombers in cyles (1/10th second) */
56 #define BOMBCHECK 20
57
58 /* how often to check for players in the game in cyles (1/10th second) */
59 #define PLAYERCHECK 100
60
61 #define WARHOSTILE(p) ((((p)->p_swar | (p)->p_hostile)& \
62 perfs[0]->p_team) || ((perfs[0]->p_swar | \
63 perfs[0]->p_hostile) & (p)->p_team))
64
65 #define SNAKETORPDAMAGE 30
66 #define SNAKEPLASMADAMAGE 100
67
68 static struct torp *thead, *eyet, *eyetp;
69 static int lx, ly;
70 static struct plasmatorp *fl, *fr;
71 static int explode, explodetorps, tfuse;
72
73 extern struct player *perfs[2];
74 extern int num_perfs;
75 extern int debug;
76 extern int lastm;
77 extern int tno;
78 extern int target;
79 extern int berserk;
80 extern int patrol;
81 extern int noSmush;
82 extern int plan_guard; /* KAO */
83 extern int planet1, planet2; /* KAO */
84 extern int team1, team2;
85 extern int length;
86
87 static int plan_count = 0;
88 static int s_clock;
89 static _move();
90 static int defenders[ALLTEAM];
91
92 struct player *whokilledme();
93 struct planet *homeworld = 0;
94 struct planet *homestar = 0;
95
96 unsigned char getacourse();
97 extern void (*r_signal()) ();
98
99
100 struct planet *
101 star_of(pl)
102 struct planet *pl;
103 {
104 int i;
105 if (pl->pl_system < 1)
106 return 0;
107
108 for (i = 0; i < NUMPLANETS; i++)
109 {
110 if (!(planets[i].pl_flags & PLSTAR))
111 continue;
112 if (planets[i].pl_system == pl->pl_system)
113 return &planets[i];
114 }
115
116 return 0;
117 }
118
119
120
121 snakemove()
122 {
123 s_clock++;
124
125 _move();
126 }
127
128 static
129 _move()
130 {
131 if (!perfs[0] || !perfs[1])
132 exitSnake();
133
134 /* keep ghostbuster away */
135 perfs[0]->p_ghostbuster = 0;
136 perfs[1]->p_ghostbuster = 0;
137
138 if (s_clock == 5)
139 startsnake();
140 else if (s_clock > 5)
141 {
142 check_explode();
143 if (!explode)
144 {
145 movesnake();
146 }
147 else if ((perfs[0]->p_ntorp == 0 && perfs[1]->p_ntorp == 0 &&
148 perfs[0]->p_nplasmatorp == 0 && perfs[1]->p_nplasmatorp == 0) ||
149 /* xx -- sometimes above doesn't work? */
150 s_clock - explode > 56)
151 exitSnake();
152 }
153 return 1;
154 }
155
156 startsnake()
157 {
158 register i, l;
159 register struct player *j;
160 register struct torp *k;
161 struct player *p1 = perfs[0], *p2 = perfs[1];
162 int first = 1;
163 int px, py;
164
165 for (i = 0; i < NUMPLANETS; i++)
166 {
167 if (planets[i].pl_flags & PLHOME && planets[i].pl_owner == 1 << tno)
168 {
169 homeworld = &planets[i];
170 break;
171 }
172 if (!homeworld && planets[i].pl_owner == 1 << tno)
173 homeworld = &planets[i];
174 }
175
176 if (!homeworld)
177 {
178 /* ouch */
179 homeworld = &planets[lrand48() % NUMPLANETS];
180 fprintf(stderr, "snake: My race (%d) has no planets. Picking one at random: %s\n", tno, homeworld->pl_name);
181 }
182 homestar = star_of(homeworld);
183 if (!homestar)
184 homestar = homeworld;
185
186 px = (lrand48() % 10000) - 5000;
187 py = (lrand48() % 10000) - 5000;
188
189 p1->p_ntorp = p2->p_ntorp = 0;
190 p1->p_nplasmatorp = p2->p_nplasmatorp = 0;
191
192 /* body */
193
194 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
195 {
196
197 for (l = 0, i = j->p_no * MAXTORP, k = &torps[i];
198 i < j->p_no * MAXTORP + length; i++, k++, l++)
199 {
200
201 if (l == EYETORP && j == perfs[0])
202 {
203 /* eye location */
204 eyet = k;
205 }
206 if (l == ((EYETORP == 0) ? 1 : (EYETORP - 1)) && j == perfs[0])
207 {
208 /* perpendicular torp offset */
209 eyetp = k;
210 }
211 /* torps are free here */
212 snake_torp(k, i, j);
213 /* note: have to be same team for this to work */
214 k->t_x = homeworld->pl_x + px;
215 k->t_y = homeworld->pl_y + py - (l + (j == perfs[1] ? length : 0)) * TORPSEP;
216 /*
217 * if(debug) fprintf(stderr, "k->t_x %d, k->t_y %d\n", k->t_x, k->t_y);
218 */
219 if (first)
220 {
221 thead = k;
222 first = 0;
223 }
224 }
225 }
226
227 /* eyes */
228 fl = &plasmatorps[perfs[0]->p_no * MAXPLASMA];
229 fl->pt_no = perfs[0]->p_no * MAXPLASMA;
230 fl->pt_status = PTMOVE;
231 fl->pt_owner = perfs[0]->p_no;
232 fl->pt_team = perfs[0]->p_team;
233 fl->pt_x = eyet->t_x - EYEWIDTH;
234 fl->pt_y = eyet->t_y;
235 if (plan_guard == 0)
236 fl->pt_damage = SNAKEPLASMADAMAGE;
237 else
238 fl->pt_damage = SNAKEPLASMADAMAGE * 10;
239 fl->pt_speed = 0;
240 fl->pt_war = 0;
241 fl->pt_fuse = MAXINT;
242 fl->pt_turns = 0;
243
244 perfs[0]->p_nplasmatorp++;
245
246 fr = &plasmatorps[perfs[1]->p_no * MAXPLASMA];
247 fr->pt_no = perfs[1]->p_no * MAXPLASMA;
248 fr->pt_status = PTMOVE;
249 fr->pt_owner = perfs[1]->p_no;
250 fr->pt_team = perfs[1]->p_team; /* doesn't work */
251 fr->pt_x = eyet->t_x + EYEWIDTH;
252 fr->pt_y = eyet->t_y;
253 fr->pt_damage = SNAKEPLASMADAMAGE;
254 fr->pt_speed = 0;
255 fr->pt_war = 0;
256 fr->pt_fuse = MAXINT;
257 fr->pt_turns = 0;
258
259 perfs[1]->p_nplasmatorp++;
260
261 if (debug)
262 fprintf(stderr, "started\n");
263 }
264
265 restore_eye()
266 {
267 if (fl->pt_status != PTMOVE)
268 {
269 /* eyes */
270 fl = &plasmatorps[perfs[0]->p_no * MAXPLASMA];
271 fl->pt_no = perfs[0]->p_no * MAXPLASMA;
272 fl->pt_status = PTMOVE;
273 fl->pt_owner = perfs[0]->p_no;
274 fl->pt_team = perfs[0]->p_team;
275 fl->pt_x = eyet->t_x - EYEWIDTH;
276 fl->pt_y = eyet->t_y;
277 if (plan_guard == 0)
278 fl->pt_damage = SNAKEPLASMADAMAGE;
279 else
280 fl->pt_damage = SNAKEPLASMADAMAGE * 10;
281 fl->pt_speed = 0;
282 fl->pt_war = 0;
283 fl->pt_fuse = MAXINT;
284 fl->pt_turns = 0;
285 perfs[0]->p_nplasmatorp++;
286 }
287 if (fr->pt_status != PTMOVE)
288 {
289 fr = &plasmatorps[perfs[1]->p_no * MAXPLASMA];
290 fr->pt_no = perfs[1]->p_no * MAXPLASMA;
291 fr->pt_status = PTMOVE;
292 fr->pt_owner = perfs[1]->p_no;
293 fr->pt_team = perfs[1]->p_team; /* doesn't work */
294 fr->pt_x = eyet->t_x + EYEWIDTH;
295 fr->pt_y = eyet->t_y;
296 fr->pt_damage = SNAKEPLASMADAMAGE;
297 fr->pt_speed = 0;
298 fr->pt_war = 0;
299 fr->pt_fuse = MAXINT;
300 fr->pt_turns = 0;
301 perfs[1]->p_nplasmatorp++;
302 }
303 }
304
305 movesnake()
306 {
307 register i, px, py;
308 register struct player *j;
309 register struct torp *k /* , *prev = thead */ ;
310 unsigned char tc;
311 struct player *tr;
312 static
313 int dir = 8;
314 int ok;
315
316 if ((s_clock % PLAYERCHECK) == 0)
317 {
318 /* every x seconds make sure there's people in the game */
319 ok = 0;
320 defenders[FED] = defenders[ROM] = defenders[KLI] = defenders[ORI] = 0;
321 for (i = 0, j = players; i < MAXPLAYER; i++, j++)
322 {
323 if ((j->p_status != PFREE) && !(j->p_flags & PFROBOT))
324 {
325 ok = 1;
326 defenders[j->p_team]++;
327 }
328 }
329 if (!ok)
330 exitSnake();
331 }
332 if (patrol && (target == -1) && (s_clock % BOMBCHECK) == 0)
333 {
334 target = bombcheck(team1, team2);
335 }
336 if ((s_clock % (4 + (lrand48() % 4))) == 0)
337 dir = -dir;
338
339 thead->t_dir += dir + rrnd(8);
340
341 if (target > -1)
342 {
343 tr = &players[target];
344 if (tr->p_status == PALIVE)
345 {
346 int nd, td;
347 tc = getacourse(tr->p_x, tr->p_y, thead->t_x, thead->t_y);
348 nd = angdist(thead->t_dir, tc);
349 if (nd > 8)
350 {
351 td = tc + nd;
352 if (td == thead->t_dir)
353 thead->t_dir -= 8;
354 else
355 thead->t_dir += 8;
356 }
357 }
358 }
359 if (target == -1)
360 {
361 if (!patrol)
362 check_tboundary(ALLTEAM, &thead->t_dir, 8, thead->t_x, thead->t_y);
363 else
364 check_tboundary(team1 | team2, &thead->t_dir, 8, thead->t_x, thead->t_y);
365 }
366 lx = thead->t_x;
367 ly = thead->t_y;
368
369 if (!plan_guard)
370 {
371 /* NOTE: we aren't letting the daemon move the torp head */
372 thead->t_x += (double) TORPSEP *Cos[thead->t_dir];
373 thead->t_y += (double) TORPSEP *Sin[thead->t_dir];
374 }
375 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
376 {
377 if (plan_guard)
378 {
379 int temp;
380 thead = &torps[j->p_no * MAXTORP];
381 if (j == perfs[0])
382 temp = planet1;
383 else
384 temp = planet2;
385 lx = thead->t_x;
386 ly = thead->t_y;
387 thead->t_x = planets[temp].pl_x + Cos[255 - plan_count] * PLANRAD;
388 thead->t_y = planets[temp].pl_y + Sin[255 - plan_count] * PLANRAD;
389 }
390 for (i = j->p_no * MAXTORP, k = &torps[i];
391 i < j->p_no * MAXTORP + length; i++, k++)
392 {
393
394 if (k->t_status == TFREE)
395 /* got exploded. x & y location will remain however */
396 snake_torp(k, i, j);
397
398 if (k == thead)
399 continue;
400
401 px = k->t_x;
402 py = k->t_y;
403
404 k->t_x = lx;
405 k->t_y = ly;
406
407 lx = px;
408 ly = py;
409 }
410 }
411 if (plan_guard)
412 {
413 thead = &torps[perfs[0]->p_no * MAXTORP];
414 plan_count = (plan_count + PLANRATE) % 256;
415 }
416 lx = thead->t_x;
417 ly = thead->t_y;
418 doeyes();
419 }
420
421 check_explode()
422 {
423 register int i, l;
424 register struct player *j;
425 register struct torp *k;
426 static struct player *killer;
427
428 if (fl->pt_status == PTDET || fr->pt_status == PTDET ||
429 fl->pt_status == PTEXPLODE || fr->pt_status == PTEXPLODE || explode)
430 {
431 if (plan_guard)
432 {
433 restore_eye();
434 return;
435 } /* KAO */
436 if (debug)
437 fprintf(stderr, "snake exploding\n");
438 if (!explode)
439 {
440 /* do once */
441 explode = s_clock;
442 tfuse = 0;
443 if (fl->pt_status == PTDET || fl->pt_status == PTEXPLODE)
444 {
445 killer = whokilledme(fl);
446 if (killer)
447 award(killer);
448 }
449 if (fr->pt_status == PTDET || fr->pt_status == PTEXPLODE)
450 {
451 killer = whokilledme(fr);
452 if (killer)
453 award(killer);
454 }
455 }
456 if (fl->pt_status != PTFREE && fl->pt_status != PTEXPLODE)
457 {
458 fl->pt_war = FED | ROM | KLI | ORI; /* make sure its at war when
459 * it explodes */
460 fl->pt_status = PTEXPLODE;
461 fl->pt_fuse = 10;
462 }
463 if (fl->pt_status != PTFREE && fr->pt_status != PTEXPLODE)
464 {
465 fl->pt_war = FED | ROM | KLI | ORI;
466 fr->pt_status = PTEXPLODE;
467 fr->pt_fuse = 10;
468 }
469 /*
470 * now for some fancy stuff. If killer is our target and is hostile or at
471 * war with our team then snake torp head makes a beeline for him. This
472 * lasts until killer dies or torps have been chasing killer for 40
473 * cycles
474 */
475
476 if (killer && WARHOSTILE(killer) && (noSmush < 1) && (killer->p_status == PALIVE) &&
477 tfuse < 40 && (killer->p_no == target || noSmush < 0))
478 {
479 crash_killer(killer);
480 }
481 else
482 {
483 /* explode all torps in sequence, 1 per cycle until all gone */
484 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
485 {
486 for (l = (j == perfs[0]) ? 0 : length, i = j->p_no * MAXTORP, k = &torps[i];
487 i < j->p_no * MAXTORP + length; i++, k++, l++)
488 {
489 if (l == explodetorps && k->t_status != TEXPLODE &&
490 k->t_status != TFREE)
491 {
492 k->t_status = TEXPLODE;
493 k->t_fuse = 10;
494 explodetorps++;
495 return;
496 }
497 else if (l == explodetorps)
498 explodetorps++;
499 }
500 }
501 }
502 }
503 }
504
505 crash_killer(p)
506 struct player *p;
507 {
508 register int i, px, py;
509 register struct player *j;
510 register struct torp *k;
511 unsigned char tc;
512 int active = 0;
513
514 tfuse++;
515
516 tc = getacourse(p->p_x, p->p_y, thead->t_x, thead->t_y);
517 thead->t_dir = tc;
518
519 lx = thead->t_x;
520 ly = thead->t_y;
521
522 thead->t_x += (double) (12 * WARP1) * Cos[thead->t_dir];
523 thead->t_y += (double) (12 * WARP1) * Sin[thead->t_dir];
524
525 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
526 {
527 for (i = j->p_no * MAXTORP, k = &torps[i];
528 i < j->p_no * MAXTORP + length; i++, k++)
529 {
530
531 /* move the head up if it exploded */
532 if (k != thead && thead->t_status == TFREE)
533 thead = k;
534 else if (k == thead)
535 continue;
536
537 if (k->t_status != TFREE)
538 active++;
539
540 px = k->t_x;
541 py = k->t_y;
542
543 k->t_x = lx;
544 k->t_y = ly;
545
546 lx = px;
547 ly = py;
548 }
549 }
550 return active;
551 }
552
553
554 doeyes()
555 {
556 unsigned char c = getacourse(eyetp->t_x, eyetp->t_y, eyet->t_x,
557 eyet->t_y);
558 int ew = EYEWIDTH, war_ok;
559
560 /* c + 64 -- fl c - 64 -- fr */
561
562 if (plan_guard)
563 {
564 fl->pt_x = planets[planet1].pl_x + Cos[255 - plan_count] * PLANRAD;
565 fl->pt_y = planets[planet1].pl_y + Sin[255 - plan_count] * PLANRAD;
566 fr->pt_x = planets[planet2].pl_x + Cos[255 - plan_count] * PLANRAD;
567 fr->pt_y = planets[planet2].pl_y + Sin[255 - plan_count] * PLANRAD;
568 return;
569 }
570 if (fl->pt_war)
571 ew += 15;
572
573 fl->pt_x = eyet->t_x + (double) (ew) * Cos[(unsigned char) (c - EYEANGLE)];
574 fl->pt_y = eyet->t_y + (double) (ew) * Sin[(unsigned char) (c - EYEANGLE)];
575
576 #ifdef nodef
577 if (fl->pt_x < 0)
578 fl->pt_x = 0;
579 else if (fl->pt_x > GWIDTH)
580 fl->pt_x = GWIDTH;
581
582 if (fl->pt_y < 0)
583 fl->pt_y = 0;
584 else if (fl->pt_y > GWIDTH)
585 fl->pt_y = GWIDTH;
586 #endif
587
588 if (fr->pt_war)
589 ew += 15;
590
591 fr->pt_x = eyet->t_x + (double) (ew) * Cos[(unsigned char) (c + EYEANGLE)];
592 fr->pt_y = eyet->t_y + (double) (ew) * Sin[(unsigned char) (c + EYEANGLE)];
593
594 #ifdef nodef
595 if (fr->pt_x < 0)
596 fr->pt_x = 0;
597 else if (fl->pt_x > GWIDTH)
598 fr->pt_x = GWIDTH;
599
600 if (fr->pt_y < 0)
601 fr->pt_y = 0;
602 else if (fl->pt_y > GWIDTH)
603 fr->pt_y = GWIDTH;
604 #endif
605
606 /* toggle war */
607 if ((s_clock % 6) == 0)
608 {
609 /*
610 * your home planet and shipyards are always safe from your own snake
611 * unless you are a target.
612 */
613 war_ok = !sp_area(thead->t_x, thead->t_y);
614
615 if (!fr->pt_war && war_ok)
616 fr->pt_war = (FED | ROM | KLI | ORI) & ~(war_ok ? 0 : (1 << tno));
617 else
618 fr->pt_war = 0;
619
620 if (!fl->pt_war && war_ok)
621 fl->pt_war = (FED | ROM | KLI | ORI) & ~(war_ok ? 0 : (1 << tno));
622 else
623 fl->pt_war = 0;
624 }
625 }
626
627 exitSnake(sig)
628 int sig;
629 {
630 register int i;
631 register struct player *j;
632 register struct torp *k;
633 register struct plasmatorp *f;
634
635 r_signal(SIGALRM, SIG_DFL);
636
637 if (debug)
638 fprintf(stderr, "snake exiting\n");
639
640 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
641 {
642 for (i = j->p_no * MAXTORP, k = &torps[i];
643 i < j->p_no * MAXTORP + length; i++, k++)
644 {
645 /* torps are free here */
646 if (k->t_status != TFREE)
647 k->t_status = TOFF;
648 }
649 f = &plasmatorps[j->p_no * MAXPLASMA];
650 f->pt_status = PTFREE;
651 /* plasma */
652 }
653
654 memset(perfs[0], 0, sizeof(struct player));
655 memset(perfs[1], 0, sizeof(struct player));
656 perfs[0]->p_stats.st_tticks = 1;
657 perfs[1]->p_stats.st_tticks = 1;
658
659 /*
660 * note: if we had a segmentation violation or bus error we want a core
661 * file to debug
662 */
663 if (sig == SIGBUS || sig == SIGSEGV)
664 abort();
665 else
666 exit(0);
667 }
668
669 pmessage(str, recip, group, address)
670 char *str;
671 int recip;
672 int group;
673 char *address;
674 {
675 pmessage2(str, recip, group, address, 255);
676 }
677
678 pmessage2(str, recip, group, address, from)
679 char *str;
680 int recip;
681 int group;
682 char *address;
683 unsigned char from;
684 {
685 struct message *cur;
686 int mesgnum;
687
688 if ((mesgnum = ++(mctl->mc_current)) >= MAXMESSAGE)
689 {
690 mctl->mc_current = 0;
691 mesgnum = 0;
692 }
693 cur = &messages[mesgnum];
694 cur->m_no = mesgnum;
695 cur->m_flags = group;
696 cur->m_recpt = recip;
697 cur->m_from = from;
698 (void) sprintf(cur->m_data, "%-9s %s", address, str);
699 cur->m_flags |= MVALID;
700 }
701
702 /* get course from (mx,my) to (x,y) */
703 unsigned char
704 getacourse(x, y, mx, my)
705 int x, y, mx, my;
706 {
707 if (x == mx && y == my)
708 return 0;
709
710 return (unsigned char) (int) (atan2((double) (x - mx),
711 (double) (my - y)) / 3.14159 * 128.);
712 }
713
714 /*
715 * FED 1 ROM 2 KLI 4 ORI 8
716 */
717
718 /*
719 * 256/0 192 + 64 128 */
720
721 check_tboundary(teams, mycrs, range, x, y)
722 int teams;
723 int x, y;
724 unsigned char *mycrs;
725 int range;
726 {
727 int lx = homestar->pl_x - SYSWIDTH / 2, rx = homestar->pl_x + SYSWIDTH / 2,
728 ty = homestar->pl_y - SYSWIDTH / 2, by = homestar->pl_y + SYSWIDTH / 2;
729 int r = 0, l = 0;
730 unsigned char crs = *mycrs;
731
732 if (x < lx && crs >= 128)
733 {
734 if (crs >= 192)
735 *mycrs += range;
736 else
737 *mycrs -= range;
738 l = 1;
739 }
740 else if (x > rx && crs < 128)
741 {
742 if (crs > 64)
743 *mycrs += range;
744 else
745 *mycrs -= range;
746 r = 1;
747 }
748 if (y < ty && (crs >= 192 || crs < 64))
749 {
750 if (crs >= 192 && !l)
751 *mycrs -= range;
752 else
753 *mycrs += range;
754 }
755 else if (y > by && (crs < 192 && crs >= 64))
756 {
757 if (crs < 128 && !r)
758 *mycrs -= range;
759 else
760 *mycrs += range;
761 }
762 }
763
764 /* return rnd between -range & range */
765 rrnd(range)
766 int range;
767 {
768 return lrand48() % (2 * range) - range;
769 }
770
771 #ifdef nodef
772 /* NOTUSED */
773 contrast(t)
774 int t;
775 {
776 return ROM; /* experiment */
777 switch (t)
778 {
779 case FED:
780 return ORI;
781 case ORI:
782 return FED;
783 case KLI:
784 return ROM;
785 case ROM:
786 return KLI;
787 default:
788 return FED;
789 }
790 }
791
792 #endif
793
794 snake_torp(t, n, p)
795 struct torp *t;
796 int n;
797 struct player *p;
798 {
799 t->t_no = n;
800 t->t_status = TMOVE;
801 t->t_owner = p->p_no;
802 t->t_team = p->p_team;
803 t->t_dir = 128;
804 if (plan_guard == 0)
805 t->t_damage = SNAKETORPDAMAGE;
806 else
807 t->t_damage = SNAKETORPDAMAGE * 10;
808 t->t_speed = 0;
809 if (berserk)
810 t->t_war = FED | ROM | ORI | KLI;
811 else if (target == -1)
812 t->t_war = 0;
813 else
814 t->t_war = perfs[0]->p_swar | perfs[0]->p_hostile;
815 t->t_fuse = MAXINT;
816 t->t_turns = 0;
817 p->p_ntorp++;
818 }
819
820 struct player *
821 whokilledme(pt)
822 struct plasmatorp *pt;
823 {
824 register i;
825 register struct phaser *j;
826
827 for (i = 0, j = &phasers[i]; i < MAXPLAYER; i++, j++)
828 {
829 if (j->ph_status == PHHIT2)
830 {
831 if (debug)
832 {
833 fprintf(stderr, "found PHHIT2 from %d at %d,%d\n", players[i].p_no,
834 j->ph_x, j->ph_y);
835 fprintf(stderr, "plasma is at %d,%d\n", pt->pt_x, pt->pt_y);
836 fprintf(stderr, "fl is at %d,%d\n", fl->pt_x, fl->pt_y);
837 fprintf(stderr, "fr is at %d,%d\n", fr->pt_x, fr->pt_y);
838 }
839 if (j->ph_x == pt->pt_x && j->ph_y == pt->pt_y)
840 {
841 return &players[i];
842 }
843 }
844 }
845 return NULL;
846 }
847
848 /*
849 * NOTE: the procedure could be writing shared memory variables at the same
850 * time as the daemon. This may produce unpredicatable results. A better
851 * implementation would mark the "snake plasma" and have the daemon do the
852 * awarding.
853 */
854
855 award(win)
856 struct player *win;
857 {
858 char buf[80];
859 char addrbuf[10];
860
861 if (!win)
862 return;
863
864 if (target == -1 && !(win->p_flags & PFROBOT) && !WARHOSTILE(win))
865 {
866 strcpy(buf, "Snake eyes!");
867
868 /* what do we have for our big winner today, fred? */
869
870 if (((100 * win->p_damage) / win->p_ship.s_maxdamage) > 50 ||
871 ((100 * win->p_shield) / win->p_ship.s_maxshield) < 50)
872 {
873 win->p_damage = 0;
874 win->p_shield = win->p_ship.s_maxshield;
875 strcat(buf, " You win free repairs!");
876 }
877 else if (((100 * win->p_fuel) / win->p_ship.s_maxfuel) < 50)
878 {
879 win->p_fuel = win->p_ship.s_maxfuel;
880 strcat(buf, " You win free fuel!");
881 }
882 else if (((100 * win->p_etemp) / win->p_ship.s_maxegntemp) > 60)
883 {
884 win->p_etemp = 0;
885 strcat(buf, " You win free engine cooling!");
886 }
887 else if (((100 * win->p_wtemp) / win->p_ship.s_maxwpntemp) > 60)
888 {
889 win->p_wtemp = 0;
890 strcat(buf, " You win free weapons cooling!");
891 }
892 else
893 {
894 win->p_damage = 0;
895 win->p_shield = win->p_ship.s_maxshield;
896 win->p_fuel = win->p_ship.s_maxfuel;
897 win->p_etemp = 0;
898 win->p_wtemp = 0;
899 strcat(buf, " You feel healthy!");
900 }
901
902 /* ... */
903
904 sprintf(addrbuf, "%s->%c%c", SERVNAME,
905 teams[win->p_team].letter, shipnos[win->p_no]);
906 pmessage2(buf, win->p_no, MINDIV, addrbuf, 255);
907 }
908 sprintf(buf, "%s (%c%c) slew the vile space serpent!",
909 win->p_name, teams[win->p_team].letter, shipnos[win->p_no]);
910 pmessage(buf, 0, MALL | MKILLA, MSERVA, 255);
911
912 /* and get .5 kills */
913
914 win->p_kills += 0.5;
915 if (win->p_ship.s_type == STARBASE)
916 {
917 if (win->p_stats.st_sbmaxkills < win->p_kills)
918 {
919 win->p_stats.st_sbmaxkills = win->p_kills;
920 }
921 }
922 else if (win->p_stats.st_tmaxkills < win->p_kills)
923 {
924 win->p_stats.st_tmaxkills = win->p_kills;
925 }
926 }
927
928 bombcheck(team1, team2)
929 int team1, team2;
930 {
931 register i;
932 register struct player *j;
933 struct planet *p;
934
935 for (i = 0, j = players; i < MAXPLAYER; i++, j++)
936 {
937 if (j->p_status == PALIVE)
938 {
939 if ((j->p_flags & PFBOMB) && (j->p_flags & PFORBIT))
940 {
941 p = &planets[j->p_planet];
942 if (!((j->p_swar | j->p_hostile) & p->pl_owner))
943 continue;
944
945 if (defenders[p->pl_owner] >= configvals->tournplayers)
946 continue;
947
948 #if 0
949 /* ignore planets that aren't within team boundaries */
950 if (p->pl_x > boundaries[p->pl_owner].rx ||
951 p->pl_x < boundaries[p->pl_owner].lx ||
952 p->pl_y > boundaries[p->pl_owner].by ||
953 p->pl_y < boundaries[p->pl_owner].ty)
954 continue;
955 #endif
956
957 if (!team1 && !team2)
958 {
959 /* any planet */
960 printf("snake found bomber: targeting %c%c\n",
961 teams[j->p_team].letter, shipnos[j->p_no]);
962 fflush(stdout);
963 make_war(j, p->pl_owner);
964 return j->p_no;
965 }
966 else
967 {
968 if (team1)
969 {
970 if (p->pl_owner == team1)
971 {
972 printf("found bomber: targeting %c%c\n",
973 teams[j->p_team].letter, shipnos[j->p_no]);
974 fflush(stdout);
975 make_war(j, p->pl_owner);
976 return j->p_no;
977 }
978 }
979 if (team2)
980 {
981 if (p->pl_owner == team2)
982 {
983 printf("found bomber: targeting %c%c\n",
984 teams[j->p_team].letter, shipnos[j->p_no]);
985 fflush(stdout);
986 make_war(j, p->pl_owner);
987 return j->p_no;
988 }
989 }
990 }
991 }
992 }
993 }
994 return -1;
995 }
996
997 make_war(p, plteam)
998 struct player *p;
999 int plteam;
1000 {
1001 register int i;
1002 register struct player *j;
1003 register struct torp *k;
1004
1005 perfs[0]->p_team = plteam;
1006 perfs[0]->p_swar = 0;
1007 perfs[0]->p_hostile = 0;
1008 perfs[1]->p_team = plteam;
1009 perfs[1]->p_swar = 0;
1010 perfs[1]->p_hostile = 0;
1011
1012 perfs[0]->p_swar |= p->p_team;
1013 perfs[0]->p_hostile |= p->p_team;
1014 perfs[1]->p_swar |= p->p_team;
1015 perfs[1]->p_hostile |= p->p_team;
1016
1017 /* update our torps war status */
1018 for (j = perfs[0]; j; j = (j == perfs[1] ? NULL : perfs[1]))
1019 {
1020 for (i = j->p_no * MAXTORP, k = &torps[i];
1021 i < j->p_no * MAXTORP + length; i++, k++)
1022 {
1023
1024 k->t_war = perfs[0]->p_swar | perfs[0]->p_hostile;
1025 }
1026 }
1027 }
1028
1029
1030
1031 /*
1032 * start planet areas are places where people will likely enter the game
1033 * (only considers 1 start planet at this time)
1034 */
1035
1036 sp_area(x, y)
1037 int x, y;
1038 {
1039 register i, j, px, py;
1040
1041 #if 0
1042 /* check for proximity to a shipyard? */
1043 return 0;
1044 #else
1045
1046 for (i = 0; i < NUMPLANETS; i++)
1047 {
1048 struct planet *pl = &planets[i];
1049 if (!(pl->pl_flags & (PLSHIPYARD | PLHOME)))
1050 continue;
1051 px = pl->pl_x;
1052 py = pl->pl_y;
1053 /* printf("checking %s (%d,%d)\n", pl->pl_name, i*10,j); */
1054
1055 if (!(x < px - 5300 || x > px + 5300 ||
1056 y < py - 5300 || y > py + 5300))
1057 {
1058 #ifdef maybe /* not used. */
1059 if (target != -1)
1060 {
1061 struct player *p = &players[target];
1062 /*
1063 * if target is also in same home area, he should at least be able to
1064 * phaser the snake since the torps are already deadly
1065 */
1066 if (!(p->p_x < px - 5300 || p->p_x > px + 5300 ||
1067 p->p_y < py - 5300 || p->p_y > py + 5300))
1068 return 0;
1069 else
1070 return 1;
1071 }
1072 #endif
1073 return 1;
1074 }
1075 }
1076
1077 return 0;
1078
1079 #endif
1080 }