task PointExtend(){
#include_function ".\Config.txt"

let ExtendPoint = [500,1500,2750,4500,6000,8000,9999,3333,6666,9999];//エクステンドの点符必要数の羅列

if(ChooseMode == 9){ExtendPoint = [1234,5555,9999,5000,9999];}
let ExtendCount = 0;				//エクステンド回数を記憶する変数
let Point = GetPoint;				//Pointの値を格納する変数
let Continue = 3;
let OverExtendBonusCount = 0;
if(ChooseMode == 9){Continue = 0;}
loop{
if(GetAllowedContinueCount != Continue){	//コンティニューしたら
ExtendCount = 0;				//本家同様、エクステンドの値を初期値に
Continue--;					//コンティニュー回数−１
}
Point = GetPoint;				//取得数を毎フレーム確認
SetNormPoint(ExtendPoint[ExtendCount]);		//次のエクステンドの数を毎フレーム表示
if(Point >= ExtendPoint[ExtendCount]){		//エクステンドの値を超えたら

	if(GetPlayerLife >= 8&&GetPlayerBomb >= 6){//残機７以上でボム６以上ならボーナス250万点
	AddScore(2500000+OverExtendBonusCount*750000);
	OverExtendBonusCount++;}
	if(GetPlayerLife >= 8&&GetPlayerBomb == 5){//残機７以上でボム５ならボム＋１
	AddBomb(1);}
	if(GetPlayerLife >= 8&&GetPlayerBomb <= 4){//残機７以上でボム４以下ならボム＋２
	AddBomb(2);}
	if(GetPlayerLife <= 7){ExtendPlayer(1);}//残機６以下なら残機＋１
	PlaySE("se1UP.wav");			//エクステンド音を鳴らす
	if(ExtendPoint[ExtendCount] == 9999){
	AddPoint(-9999);			//9999を越えたら9999減らす
	}
	if(ExtendCount == 9&&ChooseMode != 9){ExtendCount = 6;}	//エクステンドをループさせる
	if(ExtendCount == 4&&ChooseMode == 9){ExtendCount = 2;}
	ExtendCount++;				//エクステンド回数＋１
	}
yield;

}
}

