/////////////////////////////////////////////////////////////////////

var video_mode = 7; // 800x600
var video_depth = 16; // 16 bit mode

////////////////////////////////////////////////////////////////////////////

sound tank_snd = <tankrun.wav>;
sound tankexplo_snd = <tankexplo.wav>;
sound turret_snd = <turret.wav>;
sound tankrocket_snd = <tankrocket.wav>;
sound beep_sound = <beep.wav>;

////////////////////////////////////////////////////////////////////////////

bmap tanksmoke_pcx = <tanksmoke.pcx>;

////////////////////////////////////////////////////////////////////////////

string level1_wmb = <level1.wmb>;

string challenger_turret = <chturret.mdl>;
string challenger_barrel = <chbarrel.mdl>;
string tank_rocket = <tankrock.mdl>;

string explosion_pcx = <explo+6.pcx>;

////////////////////////////////////////////////////////////////////////////

define shield skill20;

////////////////////////////////////////////////////////////////////////////

entity* procket_ptr; // player's rocket

////////////////////////////////////////////////////////////////////////////

var rocket_coords;
var player_speed;
var procket_speed; // rocket speed -> player's rocket
var erocket_speed; // rocket speed -> enemy rocket
var turret_offset;
var barrel_offset;
var enemy_speed;

var fall_speed = 0.9;

var engine_handle = 0; // sound handle for the tank
var turret_handle = 0; // sound handle for the turret

///////////////////////////////////////////////////////////////////////////

function attach_player_barrel();
function attach_player_turret();
function player_rocket();
function explode_rocket();
function tank_damaged();
function animate_explosion();
function tank_smoke();
function fade_smoke();
function enemy_rocket();

///////////////////////////////////////////////////////////////////////////

function main()
{
	clip_size = 0; // show all the triangles for all the models
	on_d = null; // disable the standard "debug" key
	level_load (level1_wmb);
}	

function attach_player_barrel() 
{
	proc_late(); // prevent shaking
	my.passable = on;
	my.metal = on;
	while(you) // as long as the creator exists
	{
		vec_set(my.x,you.x);
		my.pan = you.pan + turret_offset;
		my.tilt = you.tilt + barrel_offset;
   		my.frame = you.frame;
	   	my.next_frame = you.next_frame;
		vec_for_vertex(rocket_coords, my, 33); // vertex for player's rocket

		if (mouse_left == 1 && procket_ptr == null && player.shield > 0)
		// if we press the LMB and the previous rocket has disappeared and the tank isn't destroyed
		{
			ent_create (tank_rocket, rocket_coords, player_rocket); 
			snd_play (tankrocket_snd, 100, 0);
		}

   		wait(1);
	}
	ent_remove(my);
}

function attach_player_turret() 
{
	proc_late(); // prevent shaking
	my.passable = on;
	my.metal = on;
	while(you) // as long as the creator exists
	{
		vec_set(my.x, you.x);
		my.pan = you.pan + turret_offset;
   		my.frame = you.frame;
	   	my.next_frame = you.next_frame;
   		wait(1);
	}
	ent_remove(my);
}

action player_tank
{
	player = me;
	my.enable_impact = on;
	my.enable_entity = on;
	my.event = tank_damaged;
	ent_create(challenger_turret, nullvector, attach_player_turret); 
	ent_create(challenger_barrel, nullvector, attach_player_barrel); 
	my.shield = 250; // 250 shield points for player's tank
	while (my.shield > 0) // the 10th hit will destroy player's tank
	{
		camera.pan = my.pan;
		camera.x = my.x - 500 * cos (my.pan); // the camera is placed 500 quants behind the tank
		camera.y = my.y - 500 * sin (my.pan);
		camera.z = my.z + 300; // and 300 quants above the tank
		camera.tilt = -20; // the camera looks down

		if (mouse_force.x != 0) // if we move the mouse on x
		{
			if (turret_handle == 0)
			{
				turret_handle = snd_play (turret_snd, 70, 0);	
			}
			turret_offset -= 2 * mouse_force.x * time;
		}
		else
		{
			turret_handle = 0;
		}
		if (mouse_force.y != 0) // if we move the mouse on y
		{
			barrel_offset += 2 * mouse_force.y * time;
		}
		if (player_speed.x != 0) // if we are moving the tank
		{
			my.pan -= 0.1 * (key_d - key_a) * player_speed.x * time;
			if (engine_handle == 0) // if the engine sound isn't playing
			{
				engine_handle = snd_loop (tank_snd, 50, 0);
				snd_tune (engine_handle, 25, 100, 0); // play the sound at its original frequency (100%)
				my.skill10 = 100;
			}
		}
		else
		{
			my.skill10 -= 5 * time; // decrease the frequency
			snd_tune (engine_handle, 25, my.skill10, 0); // using snd_tune
			if (my.skill10 < 20) // if we go below 20% of the original frequency
			{
				snd_stop (engine_handle); // stop the engine sound
				engine_handle = 0;
			}
		}

		player_speed.x = 1.5 * (key_w - key_s) * time + max (1 - time * 0.15, 0) * player_speed.x;
		player_speed.y = 0;
		player_speed.z = 0;
		move_mode = ignore_you + ignore_passable;	
		ent_move(player_speed, nullvector);

		wait (1);
	}
}	
	
