6
+ − 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
+ − 20 char binary[] = "@(#)snake";
+ − 21
+ − 22 #include "config.h"
+ − 23 #include <stdio.h>
+ − 24 #include <sys/types.h>
+ − 25 #include <sys/stat.h>
+ − 26 #include <sys/file.h>
+ − 27 #include <sys/time.h>
+ − 28 #include <signal.h>
+ − 29 #include <setjmp.h>
+ − 30 #include "defs.h"
+ − 31 #include "struct.h"
+ − 32 #include "data.h"
+ − 33 #include "shmem.h"
+ − 34
+ − 35 #ifndef linux
+ − 36 double atof();
+ − 37 #endif
+ − 38 extern void (*r_signal()) ();
+ − 39
+ − 40 struct player *perfs[2];
+ − 41 int printsnakeUsage();
+ − 42 int num_perfs = 2;
+ − 43 int debug = 0;
+ − 44 int target = -1;
+ − 45 int berserk = 0;
+ − 46 int patrol = 0;
+ − 47 int noSmush = 0;
+ − 48 int plan_guard = 0; /* KAO */
+ − 49 int planet1, planet2; /* KAO */
+ − 50 int team1 = 0, team2 = 0;
+ − 51 int length = MAXTORP; /* how many pairs of torps in the snake */
+ − 52
+ − 53 struct itimerval udt; /* derived from frequency RF */
+ − 54 int lastm;
+ − 55 int tno = 0;
+ − 56
+ − 57 int
+ − 58 choose_team(team)
+ − 59 {
+ − 60 if (tno < 0)
+ − 61 tno = team;
+ − 62 if (!team1)
+ − 63 team1 = 1 << team;
+ − 64 else if (!team2)
+ − 65 team2 = 1 << team;
+ − 66 }
+ − 67
+ − 68 main(argc, argv)
+ − 69 int argc;
+ − 70 char **argv;
+ − 71 {
+ − 72 register int i;
+ − 73 int snakemove(), exitSnake();
+ − 74 int pno;
+ − 75 char str[80], tlet;
+ − 76 int pc = 0;
+ − 77 int usage = 0;
+ − 78 double frequency = 10; /* default of 10 updates per second */
+ − 79
+ − 80 argv0 = argv[0];
+ − 81 tno = -1;
+ − 82
+ − 83 srand48(getpid() + time((time_t *) 0));
+ − 84 memset(perfs, 0, sizeof(perfs));
+ − 85
+ − 86 for (; argc > 1 && argv[1][0] == '-'; argc--, argv++)
+ − 87 {
+ − 88 switch (argv[1][1])
+ − 89 {
+ − 90 case 'p':
+ − 91 patrol++;
+ − 92 break;
+ − 93 case 'n':
+ − 94 noSmush = 1;
+ − 95 break;
+ − 96 case 's':
+ − 97 noSmush = -1;
+ − 98 break;
+ − 99 case 'g': /* KAO */
+ − 100 plan_guard++; /* KAO */
+ − 101 argv++; /* KAO */
+ − 102 argc--;
+ − 103 planet1 = atoi(argv[1]); /* KAO */
+ − 104 argc--;
+ − 105 argv++; /* KAO */
+ − 106 planet2 = atoi(argv[1]); /* KAO */
+ − 107 break; /* KAO */
+ − 108 case 'b':
+ − 109 berserk++;
+ − 110 break;
+ − 111 case 'd':
+ − 112 debug++;
+ − 113 break;
+ − 114 case 't':
+ − 115 { /* target */
+ − 116 char c;
+ − 117 c = argv[1][2];
+ − 118 target = -1;
+ − 119 if (c == '\0')
+ − 120 {
+ − 121 fprintf(stderr, "Must specify target. e.g. -t3.\n");
+ − 122 exit(1);
+ − 123 }
+ − 124 if ((c >= '0') && (c <= '9'))
+ − 125 target = c - '0';
+ − 126 else if ((c >= 'a') && (c <= 'z'))
+ − 127 target = c - 'a' + 10;
+ − 128 else
+ − 129 {
+ − 130 fprintf(stderr, "Must specify target. e.g. -t3.\n");
+ − 131 exit(1);
+ − 132 }
+ − 133 }
+ − 134 break;
+ − 135
+ − 136 case 'T': /* team */
+ − 137 tlet = argv[1][2];
+ − 138 if (isupper(tlet))
+ − 139 tlet = tolower(tlet);
+ − 140 switch (tlet)
+ − 141 {
+ − 142 case 'f':
+ − 143 choose_team(0);
+ − 144 break;
+ − 145 case 'r':
+ − 146 choose_team(1);
+ − 147 break;
+ − 148 case 'k':
+ − 149 choose_team(2);
+ − 150 break;
+ − 151 case 'o':
+ − 152 choose_team(3);
+ − 153 break;
+ − 154 case 'i':
+ − 155 tno = 4;
+ − 156 break;
+ − 157 default:
+ − 158 fprintf(stderr, "Unknown team type. Usage -Tx where x is [frkoi]\n");
+ − 159 exit(1);
+ − 160 } /* end switch argv */
+ − 161 break;
+ − 162
+ − 163 case 'l':
+ − 164 length = atoi(argv[1] + 2);
+ − 165 if (length < 1)
+ − 166 {
+ − 167 length = 1;
+ − 168 }
+ − 169 else if (length > MAXTORP)
+ − 170 {
+ − 171 length = MAXTORP;
+ − 172 }
+ − 173 break;
+ − 174 case 'f':
+ − 175 frequency = atof(argv[1] + 2);
+ − 176 if (frequency < 0)
+ − 177 {
+ − 178 frequency = 1;
+ − 179 }
+ − 180 break;
+ − 181 default:
+ − 182 fprintf(stderr, "Unknown option '%c'\n", argv[1][1]);
+ − 183 usage++;
+ − 184 exit(1);
+ − 185 } /* end switch argv[1][1] */
+ − 186 } /* end for */
+ − 187
+ − 188 if (usage)
+ − 189 {
+ − 190 printsnakeUsage();
+ − 191 exit(1);
+ − 192 }
+ − 193
+ − 194 /* if -T wasn't specified default to FED */
+ − 195 if (tno < 0)
+ − 196 tno = lrand48() % 4;
+ − 197
+ − 198 /* XX -- teams imply patrol */
+ − 199 if (team1 && team2)
+ − 200 patrol++;
+ − 201
+ − 202 #ifdef nodef
+ − 203 /* debug */
+ − 204 if (patrol)
+ − 205 {
+ − 206 printf("snake (%s): patrolling %s,%s\n", teamshort[1 << tno],
+ − 207 teamshort[team1],
+ − 208 teamshort[team2]);
+ − 209 }
+ − 210 fflush(stdout);
+ − 211 #endif
+ − 212
+ − 213 /* readsysdefaults(); */
+ − 214
+ − 215 (void) r_signal(SIGHUP, exitSnake);
+ − 216 (void) r_signal(SIGINT, exitSnake);
+ − 217 (void) r_signal(SIGBUS, exitSnake);
+ − 218 (void) r_signal(SIGSEGV, exitSnake);
+ − 219 openmem(0, 0);
+ − 220
+ − 221 lastm = mctl->mc_current;
+ − 222
+ − 223 for (i = 0; i < 2; i++)
+ − 224 { /* two players per snake */
+ − 225 pno = findrslot();
+ − 226 if (pno < 0)
+ − 227 {
+ − 228 fprintf(stderr, "snake: no room in game\n");
+ − 229 if (i > 0)
+ − 230 perfs[0]->p_status = PFREE;
+ − 231 exit(1);
+ − 232 }
+ − 233 me = &players[pno];
+ − 234
+ − 235 perfs[i] = me;
+ − 236
+ − 237 me->p_no = pno;
+ − 238 myship = &me->p_ship;
+ − 239 mystats = &me->p_stats;
+ − 240
+ − 241 strcpy(pseudo, "The Snake");
+ − 242 strcpy(login, "SnkeChrmr");
+ − 243
+ − 244 strcpy(me->p_name, pseudo);
+ − 245 me->p_name[sizeof(me->p_name) - 1] = '\0';
+ − 246
+ − 247 (void) strncpy(me->p_login, login, sizeof(me->p_login));
+ − 248 me->p_login[sizeof(me->p_login) - 1] = '\0';
+ − 249 (void) strncpy(me->p_monitor, "Server", sizeof(me->p_monitor));
+ − 250 me->p_monitor[sizeof(me->p_monitor) - 1] = '\0';
+ − 251 /* enter(tno, 0, pno, class, -1); */
+ − 252
+ − 253 me->p_team = (tno < 4) ? (1 << tno) : 0;
+ − 254 config();
+ − 255
+ − 256 me->p_pos = -1;
+ − 257 me->p_flags |= PFROBOT; /* Mark as a robot */
+ − 258 me->p_flags |= PFSNAKE; /* Mark as snake */
+ − 259 if (berserk)
+ − 260 me->p_hostile = FED | ROM | ORI | KLI;
+ − 261 }
+ − 262
+ − 263 r_signal(SIGALRM, snakemove);
+ − 264
+ − 265 {
+ − 266 double period = 1 / frequency;
+ − 267 udt.it_interval.tv_sec = period; /* get the whole part */
+ − 268 period -= udt.it_interval.tv_sec; /* get the fractional part */
+ − 269 udt.it_interval.tv_usec = 1e6 * period;
+ − 270 udt.it_value.tv_sec = 1;
+ − 271 udt.it_value.tv_usec = 0;
+ − 272 }
+ − 273
+ − 274 if (setitimer(ITIMER_REAL, &udt, 0) < 0)
+ − 275 {
+ − 276 perror("setitimer");
+ − 277 for (i = 0; i < num_perfs; i++)
+ − 278 {
+ − 279 if (perfs[i])
+ − 280 perfs[i]->p_status = PFREE;
+ − 281 }
+ − 282 exit(1);
+ − 283 }
+ − 284 #ifndef SVR4
+ − 285 /* allows robots to be forked by the daemon -- Evil ultrix bullshit */
+ − 286 sigsetmask(0);
+ − 287 #endif /* SVR4 */
+ − 288
+ − 289 /* NOTE: snakes do not become alive. */
+ − 290
+ − 291 while (1)
+ − 292 {
+ − 293 pause();
+ − 294 }
+ − 295 }
+ − 296
+ − 297 findtestslot()
+ − 298 {
+ − 299 register int i;
+ − 300
+ − 301 for (i = MAXPLAYER - configvals->ntesters; i < MAXPLAYER; i++)
+ − 302 {
+ − 303 if (players[i].p_status == PFREE)
+ − 304 { /* We have a free slot */
+ − 305 players[i].p_status = POUTFIT; /* possible race code */
+ − 306 break;
+ − 307 }
+ − 308 }
+ − 309 if (i == MAXPLAYER)
+ − 310 {
+ − 311 return -1; /* no room in tester slots */
+ − 312 }
+ − 313 memset(&players[i].p_stats, 0, sizeof(struct stats));
+ − 314 players[i].p_stats.st_tticks = 1;
+ − 315 return (i);
+ − 316 }
+ − 317
+ − 318 findrslot()
+ − 319 {
+ − 320 register int i;
+ − 321
+ − 322 /* look for tester slot first */
+ − 323 i = findtestslot();
+ − 324 if (i > -1)
+ − 325 return i;
+ − 326
+ − 327 for (i = 0; i < MAXPLAYER; i++)
+ − 328 {
+ − 329 if (players[i].p_status == PFREE)
+ − 330 { /* We have a free slot */
+ − 331 players[i].p_status = POUTFIT; /* possible race code */
+ − 332 break;
+ − 333 }
+ − 334 }
+ − 335 if ((i == MAXPLAYER) || (i == -1))
+ − 336 {
+ − 337 if (debug)
+ − 338 {
+ − 339 fprintf(stderr, "No more room in game\n");
+ − 340 }
+ − 341 return -1;
+ − 342 }
+ − 343 memset(&players[i].p_stats, 0, sizeof(struct stats));
+ − 344 players[i].p_stats.st_tticks = 1;
+ − 345 return (i);
+ − 346 }
+ − 347
+ − 348 void
+ − 349 warning(mess)
+ − 350 char *mess;
+ − 351 {
+ − 352 if (debug)
+ − 353 fprintf(stderr, "warning: %s\n", mess);
+ − 354 }
+ − 355
+ − 356 config()
+ − 357 {
+ − 358 /* mostly not used */
+ − 359 #if 0
+ − 360 /* what the heck is this procedure for ? */
+ − 361 myship->s_phasercost = 0;
+ − 362 myship->s_torpcost = 0;
+ − 363 myship->s_cloakcost = 0;
+ − 364 myship->s_torpfuse = 1000000;
+ − 365 myship->s_torpdamage = 10;
+ − 366 myship->s_plasmadamage = 50;
+ − 367 myship->s_plasmacost = 0;
+ − 368 myship->s_plasmaturns = 0;
+ − 369 myship->s_plasmaspeed = 10;
+ − 370 myship->s_plasmafuse = 1000000;
+ − 371 myship->s_wpncoolrate = 100;
+ − 372 myship->s_egncoolrate = 100;
+ − 373 #endif
+ − 374 }
+ − 375
+ − 376 /*---------------------[ prints the usage of snake ]---------------------*/
+ − 377
+ − 378 printsnakeUsage()
+ − 379 {
+ − 380 printf("Usage: snake [options]\n");
+ − 381 printf("Options:\n\
+ − 382 -u -- this usage message\n\
+ − 383 -p -- patrol\n\
+ − 384 -s -- noSmush (?)\n\
+ − 385 -b -- berserk\n\
+ − 386 -d -- debug\n\
+ − 387 -t -- target <player number>\n\
+ − 388 -T -- team [frkoi]\n\
+ − 389 -l -- length (in torps)\n\
+ − 390 -f -- frequency\n\
+ − 391 -g -- guardian: -g <planet1> <planet2> (must be 2 planets listed,\n\
+ − 392 by number).\n");
+ − 393 }
+ − 394
+ − 395 /*--------------------------[ printsnakeUsage ]--------------------------*/