#include "c_includ.h" /* * c_explode.c * Todd W Mummert, CMU, January 1991 * * This is an attempt at cleaning up the explosion routines. Why is this * not the same as the drawing routines? probably should be, but because * of the way pieces explode, the equations are more complex. Rather * than slow down the draw routines, we just have a similiar, but * different, set of equations here. */ /* * the standard routine for exploding pieces, which will not take * into account rotating objects. */ void calcpointsV(dc, method, index, g, pl) DCp dc; Methodp method; int index; Genericp g, pl; { int i; float dx, dy, dz, xn, yn, zn, cn, sn, cp, sp, rx, ry, rz, prx, pry, prz; Coord2dp new; Coord3dp old; old = dc->s->object+index; new = dc->points+index; dx = pl->x - g->x - dc->pos.x; dy = pl->y - g->y - dc->pos.y; dz = - dc->pos.z; xn = dx*dc->cta + dy*dc->sta; yn = -dx*dc->sta*dc->ctp + dy*dc->cta*dc->ctp + dz*dc->stp; zn = dx*dc->sta*dc->stp - dy*dc->cta*dc->stp + dz*dc->ctp; cn = pl->ca*dc->cta + pl->sa*dc->sta; sn = pl->sa*dc->cta - pl->ca*dc->sta; cp = dc->ctp; sp = -dc->stp; for (i=0; inum; i++, old++, new++) { rx = old->x - xn; ry = old->y - yn; rz = old->z - zn; prx = rx*cn + ry*sn*cp + rz*sn*sp; pry = -rx*sn + ry*cn*cp + rz*cn*sp; if (pry < 10.0) pry = 10.0; prz = -ry*sp + rz*cp; new->x = 500 + prx / pry * 450; new->y = 260 - prz / pry * 450; } } /* * the routine that is used for drawing the exploding * copter blade. */ void calcpointsVI(dc, method, index, g, pl) DCp dc; Methodp method; int index; Genericp g, pl; { int i; float dx, dy, dz, xn, yn, zn, c1, s1, c2, s2, cp, sp; float t1, t2, t3, t4, t5, t6, t7, t8, t9, rx, ry, rz, prx, pry, prz; Coord2dp new; Coord3dp old; old = dc->s->object+index; new = dc->points+index; dx = pl->x - g->x - dc->pos.x; dy = pl->y - g->y - dc->pos.y; dz = - dc->pos.z; xn = dx*dc->cta + dy*dc->sta*dc->ctp + dz*dc->sta*dc->stp; yn = -dx*dc->sta + dy*dc->cta*dc->ctp + dz*dc->cta*dc->stp; zn = -dy*dc->stp + dz*dc->ctp; c1 = pl->ca*dc->cta; s1 = pl->sa*dc->sta; c2 = pl->ca*dc->sta; s2 = pl->sa*dc->cta; cp = dc->ctp; sp = dc->stp; t1 = c1 + s1 * cp; t2 = -c2 + s2 * cp; t3 = -pl->sa * sp; t4 = -s2 + c2 * cp; t5 = s1 + c1 * cp; t6 = -pl->ca * sp; t7 = dc->sta * sp; t8 = dc->cta * sp; t9 = cp; for (i=0; inum; i++, old++, new++) { rx = old->x - xn; ry = old->y - yn; rz = old->z - zn; prx = rx * t1 + ry * t2 + rz * t3; pry = rx * t4 + ry * t5 + rz * t6; prz = rx * t7 + ry * t8 + rz * t9; if (pry < 10.0) pry = 10.0; new->x = 500 + prx / pry * 450; new->y = 260 - prz / pry * 450; } } void explodeobject(g, pl) Genericp g, pl; { static float vars0[] = { 0.996195, 0.087156, 0.996195, 0.087156}; static float vars1[] = { 0.996195, -0.087156, 0.996195, -0.087156}; static float vars2[] = { 0.819152, 0.573576, 0.996195, 0.087156}; static Coord3d tank0[] = { 30, -53, -15, 35, -60, 15, 35, 60, -5, 30, 37, -15, -30, 37, -15, -35, 60, -5, -35, -60, 15, -30, -53, -15, 30, -53, -15, 30, 37, -15, 35, -60, 15, -35, -60, 15, 35, 60, -5, -35, 60, -5, -30, -53, -15, -30, 37, -15}; static int tank0pnum[] = {10, 0}; static int tank0mnum[] = {6, 0}; static Method tank0methods[] = {16, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d tank1[] = { -10, -50, 10, -10, -18, 10, 10, -18, 10, 10, -50, 10, 25, -55, -11, 25, 55, -20, 10, -18, 10, -10, -18, 10, -25, 55, -20, -25, -55, -11, -10, -50, 10, 10, -50, 10}; static int tank1pnum[] = {12, 0}; static int tank1mnum[] = {0}; static Method tank1methods[] = {12, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d tank2[] = { -3, 28, -3, 3, 28, -3, 3, 28, 3, -3, 28, 3, -3, 28, -3, 3, -28, 3, 3, 28, 3, -3, -28, 3, -3, 28, 3, -3, -13, -3, -3, 28, -3, 3, -13, -3, 3, 28, -3}; static int tank2pnum[] = {5, 0}; static int tank2mnum[] = {8, 0}; static Method tank2methods[] = {13, calcpointsV, NULL, 0, NULL, NULL}; static StaticDC tankstaticdcs[] = { tank0, tank0pnum, tank0mnum, tank0methods, COLOR_TANK, tank1, tank1pnum, tank1mnum, tank1methods, COLOR_TANK, tank2, tank2pnum, tank2mnum, tank2methods, COLOR_TANK}; static float* tankvars[] = {vars0, vars0, vars1}; static float tankyoffsets[] = {0.0, 5.0, 32.0}; static float tankzoffsets[] = {-25.0, 0.0, 0.0}; static Coord3d super0[] = { 15, 60, -15, 30, -60, -15, 30, -60, 19, 15, 60, -15, -15, 60, -15, -30, -60, -15, -30, -60, 19, -15, 60, -15, -30, -60, 19, 30, -60, 19, -30, -60, -15, 30, -60, -15}; static int super0pnum[] = {8, 0}; static int super0mnum[] = {4, 0}; static Method super0methods[] = {12, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d super1[] = { 0, 47, -18, 13, -48, 9, 11, -48, 19, 11, -13, 19, 0, 47, -18, -13, -48, 9, -11, -48, 19, -11, -13, 19, 0, 47, -18, 11, -48, 19, -11, -48, 19, 11, -13, 19, -11, -13, 19}; static int super1pnum[] = {9, 0}; static int super1mnum[] = {4, 0}; static Method super1methods[] = {13, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d super2[] = { 3, -36, 0, 3, 36, 0, -3, -36, 0, -3, 36, 0, 3, -27, -6, 3, 36, -6, -3, -27, -6, -3, 36, -6, 3, 36, -6, 3, 36, 0, -3, 36, 0, -3, 36, -6, 3, 36, -6}; static int super2pnum[] = {4, 0}; static int super2mnum[] = {5, 0}; static Method super2methods[] = {9, calcpointsV, NULL, 0, NULL, NULL}; static StaticDC superstaticdcs[] = { super0, super0pnum, super0mnum, super0methods, COLOR_SUPER, super1, super1pnum, super1mnum, super1methods, COLOR_SUPER, super2, super2pnum, super2mnum, super2methods, COLOR_SUPER}; static float superyoffsets[] = {0.0, -12.0, 19.0}; static float superzoffsets[] = {-25.0, -15.0, 0.0}; static Coord3d missile0[] = { 15, -30, -25, 25, -30, 0, 0, -45, 0, 15, -30, -25, -15, -30, -25, 0, -45, 0, 15, -30, 25, -15, -30, 25, 0, -45, 0, -25, -30, 0, -15, -30, 25}; static int missile0pnum[] = {11, 0}; static int missile0mnum[] = {0}; static Method missile0methods[] = {11, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d missile1[] = { 15, -30, -25, 0, 50, 0, 25, -30, 0, 15, -30, 25, 0, 50, 0, -15, -30, -25, -25, -30, 0, 0, 50, 0, -15, -30, 25}; static int missile1pnum[] = {9, 0}; static int missile1mnum[] = {0}; static Method missile1methods[] = {9, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d missile2[] = { 13, -17, 11, 15, -30, 5, 23, -38, -10, 23, 0, -10, 13, -17, 11}; static int missile2pnum[] = {5, 0}; static int missile2mnum[] = {0}; static Method missile2methods[] = {5, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d missile3[] = { -13, -17, 11, -15, -30, 5, -23, -38, -10, -23, 0, -10, -13, -17, 11}; static int missile3pnum[] = {5, 0}; static int missile3mnum[] = {0}; static Method missile3methods[] = {5, calcpointsV, NULL, 0, NULL, NULL}; static StaticDC missilestaticdcs[] = { missile0, missile0pnum, missile0mnum, missile0methods, COLOR_MISSILE, missile1, missile1pnum, missile1mnum, missile1methods, COLOR_MISSILE, missile2, missile2pnum, missile2mnum, missile2methods, COLOR_MISSILE, missile3, missile3pnum, missile3mnum, missile3methods, COLOR_MISSILE}; static float* missilevars[] = {vars0, vars0, vars1, vars1}; static float missileyoffsets[] = {0.0, 0.0, 0.0, 0.0}; static float missilezoffsets[] = {0.0, 0.0, -30.0, -30.0}; static Coord3d copter0[] = { 6, 100, 0, 6, 100, 0, -6, -100, 0, 6, -100, 0, -6, 100, 0, 6, 100, 0}; static int copter0pnum[] = {6, 0}; static int copter0mnum[] = {0}; static Method copter0methods[] = {6, calcpointsVI, NULL, 0, NULL, NULL}; static Coord3d copter1[] = { 0, -32, -10, 7, 52, -34, 10, 48, -14, 0, -34, 0, 0, -52, 28, 0, -62, 28, 0, -48, -10, 0, -32, -10, -7, 52, -34, -10, 48, -14, 0, -34, 0}; static int copter1pnum[] = {11, 0}; static int copter1mnum[] = {0}; static Method copter1methods[] = {11, calcpointsV, NULL, 0, NULL, NULL}; static Coord3d copter2[] = { -14, 34, -34, 14, 34, -34, 0, 60, -14, -14, 34, -34, -7, -30, -34, 7, -30, -34, 14, 34, -34, 26, 34, -14, 0, 60, -14, -26, 34, -14, -10, -34, -14, 10, -34, -14, 26, 34, -14, 4, 20, 16, 0, 22, 16, -4, 20, 16, -4, -22, 16, 4, -22, 16, 4, 20, 16, -10, -34, -14, -4, -22, 16, 10, -34, -14, 4, -22, 16, 0, 22, 16, 0, 60, -14, -14, 34, -34, -26, 34, -14, -26, 34, -14, -4, 20, 16}; static int copter2pnum[] = {19, 0}; static int copter2mnum[] = {10, 0}; static Method copter2methods[] = {29, calcpointsV, NULL, 0, NULL, NULL}; static StaticDC copterstaticdcs[] = { copter0, copter0pnum, copter0mnum, copter0methods, COLOR_COPTER, copter1, copter1pnum, copter1mnum, copter1methods, COLOR_COPTER, copter2, copter2pnum, copter2mnum, copter2methods, COLOR_COPTER}; static float* coptervars[] = {vars2, vars0, vars1}; static float copteryoffsets[] = {0.0, -82.0, 0.0}; static float copterzoffsets[] = {30.0, 0.0, 0.0}; static StaticDCp staticdcs[] = { NULL, NULL, tankstaticdcs, superstaticdcs, missilestaticdcs, copterstaticdcs}; static float* yoffsets[] = { NULL, NULL, tankyoffsets, superyoffsets, missileyoffsets, copteryoffsets}; static float* zoffsets[] = { NULL, NULL, tankzoffsets, superzoffsets, missilezoffsets, copterzoffsets}; static float* *vars[] = { NULL, NULL, tankvars, tankvars, missilevars, coptervars}; static int pieces[] = {0, 0, 3, 3, 4, 3}; static float gravity = 1.0; int color, i, j, p; DCp dc; Methodp methods; float yoffset, dx, dy, temp; static int threshold = 0.8; Float2d pro; float* v; if (g->type == IS_LANDER) { if (g->attr & EXERASE || g->ecount >= 40) { g->dc[0].seen = False; drawobject(g, pl); g->attr = 0; return; } /* lander just blinks on every */ if (g->dc[0].seen && g->ccount%3) /* 3rd cycle */ g->dc[0].seen = False; else g->ccount = 0; drawobject(g, pl); g->ccount++; return; } p = pieces[g->lntype]; gprsetdrawvalue(opt->cpi[COLOR_BG]); for (i=0; idc[i]; if (dc->last) displayobject(dc); } if (g->attr & EXERASE || g->ecount >= 40) { g->attr = 0; return; } if (!(g->attr & HAS_DC)) { g->attr |= HAS_DC; for (i=0; idc[i]; dc->s = staticdcs[g->lntype]+i; switch (g->type) { case IS_CUBE: case IS_PYRAMID: case IS_LANDER: case IS_MISSILE: case IS_COPTER: case IS_SUPER: case IS_TANK: dc->fades = opt->fading_colors - 1; dc->basecolor = dc->s->basecolor; break; case IS_SALVO: dc->fades = False; if (g->salvo == pl) dc->basecolor = COLOR_PSALVO; else dc->basecolor = COLOR_ESALVO; break; } dc->cta = g->ca; dc->sta = g->sa; dc->ctp = 1.0; dc->stp = 0.0; yoffset = *(yoffsets[g->lntype]+i); dc->pos.x = -yoffset * g->sa; dc->pos.y = yoffset * g->sa; dc->pos.z = g->z + *(zoffsets[g->lntype]+i); dc->vel.x = frand() * 20.0 - 10.0; dc->vel.y = frand() * 20.0 - 10.0; dc->vel.z = 12.5 + frand() * 7.5; } if (g->type == IS_COPTER) g->dc[0].vel.z += 6.0; } for (i=0; idc[i]; dx = g->x + dc->pos.x - pl->x; dy = g->y + dc->pos.y - pl->y; if (sqrt(dx*dx + dy*dy) < 2000.0) { if (dc->fades) { color = g->range/OUT_OF_DRAWING_RANGE * opt->fading_colors; if (color >= opt->fading_colors) color = opt->fading_colors-1; } else color = 0; gprsetdrawvalue(color + opt->cpi[dc->basecolor]); pro.x = dx * pl->ca + dy * pl->sa; pro.y = -dx * pl->sa + dy * pl->ca; if (pro.y/fabs(pro.x+1) > threshold) { methods = dc->s->methods; for (j=0; methods->num; methods++) { methods->calc(dc, methods, j, g, pl); j += methods->num; } displayobject(dc); dc->last = True; } else dc->last = False; } else dc->last = False; dc->pos.x += dc->vel.x; dc->pos.y += dc->vel.y; dc->vel.z -= gravity; dc->pos.z += dc->vel.z; if (dc->pos.z < -40.0) { dc->pos.z = -40.0; dc->vel.z *= -0.2; } v = vars[g->lntype][i]; temp = dc->cta; dc->cta = dc->cta*v[0] - dc->sta*v[1]; dc->sta = dc->sta*v[0] + temp*v[1]; temp = dc->ctp; dc->ctp = dc->ctp*v[2] - dc->stp*v[3]; dc->stp = dc->stp*v[2] + temp*v[3]; } } void explodesalvo (g, pl) Genericp g; Genericp pl; { float mrx[5], mry[5]; float mrz[5], xmoff[5], ymoff[5], zmoff[5]; static float gravity = 1.0; int i, j; Coord2dp point, first; if (g->dc[0].last) { gprsetdrawvalue(opt->cpi[COLOR_BG]); multiline(g->dc[0].points, 5); } if (g->attr & EXERASE || g->ecount >= 20) { g->attr = 0; return; } if (g->attr & IS_NEW) { g->ccount = 0; g->attr &= ~IS_NEW; for (j=0; j<5; j++) { g->dc[j].vel.x = frand() * 20.0 - 10.0; g->dc[j].vel.y = frand() * 20.0 - 10.0; g->dc[j].vel.z = -7.5 - frand() * 5.0; g->dc[j].pos.x = 0.0; g->dc[j].pos.y = 0.0; g->dc[j].pos.z = 0.0; } } if (g->dc[0].seen) { if (g->salvo == pl) gprsetdrawvalue(opt->cpi[COLOR_PSALVO]); else gprsetdrawvalue(opt->cpi[COLOR_ESALVO]); for (i=0; i<5; i++) { g->dc[i].pos.x += g->dc[i].vel.x; g->dc[i].pos.y += g->dc[i].vel.y; g->dc[i].vel.z += gravity; g->dc[i].pos.z -= g->dc[i].vel.z; } point = g->dc[0].points; for (i=0; i<5; i++) { xmoff[i] = g->dc[i].pos.x + g->x - pl->x; ymoff[i] = g->dc[i].pos.y + g->y - pl->y; zmoff[i] = g->dc[i].pos.z; mrx[i] = xmoff[i] * pl->ca + ymoff[i] * pl->sa; mry[i] = -xmoff[i] * pl->sa + ymoff[i] * pl->ca; mrz[i] = zmoff[i]; if (mry[i] < 10.0) mry[i] = 10.0; first = point++; point->x = first->x = 500 + mrx[i] / mry[i] * 450; first->y = 260 - mrz[i] / mry[i] * 450; point->y = first->y+2; point++; } multiline(g->dc[0].points, 5); g->dc[0].last = True; } else g->dc[0].last = False; g->ccount++; }