
struct bullet {
	atom *me;
	int life;
	bool drew;
	bool todraw;
	int side;
	int width;
	color c;

	bullet() {
		init();
	}

	void init() {
		me = NULL;
		life = -1;
		drew = false;
		todraw = true;
		width = 1;
		c = black;
	}

	void update() {
		if(me == NULL) return;
		me->iy -= GRAVITY;
		life--;
		//if(life < 1000 && change > 1.5 || (abs((int)me->ix) < .1 && abs((int)me->iy) < .1)) life = 0;
		if((fabs(me->ix) * me->rmdt < .5 && fabs(me->iy) * me->rmdt < .5)) life = 0;
		if(life <= 0) {
			destroyatom(me);
			me = NULL;
			life = -1;
		}
	}

	void draw() {
		if(!todraw || c.a == 0) return;

		if(width != 1 && 0) {
			int points[8];
			int p1x, p2x, p1y, p2y;
			float m = -me->ix / me->iy;
			float ox, oy, od;
			ox = 1; oy = m;
			od = sqrt(ox * ox + oy * oy);
			ox = ox / od;
			oy = oy / od;
			ox *= width * 0.5;
			oy *= width * 0.5;
			p1x = me->x;
			p1y = me->y;
			p2x = p1x - me->ix * 10 * me->rmdt;
			p2y = p1y - me->iy * 10 * me->rmdt;
			
			points[0] = p1x - ox;
			points[1] = p1y - oy;
			points[2] = p1x + ox;
			points[3] = p1y + oy;
			points[4] = p2x + ox;
			points[5] = p2y + oy;
			points[6] = p2x - ox;
			points[7] = p2y - oy;

			polygon(buf, 4, points, c);
			line(buf, points[0], points[1], points[2], points[3], black);
			line(buf, points[2], points[3], points[4], points[5], black);
			line(buf, points[4], points[5], points[6], points[7], black);
			line(buf, points[6], points[7], points[0], points[1], black);
			drew = true;
		}
		else {
			//float m = me->iy / me->ix;
			float p1x, p2x, p1y, p2y, p3x, p3y;
			p1x = me->x;
			p1y = me->y;
			p2x = p1x - me->ix * 2;
			p2y = p1y - me->iy * 2;
			p3x = p1x - me->ix * 6;
			p3y = p1y - me->iy * 6;
			if((p1x > lx && p1x < rx) || (p2x > lx && p2x < rx)) {
				glLineWidth(width);
				if(side == 0) {
					glColor4f(0.2,0.2,0.2,0.8);
					glBegin(GL_LINES);
						glVertex2f(p1x, p1y);
						glVertex2f(p2x, p2y);
						glColor4f(0.3,0.8,0.3,1);
						glVertex2f(p2x, p2y);
						glVertex2f(p3x, p3y);
					glEnd();
				}
				else {
					glColor4f(0.2,0.2,0.2,0.8);
					glBegin(GL_LINES);
						glVertex2f(p1x, p1y);
						glVertex2f(p2x, p2y);
						glColor4f(1.0,0.3,0.3,1);
						glVertex2f(p2x, p2y);
						glVertex2f(p3x, p3y);
					glEnd();
				}

				//line(buf, p1x, p1y, p2x, p2y, color);
				drew = true;
			}
		}
	}

	void erase() {
		if(!todraw) return;
		if(width == 1) {
			//float m = me->iy / me->ix;
			if(!drew) return;
			int p1x, p2x, p1y, p2y;
			p1x = me->x;
			p1y = me->y;
			p2x = p1x - me->ix * 2;
			p2y = p1y - me->iy * 2;
			do_line(buf, p1x, p1y, p2x, p2y, 0, NULL);
			drew = false;
		}
		else {
			int p1x, p2x, p1y, p2y, nx, ny, nw, nh;
			p1x = me->x;
			p1y = me->y;
			p2x = p1x - me->ix * 4;
			p2y = p1y - me->iy * 4;
			nx = findlow(p1x, p2x) - 2 * width;
			ny = findlow(p1y, p2y) - 2 * width;
			nw = findhigh(p1x, p2x) - nx + 4 * width;
			nh = findhigh(p1y, p2y) - ny + 4 * width;
			blit(bg, buf, nx, ny, nx, ny, nw, nh);
		}			
	}
};

bullet bullets[MAXBULLETS];

void addanimation(ABITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand);

