/*=========================================================================

	ndustdev.cpp

	Author:		CRB
	Created: 
	Project:	Spongebob
	Purpose: 

	Copyright (c) 2000 Climax Development Ltd

===========================================================================*/

#ifndef __ENEMY_NPC_H__
#include "enemy\npc.h"
#endif

#ifndef	__ENEMY_NDUSTDEV_H__
#include "enemy\ndustdev.h"
#endif

#ifndef __GAME_GAME_H__
#include	"game\game.h"
#endif


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

void CNpcDustDevilEnemy::postInit()
{
	m_npcPath.setPathType( CNpcPath::SINGLE_USE_PATH );

	m_fadeVal = 128;
	m_fadeOut = false;
}

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

void CNpcDustDevilEnemy::render()
{
	SprFrame = NULL;

	if ( m_isActive )
	{
		CEnemyThing::render();

		if (canRender())
		{
			DVECTOR &renderPos=getRenderPos();

			SprFrame = m_actorGfx->Render(renderPos,m_animNo,( m_frame >> 8 ),m_reversed);
			setSemiTrans( SprFrame, true );
			m_actorGfx->RotateScale( SprFrame, renderPos, m_drawRotation, 4096, 4096 );
			setRGB0( SprFrame, m_fadeVal, m_fadeVal, m_fadeVal );

			sBBox boundingBox = m_actorGfx->GetBBox();
			setCollisionSize( ( boundingBox.XMax - boundingBox.XMin ), ( boundingBox.YMax - boundingBox.YMin ) );
			setCollisionCentreOffset( ( boundingBox.XMax + boundingBox.XMin ) >> 1, ( boundingBox.YMax + boundingBox.YMin ) >> 1 );
		}
	}
}

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

void CNpcDustDevilEnemy::processMovement( int _frames )
{
	s32 maxHeight = 40;
	s32 distX, distY;
	s32 fallSpeed = 3;
	s8 yMovement = fallSpeed * _frames;
	s32 groundHeight;

	s32 moveX = 0;
	s32 moveY = 0;
	s32 moveVel = 0;
	s32 moveDist = 0;

	bool pathComplete;

	if ( m_soundId == NOT_PLAYING && m_data[m_type].moveSfx < CSoundMediator::NUM_SFXIDS )
	{
		m_soundId = (int) CSoundMediator::playSfx( m_data[m_type].moveSfx, true );
	}

	// deal with anims

	if ( !m_animPlaying )
	{
		m_animPlaying = true;
		m_frame = 0;
		m_animNo = m_data[m_type].moveAnim;
	}

	if ( m_fadeOut )
	{
		m_fadeVal -= _frames * 12;

		if ( m_fadeVal < 0 )
		{
			m_npcPath.resetPath();

			Pos = m_base;

			m_fadeOut = false;
			m_fadeVal = 128;
		}
	}
	else
	{
		// ignore y component of waypoint, since we are stuck to the ground

		if ( m_npcPath.thinkFlat( Pos, &pathComplete, &distX, &distY, &m_heading ) )
		{
			// path has finished, waypoint has changed, or there are no waypoints - do not move horizontally

			if ( pathComplete )
			{
				m_fadeOut = true;
			}
			else
			{
				// check for vertical movement

				groundHeight = CGameScene::getCollision()->getHeightFromGround( Pos.vx, Pos.vy, yMovement + 16 );

				if ( groundHeight <= yMovement )
				{
					// groundHeight <= yMovement indicates either just above ground or on or below ground

					moveY = groundHeight;
				}
				else
				{
					// fall

					moveY = yMovement;
				}
			}
		}
		else
		{
			// check for collision

			distX = distX / abs( distX );

			if ( CGameScene::getCollision()->getHeightFromGround( Pos.vx + ( distX * m_speed * _frames ), Pos.vy ) < -maxHeight )
			{
				// there is an obstacle in the way, increment the path point (hopefully this will resolve the problem)

				m_npcPath.incPath();
			}
			else
			{
				// check for vertical movement

				groundHeight = CGameScene::getCollision()->getHeightFromGround( Pos.vx, Pos.vy, yMovement + 16 );

				if ( groundHeight <= yMovement )
				{
					// groundHeight <= yMovement indicates either just above ground or on or below ground

					moveX = distX * m_speed * _frames;
					moveY = groundHeight;
				}
				else
				{
					// fall

					moveY = yMovement;
				}
			}
		}

		processMovementModifier( _frames, moveX, moveY, moveVel, moveDist );
	}
}

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

void CNpcDustDevilEnemy::processMovementModifier( int _frames, s32 distX, s32 distY, s32 dist, s16 headingChange )
{
	Pos.vx += distX;
	Pos.vy += distY;

	// sort out draw rotation

	DVECTOR testPos1, testPos2;

	testPos1 = testPos2 = Pos;
	testPos1.vx -= 10;
	testPos2.vx += 10;

	int groundDist = CGameScene::getCollision()->getHeightFromGround( testPos1.vx, testPos1.vy, 16 );

	if ( abs( groundDist ) > 15 )
	{
		m_drawRotation = 0;
		return;
	}

	testPos1.vy += groundDist;

	groundDist = CGameScene::getCollision()->getHeightFromGround( testPos2.vx, testPos2.vy, 16 );

	if ( abs( groundDist ) > 15 )
	{
		m_drawRotation = 0;
		return;
	}

	testPos2.vy += groundDist;

	s32 xDist = testPos2.vx - testPos1.vx;
	s32 yDist = testPos2.vy - testPos1.vy;

	s16 heading = ratan2( yDist, xDist ) & 4095;

	m_drawRotation = heading;
}

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

s32 CNpcDustDevilEnemy::getFrameShift( int _frames )
{
	return( ( _frames << 8 ) >> 2 );
}