
/*
 * 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	"@(#)tank.c	1.11 :/usr/key/jojow/X/src/guts/SCCS/s.tank.c 3/19/91 10:16:20 "

/* tank.c - routines for handling tanks */

#include "server.h"


checktanks()
{
	register tank_t *tp, *tr;

	for( tp = Tvalid ; tp ; tp = tr ) {

		tr = tp->t_next;

		/* wait to enter */
		if( (tp->t_state & TEXP) ) {
			if( --(tp->t_wait) )
				continue;
			tp->t_state &= ~TEXP;
		}

		/* check for dropped players */
		if( tp->t_state & THRTBEAT )
			tp->t_hbmiss = 0;

		else if( ++(tp->t_hbmiss) > MAXHBMISS ){
			(void)printf("recompute: dropping player %s\n",tp->t_name);
			(void)sprintf(tp->t_msgb,"i%c",tp->t_id+'0');
			(void)texit_1(&tp->t_msg);
			continue;
		}
		
		tp->t_state &= ~THRTBEAT;

		/* turn off safety period */
		if( tp->t_state & (TSAFE | TCLOAK) ) {
			Servstate |= SSCUDFRC;
			if( !(--(tp->t_safe)) ) 
				tp->t_state &= ~TSAFE;
		}

		/* regenerate damage */
		if( ++(tp->t_regpri) >= Regenpri ) {
			if( (tp->t_damage < Tdamage) && 
				(tp->t_damage += Regenamt) > Tdamage )
				tp->t_damage = Tdamage;
			tp->t_regpri = 0;
		}

		/* is it time to move the tank */
		if( ++(tp->t_pri) < TANKPRI )
			continue;

		tp->t_pri = 0;

		if( movetank(tp) )
			Servstate |= SSCUDFRC;
	}
}


movetank(tp)
	register tank_t *tp;
{
	int nx, ny, cmd;
	int ox, oy;

	
	/* time to cloak? */
	if( tp->t_state & TCLOAK ) {
		if( tp->t_energy > Cloakcost ) {
			tp->t_energy -= Cloakcost;
			Totenergy += Cloakcost;
		}
		else
			tp->t_state &= ~TCLOAK;
		Servstate |= SSCUDFRC;
	}

	ox = nx = tp->t_x;
	oy = ny = tp->t_y;

	cmd = tp->t_cmd;
	tp->t_cmd = 0;
	switch (cmd) {
		case 'h':
			if( tp->t_dir != 3) {
				tp->t_dir = 3;
				return 1;
			}
			nx--;
			break;
		case 'j':
			if( tp->t_dir != 2) {
				tp->t_dir = 2;
				return 1;
			}
			ny++;
			break;
		case 'k':
			if( tp->t_dir != 0) {
				tp->t_dir = 0;
				return 1;
			}
			ny--;
			break;
		case 'l':
			if( tp->t_dir != 1) {
				tp->t_dir = 1;
				return 1;
			}
			nx++;
			break;
		case 'f':
		case ' ':
			tp->t_state &= ~TCLOAK;
			if( !TANKSAFE(tp) && (tp->t_shellf < MAXSHELLF) )
				fire_shell(tp);
			return 0;
		case 'd':
			if( !TANKSAFE(tp) && (tp->t_minef < MAXMINEF) )
				arm_mine(tp);
			return 0;
		case 's':
			tp->t_state &= ~TCLOAK;
			if( !TANKSAFE(tp) && (tp->t_heatf < MAXHEATF) )
				fire_heat(tp);
			return 0;
		case 'c':
			if( !(tp->t_state & TSAFE) )
				cloak_mode(tp);
			return 0;
		case 0 :
			return 0;
		default:
			(void)printf("invalid command %c - %d\n",cmd,cmd);
			return 0;
	}

	/* check out the new position */
	switch( (int)field[nx][ny] ) {

nowspace:
		/* no problem! */
		case FSPACE:
			if( !(tp->t_state & TEXP) ) {
				field[nx][ny] = FTANK;
				fpts[nx][ny] = (void *)tp;
				tp->t_x = nx;
				tp->t_y = ny;
			}
			field[ox][oy] = FSPACE;
			fpts[ox][oy] = NULL;


			if( tp->t_state & TMINE )
				drop_mine(tp,ox,oy);

			return 1;

		/* toe poppers */
		case FMINE:
			mineblow(tp,(mine_t *)fpts[nx][ny],nx,ny);
			goto nowspace;

		/* power pellet */
		case FPOW: 
			powblow(tp,(pow_t *)fpts[nx][ny],nx,ny);
			goto nowspace;

		case FBON: 
			bonblow(tp,(bon_t *)fpts[nx][ny],nx,ny);
			goto nowspace;

		/* Don't move */
		default:
			return 0;
	}
}


place_tank(tp)
	tank_t *tp;
{
	int x, y;

	do {
		x = random() % MAZE_XL;
		y = random() % MAZE_YL;
	} while( field[x][y] != FSPACE );

	tp->t_x = x;
	tp->t_y = y;
	field[x][y] = FTANK;
	fpts[x][y] = (void *)tp;
}


cloak_mode(tp)
	tank_t *tp;
{
	/* turn it on or off? */
	if( tp->t_state & TCLOAK) {
		tp->t_state &= ~TCLOAK;
		return;
	}

	/* enough energy for the drain? */
	if( tp->t_energy < Cloakcost )
		return;

	tp->t_energy -= Cloakcost;
	Totenergy += Cloakcost;
	tp->t_state |= TCLOAK;

	Servstate |= SSCUDFRC;
}

tank_reset(tp,delay)
	tank_t *tp;
	int delay;
{
	if( tp->t_state & TMINE )
		tp->t_minef--;

	tp->t_state = TVALID | TSAFE;

	if( delay ) {
		tp->t_state |= TEXP;
		tp->t_wait = delay;
	}

	tp->t_safe = TSAFECNT;
	tp->t_pri = 0;

	tp->t_energy = Tenergy;
	tp->t_damage = Tdamage;
	Totenergy -= Tenergy;
}


tank_cleanup(tp)
	tank_t *tp;
{
	/* remove mines */
	rm_mines(tp);

	/* remove shells */
	rm_shells(tp);

	/* remove heats */
	rm_heats(tp);
}


tankdest(tp)
	tank_t *tp;
{
	register tank_t *tr;

	for( tr = Tvalid ; tr ; tr = tr->t_next ) {
		if( tr != tp )
			explode(tr,tp,tr->t_damage+1,tr->t_x,tr->t_y);
	}
}

/* Lint Output
*/