struct bomb {
	atom *me;
	ABITMAP *bmp;
	bool drew;
	bool on;
	bool dud;

	bomb() {
		init();
	}

	void init() {
		me = NULL;
		drew = false;
		on = false;
		dud = true;
	}

	void update() {
		if(!on) return;
		float cx, cy, cd;
		cx = me->ix - me->oix;
		cy = me->iy - me->oiy;

		cy -= GRAVITY;
		cd = sqrt(cx * cx + cy * cy);
		cd = fabs(cd);
		
		if(cd > 0.05) {
			bullet *b;
			on = false;
			float ang = 0;
			int py;
			float ca, sa;
			atom *a;
			int count = 0;

			py = path[(int)me->x];

			for(ang = 0; ang < 2*pi; ang += (2*pi) / 10) {
				count++;
				ca = cos(ang);
				sa = sin(ang);
				if(!dud) {
					b = addbullet(me->x, me->y, 20 * ca, 20 * sa, 3, 10, 20, 1, gray, false);
					if(b && b->me) {
						b->me->dmult = 100;
					}
					b = addbullet(me->x, me->y, 20 * ca, 20 * sa, 3, 30, 20, 1, nullcolor, true);
					if(b && b->me) {
						b->me->dmult = 100;
					}
				}
				if(me->y > py - 20) {
					cleartmplevels();
					a = addatom(me->x, py - 15, tmplevels, 0);
					a->ix = (rand() % 10 / 10.0) * ca;
					a->iy = (rand() % 10 / 10.0) * sa;
					a->bmp = create_bitmap_ex(32, 16, 16);
					blitopaque(grounddebris1, a->bmp, 0, 0, 0, 0, 16, 16);
					createtexture(a->bmp);
					adddebris(a, false);
				}
				if(count % 1 == 0) {
					tmplevels[1] = true;
					tmplevels[5] = true;
					a = addatom(me->x, me->y, tmplevels, 10);
					//a->ix = (rand() % 10 / 3.0) * ca;
					//a->iy = (rand() % 10 / 3.0) * sa;
					a->ix = 1.5 * ca;
					a->iy = 1.5 * sa;
					a->life = 40;
					a->draw = true;
					a->c = magenta;
					//a->bmp = create_bitmap(14, 14);
//void addtrailanim(atom *a, ABITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay);
					addtrailanim(a, explosionsmallanim, 24, 5, 0, 100, -2, 5, false, -3);
					//blit(bombdebris1, a->bmp, 0, 0, 0, 0, 14, 14);
					adddebris(a, false);
				}
			}
			addanimation(explosionanim, 16, me->x - 32, me->y + 37, true, 0, 1, 0);
			dopanvol(me->x, 0.1);
			play_sample(explode, vol, pan, 1000, 0);

			if(me->y > py - 5) {
				addscorch(me->x, 600 - me->y);
				/*
				ABITMAP *tmp;
				int py, pyr, nx;
				tmp = create_bitmap(60, 60);
				blit(bg, tmp, me->x - 27, me->y - 19, 0, 0, 60, 60);
				draw_trans_sprite(tmp, scorch, 0, 0);
				for(int xp = 0; xp < 60; xp++) {
					nx = (int)xp + (int)me->x - 27;
					if(nx > 0 && nx < buf->w - 1) {
						py = path[(int)xp + (int)me->x - 27] + 1;
						pyr = py - me->y + 20 + 1;
						blit(tmp, bg, xp, pyr, xp + me->x - 27, py, 1, 60 - pyr);
						blit(tmp, buf, xp, pyr, xp + me->x - 27, py, 1, 60 - pyr);
					}
					//blit(tmp, buf, xp, 0, xp + a->x - 27, a->y - 20, 1, path[(int)xp] - (a->y - 22));
				}
				destroy_bitmap(tmp);
				tmp = NULL;
				*/
			}

			destroyatom(me);
			me = NULL;
		}
	}

