#include "CS_KanpaFishingBlade.h"
#include "CS_Kanpa.h"
#include "CS_PeWaterDrop.h"
#include "PeSmog.h"
#include "CS_PeHurt.h"
#include "CS_Heart.h"
CS_KanpaFishingBlade::CS_KanpaFishingBlade(std::shared_ptr<Entity> parent)
{
	type = 2;
	attackParent = parent;
	//初始动画设置
	ani.png = L"CS_CaveStoryMod";
	ani.sprite_index = L"am_fishhook_90";
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	cbRect.fullWaterBlock = true;
	//设置碰撞框
	cbRect.left = cbRect.right = cbRect.top = cbRect.bottom = 4;
	damage_reset_counter = 30;
	attackState_reset_counter_max = 30;
	el.name = L"fishhook";
}

void CS_KanpaFishingBlade::Init(std::weak_ptr<Entity> self)
{
	stateGravity.Init(shared_from_this());
	Entity::Init(self);
}

void CS_KanpaFishingBlade::Step()
{
	auto wattackParent = attackParent.lock();
	if (!wattackParent)
		return;

	auto mychar = std::static_pointer_cast<CS_Kanpa>(wattackParent);
	if (hookFinish)
	{
		//鱼已上钩
		float dstX = mychar->x;
		float dstY = mychar->y - 16;
		//鱼和鱼钩回到玩家处
		last_x = x;
		last_y = y;
		x += (dstX - x) / 16;
		y += (dstY - y) / 16;
		auto wtarget = target.lock();
		if (wtarget)
		{
			wtarget->x = x;
			wtarget->last_x = last_x;
			wtarget->y = y;
			wtarget->last_y = last_y;
			wtarget->topDraw = true;
			float dx = dstX - x;
			float dy = dstY - y;
			if (dx * dx + dy * dy < 1)
			{
				//完成钓鱼
				wtarget->EndCaught(attackParent);
				wtarget->topDraw = false;
				target.reset();
				hitBox.reset();
				waitForHit = false;
				Destroy();
				mychar->inputLock.SetJump(true);
			}
		}
	}
	else
	{
		//控制鱼钩(在水中才能控制)
		if (cbRect.inWater)
		{
			if (waitForHit)
			{
				//如果产生了结果
				if (bHit)
				{
					//命中了
					if (hitResult)
					{
						int outRealDmg = 0; 
						gameFunc->PlaySound(L"CS_018_menu_select");
						auto wtarget = target.lock();
						if (wtarget)
						{
							if (wtarget->hp > 20)
							{
								//鱼挣脱
								wtarget->EndCaught(attackParent);
								//给鱼20伤害
								wtarget->Hurt(attackParent, 20, x > wtarget->x ? 180.0f : 0, false, 0, 0x200 / ts, 1, &outRealDmg);
								SetCS_PeHurt_Num3(shared_from_this(), x, y);
								target.reset();
								hitBox.reset();
								waitForHit = false;
							}
							else
							{
								auto wtarget = target.lock();
								if (wtarget)
								{
									//如果是boss鱼
									if (wtarget->hp_max >= 100)
									{
										//给鱼20伤害
										wtarget->Hurt(attackParent, 20, x > wtarget->x ? 180.0f : 0, false, 0, 0x200 / ts, 1, &outRealDmg);
										SetCS_PeHurt_Num3(shared_from_this(), x, y);
									}
									//将鱼掉上
									hookFinish = true;
									//释放hitbox
									auto whitBox = hitBox.lock();
									if (whitBox)
										whitBox->bLeave = true;
									hitBox.reset();
								}
							}
						}
					}
					else
					{
						gameFunc->PlaySound(L"CS_056_splash");
						auto wtarget = target.lock();
						//鱼挣脱
						if (wtarget)
							wtarget->EndCaught(attackParent);
						target.reset();
						hitBox.reset();
						waitForHit = false;
					}
					mychar->face = 0;
					mychar->showSweat = false;
				}
				else
				{
					auto mychar = std::static_pointer_cast<CS_Kanpa>(wattackParent);
					mychar->face = 1;
					mychar->showSweat = true;
				}
				vx = vy = 0;
			}
			else
			{
				MoveControl();
			}
		}
		else
		{
			setWaterSplash = true;
			//在地上只能掉落
			stateGravity.Step();
			if (cbRect.cbBottom)
			{
				Destroy();
				auto whitBox = hitBox.lock();
				if (whitBox)
					whitBox->Destroy();
				auto pe = std::make_shared<PeSmog>();
				pe->x = x;
				pe->y = y;
				gameFunc->SetEntity(shared_from_this(), pe);
			}
		}
		//落水水花
		if (setWaterSplash && cbRect.inWater)
		{
			setWaterSplash = false;
			//生成水花
			SetCS_PeWaterDrop(shared_from_this(), shared_from_this());
		}
		//清除最后一次碰撞结果
		Entity::ClearCollisionResult();
		//执行运动
		Entity::Step();
		//执行碰撞
		Entity::Collision();
		//如果离开的钓鱼状态
		if (!mychar->skillFishing.GetEnable() || mychar->cbRect.inWater)
		{
			auto whitBox = hitBox.lock();
			if (whitBox)
				whitBox->Destroy();
			Destroy();
			auto pe = std::make_shared<PeSmog>();
			pe->x = x;
			pe->y = y;
			gameFunc->SetEntity(shared_from_this(), pe);
		}
		//判定窗跟随
		auto whitBox = hitBox.lock();
		if (whitBox)
		{
			whitBox->x = x;
			whitBox->last_x = last_x;
			whitBox->y = y;
			whitBox->last_y = last_y;
		}
	}
}

