|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T r ┃
Length: 8296 (0x2068) Types: TextFile Names: »rmove.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/xtrek/rmove.c«
#ifndef lint static char *rcsid_rmove_c = "$Header: rmove.c,v 10.1 86/11/30 15:27:49 jg Rel $"; #endif lint /* Copyright (c) 1986 Chris Guthrie */ #include <X/Xlib.h> #include <stdio.h> #include <signal.h> #include "defs.h" #include "struct.h" #include "data.h" #include "sintab.h" #define AVOID_TIME 4 #define STAY 0x1 #define RUN 0x2 #define ATTACK 0x3 #define REPAIR 0x4 #define AVOID 0x5 #define NORMALIZE(d) ((((d) % 256) + 256) % 256) struct player *enemy; int edist; unsigned char ecourse; int rstatus; int timer; static int avoidTime; extern int debug; extern int hostile; extern int easy; extern int sticky; double atan2(); double hypot(); unsigned char getcourse(); rmove() { register int i; register struct player *j; register int burst; register int numHits, tDir; int avDir, found; double dx, dy; int tdist; unsigned char tcourse = 10; /* Check that I'm alive */ if (me->p_status == PEXPLODE) { signal(SIGALRM, SIG_IGN); while (me->p_status == PEXPLODE) ; while (me->p_ntorp > 0) ; me->p_status = PFREE; exit(0); } if (me->p_status == PDEAD) { signal(SIGALRM, SIG_IGN); me->p_status = PFREE; exit(0); } /* Find an enemy */ enemy = me; edist = GWIDTH + 1; for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) { if ((j->p_status != PALIVE) || (j == me) || ((j->p_flags & PFROBOT) && (!hostile))) continue; if ((j->p_swar | j->p_war) & me->p_team) { /* We have an enemy */ /* Get his range */ dx = j->p_x - me->p_x; dy = j->p_y - me->p_y; tdist = hypot(dx, dy); /* Check to see if ship is in our space. */ if (!hostile) { if (tdist > 15000) { /* if (1) { */ switch (me->p_team) { case FED: if ((j->p_x > GWIDTH/2) || (j->p_y < GWIDTH/2)) continue; break; case ROM: if ((j->p_x > GWIDTH/2) || (j->p_y > GWIDTH/2)) continue; break; case KLI: if ((j->p_x < GWIDTH/2) || (j->p_y > GWIDTH/2)) continue; break; case ORI: if ((j->p_x < GWIDTH/2) || (j->p_y < GWIDTH/2)) continue; break; } } } if (debug) fprintf(stderr, "%d) found enemy %d in our space at %d,%d\n", me->p_no, j->p_no, j->p_x, j->p_y); if (tdist < edist) { enemy = j; edist = tdist; continue; } } } if ((enemy == me) && (!sticky)) { /* No more enemies */ if (timer == 0) timer = me->p_updates + 600; if (me->p_updates >= timer) { signal(SIGALRM, SIG_IGN); me->p_status = PFREE; exit(0); } go_home(); } else { timer = 0; } /* Get course to nearest enemy */ found = 0; for (i = 0; i < 50; i++) { double he_x, he_y, area; he_x = enemy->p_x + cos[enemy->p_dir] * enemy->p_speed * i * WARP1; he_y = enemy->p_y + sin[enemy->p_dir] * enemy->p_speed * i * WARP1; area = i * me->p_ship.s_torpspeed * WARP1; if (hypot(he_x - me->p_x, he_y - me->p_y) < area) { found = 1; tcourse = getcourse((int) he_x, (int) he_y); break; } } if (debug) fprintf(stderr, "torpedo course to enemy %d is %d (%d) - %s\n", (int)tcourse, enemy->p_no, (int) tcourse * 360 / 256, found ? "aiming to hit" : "no hit possible"); if (debug) fprintf(stderr, "Set course to enemy is %d (%d)\n", (int)ecourse, (int) ecourse * 360 / 256); ecourse = getcourse(enemy->p_x, enemy->p_y); if ((edist > 40000) && !(hostile)) { if (me->p_damage > 0) { me->p_desspeed = 0; shield_down(); repair(); if (debug) fprintf(stderr, "%d) repairing damage at %d\n", me->p_no, me->p_damage); } else { rstatus = STAY; go_home(); if ((me->p_updates % 200) == 0) if (debug) fprintf(stderr, "%d(%d) nearest enemy %c%d %16s (%d/%d) dist %d\n", me->p_no, (int) me->p_kills, teamlet[enemy->p_team], enemy->p_no, enemy->p_login, enemy->p_damage, enemy->p_shield, edist); } return; } if (me->p_damage > 0 && edist < 25000) { /* Run away */ me->p_desspeed = 6; if (!(me->p_flags & PFCLOAK)) cloak(); shield_down(); me->p_desdir = ecourse - 128; if (debug) fprintf(stderr, "%d(%d)(%d/%d) running from %c%d %16s damage (%d/%d) dist %d\n", me->p_no, (int) me->p_kills, me->p_damage, me->p_shield, teamlet[enemy->p_team], enemy->p_no, enemy->p_login, enemy->p_damage, enemy->p_shield, edist); } else if (rstatus == AVOID) { if (--avoidTime <= 0) rstatus = ATTACK; if (debug) fprintf(stderr, "avoiding: dir = %d\n", me->p_desdir); } else { rstatus = ATTACK; if (me->p_flags & PFCLOAK) cloak(); if (debug) fprintf(stderr, "%d(%d)(%d/%d) attacking %c%d %16s damage (%d/%d) dist %d\n", me->p_no, (int) me->p_kills, me->p_damage, me->p_shield, teamlet[enemy->p_team], enemy->p_no, enemy->p_login, enemy->p_damage, enemy->p_shield, edist); if (me->p_desdir != me->p_dir) me->p_desspeed = 2; else if (me->p_etemp > 900) /* 90% of 1000 */ me->p_desspeed = 5; else me->p_desspeed = 5; shield_up(); if (edist < 15000) { numHits = projectDamage(enemy->p_no, &avDir); if (debug) { fprintf(stderr, "%d hits expected from %d from dir = %d\n", numHits, enemy->p_no, avDir); } if (numHits == 0) { me->p_desdir = ecourse + 32; if (debug) fprintf(stderr, "attacking: dir = %d\n", me->p_desdir); } else { /* * Avoid Torps */ avoidTime = AVOID_TIME; tDir = avDir - me->p_dir; /* put into 0->255 range */ tDir = NORMALIZE(tDir); if (debug) fprintf(stderr, "mydir = %d avDir = %d tDir = %d q = %d\n", me->p_dir, avDir, tDir, tDir / 64); switch (tDir / 64) { case 0: case 1: me->p_desdir = NORMALIZE(avDir + 64); break; case 2: case 3: me->p_desdir = NORMALIZE(avDir - 64); break; } if (!(me->p_flags & PFCLOAK)) cloak(); rstatus = AVOID; if (debug) fprintf(stderr, "evading to dir = %d\n", me->p_desdir); } } else { me->p_desdir = ecourse; } } /* Fire weapons!!! */ if (edist < 10000) { if (debug) fprintf(stderr, "%d) firing torps\n", me->p_no); for (burst = 0; (burst < 2) && (me->p_ntorp < MAXTORP); burst++) { if (me->p_flags & PFCLOAK) cloak(); if (easy) ntorp(tcourse, TMOVE); else ntorp(tcourse, TSTRAIGHT); } } if ((edist < 5000) && (!easy)) { if (debug) fprintf(stderr, "%d) phaser firing\n", me->p_no); if (me->p_flags & PFCLOAK) cloak(); phaser(ecourse); } } unsigned char getcourse(x, y) int x, y; { return((unsigned char) (atan2((double) (x - me->p_x), (double) (me->p_y - y)) / 3.14159 * 128.)); } struct { int x; int y; } center[] = { {0, 0}, {GWIDTH / 4, GWIDTH * 3 / 4}, /* Fed */ {GWIDTH / 4, GWIDTH / 4}, /* Rom */ {0, 0}, {GWIDTH * 3 / 4, GWIDTH / 4}, /* Kli */ {0, 0}, {0, 0}, {0, 0}, {GWIDTH * 3 / 4, GWIDTH * 3 / 4}}; /* Ori */ /* This function will send the robot back to the center of it's space when it has nothing better to do. Centers are defined above. */ go_home() { int x, y, speed; double dx, dy; int tdist; x = center[me->p_team].x; y = center[me->p_team].y; if ((ABS(x - me->p_x) < 100) && (ABS(y - me->p_y) < 100)) me->p_desspeed = 0; else { me->p_desdir = getcourse(x, y); dx = x - me->p_x; dy = y - me->p_y; me->p_desspeed = (hypot(dx, dy) / 10000) + 1; } } projectDamage(eNum, dirP) int *dirP; { register int i, j, numHits = 0, mx, my, tx, ty, dx, dy; double tdx, tdy, mdx, mdy; register struct torp *t; *dirP = 0; for (i = 0, t = &torps[eNum * MAXTORP]; i < MAXTORP; i++, t++) { if (t->t_status == TFREE) continue; tx = t->t_x; ty = t->t_y; mx = me->p_x; my = me->p_y; tdx = (double) t->t_speed * cos[t->t_dir] * WARP1; tdy = (double) t->t_speed * sin[t->t_dir] * WARP1; mdx = (double) me->p_speed * cos[me->p_dir] * WARP1; mdy = (double) me->p_speed * sin[me->p_dir] * WARP1; for (j = t->t_fuse; j > 0; j--) { tx += tdx; ty += tdy; mx += mdx; my += mdy; dx = tx - mx; dy = ty - my; if (ABS(dx) < EXPDIST && ABS(dy) < EXPDIST) { numHits++; *dirP += t->t_dir; break; } } } if (numHits > 0) *dirP /= numHits; return (numHits); }