	void draw() {
		if(!on) return;
		if(me->x + 5 > lx && me->x - 5 < rx) {
			float angle;
			angle = atan2(me->iy, me->ix);
			angle *= convk4;
			float ox, oy;
			ox = 6.5;
			oy = 2.5;

			glPushMatrix();
			
			//13x5 bomb
			//14x7 missile
			if(bmp == bombbmp) {
				glTranslatef(me->x - 0, me->y - 0, 0);
				glRotatef(angle,0,0,1);
				glBindTexture(GL_TEXTURE_2D, bmp->texID);
				glBegin(GL_QUADS);
					glTexCoord2f(0, 0); glVertex2f(-ox, -oy);
					glTexCoord2f(1, 0); glVertex2f(ox, -oy);
					glTexCoord2f(1, 1); glVertex2f(ox, oy);
					glTexCoord2f(0, 1); glVertex2f(-ox, oy);
				glEnd();
			}
			else if(bmp == missilebmp || bmp == shell) {
				glTranslatef(me->x - 0, me->y - 0, 0);
				glRotatef(angle,0,0,1);
				glBindTexture(GL_TEXTURE_2D, bmp->texID);
				glBegin(GL_QUADS);
					glTexCoord2f(0, 0); glVertex2f(0, -oy);
					glTexCoord2f(1, 0); glVertex2f(2*ox, -oy);
					glTexCoord2f(1, 1); glVertex2f(2*ox, oy);
					glTexCoord2f(0, 1); glVertex2f(0, oy);
				glEnd();
			}
				
			glPopMatrix();

			/*
			if(bmp == bombbmp) rotate_sprite(buf, bmp, me->x - 5, me->y - 2, (angle));
			else pivot_sprite(buf, bmp, me->x, me->y, 0, 3, (angle));
			drew = true;
			*/
		}
	}

	void erase() {
		if(!on) return;
		if(!drew) return;
		drew = false;
		if(bmp == bombbmp) blit(bg, buf, me->x - 8, me->y - 8, me->x - 8, me->y - 8, 16, 16);
		else blit(bg, buf, me->x - 15, me->y - 15, me->x - 15, me->y - 15, 30, 30);
	}
};

bomb bombs[MAXBOMBS];
int numbombs;

void createexplosion(float x, float y) {
	bullet *b;
	float ang = 0;
	int py;
	float ca, sa;
	atom *a;
	int count = 0;

	py = path[(int)x];

	for(ang = 0; ang < 2*pi; ang += (2*pi) / 10) {
		count++;
		ca = cos(ang);
		sa = sin(ang);
		b = addbullet(x, y, 20 * ca, 20 * sa, 3, 10, 20, 1, gray, false);
		if(b && b->me) {
			b->me->dmult = 100;
		}
		b = addbullet(x, y, 20 * ca, 20 * sa, 3, 30, 20, 1, nullcolor, true);
		if(b && b->me) {
			b->me->dmult = 100;
		}
		if(y > py - 20) {
			cleartmplevels();
			a = addatom(x, py - 15, tmplevels, 0);
			a->ix = (rand() % 10 / 10.0) * ca;
			a->iy = (rand() % 10 / 10.0) * sa;
			a->bmp = create_bitmap_ex(32, 16, 16);
			blitopaque(grounddebris1, a->bmp, 0, 0, 0, 0, 16, 16);
			createtexture(a->bmp);
			adddebris(a, false);
		}
		if(count % 1 == 0) {
			tmplevels[1] = true;
			tmplevels[5] = true;
			a = addatom(x, y, tmplevels, 10);
			//a->ix = (rand() % 10 / 3.0) * ca;
			//a->iy = (rand() % 10 / 3.0) * sa;
			a->ix = 1.5 * ca;
			a->iy = 1.5 * sa;
			a->life = 40;
			a->draw = true;
			a->c = magenta;
			//a->bmp = create_bitmap(14, 14);
//void addtrailanim(atom *a, ABITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay);
			addtrailanim(a, explosionsmallanim, 24, 5, 0, 100, -2, 5, false, -3);
			//blit(bombdebris1, a->bmp, 0, 0, 0, 0, 14, 14);
			adddebris(a, false);
		}
	}
	addanimation(explosionanim, 16, x - 32, y + 37, true, 0, 1, 0);
	dopanvol(x, 0.1);
	play_sample(explode, vol, pan, 1000, 0);

	if(y > py - 5) {
		addscorch(x, 600 - y);
	}
}