void CS_KanpaFishingBlade::Attack(std::weak_ptr<Entity> dst, int* outDamage, float* outAngle, bool* outTakedown, int* outElemType, float* outShockForce, float* outHeavy)
{
	auto wdst = dst.lock();
	if (!wdst)
		return;
	auto wtarget = target.lock();

	if (wdst->hp <= 0 || wtarget || hookFinish)
		return;
	//不能钓心
	if (wdst->el.name == CS_HEART_CREATENAME)
		return;
	//碰到目标后尝试抓取
	auto wcaughtTarget = wdst->BeginCaught(attackParent).lock();
	if (!wcaughtTarget)
	{
		//如果目标无法抓取则被弹开
		const float speed = 0x400 / ts;
		auto vec = XMVector2Normalize(XMVectorSet(x - wdst->x, y - wdst->y, 0, 0));
		vx = XMVectorGetX(vec) * speed;
		vy = XMVectorGetY(vec) * speed;
		shock_counter = 30;
		return;
	}
	//抓住了对方
	target = wcaughtTarget;
	wtarget = target.lock();
	if (wtarget)
	{
		float dstCaughtDifficulty = wtarget->caughtDifficulty;
		if (gameFunc->pGameOption_difficulty)
			if (*gameFunc->pGameOption_difficulty == 0)
				dstCaughtDifficulty /= 2;
		//设置判定框
		auto whitBox = std::make_shared<CS_KanpaFishingBladeHitbox>(shared_from_this(), dstCaughtDifficulty);
		hitBox = whitBox;
		gameFunc->SetEntity(shared_from_this(), whitBox);
		waitForHit = true;
		bHit = false;
		hitResult = false;
	}
}

void CS_KanpaFishingBlade::Destroy()
{
	auto wattackParent = attackParent.lock();
	if (wattackParent)
	{
		auto mychar = std::static_pointer_cast<CS_Kanpa>(wattackParent);
		mychar->skillFishing.fishhook.reset();
		mychar->face = 0;
		mychar->showSweat = false;
	}
	Entity::Destroy();
}

