#include "CS_Boss_Malco.h"
#include "CS_PeSmoke.h"
#include "CS_Exp.h"
#include "CS_AmPhoton.h"
CS_Boss_Malco::CS_Boss_Malco()
{
	type = 2;
	ani.png = L"CS_CaveStoryMod";
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	cbRect.enableSelfSoild = true;
	cbRect.left = cbRect.right = 6;
	cbRect.top = 11;
	cbRect.bottom = 8;
	hp_max = hp = 40;
	damage_reset_counter = 60;
	attackState_reset_counter_max = 60;
	drawBeforeOtherEntity = true;
	turnBack_count = Random(1, 4);
}

void CS_Boss_Malco::Init(std::weak_ptr<Entity> self)
{
	if (gameFunc->pGameOption_difficulty)
	{
		if (*gameFunc->pGameOption_difficulty == 0)
		{
			bNormalMode = true;
			hp_max = hp = 10;
		}
	}
	stateResist.Init(shared_from_this());
	stateGravity.Init(shared_from_this());
	Entity::Init(self);
}

void CS_Boss_Malco::Step()
{
	if (hp <= 0)
	{
		attackState = false;
		return;
	}
	const float moveSpeed = 0x20 / ts;
	int readyTime;
	//跟上移动平台
	Entity::BeginMovingPlatform();
	stateResist.apply_resistH = cbRect.cbBottom;
	stateGravity.Step();
	switch (stateID)
	{
	case 0://加速冲向玩家直到撞墙
		//如果撞墙则转向
		if (cbRect.cbLeft)
		{
			lr = 1;
			gameFunc->PlaySound(L"CS_071_little_crash");
			SetCS_PeSmokeMedium(shared_from_this(), x, y);
			if (gameFunc->SetQuake)
				gameFunc->SetQuake(gameFunc->game, 30, 0);
			//撞墙后会跳起来
			if (Random(0, 10) <= 4)
				vy = -1600 / ts;
			//切换发射激光状态
			if (turnBack_count > 0)
			{
				turnBack_count--;
				if (turnBack_count == 0)
				{
					stateID = 1;
					action_timecounter = 60;
				}
			}
				
		}	
		else if (cbRect.cbRight)
		{
			lr = 0;
			gameFunc->PlaySound(L"CS_071_little_crash");
			SetCS_PeSmokeMedium(shared_from_this(), x, y);
			if (gameFunc->SetQuake)
				gameFunc->SetQuake(gameFunc->game, 30, 0);
			//撞墙后会跳起来
			if (Random(0, 10) <= 4)
				vy = -1600 / ts;
			//切换发射激光状态
			if (turnBack_count > 0)
			{
				turnBack_count--;
				if (turnBack_count == 0)
				{
					stateID = 1;
					action_timecounter = 60;
				}
			}
		}
		if (lr == 0)
			vx -= moveSpeed;
		else
			vx += moveSpeed;
		stateResist.apply_resistH = false;
		ani.sprite_index = lr == 0 ? L"ls_malco_move_l" : L"ls_malco_move_r";
		break;
	case 1://发射激光
		//转身后过1秒
		if (action_timecounter > 0)
		{
			action_timecounter--;
			break;
		}
		//准备发射激光
		readyTime = 100;
		if (hp <= hp_max / 2)
			readyTime -= 75;
		if (++act_wait > readyTime && act_wait % 6 == 1)
		{
			float deg = 0;
			if (lr == 0)
				deg = -180;
			else
				deg = 0;
			deg += Random(-22, 22);
			SetCS_AmPhoton(shared_from_this(), x + (lr == 0 ? -4.0f : 4.0f), y,
				3 * cosf(deg * deg2rad), 3 * sinf(deg * deg2rad));
			gameFunc->PlaySound(L"CS_012_block_destroy");
		}
		if (shock_counter > 0)
			act_wait++;
		if (act_wait > 50 && act_wait / 2 % 2)
			ani.image_index = 1;
		else
			ani.image_index = 0;
		//恢复为冲撞模式
		readyTime = 132;
		if (hp <= hp_max / 2)
			readyTime -= 50;
		if (act_wait > readyTime)
		{
			stateID = 0;
			turnBack_count = Random(1, 4);
			act_wait = 0;
		}
		ani.sprite_index = lr == 0 ? L"ls_malco_stand_l" : L"ls_malco_stand_r";
		break;
	}

	//限速
	if (bNormalMode)
	{
		if (vx > 0x300 / ts)
			vx = 0x300 / ts;
		if (vx < -0x300 / ts)
			vx = -0x300 / ts;
	}
	else
	{
		if (vx > 0x5ff / ts)
			vx = 0x5ff / ts;
		if (vx < -0x5ff / ts)
			vx = -0x5ff / ts;
	}
	stateResist.Step();
	//跟上移动平台
	Entity::EndMovingPlatform();
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	//执行运动
	Entity::Step();
	//执行碰撞
	Entity::Collision();
	//维持在斜坡上
	Entity::KeepOnSlopes();
}

void CS_Boss_Malco::SetState(int stateID, int lr)
{
	this->lr = lr;
	this->stateID = stateID;
	ani.sprite_index = lr == 0 ? L"ls_malco_stand_l" : L"ls_malco_stand_r";
}

void CS_Boss_Malco::Attack(std::weak_ptr<Entity> dst, int* outDamage, float* outAngle, bool* outTakedown, int* outElemType, float* outShockForce, float* outHeavy)
{
	*outDamage = 3;
	auto wdst = dst.lock();
	if (wdst)
	{
		if (wdst->lr == 0)
		{
			*outAngle = 315;
		}
		else
		{
			*outAngle = 225;
		}
	}
	*outTakedown = true;
	*outElemType = 0;
	*outShockForce = 0x200 / ts;
	*outHeavy = 2;
}

bool CS_Boss_Malco::Hurt(std::weak_ptr<Entity> src, int getDamage, float angle, bool bTakedown, int elemType, float shockForce, float heavy, int* outRealDamage)
{
	if (getDamage == 0)
		return false;
	if (hp == 0)
		return false;
	*outRealDamage = getDamage;
	shock_counter = 30;
	hp -= getDamage;
	if (hp > 0)
	{
		gameFunc->PlaySound(L"CS_051_enemy_hurt");
	}
	else
	{
		gameFunc->PlaySound(L"CS_071_little_crash");
		//创建云团
		SetCS_PeSmokeMedium(shared_from_this(), x, y);
		hp = 0;
	}
	//显示伤害值
	if (gameFunc->dmgNum)
		gameFunc->SetDmgNum(gameFunc->dmgNum, getDamage, x, y - 16, 0, shared_from_this());
	return true;
}

std::shared_ptr<Entity> CreateCS_Boss_Malco()
{
	return std::make_shared<CS_Boss_Malco>();
}
