#東方弾幕風
#Title[「恋するハート」]
#Text[]
#ScriptVersion[2]

script_enemy_main {
	let name	= "「恋するハート」";

	// shot_all.png
	#include_function ".\lib_usershot.txt"
	// 白蓮さん初期設定
	#include_function ".\lib\setting_byakuren.txt"

	imgBlankCircle = GetCurrentScriptDirectory() ~ "\img\heart.png";

	// 初期位置
	let xIni	= GetCenterX;
	let yIni	= GetClipMinY + 125;

	let D_RATE = 80;
	let D_WAIT = 280;
	
	let BASE_SPEED = 1;	//速くすると判定がやばい！

	// ぐるぐるレーザー用
	let arrayLaser = [];		//半径を記録
	let arrayLaser_type = [];	//レーザーの種類を記録
	let LASER_GRAF = [205, 206, 207, 208, 209, 205, 206, 207, 208];
	let LASER_COUNT = 9;
	let LASER_SPEED = 1;	//円レーザーの縮まる速度
	
	let HP_FLAG = 0;
//	CreateDebugWindow;

	@Initialize {
		CutIn(YOUMU, name, "", 0, 0, 0, 0);

		SetLife(8000);
		SetTimer(120);
		SetScore(3000000);
		SetDamageRate(5, 5);

		Ini_Graphic;
		LoadGraphic(imgEffect);
		LoadGraphic(imgBlankCircle);

		TMain;
	}

	@MainLoop {
		SetCollisionA(GetX, GetY, 32);
		SetCollisionB(GetX, GetY, 16);

		yield;
	}

	@DrawLoop {
		Draw_Byakuren;
	}

	@Finalize {
		if (!IsTimeOut()) { makeTokutenItem(20); }
//		DeleteGraphic(imgBoss);
	}

	// メインタスク
	task TMain {
		yield;

		sub_effects;

		TRate;
		standBy;
		powerSave;
		effect_guruguru_circle(255,255,128);

		//弾
		wait(20);
		TShot;
	}

	//弾射出タスク
	task TShot()
	{
		TShot2;

		let t = 0;

		let special_shot = 0;
		let ctype = 0;
		let stop = 0;
		let finish = 0;

		//レーザー
		loop
		{
			if (GetLife() < 7500 && HP_FLAG <= 0) { special_shot = 1; HP_FLAG = 1; }
			else if (GetLife() < 6000 && HP_FLAG == 1) { special_shot = 1; HP_FLAG = 2; }
			else if (GetLife() < 4500 && HP_FLAG == 2) { special_shot = 1; HP_FLAG = 3; }
			else if (GetLife() < 2500 && HP_FLAG == 3) { special_shot = 1; HP_FLAG = 4; }
			
			if (special_shot)
			{
				special_shot = 0;
				if (HP_FLAG == 1) { ctype = 7; stop = 1; finish = 50; }
				else if (HP_FLAG == 2) { ctype = 5; stop = 1; finish = 68; }
				else if (HP_FLAG == 3) { ctype = 6; stop = 1; finish = 32; }
				else if (HP_FLAG == 4) { ctype = 8; stop = 1; finish = 86; }
				StopSE(SE_DON19);
				PlaySE(SE_DON19);
			}
			else
			{
				ctype = t%5;
				stop = 0;
				finish = 86;
				circle_heart(ctype, finish, stop);
			}
			circle_heart(ctype, finish, stop);
			
			t++;
			wait(180);
		}
	}

	task TShot2()
	{
		let gra = [US_STAR_M_BLUE, US_STAR_M_GREEN, US_STAR_M_YELLOW, US_STAR_M_ORANGE, US_STAR_M_RED, US_STAR_M_RED];
		let angle = GetAngleToPlayer;
		loop
		{
			angle += 8;
			let way = 16 + HP_FLAG*2;
			ascent(let n in 0 .. way)
			{
				shot_heart(GetX, GetY, BASE_SPEED, angle + n*360/16, gra[HP_FLAG], 5, 0, 0, 0);
			}
			wait(75);
		}
	}
	
	//一周レーザー　ハリボテ生成＋管理フラグ記録
	task circle_heart(gra_num, finish, stop)
	{
		let r = 370;
		gra_num = gra_num % LASER_COUNT;
		
		//空いている配列を探す
		let anum = 0;
		loop (length(arrayLaser))
		{
			if(arrayLaser[anum] == -1)	//初期化は-1で
			{
				break;
			}
			anum++;
		}
		
		//配列が足りない場合は追加
		//eraseしないのでanumの値ははタスク終了まで有効なはず→ダメなら修正
		if (anum >= length(arrayLaser))
		{
			loop(anum-length(arrayLaser)) { arrayLaser = arrayLaser~[-1]; }
			loop(anum-length(arrayLaser_type)) { arrayLaser_type = arrayLaser_type~[-1]; }
			arrayLaser = arrayLaser~[r];
			arrayLaser_type = arrayLaser_type~[gra_num];
		}
		else
		{
			arrayLaser[anum] = r;
			arrayLaser_type[anum] = gra_num;
		}
		
		StopSE(SE_BELL);
		PlaySE(SE_BELL);
		
		//レーザーを出す
		ascent (let i in 0 .. 16)
		{
			laser_haribote(anum, i, gra_num);
		}
		
		loop
		{
			if (arrayLaser[anum] < finish)
			{
				if (!stop)
				{
					//フラグを初期化し廃棄
					arrayLaser[anum] = -1;
					arrayLaser_type[anum] = -1;
				}
				break;
			}
			arrayLaser[anum] = arrayLaser[anum] - LASER_SPEED;
			
			yield;
		}
	}
	
	//一周レーザーのハリボテ（軌道変化の目印）
	//anum=レーザーのフラグ配列の参照先、フラグが初期化されるとレーザー削除
	task laser_haribote(anum, num, gra_num)
	{
		let obj = Obj_Create(OBJ_LASER);
		let angle = 360*num/16;
		let FLG = 0;

		ObjShot_SetGraphic(obj, LASER_GRAF[gra_num]);
		ObjLaser_SetSource(obj, false);
		ObjShot_SetBombResist(obj, true);
		Obj_SetCollisionToPlayer(obj, false);
		Obj_SetAutoDelete(obj, false);
		Obj_SetAlpha(obj, 160);
		ObjLaser_SetWidth(obj, 5);

		while(!Obj_BeDeleted(obj))
		{
			ObjLaser_SetLength(obj, arrayLaser[anum]*2*sin(360/32));
			Obj_SetPosition(obj, GetX() + arrayLaser[anum]*cos(angle), GetY() + arrayLaser[anum]*sin(angle));
			Obj_SetAngle(obj, angle-101.25);	//90+360/16/2=101.25
			
			//当たり判定セット
			if (!FLG && arrayLaser[anum] < 100)
			{
				Obj_SetAlpha(obj, 255);
				Obj_SetCollisionToPlayer(obj, true);
				FLG = 1;
			}

			yield;

			angle += 1;
			if (arrayLaser[anum] == -1) { break; }	//初期化された
		}

		ObjShot_FadeDelete(obj);
	}

	//レーザーに当たったら軌道を変える
	//当たると一定時間軌道の変化は起こらない
	//→重いので当たり判定チェックではなくフラグ管理にした。これでもまだ重い
	task shot_heart(x, y, speed, angle, graphic, delay, through, ignore5, ignore6)
	{
		if (GetEnemyShotCount() > 1000) { break; }	//重くなりやすいので弾数ストッパー
		
		let obj = Obj_Create(OBJ_SHOT);
		Obj_SetPosition(obj, x, y);
		Obj_SetSpeed(obj, speed);
		Obj_SetAngle(obj, angle);
		ObjShot_SetGraphic(obj, graphic);
		ObjShot_SetDelay(obj, delay);
		
		yield;	//保険
		
		let sx = speed * cos(angle);
		let sy = speed * sin(angle);
		while(!Obj_BeDeleted(obj))
		{
			if (through > 0)	//判定スルー
				{ through--; }
			else
			{
				//円に対して接線より外向きの角度なら
				//→外側から内側に向かう弾は判定に含めない（判定誤差はあるが多分問題なし）
				if ((sx*(Obj_GetX(obj)-GetX))+(sy*(Obj_GetY(obj)-GetY) > 0)) {
					//原点からの距離
					let r_start = ((Obj_GetX(obj)-GetX)^2 + (Obj_GetY(obj)-GetY)^2)^0.5;
					//↑の１frame後の距離
					let r_next = (((Obj_GetX(obj)+sx)-GetX)^2 + ((Obj_GetY(obj)+sy)-GetY)^2)^0.5;
					
					ascent (let i in 0 .. length(arrayLaser))
					{
						//r_startより外側にあり、１frame後にr_nextの内側に来る円を探す
						if(arrayLaser[i] > r_start && arrayLaser[i]-LASER_SPEED < r_next)
						{
							//through値を設定＆軌道変化（sx, syの更新も）
							through = 15;
							alternative (arrayLaser_type[i])
							case(0)
							{
								Obj_SetAngle(obj, Obj_GetAngle(obj)-45);
							}
							case(1)
							{
								Obj_SetAngle(obj, Obj_GetAngle(obj)+45);
							}
							case(2)
							{
								Obj_SetAngle(obj, Obj_GetAngle(obj)+cos(Obj_GetAngle(obj)*6)*30);
							}
							case(3)
							{
								Obj_SetAngle(obj, Obj_GetAngle(obj)+sin(Obj_GetAngle(obj)*6)*30);
							}
							case(4)
							{
								let ang = atan2(Obj_GetY(obj)-GetY, Obj_GetX(obj)-GetX);
							//	if (Obj_GetX(obj)-GetX > 0) { ang += 180; }
								Obj_SetAngle(obj, ang*2-Obj_GetAngle(obj));
							}
							case(5)
							{
								if (!ignore5)
								{
									//分裂（横）
									shot_heart(Obj_GetX(obj), Obj_GetY(obj), Obj_GetSpeed(obj), Obj_GetAngle(obj)+45, graphic, 0, 5, 1, ignore6);
									Obj_SetAngle(obj, Obj_GetAngle(obj)-45);
									ignore5 = 1;
									through = 5;
								}
							}
							case(6)
							{
								if (!ignore6)
								{
									//分裂（縦）
									shot_heart(Obj_GetX(obj), Obj_GetY(obj), Obj_GetSpeed(obj)*1.2, Obj_GetAngle(obj), graphic, 0, 5, ignore5, 1);
									Obj_SetSpeed(obj, Obj_GetSpeed(obj)*0.8);
									ignore6 = 1;
									through = 5;
								}
							}
							case(7)
							{
								//スピードアップ！
								Obj_SetSpeed(obj, Obj_GetSpeed(obj)*1.75);
								through = 5;
							}
							case(8)
							{
								//スピードアップ！
								Obj_SetSpeed(obj, Obj_GetSpeed(obj)*1.5);
								through = 5;
							}
							//再計算
							sx = Obj_GetSpeed(obj) * cos(Obj_GetAngle(obj));
							sy = Obj_GetSpeed(obj) * sin(Obj_GetAngle(obj));
							break;
						}
					}
				}
			}
			yield;
		}
		Obj_Delete(obj);
	}

}
