Mercurial > ~darius > hgwebdir.cgi > paradise_server
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/robotII.c Sat Dec 06 04:37:04 1997 +0000 @@ -0,0 +1,622 @@ +/*-------------------------------------------------------------------------- +NETREK II -- Paradise + +Permission to use, copy, modify, and distribute this software and its +documentation, or any derivative works thereof, for any NON-COMMERCIAL +purpose and without fee is hereby granted, provided that this copyright +notice appear in all copies. No representations are made about the +suitability of this software for any purpose. This software is provided +"as is" without express or implied warranty. + + Xtrek Copyright 1986 Chris Guthrie + Netrek (Xtrek II) Copyright 1989 Kevin P. Smith + Scott Silvey + Paradise II (Netrek II) Copyright 1993 Larry Denys + Kurt Olsen + Brandon Gillespie +--------------------------------------------------------------------------*/ + +char binary[] = "@(#)robotII"; + +#include "config.h" + +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/file.h> +#ifndef ULTRIX +#include <sys/fcntl.h> +#endif +#include <signal.h> +#include <setjmp.h> +#include <errno.h> +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "shmem.h" + +extern void (*r_signal()) (); + +void config(); + +struct itimerval udt; +extern int redrawall; /* maint: missing "extern" 6/22/92 TC */ +extern int lastm; /* maint: missing "extern" 6/22/92 TC */ + +/* This lets you specify which ships a robot is allowed to choose */ +int robotships[NUM_TYPES] = { + 1, /* SCOUT */ + 1, /* DESTROYER */ + 1, /* CRUISER */ + 1, /* BATTLESHIP */ + 1, /* ASSAULT */ + 0, /* STARBASE */ + 0, /* ATT */ + 0, /* JUMPSHIP */ + 1, /* FRIGATE */ + 0, /* WARBASE */ + 1, /* LIGHTCRUISER */ + 0, /* CARRIER */ + 0, /* UTILITY */ + 1 /* PATROL */ +}; + +/* lots of neat flags */ +int hostile; +int debug; +int level; +int fleet; +int sticky; +int berserk; +int practice; +int nofuel; + +int polymorphic; /* match opponent's ship class 8/15/91 TC */ +int target; /* Terminator's target 7/27/91 TC */ +int phrange; /* phaser range 7/31/91 TC */ +int trrange; /* tractor range 8/2/91 TC */ + +int startplanet = -1; /* CRD feature - MAK, 2-Jun-93 */ + +/* velocities 8/9/91 TC */ + +int dogslow; /* dodge speed (hard turn) */ +int dogfast; /* dodge speed (soft turn) */ +int runslow; /* run speed (flat etemp) */ +int runfast; /* run speed (gain etemp) */ +int closeslow; /* approach speed (hard turn) */ +int closefast; /* approach speed (soft turn) */ + +char *rnames[6] = {"M5", "Colossus", "Guardian", "HAL", "DreadPirate Bob", +"TERMINATOR"}; + +#ifdef ROBOTSTATS +void +do_robot_login() +{ + int plfd, position, entries, i; + char *path; + struct statentry player; + struct stat buf; + + path = build_path(PLAYERFILE); + plfd = open(path, O_RDONLY, 0); + if (plfd < 0) + { + fprintf(stderr, "%s: I cannot open the player file! (errno: %d)\n", + argv0, errno); + me->p_pos = -1; + return; + } + position = 0; + while (read(plfd, (char *) &player, sizeof(struct statentry)) == + sizeof(struct statentry)) + { + if (!strcmp(pseudo, player.name)) + { + close(plfd); + me->p_pos = position; + memcpy(&(me->p_stats), &player.stats, sizeof(struct stats)); + return; + } + position++; + } + /* Not in there, so create it */ + strcpy(player.name, pseudo); + strcpy(player.password, "*"); /* an invalid password to prevent logins */ + memset(&player.stats, 0, sizeof(struct stats)); + player.stats.st_tticks = 1; + player.stats.st_flags = ST_INITIAL; + + plfd = open(path, O_RDWR | O_CREAT, 0644); + if (plfd < 0) + { + fprintf(stderr, "%s: I cannot open the player file! (errno: %d)\n", + argv0, errno); + me->p_pos = -1; + return; + } + else + { + fstat(plfd, &buf); + entries = buf.st_size / sizeof(struct statentry); + lseek(plfd, entries * sizeof(struct statentry), 0); + write(plfd, (char *) &player, sizeof(struct statentry)); + close(plfd); + me->p_pos = entries; + memcpy(&(me->p_stats), &player.stats, sizeof(struct stats)); + } +} + +void +save_robot() +{ + int fd; + char *path; + + if (me->p_pos < 0) + return; + path = build_path(PLAYERFILE); + fd = open(path, O_WRONLY, 0644); + if (fd >= 0) + { + me->p_stats.st_lastlogin = time(NULL); + lseek(fd, 32 + me->p_pos * sizeof(struct statentry), 0); + write(fd, (char *) &me->p_stats, sizeof(struct stats)); + close(fd); + } +} +#endif + +int +main(argc, argv) + int argc; + char **argv; +{ + register int i; + int rmove(); + int team = -1; + int bteam; + int pno; + int class; /* ship class 8/9/91 TC */ + + argv0 = argv[0]; + srand48(time(NULL) + getpid()); + + openmem(0, 0); + + for (;;) + { + class = lrand48() % NUM_TYPES; /* pick a ship type */ + if (robotships[class] && shipsallowed[class]) + break; + } + + target = -1; /* no target 7/27/91 TC */ + for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) + { + switch (argv[1][1]) + { + case 'S': + startplanet = atoi(&argv[1][2]); + if (startplanet >= configvals->numplanets) + { + printf("startplanet insane: %d\n", startplanet); + startplanet = -1; + } + break; + case 'F': + nofuel++; + break; + case 'P': + polymorphic++; + break; + case 'f': + fleet++; + break; + case 's': + sticky++; + break; + case 'd': + debug++; + break; + case 'h': + hostile++; + break; + case 'p': + practice++; + break; + case 'b': + berserk++; + break; + case 'l': + if (argv[1][2] != '\0') + level = atoi(&argv[1][2]); + else + level = 100; + break; + case 'c': /* ship class */ + { + char cstr[NUM_TYPES + 1]; + + for (class = 0; class <= NUM_TYPES; class++) + { + if (class == NUM_TYPES) + { + cstr[NUM_TYPES] = 0; + fprintf(stderr, "Unknown ship class, must be one of [%s].\n", cstr); + exit(1); + } + if (argv[1][2] == shipvals[class].s_letter) + break; + cstr[class] = shipvals[class].s_letter; + } + } + break; + case 'T': /* team */ + switch (argv[1][2]) + { + case 'f': + team = 0; + bteam = FED; + break; + case 'r': + team = 1; + bteam = ROM; + break; + case 'k': + team = 2; + bteam = KLI; + break; + case 'o': + team = 3; + bteam = ORI; + break; + case 'n': /* change 5/10/91 TC neutral */ + case 'i': + team = 4; + bteam = FED | ROM | KLI | ORI; /* don't like anybody */ + break; + case 't': + { + char c; + c = argv[1][3]; + + team = 5; + bteam = FED | ROM | KLI | ORI; /* don't like anybody */ + target = -1; + if (c == '\0') + { + fprintf(stderr, "Must specify target. e.g. -Tt3.\n"); + exit(1); + } + if ((c >= '0') && (c <= '9')) + target = c - '0'; + else if ((c >= 'a') && (c <= 'v')) + target = c - 'a' + 10; + else + { + fprintf(stderr, "Must specify target. e.g. -Tt3.\n"); + exit(1); + } + } /* end case 't' */ + break; + default: + fprintf(stderr, "Unknown team type. Usage -Tx where x is [frko]\n"); + exit(1); + } /* end switch argv */ + break; + default: + fprintf(stderr, "Unknown option '%c' (must be one of: bcdfpsFPT)\n", argv[1][1]); + exit(1); + } /* end switch argv[1][1] */ + + + } /* end for */ + + if (team < 0 || team >= 6) + { /* change 7/27/91 TC was 4 now 6 */ + if (debug) + fprintf(stderr, "Choosing random team.\n"); + team = lrand48() % 4; + } + + pno = findrslot(); /* Robots are entitled to tester's slots. */ + me = &players[pno]; + me->p_no = pno; + myship = &me->p_ship; + mystats = &me->p_stats; + lastm = mctl->mc_current; + + /* + * At this point we have memory set up. If we aren't a fleet, we don't + * want to replace any other robots on this team, so we'll check the other + * players and get out if there are any on our team. + */ + + if (practice) + { + strcpy(pseudo, "Hozer"); + } + else + { + strcpy(pseudo, rnames[team]); + } + strcpy(login, "Robot"); + + (void) strncpy(me->p_login, login, sizeof(me->p_login)); + me->p_login[sizeof(me->p_login) - 1] = '\0'; + (void) strncpy(me->p_monitor, "Nowhere", sizeof(me->p_monitor)); + me->p_monitor[sizeof(me->p_monitor) - 1] = '\0'; + + /* repeat "Nowhere" for completeness 4/13/92 TC */ + (void) strncpy(me->p_full_hostname, "Nowhere", sizeof(me->p_full_hostname)); + me->p_full_hostname[sizeof(me->p_full_hostname) - 1] = '\0'; + + if (target >= 0) + { /* hack 7/27/91 TC */ + enter(team, target, pno, class, startplanet); + startplanet = -1; /* Termies should forget about startplanet */ + } + else + startplanet = enter(team, 0, pno, class, startplanet); + +#ifdef ROBOTSTATS + do_robot_login(); +#else + me->p_pos = -1; /* So robot stats don't get saved */ +#endif + + me->p_flags |= PFROBOT; /* Mark as a robot */ + if ((berserk) || (team == 4)) /* indeps are hostile */ + me->p_hostile = (FED | ROM | KLI | ORI); /* unless they are berserk */ + else if (team == 5) + me->p_hostile = 0; /* Termies declare war later */ + else if (practice) + me->p_hostile = bteam; /* or practice */ + else + me->p_hostile = 0; /* robots are peaceful */ + + if (practice) + me->p_flags |= PFPRACTR; /* Mark as a practice robot */ + r_signal(SIGALRM, rmove); + + config(); + if (practice) + { + udt.it_interval.tv_sec = 1; /* Robots get to move 1/sec */ + udt.it_interval.tv_usec = 000000; + } + else + { + udt.it_interval.tv_sec = 0; /* Robots get to move 2/sec */ + udt.it_interval.tv_usec = 500000; + } + udt.it_value.tv_sec = 1; + udt.it_value.tv_usec = 0; + if (setitimer(ITIMER_REAL, &udt, 0) < 0) + { + perror("setitimer"); + me->p_status = PFREE; /* Put robot in game */ + move_player(me->p_no, -1, -1, 1); + exit(1); + } + /* allows robots to be forked by the daemon -- Evil ultrix bullshit */ +#ifndef SVR4 + sigsetmask(0); +#endif /* SVR4 */ + + if (team == 4) + { + int count = 0; + for (i = 0; i < MAXPLAYER; i++) + { + if (players[i].p_status == PALIVE) + count++; + } + if (((count <= 1) && (!fleet)) || + ((count < 1) && (fleet))) + { /* if one or less players, don't show */ + if (debug) + fprintf(stderr, "No one to hoze.\n"); + players[pno].p_status = PFREE; + move_player(me->p_no, -1, -1, 1); + exit(1); + } + } + if (!fleet) + { + for (i = 0; i < MAXPLAYER; i++) + { + if ((players[i].p_status == PALIVE) && (players[i].p_team == bteam)) + { + if (debug) + fprintf(stderr, "Galaxy already defended\n"); + players[pno].p_status = PFREE; + move_player(me->p_no, -1, -1, 1); + exit(1); + } + } + } + me->p_status = PALIVE; /* Put robot in game */ + while (1) + { + pause(); + } + return 0; +} + +int +findrslot() +{ + register int i; + +#if 0 + for (i = 0; i < MAXPLAYER; i++) +#else + for (i = MAXPLAYER - 1; i >= 0; i--) +#endif + { + /* reverse entry..let's be trendy 4/6/92 TC */ + if (players[i].p_status == PFREE) + { /* We have a free slot */ + players[i].p_status = POUTFIT; /* possible race code */ + break; + } + } + if ((i == MAXPLAYER) || (i == -1)) + { + if (debug) + { + fprintf(stderr, "No more room in game\n"); + } + exit(0); + } + memset(&players[i].p_stats, 0, sizeof(struct stats)); + players[i].p_stats.st_tticks = 1; + return (i); +} + +void +warning(mess) + char *mess; +{ + if (debug) + fprintf(stderr, "warning: %s\n", mess); +} + +void +config() +{ + /* calc class-specific stuff */ + + phrange = PHASEDIST * me->p_ship.s_phaser.damage / 100; + trrange = TRACTDIST * me->p_ship.s_tractrng; + + switch (myship->s_type) + { + case SCOUT: + dogslow = 5; + dogfast = 7; + runslow = 8; + runfast = 9; + closeslow = 5; + closefast = 7; + break; + case DESTROYER: + dogslow = 4; + dogfast = 6; + runslow = 6; + runfast = 8; + closeslow = 4; + closefast = 6; + break; + case CRUISER: + dogslow = 4; + dogfast = 6; + runslow = 6; + runfast = 7; + closeslow = 4; + closefast = 6; + break; + case BATTLESHIP: + dogslow = 3; + dogfast = 5; + runslow = 5; + runfast = 6; + closeslow = 3; + closefast = 4; + break; + case FRIGATE: + dogslow = 3; + dogfast = 5; + runslow = 5; + runfast = 6; + closeslow = 3; + closefast = 4; + break; + case ASSAULT: + dogslow = 3; + dogfast = 5; + runslow = 6; + runfast = 7; + closeslow = 3; + closefast = 4; + break; + case JUMPSHIP: + dogslow = 2; + dogfast = 3; + runslow = 2; + runfast = 3; + closeslow = 2; + closefast = 3; + break; + case STARBASE: + dogslow = 2; + dogfast = 2; + runslow = 2; + runfast = 2; + closeslow = 2; + closefast = 2; + break; + case WARBASE: + dogslow = 2; + dogfast = 2; + runslow = 2; + runfast = 2; + closeslow = 2; + closefast = 2; + break; + case LIGHTCRUISER: + dogslow = 5; + dogfast = 6; + runslow = 6; + runfast = 7; + closeslow = 5; + closefast = 7; + break; + case CARRIER: + dogslow = 3; + dogfast = 4; + runslow = 5; + runfast = 6; + closeslow = 4; + closefast = 6; + break; + case UTILITY: + dogslow = 3; + dogfast = 4; + runslow = 5; + runfast = 6; + closeslow = 4; + closefast = 5; + break; + case PATROL: + dogslow = 7; + dogfast = 8; + runslow = 9; + runfast = 10; + closeslow = 8; + closefast = 9; + break; + } + + if (debug) + printf("My phaser range: %d.\n", phrange); + if (debug) + printf("My tractor range: %d.\n", trrange); + + if (!nofuel) + { + myship->s_phaser.cost = 0; + myship->s_torp.cost = 0; + myship->s_cloakcost = 0; + } + if (target >= 0) + { /* 7/27/91 TC */ + myship->s_imp.maxspeed = 20;/* was 10, so you can't run */ + myship->s_imp.cost = 1; + myship->s_egncoolrate = 100; + } +}