/****************************************************************/ /* code copyright 1995-1996 Andrew Johnson - ALL RIGHTS RESERVED*/ /* ajohnson@eecs.uic.edu */ /* */ /* Electronic Visualization Lab (M/C 154) */ /* University of Illinois at Chicago */ /* 851 South Morgan St. Room 1120 SEO */ /* Chicago, IL 60607-7053 */ /* */ /* (312) 996-3002 (312) 413-7585 FAX */ /***********************************************************************/ /* update.c v 1.2 */ /* update routines for battalion */ /***********************************************************************/ #include "battalion.h" /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /* output an error message */ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ void showError(char * theString) { fprintf(stderr, "BATTALION ERROR: %s\n", theString); fflush(stderr); } /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /* compute height of a building */ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ float buildingHeight(int type, int shape) { float height; switch(type){ case 0: height = 0.5; break; case 1: switch(shape){ case 1: case 11: case 14: case 22: case 23: case 24: case 37: height = 0.8; break; case 9: height = 0.2; break; case 5: case 6: case 13: case 28: height = -0.2; break; case 31: case 32: height = -0.4; break; default: height = 0.0; break; } break; case 2: height = -0.8; break; case 3: if (shape == 0) height = -0.4; else height = -0.6; break; default: showError("invalid building type (buildingHeight)"); break; } return(height); } /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ int same(char * first, char * second) { if (strcmp(first, second) == 0) return(1); else return(0); } /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ int different(char * first, char * second) { if (strcmp(first, second) != 0) return(1); else return(0); } /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ struct monsterInfo resetMonsterParameters(struct monsterInfo Googelon) { register int i; /************************************/ /* reset general monster parmeters */ /************************************/ Googelon.monsterScore = 0; Googelon.monsterIsDead = 0; Googelon.deadCount = 0; Googelon.timeDead = 0; Googelon.energyRemaining = MAXLIFE; Googelon.moveCount = 0; Googelon.headHorzRotate = 0; Googelon.headVertRotate = 150; Googelon.beamOn = 0; Googelon.monsterID = rand(); for(i=0; iheadHorzRotate; vert = m->headVertRotate; doSound(MONSTERBEAM); if (vert < 175) R = 4; else R = 1.2 / (cos((900 - vert) * BIG_DEG_TO_RAD)); loc3[0] = x + R * -cos((900 + horz) * BIG_DEG_TO_RAD); loc3[2] = z + R * sin((900 + horz) * BIG_DEG_TO_RAD); if (vert < 0) loc3[1] = PLANEY+1.2 + R * sin(fabs(vert* BIG_DEG_TO_RAD)); else loc3[1] = PLANEY+1.2 - R * sin(fabs(vert* BIG_DEG_TO_RAD)); loc1[0] = x; loc1[1] = PLANEY + 1.2; loc1[2] = z; /**********************************/ /* does beam touch ground */ /**********************************/ if (loc3[1] <= PLANEY + 0.1) { addProjectile(loc3[0], PLANEY + 0.175, loc3[2], PROJSCAR, 0, -0.0075, 0, 0, NULL); } /******************************/ /* what does beam hit */ /******************************/ if ((loc3[2] - loc1[2]) == 0) loc1[2] += NEARZERO; rbeamhorz = fabs(sqrt(pow(loc3[0] - loc1[0], 2) + pow(loc3[2] - loc1[2], 2))); abeamhorz = atan((loc3[0] - loc1[0]) / (loc3[2] - loc1[2])); if ((loc3[2] - loc1[2]) < 0) abeamhorz += PI; hdiff = - abeamhorz; beamx = 0; /* rbeamhorz * sin(abeamhorz + hdiff); */ beamz = rbeamhorz; /* rbeamhorz * cos(abeamhorz + hdiff); */ if (beamz == 0) beamz = NEARZERO; rbeamvert = fabs(sqrt(pow(loc3[1] - loc1[1], 2) + beamz*beamz)); abeamvert = atan( (loc3[1] - loc1[1]) / beamz); vdiff = -abeamvert; beamy = 0; /* rbeamvert * sin(abeamvert + vdiff); */ beamz = rbeamvert; /* rbeamvert * cos(abeamvert + vdiff); */ if (beamz < 0) abeamvert += PI; /**********************************/ /* does beam touch a tank */ /**********************************/ temptank = allTanks; while(temptank->next != NULL) { ttank = temptank->next; if ((ttank->z - loc1[2]) == 0) loc1[2] += NEARZERO; rtankhorz = fabs(sqrt((pow(ttank->x - loc1[0], 2) + pow(ttank->z - loc1[2], 2)))); atankhorz = atan( (ttank->x - loc1[0]) / (ttank->z - loc1[2])); if ((ttank->z - loc1[2]) < 0) atankhorz += PI; tankx = rtankhorz * sin(atankhorz + hdiff); tankz = rtankhorz * cos(atankhorz + hdiff); if (tankz == 0) tankz = NEARZERO; if ((ttank->type == HELO) || (ttank->type == CHH)) { rtankvert = fabs(sqrt(pow(ttank->y - loc1[1], 2) + tankz*tankz)); atankvert = atan( (ttank->y - loc1[1]) / tankz); } else /* tanks are positioned IN the ground so raise them up a bit */ { rtankvert = fabs(sqrt(pow(ttank->y+0.2 - loc1[1], 2) + tankz*tankz)); atankvert = atan( (ttank->y+0.2 - loc1[1]) / tankz); } if (tankz < 0) atankvert += PI; tanky = rtankvert * sin(atankvert + vdiff); tankz = rtankvert * cos(atankvert + vdiff); itsDead = 0; switch(ttank->type){ case TANK: case LAUNCHER: case MASERTANK: if ((fabs(ttank->z - loc3[2]) <= BEAMKILL) && (fabs(ttank->y - loc3[1]) <= 0.3) && (fabs(ttank->x - loc3[0]) <= BEAMKILL)) itsDead = 1; break; case HELO: case CHH: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.15) && (fabs(tanky) < 0.15)) itsDead = 1; break; case AIRPLANE: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.50) && (fabs(tanky) < 0.40)) itsDead = 1; break; case FIGHTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30)) itsDead = 1; break; case MECHAG: if ((tankz >= 0) && (tankz <= (beamz+0.2)) && (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55)) itsDead = 1; break; case HERO: if ((tankz >= 0) && (tankz <= (beamz+0.2)) && (fabs(tankx) < 0.2) && (fabs(tanky) < 0.55)) itsDead = 1; break; default: showError("Bogus Vehicle in Tank List! (updateBeam)"); break; } if (itsDead) { ttank->damage -= 1; switch (ttank->type) { case TANK: case LAUNCHER: case MASERTANK: case AIRPLANE: case FIGHTER: case HELO: addScore(ttank->type, m); break; case MECHAG: addScore(PARTIALM, m); break; case CHH: addScore(PARTIALC, m); break; case HERO: addScore(PARTIALH, m); break; } if (ttank->damage <= 0) { /**********************************/ /* if so, slag it! */ /**********************************/ doSound(SLAG); ttank->damage = -99; } } temptank = temptank->next; } /***********************/ /* check other targets */ /***********************/ temptarget = t->next; while(temptarget != NULL) { if (temptarget->monster.monsterID != m->monsterID) { if ((temptarget->z - loc1[2]) == 0) loc1[2] += NEARZERO; rtankhorz = fabs(sqrt((pow(temptarget->x - loc1[0], 2) + pow(temptarget->z - loc1[2], 2)))); atankhorz = atan( (temptarget->x - loc1[0]) / (temptarget->z - loc1[2])); if ((temptarget->z - loc1[2]) < 0) atankhorz += PI; tankx = rtankhorz * sin(atankhorz + hdiff); tankz = rtankhorz * cos(atankhorz + hdiff); if (tankz == 0) tankz = NEARZERO; rtankvert = fabs(sqrt(pow(((temptarget->monster.height * 0.5 + temptarget->monster.bottom * 0.5) - loc1[1]), 2) + tankz*tankz)); atankvert = atan( ((temptarget->monster.height * 0.5 + temptarget->monster.bottom * 0.5) - loc1[1]) / tankz); if (tankz < 0) atankvert += PI; tanky = rtankvert * sin(atankvert + vdiff); tankz = rtankvert * cos(atankvert + vdiff); itsDead = 0; switch(temptarget->monster.monster){ case FLUTTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30)) itsDead = 1; break; case GOOGELON: case VAPOUR: case TECHS: if ((tankz >= 0) && (tankz <= (beamz+0.2)) && (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55)) itsDead = 1; break; default: showError("Bogus Monster in Target List! (updateBeam)"); break; } if (itsDead) { /* addScore(MONSTER, m); */ temptarget->monster.energyRemaining -= 1; } } temptarget = temptarget->next; } /**************************/ /* check player's monster */ /**************************/ if (g != m) { if ((0 - loc1[2]) == 0) loc1[2] += NEARZERO; rtankhorz = fabs(sqrt(loc1[0]*loc1[0] + loc1[2]*loc1[2])); atankhorz = atan( loc1[0] / loc1[2]); if (-loc1[2] < 0) atankhorz += PI; tankx = rtankhorz * sin(atankhorz + hdiff); tankz = rtankhorz * cos(atankhorz + hdiff); if (tankz == 0) tankz = NEARZERO; rtankvert = fabs(sqrt(pow(((g->height * 0.5 + g->bottom * 0.5) - loc1[1]), 2) + tankz*tankz)); atankvert = atan( ((g->height * 0.5 + g->bottom * 0.5) - loc1[1]) / tankz); if (tankz < 0) atankvert += PI; tanky = rtankvert * sin(atankvert + vdiff); tankz = rtankvert * cos(atankvert + vdiff); itsDead = 0; switch(g->monster){ case FLUTTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30)) itsDead = 1; break; case GOOGELON: case VAPOUR: case TECHS: if ((tankz >= 0) && (tankz <= (beamz+0.2)) && (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55)) itsDead = 1; break; default: showError("Bogus Monster in Target List! (updateBeam)"); break; } if (itsDead) { addScore(MONSTER, m); g->energyRemaining -= 1; } } /**********************************/ /* does beam touch a tree */ /**********************************/ for (i=0;iz - loc1[2]) == 0) loc1[2] += NEARZERO; rtankhorz = fabs(sqrt(pow(ttree->x - loc1[0], 2) + pow(ttree->z - loc1[2], 2))); atankhorz = atan( (ttree->x - loc1[0]) / (ttree->z - loc1[2])); if ((ttree->z - loc1[2]) < 0) atankhorz += PI; tankx = rtankhorz * sin(atankhorz + hdiff); tankz = rtankhorz * cos(atankhorz + hdiff); /* y of building is located on the plane*/ if (ttree->type == 1) switch(ttree->treeshape){ case 1: case 11: case 14: case 22: case 23: case 24: height = 0.8; break; case 5: case 6: case 13: case 28: case 31: case 32: height = 0.3; break; default: height = 0.5; break; } else height = 0.5; if (tankz == 0) tankz = NEARZERO; rtankvert = fabs(sqrt(pow(ttree->y + height - loc1[1], 2) + tankz * tankz)); atankvert = atan( (ttree->y + height - loc1[1]) / tankz); if (tankz < 0) atankvert += PI; tanky = rtankvert * sin(atankvert + vdiff); tankz = rtankvert * cos(atankvert + vdiff); if ((tankz >= 0) && (tankz <= (beamz + 0.2)) && (fabs(tankx) < 0.4) && (fabs(tanky) < height)) { if ((ttree->intact) && (ttree->type == 1)) addScore(BUILDING, m); ttree->intact = 0; } } } /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ /* decide whether a vehicle has been hit */ /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ int tankHit(struct tank * ttank, float xloc, float yloc, float zloc) { float blastx, blasty, blastz; switch(ttank->type){ case TANK: case LAUNCHER: case MASERTANK: blastx = blasty = blastz = BLASTRX05; break; case HELO: blastx = blastz = BLASTRX075; blasty = BLASTRX07; break; case AIRPLANE: blastx = blastz = BLASTR; blasty = BLASTRX07; break; case FIGHTER: blastx = blastz = BLASTR; blasty = BLASTRX05; break; case CHH: blastx = blastz = BLASTRX06; blasty = BLASTRX04; break; case MECHAG: blastx = blastz = BLASTR; blasty = BLASTRX2; break; case HERO: blastx = blastz = BLASTRX04; blasty = BLASTRX2; break; default: showError("Bogus Vehicle in Tank List! (tankHit)"); break; } if ((fabs(ttank->x - xloc) < blastx) && (fabs(ttank->z - zloc) < blastz) && (fabs(ttank->y - yloc) < blasty)) return(1); else return(0); }