#include "CS_Boss_Tap.h"
#include "CS_PeSmoke.h"
#include "PeSmog.h"
#include "CS_Boss_TapDmgRect.h"
#include "CS_AmWindShield.h"
#include "CS_AmTornado.h"
#include "CS_TapScissorsRain_Locater.h"
#include "CS_AmChainBat.h"
#include "CS_Boss_TapPress.h"
#include <random>
CS_Boss_Tap::CS_Boss_Tap()
{
	ani.png = L"CS_CaveStoryMod";
	ani.sprite_index = L"mc_tap_stand";
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	//设置碰撞框
	cbRect.left = cbRect.right = 16;
	cbRect.bottom = 8;
	cbRect.top = 32;
	hp_max = hp = 400;
	damage_reset_counter = 60;
	attackState_reset_counter_max = 60;
	drawBeforeOtherEntity = true;
	//设置攻击模式
	TapAttackMode mode[] =
	{
		TapAttackMode_Paper,
		TapAttackMode_Scissors,
		TapAttackMode_Rock,
	};
	for (auto& p : mode)
		attackModeList.push_back(p);
}

void CS_Boss_Tap::Init(std::weak_ptr<Entity> self)
{
	if (gameFunc->pGameOption_difficulty)
		if (*gameFunc->pGameOption_difficulty == 0)
			bNormalMode = true;
	stateGravity.Init(shared_from_this());
	stateSplash.Init(shared_from_this());
	auto wdmgRect = std::make_shared<CS_Boss_TapDmgRect>(std::static_pointer_cast<CS_Boss_Tap>(shared_from_this()));
	dmgRect = wdmgRect;
	gameFunc->SetEntity(shared_from_this(), wdmgRect);
	Entity::Init(self);
}

