#include "CS_Puppy.h"
#include "CS_PeSmoke.h"
#include "CS_Heart.h"
#include "CS_PuppyAi.h"
CS_Puppy::CS_Puppy()
{
	type = 1;
	//初始动画设置
	ani.png = L"CS_CaveStoryMod";
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	//设置碰撞框
	cbRect.left = cbRect.right = 5;
	cbRect.top = 6;
	cbRect.bottom = 8;
	//初始数值
	uiName = L"mimiga";
	saveName = CS_PUPPY_CREATENAME;
	throwItem = 0;
	throwItem_max = 0;
	throwItem_type = 1;
	hp_max = 100;
	hp = 100;
	mp_max = 5;
	mp = 0;
	//设置ai
	aiName = CS_PUPPYAI_CREATENAME;
}

void CS_Puppy::Init(std::weak_ptr<Entity> self)
{
	//添加状态控制器（也是执行顺序）
	AddState(&stateFlash);
	AddState(&stateInvincible);
	AddState(&stateGravity);
	AddState(&stateWater);
	AddState(&stateControl);
	AddState(&stateResist);//在stateControl后面
	AddState(&stateJump);
	AddState(&stateStand);
	AddState(&stateMove);
	AddState(&stateAir);
	AddState(&stateHurt);
	//添加技能
	AddSkill(&skillBite);
	//设置初始状态
	ChangeState(stateStand.GetStateID());
	//设置初始物理状态
	SetPhysice(false);
	//设置初始技能绑定
	SetSkillBindIndex(&skillBite, 0);
	skillBite.lock = false;
	stateStand.Step();
	MyCharEntity::Init(self);
}

void CS_Puppy::Step()
{
	//防止掉地图外面
	Entity::KeepInMap();
	//跟上移动平台
	Entity::BeginMovingPlatform();
	//状态机
	if (stateID == 0 && type == 1)
	{
		//玩家控制
		for (auto& p : stateList)
			p->Step();
		if (atkFeedBack > 0)
			atkFeedBack--;
		else if (action_timecounter > 0)
			action_timecounter--;
		if (enableAI)
		{
			CheckResetFollowTarget();
		}
	}
	else if (type == 0 || stateID != 0)
	{
		//动画
		switch (stateID)
		{
		case 0://站立
			stateStand.State();
			vx = 0;
			//重力
			stateGravity.State();
			break;
		case 1://移动
			//重力
			stateGravity.State();
			break;
		case 2://站立着
			vx = 0;
			if (action_timecounter > 0)
			{
				action_timecounter--;
				if(action_timecounter == 0)
					ani.sprite_index = lr == 0 ? L"mc_puppy_stand_l" : L"mc_puppy_stand_r";
			}
			//重力
			stateGravity.State();
			break;
		case 4:
			if (cbRect.cbBottom)
				ani.sprite_index = lr == 0 ? L"mc_puppy_lie_l" : L"mc_puppy_lie_r";
			else
				ani.sprite_index = lr == 0 ? L"mc_puppy_hurt_l" : L"mc_puppy_hurt_r";
			//重力
			stateGravity.State();
			//阻力
			stateResist.State();
			break;
		}
	}
	//更新UI
	MyCharEntity::UpdateUI();
	//风场
	Entity::Wind();
	//跟上移动平台
	Entity::EndMovingPlatform();
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	//动画延迟一帧
	if (animation_delay)
		animation_delay = false;
	else
		Entity::Step();//执行运动
	//执行碰撞
	Entity::Collision();
	//维持在斜坡上
	Entity::KeepOnSlopes();
}

void CS_Puppy::SetState(int stateID, int lr)
{
	this->stateID = stateID;
	this->lr = lr;
	switch (stateID)
	{
	case 0://没有动画（恢复玩家控制）
		faceToBack = false;
		vx = 0;
		break;
	case 1://移动
		animation_delay = true;
		ani.sprite_index = lr == 0 ? L"mc_puppy_move_l" : L"mc_puppy_move_r";
		vx = lr == 0 ? -animation_moveSpeed : animation_moveSpeed;
		ani.hideLayerList.erase(1);
		ani.hideLayerList.insert(0);
		stateStand.sit_counter = stateStand.sit_counter_max;
		break;
	case 2://站立着
		vx = vy = 0;
		ani.sprite_index = lr == 0 ? L"mc_puppy_stand_l" : L"mc_puppy_stand_r";
		ani.hideLayerList.erase(1);
		ani.hideLayerList.insert(0);
		stateStand.sit_counter = stateStand.sit_counter_max;
		break;
	case 3://站立吠叫
		action_timecounter = 8;
		ani.sprite_index = lr == 0 ? L"mc_puppy_stand_barking_l" : L"mc_puppy_stand_barking_r";
		gameFunc->PlaySound(L"CS_105_puppy_bark");
		this->stateID = 2;
		ani.hideLayerList.erase(1);
		ani.hideLayerList.insert(0);
		stateStand.sit_counter = stateStand.sit_counter_max;
		break;
	case 4://倒下
		if(cbRect.cbBottom)
			ani.sprite_index = lr == 0 ? L"mc_puppy_lie_l" : L"mc_puppy_lie_r";
		else
			ani.sprite_index = lr == 0 ? L"mc_puppy_hurt_l" : L"mc_puppy_hurt_r";
		ani.hideLayerList.erase(1);
		ani.hideLayerList.insert(0);
		stateStand.sit_counter = stateStand.sit_counter_max;
		break;
	}
}

