
/*
 * Copyright (c) 1991    Jon Wesener 
 * Gaming Software
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation.  No representations are made about the
 * suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 *
 */

#ident	"@(#)shell.c	1.6 :/usr/key/jojow/X/src/guts/SCCS/s.shell.c 3/19/91 10:16:16 "

/* shell.c - routines for handling shells */

#include "server.h"


checkshells()
{
	register shell_t *sp;
	shell_t *sr;

	for( sp = Svalid ; sp ; sp = sr ) {

		sr = sp->s_next;

		/* is it time to move the shell */
		if( ++(sp->s_pri) < SHELLPRI )
			continue;

		sp->s_pri = 0;

		moveshell(sp);
		Servstate |= SSCUDFRC;
	}
}


static int xmv[] = {0,1,0,-1};
static int ymv[] = {-1,0,1,0};

moveshell(sp)
	register shell_t *sp;
{
	int nx, ny;
	int dead = 0;
	tank_t *tp;


	nx = sp->s_x + xmv[sp->s_dir];
	ny = sp->s_y + ymv[sp->s_dir];
		
	/* check new position */
	if( field[nx][ny] == FWALL )
		dead = 1;
	else if( field[nx][ny] == FTANK ) {

		tp = (tank_t *)fpts[nx][ny];
		if( !TANKSAFE(tp) ) {
			dead = 1;
			explode(tp,sp->s_own,Shelldmg,nx,ny);
		}
	}

	if( !dead ) {
		sp->s_x = nx;
		sp->s_y = ny;
	}
	/* shell gone? */
	else {
		shell_t *sr;


		/* remove from active list */
		if( Svalid == sp )
			Svalid = sp->s_next;
		else {
			for( sr = Svalid ; sr->s_next != sp ; sr = sr->s_next );
			sr->s_next = sp->s_next;
		}

		/* put it back on the free list */
		sp->s_next = Sfree;
		sp->s_own->t_shellf--;
		Sfree = sp;
	}
}


fire_shell(tp)
	register tank_t *tp;
{
	shell_t *sp;


	/* any shells to fire? */
	if(  tp->t_energy < Shellcost )
		return;

	tp->t_energy -= Shellcost;
	Totenergy += Shellcost;
	tp->t_shellf++;

	sp = Sfree;
	Sfree = sp->s_next;

	sp->s_x = tp->t_x;
	sp->s_y = tp->t_y;
	sp->s_dir = tp->t_dir;
	sp->s_pri = 0;
	sp->s_own = tp;

	sp->s_next = Svalid;
	Svalid = sp;
}


rm_shells(tp)
	tank_t *tp;
{
	shell_t *sp, *sr, *sn;
	
	/* remove all the mines belonging to tp */
	for( sp = Svalid ; sp ; sp = sn ) {

		sn = sp->s_next;

		if( sp->s_own != tp )
			continue;

		/* kill it */
		if( Svalid == sp )
			Svalid = sp->s_next;
		else {
			for( sr = Svalid ; sr->s_next != sp ; sr = sr->s_next );
			sr->s_next = sp->s_next;
		}

		sp->s_next = Sfree;
		Sfree = sp;
	}
}


shelldest()
{
	register shell_t *sp, *sr;


	/* Walk down the list and remove them */
	for( sr = sp = Svalid ; sp ; sp = sp->s_next ) {
		sr = sp;

		sp->s_own->t_shellf--;
	}

	if( Svalid ) {
		sr->s_next = Sfree;
		Sfree = Svalid;
		Svalid = NULL;
	}
}

/* Lint Output
*/
