#include "CS_SantaGhostFireBlade.h"
#include "CS_PeGunShotSpark.h"
#include "CS_SantaGhostFireBladeTail.h"
#include "CS_SantaGhostFireBladeSpark.h"
#include <PeSmog.h>
#include "CS_PeGunShotHit.h"
#include "CS_PeHurt.h"
#include "CS_PeSmoke.h"

CS_SantaGhostFireBlade::CS_SantaGhostFireBlade(std::shared_ptr<Entity> parent, int level,int birthTime)
{
	type = 2;
	attackParent = parent;
	this->level = level;
	//设置光线
	auto wpeLight = std::make_shared<CS_PeLightFade>();
	peLight = wpeLight;
	parent->gameFunc->SetEntity(parent, wpeLight);
	auto wpeLightColor = std::make_shared<CS_PeLightFade>();;
	peLightColor = wpeLightColor;
	wpeLightColor->light.usingLight = false;
	wpeLightColor->color = RGBA(0xff, 0x98, 0, 0x10);
	parent->gameFunc->SetEntity(parent, wpeLightColor);
	//设置等级对应的各种属性
	SetLevel(level);
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	cbRect.fullWaterBlock = true;
	SetCbRect_Collision();
	//设置方向和初始位置
	ud = parent->ud;
	lr = parent->lr;
	birthTime_counter = birthTime;
	//初速度
	if (ud == -1)
	{
		vy = -1;
		vx = 0;
	}
	else if (ud == 0)
	{
		vy = 0;
		vx = lr == 0 ? -1.0f : 1.0f;
	}
	else
	{
		vy = 1;
		vx = 0;
	}
	SetDir(SpeedGetDir());
	if (ud == -1)
	{
		if (lr == 0)
			x = parent->x - 4;
		else
			x = parent->x + 4;
		y = parent->y - 12;
		SetCS_PeGunShotSpark(parent, x, y);
		x = parent->x;//修正
		y = parent->y - 8;//修正
	}
	else if (ud == 0)
	{
		y = parent->y;
		if (lr == 0)
		{
			x = parent->x - 12;
			SetCS_PeGunShotSpark(parent, x, y);
			x = parent->x - 7;//修正
		}
		else
		{
			x = parent->x + 12;
			SetCS_PeGunShotSpark(parent, x, y);
			x = parent->x + 7;//修正
		}
	}
	else
	{
		if (lr == 0)
			x = parent->x - 1;
		else
			x = parent->x + 1;
		y = parent->y + 10;
		SetCS_PeGunShotSpark(parent, x, y);
		x = parent->x;//修正
		y = parent->y + 8;//修正
	}
	//播放音效
	parent->gameFunc->PlaySound(L"CS_034_fireball");
	//绑定坐标
	wpeLight->last_x = wpeLight->x = x;
	wpeLight->last_y = wpeLight->y = y;
	wpeLightColor->last_x = wpeLightColor->x = x;
	wpeLightColor->last_y = wpeLightColor->y = y;
}

void CS_SantaGhostFireBlade::Step()
{
	if (birthTime_counter > 0)
		birthTime_counter--;
	//设置贴图
	if (ani.png.length() == 0)
	{
		ani.png = L"CS_CaveStoryMod";
	}
	//遇墙反弹
	if (cbRect.cbLeft)
	{
		vx = 1;
		lr = 1;
	}
	else if (cbRect.cbRight)
	{
		vx = -1;
		lr = 0;
	}
	else if (cbRect.cbTop)
		vy = 1;
	else if (cbRect.cbBottom)
		vy = -1;
	SetDir(SpeedGetDir());
	//过了存在时间则会掉级或者消失
	LevelDownStep();
	//尾巴效果
	TailStep();
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	//执行运动
	Entity::Step();
	//设置墙体碰撞矩形
	SetCbRect_Collision();
	//执行碰撞
	Entity::Collision();
	//设置实体碰撞矩形
	SetCbRect_Entity();
	//光线
	auto wpeLight = peLight.lock();
	if (wpeLight)
	{
		wpeLight->x = x;
		wpeLight->last_x = last_x;
		wpeLight->y = y;
		wpeLight->last_y = last_y;
	}
	auto wpeLightColor = peLightColor.lock();
	if (wpeLightColor)
	{
		wpeLightColor->x = x;
		wpeLightColor->last_x = last_x;
		wpeLightColor->y = y;
		wpeLightColor->last_y = last_y;
	}
	//遇水消散
	if (cbRect.inWater)
	{
		gameFunc->PlaySound(L"CS_070_expl_small");
		//创建云团
		SetCS_PeSmokeSmall(shared_from_this(), x, y);
		Destroy();
	}
	//卡墙里直接消失
	if (cbRect.cbLeft && cbRect.cbRight)
		Destroy();
	else if(cbRect.cbTop && cbRect.cbBottom)
		Destroy();
	//超出地图消失
	if (IsOutOfMap(128))
		Destroy();
}

