#include "../../mainproc/GameMain.h"
#include "../../Interface/Debug/DebugMessage.h"
#include "../../Interface/WorldFrames/ChatFrame.h"

#include "../net_party/NetCli_PartyChild.h"
#include "../net_script/NetCli_Script.h"
#include "NetCli_AttackChild.h"

//-----------------------------------------------------------------------------
bool NetCli_AttackChild::_Init()
{
	if (This)
		return false;

	This = new NetCli_AttackChild;
	return NetCli_Attack::_Init();
}

//-----------------------------------------------------------------------------
bool NetCli_AttackChild::_Release()
{
	NetCli_Attack::_Release();

	if (This)
	{
		delete This;
		This = NULL;
	}
	return true;
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_AttackSignalResult( int TargetID , AttackSignalResultENUM Result )
{
	switch( Result )
	{
	case EM_AttackSignalResult_OK:
		g_pDebugMessage->DebugOutput(2, "開啟攻擊");
		break;
	case EM_AttackSignalResult_TargetDisAttackAbled:
		g_pDebugMessage->DebugOutput(2, "目標不可攻擊");
		break;
	case EM_AttackSignalResult_TargetNULL:
		g_pDebugMessage->DebugOutput(2, "目標不存在");
		break;
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_AttackResult( int AttackID , int UnderAttackID , int DamageHP , ATTACK_DMGTYPE_ENUM	Type , AttackHandTypeENUM	HandType )
{
	CRoleSprite* attack = g_pGameMain->FindRoleSprite(AttackID);
	CRoleSprite* target = g_pGameMain->FindRoleSprite(UnderAttackID);
	int playerId = g_pGameMain->GetPlayerID();

	if ( attack == NULL || target == NULL )
		return;

	if ( attack )
	{
		char tmp[MAX_PATH];

		// 若是NPC自動修正面向，朝向被攻擊對像
		switch ( attack->GetObjectType() )
		{
		case eSpriteObject_NPC:
		case eSpriteObject_QuestNPC:
			if ( target )
			{
				attack->SetDirection(target->GetPos() - attack->GetPos());
			}
			break;
		}

		// 攻擊者是自己
		if ( playerId == AttackID )
		{
			switch ( Type )
			{
			case EM_ATTACK_DMGTYPE_MISS:		//MISS
				sprintf(tmp, "Attack to %s, Miss!!", target->GetName());
				break;

			case EM_ATTACK_DMGTYPE_DODGE:
				sprintf(tmp, "Attack to %s, Dodge!!", target->GetName());
				break;

			case EM_ATTACK_DMGTYPE_HALF:
				sprintf(tmp, "Attack to %s, Parry!!", target->GetName());
				break;

			case EM_ATTACK_DMGTYPE_NORMAL:
				sprintf(tmp, "Attack to %s, Normal damage %d", target->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_DOUBLE:
				sprintf(tmp, "Attack to %s, Double damage %d", target->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_TRIPLE:
				sprintf(tmp, "Attack to %s, Triple damage %d", target->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_HITBACK:
				sprintf(tmp, "Hitback to %s, damage %d", target->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_ABSORB:
				sprintf(tmp, "%s物理傷害吸收%d", target->GetName(), DamageHP);
				break;

			default:
				memset(tmp, 0, sizeof(tmp));
				break;

			}
			g_pChatFrame->AddMessage(3, tmp);
		}
		// 被攻擊者是自己
		else if ( playerId == UnderAttackID )
		{
			if ( g_pGameMain->GetTargetPlayer() == NULL )
				g_pGameMain->SetTargetPlayer( attack );

			switch ( Type )
			{
			case EM_ATTACK_DMGTYPE_MISS:
				sprintf(tmp, "%s Attack to you, Miss!", attack->GetName());
				break;

			case EM_ATTACK_DMGTYPE_DODGE:
				sprintf(tmp, "%s Attack to you, Dodge!", attack->GetName());
				break;

			case EM_ATTACK_DMGTYPE_HALF:			//被隔檔
				sprintf(tmp, "%s Attack to you, Parry!", attack->GetName());
				break;

			case EM_ATTACK_DMGTYPE_NORMAL:			//一般
				sprintf(tmp, "%s Attack to you, Normal damage %d", attack->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_DOUBLE:			//會心一擊
				sprintf(tmp, "%s Attack to you, Double damage %d", attack->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_TRIPLE:			//必殺一擊
				sprintf(tmp, "%s Attack to you, Triple damage %d", attack->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_HITBACK:			//反擊
				sprintf(tmp, "%s Hitback to you, Damage %d", attack->GetName(), DamageHP);
				break;

			case EM_ATTACK_DMGTYPE_ABSORB:
				sprintf(tmp, "物理傷害吸收%d", DamageHP);
				break;

			default:
				memset(tmp, 0, sizeof(tmp));
				break;
			}

			g_pChatFrame->AddMessage(3, tmp);
		}

		// 攻擊者與被攻擊者自動進入戰鬥模式		
		attack->SetCombatState(true);
		if ( HandType == EM_AttackHandType_Second )
			attack->SetAttackMotion(true);
		else
			attack->SetAttackMotion(false);
	}

	if ( target )
	{
		target->SetCombatState(true);
		target->SetHP( target->GetHP() - DamageHP );
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_Dead( int DeaderID , int KillerID , int Time , RolePosStruct &Pos )
{
	g_pDebugMessage->DebugOutput(0, "[R_Dead] DeaderID %d KillerID %d Time %d", DeaderID , KillerID , Time);

	CRoleSprite* pSprite = g_pGameMain->FindRoleSprite( DeaderID );
	if ( pSprite )
	{		
		pSprite->SetServerPos( CRuVector3(Pos.X, Pos.Y, Pos.Z) );
		//pSprite->SetAction( eAction_Dead );
		//pSprite->SetDead( true );
		
		if ( DeaderID != g_pGameMain->GetPlayerID() )
			pSprite->AdjustPosWithServerPos();
		
		/*
		SpriteEventInfo event;
		event.func			= CRoleSprite::DelayAction;
		event.nowTime		= 1.0f;
		event.userData[0]	= eAction_Dead;
		pSprite->PushEvent( 0, event );
		*/
		pSprite->SetDeadState(true);
		pSprite->SetActorState(ruFUSION_ACTORSTATE_DEAD);

		// 任務計算殺敵數量檢查
		//-------------------------------------------------------------

		if( KillerID == g_pGameMain->GetPlayerID() )	// 檢查是不是角色本身或隊友殺死
		{
			// 組隊現在還未實作, 之後再處理
			// 死亡目標與本身的距離在不在允許範圍


			// 一切都符合, 計算殺敵計數
			CNetCli_Script::OnEvent_KillObj( pSprite->GetIdentify() );
		}			
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_Resurrection( int ItemID )
{

	CRoleSprite* pSprite = g_pGameMain->FindRoleSprite( ItemID );
	if ( pSprite )
	{
		//pSprite->SetCombatState(false);
		pSprite->SetDeadState(false);
		pSprite->SetActorState(ruFUSION_ACTORSTATE_REVIVING);
		
		/*
		//pSprite->SetDead( false );
		pSprite->SetFight( false );
		pSprite->SetAction(eAction_Revive);
		*/
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_HPMPSP( int ItemID , int HP , int MP , int SP , int SP_Sub )
{
	CRoleSprite* pSprite = g_pGameMain->FindRoleSprite( ItemID );
	if ( pSprite )
	{
		pSprite->SetHP( HP );
		pSprite->SetMP( MP );
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_MaxHPMaxMPMaxSP( int ItemID , int MaxHP , int MaxMP , int MaxSP , int MaxSP_Sub )
{
	CRoleSprite* pSprite = g_pGameMain->FindRoleSprite( ItemID );
	if ( pSprite )
	{
		pSprite->SetMaxHP( MaxHP );
		pSprite->SetMaxMP( MaxMP );
	}
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_PartyMemberHPMPSP	( int DBID , int HP , int MP , int SP , int SP_Sub )
{
	char Buf[512];
	sprintf( Buf , "[Party成員] : 資料更新 DBID = %d HP = %d MP = %d SP = %d" , DBID , HP , MP , SP );	
	g_pDebugMessage->DebugOutput( 5, Buf );

	NetCli_PartyChild::SetPartyMemberHPMPSP( DBID, HP, MP, SP );
}

//-----------------------------------------------------------------------------
void NetCli_AttackChild::R_PartyMemberMaxHPMPSP ( int DBID , int MaxHP , int MaxMP , int MaxSP , int MaxSP_Sub )
{
	char Buf[512];
	sprintf( Buf , "[Party成員] : 資料更新 DBID = %d MaxHP = %d MaxMP = %d MaxSP = %d" , DBID , MaxHP , MaxMP , MaxSP );
	g_pDebugMessage->DebugOutput( 5, Buf );

	NetCli_PartyChild::SetPartyMemberMaxHPMPSP( DBID, MaxHP, MaxMP, MaxSP );
}