comparison src/rmove.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 <math.h>
23 #include "defs.h"
24 #include "struct.h"
25 #include "data.h"
26 #include "weapons.h"
27 #include "shmem.h"
28
29 #define SIZEOF(s) (sizeof (s) / sizeof (*(s)))
30 #define AVOID_TIME 4
31 #define AVOID_CLICKS 200
32
33 #define BOREDOM_TIME 1200 /* 10 minutes since last torp fired
34 * => become hostile to all 4/13/92
35 * TC */
36
37 #define AVOID_STAR 8000 /* Distance from star within which collision
38 * avoidance is invoked. - MAK, 16-Jun-93 */
39 #define AVOID_MELT 2000 /* Distance from star within which collision
40 * prevention is invoked. - MAK, 16-Jun-93 */
41
42 #define NORMALIZE(d) (((d) + 256) % 256)
43
44 #define E_INTRUDER 0x01
45 #define E_TSHOT 0x02
46 #define E_PSHOT 0x04
47 #define E_TRACT 0x08
48 #define NOENEMY (struct Enemy *) -1
49
50 struct Enemy
51 {
52 int e_info;
53 int e_dist;
54 unsigned char e_course; /* course to enemy */
55 unsigned char e_edir; /* enemy's current heading */
56 unsigned char e_tcourse; /* torpedo intercept course to enemy */
57 unsigned int e_flags;
58 int e_tractor; /* who he's tractoring/pressoring */
59 int e_phrange; /* his phaser range */
60 unsigned int e_hisflags; /* his pflags. bug fix: 6/24/92 TC */
61 };
62
63 static int avoidTime;
64
65 #define MESSFUSEVAL 200 /* maint: removed trailing ';' 6/22/92 TC */
66 static int messfuse = MESSFUSEVAL;
67 static char rmessage[110];
68 static char tmessage[110];
69 static char *rmessages[] = {
70 /* I got bored and actually made it say something: 'DIE SCUM' */
71 "1000100 1001001 1000101 100000 1010011 1000011 1010101 1001101 !"
72 "Crush, Kill, DESTROY!!",
73 "Run coward!",
74 "Hey! Come on you Hoser! I dare you!",
75 "Resistance is useless!",
76 "Dry up and blow away you weenie!",
77 "Go ahead, MAKE MY DAY!",
78 "Just hit '<shift> Q' ... and spare both of us the trouble",
79 "Is that REALLY you Kurt?",
80 "I have you now!",
81 "By the way, any last requests?",
82 "Dropping your shields is considered a peaceful act.",
83 "Drop your shields, and I MAY let you live ...",
84 "Don't you have midterms coming up or something?",
85 "Ya wanna Tango baby?",
86 "Hey! Outta my turf you filthy $t!",
87 "I seeeee you...",
88 "I claim this space for the $f.",
89 "Give up fool ... you're meat.",
90 "And another one bites the dust ...",
91 "Surrender ... NOW!",
92 "Hey! Have you heard about the clever $t? No?.. Me neither.",
93 "You have been registered for termination.",
94 "This'll teach you to mind your own business!",
95 "Man, you stupid $ts never learn!",
96 "ALL RIGHT, enough goofing off ... you're toast buster!",
97 "You pesky humans just NEVER give up, do you?",
98 "You're actually paying money so you can play this game?",
99 "My job is to put over-zealous newbies like you out of your misery.",
100 "How can you stand to be $T?!? What a hideous life!",
101 "All $ts are losers!",
102 "$ts all suck. Come join the $f!",
103 "The $f shall crush all filthy $ts like you!",
104 "TWINK",
105 "How can your friends stand to let you live?",
106 "Happy, Happy, Joy, Joy."
107 };
108
109 char *termie_messages[] = {
110 "$n: Hasta la vista, Baby.",
111 "Come quietly, or there will be trouble. [thump] [thump]",
112 "Make your peace with GOD.",
113 "$n: Say your prayers",
114 "This galaxy isn't big enough for the two of us, $n.",
115 "$n, I have a warrant for your arrest.",
116 "$n, self-destruct now.",
117 "Coming through. Out of my way.",
118 "You feel lucky, punk?",
119 "Killing is our business. Business is good.",
120 "$n, Die. You have 10 seconds to comply.",
121 "You can run $n, but you can't hide!",
122 "Sorry, I am out of cool quotes. Just die.",
123 "$n: duck."
124 };
125
126 extern int debug;
127 extern int hostile;
128 extern int sticky;
129 extern int practice;
130 extern int polymorphic;
131
132 extern int startplanet; /* CRD feature - MAK, 2-Jun-93 */
133
134 extern int target; /* robotII.c 7/27/91 TC */
135 extern int phrange; /* robotII.c 7/31/91 TC */
136 extern int trrange; /* robotII.c 8/2/91 TC */
137
138 extern int dogslow; /* robotII.c 8/9/91 TC */
139 extern int dogfast;
140 extern int runslow;
141 extern int runfast;
142 extern int closeslow;
143 extern int closefast;
144
145 unsigned char getcourse();
146 char *robo_message();
147 char *termie_message(); /* added 8/2/91 TC */
148
149
150 extern void (*r_signal()) ();
151 #ifndef IRIX
152 extern int fprintf();
153 #endif
154 extern unsigned int sleep();
155 void exitRobot();
156 extern void move_player();
157 void messAll();
158 int phaser_plasmas();
159 void pmessage2();
160 int do_repair();
161 void go_home();
162 extern int ntorp();
163 extern int repair_off();
164 extern int cloak_off();
165 extern int phaser();
166 extern int angdist();
167 int isTractoringMe();
168 extern int pressor_player();
169 extern int tractor_player();
170 int projectDamage();
171 extern int set_course();
172 extern int cloak_on();
173 extern int shield_up();
174 extern void detothers();
175 extern int shield_down();
176 extern int set_speed();
177 extern int lock_planet();
178 extern int orbit();
179 extern int repair();
180 #ifdef ROBOTSTATS
181 extern void save_robot();
182 #endif
183
184 void
185 rmove()
186 {
187 register struct player *j;
188 register struct planet *l;
189 register int i;
190 register int burst;
191 register int numHits, tDir;
192 int avDir;
193 extern struct Enemy *get_nearest();
194 struct Enemy *enemy_buf;
195 struct player *enemy;
196 static int clock = 0;
197 static int avoid[2] = {-32, 32};
198 int no_cloak;
199 char towhom[80];
200 int timer;
201 static int lastTorpped = 0; /* when we last fired a torp 4/13/92 TC */
202
203 clock++;
204 /* Check that I'm alive */
205 if (me->p_status == PEXPLODE)
206 {
207 r_signal(SIGALRM, SIG_IGN);
208 if (debug)
209 fprintf(stderr, "Robot: Augh! exploding.\n");
210
211
212 /* hack: get rid of robot processes! */
213
214 if (1)
215 {
216 sleep(3);
217 }
218 else
219 {
220 while (me->p_status == PEXPLODE);
221 }
222 if (debug)
223 fprintf(stderr, "Robot: done exploding.\n");
224 if (1)
225 {
226 sleep(3);
227 }
228 else
229 {
230 while (me->p_ntorp > 0);
231 }
232 if (debug)
233 fprintf(stderr, "Robot: torps are gone.\n");
234 exitRobot();
235 }
236 if (me->p_status == PDEAD)
237 {
238 r_signal(SIGALRM, SIG_IGN);
239 /*
240 * me->p_status = PFREE; move_player(me->p_no, -1,-1, 1); exit(0);
241 */
242 exitRobot();
243 }
244 /* keep ghostbuster away */
245 me->p_ghostbuster = 0;
246
247 timer = 0;
248 for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++)
249 {
250 if ((j->p_status != PFREE) && !(j->p_flags & PFROBOT))
251 timer = 1;
252 }
253 if (!timer && !sticky)
254 {
255 r_signal(SIGALRM, SIG_IGN);
256 me->p_status = PFREE;
257 move_player(me->p_no, -1, -1, 1);
258 exit(0);
259 }
260 /* if I'm a Terminator, quit if he quits, and quit if he dies and */
261 /* I'm not "sticky" (-s) */
262
263 if (target >= 0)
264 {
265 if (players[target].p_status == PFREE)
266 { /* he went away */
267 me->p_status = PEXPLODE;
268 return;
269 }
270 if ((!sticky) && (players[target].p_status != PALIVE))
271 { /* he died */
272 me->p_status = PEXPLODE;
273 return;
274 }
275 }
276 /*
277 * If it's been BOREDOM_TIME updates since we fired a torp, become hostile
278 * to all races, if we aren't already, and if we're not a practice robot
279 * (intended for guardian bots). 4/13/92 TC
280 */
281
282 if ((clock - lastTorpped > BOREDOM_TIME) && (!practice) && (!hostile) &&
283 (me->p_team != 0))
284 {
285 messAll("Bored, Bored, Bored.");
286 hostile++;
287 declare_war(ALLTEAM);
288 }
289 /* Our first priority is to phaser plasma torps in nearby vicinity... */
290 /* If we fire, we aren't allowed to cloak... */
291 no_cloak = phaser_plasmas();
292
293 /* Find an enemy */
294
295 enemy_buf = get_nearest();
296
297 if ((enemy_buf != NULL) && (enemy_buf != NOENEMY))
298 { /* Someone to kill */
299 enemy = &players[enemy_buf->e_info];
300 if (((lrand48() % messfuse) == 0) &&
301 (ihypot(me->p_x - enemy->p_x, me->p_y - enemy->p_y) < 20000))
302 {
303 /* change 5/10/21 TC ...neut robots don't message */
304 messfuse = MESSFUSEVAL;
305 if (me->p_team != 0)
306 {
307 sprintf(towhom, " %s->%s",
308 twoletters(&players[me->p_no]),
309 twoletters(&players[enemy->p_no]));
310 pmessage2(robo_message(enemy), enemy->p_no,
311 MINDIV, towhom, me->p_no);
312 }
313 else if (target >= 0)
314 {
315 /*
316 * MAK, 28-Apr-92 - send termie messages only to target
317 * messAll(termie_message(enemy));
318 */
319 sprintf(towhom, " %s->%s",
320 twoletters(&players[me->p_no]),
321 twoletters(&players[enemy->p_no]));
322 pmessage2(termie_message(enemy), enemy->p_no,
323 MINDIV, towhom, me->p_no);
324 }
325 }
326 else if (--messfuse == 0)
327 messfuse = 1;
328 timer = 0;
329 if (debug)
330 fprintf(stderr, "%d) noticed %d\n", me->p_no, enemy_buf->e_info);
331 }
332 else if (enemy_buf == NOENEMY)
333 { /* no more players. wait 1 minute. */
334 if (do_repair())
335 {
336 return;
337 }
338 go_home(0);
339 /*
340 * if (debug) fprintf(stderr, "%d) No players in game.\n", me->p_no);
341 */
342 return;
343 }
344 else if (enemy_buf == 0)
345 { /* no one hostile */
346 /*
347 * if (debug) fprintf(stderr, "%d) No hostile players in game.\n",
348 * me->p_no);
349 */
350 if (do_repair())
351 {
352 return;
353 }
354 go_home(0);
355 timer = 0;
356 return;
357 }
358 /*
359 * Note a bug in this algorithm: * Once someone dies, he is forgotten.
360 * This makes robots particularly easy * to kill on a suicide run, where
361 * you aim to where you think he will turn * as you die. Once dead, the
362 * robot will ignore you and all of your * active torpedoes!
363 */
364
365 /*
366 * Algorithm: * We have an enemy. * First priority: shoot at target in
367 * range. * Second: Dodge stars, torps, and plasma torps. * Third: Get away
368 * if we are damaged. * Fourth: repair. * Fifth: attack.
369 */
370
371 /*
372 * * If we are a practice robot, we will do all but the second. One * will
373 * be modified to shoot poorly and not use phasers.
374 */
375 /* Fire weapons!!! */
376 /*
377 * get_nearest() has already determined if torpedoes and phasers * will
378 * hit. It has also determined the courses which torps and * phasers
379 * should be fired. If so we will go ahead and shoot here. * We will lose
380 * repair and cloaking for the rest of this interrupt. * if we fire here.
381 */
382
383 if (practice)
384 {
385 no_cloak = 1;
386 if (enemy_buf->e_flags & E_TSHOT)
387 {
388 /*
389 * if (debug) fprintf(stderr, "%d) firing torps\n", me->p_no);
390 */
391 for (burst = 0; (burst < 3) && (me->p_ntorp < MAXTORP); burst++)
392 {
393 ntorp(enemy_buf->e_tcourse, TMOVE);
394 }
395 }
396 }
397 else
398 {
399 if (enemy_buf->e_flags & E_TSHOT)
400 {
401 /*
402 * if (debug) fprintf(stderr, "%d) firing torps\n", me->p_no);
403 */
404 for (burst = 0; (burst < 2) && (me->p_ntorp < MAXTORP); burst++)
405 {
406 repair_off();
407 cloak_off();
408 ntorp(enemy_buf->e_tcourse, TMOVE); /* was TSTRAIGHT 8/9/91 TC */
409 no_cloak++;
410 lastTorpped = clock; /* record time of firing 4/13/92 TC */
411 }
412 }
413 if (enemy_buf->e_flags & E_PSHOT)
414 {
415 /*
416 * if (debug) fprintf(stderr, "%d) phaser firing\n", me->p_no);
417 */
418 no_cloak++;
419 repair_off();
420 cloak_off();
421 phaser(enemy_buf->e_course);
422 }
423 }
424
425 /* auto pressor 7/27/91 TC */
426 /* tractor/pressor rewritten on 5/1/92... glitches galore :-| TC */
427
428 /*
429 * whoa, too close for comfort, or he's tractoring me, or headed in for me,
430 * or I'm hurt
431 */
432
433 /* a little tuning -- 0.8 on phrange and +/- 90 degrees in for pressor */
434
435 /*
436 * pressor_player(-1); this didn't do anything before, so we'll let the
437 * pressors disengage by themselves 5/1/92 TC
438 */
439 if (enemy_buf->e_flags & E_TRACT)
440 { /* if pressorable */
441 if (((enemy_buf->e_dist < 0.8 * enemy_buf->e_phrange) &&
442 (angdist(enemy_buf->e_edir, enemy_buf->e_course) > 64)) ||
443 (isTractoringMe(enemy_buf)) ||
444 (me->p_damage > 0))
445 {
446 if (!(enemy->p_flags & PFCLOAK))
447 {
448 if (debug)
449 fprintf(stderr, "%d) pressoring %d\n", me->p_no,
450 enemy_buf->e_info);
451 pressor_player(enemy->p_no);
452 no_cloak++;
453 repair_off();
454 cloak_off();
455 }
456 }
457 }
458 /* auto tractor 7/31/91 TC */
459
460 /* tractor if not pressoring and... */
461
462 /* tractor if: in range, not too close, and not headed +/- 90 degrees */
463 /* of me, and I'm not hurt */
464
465 if ((!(me->p_flags & PFPRESS)) &&
466 (enemy_buf->e_flags & E_TRACT) &&
467 (angdist(enemy_buf->e_edir, enemy_buf->e_course) < 64) &&
468 (enemy_buf->e_dist > 0.7 * enemy_buf->e_phrange))
469 {
470 if (!(me->p_flags & PFTRACT))
471 {
472 if (debug)
473 fprintf(stderr, "%d) tractoring %d\n", me->p_no,
474 enemy_buf->e_info);
475 tractor_player(enemy->p_no);
476 no_cloak++;
477 }
478 }
479 else
480 tractor_player(-1); /* otherwise don't tractor */
481
482 /* Avoid stars - MAK, 16-Jun-93 */
483 /*
484 * This section of code allows robots to avoid crashing into stars. Within
485 * a specific range (AVOID_STAR), they will check to see if their current
486 * course will take them close to the star. If so, course will be adjusted
487 * to avoid the star. Within a smaller range (AVOID_MELT), course is
488 * adjusted directly away from the star. Collision avoidance is all they
489 * will do for this round, other than shooting.
490 */
491 for (i = 0, l = &planets[0]; i < NUMPLANETS; i++, l++)
492 {
493 if (PL_TYPE(*l) == PLSTAR)
494 {
495 int dx, dy, stardir, newcourse = -1;
496 dx = ABS(l->pl_x - me->p_x);
497 dy = ABS(l->pl_y - me->p_y);
498 /* Avoid over box rather than circle to speed calculations */
499 if (dx < AVOID_STAR && dy < AVOID_STAR)
500 {
501 stardir = getcourse(l->pl_x, l->pl_y);
502
503 if (dx < AVOID_MELT && dy < AVOID_MELT)
504 {
505 /* Emergency! Way too close! */
506 newcourse = NORMALIZE(stardir - 128);
507 if (debug)
508 {
509 fprintf(stderr, "Steering away from star %s, dir = %d\n",
510 l->pl_name, newcourse);
511 }
512 }
513 else if (angdist(me->p_dir, stardir) < 16)
514 {
515 /* Heading towards star, so adjust course. */
516 newcourse =
517 NORMALIZE((me->p_dir < stardir) ? stardir - 32 : stardir + 32);
518 if (debug)
519 {
520 fprintf(stderr, "Adjusting course away from star %s, dir = %d\n",
521 l->pl_name, newcourse);
522 }
523 }
524 if (newcourse != -1)
525 { /* Change course and speed */
526 me->p_desdir = newcourse;
527 if (angdist(me->p_desdir, me->p_dir) > 64)
528 me->p_desspeed = dogslow;
529 else
530 me->p_desspeed = dogfast;
531 return;
532 }
533 }
534 }
535 }
536
537 /* Avoid torps */
538 /*
539 * This section of code allows robots to avoid torps. * Within a specific
540 * range they will check to see if * any of the 'closest' enemies torps
541 * will hit them. * If so, they will evade for four updates. * Evading is
542 * all they will do for this round, other than shooting.
543 */
544
545 if (!practice)
546 {
547 if ((enemy->p_ntorp < 5))
548 {
549 if ((enemy_buf->e_dist < 15000) || (avoidTime > 0))
550 {
551 numHits = projectDamage(enemy->p_no, &avDir);
552 if (debug)
553 {
554 /*
555 * fprintf(stderr, "%d hits expected from %d from dir = %d\n",
556 * numHits, enemy->p_no, avDir);
557 */
558 }
559 if (numHits == 0)
560 {
561 if (--avoidTime > 0)
562 { /* we may still be avoiding */
563 if (angdist(me->p_desdir, me->p_dir) > 64)
564 me->p_desspeed = dogslow;
565 else
566 me->p_desspeed = dogfast;
567 return;
568 }
569 }
570 else
571 {
572 /* Actually avoid Torps */
573 avoidTime = AVOID_TIME;
574 tDir = avDir - me->p_dir;
575 /* put into 0->255 range */
576 tDir = NORMALIZE(tDir);
577 if (debug)
578 fprintf(stderr, "mydir = %d avDir = %d tDir = %d q = %d\n",
579 me->p_dir, avDir, tDir, tDir / 64);
580 switch (tDir / 64)
581 {
582 case 0:
583 case 1:
584 set_course(NORMALIZE(avDir + 64));
585 break;
586 case 2:
587 case 3:
588 set_course(NORMALIZE(avDir - 64));
589 break;
590 }
591 if (!no_cloak)
592 cloak_on();
593
594 if (angdist(me->p_desdir, me->p_dir) > 64)
595 me->p_desspeed = dogslow;
596 else
597 me->p_desspeed = dogfast;
598
599 shield_up();
600 detothers(); /* hmm */
601 if (debug)
602 fprintf(stderr, "evading to dir = %d\n", me->p_desdir);
603 return;
604 }
605 }
606 }
607 /*
608 * Trying another scheme. * Robot will keep track of the number of torps
609 * a player has * launched. If they are greater than say four, the robot
610 * will * veer off immediately. Seems more humanlike to me.
611 */
612
613 else if (enemy_buf->e_dist < 15000)
614 {
615 if (--avoidTime > 0)
616 { /* we may still be avoiding */
617 if (angdist(me->p_desdir, me->p_dir) > 64)
618 me->p_desspeed = dogslow;
619 else
620 me->p_desspeed = dogfast;
621 return;
622 }
623 if (lrand48() % 2)
624 {
625 me->p_desdir = NORMALIZE(enemy_buf->e_course - 64);
626 avoidTime = AVOID_TIME;
627 }
628 else
629 {
630 me->p_desdir = NORMALIZE(enemy_buf->e_course + 64);
631 avoidTime = AVOID_TIME;
632 }
633 if (angdist(me->p_desdir, me->p_dir) > 64)
634 me->p_desspeed = dogslow;
635 else
636 me->p_desspeed = dogfast;
637 shield_up();
638 return;
639 }
640 }
641 /* Run away */
642 /*
643 * The robot has taken damage. He will now attempt to run away from * the
644 * closest player. This obviously won't do him any good if there * is
645 * another player in the direction he wants to go. * Note that the robot
646 * will not run away if he dodged torps, above. * The robot will lower his
647 * shields in hopes of repairing some damage.
648 */
649
650 #define STARTDELTA 5000 /* ships appear +/- delta of home planet */
651
652 if (me->p_damage > 0 && enemy_buf->e_dist < 13000)
653 {
654 if (me->p_etemp > 900) /* 90% of 1000 */
655 me->p_desspeed = runslow;
656 else
657 me->p_desspeed = runfast;
658 if (!no_cloak)
659 cloak_on();
660 repair_off();
661 shield_down();
662 set_course(enemy_buf->e_course - 128);
663 if (debug)
664 fprintf(stderr, "%d(%d)(%d/%d) running from %s %16s damage (%d/%d) dist %d\n",
665 me->p_no,
666 (int) me->p_kills,
667 me->p_damage,
668 me->p_shield,
669 twoletters(enemy),
670 enemy->p_login,
671 enemy->p_damage,
672 enemy->p_shield,
673 enemy_buf->e_dist);
674 return;
675 }
676 /* Repair if necessary (we are safe) */
677 /*
678 * The robot is safely away from players. It can now repair in peace. * It
679 * will try to do so now.
680 */
681
682 if (do_repair())
683 {
684 return;
685 }
686 /* Attack. */
687 /*
688 * The robot has nothing to do. It will check and see if the nearest *
689 * enemy fits any of its criterion for attack. If it does, the robot *
690 * will speed in and deliver a punishing blow. (Well, maybe)
691 */
692
693 if ((enemy_buf->e_flags & E_INTRUDER) || (enemy_buf->e_dist < 15000)
694 || (hostile))
695 {
696 if ((!no_cloak) && (enemy_buf->e_dist < 10000))
697 cloak_on();
698 shield_up();
699 if (debug)
700 fprintf(stderr, "%d(%d)(%d/%d) attacking %s %16s damage (%d/%d) dist %d\n",
701 me->p_no,
702 (int) me->p_kills,
703 me->p_damage,
704 me->p_shield,
705 twoletters(enemy),
706 enemy->p_login,
707 enemy->p_damage,
708 enemy->p_shield,
709 enemy_buf->e_dist);
710
711 if (enemy_buf->e_dist < 15000)
712 {
713 set_course(enemy_buf->e_course +
714 avoid[(clock / AVOID_CLICKS) % SIZEOF(avoid)]);
715 if (angdist(me->p_desdir, me->p_dir) > 64)
716 set_speed(closeslow, 1);
717 else
718 set_speed(closefast, 1);
719 }
720 else
721 {
722 me->p_desdir = enemy_buf->e_course;
723 if (angdist(me->p_desdir, me->p_dir) > 64)
724 set_speed(closeslow, 1);
725 if (target >= 0) /* 7/27/91 TC */
726 set_speed(12, 1);
727 else if (me->p_etemp > 900) /* 90% of 1000 */
728 set_speed(runslow, 1);
729 else
730 set_speed(runfast, 1);
731 }
732 }
733 else
734 {
735 go_home(enemy_buf);
736 }
737 }
738
739 unsigned char
740 getcourse(x, y)
741 int x, y;
742 {
743 return ((unsigned char) (int) (atan2((double) (x - me->p_x),
744 (double) (me->p_y - y)) / 3.14159 * 128.));
745 }
746
747 /* the 100000's here were once GWIDTHs... */
748 struct
749 {
750 int x;
751 int y;
752 } center[] =
753 {
754 {
755
756 100000 / 2, 100000 / 2
757 }, /* change 5/20/91 TC was {0,0} */
758 {
759 100000 / 4, 100000 * 3 / 4
760 }, /* Fed */
761 {
762 100000 / 4, 100000 / 4
763 }, /* Rom */
764 {
765 0, 0
766 },
767 {
768 100000 *3 / 4, 100000 / 4
769 } , /* Kli */
770 {
771 0, 0
772 } ,
773 {
774 0, 0
775 } ,
776 {
777 0, 0
778 } ,
779 {
780 100000 *3 / 4, 100000 * 3 / 4
781 }
782 }; /* Ori */
783
784 /*
785 * This function means that the robot has nothing better to do. If there are
786 * hostile players in the game, it will try to get as close to them as it
787 * can, while staying in its own space. Otherwise, it will head to the center
788 * of its own space.
789 */
790 /* CRD feature: robots now hover near their start planet - MAK, 2-Jun-93 */
791
792 #define GUARDDIST 8000
793
794 void
795 go_home(ebuf)
796 struct Enemy *ebuf;
797 {
798 int x, y;
799 double dx, dy;
800 struct player *j;
801
802 if (ebuf == 0)
803 { /* No enemies */
804 /*
805 * if (debug) fprintf(stderr, "%d) No enemies\n", me->p_no);
806 */
807 if (target >= 0)
808 {
809 /* First priority, current target (if any) */
810 j = &players[target];
811 x = j->p_x;
812 y = j->p_y;
813 }
814 else if (startplanet == -1)
815 {
816 /* No start planet, so go to center of galaxy */
817 x = (GWIDTH / 2);
818 y = (GWIDTH / 2);
819 }
820 else
821 {
822 /* Return to start planet */
823 x = planets[startplanet].pl_x + (lrand48() % 2000) - 1000;
824 y = planets[startplanet].pl_y + (lrand48() % 2000) - 1000;
825 }
826 }
827 else
828 { /* Let's get near him */
829 j = &players[ebuf->e_info];
830 x = j->p_x;
831 y = j->p_y;
832
833 if (startplanet != -1)
834 {
835 /* Get between enemy and planet */
836 int px, py;
837 double theta;
838
839 px = planets[startplanet].pl_x;
840 py = planets[startplanet].pl_y;
841 theta = atan2((double) (y - py), (double) (x - px));
842 x = px + GUARDDIST * cos(theta);
843 y = py + GUARDDIST * sin(theta);
844 }
845 }
846 /*
847 * if (debug) fprintf(stderr, "%d) moving towards (%d/%d)\n", me->p_no, x,
848 * y);
849 */
850
851 /*
852 * Note that I've decided that robots should never stop moving. * It makes
853 * them too easy to kill
854 */
855
856 me->p_desdir = getcourse(x, y);
857 if (angdist(me->p_desdir, me->p_dir) > 64)
858 set_speed(dogslow, 1);
859 else if (me->p_etemp > 900) /* 90% of 1000 */
860 set_speed(runslow, 1);
861 else
862 {
863 dx = x - me->p_x;
864 dy = y - me->p_y;
865 set_speed((ihypot((int) dx, (int) dy) / 5000) + 3, 1);
866 }
867 cloak_off();
868 }
869
870 int
871 phaser_plasmas()
872 {
873 register struct plasmatorp *pt;
874 register int i;
875 int myphrange;
876
877 myphrange = phrange; /* PHASEDIST * me->p_ship.s_phaserdamage /
878 * 100; */
879 for (i = 0, pt = &plasmatorps[0]; i < MAXPLASMA * MAXPLAYER; i++, pt++)
880 {
881 if (pt->pt_status != PTMOVE)
882 continue;
883 if (i == me->p_no)
884 continue;
885 if (!(pt->pt_war & me->p_team) && !(me->p_hostile & pt->pt_team))
886 continue;
887 if (abs(pt->pt_x - me->p_x) > myphrange)
888 continue;
889 if (abs(pt->pt_y - me->p_y) > myphrange)
890 continue;
891 if (ihypot(pt->pt_x - me->p_x, pt->pt_y - me->p_y) > myphrange)
892 continue;
893 repair_off();
894 cloak_off();
895 phaser(getcourse(pt->pt_x, pt->pt_y));
896 return 1; /* was this missing? 3/25/92 TC */
897 break;
898 }
899 return 0; /* was this missing? 3/25/92 TC */
900 }
901
902 int
903 projectDamage(eNum, dirP)
904 int eNum;
905 int *dirP;
906 {
907 register int i, j, numHits = 0, mx, my, tx, ty, dx, dy;
908 double tdx, tdy, mdx, mdy;
909 register struct torp *t;
910
911 *dirP = 0;
912 for (i = 0, t = &torps[eNum * MAXTORP]; i < MAXTORP; i++, t++)
913 {
914 if (t->t_status == TFREE)
915 continue;
916 tx = t->t_x;
917 ty = t->t_y;
918 mx = me->p_x;
919 my = me->p_y;
920 tdx = (double) t->t_speed * Cos[t->t_dir] * WARP1;
921 tdy = (double) t->t_speed * Sin[t->t_dir] * WARP1;
922 mdx = (double) me->p_speed * Cos[me->p_dir] * WARP1;
923 mdy = (double) me->p_speed * Sin[me->p_dir] * WARP1;
924 for (j = t->t_fuse; j > 0; j--)
925 {
926 tx += tdx;
927 ty += tdy;
928 mx += mdx;
929 my += mdy;
930 dx = tx - mx;
931 dy = ty - my;
932 if (ABS(dx) < EXPDIST && ABS(dy) < EXPDIST)
933 {
934 numHits++;
935 *dirP += t->t_dir;
936 break;
937 }
938 }
939 }
940 if (numHits > 0)
941 *dirP /= numHits;
942 return (numHits);
943 }
944
945 int
946 isTractoringMe(enemy_buf)
947 struct Enemy *enemy_buf;
948 {
949 return ((enemy_buf->e_hisflags & PFTRACT) && /* bug fix: was using */
950 !(enemy_buf->e_hisflags & PFPRESS) && /* e_flags 6/24/92 TC */
951 (enemy_buf->e_tractor == me->p_no));
952 }
953
954 struct Enemy ebuf;
955
956 struct Enemy *
957 get_nearest()
958 {
959 int pcount = 0;
960 register int i;
961 register struct player *j;
962 int intruder = 0;
963 int tdist;
964 double dx, dy;
965 double vxa, vya, l; /* Used for trap shooting */
966 double vxt, vyt;
967 double vxs, vys;
968 double dp;
969
970 /* Find an enemy */
971 ebuf.e_info = me->p_no;
972 ebuf.e_dist = GWIDTH + 1;
973
974 pcount = 0; /* number of human players in game */
975
976 if (target >= 0)
977 {
978 j = &players[target];
979 if (!((me->p_swar | me->p_hostile) & j->p_team))
980 declare_war(players[target].p_team); /* make sure we're at war
981 * 7/31/91 TC */
982
983 /* We have an enemy */
984 /* Get his range */
985 dx = j->p_x - me->p_x;
986 dy = j->p_y - me->p_y;
987 tdist = ihypot((int) dx, (int) dy);
988
989 if (j->p_status != POUTFIT)
990 { /* ignore target if outfitting */
991 ebuf.e_info = target;
992 ebuf.e_dist = tdist;
993 ebuf.e_flags &= ~(E_INTRUDER);
994 }
995 /* need a loop to find hostile ships */
996 /* within tactical range */
997
998 for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++)
999 {
1000 if ((j->p_status != PALIVE) || (j == me) ||
1001 ((j->p_flags & PFROBOT) && (!hostile)))
1002 continue;
1003 else
1004 pcount++; /* Other players in the game */
1005 if (((j->p_swar | j->p_hostile) & me->p_team)
1006 || ((me->p_swar | me->p_hostile) & j->p_team))
1007 {
1008 /* We have an enemy */
1009 /* Get his range */
1010 dx = j->p_x - me->p_x;
1011 dy = j->p_y - me->p_y;
1012 tdist = ihypot((int) dx, (int) dy);
1013
1014 /* if target's teammate is too close, mark as nearest */
1015
1016 if ((tdist < ebuf.e_dist) && (tdist < 15000))
1017 {
1018 ebuf.e_info = i;
1019 ebuf.e_dist = tdist;
1020 ebuf.e_flags &= ~(E_INTRUDER);
1021 }
1022 } /* end if */
1023 } /* end for */
1024 }
1025 else
1026 { /* no target */
1027 /* avoid dead slots, me, other robots (which aren't hostile) */
1028 for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++)
1029 {
1030 if ((j->p_status != PALIVE) || (j == me) ||
1031 ((j->p_flags & PFROBOT) && (!hostile)))
1032 continue;
1033 else
1034 pcount++; /* Other players in the game */
1035 if (((j->p_swar | j->p_hostile) & me->p_team)
1036 || ((me->p_swar | me->p_hostile) & j->p_team))
1037 {
1038 /* We have an enemy */
1039 /* Get his range */
1040 dx = j->p_x - me->p_x;
1041 dy = j->p_y - me->p_y;
1042 tdist = ihypot((int) dx, (int) dy);
1043
1044 /* Check to see if ship is near our planet. */
1045 if (startplanet != -1)
1046 {
1047 int px, py;
1048 px = planets[startplanet].pl_x;
1049 py = planets[startplanet].pl_y;
1050
1051 intruder = (ihypot(j->p_x - px, j->p_y - py)
1052 < GUARDDIST);
1053 }
1054 if (tdist < ebuf.e_dist)
1055 {
1056 ebuf.e_info = i;
1057 ebuf.e_dist = tdist;
1058 if (intruder)
1059 ebuf.e_flags |= E_INTRUDER;
1060 else
1061 ebuf.e_flags &= ~(E_INTRUDER);
1062 }
1063 } /* end if */
1064 } /* end for */
1065 } /* end else */
1066 if (pcount == 0)
1067 {
1068 return (NOENEMY); /* no players in game */
1069 }
1070 else if (ebuf.e_info == me->p_no)
1071 {
1072 return (0); /* no hostile players in the game */
1073 }
1074 else
1075 {
1076 j = &players[ebuf.e_info];
1077
1078 /* Get torpedo course to nearest enemy */
1079 ebuf.e_flags &= ~(E_TSHOT);
1080
1081 vxa = (j->p_x - me->p_x);
1082 vya = (j->p_y - me->p_y);
1083 l = ihypot((int) vxa, (int) vya); /* Normalize va */
1084 if (l != 0)
1085 {
1086 vxa /= l;
1087 vya /= l;
1088 }
1089 vxs = (Cos[j->p_dir] * j->p_speed) * WARP1;
1090 vys = (Sin[j->p_dir] * j->p_speed) * WARP1;
1091 dp = vxs * vxa + vys * vya; /* Dot product of (va vs) */
1092 dx = vxs - dp * vxa;
1093 dy = vys - dp * vya;
1094 l = hypot(dx, dy); /* Determine how much speed is required */
1095 dp = (float) (me->p_ship.s_torp.speed * WARP1);
1096 l = (dp * dp - l * l);
1097 if (l > 0)
1098 {
1099 double he_x, he_y, area;
1100
1101 /* Only shoot if within distance */
1102 he_x = j->p_x + Cos[j->p_dir] * j->p_speed * 50 * WARP1;
1103 he_y = j->p_y + Sin[j->p_dir] * j->p_speed * 50 * WARP1;
1104 area = 50 * me->p_ship.s_torp.speed * WARP1;
1105 if (ihypot(he_x - me->p_x, he_y - me->p_y) < area)
1106 {
1107 l = sqrt(l);
1108 vxt = l * vxa + dx;
1109 vyt = l * vya + dy;
1110 ebuf.e_flags |= E_TSHOT;
1111 ebuf.e_tcourse = getcourse((int) vxt + me->p_x, (int) vyt + me->p_y);
1112 }
1113 }
1114 /* Get phaser shot status */
1115 if (ebuf.e_dist < 0.8 * phrange)
1116 ebuf.e_flags |= E_PSHOT;
1117 else
1118 ebuf.e_flags &= ~(E_PSHOT);
1119
1120 /* Get tractor/pressor status */
1121 if (ebuf.e_dist < trrange)
1122 ebuf.e_flags |= E_TRACT;
1123 else
1124 ebuf.e_flags &= ~(E_TRACT);
1125
1126
1127 /* get his phaser range */
1128 ebuf.e_phrange = PHASEDIST * j->p_ship.s_phaser.damage / 100;
1129
1130 /* get course info */
1131 ebuf.e_course = getcourse(j->p_x, j->p_y);
1132 ebuf.e_edir = j->p_dir;
1133 ebuf.e_hisflags = j->p_flags;
1134 ebuf.e_tractor = j->p_tractor;
1135 /*
1136 * if (debug) fprintf(stderr, "Set course to enemy is %d (%d)\n",
1137 * (int)ebuf.e_course, (int) ebuf.e_course * 360 / 256);
1138 */
1139
1140 /* check to polymorph */
1141
1142 if ((polymorphic) && (j->p_ship.s_type != me->p_ship.s_type) &&
1143 (j->p_ship.s_type != ATT))
1144 { /* don't polymorph to ATT 4/8/92 TC */
1145 extern int config();
1146 extern int getship();
1147 int old_shield;
1148 int old_damage;
1149 old_shield = me->p_ship.s_maxshield;
1150 old_damage = me->p_ship.s_maxdamage;
1151
1152 getship(&(me->p_ship), j->p_ship.s_type);
1153 config();
1154 if (me->p_speed > me->p_ship.s_imp.maxspeed)
1155 me->p_speed = me->p_ship.s_imp.maxspeed;
1156 me->p_shield = (me->p_shield * (float) me->p_ship.s_maxshield)
1157 / (float) old_shield;
1158 me->p_damage = (me->p_damage * (float) me->p_ship.s_maxdamage)
1159 / (float) old_damage;
1160 }
1161 return (&ebuf);
1162 }
1163 }
1164
1165 struct planet *
1166 get_nearest_planet()
1167 {
1168 register int i;
1169 register struct planet *l;
1170 register struct planet *nearest;
1171 int dist = GWIDTH; /* Manhattan distance to nearest planet */
1172 int ldist;
1173
1174 nearest = &planets[0];
1175 for (i = 0, l = &planets[i]; i < NUMPLANETS; i++, l++)
1176 {
1177 if ((ldist = (abs(me->p_x - l->pl_x) + abs(me->p_y - l->pl_y))) <
1178 dist)
1179 {
1180 dist = ldist;
1181 nearest = l;
1182 }
1183 }
1184 return nearest;
1185 }
1186
1187 int
1188 do_repair()
1189 {
1190 /* Repair if necessary (we are safe) */
1191
1192 register struct planet *l;
1193 int dx, dy;
1194 int dist;
1195
1196 l = get_nearest_planet();
1197 dx = abs(me->p_x - l->pl_x);
1198 dy = abs(me->p_y - l->pl_y);
1199
1200 if (me->p_damage > 0)
1201 {
1202 if ((me->p_swar | me->p_hostile) & l->pl_owner)
1203 {
1204 if (l->pl_armies > 0)
1205 {
1206 if ((dx < PFIREDIST) && (dy < PFIREDIST))
1207 {
1208 if (debug)
1209 fprintf(stderr, "%d) on top of hostile planet (%s)\n", me->p_no, l->pl_name);
1210 return (0); /* can't repair on top of hostile planets */
1211 }
1212 if (ihypot((int) dx, (int) dy) < PFIREDIST)
1213 {
1214 if (debug)
1215 fprintf(stderr, "%d) on top of hostile planet (%s)\n", me->p_no, l->pl_name);
1216 return (0);
1217 }
1218 }
1219 me->p_desspeed = 0;
1220 }
1221 else
1222 { /* if friendly */
1223 if ((l->pl_flags & PLREPAIR) &&
1224 !(me->p_flags & PFORBIT))
1225 { /* oh, repair! */
1226 dist = ihypot((int) dx, (int) dy);
1227
1228 if (debug)
1229 fprintf(stderr, "%d) locking on to planet %d\n",
1230 me->p_no, l->pl_no);
1231 cloak_off();
1232 shield_down();
1233 me->p_desdir = getcourse(l->pl_x, l->pl_y);
1234 lock_planet(l->pl_no);
1235 me->p_desspeed = 4;
1236 if (dist - (ORBDIST / 2) < (11500 * me->p_speed * me->p_speed) /
1237 me->p_ship.s_imp.dec)
1238 {
1239 if (me->p_desspeed > 2)
1240 {
1241 set_speed(2, 1);
1242 }
1243 }
1244 if ((dist < ENTORBDIST) && (me->p_speed <= 2))
1245 {
1246 me->p_flags &= ~PFPLLOCK;
1247 orbit();
1248 }
1249 return (1);
1250 }
1251 else
1252 { /* not repair, so ignore it */
1253 me->p_desspeed = 0;
1254 }
1255 }
1256 shield_down();
1257 if (me->p_speed == 0)
1258 repair();
1259 if (debug)
1260 fprintf(stderr, "%d) repairing damage at %d\n",
1261 me->p_no,
1262 me->p_damage);
1263 return (1);
1264 }
1265 else
1266 {
1267 return (0);
1268 }
1269 }
1270
1271
1272 void
1273 pmessage(str, recip, group, address)
1274 char *str;
1275 int recip;
1276 int group;
1277 char *address;
1278 {
1279 pmessage2(str, recip, group, address, 255);
1280 }
1281
1282
1283 void
1284 pmessage2(str, recip, group, address, from)
1285 char *str;
1286 int recip;
1287 int group;
1288 char *address;
1289 unsigned char from;
1290 {
1291 struct message *cur;
1292 int mesgnum;
1293
1294 if ((mesgnum = ++(mctl->mc_current)) >= MAXMESSAGE)
1295 {
1296 mctl->mc_current = 0;
1297 mesgnum = 0;
1298 }
1299 cur = &messages[mesgnum];
1300 cur->m_no = mesgnum;
1301 cur->m_flags = group;
1302 cur->m_recpt = recip;
1303 cur->m_from = from;
1304 (void) sprintf(cur->m_data, "%-9s %s", address, str);
1305 cur->m_flags |= MVALID;
1306 }
1307
1308
1309 char *
1310 robo_message(enemy)
1311 struct player *enemy;
1312 {
1313 int i;
1314 char *s, *t;
1315
1316 i = (lrand48() % (sizeof(rmessages) / sizeof(rmessages[0])));
1317
1318 for (t = rmessages[i], s = rmessage; *t != '\0'; s++, t++)
1319 {
1320 switch (*t)
1321 {
1322 case '$':
1323 switch (*(++t))
1324 {
1325 case '$':
1326 *s = *t;
1327 break;
1328 case 'T': /* "a Fed" or "a Klingon" ... */
1329 if (enemy->p_team != me->p_team &&
1330 enemy->p_team == ORI)
1331 {
1332 strcpy(s, "an ");
1333 }
1334 else
1335 {
1336 strcpy(s, "a ");
1337 }
1338 s = s + strlen(s);
1339 case 't': /* "Fed" or "Orion" */
1340 if (enemy->p_team != me->p_team)
1341 {
1342 switch (enemy->p_team)
1343 {
1344 case FED:
1345 strcpy(s, "Fed");
1346 break;
1347 case ROM:
1348 strcpy(s, "Romulan");
1349 break;
1350 case KLI:
1351 strcpy(s, "Klingon");
1352 break;
1353 case ORI:
1354 strcpy(s, "Orion");
1355 break;
1356 }
1357 }
1358 else
1359 {
1360 strcpy(s, "TRAITOR");
1361 }
1362 s = s + strlen(s) - 1;
1363 break;
1364 case 'f':
1365 switch (me->p_team)
1366 {
1367 case FED:
1368 strcpy(s, "Federation");
1369 break;
1370 case ROM:
1371 strcpy(s, "Romulan empire");
1372 break;
1373 case KLI:
1374 strcpy(s, "Klingon empire");
1375 break;
1376 case ORI:
1377 strcpy(s, "Orion empire");
1378 break;
1379 }
1380 s = s + strlen(s) - 1;
1381 break;
1382 default:
1383 *s = *t;
1384 }
1385 break;
1386 default:
1387 *s = *t;
1388 break;
1389 }
1390 }
1391 *s = '\0';
1392 return (rmessage);
1393 }
1394
1395 char *
1396 termie_message(enemy)
1397 struct player *enemy;
1398 {
1399 int i;
1400 char *s, *t;
1401
1402 i = (lrand48() % (sizeof(termie_messages) / sizeof(termie_messages[0])));
1403
1404 for (t = termie_messages[i], s = tmessage; *t != '\0'; s++, t++)
1405 {
1406 switch (*t)
1407 {
1408 case '$':
1409 switch (*(++t))
1410 {
1411 case '$':
1412 *s = *t;
1413 break;
1414 case 'T': /* "a Fed" or "a Klingon" ... */
1415 if (enemy->p_team != me->p_team &&
1416 enemy->p_team == ORI)
1417 {
1418 strcpy(s, "an ");
1419 }
1420 else
1421 {
1422 strcpy(s, "a ");
1423 }
1424 s = s + strlen(s);
1425 case 't': /* "Fed" or "Orion" */
1426 if (enemy->p_team != me->p_team)
1427 {
1428 switch (enemy->p_team)
1429 {
1430 case FED:
1431 strcpy(s, "Fed");
1432 break;
1433 case ROM:
1434 strcpy(s, "Romulan");
1435 break;
1436 case KLI:
1437 strcpy(s, "Klingon");
1438 break;
1439 case ORI:
1440 strcpy(s, "Orion");
1441 break;
1442 }
1443 }
1444 else
1445 {
1446 strcpy(s, "TRAITOR");
1447 }
1448 s = s + strlen(s) - 1;
1449 break;
1450 case 'f':
1451 switch (me->p_team)
1452 {
1453 case FED:
1454 strcpy(s, "Federation");
1455 break;
1456 case ROM:
1457 strcpy(s, "Romulan empire");
1458 break;
1459 case KLI:
1460 strcpy(s, "Klingon empire");
1461 break;
1462 case ORI:
1463 strcpy(s, "Orion empire");
1464 break;
1465 }
1466 s = s + strlen(s) - 1;
1467 break;
1468 case 'n': /* name 8/2/91 TC */
1469 strcpy(s, enemy->p_name);
1470 s = s + strlen(s) - 1;
1471 break;
1472 default:
1473 *s = *t;
1474 }
1475 break;
1476 default:
1477 *s = *t;
1478 break;
1479 }
1480 }
1481 *s = '\0';
1482 return (tmessage);
1483
1484 }
1485
1486 void
1487 exitRobot()
1488 {
1489 static char buf[80];
1490
1491 r_signal(SIGALRM, SIG_IGN);
1492 if (me != NULL && me->p_team != ALLTEAM)
1493 {
1494 if (target >= 0)
1495 {
1496 strcpy(buf, "I'll be back.");
1497 messAll(buf);
1498 }
1499 else
1500 {
1501 /*
1502 * sprintf(buf, "%s %s (%s) leaving the game (%.16s@%.16s)",
1503 * ranks[me->p_stats.st_rank].name, me->p_name, me->p_mapchars,
1504 * me->p_login, me->p_monitor); messAll(buf);
1505 */
1506 }
1507 }
1508 #ifdef ROBOTSTATS
1509 save_robot();
1510 #endif
1511
1512 strcpy(buf, me->p_name);
1513 /* something about Terminators hangs up the slot when a human */
1514 /* tries to log in on that slot, so... */
1515 memset(me, 0, sizeof(struct player)); /* confusion 8/5/91 TC */
1516 strcpy(me->p_name, buf);
1517
1518 /*
1519 * me->p_status = PFREE; move_player(me->p_no, -1,-1, 1);
1520 */
1521
1522 /*
1523 * all right, so zeroing out p_stats.st_tticks has undesireable side
1524 * effects when the client tries to compute ratings...
1525 */
1526
1527 me->p_stats.st_tticks = 1; /* quick fix 3/15/92 TC */
1528 exit(0);
1529 }
1530
1531 void
1532 messAll(buf)
1533 char *buf; /* wasn't K&R before...oops 5/1/92 TC */
1534 {
1535 static char addrbuf[20];
1536
1537 sprintf(addrbuf, " %s->ALL", twoletters(me));
1538 pmessage2(buf, 0, MALL, addrbuf, me->p_no);
1539 }