/***********************************************
 * _boom#.zes
 * 
 * Author: GD
 * Date:   2 July 2002
 *
 * Desc:   Script for 3 types of boomerang, this draws the
 *		   actual boomerangs going accross the screen.
 *
 * Usage:
 *         
 *     
 * Sprites: _WeaponSheet1.spt
 *    
 ***********************************************/
#include <entity>
#include <general>
#include <float>
#include <core>

new float: timeActive = 0.00;
new float: airtime = 0.00;
new float: sparkleCount = 0.00;
new float: soundFXCount = 20.00;
new hitSomthing = false;
new wimage[20];
new parent[20];
new param;
new float: rotation = 0.00;
new range = 80;
new sparkleAmount = 0;

main()
{
	if (FirstRun())
	{
		new n;
		
		GetParent("this", parent);
		
		// Get the scripts parameter
     	param = GetParam("this");
     	SetActiveDist("this", -2);
     	SetSpeed("this", 160);
     	SetActiveInGroups("this", true);	// will be active in any group
     	SetActiveDist("this", -2);			// -2 means its always active
		
		if (param == 'r') // Red
		{
			wimage = "_rboom1";
			range = 50;
		}
		if (param == 'g') // Gold
		{
			wimage = "_gboom1";
			range = 80;
			SetSpeed("this", 180);
			sparkleAmount = 12;
		}
		if (param == 'b') // Blue/ice
		{
			wimage = "_bboom1";
			range = 90;
			SetSpeed("this", 180);
			sparkleAmount = 8;
		}
		
		// Do this so the parent entity knows it cant create any more
		// Boomerangs until this one returns
		SetValue(parent, 5, 1);
	}
	else
	{		
		// Check the sound effects counter
		soundFXCount += 100 * GetTimeDelta();
		if ( soundFXCount > 14)
		{
			// We cant play the sound each loop becuase that would sound bad and probably
			// grind everything to a halt, so just play it every so often
			PlaySound("_boomerang.wav", 128);
			soundFXCount = 0.00;
		}
		
		// Dont allow this entity to live for too long if it doesnt hit anything
		timeActive += 1 * GetTimeDelta();
		if ( timeActive > 5)
			EndBoomerang();
		
		if ( !hitSomthing )
			MoveBoomerang();
		else
			BoomReturn();
		
		// Create a sparkly effect from the boomerang
		if ( sparkleAmount > 0)
		{
			
			sparkleCount += 100 * GetTimeDelta();
			if ( sparkleCount > sparkleAmount )
			{	
				new Buffer[20];
				CreateEntity("_sparkle1", GetX("this") + random(8), GetY("this")+ random(8), Buffer);
				sparkleCount = 0.00;
			}
		}
	}
}

//----------------------------------------
// Name: MoveBoomerang()
//----------------------------------------
MoveBoomerang()
{
	new Buffer[20];
	
	if (GetPauseLevel() == 0)
	{
		// Move the Boomerang
		AngleMove("this");
	
		// Test for a collision on the mask layer
		if (AngleCollide("this", 3, 3, 126, 0, 8, 8))
		{
			// Make a small explosion effect
			CreateEntity("_explosion2", GetX("this") + 8, GetY("this") + 8, Buffer);
			PlaySound("_swordclash.wav", 244);
			
			hitSomthing = true;
		}
		
		// Check if we hit any enemies
		CheckForEnemies();
	}
	
	// Advance a counter to check how long its been in the air
	airtime += 100 * GetTimeDelta();
	if ( airtime > range)
		hitSomthing = true;
	
	DrawBoom();	
}

//----------------------------------------
// Name: BoomReturn()
//----------------------------------------
BoomReturn()
{
	new px = GetX("player1") + 8;
	new py = GetY("player1") + 8;
	new x  = GetX("this") + 8;
	new y  = GetY("this") + 8;
	new detect = 12;
	
	if (GetPauseLevel() == 0)
	{
		// Make the boomerang head towards the player
		SetMoveAngle("this", CalculateAngle(x, y, px, py));
		AngleMove("this");
		
		// If the boomerang is near enough to the player then take it back
		if ( px >= x - detect && px <= x + detect)
		{
			if ( py >= y - detect && py <= y + detect)
			{
				// Player has the boomerang
				EndBoomerang();
			}
		}
		
		// If the boomerang is too far from the player then just return it anyway, this ensures
		// that it wont be lost, this is why the boomerang must be active all the time, even if the player
		// is way off the screen.
		if ( px < x - 300 || px > x + 300 || py < y - 300 || py > y + 300)
		{
			// Player has the boomerang
			EndBoomerang();
		}

		// Check if we hit any enemies
		CheckForEnemies();
	}
	
	DrawBoom();
}

//----------------------------------------
// Name: DrawBoom()
//----------------------------------------
DrawBoom()
{
	new adj = 5;
	
	// Make the weapon spin
	rotation += 900 * GetTimeDelta();
	if ( rotation >= 355.00 )
		rotation = 1.00;
	
	// Draw the weapon
	new x = GetX("this");
	new y = GetY("this");
	PutSprite( wimage, x, y, y + 16, 0, 255, 255, 255, 255, floatround(rotation));
	SetCollisionRect("this", 0, false, x + adj, y + adj, x + 16 - adj, y + 16 - adj);
}

//----------------------------------------
// Name: EndBoomerang()
//----------------------------------------
EndBoomerang()
{
	// Inform the players boomerang weapon script that we have returned
	SetValue(parent, 5, 0);
	
	// Delete this entity
	DeleteEntity("this");	
}


//----------------------------------------
// Name: CheckForEnemies()
//----------------------------------------
CheckForEnemies()
{
	new x = GetX("this");
	new y = GetY("this");
	new temp[20];
	
	// Go to the start of the Entity List
	StartEntity(40, x, y);
	do
	{
		ToString(GetCurrentEntity(), temp);
		
		// Check this entity is an enemy
		if ( GetType( temp ) == enemyType && !isDead( temp ) )
		{
			// Check this entity is near the fireball
			if (Collide("this", temp))
			{
				// If this is an ice boomerang then deal some ice damage
				if (param == 'r')
				{
					CallFunction( temp, false, "HitByWeapon", "snnn", "stun", 100, x, y);
					PlaySound("_enemyhurt.wav", 240);
					hitSomthing = true;
				}
				else if (param == 'g')
				{
					CallFunction( temp, false, "HitByWeapon", "snnn", "weapon", 100, x, y);
					hitSomthing = true;
				}
				else
					CallFunction( temp, false, "HitByWeapon", "snnn", "ice", 50, x, y);		
				
			}
		}
	}while( NextEntity() )
}