//=============================================================================
// BiterFish.
// Do not add directly - rather add BiterFishSchools to the world
//=============================================================================
class BiterFish expands FlockPawn;


#exec MESH IMPORT MESH=AmbientFish ANIVFILE=MODELS\fish1_a.3D DATAFILE=MODELS\fish1_d.3D X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=AmbientFish X=00 Y=-20 Z=00 YAW=-64

#exec MESH SEQUENCE MESH=AmbientFish SEQ=All    STARTFRAME=0   NUMFRAMES=11
#exec MESH SEQUENCE MESH=AmbientFish SEQ=Swim1  STARTFRAME=0   NUMFRAMES=8
#exec MESH SEQUENCE MESH=AmbientFish SEQ=Bite   STARTFRAME=8   NUMFRAMES=3

#exec TEXTURE IMPORT NAME=Jfish21  FILE=MODELS\fish2.PCX GROUP=Skins 
#exec MESHMAP SCALE MESHMAP=AmbientFish X=0.06 Y=0.06 Z=0.12
#exec MESHMAP SETTEXTURE MESHMAP=AmbientFish NUM=1 TEXTURE=Jfish21

// Attack damage.
var() byte
	BiteDamage;

var vector OldSchoolDestination;
var BiterFishSchool School;

function Damage( int Damage, Pawn instigatedBy, Vector hitlocation, 
						Vector momentum, name damageType)
{
	local bool bAlreadyDead;

	bAlreadyDead = (Health <= 0);

	if (Physics == PHYS_None)
		SetMovementPhysics();
	if (Physics == PHYS_Walking)
		momentum.Z = 0.4 * size(momentum);
	if ( instigatedBy == self )
		momentum *= 0.6;
	momentum = momentum/Mass;
	ClientAddVelocity( momentum ); 
	Health -= Damage;
	if ( Health < -20 )
	{
		Spawn(class'Bloodspurt');
		Destroy();
	}
	else if ( !bAlreadyDead && (Health < 0) )
		Died(instigatedBy, damageType, hitLocation);
}

function Landed(vector HitNormal)
{
	local rotation newRotation;

	SetPhysics(PHYS_None);
	SetTimer(0.2 + FRand(), false);
	newRotation = Rotation;
	newRotation.Pitch = 0;
	newRotation.Roll = 16384;
	SetRotation(newRotation);
	GotoState('Flopping');
}

function PreSetMovement()
{
	bCanSwim = true;
	if (Region.Zone.bWaterZone)
		SetPhysics(PHYS_Swimming);
	else
		SetPhysics(PHYS_Falling);
	MinHitWall = -0.6;
}

function ZoneChange( ZoneInfo NewZone )
{
	local Rotation newRotation;
	if (NewZone.bWaterZone)
	{
		if ( !Region.Zone.bWaterZone && (Physics != PHYS_Swimming) )
		{
			newRotation = Rotation;
			newRotation.Roll = 0;
			SetRotation(newRotation);
			MoveTimer = -1.0;
		}
		SetPhysics(PHYS_Swimming);
		if (State != 'Swimming');
			GotoState('Swimming');
	}
	else if (Physics != PHYS_Falling)
	{
		MoveTimer = -1;
		SetPhysics(PHYS_Falling);
	}
}

function FootZoneChange(ZoneInfo newFootZone)
{
	if ( (Level.TimeSeconds - SplashTime > 3) && 
	 	!FootRegion.Zone.bWaterZone && newFootZone.bWaterZone )
	{
		SplashTime = Level.TimeSeconds;
		PlaySound(sound 'LSplash', SLOT_Interact, 0.4,,500);
		Spawn(class 'WaterImpact',,,Location - CollisionHeight * vect(0,0,1));
	}
	
	if ( FootRegion.Zone.bPainZone )
	{
		if ( !newFootZone.bPainZone )
			PainTime = -1.0;
	}
	else if (newFootZone.bPainZone)
		PainTime = 0.01;
}

function Died(pawn Killer, name damageType, vector HitLocation)
{
	local rotation newRot;

	newRot = Rotation;
	if ( FRand() < 0.5 )
		newRot.Roll = 16384;
	else 
		newRot.Roll = -16384;
	SetRotation(newRot);
	SetPhysics(PHYS_Falling);
	Buoyancy = 1.05 * mass;
	Velocity.Z = FMax(0, Velocity.Z);
	AnimRate = 0.0;

	school.FishDied();
	RemoteRole = ROLE_DumbProxy;
	GotoState('Dying');
}

Auto State Swimming
{
	function PickDestination()
	{
		if ( (School.State == 'Stasis') && !PlayerCanSeeMe() )
		{
			School.Remove(self);
			return;
		}
		if ( School.validDest )
			OldSchoolDestination = School.Location;
		Destination = OldSchoolDestination +
			 0.5 * School.schoolradius * ( Normal(Location - School.Location) + VRand());
	}

	function Touch(Actor Other)
	{
		if ( Pawn(Other) == School.Enemy )
			Other.Damage(2, self, location, vect(0,0,0), 'bitten');
	}
		
Begin:
	if (!Region.Zone.bWaterZone)
		GotoState('Flopping');
	SetPhysics(PHYS_Swimming);
Swim:
	Enable('HitWall');
	LoopAnim('Swim1', 0.7 + FRand());
 	if ( (School.Enemy!=None) && (School.MoveTarget == School.Enemy) && (FRand()<0.5) )
 		MoveToward(School.Enemy);
 	else
 	{
		PickDestination();
		MoveTo(Destination);
School:
		if ( (FRand() < 0.75) && (OldSchoolDestination == School.Location) 
			&& ((School.Enemy == None) || !School.Enemy.Region.Zone.bWaterZone) )
		{
			Acceleration = vect(0,0,0);
			Sleep(1.5 * FRand());
			Goto('School');
		}
 	}
	Sleep(0.5 * FRand());
	Goto('Swim');
}

State Flopping
{

	function Landed(vector HitNormal)
	{
		local rotation newRotation;

		SetPhysics(PHYS_None);
		SetTimer(0.2 + FRand(), false);
		newRotation = Rotation;
		newRotation.Pitch = 0;
		newRotation.Roll = 16384;
		SetRotation(newRotation);
	}
		
	function Timer()
	{
		if (FRand() < 0.01)
			GotoState('Dying');
		else
		{
			SetPhysics(PHYS_Falling);
			Velocity = 200 * VRand();
			Velocity.Z = 60 + 160 * FRand();
			DesiredRotation.Pitch = Rand(8192) - 4096;
			DesiredRotation.Yaw = Rand(65535);
		}		
	}

Begin:
	SetPhysics(PHYS_Falling);
Flop:
	If (FRand() < 0.5)
		PlayAnim('Swim1', 0.1 * FRand());
	else
		PlayAnim('Bite', 0.1 * FRand());
	FinishAnim();
	Goto('Flop');
}

State Dying
{
	ignores zonechange, headzonechange, falling, hitwall;

	function Landed(vector HitNormal)
	{
		SetPhysics(PHYS_None);
	}	

	function Timer()
	{
		if ( !PlayerCanSeeMe() )
			Destroy();
	}

Begin:
	Sleep(12);
	SetTimer(4.0, true);
}			
		