bullet *addbullet(float x, float y, float ix, float iy, int comp, int life, float dmult, int width, color c, bool personnel) {
	bullet *b;
	int i;
	int level;

	settmplevels();

	if(personnel) {
		cleartmplevels();
		tmplevels[1] = true;
		tmplevels[5] = true;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;
		level = 10;
	}
	else if(comp == 0) {
		tmplevels[1] = false;
		tmplevels[3] = false;
		tmplevels[6] = false;
		tmplevels[7] = false;
		tmplevels[9] = false;
		tmplevels[11] = false;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;
		
	
		tmplevels[16] = false;
		tmplevels[17] = false;
		tmplevels[18] = false;
		tmplevels[19] = false;
		level = 3;
	}
	else if(comp == 1) {
		tmplevels[2] = false;
		tmplevels[3] = false;
		tmplevels[4] = false;
		tmplevels[5] = false;
		tmplevels[6] = false;
		tmplevels[9] = false;
		tmplevels[12] = false;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;
		
	
		tmplevels[16] = false;
		tmplevels[17] = false;
		tmplevels[18] = false;
		tmplevels[19] = false;
		level = 6;
	}
	else if(comp == 3) {
		tmplevels[9] = false;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;
		level = 9;
	}

	b = &(bullets[0]);
	for(i = 0; i < MAXBULLETS; i++) {
		if(b->life < 0) {
			b->life = life;
			b->me = addatom(x, y, tmplevels, level);
			if(comp != 3) {
				//ix *= 0.2;
				//iy *= 0.2;
			}
			b->me->ix = ix;
			b->me->iy = iy;
			b->me->dmult = dmult;
			b->width = width;
			b->todraw = true;
			b->c = c;
			b->side = comp;
			if(comp != 3) {
				b->me->rmdt = 1;
			}
			else {
				b->todraw = false;
				b->me->rmdt = 0.1;
			}
			return b;
			break;
		}
		b++;
	}
	return NULL;
}

bomb *addbomb(float x, float y, float ix, float iy, bool comp, ABITMAP *bmp, int bombtype) {
	bomb *b;
	int level;
	int i;
	bool dud;

	settmplevels();

	if(rand() % 3 == 0) dud = false;
	else dud = true;
	
	dud = false;

	if(dud) {
		cleartmplevels();
		level = 0;
	}
	else if(!comp) {
		tmplevels[1] = false;
		tmplevels[3] = false;
		tmplevels[6] = false;
		tmplevels[7] = false;
		tmplevels[9] = false;
		tmplevels[10] = false;
		tmplevels[11] = false;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;

		tmplevels[16] = false;
		tmplevels[17] = false;
		tmplevels[18] = false;
		tmplevels[19] = false;
		level = 13;
	}
	else {
		tmplevels[2] = false;
		tmplevels[3] = false;
		tmplevels[4] = false;
		tmplevels[5] = false;
		tmplevels[6] = false;
		tmplevels[7] = false;
		tmplevels[9] = false;
		tmplevels[10] = false;
		tmplevels[12] = false;
		tmplevels[13] = false;
		tmplevels[14] = false;
		tmplevels[16] = true;
		
		tmplevels[16] = false;
		tmplevels[17] = false;
		tmplevels[18] = false;
		tmplevels[19] = false;
		level = 14;
	}

	b = &(bombs[0]);
	i = 0;
	while(i < MAXBOMBS && b->on) {b++; i++;}
	if(i >= MAXBOMBS) return NULL;
	b->on = true;
	b->me = addatom(x, y, tmplevels, level);
	if(bombtype == MISSILE) b->me->mass = 0;
	b->me->ix = ix;
	b->me->iy = iy;
	b->me->oix = ix;
	if(bombtype == BOMB) b->me->oiy = iy + GRAVITY;
	else b->me->oiy = iy;
	b->me->rmdt = 1;
	b->bmp = bmp;
	b->dud = dud;
	if(b == &(bombs[numbombs]))
		numbombs++;
	return b;
}

struct animation {
	ABITMAP **frames;
	int aframe;
	int numframes;
	float x, y;
	bool on;
	bool drew;
	bool trans;
	int w, h;
	float dy;
	int delay;
	int randoff;
	bool particle;
	int parttype;
	int life;

	animation() {
		reset();
	}

	void reset() {
		aframe = 0;
		on = false;
		trans = false;
		delay = 1;
		parttype = 0;
	}

	void init(ABITMAP **newframes, int newnumframes, int newx, int newy, float newdy, int newdelay, int newrand) {
		frames = newframes;
		numframes = newnumframes;
		aframe = 0;
		x = newx;
		y = newy;
		w = frames[0]->w;
		h = frames[0]->h;
		on = true;
		dy = newdy;
		delay = newdelay;
		randoff = newrand;
		life = 0;
		particle = false;
	}