void CS_Boss_Tap::Step()
{
	if (initArg)
	{
		initArg = false;
		if (el.arg.length() && ParseInts(el.arg.c_str(), argbuff))
		{
			if (argbuff.size() == 2)
			{
				leftSide = 16.0f * argbuff[0];
				rightSide = 16.0f * argbuff[1];
			}
		}
	}
	stateSplash.Step();
	switch (stateID)
	{
	case 0://不动
		break;
	case 1:
		ani.image_index = 0;
		vy += 0x20 / ts;
		if (drop_counter > 0)
		{
			drop_counter--;
			cbRect.enableCbRect = false;
			cbRect.enableSoild = false;
		}
		else
		{
			cbRect.enableCbRect = true;
			cbRect.enableSoild = true;
		}
		if (cbRect.enableSoild)
		{
			if (cbRect.cbBottom)
			{
				for (int i = 0; i < 4; i++)
				{
					auto pe = std::make_shared<CS_PeSmoke>();
					pe->x = x + Random(-12, 12);
					pe->y = y + Random(-12, 12);
					pe->vx = Random(-341, 341) / ts;
					pe->vy = Random(-0x600, 0) / ts;
					gameFunc->SetEntity(shared_from_this(), pe);
				}
				gameFunc->PlaySound(L"CS_026_quake");
				if (gameFunc->SetQuake)
					gameFunc->SetQuake(gameFunc->game, 30, 0);
				stateID = 0;
			}
		}
		//限速
		if (vy > 0x5FF / ts)
			vy = 0x5FF / ts;
		if (vy < -0x5FF / ts)
			vy = -0x5FF / ts;
		break;
	case 2://战斗
		if (attackModeList.empty())
		{
			//随机生成两个模式
			for (auto i = 0; i < 2; i++)
				attackModeList.push_back((TapAttackMode)Random(0, 2));
		}
		else
		{
			//抽取下一个攻击模式
			auto mode = attackModeList.front();
			attackModeList.pop_front();
			switch (mode)
			{
			case TapAttackMode_Paper:
				stateID = 3;
				break;
			case TapAttackMode_Scissors:
				stateID = 20;
				break;
			case TapAttackMode_Rock:
				stateID = 40;
				break;
			}
		}
		bAction = true;
		break;
	case 3://布的攻击模式
		ani.sprite_index = L"mc_tap_paper";
		SetAttackRect(16, 16, 64, 8);
		action_timecounter = 16;
		windShield_count = 3;
		stateID = 4;
		break;
	case 4://转身等待
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			//选择一个玩家作为攻击目标
			if (gameFunc->GetPlayerDistance)
			{
				auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
				if (wplayer)
				{
					target = wplayer;
				}
			}
		}
		if (!target.expired())
		{
			//并转过身面对目标方向
			auto wtarget = target.lock();
			lr = x > wtarget->x ? 0 : 1;
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_side_l" : L"mc_tap_paper_side_r";
			SetAttackRect(16, 16, 64, 8);
			action_timecounter = 60;//设置风盾时间
			stateID = 5;
		}
		break;
	case 5://风盾
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_slap_l" : L"mc_tap_paper_slap_r";
			//设置叩击状态下的矩形框
			if (lr == 0)
				SetAttackRect(88, -8, 16, 8);
			else
				SetAttackRect(-8, 88, 16, 8);
			action_timecounter = 16;
			//进行叩击
			stateID = 6;
			//生成风盾
			auto am = std::make_shared<CS_AmWindShield>(shared_from_this(),true);
			am->x = x + (lr == 0 ? -32 : 32);
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
		}
		break;
	case 6://叩击停顿
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			if (windShield_count > 0)
			{
				windShield_count--;
				stateID = 4;
			}
			else
			{
				stateID = 7;
			}
		}
		break;
	case 7://进行冲锋
		if (lr == 0)
		{
			//向左冲撞
			if (bNormalMode)
				vx = -0x600 / ts;
			else
				vx = -0xc00 / ts;
			if (cbRect.cbLeft)
				stateID = 8;
		}
		else
		{
			//向右冲撞
			if (bNormalMode)
				vx = 0x600 / ts;
			else
				vx = 0xc00 / ts;
			if (cbRect.cbRight)
				stateID = 8;
		}
		walkSound += abs(vx);
		if (walkSound > 32)
		{
			walkSound -= 32;
			gameFunc->PlaySound(L"CS_107_block_move");
			SetPeSmog(shared_from_this(), x, y, 1, 1, lr == 0 ? 0 : 180.0f);
		}
		break;
	case 8://撞击停顿
		stateID = 9;
		action_timecounter = 60;
		break;
	case 9:
		switch (action_timecounter)
		{
		case 30://恢复站立
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_side_l" : L"mc_tap_paper_side_r";
			SetAttackRect(16, 16, 64, 8);
			break;
		case 20:
			ani.sprite_index = L"mc_tap_paper";
			SetAttackRect(16, 16, 64, 8);
			break;
		case 10://转身
			lr = lr == 0 ? 1 : 0;
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_side_l" : L"mc_tap_paper_side_r";
			SetAttackRect(16, 16, 64, 8);
			break;
		}
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_tornado_ready_l" : L"mc_tap_paper_tornado_ready_r";
			if(lr == 0)
				SetAttackRect(32, 8, 40, 8);
			else
				SetAttackRect(8, 32, 40, 8);
			if (bNormalMode)
				action_timecounter = 60;
			else
				action_timecounter = 30;
			stateID = 10;
		}	
		break;
	case 10://龙卷风准备
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = lr == 0 ? L"mc_tap_paper_tornado_hand_l" : L"mc_tap_paper_tornado_hand_r";
			if (lr == 0)
				SetAttackRect(32, 16, 40, 8);
			else
				SetAttackRect(16, 32, 40, 8);
			//生成龙卷
			auto am = std::make_shared<CS_AmTornado>(shared_from_this());
			am->x = x;
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
			action_timecounter = 30;
			stateID = 11;
		}
		break;
	case 11://龙卷风僵直时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			//恢复成掌
			ani.sprite_index = L"mc_tap_paper";
			SetAttackRect(16, 16, 64, 8);
			action_timecounter = 30;
			stateID = 12;
		}
		break;
	case 12://停顿时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
			stateID = 2;//进入下一个攻击模式
		break;
	case 20://剪刀的攻击模式
		ani.sprite_index = L"mc_tap_scissors";
		SetAttackRect(16, 16, 64, 8);
		action_timecounter = 30;
		stateID = 21;
		break;
	case 21://变身成剪刀
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			SetPeSmog(shared_from_this(), x, y, 8);
			ani.sprite_index = L"mc_tap_scissors_u";
			action_timecounter = 30;
			stateID = 22;
		}
		break;
	case 22://直到上升到屏幕之外
		cbRect.enableCbRect = false;
		cbRect.enableSoild = false;
		vy = -0x800 / ts;
		if (bNormalMode)
			vy = -0x400 / ts;
		vx = 0;
		if (y < -16)
		{
			vy = 0;
			action_timecounter = 30;
			stateID = 23;
		}
		break;
	case 23://剪刀雨的准备时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			//设置剪刀雨
			auto& roomRes = *gameFunc->GetLoadedEntity(gameFunc->entityRes);
			std::list<std::shared_ptr<Entity>>* pLs = nullptr;
			for (auto& p : roomRes)
			{
				if (p.first->layerType == 0)
				{
					pLs = &p.second.Ls;
					break;
				}
			}
			std::vector<std::shared_ptr<Entity>> arr;
			if (pLs)
			{
				for (auto& e : *pLs)
					if (e->el.name == CS_TAPSCISSORSRAIN_LOCATER_CREATENAME)
						arr.push_back(e);
			}
			std::random_device rd;
			std::mt19937 gen(rd());
			std::shuffle(arr.begin(), arr.end(), gen);

			scissorsFallLocation.clear();
			for (auto& e : arr)
			{
				e->SetState(L"fallscissors", (int)scissorsFallLocation.size() * 20);
				scissorsFallLocation.push_back(e->x);
			}
			action_timecounter = ((int)scissorsFallLocation.size() + 1) * 20 + 30;
			stateID = 24;
		}
		break;
	case 24://等待剪刀雨下落完毕
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			//自身变成剪刀最后一个下落
			ani.sprite_index = L"mc_tap_scissors_d";
			//随机选一个位置下落
			int index = Random(0, (int)scissorsFallLocation.size() - 1);
			x = scissorsFallLocation[index];
			y = -16;
			//特效
			auto wlightTail = std::make_shared<PeLightTail>(shared_from_this(), 40, 32.0f);
			lightTail = wlightTail;
			gameFunc->SetEntity(shared_from_this(), wlightTail);
			//固体
			cbRect.enableCbRect = true;
			cbRect.enableSoild = true;
			stateID = 25;
		}
		break;
	case 25://等待自身下落完毕
		vx = 0;
		vy = 0xc00 / ts;
		if (bNormalMode)
			vy = 0x600 / ts;
		if (cbRect.cbBottom)
		{
			auto wlightTail = lightTail.lock();
			if (wlightTail)
				wlightTail->Leave();
			lightTail.reset();
			//设置烟雾
			SetPeSmog(shared_from_this(), x, y, 8);
			gameFunc->PlaySound(L"CS_012_block_destroy");
			ani.sprite_index = L"mc_tap_scissors";
			SetAttackRect(16, 16, 64, 8);
			action_timecounter = 30;
			stateID = 26;
		}
		break;
	case 26://僵直时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			//选择一个玩家作为攻击目标
			if (gameFunc->GetPlayerDistance)
			{
				auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
				if (wplayer)
				{
					target = wplayer;
					lr = x > wplayer->x ? 0 : 1;
					ani.sprite_index = lr == 0 ? L"mc_tap_scissors_slash_ready_l" : L"mc_tap_scissors_slash_ready_r";
					action_timecounter = 30;
					slash_count = 2;
					bSetSlashDir = true;
					stateID = 27;
				}
			}
		}
		break;
	case 27://剪刀攻击模式2
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			if (bSetSlashDir)
				bSetSlashDir = false;
			else
				lr = lr == 0 ? 1 : 0;
			//特效
			auto wlightTail = std::make_shared<PeLightTail>(shared_from_this(), 40, 120.0f);
			lightTail = wlightTail;
			gameFunc->SetEntity(shared_from_this(), wlightTail);
			gameFunc->PlaySound(L"CS_106");
			ani.sprite_index = lr == 0 ? L"mc_tap_scissors_slash_l" : L"mc_tap_scissors_slash_r";
			stateID = 28;
		}
		if (action_timecounter / 2 % 2 == 0)
		{
			shader.usingShader = false;
		}
		else
		{
			shader.usingShader = true;
			shader.ps = shader.vs = L"flash";
		}
		break;
	case 28://剪刀斩击1
		if (bNormalMode)
			vx = lr == 0 ? -0xc00 / ts : 0xc00 / ts;
		else
			vx = lr == 0 ? -0x1800 / ts : 0x1800 / ts;
		if (lr == 0 && cbRect.cbLeft || lr != 0 && cbRect.cbRight)
		{
			ani.sprite_index = lr == 0 ? L"mc_tap_scissors_slash_ready_l" : L"mc_tap_scissors_slash_ready_r";
			action_timecounter = 30;
			if (slash_count > 0)
			{
				slash_count--;
				stateID = 27;
			}
			else
			{
				action_timecounter = 30;
				stateID = 29;
			}
			auto wlightTail = lightTail.lock();
			if (wlightTail)
				wlightTail->Leave();
			lightTail.reset();
		}
		break;
	case 29://斩击结束
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = L"mc_tap_scissors";
			SetAttackRect(16, 16, 64, 8);
			action_timecounter = 30;
			stateID = 30;
		}
		break;
	case 30://进入下一个攻击模式
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
			stateID = 2;
		break;
	case 40://石头的攻击模式
		ani.sprite_index = L"mc_tap_rock";
		SetAttackRect(16, 16, 32, 8);
		hammerblow_count = 2;
		action_timecounter = 30;
		stateID = 41;
		break;
	case 41://预备动作
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			if (bNormalMode)
				action_timecounter = 80;//设置上升时间
			else
				action_timecounter = 40;//设置上升时间
			stateID = 42;
		}
		break;
	case 42://上升
		cbRect.enableCbRect = false;
		cbRect.enableSoild = false;
		vx = 0;
		if (bNormalMode)
			vy = -0x400 / ts;
		else
			vy = -0x800 / ts;
		if (action_timecounter > 0)
		{
			action_timecounter--;
		}
		else
		{
			vy = 0;
			//选择一个玩家作为攻击目标
			if (gameFunc->GetPlayerDistance)
			{
				auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
				if (wplayer)
				{
					cbRect.enableCbRect = true;
					cbRect.enableSoild = true;
					target = wplayer;
					stateID = 43;
				}
					
			}		
		}
		break;
	case 43://跟踪玩家
		if (target.expired())
		{
			//重新选择一个玩家作为目标
			if (gameFunc->GetPlayerDistance)
			{
				auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
				if (wplayer)
					target = wplayer;
			}
		}
		else
		{
			auto wtarget = target.lock();
			bool bLock = false;
			if (abs(x - wtarget->x) >= 4)
			{
				if (x > wtarget->x)
				{
					vx = -0x800 / ts;
					if(bNormalMode)
						vx = -0x400 / ts;
					ani.sprite_index = L"mc_tap_rock_l";
					SetAttackRect(24, 24, 32, 8);
				}
				else
				{
					vx = 0x800 / ts;
					if (bNormalMode)
						vx = 0x400 / ts;
					ani.sprite_index = L"mc_tap_rock_r";
					SetAttackRect(24, 24, 32, 8);
				}
			}
			else
			{
				bLock = true;
			}
			if (x < leftSide)
			{
				last_x = x = leftSide;
				if(abs(x - wtarget->x) < 32)
					bLock = true;
			}
			if (x > rightSide)
			{
				last_x = x = rightSide;
				if (abs(x - wtarget->x) < 32)
					bLock = true;
			}	
			if(bLock)
			{
				//已锁定
				ani.sprite_index = L"mc_tap_rock_d";
				SetAttackRect(16, 16, 40, 8);
				action_timecounter = 60;
				stateID = 44;
			}
		}
		break;
	case 44://锁定玩家
		last_x = x;
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter > 20)
		{
			if (target.expired())
			{
				//目标丢失
				stateID = 43;
			}
			else
			{
				auto wtarget = target.lock();
				x = wtarget->x;
				vx = 0;
				vy = 0;
			}
		}
		if (x < leftSide)
			last_x = x = leftSide;
		if (x > rightSide)
			last_x = x = rightSide;
		if (action_timecounter == 0)
			stateID = 45;
		break;
	case 45://下锤
		vy = 0x1000 / ts;
		if(bNormalMode)
			vy = 0x800 / ts;
		vx = 0;
		if (cbRect.cbBottom)
		{
			int srcLr = lr;
			lr = 0;
			//两侧产生小风盾
			auto am = std::make_shared<CS_AmWindShield>(shared_from_this());
			am->x = x + (lr == 0 ? -32 : 32);
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
			lr = 1;
			am = std::make_shared<CS_AmWindShield>(shared_from_this());
			am->x = x + (lr == 0 ? -32 : 32);
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
			lr = srcLr;
			for (int i = 0; i < 4; i++)
			{
				auto pe = std::make_shared<CS_PeSmoke>();
				pe->x = x + Random(-12, 12);
				pe->y = y + Random(-12, 12);
				pe->vx = Random(-341, 341) / ts;
				pe->vy = Random(-0x600, 0) / ts;
				gameFunc->SetEntity(shared_from_this(), pe);
			}
			gameFunc->PlaySound(L"CS_026_quake");
			if (gameFunc->SetQuake)
				gameFunc->SetQuake(gameFunc->game, 30, 0);
			action_timecounter = 30;
			stateID = 46;
		}
		break;
	case 46://下锤的僵直时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = L"mc_tap_rock";
			SetAttackRect(16, 16, 32, 8);
			if (hammerblow_count > 0)
			{
				hammerblow_count--;
				stateID = 41;
			}
			else
			{
				stateID = 47;
			}
		}
		break;
	case 47://石头的攻击模式2 压路机【】
		action_timecounter = 60;
		stateID = 48;
		break;
	case 48:
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			if (chainBat.expired())
			{
				//选择一个玩家作为攻击目标
				if (gameFunc->GetPlayerDistance)
				{
					auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
					if (wplayer)
					{
						cbRect.enableCbRect = true;
						cbRect.enableSoild = true;
						target = wplayer;
						//生成锁链蝙蝠
						auto wchainBat = std::make_shared<CS_AmChainBat>(wplayer);
						chainBat = wchainBat;
						wchainBat->x = x;
						wchainBat->y = y;
						gameFunc->SetEntity(shared_from_this(), wchainBat);
						//产生烟雾
						SetPeSmog(shared_from_this(), x, y, 3);
					}

				}
			}
		}
		if (y < 0)
		{
			gameFunc->PlaySound(L"CS_026_quake");
			gameFunc->SetQuake(gameFunc->game, 30, 0);
			action_timecounter = 8 * 60;
			stateID = 49;
		}
		cbRect.enableCbRect = false;
		cbRect.enableSoild = false;
		vx = 0;
		vy = -0x800 / ts;
		if (bNormalMode)
			vy = -0x400 / ts;
		break;
	case 49://随机下落一些石块
		{
			auto& roomRes = *gameFunc->GetLoadedEntity(gameFunc->entityRes);
			std::list<std::shared_ptr<Entity>>* pLs = nullptr;
			for (auto& p : roomRes)
			{
				if (p.first->layerType == 0)
				{
					pLs = &p.second.Ls;
					break;
				}
			}
			std::vector<std::shared_ptr<Entity>> arr;
			if (pLs)
			{
				for (auto& e : *pLs)
					if (e->el.name == CS_TAPSCISSORSRAIN_LOCATER_CREATENAME)
						arr.push_back(e);
			}
			std::random_device rd;
			std::mt19937 gen(rd());
			std::shuffle(arr.begin(), arr.end(), gen);
			int i = 0;
			for (auto& e : arr)
			{
				if (i >= 6)
					break;
				e->SetState(L"fallrock", (i + 1) * 60);
				i++;
			}
			stateID = 50;
		}
		break;
	case 50://等待落石完成
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			auto wchainBat = chainBat.lock();
			if (wchainBat)
			{
				x = wchainBat->x;
				y = -32;
				vy = 0;
			}
			else
			{
				//选择一个玩家作为攻击目标
				if (gameFunc->GetPlayerDistance)
				{
					auto wplayer = gameFunc->GetPlayerDistance(gameFunc->game, x, y).lock();
					if (wplayer)
					{
						x = wplayer->x;
						y = -32;
						vy = 0;
					}
				}
			}
			//设置压路机
			ani.sprite_index = L"mc_tap_rock_d";
			SetAttackRect(16, 16, 40, 8);
			auto wpress = std::make_shared<CS_Boss_TapPress>(shared_from_this());
			press = wpress;
			wpress->x = x;
			wpress->y = y;
			gameFunc->SetEntity(shared_from_this(), wpress);
			stateID = 51;
		}
		break;
	case 51://等待压路机落地
		{
			auto wpress = press.lock();
			if (wpress && wpress->inUsing)
			{
				x = wpress->x;
				last_x = wpress->last_x;
				y = wpress->y - wpress->cbRect.top;
				last_y = wpress->last_y - wpress->cbRect.top;
				if (wpress->cbRect.cbBottom)
				{
					stateID = 0;
				}
				cbRect.enableCbRect = false;
				cbRect.enableSoild = false;
				cbRect.ignoreMovePlatform = true;
			}
			else
			{
				//破坏了
				cbRect.enableCbRect = true;
				cbRect.enableSoild = true;
				cbRect.ignoreMovePlatform = false;
				Entity::ClearCollisionResult();
				stateID = 52;
			}
		}
		break;
	case 52://下压到底
		vy = 0x1000 / ts;
		if (bNormalMode)
			vy = 0x800 / ts;
		vx = 0;
		if (cbRect.cbBottom)
		{
			int srcLr = lr;
			lr = 0;
			//两侧产生小风盾
			auto am = std::make_shared<CS_AmWindShield>(shared_from_this());
			am->x = x + (lr == 0 ? -32 : 32);
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
			lr = 1;
			am = std::make_shared<CS_AmWindShield>(shared_from_this());
			am->x = x + (lr == 0 ? -32 : 32);
			am->y = y;
			gameFunc->SetEntity(shared_from_this(), am);
			//接触锁链蝙蝠绑定
			auto wchainBat = chainBat.lock();
			if (wchainBat)
				wchainBat->SetState(L"release", 0);
			lr = srcLr;
			for (int i = 0; i < 4; i++)
			{
				auto pe = std::make_shared<CS_PeSmoke>();
				pe->x = x + Random(-12, 12);
				pe->y = y + Random(-12, 12);
				pe->vx = Random(-341, 341) / ts;
				pe->vy = Random(-0x600, 0) / ts;
				gameFunc->SetEntity(shared_from_this(), pe);
			}
			gameFunc->PlaySound(L"CS_026_quake");
			if (gameFunc->SetQuake)
				gameFunc->SetQuake(gameFunc->game, 30, 0);
			action_timecounter = 30;
			stateID = 53;
		}
		break;
	case 53://僵直时间
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
		{
			ani.sprite_index = L"mc_tap_rock";
			SetAttackRect(16, 16, 32, 8);
			stateID = 54;
		}
		break;
	case 54://进入下一个攻击模式
		if (action_timecounter > 0)
			action_timecounter--;
		if (action_timecounter == 0)
			stateID = 2;
		break;
	case 100://被击败
		ani.sprite_index = L"mc_tap_defeated";
		stateGravity.State();
		if (abs(vx) < 0.001f)
			vx = 0;
		else
			vx /= 1.05f;
		break;
	}
	srcVx = vx;
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	switch (stateID)
	{
	case 44:
	case 51:
		break;
	default:
		//执行运动
		Entity::Step();
		break;
	}
	//执行碰撞
	Entity::Collision();
	vx = srcVx;
	//维持在斜坡上
	Entity::KeepOnSlopes();
	//绑定dmgRect坐标
	auto wdmgRect = dmgRect.lock();
	if (wdmgRect)
	{
		wdmgRect->x = x;
		wdmgRect->y = y;
		wdmgRect->lr = lr;
	}
}

