#include "scripts/common.txt"
#include "scripts/BP_common.txt"

class BP_AdonRopeProjectile : ScriptObject
{
    kActor @self;
	bool hitPoint;
	kVec3 lastTrailPos;
	float activeTime;
	float trailTime;
	//------------------------------------------------------------------------------------------------------------------------
    BP_AdonRopeProjectile(kActor @actor)
    {
        @self = actor;
		lastTrailPos = self.Origin();
    }
	//------------------------------------------------------------------------------------------------------------------------
	void Setup(kVec3 actorVelocity)
	{
		self.Gravity() = 0.1f;
		self.ClipFlags() = (CF_DROPOFF|CF_CLIPEDGES|CF_COLLIDEFLOORS|CF_COLLIDEHEIGHT|CF_COLLIDECORPSES|CF_COLLIDEWATER);
		self.Velocity() = actorVelocity;
		self.Flags() |= AF_ALWAYSACTIVE;
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnSpawn()
	{
		
	}
	//------------------------------------------------------------------------------------------------------------------------
    void OnTick()
	{
		if (hitPoint)
		{
			if (!playerIsRoping)
			{
				self.Remove();
			}
		}
		else
		{
			activeTime += GAME_DELTA_TIME;
			if (activeTime > 10.0f)
			{
				self.Remove();
			}
			
			kVec3 origin = self.Origin();
			
			trailTime += GAME_DELTA_TIME;
			if (self.GameTicks() == 0 || trailTime >= 2.0f)
			{
				trailTime = 0.0f;
				self.RenderModel().AddTrailEffect("Trail_Adon_Grapple", 0);
			}
			
			//go through all rope points in map and see if they are near this projectile
			for (int i = 0; i < int(ropePoints.length()); i++)
			{
				if (IsActorInRadius(ropePoints[i], origin, 10000))
				{
					hitPoint = true;
					Game.PlaySound("sounds/shaders/trex_bite_attack.ksnd");
					playerIsRoping = true;
					playerRopePoint = ropePoints[i].Origin();
					self.Gravity() = 0.0f;
					self.Velocity() = Math::vecZero;
				}
			}
		}
    }
	//------------------------------------------------------------------------------------------------------------------------
	bool TryRopeActor(kActor @cActor)
	{
        if (!ActorExists(cActor))
		{
			return false;
		}
		
		//only these actor types
		switch (cActor.Type())
		{
			case 2: //Human_Grunt_Soldier
			case 6050: //Robot_Grunt_Soldier
			case 6075: //Human_Grunt_Soldier_Spawn
			case 1: //Monster_Raptor_Common
			case 4: //Monster_Dimetrodon_Common
			case 11: //Monster_Purlin
			case 9: //Monster_Stalker
			case 10: //Monster_Alien
			case 21: //Monster_Insect_Beetle
			case 25: //Monster_Insect_DragonFly
			case 12: //Monster_Mech_Sentry
			{
				@playerRopeActor = @cActor;
				playerRopeActorLP = cActor.Origin();
				playerRopeActorDistTime = 0.0f;
				return true;
			}
		}
		
		return false;
	}
	//------------------------------------------------------------------------------------------------------------------------
	void OnCollide(kCModel @cModel)
	{
		kActor @cActor = cModel.ContactActor();
		kActor @player = Player.Actor().CastToActor();
		if (@cActor == @player)
		{
			return;
		}
		
		bool ropedActor = TryRopeActor(@cActor);
		
		if (ropedActor)
		{
			self.Remove();
		}
		else
		{
			//hook on to any surface
			kVec3 p = cModel.InterceptVector();
			hitPoint = true;
			Game.PlaySound("sounds/shaders/trex_bite_attack.ksnd");
			playerIsRoping = true;
			playerRopePoint = p;
			self.Gravity() = 0.0f;
			self.Velocity() = Math::vecZero;
			self.ClipFlags() |= CF_NOCOLLIDEFUNC;
			
			//self.Velocity() = Math::Vec3Reflect(self.Velocity(), cModel.ContactNormal());
			//self.Velocity() *= 0.5f;
		}
	}
	//------------------------------------------------------------------------------------------------------------------------
};
