/*ボススクリプトや雑魚敵にて使用するローカルな関数ライブラリ*/

/*	定型変数	*/
let cx		= GetCenterX;
let cy		= GetCenterY;
let minx	= GetClipMinX;
let miny	= GetClipMinY;
let maxx	= GetClipMaxX;
let maxy	= GetClipMaxY;
let csd		= GetCurrentScriptDirectory;
/*	ここまで	*/


/*　フレーム制御関数　ここから　*/
function wait(w)//指定した数値フレーム待機する
{
	loop(w)
	{
		yield;
	}
}
/*　フレーム制御関数　ここまで　*/

/*　値を返す関数　ここから　*/
function GetAngleToAB(x1,y1,x2,y2)//特定の座標(x1,y1)から特定の座標(x2,y2)までの角度を求める。
{
	return atan2(y2-y1,x2-x1);
}
function GetLengthToAB(x1,y1,x2,y2)//特定の座標点１〜特定の座標点２までの距離を求める
{
	return ((x2-x1)^2+(y2-y1)^2)^(1/2);
}
function GetDouX(x,r,deg)//任意の座標から半径rの円を書いた時、指定された角度に直線を引いた時に円と交差するＸ座標を返す関数
{
	return x+r*cos(deg);
}
function GetDouY(y,r,deg)//任意の座標から半径rの円を書いた時、指定された角度に直線を引いた時に円と交差するＹ座標を返す関数
{
	return y+r*sin(deg);
}
/*　値を返す関数　ここまで　*/