void CS_Boss_Tap::SetState(int stateID, int lr)
{
	this->lr = lr;
	if (stateID < 1000)
	{
		this->stateID = stateID;
		switch (stateID)
		{
		case 0:
			ani.sprite_index = L"mc_tap_stand";
			return;
		case 2://战斗
			return;
		}
	}
	else
	{
		this->stateID = 1;
		drop_counter = stateID - 1000;
		cbRect.enableCbRect = false;
		cbRect.enableSoild = false;
		//清除最后一次碰撞结果
		Entity::ClearCollisionResult();
	}
}

void CS_Boss_Tap::SetState(std::wstring stateName, int lr)
{
	if (stateName == L"normal_look")
	{
		ani.hideLayerList.insert(0);
		ani.hideLayerList.insert(1);
		ani.hideLayerList.insert(2);
		ani.hideLayerList.insert(3);
	}
	else if (stateName == L"left_look")
	{
		ani.hideLayerList.insert(0);
		ani.hideLayerList.insert(1);
		ani.hideLayerList.insert(2);
		ani.hideLayerList.erase(3);
	}
	else if (stateName == L"right_look")
	{
		ani.hideLayerList.insert(0);
		ani.hideLayerList.insert(1);
		ani.hideLayerList.erase(2);
		ani.hideLayerList.insert(3);
	}
	else if (stateName == L"down_look")
	{
		ani.hideLayerList.insert(0);
		ani.hideLayerList.erase(1);
		ani.hideLayerList.insert(2);
		ani.hideLayerList.insert(3);
	}
	else if (stateName == L"dead_fish_eyes")
	{
		ani.hideLayerList.erase(0);
		ani.hideLayerList.insert(1);
		ani.hideLayerList.insert(2);
		ani.hideLayerList.insert(3);
	}
	else if (stateName == L"fight")
	{
		SetState(2, lr);
	}
}

