#include "CS_Enemy_Redfish.h"
#include "CS_PeSmoke.h"
#include "CS_Exp.h"
#include "CS_PeWaterDrop.h"
CS_Enemy_Redfish::CS_Enemy_Redfish()
{
	//钓鱼难度
	caughtDifficulty = 0.7f;
	swimModeChangeCounter = 1;
}

void CS_Enemy_Redfish::SetState(int stateID, int lr)
{
	this->lr = lr;
	ani.sprite_index = lr == 0 ? L"ls_redfish_swim_l" : L"ls_redfish_swim_r";
}

void CS_Enemy_Redfish::HurtAnimate()
{
	ani.sprite_index = lr == 0 ? L"ls_redfish_hurt_l" : L"ls_redfish_hurt_r";
}

void CS_Enemy_Redfish::AnimateSpeedStep()
{
	float sp = max(abs(vx), abs(vy));
	ani.image_counter_speed = sp * 2;
	if (ani.image_counter_speed < 0.1f)
		ani.image_index = 0;
}

void CS_Enemy_Redfish::SwimStep()
{
	if (farAway_counter)
	{
		farAway_counter--;
		ResistStep();
		ani.sprite_index = lr == 0 ? L"ls_redfish_swim_l" : L"ls_redfish_swim_r";
	}
	else
	{
		//检查附近有没有玩家或者鱼钩
		bool playerHookAround = false;
		fleeList.clear();
		fleePos.clear();
		const float fleeDistance = 8.0f;
		//在抛射物中寻找鱼钩
		auto& allEntity = *gameFunc->GetLoadedEntity(gameFunc->entityRes);
		for (auto& p : allEntity)
		{
			auto& mapLayer = p.first;
			//只用主层
			if (mapLayer->layerType != 0)
				continue;
			auto& entityLayer = p.second;
			for (auto am : entityLayer.Am)
			{
				if (am->el.name == L"fishhook")
				{
					//加入和鱼钩之间的寻路距离
					auto cell = gameFunc->GetPath(shared_from_this(), am->x / 16, am->y / 16, x / 16, y / 16);
					if (cell->dis <= fleeDistance)
						fleeList.insert(std::make_pair(cell->dis, am));
				}
			}
		}
		//取所有玩家
		if (gameFunc->GetGlobalEntityTable)
		{
			auto& allPlayer = *gameFunc->GetGlobalEntityTable(gameFunc->game);
			for (auto& p : allPlayer)
			{
				auto wplayer = p.second.lock();
				if (wplayer)
				{
					if (wplayer->el.name == L"null")
						continue;
					auto cell = gameFunc->GetPath(shared_from_this(), wplayer->x / 16, wplayer->y / 16, x / 16, y / 16);
					if (cell->dis <= fleeDistance)
						fleeList.insert(std::make_pair(cell->dis, wplayer));
				}
			}
		}
		playerHookAround = !fleeList.empty();
		if (playerHookAround)
		{
			//玩家或者鱼钩在附近
			//鱼会尝试远离它
			float dirX = 0, dirY = 0;
			auto wdst = fleeList.begin()->second.lock();
			if (wdst)
				TestMaxDir(wdst->x, wdst->y, &dirX, &dirY);
			//改变游泳姿态
			float speed = Random(0x200, 0x600) / ts;
			vx += speed * dirX;
			vy += speed * dirY;
			lr = vx < 0 ? 0 : 1;
			farAway_counter = Random(0, 10);
		}
		else
		{
			//自然游动
			if (swimModeChangeCounter > 0)
			{
				swimModeChangeCounter--;
				if (swimModeChangeCounter == 0)
				{
					//改变游泳姿态
					float speedX = Random(-0x600, 0x600) / ts;
					float speedY = Random(-0x300, 0x300) / ts;
					vx += speedX;
					vy += speedY;
					lr = vx < 0 ? 0 : 1;
					swimModeChangeCounter = Random(10, 120);
				}
			}
			ResistStep();
			if (lr == 0 && cbRect.cbLeft)
			{
				lr = 1;
				vx = Random(0, 0x600) / ts;
			}
			else if (lr == 1 && cbRect.cbRight)
			{
				lr = 0;
				vx = Random(-0x600, 0) / ts;
			}
			ani.sprite_index = lr == 0 ? L"ls_redfish_swim_l" : L"ls_redfish_swim_r";
		}
	}
}

void CS_Enemy_Redfish::TestMaxDir(float dstX, float dstY, float* outDirX, float* outDirY)
{
	//测试自己周围9格，哪格距离最远
	int retDir = -1;
	float disMax = 0;
	auto cell_center = gameFunc->GetPath(shared_from_this(), dstX / 16, dstY / 16, x / 16, y / 16);
	disMax = cell_center->dis;

	for (int Y = -2; Y <= 2; Y++)
	{
		for (int X = -2; X <= 2; X++)
		{
			auto cell = gameFunc->GetPath(shared_from_this(), dstX / 16, dstY / 16, x / 16 + X, y / 16 + Y);
			if (cell->dis > disMax && PxaIsWater(GetMapPxa((int)(x / 16 + X), (int)(y / 16 + Y))))
			{
				auto dir = XMVector2Normalize(XMVectorSet((float)X, (float)Y, 0, 0));
				*outDirX = XMVectorGetX(dir);
				*outDirY = XMVectorGetY(dir);
			}
		}
	}
}

std::shared_ptr<Entity> CreateCS_Enemy_Redfish()
{
	return std::make_shared<CS_Enemy_Redfish>();
}