task MagicPointOnStage(){

#include_function ".\Config.txt"

SetCommonData("MAGICPOINT",0);
SetCommonData("DRAWBONUS",0);
SetCommonData("DRAWMAX",0);
SetCommonData("FULLITEM_GET",0);
yield;
let E = GetCommonData("EASY_START");
let N = GetCommonData("NORMAL_START");
let H = GetCommonData("HARD_START");
let L = GetCommonData("LUNATIC_START");
let EX = GetCommonData("EXTRA_START");

let AddToEnemy;
let ReduceToLive;
let ReduceToMissRate = [0,0.1,0.4,0.9,1.6,2.5,3.6,5];
let Level;
let Difficultly;
let Graze = GetGraze;
let GrazeA = 0;
let Point = GetPoint;
let PointA = GetPoint;

let FirstPlayer = ChoosePlayerLife() - 4;
let ReduceToFirstPlayer = [1.5,3,5,7,10];
let ReduceRateUp = 1;
let Count = 0;

if(E == 1){SetCommonData("MAGICPOINT",5);AddToEnemy = 0.8;ReduceToLive = 0.008333;Level = 10;Difficultly = 0;}
if(N == 1){SetCommonData("MAGICPOINT",10);AddToEnemy = 1.4;ReduceToLive = 0.009527;Level = 12;Difficultly = 1;}
if(H == 1){SetCommonData("MAGICPOINT",15);AddToEnemy = 2.0;ReduceToLive = 0.011115;Level = 16;Difficultly = 2;}
if(L == 1){SetCommonData("MAGICPOINT",25);AddToEnemy = 3.0;ReduceToLive = 0.016667;Level = 20;Difficultly = 3;}
if(EX == 1){SetCommonData("MAGICPOINT",300);AddToEnemy = 10.0;ReduceToLive = 0.033334;Level = 20;Difficultly = 0.5;}
if(E > 1){SetCommonData("MAGICPOINT",25);AddToEnemy = 0.8;ReduceToLive = 0.008333;Level = 10;Difficultly = 0;}
if(N > 1){SetCommonData("MAGICPOINT",50);AddToEnemy = 1.4;ReduceToLive = 0.009527;Level = 12;Difficultly = 1;}
if(H > 1){SetCommonData("MAGICPOINT",75);AddToEnemy = 2.0;ReduceToLive = 0.011115;Level = 16;Difficultly = 2;}
if(L > 1){SetCommonData("MAGICPOINT",125);AddToEnemy = 3.0;ReduceToLive = 0.016667;Level = 20;Difficultly = 3;}

let bonusrate = 1 / (10 + 7 * Difficultly);

SetCommonData("MAGICPOINT_ADD",AddToEnemy);
SetCommonData("MAGICPOINT_REDUCE",ReduceToLive);
SetCommonData("MAGICPOINT_BONUSRATE",bonusrate);

let PMP = PlacticeMagicPoint;


if(IsReplay == false){SetCommonData("PLACTICE_MAGICPOINT",PMP);
SaveCommonDataInReplayFile();}

PMP = GetCommonData("PLACTICE_MAGICPOINT");

if(E > 1||N > 1||H > 1||L > 1){
if(GetCommonData("PLACTICE_MAGICPOINT") >= 0){SetCommonData("MAGICPOINT",PMP);}
}

if(FirstPlayer >= 0){ReduceRateUp = ReduceToFirstPlayer[FirstPlayer];}

loop{
	Count++;
	let a	= GetCommonData("MAGICPOINT");
	let zanki = GetPlayerLife;
	if(zanki >= 8){zanki = 7;}
	let ReduceToMiss;
	Graze = GetGraze;

	if(Count >= 90){SetCommonData("BONUSSCORE",0);
	SetCommonData("DRAWBONUS",0);
	SetCommonData("DRAWMAX",0);}

	if(Graze != GrazeA){
	a += (Difficultly  + 1) * zanki * 0.0375;
	GrazeA = Graze;
	SetCommonData("MAGICPOINT",a);
	}

	if(OnBomb == true){
	PointA = GetPoint;
	let b;
	let PMS = GetPlayerMoveState();


	if(PMS == MOVE_NORMAL){
	b = (a * 0.6) / ReduceRateUp;
	SetCommonData("MAGICPOINT",b);
	while(OnBomb == true){yield;	CollectItems;}
	Point = GetPoint;
	if(PointA > Point){Point += 9999;}
	let Bonus = trunc((Point - PointA) * ((((a / 1000) ^ 2) * 12.5) ^ 2) * 10);

	AddScore(-7500 * (Point - PointA));
	AddScore(Bonus);
	if(Bonus != 0){
	SetCommonData("BONUSSCORE",Bonus);
	yield;
	SetCommonData("DRAWBONUS",1);
	Count = 0;
	b = a + Bonus / 10000;
	SetCommonData("MAGICPOINT",b);
	}
	}

	else if(PMS == MOVE_SLOW){
	let n;
	b = (a * 0.93) / ReduceRateUp;
	SetCommonData("MAGICPOINT",b);
	while(OnBomb == true){yield;	CollectItems;}
	Point = GetPoint;
	if(PointA > Point){Point += 9999;}
	if(Difficultly <= 1){n = 50;}
	else{n = 50 + (Difficultly - 1) * 25;}
	let BonusP = trunc((Point - PointA) * (0.5 - Difficultly * 0.0625) + (b / n));

	CreateEnemyFromFile(GetCurrentScriptDirectory~"\Stage\ZAKO\Enemy00.txt",GetCenterX,GetCenterY,0,0,BonusP+1);

	AddScore(-15000 * (Point - PointA));
	SetCommonData("BONUSSCORE",BonusP+1);
	loop(2){yield;}
	SetCommonData("DRAWBONUS",2);
	Count = 0;
	CollectItems;
	}


	}

	if(OnPlayerMissed == true){
	while(OnPlayerMissed == true){yield;}//喰らいボム時間待機
	if(OnBomb == false){//喰らいボムに失敗していたら減少させる
	ReduceToMiss = Level * ReduceToMissRate[zanki] * ReduceRateUp;
	a -= ReduceToMiss;
	if(0 >= a){a = 0;}//MasicPointが０以下になったら０にする
	SetCommonData("MAGICPOINT",a);
	}
	}

	if(GetCommonData("FULLITEM_GET") == 1){
	Count = 0;
	SetCommonData("FULLITEM_GET",0);
	SetCommonData("DRAWMAX",1);
	}

	if(Difficultly <= 1){
	if(a > 999.999999){
	a = 999.999999;
	SetCommonData("MAGICPOINT",a);
	}
	}
	if(Difficultly == 2){
	if(a > 1499.999999){
	a = 1499.999999;
	SetCommonData("MAGICPOINT",a);
	}
	}
	if(Difficultly == 3){
	if(a > 1999.999999){
	a = 1999.999999;
	SetCommonData("MAGICPOINT",a);
	}
	}
	if(Difficultly == 0.5){
	if(a > 2999.999999){
	a = 2999.999999;
	SetCommonData("MAGICPOINT",a);
	}
	}
yield;
}
}