	void init(int newx, int newy, float newdy, int newparttype, int newrand) {
		aframe = 0;
		x = newx;
		y = newy;
		on = true;
		dy = newdy;
		delay = 1;
		randoff = newrand;
		parttype = newparttype;
		life = 0;
		particle = true;
	}

	void draw() {
		if(!on) return;
		if(aframe == numframes) {
			on = false;
		}
		else if(x + w > lx && x < rx) {
			drew = true;
			y += dy;
			if(dy != 0) {
				x += rand() % randoff * 0.1 - 0.05 * randoff;
				y += rand() % randoff * 0.1 - 0.05 * randoff;
			}

			if(!particle) {
				glColor3f(1.0,1.0,1.0);
				gldrawsprite(x, y, frames[aframe]);

				/*
				if(trans) draw_sprite(buf, frames[aframe], x, y);
				else draw_sprite(buf, frames[aframe], x, y);
				*/

				if(delay < 0) {
					aframe += -delay;
					if(aframe > numframes) aframe = numframes;
				}
				else if(delay == 1 || drawframe % delay == 0) {
					aframe++;
				}
			}
			else {
				if(parttype == 0) {
					glEnable(GL_TEXTURE_2D);
					//glBlendFunc(GL_SRC_ALPHA,GL_ONE);
					//glColor4f(1.0 - life*0.0001, 0.0 + life*0.01, 0.0 + life*0.01, 1.0 - life*0.01);

					glColor4f(1.0,life*0.005 + 0.5,life*0.005, 0.5 - life*0.00);

					//glColor4f(1.0,0.0,0.0,1.0);
					glBindTexture(GL_TEXTURE_2D, particlebmp->texID);
					glPushMatrix();
					glTranslatef(x, y, 0);
					glBegin(GL_QUADS);
						glTexCoord2f(0, 0); glVertex2f(-10, 10);
						glTexCoord2f(0, 1); glVertex2f(-10, -10);
						glTexCoord2f(1, 1); glVertex2f(10, -10);
						glTexCoord2f(1, 0); glVertex2f(10, 10);
					glEnd();
					glPopMatrix();

					//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

					//glPixelTransferf(GL_RED_BIAS, 0.5);
					//glPixelTransferf(GL_BLUE_SCALE, 0.5);
					//gldrawsprite(x, y, particlebmp);
					life++;
					if(life == 100)
						on = false;
					glDisable(GL_TEXTURE_2D);
					//glPixelTransferf(GL_RED_BIAS, 0.0);
					//glPixelTransferf(GL_BLUE_SCALE, 1.0);
				}
			}
		}
		else if(particle) {
			y += dy;
			life++;
			if(life == 100)
				on = false;
		}
		else if(delay == 1 || drawframe % delay == 0) {
			y += dy;
			aframe++;
		}
	}

	void erase() {
		if(!on || !drew) return;
		blit(bg, buf, x, y, x, y, w, h);
		drew = false;
	}
};

animation animations[MAXANIMATIONS];
int numanimations;

void addanimation(ABITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand) {
	animation *a;
	int i;
	a = &(animations[0]);
	i = 0;
	while(i < MAXANIMATIONS && a->on) {a++; i++;}
	if(i >= MAXANIMATIONS) return;
	a->init(newframes, newnumframes, newx, newy, dy, delay, rand);
	a->trans = trans;
	if(a == &(animations[numanimations]))
		numanimations++;
}

//addparticleanimation(me->x + rand() % (2 * randoff) - randoff - wot, me->y + rand() % (2 * randoff) - randoff + hot, parttype, dy, 1);

void addparticleanimation(int newx, int newy, int parttype, float dy, int rand) {
	animation *a;
	int i;
	a = &(animations[0]);
	i = 0;
	while(i < MAXANIMATIONS && a->on) {a++; i++;}
	if(i >= MAXANIMATIONS) return;
	a->init(newx, newy, dy, parttype, rand);
	if(a == &(animations[numanimations]))
		numanimations++;
}

void drawanimations() {
	animation *a;
	int i;

	a = &(animations[0]);
	for(i = 0; i < numanimations; i++) {
		a->draw();
		a++;
	}
}

void eraseanimations() {
	animation *a;
	int i;

	a = &(animations[0]);
	for(i = 0; i < numanimations; i++) {
		a->erase();
		a++;
	}
}

