#include "CS_KingGuard.h"
#include "CS_King.h"
#include "CS_KingGuardCircle.h"
#include "CS_PeGunShotHit.h"
const int CS_KingSTATENAME_GUARD = ++entityStateID;
CS_KingGuard::CS_KingGuard()
{
	stateID = CS_KingSTATENAME_GUARD;
	cd_counter = 0;
	cd_counter_max = 90;
	iconIndex = 2;
}

const wchar_t* CS_KingGuard::GetSaveName()
{
	return L"Guard";
}

const wchar_t* CS_KingGuard::GetFuncName()
{
	return L"KingSkill_Guard";
}

const wchar_t* CS_KingGuard::GetCheckFuncName()
{
	return L"KingSkill_Guard_Check";
}

void CS_KingGuard::State()
{
	auto we = e.lock();
	if (!we)
		return;
	auto mychar = std::static_pointer_cast<CS_King>(we);
	//在攀岩状态下格挡不会移动
	if (bClimbAni)
	{
		mychar->stateGravity.SetEnable(false);
		mychar->vx = mychar->vy = 0;
		mychar->ani.sprite_index = we->lr == 0 ? L"mc_king_guard_lc" : L"mc_king_guard_rc";
	}
	else
	{
		mychar->ani.sprite_index = we->lr == 0 ? L"mc_king_guard_l" : L"mc_king_guard_r";
	}
	//在空中但不是攀爬状态时，可以移动
	if (!mychar->cbRect.cbBottom && !bClimbAni)
	{
		mychar->stateControl.MoveControl();
	}
	//放开了技能键
	bool b1 = (mychar->input.key & keyMask);
	if (!b1)
	{
		//直接恢复回站立
		mychar->action_timecounter = 0;
		mychar->stateGravity.SetEnable(true);
	}
	if (block_ani_counter > 0)
		block_ani_counter--;
	mychar->ani.image_index = block_ani_counter == 0 ? 0 : 1;
}

void CS_KingGuard::SubStep()
{
	//技能每步
	auto we = e.lock();
	if (!we)
		return;
	auto mychar = std::static_pointer_cast<CS_King>(we);
	bUIShowDisableSkill = !((
		!mychar->InAction()
		) &&
		!lock
		);
	bool a1 = !mychar->InAction() &&
		!lock;

	bool b1 = (mychar->input.key & keyMask);
	bool c1 = cd_counter == 0 && mychar->mp >= mp_cost;

	bool a = a1;
	bool b = b1;
	bool c = c1;
	//触发技能
	if (a && b && c)
	{
		mychar->stateResist.SetEnable(true);//burstRoll
		mychar->faceToBack = false;
		mychar->lastSkill = this;
		bClimbAni = mychar->stateControl.bClimb;
		if (bClimbAni)
		{
			if (mychar->lr == 0)
				mychar->lr = 1;
			else
				mychar->lr = 0;
		}
		mychar->ChangeState(GetStateID());
	}
	//技能冷却时间
	if (!enable)
	{
		//晃动
		if (a && b && !c)
		{
			we->shock_counter = 30;
			//锁住按键
			mychar->inputLock.key |= keyMask;
		}
		if (cd_counter > 0)
		{
			if (mychar->InAction())
			{
				cd_counter--;
			}
			else
			{
				cd_counter -= 2;
				if (cd_counter < 0)
					cd_counter = 0;
			}
		}

	}
	EntitySkillState::SubStep();
}

void CS_KingGuard::ChangeStateMsg(int stateID)
{
	if (stateID == GetStateID())
	{
		//初始化技能
		auto we = e.lock();
		if (!we)
			return;
		auto mychar = std::static_pointer_cast<CS_King>(we);
		enable = true;
		//设置承受伤害
		shieldHP = mychar->hp_max / 2;
		//设置防御圈
		auto circle = std::make_shared<CS_KingGuardCircle>(we);
		we->gameFunc->SetEntity(we, circle);
		//设置消耗
		cd_counter = cd_counter_max;
		mychar->action_timecounter = mychar->action_timecounter_max;//该技能在玩家放开按键时才会解除
	}
	else
		enable = false;
}