void CS_SantaGhostFireBlade::Attack(std::weak_ptr<Entity> dst, int* outDamage, float* outAngle, bool* outTakedown, int* outElemType, float* outShockForce, float* outHeavy)
{
	//在诞生时间是没有伤害的
	if (birthTime_counter > 0)
		return;
	*outDamage = dmg;
	if (lr == 0)
	{
		*outAngle = 270;
	}
	else
	{
		*outAngle = 270;
	}
	*outTakedown = false;
	*outElemType = 0;
	*outShockForce = 0 / ts;
	*outHeavy = 0;
}

void CS_SantaGhostFireBlade::Feedback(std::weak_ptr<Entity> target)
{
	Destroy();
	//分裂成四个斜对角方向
	if (level > 0)
	{
		int targetLevel = level - 1;
		int birthTime = 30;
		static const int dirArr[] = { 7,9,1,3 };
		for (auto& i : dirArr)
		{
			auto wattackParent = attackParent.lock();
			if (wattackParent)
			{
				auto am = std::make_shared<CS_SantaGhostFireBlade>(wattackParent, targetLevel, birthTime);
				am->SetDir(i);
				am->last_x = am->x = x;
				am->last_y = am->y = y;
				auto wpeLight = am->peLight.lock();
				if (wpeLight)
				{
					wpeLight->last_x = wpeLight->x = x;
					wpeLight->last_y = wpeLight->y = y;
				}
				auto wpeLightColor = am->peLightColor.lock();
				if (wpeLightColor)
				{
					wpeLightColor->last_x = wpeLightColor->x = x;
					wpeLightColor->last_y = wpeLightColor->y = y;
				}
				gameFunc->SetEntity(wattackParent, am);
			}
		}
	}
}

void CS_SantaGhostFireBlade::AttackEffectObject(std::weak_ptr<Entity> target, float centerX, float centerY, int realDamage)
{
	if (realDamage == 0)
	{
		gameFunc->PlaySound(L"CS_031_shot_bounce");
		SetCS_PeGunShotHit(shared_from_this(), centerX, centerY);
	}
	else
	{
		auto wtarget = target.lock();
		if (wtarget)
		{
			if (wtarget->hp > 0)
				SetCS_PeHurt_Num3(shared_from_this(), centerX, centerY);
		}
	}
}

void CS_SantaGhostFireBlade::SetDir(int dirNum)
{
	switch (dirNum)
	{
	case 7:
		lr = 0;
		vx = moveSpeed * cosf(225 * deg2rad);
		vy = moveSpeed * sinf(225 * deg2rad);
		ani.sprite_index = L"am_ghostfire_l7";
		break;
	case 8:
		vx = moveSpeed * cosf(270 * deg2rad);
		vy = moveSpeed * sinf(270 * deg2rad);
		ani.sprite_index = lr == 0 ? L"am_ghostfire_l8" : L"am_ghostfire_r8";
		break;
	case 9:
		lr = 1;
		vx = moveSpeed * cosf(315 * deg2rad);
		vy = moveSpeed * sinf(315 * deg2rad);
		ani.sprite_index = L"am_ghostfire_r9";
		break;
	case 4:
		lr = 0;
		vx = moveSpeed * cosf(180 * deg2rad);
		vy = moveSpeed * sinf(180 * deg2rad);
		ani.sprite_index = L"am_ghostfire_l4";
		break;
	case 6:
		lr = 1;
		vx = moveSpeed * cosf(0 * deg2rad);
		vy = moveSpeed * sinf(0 * deg2rad);
		ani.sprite_index = L"am_ghostfire_r6";
		break;
	case 1:
		lr = 0;
		vx = moveSpeed * cosf(135 * deg2rad);
		vy = moveSpeed * sinf(135 * deg2rad);
		ani.sprite_index = L"am_ghostfire_l1";
		break;
	case 2:
		vx = moveSpeed * cosf(90 * deg2rad);
		vy = moveSpeed * sinf(90 * deg2rad);
		ani.sprite_index = lr == 0 ? L"am_ghostfire_l2" : L"am_ghostfire_r2";
		break;
	case 3:
		lr = 1;
		vx = moveSpeed * cosf(45 * deg2rad);
		vy = moveSpeed * sinf(45 * deg2rad);
		ani.sprite_index = L"am_ghostfire_r3";
		break;
	}
	if (abs(vx) < 0.001f)
		vx = 0;
	if (abs(vy) < 0.001f)
		vy = 0;
}