function player_rocket()
{
	procket_ptr = me;
	wait (1);
	my.skill40 = 1; // it is a rocket
	my.pan = you.pan;
	my.tilt = you.tilt;
	my.enable_impact = on;
	my.enable_block = on;
	my.enable_entity = on;
	my.event = explode_rocket;
	my.skill5 = 0; // used for vertical movement
	procket_speed.x = 100;
	procket_speed.y = 0;
	procket_speed.z = 0;
	procket_speed *= time; 
	while (my != null)
	{
		my.skill5 += time;
		if (my.skill5 > 20) 
		{
			procket_speed.z -= fall_speed * time;
		}
		move_mode = ignore_you + ignore_passable; // ignores the barrel -> can't collide with it
		ent_move (procket_speed, nullvector);
		wait (1);
	}
}

function explode_rocket()
{
	wait (1);
	exclusive_global;

	// the following piece of code replaces A5's ent_playsound with a linear function
	my.skill10 = vec_dist (player.x, my.x);
	if (my.skill10 < 1000) {my.skill10 = 1000;} // all sounds below 1000 quants will be played with maximal volume
	my.skill10 = 100000 / my.skill10; // bigger distance -> lower volume; 
	snd_play (tankexplo_snd, my.skill10, 0);

	vec_set (temp, my.pos);
	temp.z += 50; // create the explosion sprite a little higher
	ent_create(explosion_pcx, temp, animate_explosion); 
	ent_remove (me); 
}

function animate_explosion()
{
	wait (1);
	my.passable = on;
	my.ambient = 100;
	while (my.frame < 7)
	{
		my.frame += 1 * time;
		wait (1);
	}
	ent_remove (me);
}

function tank_damaged()
{
	if (you.skill40 != 1) {return;} // it wasn't hit by a rocket (maybe the 2 tanks collided)
	wait (1);
	my.shield -= 25;
	if (my.shield <= 0) // player's tank was hit 10 times or the enemy tank was hit twice
	{
		while (1)
		{
			effect (tank_smoke, 5, my.pos, normal);
			sleep (0.2);
		}
	}
}

function tank_smoke()
{
	temp.x = random(2) - 1;
	temp.y = random(2) - 1;
	temp.z = random(2) + 1;
	vec_add (my.vel_x, temp);
	my.alpha = 30 + random(30);
	my.bmap = tanksmoke_pcx;
	my.size = 100;	
	my.flare = on;
	my.move = on;
	my.lifespan = 100;
	my.function = fade_smoke;
}

function fade_smoke()
{
	my.alpha -= 0.5 * time;
	if (my.alpha < 0) 
	{
		my.lifespan = 0;
	}
}

/////////////////////////////////////////////////////////////////////////////////////
// enemy - related stuff from here on

action enemy_tank
{
	while (player == null) {wait (1);}
	my.ambient -= 30; // make the skin darker - it is too bright imho
	my.enable_impact = on;
	my.enable_entity = on;
	my.event = tank_damaged;
	my.shield = 50; // 2 rockets will destroy the enemy tank
	while (my.shield > 0)
	{
		vec_set (temp.x, player.x); 
		vec_sub (temp.x, my.x);
		vec_to_angle (my.skill4, temp); // turn towards the player	
		my.skill5 = 0; // tilt = 0

		if (abs(my.skill4 - my.pan) < 1)
		{ 
			vec_for_vertex(my.skill1, my, 41); // vertex for the enemy rocket
			ent_create (tank_rocket, my.skill1, enemy_rocket); 
			sleep (3);
		}
		else
		{
			my.pan += ang(my.skill4 - my.pan) * 0.03 * time; // smooth rotation code
			enemy_speed.x = 5 * time;
			enemy_speed.y = 0;
			enemy_speed.z = 0;
			move_mode = ignore_you + ignore_passable;	
			ent_move(enemy_speed, nullvector);
		}		
		wait (1);
	}
}

function enemy_rocket()
{
	wait (1);
	my.skill40 = 1; // it is a rocket
	my.pan = you.pan;
	my.tilt = you.tilt;
	my.enable_impact = on;
	my.enable_block = on;
	my.enable_entity = on;
	my.event = explode_rocket;
	erocket_speed.x = 100;
	erocket_speed.y = 0;
	erocket_speed.z = 0;
	erocket_speed *= time; 
	while (my != null)
	{
		move_mode = ignore_you + ignore_passable; // ignores the barrel -> can't collide with it
		ent_move (erocket_speed, nullvector);
		wait (1);
	}
}