bool CS_KingGuard::Hurt(std::weak_ptr<Entity> src, int* pGetDamage, float* pAngle, bool* pTakedown, int* pElemType, float* pShockForce, float* pHeavy, int* outRealDamage, bool* outRetVal)
{
	auto we = e.lock();
	if (!we)
		return false;
	auto wsrc = src.lock();
	if (!wsrc)
		return false;
	if (enable)
	{
		auto& getDamage = *pGetDamage;
		auto& angle = *pAngle;
		auto& takedown = *pTakedown;
		auto& elemType = *pElemType;
		auto& shockForce = *pShockForce;
		auto& heavy = *pHeavy;
		//无法阻挡的攻击
		if (wsrc->noDir)
			return false;
		//速度为方向的攻击（格挡物理物体）
		if (wsrc->speedDir)
		{
			//计算攻击角度
			int atkAngle = (int)roundf(XMConvertToDegrees(XMVectorGetX(XMVector2AngleBetweenVectors(XMVectorSet(1, 0, 0, 0), XMVectorSet(wsrc->vx, wsrc->vy, 0, 0)))));
			if (wsrc->vy < 0)
			{
				atkAngle = 360 - atkAngle;
			}
			if (we->lr == 0)
			{
				//格挡范围270 - 360 0 - 90

				if (!(
					(atkAngle >= 0 && atkAngle <= 90) ||
					(atkAngle >= 270 && atkAngle <= 360))
					)
					return false;
			}
			else
			{
				//格挡范围90 - 270
				if (!(atkAngle >= 90 && atkAngle <= 270))
					return false;
			}
		}
		//自身拥有方向的攻击
		else
		{
			//如果与攻击方向同向，则防御失败，被背击
			if (wsrc->lr == we->lr)
				return false;
		}
		block_ani_counter = block_ani_counter_max;
		//使这次攻击失效
		wsrc->attackState = false;
		//成功格挡声音和效果
		wsrc->gameFunc->PlaySound(L"CS_031_shot_bounce");
		auto vec = XMVector2Normalize(XMVectorSet(wsrc->x - we->x, wsrc->y - we->y, 0, 0));
		SetCS_PeGunShotHit(wsrc, we->x + XMVectorGetX(vec) * 16, we->y + XMVectorGetY(vec) * 16);
		//伤害冲击处理
		if (wsrc->speedDir)
		{
			//玩家朝格挡方向后退
			if (we->lr == 0)
				we->vx += shockForce;
			else
				we->vx -= shockForce;
		}
		else
		{
			if (shockForce > 0)
			{
				//被攻击弹反
				float radian = angle * deg2rad;
				we->vx += shockForce * cosf(radian);
				we->vy += shockForce * sinf(radian);
			}
		}
		//输出伤害
		shieldHP -= getDamage;
		if (shieldHP >= 0)
		{
			//成功格挡
			*outRealDamage = 0;
			//显示伤害值
			if (we->gameFunc->dmgNum)
				we->gameFunc->SetDmgNum(we->gameFunc->dmgNum, (int)*outRealDamage, we->x, we->y - 16, 1, we);
			if (shieldHP == 0)
			{
				//直接恢复回站立
				auto mychar = std::static_pointer_cast<CS_King>(we);
				mychar->action_timecounter = 0;
				//锁住该按键
				mychar->inputLock.key |= keyMask;
			}
			//如果玩家有电容器物品，成功格挡时会恢复1点能量
			if (we->gameFunc->PlayerHaveItem)
				if (we->gameFunc->PlayerHaveItem(we->gameFunc->game, L"Capacitor"))
					if (we->mp < we->mp_max)
						we->mp++;
			return true;
		}
		else
		{
			//格挡失败
			*outRealDamage = abs(shieldHP);
			//显示伤害值
			if (we->gameFunc->dmgNum)
				we->gameFunc->SetDmgNum(we->gameFunc->dmgNum, (int)*outRealDamage, we->x, we->y - 16, 1, we);
			return false;
		}
	}
	return false;
}