void CS_KanpaFishingBlade::MoveControl()
{
	auto wattackParent = attackParent.lock();
	if (!wattackParent)
		return;

	auto& input = wattackParent->input;
	auto& inputLock = wattackParent->inputLock;
	auto& axis = wattackParent->axis;
	bool apply_resistH = true;
	bool apply_resistV = true;
	bool opUp = false;
	bool opDown = false;
	bool opLeft = false;
	bool opRight = false;
	//移动控制
	//上
	if (input.GetUp() || axis[0] < 0)
	{
		apply_resistV = false;
		ud = -1;
		//是否有手柄
		float joyMax_move;
		if (axis[0] < 0)
		{
			joyMax_move = max_move * -axis[0];
			//改变动画播放速度
			ani.image_counter_speed = -axis[0];
		}
		else
		{
			joyMax_move = max_move;
			ani.image_counter_speed = 1;
		}
		if (vy > -joyMax_move)
		{
			if (vy - move > -joyMax_move)
				vy -= move;
			else
				vy = -joyMax_move;
		}
		opUp = true;
	}
	//下
	else if (input.GetDown() || axis[1] > 0)
	{
		apply_resistV = false;
		ud = 1;
		//是否有手柄
		float joyMax_move;
		if (axis[1] > 0)
		{
			joyMax_move = max_move * axis[1];
			//改变动画播放速度
			ani.image_counter_speed = axis[1];
		}
		else
		{
			joyMax_move = max_move;
			ani.image_counter_speed = 1;
		}
		if (vy < joyMax_move)
		{
			if (vy + move < joyMax_move)
				vy += move;
			else
				vy = joyMax_move;
		}
		opDown = true;
	}
	else
	{
		ud = 0;
	}
	//左
	if (input.GetLeft() || axis[2] < 0)
	{
		apply_resistH = false;
		lr = 0;
		//是否有手柄
		float joyMax_move;
		if (axis[2] < 0)
		{
			joyMax_move = max_move * -axis[2];
			//改变动画播放速度
			ani.image_counter_speed = -axis[2];
		}
		else
		{
			joyMax_move = max_move;
			ani.image_counter_speed = 1;
		}
		if (vx > -joyMax_move)
		{
			if (cbRect.cbLeft)
				vx = -joyMax_move / 2;
			else
			{
				if (vx - move > -joyMax_move)
					vx -= move;
				else
					vx = -joyMax_move;
			}
		}
		opLeft = true;
	}
	//右
	else if (input.GetRight() || axis[3] > 0)
	{
		apply_resistH = false;
		lr = 1;
		//是否有手柄
		float joyMax_move;
		if (axis[3] > 0)
		{
			joyMax_move = max_move * axis[3];
			//改变动画播放速度
			ani.image_counter_speed = axis[3];
		}
		else
		{
			joyMax_move = max_move;
			ani.image_counter_speed = 1;
		}
		if (vx < joyMax_move)
		{
			if (cbRect.cbRight)
				vx = joyMax_move / 2;
			else
			{
				if (vx + move < joyMax_move)
					vx += move;
				else
					vx = joyMax_move;
			}
		}
		opRight = true;
	}
	//阻力
	if (apply_resistH)
		vx /= 1.1f;
	if (apply_resistV)
		vy /= 1.1f;

	if (opLeft && opUp)
		ani.sprite_index = L"am_fishhook_225";
	else if (opRight && opUp)
		ani.sprite_index = L"am_fishhook_315";
	else if (opLeft && opDown)
		ani.sprite_index = L"am_fishhook_135";
	else if (opRight && opDown)
		ani.sprite_index = L"am_fishhook_45";
	else if (opLeft)
		ani.sprite_index = L"am_fishhook_180";
	else if (opRight)
		ani.sprite_index = L"am_fishhook_0";
	else if (opUp)
		ani.sprite_index = L"am_fishhook_270";
	else if (opDown)
		ani.sprite_index = L"am_fishhook_90";
}