function MagicPointDrawText(){

function NumToString(let num){
let leng = trunc(log10(num))+1;//整数部分の桁数を求める
let string = ToString(num);//数字を文字列に変える
let lengA = 0;

if(leng < 2&& leng >= 1){lengA = 1;}
if(leng < 3&& leng >= 2){lengA = 2;}
if(leng < 4&& leng >= 3){lengA = 3;}
if(leng < 5&& leng >= 4){lengA = 4;}
if(leng < 6&& leng >= 5){lengA = 5;}
if(leng < 7&& leng >= 6){lengA = 6;}
if(leng < 8&& leng >= 7){lengA = 7;}
if(leng < 9&& leng >= 8){lengA = 8;}
if(leng < 10&& leng >= 9){lengA = 9;}
if(leng >= 10){lengA = 10;}

loop(10 - lengA){
string = " "~string;
}

return string[0..10];//文字列をスライシングして返す
}

let E  = GetCommonData("EASY_START");
let N  = GetCommonData("NORMAL_START");
let H  = GetCommonData("HARD_START");
let L  = GetCommonData("LUNATIC_START");
let EX = GetCommonData("EXTRA_START");

let Total = GetCommonDataDefault("GAMECLEAR_BONUS",0);

let textA = "MagicPoint";
let textB = ToString(GetCommonData("MAGICPOINT"));
let textC = "MagicPoint MAX!";
let textD = "MP"~ToString(GetCommonData("MAGICPOWER"));
let textE = "ScoreBonus!"~NumToString(GetCommonData("BONUSSCORE"));
let textF = "PointItemBonus!"~NumToString(GetCommonData("BONUSSCORE"));

let textG = "ALL CLEAR!";
let textH = "CLEAR      100000000 *            1 = 100000000";
let textI = "PLAYER      20000000 * "~NumToString(GetPlayerLife)~" = "~NumToString(GetPlayerLife * 20000000);
let textJ = "BOMB         1000000 * "~NumToString(GetPlayerBomb)~" = "~NumToString(GetPlayerBomb * 1000000);
let textK = "MAGICPOINT      3000 * "~NumToString(GetCommonData("MAGICPOINT"))~" = "~NumToString(GetCommonData("MAGICPOINT")*3000);
let textL = "EASY LEVEL * 0.5";
let textM = "HARD LEVEL * 1.2";
let textN = "LUNATIC LEVEL * 1.5";
let textO = "TOTAL      "~NumToString(Total);

let a = GetCommonDataDefault("ALPHA",255);

if(GetPlayerX < 150&&GetPlayerY > 350){
a -= 16;
if(a < 70){a = 70;}
}
else{
a += 16;
if(a > 255){a = 255;}
}

SetFontColor(190,205,255,190,155,255);
DrawText(textA,64,388,12,a);
DrawText(textB,64,400,12,a);
DrawText(textD,64,424,12,a);
if(GetCommonData("DRAWBONUS") == 1){DrawText(textE,64,48,24,255);}
if(GetCommonData("DRAWBONUS") == 2){DrawText(textF,64,48,24,255);}
if(GetCommonData("DRAWMAX") == 1){DrawText(textC,98,72,24,255);}
if(GetCommonDataDefault("GAME_CLEAR",false) == true){
DrawText(textG,64,100,18,255);
DrawText(textH,64,136,18,255);
DrawText(textI,64,154,18,255);
DrawText(textJ,64,172,18,255);
DrawText(textK,64,190,18,255);
if(E > 0){DrawText(textL,64,226,18,255);}
if(H > 0){DrawText(textM,64,226,18,255);}
if(L > 0){DrawText(textN,64,226,18,255);}
DrawText(textO,64,252,18,255);
}

SetCommonData("ALPHA",a);
}