/*　描画関係の関数　ここから　*/
function GraphicDefault//グラフィックの設定を初期に戻す関数
{
	SetGraphicScale(1,1);
	SetGraphicAngle(0,0,0);
	SetAlpha(255);
	SetColor(255,255,255);
	SetRenderState(ALPHA);
}
let TEXT_X=0;	let TEXT_Y=0;//DrawMusic専用外部変数
function DrawMusic(name)//汎用　曲名描画関数  ステージなら@DrawTopObjectで使用を推奨
{
	SetFontColor(200,200,200,100,100,100);
	TEXT_X+=5;
	if(TEXT_X<=maxx-64)
	{
		DrawText("♪"~name,maxx-TEXT_X,maxy-32,17,255);
	}
	else if(TEXT_X<=maxx+300)
	{
		DrawText("♪"~name,maxx-(maxx-64),maxy-32,17,255);
	}
	else
	{
		if(TEXT_Y<=32)
		{
			DrawText("♪"~name,maxx-(maxx-64),maxy-32+TEXT_Y,17,255);
			TEXT_Y+=0.5;
		}
	}
}
let COUNT_B=0;//DrawBackGraphic用内部変数
function DrawBackGraphic(name,x1,y1,x2,y2,rollx,rolly)//背景画像を表示する自動スクロール対応関数
{
	SetGraphicRect(x1,y1,x2,y2);
	SetTexture(name);
	let by=cy-y2+(COUNT_B*rolly)%y2;
	while(by<=cy+y2)
	{
		let bx=cx-x2+(COUNT_B*rollx)%x2;
		while(bx<=cx+x2)
		{
			DrawGraphic(bx,by);
			bx+=x2;
		}
		by+=y2;
	}
	COUNT_B++;
}
/*上の関数はHAL900のぺぇじ 様のところで公開されている物を改造した上で関数化した物です*/
let FADE_TIME=0;//フレームカウント数を取得するDrawCrossFadeText関数専用外部変数
let FADE_TEXTX=0;//描画位置をスライドするDrawCrossFadeText関数専用外部変数
function DrawCrossFadeText(name1,name2,textx1,texty1,textx2,texty2)//任意の文字列１を黄色い文字で表示、その下にクロスフェードのデフォルトカラーで文字列２を表示する関数
{

/*	お好み設定		*/
	let FontSize1=17;//	第１文字列の文字サイズ		初期は１７
	let FontSize2=17;//	第２文字列の文字サイズ		初期は１７
	let FadeStart=30;//	第２文字列の描画の開始時間	初期は３０フレーム
	let FadeIn=60;//	フェードインにかける時間	初期は６０フレーム
	let Draw=100;//		実体化状態の描画時間		初期は１２０フレーム
	let FadeOut=60;//	フェードアウトにかける時間	初期は６０フレーム
	let Shift=8;//		文字をスライドさせる量		初期は８　３未満だと正常な動作を保障しません
	let DrawEnd=0;//	全ての描画を終了する時間	初期は自動判定（フェードアウト終了と同時に全て消えます）
/*	お好み設定ここまで	*/

	if(DrawEnd<=FadeStart+FadeIn+Draw+FadeOut)//DrawEndが他の合計よりも少ない場合の処理
	{
		DrawEnd=FadeStart+FadeIn+Draw+FadeOut;
	}
	if(FADE_TIME<DrawEnd)//描画時間中
	{
		SetFontColor(240,240,0,255,255,255);//黄色っぽい文字に設定
		DrawText(name1,textx1,texty1,FontSize1,255);
		SetFontColor(255,255,255,255,255,255);//原色に設定する
		if(FADE_TIME<FadeStart)
		{
			;
		}
		else if(FADE_TIME<FadeStart+FadeIn)//フェードイン中の処理
		{
			FADE_TEXTX=(FadeStart+FadeIn)*Shift-FADE_TIME*Shift;
			DrawText(name2,textx2+FADE_TEXTX,texty2,FontSize2,128);//半透明で描画　右からスライド
			DrawText(name2,textx2-FADE_TEXTX,texty2,FontSize2,128);//半透明で描画　左からスライド
		}
		else if(FADE_TIME<FadeStart+FadeIn+Draw)//実体化処理　約2秒
		{
			DrawText(name2,textx2,texty2,FontSize2,255);//実体化描画
		}
		else if(FADE_TIME<FadeStart+FadeIn+Draw+FadeOut)//フェードアウト中の処理　約2秒
		{
			FADE_TEXTX=(FADE_TIME-FadeStart-FadeIn-Draw)*Shift;//初期値0　１フレーム毎に４増加　300引くのは最初を0にするため
			DrawText(name2,textx2+FADE_TEXTX,texty2,FontSize2,128);//半透明で描画　右からスライド
			DrawText(name2,textx2-FADE_TEXTX,texty2,FontSize2,128);//半透明で描画　左からスライド
		}
	}
	FADE_TIME++;//カウントを増やす
}
function ReverseText(text)//指定された文字列を逆にして返す関数
{//textには文字列を指定
	let w;
	let size=length(text)-1;
	ascent(i in 0..size/2)
	{
		w=text[i];
		text[i]=text[size-i];
		text[size-i]=w;
	}
	return text;
}
function DrawTextEx(text,x,y,size,alpha,type)//DrawTextに追加オプションを指定できるタイプ
{//typeには文字列で色々なタイプを指定できる　他はDrawTextと同じ
	let long=length(text);//文字数を求める
	let revtext=ReverseText(text);//逆文字を格納
	if(type=="REVERSE")//リバース機能を指定しているか
	{//リバース機能を指定していた
		DrawText(revtext,x,y,size,alpha);
	}
	else
	{
		ascent(line in 0..long)
		{
			if(type=="COLUMNAR")//縦書き指定か
			{
				DrawText(text[line],x,y+size*line,size,alpha);
			}
			else if(type=="REVERSE_COLUMNAR")//逆縦書き指定か
			{
				DrawText(revtext[line],x,y+size*line,size,alpha);
			}
			else if(type=="UP_LEFT")//左上書き指定か
			{
				DrawText(text[line],x-size*line,y-size*line,size,alpha);
			}
			else if(type=="UP_RIGHT")//右上書き指定か
			{
				DrawText(text[line],x+size*line,y-size*line,size,alpha);
			}
			else if(type=="DOWN_LEFT")//左下書き指定か
			{
				DrawText(text[line],x-size*line,y+size*line,size,alpha);
			}
			else if(type=="DOWN_RIGHT")//右下書き指定か
			{
				DrawText(text[line],x+size*line,y+size*line,size,alpha);
			}
			else if(type=="REVERSE_UP_LEFT")//左上書き指定か
			{
				DrawText(revtext[line],x-size*line,y-size*line,size,alpha);
			}
			else if(type=="REVERSE_UP_RIGHT")//右上書き指定か
			{
				DrawText(revtext[line],x+size*line,y-size*line,size,alpha);
			}
			else if(type=="REVERSE_DOWN_LEFT")//左下書き指定か
			{
				DrawText(revtext[line],x-size*line,y+size*line,size,alpha);
			}
			else if(type=="REVERSE_DOWN_RIGHT")//右下書き指定か
			{
				DrawText(revtext[line],x+size*line,y+size*line,size,alpha);
			}
		}
	}
}
/*　描画関係の関数　ここまで　*/