struct trailanim {
	int life;
	atom *me;
	int mod;
	int modoff;
	ABITMAP **anim;
	int animframes;
	float dy;
	int randoff;
	bool trans;
	int wot, hot;
	int delay;
	bool particle;
	int parttype;

	trailanim() {
		reset();
	}
	
	void reset() {
		life = 0;
		me = NULL;
		mod = 100;
		modoff = 0;
		anim = NULL;
		animframes = 0;
		trans = false;
		wot = 0;
		hot = 0;
	}

	void init(atom *newme, ABITMAP **newanim, int newanimframes, int newmod, int newmodoff, int newlife, float newdy, int newrandoff, bool newtrans, int newdelay) {
		me = newme;
		anim = newanim;
		animframes = newanimframes;
		mod = newmod;
		modoff = newmodoff;
		life = newlife;
		dy = newdy;
		randoff = newrandoff;
		trans = newtrans;
		wot = (newanim[0])->w * 0.5;
		hot = (newanim[0])->h * 0.5;
		delay = newdelay;
		particle = false;
	}

	void init(atom *newme, int newmod, int newmodoff, int newlife, float newdy, int newrandoff, int newparttype) {
		me = newme;
		mod = newmod;
		modoff = newmodoff;
		life = newlife;
		dy = newdy;
		randoff = newrandoff;
		parttype = newparttype;
		particle = true;
	}

	void update() {
		if(life <= 0) return;
		life--;
		if(me->on == false)
			life = 0;
		else {
			if((frame + modoff) % mod == 0) {
				//init(ABITMAP **newframes, int newnumframes, int newx, int newy, float newdy, int newdelay, int newrand) {
				if(!particle)
					addanimation(anim, animframes, me->x + rand() % (2 * randoff) - randoff - wot, me->y + rand() % (2 * randoff) - randoff + hot, trans, dy, delay, 1);
				else
					addparticleanimation(me->x + rand() % (2 * randoff) - randoff - wot, me->y + rand() % (2 * randoff) - randoff + hot, parttype, dy, 1);
			}
		}
	}
};

trailanim trailanims[MAXTRAILANIMS];
int numtrailanims;

void addtrailanim(atom *a, ABITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay) {
	trailanim *t;
	int i;
	t = &(trailanims[0]);
	i = 0;
	while(i < MAXTRAILANIMS && t->life > 0) {i++; t++;}
	if(i < MAXTRAILANIMS) {
		t->init(a, anim, frames, mod, modoff, life, dy, rand, trans, delay);
		if(t == &(trailanims[numtrailanims]))
			numtrailanims++;
	}
}

void addparticletrailanim(atom *a, int mod, int modoff, int life, float dy, int rand, int type) {
	trailanim *t;
	int i;
	t = &(trailanims[0]);
	i = 0;
	while(i < MAXTRAILANIMS && t->life > 0) {i++; t++;}
	if(i < MAXTRAILANIMS) {
		t->init(a, mod, modoff, life, dy, rand, type);
		if(t == &(trailanims[numtrailanims]))
			numtrailanims++;
	}
}

void updatetrailanims() {
	trailanim *a;
	int i;

	a = &(trailanims[0]);
	for(i = 0; i < numtrailanims; i++) {
		a->update();
		a++;
	}
}

void updatebombs() {
	bomb *b;
	int i;
	b = &(bombs[0]);
	for(i = 0; i < numbombs; i++) {
		if(b->on) {
			b->update();
		}
		b++;
	}
}

void drawbombs() {
	bomb *b;
	int i;
	b = &(bombs[0]);
	for(i = 0; i < numbombs; i++) {
		if(b->on) {
			b->draw();
		}
		b++;
	}
}

void erasebombs() {
	bomb *b;
	int i;
	b = &(bombs[0]);
	for(i = 0; i < numbombs; i++) {
		if(b->on) {
			b->erase();
		}
		b++;
	}
}

void drawbullets() {
	bullet *b;
	int i;
	b = &(bullets[0]);
	for(i = 0; i < MAXBULLETS; i++) {
		if(b->life > 0) {
			b->draw();
		}
		b++;
	}
}

void erasebullets() {
	bullet *b;
	int i;
	b = &(bullets[0]);
	for(i = 0; i < MAXBULLETS; i++) {
		if(b->life > 0) {
			b->erase();
		}
		b++;
	}
}