bool CS_Boss_Tap::Hurt(std::weak_ptr<Entity> src, int getDamage, float angle, bool bTakedown, int elemType, float shockForce, float heavy, int* outRealDamage)
{
	if (bHurtBlock)
		return false;
	if (!bAction)
		return false;
	if (getDamage < 5)
	{
		*outRealDamage = 0;
		return true;
	}
	if (hp == 0)
		return false;
	*outRealDamage = getDamage;
	shock_counter = 30;
	hp -= getDamage;
	if (hp > 0)
	{
		gameFunc->PlaySound(L"CS_052_enemy_hurt_big");
	}
	else
	{
		gameFunc->PlaySound(L"CS_071_little_crash");
		//创建云团
		SetCS_PeSmokeMedium(shared_from_this(), x, y);
		hp = 0;
		stateID = 100;
		damage_reset_counter = -1;
		attackState_reset_counter_max = -1;
		attackState = false;
		auto wdmgRect = dmgRect.lock();
		if (wdmgRect)
			wdmgRect->Destroy();
	}
	//伤害冲击处理
	if (shockForce > 0)
	{
		//被攻击弹反
		float radian = angle * deg2rad;
		vx = shockForce * cosf(radian);
		vy = shockForce * sinf(radian);
		vy -= 1;
	}
	//显示伤害值
	if (gameFunc->dmgNum)
		gameFunc->SetDmgNum(gameFunc->dmgNum, getDamage, x, y - 16, 0, shared_from_this());
	return true;
}

void CS_Boss_Tap::Destroy()
{
	auto wdmgRect = dmgRect.lock();
	if (wdmgRect)
		wdmgRect->Destroy();
	ActionEntity::Destroy();
}

void CS_Boss_Tap::SetAttackRect(float left, float right, float top, float bottom)
{
	auto wdmgRect = dmgRect.lock();
	if (wdmgRect)
	{
		wdmgRect->cbRect.left = left;
		wdmgRect->cbRect.right = right;
		wdmgRect->cbRect.top = top;
		wdmgRect->cbRect.bottom = bottom;
	}
}

std::shared_ptr<Entity> CreateCS_Boss_Tap()
{
	return std::make_shared<CS_Boss_Tap>();
}
