// Bridge class between EXM plugin and SiegeIV
// By Higor

class JetPushPool expands Info;

var ViewPort Player;
var JetPack CurJet;
var info EXMPlugin;

var float PushDelta[32];
var byte CrouchPush[32];
var int iPush;

var bool bCurAdj;
var SavedMove CurMove;
var int CurAdj;
var int OldAdj;

event PostBeginPlay()
{
	SetLocation( vect(30100, 30100, 30100) );
	SetCollision( true);
}

event Tick( float DeltaTime)
{
	local int j;
	local SavedMove aMove;

	while ( (j<iPush) && (PushDelta[j] < Player.Actor.CurrentTimeStamp) )
		j++;
	if ( j > 0 )
		PopList(j);

	// Prepare player for next frame
	if ( iPush > 0 )
	{
		bCurAdj = false;
		class'sg_TouchUtil'.static.SetTouch( Player.Actor, self);
		class'sg_TouchUtil'.static.SetTouch( self, Player.Actor);
	}
}

event UnTouch( Actor Other)
{
	local byte i;
	if ( Other == Player.Actor )
	{
		if ( Player.Actor.bUpdating )
		{
			if ( !bCurAdj && (iPush > 0)  )
			{
				while ( (i < iPush) && (PushDelta[i] <= Player.Actor.CurrentTimeStamp) )
					i++;
				if ( i > 0 )
					PopList(i);
				CurAdj = 0;
				OldAdj = 0;
				bCurAdj = true;
				CurMove = Player.Actor.SavedMoves; //Player has already cleaned up moves!
				if ( (CurMove != none) && (CurMove.TimeStamp >= PushDelta[0]) ) //Apply first velocity change
				{
					Player.Actor.PendingTouch = self;
					PendingTouch = Player.Actor;
					CurAdj = 1;
				}

			}
			if ( bCurAdj && (CurMove != none) )
				CurMove = CurMove.NextMove;
			if ( (CurMove != none) && (CurAdj < iPush) )
			{
				if ( CurMove.TimeStamp >= PushDelta[CurAdj] )
				{
					Player.Actor.PendingTouch = self;
					PendingTouch = Player.Actor;
					CurAdj++;
				}
			}
		}
		class'sg_TouchUtil'.static.SetTouch( Other, self);
		class'sg_TouchUtil'.static.SetTouch( self, Other);
	}
}

function AddNewPush( vector PushVel, bool bDuck)
{
	local info I;

	if ( Level.NetMode != NM_Client )
		return;

	//Non-exm code
	if ( iPush < 32 )
	{
		PushDelta[iPush] = Level.TimeSeconds;
		CrouchPush[iPush] = byte(bDuck);
		iPush++;
	}
	//Non-exm code /end

/*
	if ( EXMPlugin == none )
	{	ForEach AllActors (class'Info', I, 'EXM')
		{	if ( I.IsA('EXM_Master') )
			{
				EXMPlugin = I;
				break;
			}
		}
	}
	if ( EXMPlugin != none )
	{
		EXMPlugin.SetPropertyText( "NewFixedVelocity", string(PushVel) );
		EXMPlugin.SetPropertyText( "NewEventType", "1"); //VEL_FIXEDADD
		EXMPlugin.SetPropertyText( "bNewEvent", "1");
		EXMPlugin.Trigger( self, Pawn(Owner));
	}
*/
}

event PostTouch( Actor Other)
{
	local int i;
	if ( Other != Player.Actor || CurJet == none )
		return;
	For ( i=OldAdj ; i<=CurAdj ; i++ )
		Player.Actor.Velocity = CurJet.PushVel( bool(CrouchPush[i]) );
	OldAdj = CurAdj;
}

function PopList( int PopCount)
{
	local int i, j;

	assert( iPush > 0 );
	assert( PopCount > 0);
	assert( PopCount <= iPush);
	iPush -= PopCount;
	while ( i < iPush )
	{
		PushDelta[i] = PushDelta[i+PopCount];
		CrouchPush[i] = CrouchPush[i+PopCount];
		i++;
	}
}

defaultproperties
{
    RemoteRole=ROLE_None
    bCollideWorld=False
    bHidden=True
}