/*　ショット系の関数　ここから　*/
task CreateReflectShot01(x,y,speed,angle,graphic,delay,ref_box)//簡易的に１回だけ反射する弾を放つ
{//ref_boxの４要素の1 0配列を指定する　なお各要素は画像短形と同じ並び
	if(length(ref_box)!=4)
	{
		RaiseError("第７引数には４要素の数値型配列を指定してください","CreateReflectShot01宣言エラー");
	}
	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);
	while(Obj_BeDeleted(obj)==false)
	{
		speed=Obj_GetSpeed(obj);
		angle=Obj_GetAngle(obj);
		if(ref_box[0]==1 && Obj_GetX(obj)<=minx)//左方向反射
		{
			CreateShot01(minx+(minx-Obj_GetX(obj)),Obj_GetY(obj),speed,180-angle,graphic,0);
			Obj_Delete(obj);
		}
		if(ref_box[1]==1 && Obj_GetY(obj)<=miny)//上方向反射
		{
			CreateShot01(Obj_GetX(obj),miny+(miny-Obj_GetY(obj)),speed,0-angle,graphic,0);
			Obj_Delete(obj);
		}
		if(ref_box[2]==1 && Obj_GetX(obj)>=maxx)//右方向反射
		{
			CreateShot01(maxx-(Obj_GetX(obj)-maxx),Obj_GetY(obj),speed,180-angle,graphic,0);
			Obj_Delete(obj);
		}
		if(ref_box[3]==1 && Obj_GetY(obj)>=maxy)//下方向反射
		{
			CreateShot01(Obj_GetX(obj),maxy-(Obj_GetY(obj)-maxy),speed,0-angle,graphic,0);
			Obj_Delete(obj);
		}
		yield;
	}
}
task CreateReflectShot02(x,y,speed,angle,graphic,delay,ref_box)//簡易的に任意の回数だけ指定された壁で反射する弾を発射
{//ref_boxには各壁での反射回数を記述する　それ以外は01と同じ
	if(length(ref_box)!=4)
	{
		RaiseError("第７引数には４要素の数値型配列を指定してください","CreateReflectShot02宣言エラー");
	}
	let left=ref_box[0];
	let top=ref_box[1];
	let right=ref_box[2];
	let down=ref_box[3];
	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);
	while(Obj_BeDeleted(obj)==false)
	{
		speed=Obj_GetSpeed(obj);
		angle=Obj_GetAngle(obj);
		if(right>0 && Obj_GetX(obj)>=maxx)//右方向反射
		{
			if(right==1)
			{
				CreateShot01(maxx-(Obj_GetX(obj)-maxx),Obj_GetY(obj),speed,180-angle,graphic,0);
				Obj_Delete(obj);
			}
			else
			{
				Obj_SetAngle(obj,180-angle);
				Obj_SetX(obj,maxx-(Obj_GetX(obj)-maxx));
			}
			right--;
		}
		if(down>0 && Obj_GetY(obj)>=maxy)//下方向反射
		{
			if(down==1)
			{
				CreateShot01(Obj_GetX(obj),maxy-(Obj_GetY(obj)-maxy),speed,0-angle,graphic,0);
				Obj_Delete(obj);
			}
			else
			{
				Obj_SetAngle(obj,0-angle);
				Obj_SetY(obj,maxy-(Obj_GetY(obj)-maxy));
			}
			down--;
		}
		if(left>0 && Obj_GetX(obj)<=minx)//左方向反射
		{
			if(left==1)
			{
				CreateShot01(minx+(minx-Obj_GetX(obj)),Obj_GetY(obj),speed,180-angle,graphic,0);
				Obj_Delete(obj);
			}
			else
			{
				Obj_SetAngle(obj,180-angle);
				Obj_SetX(obj,minx+(minx-Obj_GetX(obj)));
			}
			left--;
		}
		if(top>0 && Obj_GetY(obj)<=miny)//上方向反射
		{
			if(top==1)
			{
				CreateShot01(Obj_GetX(obj),miny+(miny-Obj_GetY(obj)),speed,0-angle,graphic,0);
				Obj_Delete(obj);
			}
			else
			{
				Obj_SetAngle(obj,0-angle);
				Obj_SetY(obj,miny+(miny-Obj_GetY(obj)));
			}
			top--;
		}
		yield;
	}
}
function CreateRingShot01(x,y,r,deg,speed,angle,color,delay)//任意の座標から指定された角度deg方向の長さrの場所に弾を配置し、決められた速度と角度で発射する関数
{
	CreateShot01(GetDouX(x,r,deg),GetDouY(y,r,deg),speed,angle,color,delay);
}
/*　ショット形の関数　ここまで　*/