void CS_Puppy::SetState(std::wstring stateName, int lr)
{
	MyCharEntity::SetState(stateName, lr);
	if (stateName == L"normal")
		SetState(0, lr);
	else if (stateName == L"walk")
		SetState(1, lr);
	else if (stateName == L"stand")
		SetState(2, lr);
	else if (stateName == L"stand_bark")
		SetState(3, lr);
	else if (stateName == L"lie")
		SetState(4, lr);
}

void CS_Puppy::LoadSaveData()
{
	MyCharEntity::LoadSaveData();
}

void CS_Puppy::WriteSaveData()
{
	MyCharEntity::WriteSaveData();
}

bool CS_Puppy::Hurt(std::weak_ptr<Entity> src, int getDamage, float angle, bool bTakedown, int elemType, float shockForce, float heavy, int* outRealDamage)
{
	if (hp == 0)
		return false;
	//运行事件时，无敌状态
	if (gameFunc->ScriptIsRunning)
	{
		if (gameFunc->ScriptIsRunning(gameFunc->gameScript))
			return false;
	}
	//状态处理
	for (auto& p : stateList)
	{
		bool retVal = true;
		if (p->Hurt(src, &getDamage, &angle, &bTakedown, &elemType, &shockForce, &heavy, outRealDamage, &retVal))
			return retVal;
	}
	//技能处理
	for (auto& p : skillList)
	{
		bool retVal = true;
		if (p->Hurt(src, &getDamage, &angle, &bTakedown, &elemType, &shockForce, &heavy, outRealDamage, &retVal))
			return retVal;
	}
	if (getDamage == 0)
		return false;
	*outRealDamage = getDamage;
	stateInvincible.SetDamage(getDamage);
	hp -= getDamage;
	gameFunc->PlaySound(L"CS_puppy_hurt");
	if (hp <= 0)
	{
		//创建云团
		SetCS_PeSmokeMedium(shared_from_this(), x, y);
		hp = 0;
		UpdateUI();
		//倒地
		SetState(L"lie", lr);
	}
	//伤害冲击处理
	if (shockForce > 0)
	{
		//被攻击弹反
		float radian = angle * deg2rad;
		vx = shockForce * cosf(radian);
		vy = shockForce * sinf(radian);
		vy -= 1;
	}
	//设置闪光
	stateFlash.flash_counter = 5;
	//显示伤害值
	if (gameFunc->dmgNum)
		gameFunc->SetDmgNum(gameFunc->dmgNum, getDamage, x, y - 16, 1, shared_from_this());
	//转换状态
	ChangeState(stateHurt.GetStateID());
	return true;
}

void CS_Puppy::Gain(std::weak_ptr<Entity> item)
{
	auto witem = item.lock();
	if (!witem)
		return;
	//拾取到了生命
	if (witem->el.name == CS_HEART_CREATENAME && witem->inUsing)
	{
		//生命恢复
		hp += witem->hp;
		if (hp > hp_max)
			hp = hp_max;
		gameFunc->PlaySound(L"CS_020_health_refill");
		witem->Destroy();
	}
}

void CS_Puppy::Destroy()
{
	MyCharEntity::Destroy();
}

void CS_Puppy::GetIcon(std::wstring& png, std::wstring& sprite_index, int& image_index, std::set<int>& hideLayerList)
{
	png = L"CS_CaveStoryMod";
	sprite_index = L"mc_puppy_sit_r";
	image_index = 0;
	hideLayerList = ani.hideLayerList;
}

void CS_Puppy::CheckResetFollowTarget()
{
	//AI自动分配跟随对象
	std::shared_ptr<Entity> wfollowTarget = attackParent.lock();
	if (wfollowTarget)
	{
		//查看当前跟随对象是否还有其他跟随对象
		auto& allPlayer = *gameFunc->GetGlobalEntityTable(gameFunc->game);
		for (auto& p : allPlayer)
		{
			auto wplayer = p.second.lock();
			if (wplayer)
			{
				if (wplayer->hide)
					continue;
				if (wplayer == shared_from_this())
					continue;
				if (wplayer->enableAI && 
					wplayer->attackParent.lock() == shared_from_this() && 
					wfollowTarget == wplayer)
				{
					//防止套环
					ResetFollowTarget();
					break;
				}
				if (wplayer->enableAI && wplayer->attackParent.lock() == wfollowTarget)
				{
					//重新分配一个跟随对象
					ResetFollowTarget();
					break;
				}
			}
		}
	}
	else
		ResetFollowTarget();
}

void CS_Puppy::ResetFollowTarget()
{
	auto& allPlayer = *gameFunc->GetGlobalEntityTable(gameFunc->game);
	for (auto& p : allPlayer)
	{
		auto wdst = p.second.lock();
		//选出一个跟随对象
		if (wdst)
		{
			if (wdst->hide)
				continue;
			if (wdst->el.name == L"null")
				continue;
			if (wdst == shared_from_this())
				continue;
			//查看当前跟随对象是否还有其他跟随对象
			bool bContinue = false;
			for (auto& t : allPlayer)
			{
				auto wsrc = t.second.lock();
				if (wsrc)
				{
					if (wsrc->hide)
						continue;
					if (wsrc == wdst)
						continue;
					if (wsrc->enableAI && wsrc->attackParent.lock() == wdst)
					{
						bContinue = true;
						break;
					}
				}
			}
			if (bContinue)
			{
				continue;
			}
			else
			{
				//跟随这个对象
				attackParent = wdst;
				break;
			}
		}
	}
}

std::shared_ptr<Entity> CreateCS_Puppy()
{
	return std::make_shared<CS_Puppy>();
}