task MagicPowerOnStage{
SetCommonData("MAGICPOWER",0);
let PointA = 0;		//前フレームの点アイテムの数を格納する変数
let Point = GetPoint;	//点アイテムの数を格納する変数
let MagicPower;		//魔力値を格納する変数
let MagicPoint;		//魔力点を格納する変数
let ExtendCount = 0;	//ボムエクステンド数を格納する変数
let E = GetCommonData("EASY_START");
let N = GetCommonData("NORMAL_START");
let H = GetCommonData("HARD_START");
let L = GetCommonData("LUNATIC_START");
let level;
if(E > 0){level = 1;}
if(N > 0){level = 1;}
if(H > 0){level = 1.5;}
if(L > 0){level = 2;}


loop{
MagicPower = GetCommonData("MAGICPOWER");
MagicPoint = GetCommonData("MAGICPOINT");
Point = GetPoint;
//↑毎フレーム、点アイテムの数、魔力値、魔力点を取得

if(Point != PointA){					//点アイテムを取得したときの処理
if(Point >= PointA){					//点アイテム数が増えていたら
MagicPower += MagicPoint * (Point - PointA) / (5000 + ExtendCount * 900) / level;//MagicPowerを増やす
SetCommonData("MAGICPOWER",MagicPower);			//共通データ更新
}
PointA = Point;						//PointAを新しい値に定義しなおす
}

if(MagicPower >= 100){					//１００を越えたら
if(GetPlayerBomb < 6){AddBomb(1);}			//ボムが６以下の場合ボム＋１
else{MagicPoint += 100;SetCommonData("MAGICPOINT",MagicPoint);}//ボム６なら、MasicPointに100加算
PlaySE(GetCurrentScriptDirectory~"\se\tm2_power000.wav");//音を鳴らす
MagicPower -= 100;					//魔力値−１００
ExtendCount++;						//エクステンド回数＋１
SetCommonData("MAGICPOWER",MagicPower);			//共通データ更新
}

yield;	//←これ大事
}
}

function ChackThePlayer{
if(GetPlayerType == REIMU_A||GetPlayerType == REIMU_B){return 1;}
if(GetPlayerType == MARISA_A||GetPlayerType == MARISA_B){return 2;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 0){return 4;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 1){return 1;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 2){return 1;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 3){return 2;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 4){return 2;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 5){return 3;}
if(GetPlayerType == USER_PLAYER&&ChoosePatchePlayer == 6){return 3;}
}