int CS_SantaGhostFireBlade::SpeedGetDir()
{
	if(vy < 0)
	{ 
		if (vx < 0)
			return 7;
		else if (vx == 0)
			return 8;
		else
			return 9;
	}
	else if (vy == 0)
	{
		if (vx < 0)
			return 4;
		else
			return 6;
	}
	else
	{
		if (vx < 0)
			return 1;
		else if (vx == 0)
			return 2;
		else
			return 3;
	}
}

void CS_SantaGhostFireBlade::SetLevel(int level)
{
	switch (level)
	{
	case 0:
		dmg = 1;
		moveSpeed = 0x600 / ts;
		break;
	case 1:
		dmg = 2;
		moveSpeed = 0x500 / ts;
		break;
	case 2:
		dmg = 3;
		moveSpeed = 0x400 / ts;
		break;
	case 3:
		dmg = 4;
		moveSpeed = 0x300 / ts;
		break;
	}
	auto wpeLight = peLight.lock();
	if (wpeLight)
		wpeLight->SetRadius(level + 4);
	auto wpeLightColor = peLightColor.lock();
	if (wpeLightColor)
		wpeLightColor->SetRadius(level + 4);
	ani.hideLayerList.insert(0);
	ani.hideLayerList.insert(1);
	ani.hideLayerList.insert(2);
	ani.hideLayerList.insert(3);
	ani.hideLayerList.erase(level);
}

void CS_SantaGhostFireBlade::LevelDownStep()
{
	if (levelDownTime_counter > 0)
	{
		levelDownTime_counter--;
		if (levelDownTime_counter == 0)
		{
			for (int i = 0; i <= level; i++)
			{
				SetPeSmog(shared_from_this(), x, y, 1, 1, (float)Random(0, 360));
			}
			if (level > 0)
			{
				//退化
				level--;
				SetLevel(level);
				levelDownTime_counter = levelDownTime_counter_max;
			}
			else
			{
				Destroy();
			}
		}
	}
}

void CS_SantaGhostFireBlade::TailStep()
{
	if (tailTime_counter > 0)
	{
		tailTime_counter--;
		if (tailTime_counter == 0)
		{
			//产生火球尾巴
			auto pe = std::make_shared<CS_SantaGhostFireBladeTail>(shared_from_this(), level);
			gameFunc->SetEntity(shared_from_this(), pe);
			tailTime_counter = tailTime_counter_max;
		}
	}
	if (Random(0, 100) < level*4)
	{
		//产生火花
		auto pe2 = std::make_shared<CS_SantaGhostFireBladeSpark>();
		pe2->x = x;
		pe2->y = y;
		gameFunc->SetEntity(shared_from_this(), pe2);
	}
}

void CS_SantaGhostFireBlade::SetCbRect_Entity()
{
	switch (level)
	{
	case 0:
		cbRect.left = cbRect.right = cbRect.top = cbRect.bottom = 4;
		break;
	case 1:
		cbRect.left = cbRect.right = cbRect.top = cbRect.bottom = 6;
		break;
	case 2:
		cbRect.left = cbRect.right = cbRect.top = cbRect.bottom = 7;
		break;
	case 3:
		cbRect.left = cbRect.right = cbRect.top = cbRect.bottom = 8;
		break;
	}
}

void CS_SantaGhostFireBlade::SetCbRect_Collision()
{
	cbRect.left = 3;
	cbRect.right = 3;
	cbRect.top = 3;
	cbRect.bottom = 3;
}

void CS_SantaGhostFireBlade::Destroy()
{
	auto wpeLight = peLight.lock();
	if (wpeLight)
		wpeLight->Destroy();
	auto wpeLightColor = peLightColor.lock();
	if (wpeLightColor)
		wpeLightColor->Destroy();
	Entity::Destroy();
}
