Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/robotII.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 char binary[] = "@(#)robotII"; | |
20 | |
21 #include "config.h" | |
22 | |
23 #include <stdio.h> | |
24 #include <sys/types.h> | |
25 #include <sys/time.h> | |
26 #include <sys/stat.h> | |
27 #include <sys/file.h> | |
28 #ifndef ULTRIX | |
29 #include <sys/fcntl.h> | |
30 #endif | |
31 #include <signal.h> | |
32 #include <setjmp.h> | |
33 #include <errno.h> | |
34 #include "defs.h" | |
35 #include "struct.h" | |
36 #include "data.h" | |
37 #include "shmem.h" | |
38 | |
39 extern void (*r_signal()) (); | |
40 | |
41 void config(); | |
42 | |
43 struct itimerval udt; | |
44 extern int redrawall; /* maint: missing "extern" 6/22/92 TC */ | |
45 extern int lastm; /* maint: missing "extern" 6/22/92 TC */ | |
46 | |
47 /* This lets you specify which ships a robot is allowed to choose */ | |
48 int robotships[NUM_TYPES] = { | |
49 1, /* SCOUT */ | |
50 1, /* DESTROYER */ | |
51 1, /* CRUISER */ | |
52 1, /* BATTLESHIP */ | |
53 1, /* ASSAULT */ | |
54 0, /* STARBASE */ | |
55 0, /* ATT */ | |
56 0, /* JUMPSHIP */ | |
57 1, /* FRIGATE */ | |
58 0, /* WARBASE */ | |
59 1, /* LIGHTCRUISER */ | |
60 0, /* CARRIER */ | |
61 0, /* UTILITY */ | |
62 1 /* PATROL */ | |
63 }; | |
64 | |
65 /* lots of neat flags */ | |
66 int hostile; | |
67 int debug; | |
68 int level; | |
69 int fleet; | |
70 int sticky; | |
71 int berserk; | |
72 int practice; | |
73 int nofuel; | |
74 | |
75 int polymorphic; /* match opponent's ship class 8/15/91 TC */ | |
76 int target; /* Terminator's target 7/27/91 TC */ | |
77 int phrange; /* phaser range 7/31/91 TC */ | |
78 int trrange; /* tractor range 8/2/91 TC */ | |
79 | |
80 int startplanet = -1; /* CRD feature - MAK, 2-Jun-93 */ | |
81 | |
82 /* velocities 8/9/91 TC */ | |
83 | |
84 int dogslow; /* dodge speed (hard turn) */ | |
85 int dogfast; /* dodge speed (soft turn) */ | |
86 int runslow; /* run speed (flat etemp) */ | |
87 int runfast; /* run speed (gain etemp) */ | |
88 int closeslow; /* approach speed (hard turn) */ | |
89 int closefast; /* approach speed (soft turn) */ | |
90 | |
91 char *rnames[6] = {"M5", "Colossus", "Guardian", "HAL", "DreadPirate Bob", | |
92 "TERMINATOR"}; | |
93 | |
94 #ifdef ROBOTSTATS | |
95 void | |
96 do_robot_login() | |
97 { | |
98 int plfd, position, entries, i; | |
99 char *path; | |
100 struct statentry player; | |
101 struct stat buf; | |
102 | |
103 path = build_path(PLAYERFILE); | |
104 plfd = open(path, O_RDONLY, 0); | |
105 if (plfd < 0) | |
106 { | |
107 fprintf(stderr, "%s: I cannot open the player file! (errno: %d)\n", | |
108 argv0, errno); | |
109 me->p_pos = -1; | |
110 return; | |
111 } | |
112 position = 0; | |
113 while (read(plfd, (char *) &player, sizeof(struct statentry)) == | |
114 sizeof(struct statentry)) | |
115 { | |
116 if (!strcmp(pseudo, player.name)) | |
117 { | |
118 close(plfd); | |
119 me->p_pos = position; | |
120 memcpy(&(me->p_stats), &player.stats, sizeof(struct stats)); | |
121 return; | |
122 } | |
123 position++; | |
124 } | |
125 /* Not in there, so create it */ | |
126 strcpy(player.name, pseudo); | |
127 strcpy(player.password, "*"); /* an invalid password to prevent logins */ | |
128 memset(&player.stats, 0, sizeof(struct stats)); | |
129 player.stats.st_tticks = 1; | |
130 player.stats.st_flags = ST_INITIAL; | |
131 | |
132 plfd = open(path, O_RDWR | O_CREAT, 0644); | |
133 if (plfd < 0) | |
134 { | |
135 fprintf(stderr, "%s: I cannot open the player file! (errno: %d)\n", | |
136 argv0, errno); | |
137 me->p_pos = -1; | |
138 return; | |
139 } | |
140 else | |
141 { | |
142 fstat(plfd, &buf); | |
143 entries = buf.st_size / sizeof(struct statentry); | |
144 lseek(plfd, entries * sizeof(struct statentry), 0); | |
145 write(plfd, (char *) &player, sizeof(struct statentry)); | |
146 close(plfd); | |
147 me->p_pos = entries; | |
148 memcpy(&(me->p_stats), &player.stats, sizeof(struct stats)); | |
149 } | |
150 } | |
151 | |
152 void | |
153 save_robot() | |
154 { | |
155 int fd; | |
156 char *path; | |
157 | |
158 if (me->p_pos < 0) | |
159 return; | |
160 path = build_path(PLAYERFILE); | |
161 fd = open(path, O_WRONLY, 0644); | |
162 if (fd >= 0) | |
163 { | |
164 me->p_stats.st_lastlogin = time(NULL); | |
165 lseek(fd, 32 + me->p_pos * sizeof(struct statentry), 0); | |
166 write(fd, (char *) &me->p_stats, sizeof(struct stats)); | |
167 close(fd); | |
168 } | |
169 } | |
170 #endif | |
171 | |
172 int | |
173 main(argc, argv) | |
174 int argc; | |
175 char **argv; | |
176 { | |
177 register int i; | |
178 int rmove(); | |
179 int team = -1; | |
180 int bteam; | |
181 int pno; | |
182 int class; /* ship class 8/9/91 TC */ | |
183 | |
184 argv0 = argv[0]; | |
185 srand48(time(NULL) + getpid()); | |
186 | |
187 openmem(0, 0); | |
188 | |
189 for (;;) | |
190 { | |
191 class = lrand48() % NUM_TYPES; /* pick a ship type */ | |
192 if (robotships[class] && shipsallowed[class]) | |
193 break; | |
194 } | |
195 | |
196 target = -1; /* no target 7/27/91 TC */ | |
197 for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) | |
198 { | |
199 switch (argv[1][1]) | |
200 { | |
201 case 'S': | |
202 startplanet = atoi(&argv[1][2]); | |
203 if (startplanet >= configvals->numplanets) | |
204 { | |
205 printf("startplanet insane: %d\n", startplanet); | |
206 startplanet = -1; | |
207 } | |
208 break; | |
209 case 'F': | |
210 nofuel++; | |
211 break; | |
212 case 'P': | |
213 polymorphic++; | |
214 break; | |
215 case 'f': | |
216 fleet++; | |
217 break; | |
218 case 's': | |
219 sticky++; | |
220 break; | |
221 case 'd': | |
222 debug++; | |
223 break; | |
224 case 'h': | |
225 hostile++; | |
226 break; | |
227 case 'p': | |
228 practice++; | |
229 break; | |
230 case 'b': | |
231 berserk++; | |
232 break; | |
233 case 'l': | |
234 if (argv[1][2] != '\0') | |
235 level = atoi(&argv[1][2]); | |
236 else | |
237 level = 100; | |
238 break; | |
239 case 'c': /* ship class */ | |
240 { | |
241 char cstr[NUM_TYPES + 1]; | |
242 | |
243 for (class = 0; class <= NUM_TYPES; class++) | |
244 { | |
245 if (class == NUM_TYPES) | |
246 { | |
247 cstr[NUM_TYPES] = 0; | |
248 fprintf(stderr, "Unknown ship class, must be one of [%s].\n", cstr); | |
249 exit(1); | |
250 } | |
251 if (argv[1][2] == shipvals[class].s_letter) | |
252 break; | |
253 cstr[class] = shipvals[class].s_letter; | |
254 } | |
255 } | |
256 break; | |
257 case 'T': /* team */ | |
258 switch (argv[1][2]) | |
259 { | |
260 case 'f': | |
261 team = 0; | |
262 bteam = FED; | |
263 break; | |
264 case 'r': | |
265 team = 1; | |
266 bteam = ROM; | |
267 break; | |
268 case 'k': | |
269 team = 2; | |
270 bteam = KLI; | |
271 break; | |
272 case 'o': | |
273 team = 3; | |
274 bteam = ORI; | |
275 break; | |
276 case 'n': /* change 5/10/91 TC neutral */ | |
277 case 'i': | |
278 team = 4; | |
279 bteam = FED | ROM | KLI | ORI; /* don't like anybody */ | |
280 break; | |
281 case 't': | |
282 { | |
283 char c; | |
284 c = argv[1][3]; | |
285 | |
286 team = 5; | |
287 bteam = FED | ROM | KLI | ORI; /* don't like anybody */ | |
288 target = -1; | |
289 if (c == '\0') | |
290 { | |
291 fprintf(stderr, "Must specify target. e.g. -Tt3.\n"); | |
292 exit(1); | |
293 } | |
294 if ((c >= '0') && (c <= '9')) | |
295 target = c - '0'; | |
296 else if ((c >= 'a') && (c <= 'v')) | |
297 target = c - 'a' + 10; | |
298 else | |
299 { | |
300 fprintf(stderr, "Must specify target. e.g. -Tt3.\n"); | |
301 exit(1); | |
302 } | |
303 } /* end case 't' */ | |
304 break; | |
305 default: | |
306 fprintf(stderr, "Unknown team type. Usage -Tx where x is [frko]\n"); | |
307 exit(1); | |
308 } /* end switch argv */ | |
309 break; | |
310 default: | |
311 fprintf(stderr, "Unknown option '%c' (must be one of: bcdfpsFPT)\n", argv[1][1]); | |
312 exit(1); | |
313 } /* end switch argv[1][1] */ | |
314 | |
315 | |
316 } /* end for */ | |
317 | |
318 if (team < 0 || team >= 6) | |
319 { /* change 7/27/91 TC was 4 now 6 */ | |
320 if (debug) | |
321 fprintf(stderr, "Choosing random team.\n"); | |
322 team = lrand48() % 4; | |
323 } | |
324 | |
325 pno = findrslot(); /* Robots are entitled to tester's slots. */ | |
326 me = &players[pno]; | |
327 me->p_no = pno; | |
328 myship = &me->p_ship; | |
329 mystats = &me->p_stats; | |
330 lastm = mctl->mc_current; | |
331 | |
332 /* | |
333 * At this point we have memory set up. If we aren't a fleet, we don't | |
334 * want to replace any other robots on this team, so we'll check the other | |
335 * players and get out if there are any on our team. | |
336 */ | |
337 | |
338 if (practice) | |
339 { | |
340 strcpy(pseudo, "Hozer"); | |
341 } | |
342 else | |
343 { | |
344 strcpy(pseudo, rnames[team]); | |
345 } | |
346 strcpy(login, "Robot"); | |
347 | |
348 (void) strncpy(me->p_login, login, sizeof(me->p_login)); | |
349 me->p_login[sizeof(me->p_login) - 1] = '\0'; | |
350 (void) strncpy(me->p_monitor, "Nowhere", sizeof(me->p_monitor)); | |
351 me->p_monitor[sizeof(me->p_monitor) - 1] = '\0'; | |
352 | |
353 /* repeat "Nowhere" for completeness 4/13/92 TC */ | |
354 (void) strncpy(me->p_full_hostname, "Nowhere", sizeof(me->p_full_hostname)); | |
355 me->p_full_hostname[sizeof(me->p_full_hostname) - 1] = '\0'; | |
356 | |
357 if (target >= 0) | |
358 { /* hack 7/27/91 TC */ | |
359 enter(team, target, pno, class, startplanet); | |
360 startplanet = -1; /* Termies should forget about startplanet */ | |
361 } | |
362 else | |
363 startplanet = enter(team, 0, pno, class, startplanet); | |
364 | |
365 #ifdef ROBOTSTATS | |
366 do_robot_login(); | |
367 #else | |
368 me->p_pos = -1; /* So robot stats don't get saved */ | |
369 #endif | |
370 | |
371 me->p_flags |= PFROBOT; /* Mark as a robot */ | |
372 if ((berserk) || (team == 4)) /* indeps are hostile */ | |
373 me->p_hostile = (FED | ROM | KLI | ORI); /* unless they are berserk */ | |
374 else if (team == 5) | |
375 me->p_hostile = 0; /* Termies declare war later */ | |
376 else if (practice) | |
377 me->p_hostile = bteam; /* or practice */ | |
378 else | |
379 me->p_hostile = 0; /* robots are peaceful */ | |
380 | |
381 if (practice) | |
382 me->p_flags |= PFPRACTR; /* Mark as a practice robot */ | |
383 r_signal(SIGALRM, rmove); | |
384 | |
385 config(); | |
386 if (practice) | |
387 { | |
388 udt.it_interval.tv_sec = 1; /* Robots get to move 1/sec */ | |
389 udt.it_interval.tv_usec = 000000; | |
390 } | |
391 else | |
392 { | |
393 udt.it_interval.tv_sec = 0; /* Robots get to move 2/sec */ | |
394 udt.it_interval.tv_usec = 500000; | |
395 } | |
396 udt.it_value.tv_sec = 1; | |
397 udt.it_value.tv_usec = 0; | |
398 if (setitimer(ITIMER_REAL, &udt, 0) < 0) | |
399 { | |
400 perror("setitimer"); | |
401 me->p_status = PFREE; /* Put robot in game */ | |
402 move_player(me->p_no, -1, -1, 1); | |
403 exit(1); | |
404 } | |
405 /* allows robots to be forked by the daemon -- Evil ultrix bullshit */ | |
406 #ifndef SVR4 | |
407 sigsetmask(0); | |
408 #endif /* SVR4 */ | |
409 | |
410 if (team == 4) | |
411 { | |
412 int count = 0; | |
413 for (i = 0; i < MAXPLAYER; i++) | |
414 { | |
415 if (players[i].p_status == PALIVE) | |
416 count++; | |
417 } | |
418 if (((count <= 1) && (!fleet)) || | |
419 ((count < 1) && (fleet))) | |
420 { /* if one or less players, don't show */ | |
421 if (debug) | |
422 fprintf(stderr, "No one to hoze.\n"); | |
423 players[pno].p_status = PFREE; | |
424 move_player(me->p_no, -1, -1, 1); | |
425 exit(1); | |
426 } | |
427 } | |
428 if (!fleet) | |
429 { | |
430 for (i = 0; i < MAXPLAYER; i++) | |
431 { | |
432 if ((players[i].p_status == PALIVE) && (players[i].p_team == bteam)) | |
433 { | |
434 if (debug) | |
435 fprintf(stderr, "Galaxy already defended\n"); | |
436 players[pno].p_status = PFREE; | |
437 move_player(me->p_no, -1, -1, 1); | |
438 exit(1); | |
439 } | |
440 } | |
441 } | |
442 me->p_status = PALIVE; /* Put robot in game */ | |
443 while (1) | |
444 { | |
445 pause(); | |
446 } | |
447 return 0; | |
448 } | |
449 | |
450 int | |
451 findrslot() | |
452 { | |
453 register int i; | |
454 | |
455 #if 0 | |
456 for (i = 0; i < MAXPLAYER; i++) | |
457 #else | |
458 for (i = MAXPLAYER - 1; i >= 0; i--) | |
459 #endif | |
460 { | |
461 /* reverse entry..let's be trendy 4/6/92 TC */ | |
462 if (players[i].p_status == PFREE) | |
463 { /* We have a free slot */ | |
464 players[i].p_status = POUTFIT; /* possible race code */ | |
465 break; | |
466 } | |
467 } | |
468 if ((i == MAXPLAYER) || (i == -1)) | |
469 { | |
470 if (debug) | |
471 { | |
472 fprintf(stderr, "No more room in game\n"); | |
473 } | |
474 exit(0); | |
475 } | |
476 memset(&players[i].p_stats, 0, sizeof(struct stats)); | |
477 players[i].p_stats.st_tticks = 1; | |
478 return (i); | |
479 } | |
480 | |
481 void | |
482 warning(mess) | |
483 char *mess; | |
484 { | |
485 if (debug) | |
486 fprintf(stderr, "warning: %s\n", mess); | |
487 } | |
488 | |
489 void | |
490 config() | |
491 { | |
492 /* calc class-specific stuff */ | |
493 | |
494 phrange = PHASEDIST * me->p_ship.s_phaser.damage / 100; | |
495 trrange = TRACTDIST * me->p_ship.s_tractrng; | |
496 | |
497 switch (myship->s_type) | |
498 { | |
499 case SCOUT: | |
500 dogslow = 5; | |
501 dogfast = 7; | |
502 runslow = 8; | |
503 runfast = 9; | |
504 closeslow = 5; | |
505 closefast = 7; | |
506 break; | |
507 case DESTROYER: | |
508 dogslow = 4; | |
509 dogfast = 6; | |
510 runslow = 6; | |
511 runfast = 8; | |
512 closeslow = 4; | |
513 closefast = 6; | |
514 break; | |
515 case CRUISER: | |
516 dogslow = 4; | |
517 dogfast = 6; | |
518 runslow = 6; | |
519 runfast = 7; | |
520 closeslow = 4; | |
521 closefast = 6; | |
522 break; | |
523 case BATTLESHIP: | |
524 dogslow = 3; | |
525 dogfast = 5; | |
526 runslow = 5; | |
527 runfast = 6; | |
528 closeslow = 3; | |
529 closefast = 4; | |
530 break; | |
531 case FRIGATE: | |
532 dogslow = 3; | |
533 dogfast = 5; | |
534 runslow = 5; | |
535 runfast = 6; | |
536 closeslow = 3; | |
537 closefast = 4; | |
538 break; | |
539 case ASSAULT: | |
540 dogslow = 3; | |
541 dogfast = 5; | |
542 runslow = 6; | |
543 runfast = 7; | |
544 closeslow = 3; | |
545 closefast = 4; | |
546 break; | |
547 case JUMPSHIP: | |
548 dogslow = 2; | |
549 dogfast = 3; | |
550 runslow = 2; | |
551 runfast = 3; | |
552 closeslow = 2; | |
553 closefast = 3; | |
554 break; | |
555 case STARBASE: | |
556 dogslow = 2; | |
557 dogfast = 2; | |
558 runslow = 2; | |
559 runfast = 2; | |
560 closeslow = 2; | |
561 closefast = 2; | |
562 break; | |
563 case WARBASE: | |
564 dogslow = 2; | |
565 dogfast = 2; | |
566 runslow = 2; | |
567 runfast = 2; | |
568 closeslow = 2; | |
569 closefast = 2; | |
570 break; | |
571 case LIGHTCRUISER: | |
572 dogslow = 5; | |
573 dogfast = 6; | |
574 runslow = 6; | |
575 runfast = 7; | |
576 closeslow = 5; | |
577 closefast = 7; | |
578 break; | |
579 case CARRIER: | |
580 dogslow = 3; | |
581 dogfast = 4; | |
582 runslow = 5; | |
583 runfast = 6; | |
584 closeslow = 4; | |
585 closefast = 6; | |
586 break; | |
587 case UTILITY: | |
588 dogslow = 3; | |
589 dogfast = 4; | |
590 runslow = 5; | |
591 runfast = 6; | |
592 closeslow = 4; | |
593 closefast = 5; | |
594 break; | |
595 case PATROL: | |
596 dogslow = 7; | |
597 dogfast = 8; | |
598 runslow = 9; | |
599 runfast = 10; | |
600 closeslow = 8; | |
601 closefast = 9; | |
602 break; | |
603 } | |
604 | |
605 if (debug) | |
606 printf("My phaser range: %d.\n", phrange); | |
607 if (debug) | |
608 printf("My tractor range: %d.\n", trrange); | |
609 | |
610 if (!nofuel) | |
611 { | |
612 myship->s_phaser.cost = 0; | |
613 myship->s_torp.cost = 0; | |
614 myship->s_cloakcost = 0; | |
615 } | |
616 if (target >= 0) | |
617 { /* 7/27/91 TC */ | |
618 myship->s_imp.maxspeed = 20;/* was 10, so you can't run */ | |
619 myship->s_imp.cost = 1; | |
620 myship->s_egncoolrate = 100; | |
621 } | |
622 } |