task FullItemOnStage{				//フルパワーアイテム生成管理タスク
SetCommonData("ItemXY",[]);			//アイテム位置座標保存用共通データ作成
let ItemLimit=128;				//アイテムのキャラオーバー数（処理落ち対策）
let ItemNum=0;					//STGシーンに存在するアイテム総数
let ItemCheck=0;				//共通データの配列の長さをチェックする変数
let XY=[];					//共通データの書き換えにワンクッション置くための変数
let ItemPerFrame=5;				//１フレームあたりの最大アイテム生成数（処理落ち対策）

loop{
ItemCheck=length(GetCommonDataDefault("ItemXY",[]));	//毎フレーム共通データの長さチェック
if(ItemCheck>0){					//配列に中身がある（アイテム発生フラグ立っている）場合の処理
	loop(ItemPerFrame){
	XY=GetCommonDataDefault("ItemXY",[]);		//共通データ内容を変数に渡す
	MakeFullItem(XY[0],XY[1]);			//アイテム生成。順番にX座標、Y座標
	loop(2){
		XY=erase(XY, 0);}			//生成したのでその要素を配列から削除
	if(length(XY)==0){				//削除後の配列が空になった場合
		SetCommonData("ItemXY",[]);		//共通データを空にして
		break;					//アイテム生成ループ脱出
	}
	else{SetCommonData("ItemXY",XY);}		//配列が空でない場合共通データに変更後の配列を渡す
}
}
yield;
}


task MakeFullItem(x,y){				//アイテム設定
if(ItemNum>ItemLimit){return;}			//キャラオーバーしていたらなかったことに
ItemNum++;					//生成時にアイテム数増やす

let imgItem = GetCurrentScriptDirectory~"\img\Item.png";
LoadGraphic(imgItem);

let obj = Obj_Create(OBJ_EFFECT);
let E = GetCommonData("EASY_START");
let N = GetCommonData("NORMAL_START");
let H = GetCommonData("HARD_START");
let L = GetCommonData("LUNATIC_START");
ObjEffect_SetTexture(obj, imgItem);
ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN);
ObjEffect_SetLayer(obj,4);
ObjEffect_CreateVertex(obj, 4);

ObjEffect_SetVertexXY(obj,0,64,64);
ObjEffect_SetVertexXY(obj,1,64,0);
ObjEffect_SetVertexXY(obj,2,0,0);
ObjEffect_SetVertexXY(obj,3,0,64);
		
ObjEffect_SetVertexUV(obj,0,32,32);
ObjEffect_SetVertexUV(obj,1,32,0);
ObjEffect_SetVertexUV(obj,2,0,0);
ObjEffect_SetVertexUV(obj,3,0,32);

Obj_SetPosition( obj, x - 32, y - 32);
Obj_SetAlpha( obj, 255 );

let speed = -1.5;
SetCommonData("FULLITEM_ISCORRECT",false);

Obj_SetSpeed( obj, speed );
Obj_SetAngle( obj, 90);

while( !Obj_BeDeleted(obj) ){

let nX = Obj_GetX( obj );
let nY = Obj_GetY( obj );

if(speed <= 1.5){speed += 0.05;}
Obj_SetSpeed( obj, speed );

if(nY >= GetClipMaxY + 64){Obj_Delete(obj);}

if(OnBomb == true||GetPlayerY <= 128){SetCommonData("FULLITEM_ISCORRECT",true);}

if(GetCommonData("FULLITEM_ISCORRECT") == true){
Obj_SetSpeed( obj, 10);
Obj_SetAngle( obj, atan2( GetPlayerY() - Obj_GetY( obj ),GetPlayerX() - Obj_GetX( obj )) );
}

if( (((GetPlayerX() - nX)^2+(GetPlayerY()-nY )^2 )^0.5) < 67.88&&OnPlayerMissed() == false) {
if(E > 0||N > 0){SetCommonData("MAGICPOINT",999.999900);}
if(H > 0){SetCommonData("MAGICPOINT",1499.999900);}
if(L > 0){SetCommonData("MAGICPOINT",1999.999900);}
SetCommonData("FULLITEM_GET",1);
Obj_Delete(obj);
}

yield;
}


ItemNum--;//消滅時にアイテム数減らす
SetCommonData("FULLITEM_ISCORRECT",false);
}

}