#include "./sound.txt"
let MainSTG = GetCurrentScriptDirectory;


let current = GetCurrentScriptDirectory;
let DEBUG = false;
let CutinDifficulty = "";
let SpellAttack_img = current~"img/SpellAttack.png"; 

let Alpha_HUD = [255, 255]; //top, bottom

let NAZRIN = "NAZRIN";
let BYAKUREN = "BYAKUREN";
let KANAKO = "KANAKO";
let MOKOU = "MOKOU";
let AYA = "AYA";
let YABUSAME = "LENEN";

let LENEN = "LENEN";

let img_effect = MainSTG~"img/effect.png"; // Effect Sheet
let img_effect2 = MainSTG~"img/effect2.png"; // Effect 2 Sheet
let img_effect3 = MainSTG~"img/effect3.png"; // Effect 3 Sheet
let img_break = MainSTG~"img/efbreak.png"; // Bullet Break Sheet
let img_fairy = MainSTG~"img/enemy.png"; // Fairy Sheet
let img_SpellAttack = MainSTG~"img/SpellAttackText.png"; // Spell Declare
let img_lifebar = MainSTG~"img/lifebar.png"; // Lifebar
let Gsquare= MainSTG ~ "img/square.png";
let img_yinyang = MainSTG~"img/yingyang.png"; // Yin Yang Sheet
let DIFFICULTY_EASY = 12;
let DIFFICULTY_NORMAL = 36;
let DIFFICULTY_HARD = 48;
let DIFFICULTY_LUNATIC = 72;
let DIFFICULTY_OVERDRIVE = 96;

let GetCenterX = GetStgFrameWidth/2;
let GetCenterY = GetStgFrameHeight/2;
let LastTimeStop = 0;
let IsTimeStopped = false;
let bosstime = 99;
let TimeSpeed = 1;
let bullets = "script/DP01/System/system/img/ZUNShot.png";
let Anim_Attack = 0;
let IsAttackAnimPlaying = false;
let Enemy_Move = 0;
let RainbowSpeed=6;

let EnemyX = GetCommonData("StarX1", 0);
let EnemyY = GetCommonData("StarY1", 0);

let EnemyDead = false;
let quality = GetCommonData("quality", 2);

let TotalEffectMax = 24*quality;
let TotalEffect = 0;



task PlaySound(str){
	PlaySE(MainSTG~"Sounds/"~str~".wav")
}

function wait(n){loop(n){yield;}}

function CreateEffectObject(px,py,img,blendtype,left,top,right,bottom){
	let obj=ObjPrim_Create(OBJ_SPRITE_2D);
	LoadTexture(img);
	ObjPrim_SetTexture(obj,img);
	ObjSprite2D_SetSourceRect(obj,left,top,right,bottom);
	ObjSprite2D_SetDestCenter(obj);
	//ObjSprite2D_SetDestRect(obj,-left/2,-top/2,right/2,bottom/2);
	if(blendtype=="ALPHA"){
	ObjRender_SetBlendType(obj,BLEND_ALPHA);
	}
	if(blendtype=="RGB"){
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	}
	if(blendtype=="ARGB"){
	ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
	}
	ObjRender_SetPosition(obj,px,py,0);
	return obj;
}



task MagicCircleV3big(enemy) {
/*placed on the main loop
Creates a Magic Circle that follows the boss around
DDC styled circle, rotates in 3D slowly
*/
let angle = 0;
let angle2 = 0;
let angle3 =0;
let enmx = ObjMove_GetX(enemy);
let enmy = ObjMove_GetY(enemy);

let circle = ObjPrim_Create(OBJ_SPRITE_3D);

ObjPrim_SetTexture(circle, img_effect);


//ObjRender_SetX(circle, enmx);
//ObjRender_SetY(circle, enmy);
ObjSprite3D_SetSourceDestRect(circle, 127, 81, 255, 206);

	while(!Obj_IsDeleted(enemy)) {
	
		ObjRender_SetX(circle, GetStgFrameWidth);
		ObjRender_SetY(circle, GetStgFrameHeight);

		
		//ObjRender_SetAngleZ(circle, 0);
		//ObjRender_SetAngleX(circle, 0);
		//ObjRender_SetAngleY(circle, 0);
		
		
		angle++;
		angle2++;
		angle3++;


		yield;
	}
	
	if (Obj_IsDeleted(enemy)){
	Obj_Delete(circle);
	}


}



task MagicCircleV2(enemy) {
/*Creates a Magic Circle that follows the boss around
Pre-DDC styled circle, rotates and changes size
*/
let angle = 0;
let scalecount = 0;
let scale = 1;
let scale2 = 1;
let enmx = ObjMove_GetX(enemy);
let enmy = ObjMove_GetY(enemy);

let circle=CreateEffectObject(ObjMove_GetX(enemy),ObjMove_GetY(enemy),img_effect,"ARGB",127,81,255,206);
Obj_SetRenderPriority(circle,0.23);


	while(!Obj_IsDeleted(enemy)) {
		
		
		

		ObjRender_SetX(circle, ObjMove_GetX(enemy));
		ObjRender_SetY(circle, ObjMove_GetY(enemy));

		
		ObjRender_SetAngleZ(circle, angle);
		
	if(scalecount>=0 && scalecount<=60){
		scale+= 0.01;
		}
	if(scalecount>=61 && scalecount<=121){
		scale-=0.01;
		}
	if(scalecount==122){
		scalecount = 0;
		}
		
		ObjRender_SetScaleX(circle,scale);
		ObjRender_SetScaleY(circle,scale);
		
		angle+=8;
		scalecount ++;

		yield;
	}
	if (Obj_IsDeleted(enemy)){
	Obj_Delete(circle);
	}

}

task CustomMCircle(enemy,graphic,speedN, accN, maxSN,arg,scaleN, type,R,G,B,alphaV) {
/*Creates a Magic Circle that follows the boss around
Pre-DDC styled circle, rotates and changes size
*/
let angle = 0;
let scalecount = 0;
let scale = scaleN;
let scale2 = 1;
let enmx = ObjMove_GetX(enemy);
let enmy = ObjMove_GetY(enemy);
let anglecount = 0;
let speed=speedN;
let count=1;
let maxspeed=maxSN;
let acc= accN;

let circle=CreateEffectObject(ObjMove_GetX(enemy),ObjMove_GetY(enemy),graphic,type,0,0,256,256);
Obj_SetRenderPriority(circle,0.23);

	if(type=="ALPHA"){
		ObjRender_SetColor(circle,R,G,B);
		ObjRender_SetAlpha(circle, alphaV);
	}


		if(arg==true){
			SpeedTask();
		}


	while(!Obj_IsDeleted(enemy)) {
		
		


		ObjRender_SetX(circle, ObjMove_GetX(enemy));
		ObjRender_SetY(circle, ObjMove_GetY(enemy));

		
		ObjRender_SetAngleZ(circle, angle);
		
		ObjRender_SetScaleX(circle,scale);
		ObjRender_SetScaleY(circle,scale);
		
		angle+=speed;
		scalecount +=count;

		yield;
	}
	if (Obj_IsDeleted(enemy)){
	Obj_Delete(circle);
	}
	
	task SpeedTask(){
		

		
		while(speed>0){
			speed+=acc;
			yield;
			}
			
		loop(60*2){
		yield;
		}
		
		while(maxspeed>absolute(speed)){
			
			speed+=acc;
			yield;
			}

	}
	
	task SetSpeed(val){
		speed=val;
	}

}

task MagicCircleV3(enemy) {
/*Creates a Magic Circle that follows the boss around
Pre-DDC styled circle, rotates and changes size
*/
let angle = 0;
let angle2 = 0;
let angle3 =0;
let enmx = ObjMove_GetX(enemy);
let enmy = ObjMove_GetY(enemy);

let circle = ObjPrim_Create(OBJ_SPRITE_3D);

ObjPrim_SetTexture(circle, img_effect);

ObjSprite3D_SetSourceDestRect(circle, 127, 81, 255, 206);
Obj_SetRenderPriority(circle,0.23);


	while(!Obj_IsDeleted(enemy)) {


		ObjRender_SetX(circle, ObjMove_GetX(enemy));
		ObjRender_SetY(circle, ObjMove_GetY(enemy));
		//ObjRender_SetZ(circle, -180);

		
		
		


		yield;
	}
	if (Obj_IsDeleted(enemy)){
	Obj_Delete(circle);
	}

}

task GlitterOnBoss(objid, r, g, b){	
	loop(4){yield;}
	let fe = 0;
	while(!Obj_IsDeleted(objid)){
		if(fe>=6){
			EffectAu1(ObjRender_GetX(objid), ObjRender_GetY(objid));
			EffectAu1(ObjRender_GetX(objid), ObjRender_GetY(objid));
			fe = 0;
		}
		fe+=1;
		yield;
	}	
	
	task EffectAu1(x, y){
let duration=70;

let rota=0;
let suma=rand(-4,4);
let alpha = rand(155, 205);
let inisize=rand(1,1.5);
let algoo=rand(inisize/duration*10,inisize/duration*1);

let square=CreateEffectObject(x,y+50+rand(-20,20),Gsquare,"ALPHA",0,0,12,12);
Obj_SetRenderPriority(square,0.24);
ObjRender_SetColor(square,r-rand(0,50),g,b);
ObjRender_SetX(square,x+rand(-30,30));
ObjRender_SetY(square,x+50+rand(-20,20));
ObjRender_SetAlpha(square,alpha);


		while(alpha>0){
			ObjRender_SetY(square,y+20);
ObjRender_SetAngleZ(square,rota);
ObjRender_SetAlpha(square,alpha);
ObjRender_SetScaleXYZ(square,inisize,inisize,1);

alpha = max(alpha-8, 0);
inisize-=inisize/duration;
rota+=suma;
y+=2;
yield;
		}
		Obj_Delete(square);

	}
	

}

task ChangeRainbowSpeed(newSpeed){
RainbowSpeed=newSpeed;
}

task RainbowGlow(rObject,delay){
RainbowSpeed=6;
let r=255;
let g=0;
let b=0;
ObjRender_SetColor(rObject,r,g,b);
wait(delay);

while(!Obj_IsDeleted(objEnemy)){

ObjRender_SetColor(rObject,r,g,b);

if(r>=255 && b<=255){
		b+=RainbowSpeed;
	}
	
	if(b>=255){
		r-=RainbowSpeed;
	}
	
	if(r<=0 && b>=255){
		g+=RainbowSpeed;
	}
	
	if(r<=0 && g>=255){
		b-=RainbowSpeed;
	}

	if(b<=0 && g>=255){
		r+=RainbowSpeed;
	}
	
	if(b<=0 && r>=255){
		g-=RainbowSpeed;
	}

yield;
}

}


//Bullet Functions

function EvilBullet1(x,y,speed,angle,delay){
let EvilBul=ObjShot_Create(OBJ_SHOT);
ObjShot_Regist(EvilBul);
ObjMove_SetX(EvilBul,x);
ObjMove_SetY(EvilBul,y);
ObjMove_SetSpeed(EvilBul,speed);
ObjMove_SetAngle(EvilBul,angle);
ObjShot_SetDelay(EvilBul,delay);
AddHitbox(EvilBul,14);
AddGraphicEvil(EvilBul,"BLACK");
AddGraphicNice(EvilBul,"BLUE");


return EvilBul;
}
task AddGraphicEvil(obj,color){
let bulletX = ObjMove_GetX(obj);
let bulletY = ObjMove_GetY(obj);
let dark=CreateEffectObject(bulletX,bulletY,bullets,"ARGB",612,678,642,708);

alternative(color)
case("BLACK"){
ObjSprite2D_SetSourceRect(dark,612,678,642,708);
}
case("BLUE"){
ObjSprite2D_SetSourceRect(dark,580,678,610,708);
}
case("VIOLET"){
ObjSprite2D_SetSourceRect(dark,548,678,578,708);
}
case("RED"){
ObjSprite2D_SetSourceRect(dark,516,678,546,708);
}


let a=0;
ObjRender_SetScaleXYZ(dark,1.7,1.7,1);
ObjRender_SetBlendType(dark,BLEND_SUBTRACT);

while(!Obj_IsDeleted(obj)){
ObjRender_SetX(dark,ObjMove_GetX(obj));
ObjRender_SetY(dark,ObjMove_GetY(obj));
ObjRender_SetAngleZ(dark,a);
a+=30;
yield;
}

}
task AddGraphicNice(obj,color){
let bulletX = ObjMove_GetX(obj);
let bulletY = ObjMove_GetY(obj);
let dark=CreateEffectObject(bulletX,bulletY,bullets,"ARGB",516,646,546,676);

alternative(color)
case("BLUE"){
ObjSprite2D_SetSourceRect(dark,516,646,546,676);
}
case("GREEN"){
ObjSprite2D_SetSourceRect(dark,548,646,578,676);
}
case("YELLOW"){
ObjSprite2D_SetSourceRect(dark,580,646,610,676);
}
case("WHITE"){
ObjSprite2D_SetSourceRect(dark,612,646,642,676);
}

let a=0;
let scale = 1;
let decrease=true;

while(!Obj_IsDeleted(obj)){
ObjRender_SetX(dark,ObjMove_GetX(obj));
ObjRender_SetY(dark,ObjMove_GetY(obj));
ObjRender_SetScaleXYZ(dark,scale,scale,1);

	if(scale>=70/100 && decrease==true){
		scale-= 3/100;
		}
	if(scale<=70/100){
	decrease=false;
	}
	
	if(decrease==false){
		scale+=3/100;
		}
	if(scale>=1){
	decrease=true;
	}

yield;
}

}
task AddHitbox(obj,hitbox){
while(!Obj_IsDeleted(obj)){
ObjShot_SetIntersectionCircleA1(obj,hitbox);
yield;
}
}

task BossExplode(){

let petal = CreateEffectObject(ObjMove_GetX(objEnemy),ObjMove_GetY(objEnemy),img_effect,"ALPHA",194,230,222,250);

while(true){
yield;
}

}

function CreateBossObject(SBIimage, rec1, rec2, rec3, rec4){
	let CBOboss = ObjEnemy_Create(OBJ_ENEMY_BOSS);
	ObjEnemy_Regist(CBOboss);
	ObjPrim_SetTexture(CBOboss, SBIimage); 
	ObjSprite2D_SetSourceRect(CBOboss, rec1, rec2, rec3, rec4); 
	return CBOboss;
}

function CreateEnemyObject(CEOlife, SBIimage, rec1, rec2, rec3, rec4){
	let CEOboss = ObjEnemy_Create(OBJ_ENEMY);
	ObjEnemy_Regist(CEOboss);
	ObjPrim_SetTexture(CEOboss, SBIimage); 
	ObjSprite2D_SetSourceRect(CEOboss, rec1, rec2, rec3, rec4); 
	ObjSprite2D_SetDestCenter(CEOboss);
	ObjEnemy_SetLife(CEOboss, CEOlife);
	return CEOboss;
}

function CreateFairyObject(CEOlife){
	let cfofairy = ObjEnemy_Create(OBJ_ENEMY);
	ObjEnemy_Regist(cfofairy);
	ObjPrim_SetTexture(cfofairy, img_fairy); 
	ObjEnemy_SetLife(cfofairy, CEOlife);
	return cfofairy;
}

function CreateYinYangBoss(x,y,color, YinLife){
	let YinYangBoss = ObjEnemy_Create(OBJ_ENEMY);
	ObjEnemy_Regist(YinYangBoss);
	ObjEnemy_SetLife(YinYangBoss, YinLife);	
	AnimateYinYangBall(YinYangBoss,color);
	ObjMove_SetX(YinYangBoss,x);
	ObjMove_SetY(YinYangBoss,y);
	return YinYangBoss;
}

task AnimateYinYangBall(YinEnemy,color){

let YinYangSprite=ObjPrim_Create(OBJ_SPRITE_2D);
let Aura=ObjPrim_Create(OBJ_SPRITE_2D);
let rotate=0;
let enmx = ObjMove_GetX(YinEnemy);
let enmy = ObjMove_GetY(YinEnemy);

ObjPrim_SetTexture(YinYangSprite, img_yinyang);
ObjPrim_SetTexture(Aura, img_yinyang);
Obj_SetRenderPriority(YinYangSprite,0.31);
Obj_SetRenderPriority(Aura,0.31);
PlayEnemyHitSound(YinEnemy, 1);

	
alternative(color)
case("RED"){
ObjSprite2D_SetSourceRect(YinYangSprite, 8, 63, 8+16, 63+16);
ObjSprite2D_SetSourceRect(Aura, 2, 88, 2+30, 88+32);
}
case("BLUE"){
ObjSprite2D_SetSourceRect(YinYangSprite, 72, 63, 72+16, 63+16);
ObjSprite2D_SetSourceRect(Aura, 65, 88, 65+30, 88+32);
}
case("GREEN"){
ObjSprite2D_SetSourceRect(YinYangSprite, 41, 63, 41+16, 63+16);
ObjSprite2D_SetSourceRect(Aura, 33, 88, 33+30, 88+32);
}
case("VIOLET"){
ObjSprite2D_SetSourceRect(YinYangSprite, 104, 63,104+16, 63+16);
ObjSprite2D_SetSourceRect(Aura, 97, 88, 97+30, 88+32);
}
	
		
		ObjSprite2D_SetDestCenter(YinYangSprite);

		ObjRender_SetX(YinYangSprite, ObjMove_GetX(YinEnemy));
		ObjRender_SetY(YinYangSprite, ObjMove_GetY(YinEnemy));


		
		ObjSprite2D_SetDestCenter(Aura);

		ObjRender_SetX(Aura, ObjMove_GetX(YinEnemy));
		ObjRender_SetY(Aura, ObjMove_GetY(YinEnemy));
		




		
		while(ObjEnemy_GetInfo(YinEnemy,INFO_LIFE)>0){
		enmx = ObjMove_GetX(YinEnemy);
		enmy = ObjMove_GetY(YinEnemy);
		ObjEnemy_SetIntersectionCircleToShot(YinEnemy,enmx-32,enmy-16,8);
		ObjEnemy_SetIntersectionCircleToPlayer(YinEnemy,enmx-32,enmy-16,8);
		
		

		ObjRender_SetAngleZ(YinYangSprite,rotate*4);
		ObjRender_SetX(YinYangSprite,enmx);
		ObjRender_SetY(YinYangSprite,enmy);
		
		ObjRender_SetAngleZ(Aura,-rotate*8);
		ObjRender_SetX(Aura,enmx);
		ObjRender_SetY(Aura,enmy);
		
		
		if(ObjMove_GetX(YinEnemy)>GetStgFrameWidth+40){
		Obj_Delete(YinEnemy);
		}
		
		if(ObjMove_GetX(YinEnemy)<0-40){
		Obj_Delete(YinEnemy);
		}
		
		if(ObjMove_GetY(YinEnemy)>GetStgFrameHeight+40){
		Obj_Delete(YinEnemy);
		}
		
		if(ObjMove_GetY(YinEnemy)<0-40){
		Obj_Delete(YinEnemy);
		}
		
		
		rotate+=1;
		yield;
		}
		se_enep00();
		Obj_Delete(YinEnemy);
		Obj_Delete(YinYangSprite);
		Obj_Delete(Aura);

}

task BossLifeSingle(EnemyObj){
	let path = img_lifebar;
	let countVertex = 36*2;
	
	let objOutline = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(objOutline, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(objOutline, countVertex);
	ObjRender_SetBlendType(objOutline, BLEND_ALPHA);
	Obj_SetRenderPriority(objOutline, 0.69);
	ObjPrim_SetTexture(objOutline, path);
	
	let objLife = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(objLife, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(objLife, countVertex);
	ObjRender_SetBlendType(objLife, BLEND_ALPHA);
	Obj_SetRenderPriority(objLife, 0.68);
	ObjPrim_SetTexture(objLife, path);
	
	let objLife2 = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(objLife2, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(objLife2, countVertex);
	ObjRender_SetBlendType(objLife2, BLEND_ALPHA);
	Obj_SetRenderPriority(objLife2, 0.68);
	ObjPrim_SetTexture(objLife2, path);
	
	ascent (iVert in 0..countVertex/2){
		let vertex = iVert * 2;
		ObjPrim_SetVertexUVT(objOutline, vertex+0, 0, 0);
		ObjPrim_SetVertexUVT(objOutline, vertex+1, 4, 16);	
		ObjPrim_SetVertexUVT(objLife, vertex+0, 6, 0);
		ObjPrim_SetVertexUVT(objLife, vertex+1, 10, 16);	
		ObjPrim_SetVertexUVT(objLife2, vertex+0, 6, 0);
		ObjPrim_SetVertexUVT(objLife2, vertex+1, 10, 16);		
	}
	
	
	let mx = 0;
	let my = 0;
	let maxRadius = 56;
	
	let lifeRateRender = 0;
	
	let lifeTotalMax = ObjEnemy_GetInfo(EnemyObj, INFO_LIFE);
	let lifeTotal = ObjEnemy_GetInfo(EnemyObj, INFO_LIFE);
	let lifeRate = min(lifeTotal / lifeTotalMax, lifeRateRender);
	
	
	
	ObjRender_SetScaleXYZ(objOutline, -1, 1, 1);
	ObjRender_SetScaleXYZ(objLife, -1, 1, 1);
	ObjRender_SetScaleXYZ(objLife2, -1, 1, 1);
	
	while(lifeTotal / lifeTotalMax>0){
		mx = ObjRender_GetX(EnemyObj);
		my = ObjRender_GetY(EnemyObj);
		RefreshVertex(objOutline);
		
		if(GetCommonData("ForceLifebar", 0) != 0){
			lifeRateRender = 0;
		}
		
		
		yield;
	}
	
	Obj_Delete(objOutline);
	Obj_Delete(objLife);
	Obj_Delete(objLife2);
	

	task RefreshVertex(objid){
	
		lifeTotal = ObjEnemy_GetInfo(EnemyObj, INFO_LIFE);
		lifeRate = min(lifeTotal / lifeTotalMax, lifeRateRender);
		
		ascent(iVert in 0..countVertex/2){
			let indexVert = iVert * 2;
			let angle = (360 / (countVertex/2 - 1) * iVert);
			angle = min(360*(lifeRateRender), angle);
			let x = maxRadius*cos(angle-90);
			let y = maxRadius*sin(angle-90);
			ObjPrim_SetVertexPosition(objLife, indexVert + 0 , x, y, 0);
			x = (maxRadius*1.025)*cos(angle-90);
			y = (maxRadius*1.025)*sin(angle-90);
			ObjPrim_SetVertexPosition(objLife, indexVert + 1 , x, y, 0);
			
			x = (maxRadius*1.065)*cos(angle-90);
			y = (maxRadius*1.065)*sin(angle-90);
			ObjPrim_SetVertexPosition(objLife2, indexVert + 0 , x, y, 0);
			x = (maxRadius*1.09)*cos(angle-90);
			y = (maxRadius*1.09)*sin(angle-90);
			ObjPrim_SetVertexPosition(objLife2, indexVert + 1 , x, y, 0);
			
			angle = min(360*(lifeRate), angle);
			x = (maxRadius)*cos(angle-90);
			y = (maxRadius)*sin(angle-90);
			ObjPrim_SetVertexPosition(objOutline, indexVert + 0 , x, y, 0);			
			x = (maxRadius*1.075)*cos(angle-90);
			y = (maxRadius*1.075)*sin(angle-90);
			ObjPrim_SetVertexPosition(objOutline, indexVert + 1 , x, y, 0);
		}
		ObjRender_SetPosition(objOutline, mx, my, 0);
		ObjRender_SetPosition(objLife, mx, my, 0);
		ObjRender_SetPosition(objLife2, mx, my, 0);
		
		lifeRateRender = min(1, lifeRateRender+0.02);
		
	}
}


function DrawText(txtStr, txtX, txtY, txtSize, txtWidth, presetTxtColor, txtPriority){
	let SnowDrawText = ObjText_Create;
	//DrawText("", GetPlayerX-24, GetPlayerY, 11, 300, "black", 0.80);
	ObjText_SetText(SnowDrawText,txtStr);
	SetTextColor;
	ObjText_SetFontSize(SnowDrawText,txtSize);
	ObjText_SetHorizontalAlignment(SnowDrawText, ALIGNMENT_LEFT);
	ObjText_SetFontBorderWidth(SnowDrawText,1);
	ObjText_SetFontBorderType(SnowDrawText,BORDER_FULL);
	ObjText_SetMaxWidth(SnowDrawText, txtWidth);
	Obj_SetRenderPriority(SnowDrawText, txtPriority);
	ObjRender_SetPosition(SnowDrawText, txtX, txtY, 0);
	
	task SetTextColor{
		if(presetTxtColor=="black"){
			ObjText_SetFontColorTop(SnowDrawText,0,0,0);
			ObjText_SetFontColorBottom(SnowDrawText,0,0,0);
			ObjText_SetFontBorderColor(SnowDrawText,161,161,255);
		}
		if(presetTxtColor=="red"){
			ObjText_SetFontColorTop(SnowDrawText,175,20,111);
			ObjText_SetFontColorBottom(SnowDrawText,190,10,123);
			ObjText_SetFontBorderColor(SnowDrawText,0,0,64);
		}
		if(presetTxtColor=="blue"){
			ObjText_SetFontColorTop(SnowDrawText,20,80,175);
			ObjText_SetFontColorBottom(SnowDrawText,80,50,175);
			ObjText_SetFontBorderColor(SnowDrawText,0,0,64);
		}
	}
	
	return SnowDrawText;
}

function DrawQuickText(txtStr, txtX, txtY){
	let SnowDrawText = ObjText_Create;
	let presetTxtColor = "black";
	//DrawText("", GetPlayerX-24, GetPlayerY, 11, 300, "black", 0.80);
	ObjText_SetText(SnowDrawText,txtStr);
	SetTextColor;
	ObjText_SetFontSize(SnowDrawText,16);
	ObjText_SetHorizontalAlignment(SnowDrawText, ALIGNMENT_LEFT);
	ObjText_SetFontBorderWidth(SnowDrawText,1);
	ObjText_SetFontBorderType(SnowDrawText,BORDER_FULL);
	ObjText_SetMaxWidth(SnowDrawText, 300);
	Obj_SetRenderPriority(SnowDrawText, 0.6);
	ObjRender_SetPosition(SnowDrawText, txtX, txtY, 0);
	
	task SetTextColor{
		if(presetTxtColor=="black"){
			ObjText_SetFontColorTop(SnowDrawText,0,0,0);
			ObjText_SetFontColorBottom(SnowDrawText,0,0,0);
			ObjText_SetFontBorderColor(SnowDrawText,161,161,255);
		}
		if(presetTxtColor=="red"){
			ObjText_SetFontColorTop(SnowDrawText,175,20,111);
			ObjText_SetFontColorBottom(SnowDrawText,190,10,123);
			ObjText_SetFontBorderColor(SnowDrawText,0,0,64);
		}
		if(presetTxtColor=="blue"){
			ObjText_SetFontColorTop(SnowDrawText,20,80,175);
			ObjText_SetFontColorBottom(SnowDrawText,80,50,175);
			ObjText_SetFontBorderColor(SnowDrawText,0,0,64);
		}
	}
	
	return SnowDrawText;
}



task ConcentrationF1(objid, r, g, b, delay){
//Working
	let locframe = 0;
	let cx = ObjRender_GetX(objid);
	let cy = ObjRender_GetY(objid);
	CreateCircleA1(objid, 136, -80/delay*2, 12, r, g, b);
	while(delay>0){
		if(Obj_IsDeleted(objid)){return;}
		cx = ObjRender_GetX(objid);
		cy = ObjRender_GetY(objid);
		if(locframe>2){
			ExplosionA3(cx, cy, cx+rand(64, 128)*cos(rand(0,360)), cy+rand(64, 128)*sin(rand(0,360)), rand(1, 3)); 
			locframe = 0;
		}
		locframe++;
		delay--;
		yield;
	}
	se_tan01;
	CreateCircleA1(objid, 0, 10, 1, r, g, b);
	loop((quality+3)*6){ExplosionA3(cx+rand(215, 160)*cos(rand(0,360)), cy+rand(215, 160)*sin(rand(0,360)), cx, cy, rand(2, 3.75));}
	
	task ExplosionA3(dx, dy, deX, deY, scale){
		// sloppier than sloppy
		let angX = rand(180, -180);
		let angY = rand(180, -180);
		let angZ = rand(180, -180);
		let spd = scale*1.5;
		let ang = atan2(dy - deY, dx - deX);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.60);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, 32, 228, 64, 252);
		ObjSprite2D_SetDestRect(obj, -16, -12, 16, 12);
		ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
		ObjRender_SetPosition(obj, deX, deY, 0);
		let alpha = 195;
		let randX = rand(-500, 500);
		let randY = rand(-500, 500);
		let odist = GetDistance(deX,deY,dx,dy);
		while(!Obj_IsDeleted(obj)){
			let dist = GetDistance(deX,deY,dx,dy);
			scale = scale-0.05;
			alpha += -0.1;
			deX += spd*cos(ang);
			deY += spd*sin(ang);
			angX += randX/85;
			angY += randY/85;
			angZ += randX/135+randY/135;
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
			ObjRender_SetAlpha(obj, alpha*(dist/odist));
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			if(scale<0||dist<spd){Obj_Delete(obj)}
			yield;
		}
		Obj_Delete(obj);
	}
}


task ConcentrationF2(objid, r, g, b, delay){
//Working, inverse to previous
	let locframe = 0;
	let cx = ObjRender_GetX(objid);
	let cy = ObjRender_GetY(objid);
	CreateCircleA1(objid, 136, -80/delay*2, 12, r, g, b);
	while(delay>0){
		if(Obj_IsDeleted(objid)){return;}
		cx = ObjRender_GetX(objid);
		cy = ObjRender_GetY(objid);
		if(locframe>2){
			ExplosionA3(cx, cy, cx+rand(64, 128)*cos(rand(0,360)), cy+rand(64, 128)*sin(rand(0,360)), rand(1, 3)); 
			locframe = 0;
		}
		locframe++;
		delay--;
		yield;
	}
	
	task ExplosionA3(dx, dy, deX, deY, scale){
		// sloppier than sloppy
		let angX = rand(180, -180);
		let angY = rand(180, -180);
		let angZ = rand(180, -180);
		let spd = scale*1.5;
		let ang = atan2(dy - deY, dx - deX);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.60);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, 32, 228, 64, 252);
		ObjSprite2D_SetDestRect(obj, -16, -12, 16, 12);
		ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
		ObjRender_SetPosition(obj, deX, deY, 0);
		let alpha = 195;
		let randX = rand(-500, 500);
		let randY = rand(-500, 500);
		let odist = GetDistance(deX,deY,dx,dy);
		while(!Obj_IsDeleted(obj)){
			let dist = GetDistance(deX,deY,dx,dy);
			scale = scale-0.05;
			alpha += -0.1;
			deX += spd*cos(ang);
			deY += spd*sin(ang);
			angX += randX/85;
			angY += randY/85;
			angZ += randX/135+randY/135;
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
			ObjRender_SetAlpha(obj, alpha*(dist/odist));
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			if(scale<0||dist<spd){Obj_Delete(obj)}
			yield;
		}
		Obj_Delete(obj);
	}
}

task ConcentrationF3(objid,delay){
//Usual charge unload
	let locframe = 0;
	let cx = ObjRender_GetX(objid);
	let cy = ObjRender_GetY(objid);
	while(delay>0){
		if(Obj_IsDeleted(objid)){return;}
		cx = ObjRender_GetX(objid);
		cy = ObjRender_GetY(objid);
		if(locframe>2){
			ExplosionA3(cx, cy, cx+rand(64, 128)*cos(rand(0,360)), cy+rand(64, 128)*sin(rand(0,360)), rand(1, 3)); 
			locframe = 0;
		}
		locframe++;
		delay--;
		yield;
	}
	se_enep02;
	loop((quality+3)*6){ExplosionA3(cx+rand(215, 160)*cos(rand(0,360)), cy+rand(215, 160)*sin(rand(0,360)), cx, cy, rand(2, 3.75));}
	
	task ExplosionA3(dx, dy, deX, deY, scale){
		// sloppier than sloppy
		let angX = rand(180, -180);
		let angY = rand(180, -180);
		let angZ = rand(180, -180);
		let spd = scale*1.5;
		let ang = atan2(dy - deY, dx - deX);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.60);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, 32, 228, 64, 252);
		ObjSprite2D_SetDestRect(obj, -16, -12, 16, 12);
		ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
		ObjRender_SetPosition(obj, deX, deY, 0);
		let alpha = 195;
		let randX = rand(-500, 500);
		let randY = rand(-500, 500);
		let odist = GetDistance(deX,deY,dx,dy);
		while(!Obj_IsDeleted(obj)){
			let dist = GetDistance(deX,deY,dx,dy);
			scale = scale-0.05;
			alpha += -0.1;
			deX += spd*cos(ang);
			deY += spd*sin(ang);
			angX += randX/85;
			angY += randY/85;
			angZ += randX/135+randY/135;
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
			ObjRender_SetAlpha(obj, alpha*(dist/odist));
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			if(scale<0||dist<spd){Obj_Delete(obj)}
			yield;
		}
		Obj_Delete(obj);
	}
}

task ConcentrationF4(objid,delay){
//Usual charge no unload
	let locframe = 0;
	let cx = ObjRender_GetX(objid);
	let cy = ObjRender_GetY(objid);
	while(delay>0){
		if(Obj_IsDeleted(objid)){return;}
		cx = ObjRender_GetX(objid);
		cy = ObjRender_GetY(objid);
		if(locframe>2){
			ExplosionA3(cx, cy, cx+rand(64, 128)*cos(rand(0,360)), cy+rand(64, 128)*sin(rand(0,360)), rand(1, 3)); 
			locframe = 0;
		}
		locframe++;
		delay--;
		yield;
	}

	
	task ExplosionA3(dx, dy, deX, deY, scale){
		// sloppier than sloppy
		let angX = rand(180, -180);
		let angY = rand(180, -180);
		let angZ = rand(180, -180);
		let spd = scale*1.5;
		let ang = atan2(dy - deY, dx - deX);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.60);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, 32, 228, 64, 252);
		ObjSprite2D_SetDestRect(obj, -16, -12, 16, 12);
		ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
		ObjRender_SetPosition(obj, deX, deY, 0);
		let alpha = 195;
		let randX = rand(-500, 500);
		let randY = rand(-500, 500);
		let odist = GetDistance(deX,deY,dx,dy);
		while(!Obj_IsDeleted(obj)){
			let dist = GetDistance(deX,deY,dx,dy);
			scale = scale-0.05;
			alpha += -0.1;
			deX += spd*cos(ang);
			deY += spd*sin(ang);
			angX += randX/85;
			angY += randY/85;
			angZ += randX/135+randY/135;
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
			ObjRender_SetAlpha(obj, alpha*(dist/odist));
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			if(scale<0||dist<spd){Obj_Delete(obj)}
			yield;
		}
		Obj_Delete(obj);
	}
}

task PlayEnemyHitSound(SoundHitEffectObjectID, hitsoundtype){
	let bosshp = ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE);
	let origbosshp = ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE);
	
	while(EnemyDead == false && Obj_IsDeleted(SoundHitEffectObjectID) == false){
		if(bosshp != ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE) && hitsoundtype == 1){
			if(ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE) > origbosshp/12){se_damage1();}
			if(ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE) < origbosshp/12){se_damage2();}
			SetAreaCommonData("CirnoPlayer", "IncreaseIce", 0.6);
		}
		if(bosshp != ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE) && hitsoundtype == 2){se_damage1;}
		if(bosshp != ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE) && hitsoundtype == 3){se_damage3;}
		
		bosshp = ObjEnemy_GetInfo(SoundHitEffectObjectID, INFO_LIFE);
		yield;
	}
}

task SetInvincibility(SnowEnemyObject, TFRAMES, SIshot, SIbomb){
	ObjEnemy_SetDamageRate(SnowEnemyObject, 0, 0);	
	loop(TFRAMES){yield;}
	ObjEnemy_SetDamageRate(SnowEnemyObject, SIshot, SIbomb);	
}

/*task StarOnBossSingle(SnowEnemyObject){ 
	//This is a relic from 0.12m and I'll optimize it later
	let objStar = ObjPrim_Create(OBJ_SPRITE_2D);
	let objxpos=ObjMove_GetX(SnowEnemyObject);
	let objypos=ObjMove_GetY(SnowEnemyObject);
	let object_time = 30;
	let obj_angle = 330;
	let osize = 0;
	let obj_sizeset = 0;
	let sizeinc = 5;
	let angleinc = 5;
	let fullsize = 0;
	let sizeframe = 0;
	let ax2 = 0.04;
	let bx2 = 1.35;

	ObjRender_SetBlendType(objStar, BLEND_ALPHA);
	Obj_SetRenderPriority(objStar, 0.30);
	ObjPrim_SetTexture(objStar, img_effect);
	ObjSprite2D_SetSourceRect(objStar, 128, 80, 256, 208);
	ObjSprite2D_SetDestRect(objStar, -64, -64, 64, 64);
	
	
	ObjRender_SetAlpha(objStar, 145);
	ObjRender_SetColor(objStar, 200,200,200);
	
	while(!Obj_IsDeleted(SnowEnemyObject)){
		if(IsTimeStopped == false){
			objxpos = ObjMove_GetX(SnowEnemyObject);
			objypos = ObjMove_GetY(SnowEnemyObject);
	
			
			StarSize;
			ObjRender_SetX(objStar, objxpos);
			ObjRender_SetY(objStar, objypos);
			ObjRender_SetScaleXYZ(objStar, osize/95, osize/95, 1);
			ObjRender_SetAngleZ(objStar, obj_angle);
		}
		yield;
	}
	Obj_Delete(objStar);
	
	task StarSize{
		sizeframe++;
		if(sizeframe>=TimeSpeed-1){
			if(fullsize==2){
				if(obj_sizeset==0){sizeinc+=ax2}
				if(obj_sizeset==1){sizeinc-=ax2}
				
				if(sizeinc<-bx2){obj_sizeset=0}
				if(sizeinc>bx2){obj_sizeset=1}
				
				obj_angle-=angleinc;
				angleinc = min(angleinc+0.5, 5);
				
				osize+=sizeinc;
			}
			if(fullsize!=2){obj_angle-=angleinc;angleinc-=0.06;}
			if(osize<145&&fullsize==0){osize+=5;}
			if(osize>144&&fullsize==0){
				fullsize=1;
				loop(55){yield;}
				sizeinc=0;
				angleinc=0;
				fullsize=2;
			}
			sizeframe = 1;
		}
	}	
}*/

task AuraOnBossSingle(objid, r, g, b){	
	loop(4){yield;}
	if(quality==0){return;}
	let fe = 0;
	while(!Obj_IsDeleted(objid)){
		if(fe>=6){
			EffectAu1(ObjRender_GetX(objid), ObjRender_GetY(objid), 0);
			EffectAu1(ObjRender_GetX(objid), ObjRender_GetY(objid), 1);
			fe = 0;
		}
		fe+=1;
		yield;
	}	
	task EffectAu1(x, y, type){
		let oy = y;
		let alpha = rand(155, 205);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.23);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, (type)*48, 144, (type+1)*48, 192);
		ObjSprite2D_SetDestCenter(obj);
		ObjRender_SetScaleXYZ(obj, rand(1, 1.65), rand(1, 1.95), 1);
		ObjRender_SetAngleZ(obj, rand(0, 360));
		let rang = 90;
		if(type==0){
			ObjRender_SetAngleZ(obj, rand(-20, 20));
		}else{rang = rand(0,360);}
		ObjRender_SetColor(obj, r, g, b);
		ObjRender_SetPosition(obj, x, y, 0);
		ObjRender_SetAlpha(obj, alpha);
		while(alpha>0){
			x = x-((1-type)*2.5+0.65)*cos(rang);
			y = y-((1-type)*2.5+0.65)*sin(rang);
			alpha = max(alpha-8, 0);
			ObjRender_SetPosition(obj, x, y, 0);
			ObjRender_SetAlpha(obj, alpha);
			yield;
		}
		Obj_Delete(obj);
	}
}

task NameOnBossSingle(objid, text){
	if(quality==0){return}
	let objText = ObjText_Create;
	ObjText_SetFontSize(objText, 11);
	ObjText_SetFontColorTop(objText, 120, 220, 154);
	ObjText_SetFontColorBottom(objText, 120, 220, 154);
	
	ObjText_SetHorizontalAlignment(objText, ALIGNMENT_LEFT);
	ObjText_SetMaxWidth(objText, 999);
	Obj_SetRenderPriority(objText, 0.79);
	ObjRender_SetX(objText, 0);
	ObjRender_SetY(objText, 1);
	ObjText_SetText(objText, text);
	if(quality==1){
		ObjRender_SetY(objText, 14);
	}
	
	
	while(!Obj_IsDeleted(objid)){
		yield;
	}
	Obj_Delete(objText);
}

task ExplosionA1(deX, deY, angX, angY, angZ){
	//explosion that moves in 3d USEFUL
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA );
	Obj_SetRenderPriority(obj, 0.50);
	ObjPrim_SetTexture(obj, img_effect);
	ObjSprite2D_SetSourceRect(obj, 129, 17, 191, 79);
	ObjSprite2D_SetDestRect(obj, -32, -32, 32, 32);
	ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
	ObjRender_SetPosition(obj, deX, deY, 0);
	
	let alpha = 255;
	let scale = 0;
	let expo = 0.4;
	let RandZ = rand(-170,170);
	while(Obj_IsDeleted(obj)==false){
	
		if(alpha>100){scale += expo;}else{scale -= expo;}
		alpha -= 5;
		if(expo>0){expo = expo^1.07;}
		
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetScaleXYZ(obj, scale*1.1, scale*1.1, 1);
		
		if(alpha<0){Obj_Delete(obj)}
		yield;
	}
	Obj_Delete(obj);
}

task ExplosionA2(deX, deY, angX, angY, angZ, deScale){
	//Explodes a single petal
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.60);
	ObjPrim_SetTexture(obj, img_effect);
	ObjSprite2D_SetSourceRect(obj, 32, 228, 64, 252);
	ObjSprite2D_SetDestRect(obj, -16, -12, 16, 12);
	ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
	ObjRender_SetPosition(obj, deX, deY, 0);
	
	let alpha = 125;
	let scale = deScale;
	let randX = rand(-500, 500);
	let randY = rand(-500, 500);
	let RandZ = rand(-170,170);
	//atan2(randY - deX, randX - deY);
	while(Obj_IsDeleted(obj)==false){
		scale += -0.05;
		alpha += -0.1;
		deX += randX/100;
		deY += randY/100;
		angX += randX/85;
		angY += randY/85;
		angZ += randX/135+randY/135;
		
		ObjRender_SetPosition(obj, deX, deY, 0);
		ObjRender_SetAngleXYZ(obj, angX, angY, angZ);
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetScaleXYZ(obj, scale, scale, scale);
		
		if(scale<0.01){Obj_Delete(obj)}
		yield;
	}
	Obj_Delete(obj);
}





task CreateCircleA1(objid, siz, sinc, destsiz, r, g, b){
//what is says
	let alpha = 255;
	let countVertex = 50;
	
	let circ = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetPrimitiveType(circ, PRIMITIVE_TRIANGLEFAN);
	ObjPrim_SetTexture(circ, NULL);
	Obj_SetRenderPriority(circ, 0.60);
	ObjPrim_SetVertexCount(circ, countVertex);
	ObjRender_SetBlendType(circ, BLEND_ALPHA);
	
	
	ObjPrim_SetVertexUVT(circ, 0, 0, 0);	
	ObjPrim_SetVertexPosition(circ, 0, 0, 0, 0);
	ObjPrim_SetVertexColor(circ, 0, 255, 255, 255);
	ObjPrim_SetVertexAlpha(circ, 0, 0);
	let x = ObjRender_GetX(objid);
	let y = ObjRender_GetY(objid);
	ObjRender_SetPosition(circ, x, y, 0);
	
	ascent(iVert in 1..countVertex){
		let angle = (360 / (countVertex - 2) * iVert);
		ObjPrim_SetVertexUVT(circ, iVert, 0, 0);	
		let x = siz*cos(angle);
		let y = siz*sin(angle);
		ObjPrim_SetVertexPosition(circ, iVert , x, y, 0);
		ObjPrim_SetVertexColor(circ, iVert, r, g, b);
		ObjPrim_SetVertexAlpha(circ, iVert, alpha);
	}
	while(alpha>0){
		if(!Obj_IsDeleted(objid)){
			x = ObjRender_GetX(objid);
			y = ObjRender_GetY(objid);
		}
		ObjRender_SetPosition(circ, x, y, 0);
		siz += sinc/TimeSpeed;
		alpha -= 8;
		ascent(iVert in 1..countVertex){
			let angle = (360 / (countVertex - 2) * iVert);
			ObjPrim_SetVertexPosition(circ, iVert , (siz+8)*cos(angle), (siz+8)*sin(angle), 0);
			ObjPrim_SetVertexAlpha(circ, iVert, alpha);
		}
		yield;
	}
	Obj_Delete(circ);
}


task ClearBullets(x, y, type, Tsize, Tspd, Tmaxrad, delay){
	let stopclear = true;
	loop(delay){yield;}
	while(stopclear==true){
		DeleteShotInCircle(TYPE_ALL,type,x,y,Tsize);
		Tsize += Tspd;
		if(Tsize>=Tmaxrad){
			stopclear = false;
		}
		yield;
	}
}

task CutInS1(SnowEnemyObject, CutType, CutSpellName, CutSpellImage, CutX1, CutY1, CutX2, CutY2){
	yield;
	let objSpellCutIn = SetSpellCutInProperties;
	let objSpellBG = ObjPrim_Create(OBJ_SPRITE_2D);
	let objTxt = ObjText_Create;
	
	let SpellDataAttempt = CutSpellName~IntToString(GetCommonData("StageDiffic", 36))~GetPlayerID~"Attempt";
	let SpellDataGet = CutSpellName~IntToString(GetCommonData("StageDiffic", 36))~GetPlayerID~"Get";
	let SpellValueAttempt = GetAreaCommonData("SpellFunctions", SpellDataAttempt, 0);
	let SpellValueGet = GetAreaCommonData("SpellFunctions", SpellDataGet, 0);
	
	let SpellTextX = 0;
	let SpellTextX2 = 0;
	let SpellTextY = 0;
	let SpellTextSet = 0;
	
	let SpellTextSize = 0;
	let SpellTextSizeInc = 0;
	
	let SpellBGAlpha = 0;
	
	let CutInAlpha = 0;
	let CutInX = 0;
	let CutInY = 0;
	let CutInPosInc = 0;
	
	let CutInTime = 0;
	let CutInitialize = false;
	
	
	SetTextProperties;
	SetSpellBGProperties;
	
	// Checker List
	if(CutType!="YOUMU" && CutType!="DAIYOUSEI" && CutType!="KYOUKO" && CutType!="KANAKO" 
	&& CutType!="NAZRIN" && CutType!="BYAKUREN" && CutType!="AYA" && CutType!="TEXT"){
		RaiseError("Invalid Cutin Type");
	}
	
	if(CutType!="AYA"){
		if(IsReplay == false){
			SpellValueAttempt++;
			SetAreaCommonData("SpellFunctions", SpellDataAttempt, SpellValueAttempt);
			SaveCommonDataAreaA1("SpellFunctions");
		}
	}
	
	
	
	//mu
	
	if(CutType=="YOUMU"){TextYoumu;}
	if(CutType=="DAIYOUSEI"){TextDaiyousei;}
	if(CutType=="KYOUKO"){TextKyouko;}
	if(CutType=="NAZRIN"){TextNazrin;}
	if(CutType=="KANAKO"){TextKanako;}
	if(CutType=="BYAKUREN"){TextByakuren;}
	if(CutType=="AYA"){TextAya;}
	if(CutType=="TEXT"){TextText;}
	BonusPoint;
	
	while(CutInTime<206){
		CutInTime++;					
		yield;
	}
	Obj_Delete(objSpellCutIn);
	
	
	SpellBGAlpha = 255;
	while(!Obj_IsDeleted(SnowEnemyObject)){
		if(GetPlayerY < 96){
			SpellBGAlpha = max(SpellBGAlpha-10, 85);
		}else{SpellBGAlpha = min(SpellBGAlpha+10, 255);}
		ObjRender_SetAlpha(objTxt, SpellBGAlpha);
		ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
		
		SpellTextX = GetStgFrameWidth-384;
		SpellTextX2 = GetStgFrameWidth-384;
		ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
		ObjRender_SetPosition(objTxt, -24+SpellTextX2, SpellTextY+15, 0);
		
		yield;
	}
	Obj_Delete(objTxt);
	Obj_Delete(objSpellBG);
	
	task TextYoumu{
		CutInY = -60;
		SpellTextY = GetStgFrameHeight/4*3;
		SpellTextX = 310;
		SpellTextX2 = 310;
		BorderOfSpiritEffect;
		while(SpellTextSet!=4){			
			if(CutInTime<120&&CutInAlpha<255){CutInAlpha+=3;}
			if(CutInTime>119&&CutInAlpha>0){CutInAlpha-=3;}
			
			ObjRender_SetPosition(objSpellCutIn, 384, CutInY, 0);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			ObjRender_SetAlpha(objSpellCutIn, CutInAlpha);
			
			if(SpellTextSet==0){
				SpellTextX-=10;
				if(SpellTextX==0){SpellTextSet=1;}
			}
			if(SpellTextSet==0 || SpellTextSet==1){
				SpellTextX2-=5;
				if(SpellTextX2==0){SpellTextSet=2;}
			}
			if(CutInTime==100){SpellTextSet=3;}
			if(SpellTextSet==3){
				SpellTextY-=10;
				if(SpellTextY<25){SpellTextSet=4;}
			}			
			CutInY+=0.9;
			yield;
		}
	}
	
	task TextDaiyousei{
		CutInY = 120;
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		BorderOfSpiritEffect;
		ObjSprite2D_SetDestRect(objSpellCutIn, -CutX2/2, 0, CutX2/2, CutY2);
		while(CutInTime<119||CutInAlpha>0){
			if(CutInTime<120&&CutInAlpha<255){CutInAlpha+=3;CutInPosInc+=0.03;}
			if(CutInTime>119&&CutInAlpha>0){CutInAlpha-=3;CutInPosInc-=0.028;}
			
			ObjRender_SetPosition(objSpellCutIn, GetCenterX, CutInY, 0);
			ObjRender_SetAlpha(objSpellCutIn, CutInAlpha);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(SpellTextY>20 && CutInTime > 85){SpellTextY-=10;}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			CutInY-=CutInPosInc;
			yield;
		}
	}
	
	task TextKanako{
		ObjSprite2D_SetDestCenter(objSpellCutIn);
		CutInX = GetCenterX*2+180;
		CutInY = GetCenterY-190;
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		SpellAttackEffect(180, 1.5);
		CutInPosInc = 18;
		CutInAlpha = 20;
		while(CutInTime<=206){
		
			if(CutInTime<31){CutInX-=CutInPosInc; CutInY+=CutInPosInc; CutInAlpha+=2;if(CutInTime>8){CutInPosInc-=0.85;}}
			if(CutInTime==30){CutInPosInc = 0.35;}
			if(CutInTime>=31 && CutInTime<130){CutInY-=CutInPosInc;CutInPosInc+=0.0225;if(CutInAlpha<235){CutInAlpha+=5;}}
			if(CutInTime>=130){CutInY-=CutInPosInc;CutInPosInc-=0.035;CutInAlpha-=3;}
			
			ObjRender_SetPosition(objSpellCutIn, CutInX, CutInY, 0);
			ObjRender_SetAlpha(objSpellCutIn, CutInAlpha);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(SpellTextY>20 && CutInTime > 85){SpellTextY-=10;}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			yield;
		}
	}

	task TextNazrin{
		CutInX = (GetCenterX*2)+256;
		CutInY = GetCenterY-128;
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		SpellAttackEffect(100, 1.5);
		let cyoff = -5;
		if(quality<=1){cyoff = 10}
		ObjSprite2D_SetDestCenter(objSpellCutIn);
		while(CutInTime<=206){
		
			if(CutInTime<21){CutInX-=20; CutInY+=5}
			if(CutInTime>=21 && CutInTime<110){CutInX--; CutInY+=0.5;}
			if(CutInTime>=110){CutInX-=20; CutInY+=5;}
			
			ObjRender_SetPosition(objSpellCutIn, CutInX, CutInY, 0);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, -24+SpellTextX2, SpellTextY+15, 0);
			
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(CutInTime > 85){SpellTextY = max(SpellTextY-10, cyoff);}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			yield;
		}
	}

	task TextByakuren{
		CutInX = -256;
		CutInY = GetCenterY;
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		SpellAttackEffect(100, 1.5);
		ObjSprite2D_SetDestCenter(objSpellCutIn);
		while(CutInTime<=206){
		
			if(CutInTime<21){CutInX+=20;}
			if(CutInTime>=21 && CutInTime<110){CutInX++;}
			if(CutInTime>=110){CutInX+=20;}
			
			ObjRender_SetPosition(objSpellCutIn, CutInX, CutInY, 0);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(SpellTextY>20 && CutInTime > 85){SpellTextY-=10;}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			yield;
		}
	}

	task TextAya{
		if(CutSpellName != ""){CutInS1(SnowEnemyObject, "TEXT", CutSpellName, NULL, 0, 0, 0, 0);}
		Obj_Delete(objSpellCutIn);
		Obj_Delete(objTxt);
		Obj_Delete(objSpellBG);
		se_charge;
		let objShootName= SetSpellCutInProperties;
		ObjRender_SetPosition(objShootName, GetCenterX+4, -CutY2*4, 0);
		ObjRender_SetBlendType(objShootName, BLEND_ALPHA);
		
		let objSpellShoot = SetSpellCutInProperties;
		ObjPrim_SetTexture(objSpellShoot, img_effect3);
		ObjSprite2D_SetSourceRect(objSpellShoot, 0, 0, 256, 64);
		ObjRender_SetPosition(objSpellShoot, GetCenterX+32, GetCenterY, 0);
		
		let objSpellShootBG = SetSpellCutInProperties;
		ObjRender_SetBlendType(objSpellShootBG, BLEND_ADD_RGB);
		ObjPrim_SetTexture(objSpellShootBG, img_effect3);
		Obj_SetRenderPriority(objSpellShootBG, 0.76);
		ObjSprite2D_SetSourceRect(objSpellShootBG, 0, 64, 512, 128);
		ObjRender_SetPosition(objSpellShootBG, GetCenterX+55*cos(335), GetCenterY+55*sin(335), 0);
		ObjRender_SetAngleZ(objSpellShootBG, 335);
		ObjSprite2D_SetDestCenter(objSpellShootBG);
		ObjRender_SetScaleXYZ(objSpellShootBG, 1.35, 1.35, 1);
		
		let g = 0;
		let b = 0;
		let g2 = 0;
		let b2 = 0;
		
		let alco = 105;
		ObjRender_SetColor(objSpellShootBG, alco, alco, alco);
		
		while(CutInTime<=206){
			if(CutInTime<60){
				if(CutInTime<30){
					g = min(128, g+16);
					ObjSprite2D_SetDestRect(objSpellShoot, -128, -g/4, 128*4-g*3, g/4);
					ObjSprite2D_SetDestRect(objSpellShootBG, -256, -g/4, 256*4-g*2*3, g/4);
					b=g;
				}
				if(CutInTime>=30){
					g = max(0, g-16);
					b = min((CutX2-CutX1)*2, b+24);
					ObjSprite2D_SetDestRect(objSpellShoot, -b, -g/6, 128, g/6);
				}
			}
			if(CutInTime==45){
				Obj_Delete(objSpellShoot);
				ObjRender_SetPosition(objSpellShoot, GetCenterX+4, -CutY2*4, 0);
				se_don00;
			}
			if(CutInTime>45 && CutInTime<120){
				ObjRender_SetPosition(objShootName, GetCenterX+4, GetCenterY, 0);
				if(CutInTime<75){
					g2 = min((CutX2-CutX1)/2, g2+24);
					ObjSprite2D_SetDestRect(objShootName, -(CutX2-CutX1)/2, -g2/6, (CutX2-CutX1)*2-g2*3, g2/6);
					b2=g2;
				}
				if(CutInTime>=75){
					g2 = max(0, g2-24);
					b2 = min((CutX2-CutX1)*2, b2+24);
					alco = max(0, alco-15);
					ObjSprite2D_SetDestRect(objShootName, -b2, -g2/6, (CutX2-CutX1)/2, g2/6);
					ObjSprite2D_SetDestRect(objSpellShootBG, -b2*2, -g2/4, 256, g2/4);
					ObjRender_SetColor(objSpellShootBG, alco, alco, alco);
				}
			}
			yield;
		}
	}

	task TextText{
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		while(CutInTime<=206){			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(SpellTextY>40 && CutInTime > 85){SpellTextY-=10;}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			yield;
		}
	}

	task TextKyouko{
		CutInY = 120;
		SpellTextY = GetStgFrameHeight/6*4;
		SpellTextX = 0;
		SpellTextX2 = 0;
		SpellTextSize = 164;
		SpellAttackEffect(180, 1);
		ObjSprite2D_SetDestRect(objSpellCutIn, -CutX2/2, 0, CutX2/2, CutY2);
		
		while(CutInTime<119||CutInAlpha>0){
			if(CutInTime<120&&CutInAlpha<255){CutInAlpha+=3;CutInPosInc+=0.03;}
			if(CutInTime>119&&CutInAlpha>0){CutInAlpha-=3;CutInPosInc-=0.028;}
			
			ObjRender_SetPosition(objSpellCutIn, GetCenterX, CutInY, 0);
			ObjRender_SetAlpha(objSpellCutIn, CutInAlpha);
			
			ObjRender_SetPosition(objSpellBG, 384+SpellTextX, SpellTextY, 0);
			ObjRender_SetPosition(objTxt, 70+SpellTextX2, SpellTextY+15, 0);
			
			
			if(SpellTextSize>0){
				SpellTextSize-=4.45;
				ObjSprite2D_SetDestRect(objSpellBG, -256-SpellTextSize, -SpellTextSize, 0, 36);
			}
			else{
				ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
				if(SpellTextY>20 && CutInTime > 85){SpellTextY-=10;}
			}
			
			if(SpellBGAlpha<255){SpellBGAlpha+=4.5}
			ObjRender_SetAlpha(objTxt, SpellBGAlpha);
			ObjRender_SetAlpha(objSpellBG, SpellBGAlpha);
			
			CutInY-=CutInPosInc;
			yield;
		}
	}
	
	function SetSpellBorderProperties{
		let SSBPtemp = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(SSBPtemp, BLEND_ALPHA);
		Obj_SetRenderPriority(SSBPtemp, 0.76);
		ObjPrim_SetTexture(SSBPtemp, img_effect2);
		ObjSprite2D_SetSourceRect(SSBPtemp, 0, 0, 1280, 80);
		ObjRender_SetPosition(SSBPtemp, GetStgFrameWidth, SpellTextY, 0);
		ObjSprite2D_SetDestRect(SSBPtemp, -280, -40, 1080, 40); //1.7
		return SSBPtemp;
	}	
	function SetSpellAttackProperties{
		let SSBPtemp = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(SSBPtemp, BLEND_ALPHA);
		Obj_SetRenderPriority(SSBPtemp, 0.75);
		ObjPrim_SetTexture(SSBPtemp, img_SpellAttack);
		ObjSprite2D_SetSourceRect(SSBPtemp, -768, 0, 768, 16);
		ObjSprite2D_SetDestCenter(SSBPtemp);
		return SSBPtemp;
	}
	
	function SetSpellCutInProperties{
		let tempobj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(tempobj, BLEND_ALPHA);
		ObjRender_SetAlpha(tempobj, 225);
		Obj_SetRenderPriority(tempobj, 0.77);
		ObjPrim_SetTexture(tempobj, CutSpellImage);
		ObjSprite2D_SetSourceRect(tempobj, CutX1, CutY1, CutX2, CutY2);
		ObjRender_SetPosition(tempobj, GetStgFrameWidth-30, 0, 0);
		while(CutX1>0){CutX1--;CutX2--;}
		while(CutY1>0){CutY1--;CutY2--;}
		ObjSprite2D_SetDestRect(tempobj, -CutX2, 0, 0, CutY2);
		return tempobj;
	}
	task SetSpellBGProperties{
		ObjRender_SetBlendType(objSpellBG, BLEND_ALPHA);
		Obj_SetRenderPriority(objSpellBG, 0.78);
		ObjPrim_SetTexture(objSpellBG, img_effect);
		ObjSprite2D_SetSourceRect(objSpellBG, 0, 256, 256, 292);
		ObjRender_SetPosition(objSpellBG, GetStgFrameWidth, SpellTextY, 0);
		ObjSprite2D_SetDestRect(objSpellBG, -256, 0, 0, 36);
	}
	task SetTextProperties{
		ObjText_SetText(objTxt,CutSpellName);
		ObjText_SetFontSize(objTxt,12);
		ObjText_SetFontColorTop(objTxt,254,254,254);
		ObjText_SetFontColorBottom(objTxt,255,119,119);
		ObjText_SetFontBorderType(objTxt,BORDER_FULL);
		ObjText_SetFontBorderColor(objTxt,0,0,64);
		ObjText_SetFontBorderWidth(objTxt,1);
		ObjText_SetHorizontalAlignment(objTxt, ALIGNMENT_RIGHT);
		ObjText_SetMaxWidth(objTxt, 400);
		ObjRender_SetPosition(objTxt, 70, SpellTextY+15, 0);
		Obj_SetRenderPriority(objTxt, 0.79);
	}

	task BorderOfSpiritEffect{
		let objSpellBorder = SetSpellBorderProperties;
		let objSpellBorder2 = SetSpellBorderProperties;
		let BorderAlpha = 0;
		let BorderPos = 0;
		ObjRender_SetAngleXYZ(objSpellBorder2, 0, 0, 90);
		while(Obj_IsDeleted(objSpellBorder) == false){
			BorderPos+=0.9;
			ObjRender_SetAlpha(objSpellBorder, BorderAlpha);
			ObjRender_SetAlpha(objSpellBorder2, BorderAlpha);
			ObjRender_SetPosition(objSpellBorder, BorderPos*2.4-500, 326-BorderPos*0.4, 0);
			ObjRender_SetPosition(objSpellBorder2, 256-BorderPos*0.5, -BorderPos*2.4, 0);
			if(CutInTime<120&&BorderAlpha<255){BorderAlpha+=3;}
			if(CutInTime>119&&BorderAlpha>0){BorderAlpha-=3;}
			if(CutInTime>119 && BorderAlpha == 0){Obj_Delete(objSpellBorder);Obj_Delete(objSpellBorder2);}
			yield;
		}
	}
	
	task SpellAttackEffect(speed, alphamod){
		let alpha = 0;
		Octagon(GetCenterX*2, GetCenterY*2, -1.15, 180, 1);
		Octagon(GetCenterX*2, GetCenterY*2, 1.05, 240, 0);
		Octagon(GetCenterX*2, GetCenterY*2, 1.05, 295, 0);
		Octagon(GetCenterX/5, GetCenterY/5, 0.75, 170, 1);
		
		ascent (i in 0..5){
			Line(GetCenterX, GetCenterY+i*75-75-95, 1.5);
		}
		ascent (i in 0..5){
			Line(GetCenterX, GetCenterY+i*75-37.5-95, -1.5);
		}
		
		while(CutInTime<speed||alpha>0){
			if(CutInTime<speed && CutInTime>15 && alpha<145){alpha+=5*alphamod}
			if(CutInTime>=speed && alpha>0){alpha-=5*alphamod}
			yield;
		}
		
		task Line(mx, my, posinc){
			let objSpellAttack = SetSpellAttackProperties;
			let LineX = 0;
			let LineY = 0;
			ObjRender_SetAngleZ(objSpellAttack, -35);
			while(CutInTime<180 || alpha>0){
				LineX = LineX+posinc*cos(-35);
				LineY = LineY+posinc*sin(-35);
				ObjRender_SetPosition(objSpellAttack, mx+LineX, my+LineY, 0);
				ObjRender_SetAlpha(objSpellAttack, alpha);
				yield;
			}
			Obj_Delete(objSpellAttack);
		}
	
		task Octagon(mx, my, spininc, dist, size){
		
			let countVertex = 16;
			let listRadius = [];
			loop(countVertex){
				listRadius = listRadius ~ [0];
			}

			let objOutline = ObjPrim_Create(OBJ_PRIMITIVE_2D);
			ObjPrim_SetPrimitiveType(objOutline, PRIMITIVE_TRIANGLESTRIP);
			ObjPrim_SetVertexCount(objOutline, countVertex);
			ObjRender_SetBlendType(objOutline, BLEND_ALPHA);
			Obj_SetRenderPriority(objOutline, 0.76);
			ObjPrim_SetTexture(objOutline, img_SpellAttack);
	
			ascent (iVert in 0..countVertex/2){
				let left = iVert * 128;
				let indexVert = iVert * 2;
				ObjPrim_SetVertexUVT(objOutline, indexVert + 0, left, 0);
				ObjPrim_SetVertexUVT(objOutline, indexVert + 1, left, 16);
			}			
	
			let frame = 0;
			let rRate = 1;
			let spin = 0;
	
			while(CutInTime<180 || alpha>0){
				spin+=spininc;
				VertexSize;
				ObjRender_SetPosition(objOutline, mx, my, 0);
				ObjRender_SetAngleZ(objOutline, spin);
				ObjRender_SetAlpha(objOutline, alpha);
				frame++;
				yield;
			}
			Obj_Delete(objOutline);
			
			task VertexSize{	
				if(frame>=35){return;}
				ascent (iVert in 0..countVertex/2){
					let indexVert = iVert * 2;
					let angle = (360 / (countVertex / 2 - 1) * iVert);

					let vx1 = listRadius[indexVert] * cos(angle);
					let vy1 = listRadius[indexVert] * sin(angle);
					ObjPrim_SetVertexPosition(objOutline, indexVert + 0, vx1, vy1, 0);

					let vx2 = listRadius[indexVert+1] * cos(angle);
					let vy2 = listRadius[indexVert+1] * sin(angle);
					ObjPrim_SetVertexPosition(objOutline, indexVert + 1, vx2, vy2, 0);

					let dr = (dist * rRate - listRadius[indexVert]) / 16;
					listRadius[indexVert] = listRadius[indexVert] + dr;
					if(frame>size){
						listRadius[indexVert + 1] = listRadius[indexVert + 1] + dr;
					}
				}
			}
		}
	}

	task BonusPoint{
		let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
		let count = 0;
		let bonus = 10;
		ObjPrim_SetTexture(obj, img_effect2);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.8);
		while(!Obj_IsDeleted(SnowEnemyObject)){
			ObjSpriteList2D_ClearVertexCount(obj);
			ObjRender_SetAlpha(obj, SpellBGAlpha);
			
			ObjRender_SetScaleXYZ(obj, 1, 1, 1);
			ObjSpriteList2D_SetSourceRect(obj, 0, 95, 128, 107);
			ObjSpriteList2D_SetDestCenter(obj);
			ObjRender_SetPosition(obj, GetStgFrameWidth-130, SpellTextY + 36, 0);
			ObjSpriteList2D_AddVertex(obj);
			
			
			let objScene = GetEnemyBossSceneObjectID;
			bonus = min(99999999, ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE));
			count = GetNumSize(bonus);
			let listNum = DigitToArray(bonus, count);
			
			//Bonus Score
			if(ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SHOOTDOWN_COUNT) +
			ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SPELL_COUNT) == 0){
				ascent(iObj in 0 .. count){
					let num = listNum[iObj];
					ObjRender_SetX(obj, GetStgFrameWidth-94-(8*count) + iObj * 7);
					ObjSpriteList2D_SetSourceRect(obj, num * 8, 112, (num + 1) * 8, 124);
					ObjSpriteList2D_SetDestCenter(obj);
					ObjSpriteList2D_AddVertex(obj);
				}
			}else{
					ObjRender_SetX(obj, GetStgFrameWidth-131);
					ObjSpriteList2D_SetSourceRect(obj, 144, 95, 176, 107);
					ObjSpriteList2D_SetDestCenter(obj);
					ObjSpriteList2D_AddVertex(obj);
			}
			
			//History
			let attempt = min(SpellValueAttempt, 999);
			let get = min(SpellValueGet, 999);
			if(attempt < 100){count = 2;}else{count = 3;}
			listNum = DigitToArray(get, count) ~ [10] ~ DigitToArray(attempt, count);
				
			ascent(iObj in 0 .. count*2+1){
				let num = listNum[iObj];
				ObjRender_SetX(obj, GetStgFrameWidth-58 + iObj * 8);
				ObjSpriteList2D_SetSourceRect(obj, num * 8, 112, (num + 1) * 8, 124);
				ObjSpriteList2D_SetDestCenter(obj);
				ObjSpriteList2D_AddVertex(obj);
			}
			
			
			yield;
		}
		if(IsReplay == false){
			if(bonus>1){
				SpellValueGet++;
				SetAreaCommonData("SpellFunctions", SpellDataGet, SpellValueGet);
			}
			SaveCommonDataAreaA1("SpellFunctions");
		}
		Obj_Delete(obj);
	}
}


task ScreenShakeA1(shaketime, intensity){
//working
	while(shaketime>0){
		Set2DCameraFocusX(GetStgFrameWidth/2 + rand(-intensity, intensity));
		Set2DCameraFocusY(GetStgFrameHeight/2 + rand(-intensity, intensity));
		shaketime--;
		yield;
	}
	Reset2DCamera;
	yield;
}
task ScreenShakeA2(shaketime, intensity){
//working
	let ramp = 0;
	let fr = 0;
	while(shaketime>0){
		if(fr>=1){
			ramp = min(ramp+0.75, intensity);
			Set2DCameraFocusX(GetStgFrameWidth/2 + rand(-ramp, ramp));
			Set2DCameraFocusY(GetStgFrameHeight/2 + rand(-ramp, ramp));
			shaketime--;
		}else{
			
		}
		if(!IsTimeStopped){fr+=1/TimeSpeed;}
		yield;
	}
	Reset2DCamera;
	yield;
}

task ScreenFlash(objid, decay, alpha){
//needs workaround
	let menuscreen = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(menuscreen, img_effect);
	ObjRender_SetBlendType(menuscreen, BLEND_ALPHA);
	Obj_SetRenderPriorityI(menuscreen, 69);
	ObjRender_SetAlpha(menuscreen, alpha);
	ObjSprite2D_SetSourceRect(menuscreen, 240, 234, 252, 246);
	ObjSprite2D_SetDestRect(menuscreen, -124, -124, 524, 524);
	
	while(alpha>0 && !Obj_IsDeleted(objid)){
		alpha+=decay;
		ObjRender_SetAlpha(menuscreen, alpha);
		yield;
	}
	
	Obj_Delete(menuscreen);
	
}

// snow did this
task ScreenDistort(SnowEnemyObject, AI, length){
//distorts screen? looks weird
	let renderTexture = GetReservedRenderTargetName(0);

	SetInvalidRenderPriorityA1(20, 79);

	let objCurentFrame = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objCurentFrame, 80);

	if(length == -1){while(ObjEnemy_GetInfo(SnowEnemyObject, INFO_LIFE) > 0){PerformActions;yield;}}	
	if(length != -1){while(length>0){length--;PerformActions;yield;}}
	
	Obj_Delete(objCurentFrame);
	ClearInvalidRenderPriority;
	
	task PerformActions{
		let currentFrameTexture = renderTexture;
		RenderToTextureA1(currentFrameTexture, 20, 79, true);
		ObjPrim_SetTexture(objCurentFrame, currentFrameTexture);
		ObjSprite2D_SetSourceRect(objCurentFrame, 32, 16, 416, 464);
		ObjSprite2D_SetDestRect(objCurentFrame, rand(32, 36+AI), rand(16, 36+AI), rand(416-AI, 416), rand(464-AI, 464));
	}
}

task Shadow(x, y, incremental, alpha, colorR, colorG, colorB, stime){
//adds a whole colour to the screen
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let ShadowTime = 0;
	let xBend = 1;
	let yBend = 1;
	let BendInc = 0.22;
	let ShadSet = 0;
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, 0.69);
	ObjRender_SetAlpha(obj, alpha);
	ObjPrim_SetTexture(obj, img_effect2);
	ObjSprite2D_SetSourceRect(obj, 0, 130, 62, 192);
	ObjSprite2D_SetDestRect(obj, -xBend, -xBend, xBend, xBend);
	ObjRender_SetPosition(obj, x, y, 0);
	ObjRender_SetColor(obj, colorR, colorG, colorB);
		while(Obj_IsDeleted(obj) == false){
		ShadowTime++;
		ObjSprite2D_SetDestRect(obj, -xBend, -xBend, xBend, xBend);
		
		if(xBend<1500&&ShadSet==0){
			xBend+=BendInc;
			BendInc+=incremental;
		}
		if(ShadowTime>stime&&ShadSet==0){
			BendInc=0;		
			ShadSet=2;
		}
		if(ShadowTime>stime&&ShadSet==2){
			xBend+=BendInc;
			BendInc-=incremental*1.75;
		}
		if(xBend<-20){Obj_Delete(obj);}
		yield;
	}
}



task SpellTime(SpellTimeSceneObjectID){
	//@Mainloop
	let GetTimer = ObjEnemyBossScene_GetInfo(SpellTimeSceneObjectID, INFO_TIMER);
	if(bosstime != GetTimer && GetTimer <11){
		if(GetTimer > 4){se_timeout;}
		if(GetTimer < 5 && GetTimer>-1){se_timeout2;}
		bosstime = GetTimer;
	}
}


task TimeStop(tX, tY, length){
//works only with addtime stop
	SetCommonData("TimeStop", 1);
	LastTimeStop = length;
	IsTimeStopped = true;
	Shadow(tX, tY, 1.45, 165, 1, 1, 1, length-25);
	ascent(time in 0..length){
		yield;
	}
	SetCommonData("TimeStop", 0);
	IsTimeStopped = false;
	ScreenFlash(ID_INVALID, -10, 50);
	ScreenShakeA1(15, 1.75);
}

task TimeSlow(divide, length){
	SetCommonData("TimeSlow", divide);
	ascent(time in 0..length){
		yield;
	}
	SetCommonData("TimeSlow", 0);
}


task ObjShot_AddTimeStopA1(objID, spd){	
	let tspd = 1;
	while(!Obj_IsDeleted(objID)){
		tspd = GetCommonData("TimeSlow", 1);
		if(GetCommonData("TimeStop", 0) > 0){
			ObjMove_SetSpeed(objID, 0);
		}else{
			ObjMove_SetSpeed(objID, spd/tspd);
		}
		yield;
	}
}	





task ObjEnemy_OnHitBombA1(objid){
//explode when hit by bomb? should call as explosion from PCB
	if(quality<=1){return;}
	let hp = ObjEnemy_GetInfo(objid, INFO_LIFE);
	let hit = 0;
	while(Obj_IsDeleted(objid) == false){
		if(IsPlayerSpellActive == true){
			if(hp > ObjEnemy_GetInfo(objid, INFO_LIFE)){hit++; hp = ObjEnemy_GetInfo(objid, INFO_LIFE);}else{hp = ObjEnemy_GetInfo(objid, INFO_LIFE);}
			if(hit>7-quality){loop(quality*2){CreateEffect(ObjMove_GetX(objid), ObjMove_GetY(objid));} hit = 0;}
		}else{hit = 0;}
		yield;
	}
	task CreateEffect(deX, deY){
		let angZ = rand(0,360);
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriority(obj, 0.60);
		ObjPrim_SetTexture(obj, img_effect);
		ObjSprite2D_SetSourceRect(obj, 64, 16, 129, 80);
		ObjSprite2D_SetDestCenter(obj);
		ObjRender_SetPosition(obj, deX, deY, 0);
		
		let alpha = 205;
		let scale = 0.25;
		let scaleinc = rand(0.35, 0.45);
		let randX = rand(-500, 500);
		let randY = rand(-500, 500);
		let randspin = rand(6,10);
		while(Obj_IsDeleted(obj)==false && scale>0 && alpha>0){
			scaleinc += -0.05;
			scale += max(-0.05, scaleinc);
			alpha += -0.1;
			deX += randX/100-scaleinc;
			deY += randY/100-scaleinc;
			angZ += randspin;
			
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleZ(obj, angZ);
			ObjRender_SetAlpha(obj, alpha);
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			
			yield;
		}
		Obj_Delete(obj);
}

}

task ImageOverImageA1(obj, path, InX, InY, radset){
	let countVertex = 64;
	ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN);
	ObjPrim_SetVertexCount(obj, countVertex);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	ObjRender_SetAlpha(obj, 255);
	Obj_SetRenderPriority(obj, 0.3);
	ObjPrim_SetTexture(obj, path);
	ascent(iVert in 0..countVertex){
		let angle = (360 / (countVertex - 1) * iVert);
		let x = InX+radset*cos(angle);
		let y = InY+radset*sin(angle);
		ObjPrim_SetVertexUVT(obj, iVert, x, y);	
		x = radset*cos(angle);
		y = radset*sin(angle);
		ObjPrim_SetVertexPosition(obj, iVert , x, y, 0);
	}
}

task SetNewImageRender(obj, InX, InY, radset){
	let countVertex = 64;
	ascent(iVert in 0..countVertex){
		let angle = (360 / (countVertex - 1) * iVert);
		let x = InX+radset*cos(angle);
		let y = InY+radset*sin(angle);
		ObjPrim_SetVertexUVT(obj, iVert, x, y);	
		x = radset*cos(angle);
		y = radset*sin(angle);
		ObjPrim_SetVertexPosition(obj, iVert , x, y, 0);
	}
}

//Animation

//top left fairies 42x38 grid
//top right fairies 48x48 grid
//bottom 4 basic color fairies 32x32 grid
//bottom right; very bottom fairies 64x64 grid



task AnimateBossA1(objID){
	//General Pre MoF
	let anim_count = 0;
	let anim_type = 0;
	
	let xoffset = 0;
	let yoffset = 0;
	
	let r = 7; // Frames yielded before moving to next frame
	let m = -6; // Initial Position - Movement Up/down 
	let x = 64; // X grid
	let y = 80; // Y grid
	
	MoveBoss(1, 0.01, 0.325);
	
	while(!Obj_IsDeleted(objID)){
		if(ObjMove_GetSpeed(objID) == 0){
			if(anim_type == 1){
				anim_count = 0;
				anim_type = 2;
			}
		}
		if(ObjMove_GetSpeed(objID) > 0){
			if(anim_type == 0){
				anim_count = 0;
				anim_type = 1;
			}
		}
		
		if(CheckDirection(objID, "right") == true){ObjRender_SetScaleXYZ(objID, 1, 1, 1)}
		if(CheckDirection(objID, "left") == true){ObjRender_SetScaleXYZ(objID, -1, 1, 1)}
		
		
		if(anim_type==0){ //Idle
			if(anim_count == 0){ObjSprite2D_SetSourceRect(objID, 0, yoffset, x, yoffset+y);}
			if(anim_count == r){ObjSprite2D_SetSourceRect(objID, x, yoffset, x*2, yoffset+y);}
			if(anim_count == r*2){ObjSprite2D_SetSourceRect(objID, x*2, yoffset, x*3, yoffset+y);}
			if(anim_count == r*3){ObjSprite2D_SetSourceRect(objID, x*3, yoffset, x*4, yoffset+y);}
			if(anim_count == r*4){ObjSprite2D_SetSourceRect(objID, x*3, yoffset, x*4, yoffset+y);}
			if(anim_count == r*5){ObjSprite2D_SetSourceRect(objID, x*2, yoffset, x*3, yoffset+y);}
			if(anim_count == r*6){ObjSprite2D_SetSourceRect(objID, x, yoffset, x*2, yoffset+y);}
			if(anim_count >= r*7-1){anim_count = -1;}
		}
		if(anim_type==1){ //Moving
			if(anim_count == 0){ObjSprite2D_SetSourceRect(objID, 0, yoffset+y, x, yoffset+y*2);}
			if(anim_count == r){ObjSprite2D_SetSourceRect(objID, x, yoffset+y, x*2, yoffset+y*2);}
			if(anim_count == r*2){ObjSprite2D_SetSourceRect(objID, x*2, yoffset+y, x*3, yoffset+y*2);}
			if(anim_count == r*3){ObjSprite2D_SetSourceRect(objID, x*3, yoffset+y, x*4, yoffset+y*2);}
			if(anim_count >= r*4-1){anim_count = r*3-1;}
		}
		if(anim_type==2){ //Moving to idle
			if(anim_count == 0){ObjSprite2D_SetSourceRect(objID, x*3, yoffset+y, x*4, yoffset+y*2);}
			if(anim_count == r){ObjSprite2D_SetSourceRect(objID, x*2, yoffset+y, x*3, yoffset+y*2);}
			if(anim_count == r*2){ObjSprite2D_SetSourceRect(objID, x, yoffset+y, x*2, yoffset+y*2);}
			if(anim_count == r*3){ObjSprite2D_SetSourceRect(objID, 0, yoffset+y, x, yoffset+y*2);}
			if(anim_count == r*4){anim_type=0; anim_count=0;}
		}
		
		ObjSprite2D_SetDestRect(objID, -x/2, -y/2+m, x/2, y/2+m);
		if(IsTimeStopped==false){anim_count++;}
		yield;
	}
	task MoveBoss(type, a, b){
		let ax2 = a;
		let bx2 = b;
		let obj_sizeset = 0;
		let sizeinc = 0;
		while(!Obj_IsDeleted(objID)){
			if(IsTimeStopped == false){
				if(obj_sizeset==0){sizeinc+=ax2}
				if(obj_sizeset==1){sizeinc-=ax2}		
				if(sizeinc<-bx2){obj_sizeset=0}
				if(sizeinc>bx2){obj_sizeset=1}
		
				m+=sizeinc;
			}
			yield;
		}	
	}
}




function CheckDirection(checkid, direc){
	let direction = false;
	let enemyang = absolute(ObjMove_GetAngle(checkid));
	let enemyspd = absolute(ObjMove_GetSpeed(checkid));
	
	
	while(enemyang>360){
		enemyang = enemyang-360;
	}

	if(enemyspd > 0){
		if(direc=="right"){
			if(enemyang > 270 || enemyang-270 < 90){
				direction=true;
			}
		}
		if(direc=="left"){
			if(enemyang < 270 && enemyang > 90){
				direction=true;
			}
		}
	}
	if(direc=="none"){
		if(enemyspd == 0){
			direction=true;
		}
	}
	
	return direction;
}

function CheckOutsideScreen(objectID, distance){
	return ObjRender_GetX(objectID)>GetStgFrameWidth+distance||ObjRender_GetX(objectID)<-distance||
		ObjRender_GetY(objectID)>GetStgFrameHeight+distance||ObjRender_GetY(objectID)<-distance;
}

function CheckOutsideScreenA2(x, y, distance){
	return x>GetStgFrameWidth+distance||x<-distance||y>GetStgFrameHeight+distance||y<-distance;
}





function GetDistance(x1,y1,x2,y2){
	return(((x2-x1)^2+(y2-y1)^2)^(1/2))
}

function AngleToBoss(x, y){
	return atan2(EnemyY - y, EnemyX - x);
}

function GetAnyKeyStateA1(type){
	let skck = false;
	if(GetVirtualKeyState(VK_LEFT) == type){skck=true;}
	if(GetVirtualKeyState(VK_RIGHT) == type){skck=true;}
	if(GetVirtualKeyState(VK_UP) == type){skck=true;}
	if(GetVirtualKeyState(VK_DOWN) == type){skck=true;}
	return skck;
}

function IsAllKeysFree{
	let skck = false;
	if(GetVirtualKeyState(VK_LEFT) == KEY_FREE &&
	GetVirtualKeyState(VK_RIGHT) == KEY_FREE &&
	GetVirtualKeyState(VK_UP) == KEY_FREE &&
	GetVirtualKeyState(VK_DOWN) == KEY_FREE){skck=true;}
	return skck;
}

task FinalizeSpell{
//ONLY for mid spells
	EnemyDead = true;
	se_tan01;
	Obj_Delete(objEnemy);
	ClearBullets(EnemyX, EnemyY, TYPE_ITEM, 30, 10, 500, 0);
	loop(argument/4+10){
		CreateItemA1(ITEM_POINT_S, EnemyX+rand(-60, 60), EnemyY+rand(-60, 60), rand(360, 3600));
		CreateItemA1(ITEM_POWER_S, EnemyX+rand(-60, 60), EnemyY+rand(-60, 60), 0.02);
	}
}

task FinalizePlural(FinalX, FinalY){
//only for bosses final spell
	EnemyDead = true;
	let finalframe = 0;

	ObjMove_SetDestAtWeight(objEnemy, FinalX-16, FinalY-12, 130, 1);
	ExplosionA1(FinalX, FinalY, 0, 0, 0);	
	loop(quality*20){ExplosionA2(FinalX, FinalY, rand(-360, 360), rand(-360, 360), rand(-360, 360), rand(1, 3));}
	ScreenShakeA1(45,24);
	ClearBullets(FinalX, FinalY, TYPE_ITEM, 30, 10, 500, 0);
	se_enep01;
	loop(100){
		if(finalframe>6){
			loop(quality+1){ExplosionA2(FinalX, FinalY, rand(-360, 360), rand(-360, 360), rand(-360, 360), rand(2, 5));}
			finalframe = 0;
			se_tan00;
		}
		finalframe++;
		ScreenShakeA1(4,12);
		yield;
	}
	
	se_enep01;
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	loop(argument/2){
		CreateItemA1(ITEM_POINT_S, FinalX+rand(-60, 60), FinalY+rand(-60, 60), rand(360, 3600));
		CreateItemA1(ITEM_POWER_S, FinalX+rand(-60, 60), FinalY+rand(-60, 60), 0.15);
		ExplosionA2(FinalX, FinalY, rand(-360, 360), rand(-360, 360), rand(-360, 360), rand(1, 7));}
	ScreenShakeA1(30,32);
	ExplosionA1(FinalX, FinalY, 0, 0, 0);
	SetCommonData("StarX1", -400);
	SetCommonData("StarY1", -400);
	Obj_Delete(objEnemy);
}

task FinalizeMid(FinalX, FinalY){
//only for bosses final spell
	EnemyDead = true;
	let finalframe = 0;

	ObjMove_SetDestAtWeight(objEnemy, FinalX-16, FinalY-12, 130, 1);
	ExplosionA1(FinalX, FinalY, 0, 0, 0);	
	loop(quality*20){ExplosionA2(FinalX, FinalY, rand(-360, 360), rand(-360, 360), rand(-360, 360), rand(1, 3));}
	ClearBullets(FinalX, FinalY, TYPE_ITEM, 30, 10, 500, 0);

	
	se_enep01;
	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	loop(argument/2){
		CreateItemA1(ITEM_POINT_S, FinalX+rand(-60, 60), FinalY+rand(-60, 60), rand(360, 3600));
		CreateItemA1(ITEM_POWER_S, FinalX+rand(-60, 60), FinalY+rand(-60, 60), 0.15);
		ExplosionA2(FinalX, FinalY, rand(-360, 360), rand(-360, 360), rand(-360, 360), rand(1, 7));}
	ExplosionA1(FinalX, FinalY, 0, 0, 0);
	SetCommonData("StarX1", -400);
	SetCommonData("StarY1", -400);
	Obj_Delete(objEnemy);
}


task BackgroundBulgeA2(objEnemy){
//??????
	if(GetCommonData("quality", 2) !=3){return;}
	let renderTexture = GetReservedRenderTargetName(0);

	let frame = 0;
	let baseEffectRadius = 0; 
	let maxEffectRadius = 144;
	let outerFluct = 16;
	let effectRadius = 0;
	let circleVertexCount = 16; 
	let innerCircleCount = 4;
	let gscale = 0;

	let priEffectMin = 20; 
	let priEffectMax = 28; 




	let frameWidth = GetStgFrameWidth;
	let frameHeight = GetStgFrameHeight;
	let frameLeft = GetStgFrameLeft;
	let frameRight = frameLeft + frameWidth;
	let frameTop = GetStgFrameTop;
	let frameBottom = frameTop + frameHeight;


	let path = GetCurrentScriptDirectory ~ "img/effect4.png";
	let objShadow = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriorityI(objShadow, 25); 
	ObjPrim_SetTexture(objShadow, path);
	ObjRender_SetBlendType(objShadow, BLEND_MULTIPLY);
	ObjSprite2D_SetSourceRect(objShadow, 1, 1, 255, 255);
	ObjSprite2D_SetDestCenter(objShadow);
	ObjRender_SetScaleXYZ(objShadow, 0, 0, 0);
	
	SetInvalidRenderPriorityA1(priEffectMin, priEffectMax);

	let objInnerC = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	Obj_SetRenderPriorityI(objInnerC, priEffectMax + 1);
	ObjPrim_SetTexture(objInnerC, renderTexture);
	ObjPrim_SetVertexCount(objInnerC, 6 * circleVertexCount * innerCircleCount);


	let objOuterC = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	Obj_SetRenderPriorityI(objOuterC, priEffectMax + 1);
	ObjPrim_SetTexture(objOuterC, renderTexture);
	ObjPrim_SetVertexCount(objOuterC, 3 * circleVertexCount);


	let objOuterE = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
	Obj_SetRenderPriorityI(objOuterE, priEffectMax + 1);
	ObjPrim_SetTexture(objOuterE, renderTexture);


	while(!Obj_IsDeleted(objEnemy)){

		ObjRender_SetScaleXYZ(objShadow, gscale, gscale, 0);
		gscale = min(gscale+(1.2/85), 1.2);
		baseEffectRadius = min(baseEffectRadius+(maxEffectRadius/85), maxEffectRadius);
		
		if(GetCommonData("ForceLifebar", 0) == 1){gscale=0;baseEffectRadius=0;}
		
		effectRadius = baseEffectRadius + outerFluct * sin(frame*4);

		let enemyX = ObjRender_GetX(objEnemy);
		let enemyY = ObjRender_GetY(objEnemy); 
		let circleLeft = enemyX - effectRadius + frameLeft;
		let circleRight = enemyX + effectRadius + frameLeft; 
		let circleTop = enemyY - effectRadius + frameTop; 
		let circleBottom = enemyY + effectRadius + frameTop; 


		RenderToTextureA1(renderTexture, priEffectMin, priEffectMax, true);


		ObjRender_SetPosition(objShadow, enemyX, enemyY, 0);


		ObjRender_SetPosition(objInnerC, -frameLeft, -frameTop, 0);
		ascent(let iPosI in 0 .. circleVertexCount){
			let xyOldRadius = 0;
			ascent(let iCircle in 0 .. innerCircleCount){
				let vertexIndex = (iPosI * innerCircleCount + iCircle) * 6;
				let angle1 =  iPosI * (360 / circleVertexCount);
				let angle2 =  (iPosI + 1) * (360 / circleVertexCount);


				let uvRadius1 = iCircle * effectRadius / innerCircleCount;
				let uvRadius2 = (iCircle + 1) * effectRadius / innerCircleCount;

				let xyRadius1t = iCircle * effectRadius / innerCircleCount;
				let xyRadius2t = (iCircle + 1) * effectRadius / innerCircleCount;
				let xyRadius1 = xyOldRadius;
				let xyBias = (xyRadius2t - xyRadius1t) / 2 + (xyRadius2t - xyRadius1t) * sin(frame*16 + (iCircle * 360 / innerCircleCount)) / 4;
				let xyRadius2 = xyRadius2t + xyBias / ((innerCircleCount - iCircle + 1) / 2);

				xyOldRadius = xyRadius2;
				if(iCircle == innerCircleCount - 1){
					xyRadius2 = uvRadius2;
				}

				let leftBias = enemyX + frameLeft;
				let topBias = enemyY + frameTop;
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex  , leftBias + xyRadius1 * cos(angle1), topBias + xyRadius1 * sin(angle1), 0);
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex+1, leftBias + xyRadius2 * cos(angle1), topBias + xyRadius2 * sin(angle1), 0);
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex+2, leftBias + xyRadius1 * cos(angle2), topBias + xyRadius1 * sin(angle2), 0);
			
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex+3, leftBias + xyRadius1 * cos(angle2), topBias + xyRadius1 * sin(angle2), 0);
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex+4, leftBias + xyRadius2 * cos(angle1), topBias + xyRadius2 * sin(angle1), 0);
				ObjPrim_SetVertexPosition(objInnerC, vertexIndex+5, leftBias + xyRadius2 * cos(angle2), topBias + xyRadius2 * sin(angle2), 0);

				ObjPrim_SetVertexUVT(objInnerC, vertexIndex  , leftBias + uvRadius1 * cos(angle1), topBias + uvRadius1 * sin(angle1));
				ObjPrim_SetVertexUVT(objInnerC, vertexIndex+1, leftBias + uvRadius2 * cos(angle1), topBias + uvRadius2 * sin(angle1));
				ObjPrim_SetVertexUVT(objInnerC, vertexIndex+2, leftBias + uvRadius1 * cos(angle2), topBias + uvRadius1 * sin(angle2));
			
				ObjPrim_SetVertexUVT(objInnerC, vertexIndex+3, leftBias + uvRadius1 * cos(angle2), topBias + uvRadius1 * sin(angle2));
				ObjPrim_SetVertexUVT(objInnerC, vertexIndex+4, leftBias + uvRadius2 * cos(angle1), topBias + uvRadius2 * sin(angle1));
				ObjPrim_SetVertexUVT(objInnerC, vertexIndex+5, leftBias + uvRadius2 * cos(angle2), topBias + uvRadius2 * sin(angle2));

			}
		}


		ObjRender_SetPosition(objOuterC, -frameLeft, -frameTop, 0);
		ascent(let iPosO in 0 .. circleVertexCount){
			let angle1 = iPosO * (360 / circleVertexCount);
			let angle2 = (iPosO + 1) * (360 / circleVertexCount);
			let rectX = 0;
			let rectY = 0;
			if(angle1 >= 0 && angle1 < 90){
				rectX = circleRight;
				rectY = circleBottom;
			}
			else if(angle1 >= 90 && angle1 < 180){
				rectX = circleLeft;
				rectY = circleBottom;
			}
			else if(angle1 >= 180 && angle1 < 270){
				rectX = circleLeft;
				rectY = circleTop;
			}
			else if(angle1 >= 270 && angle1 < 360){
				rectX = circleRight;
				rectY = circleTop;
			}
			let vertexIndex = iPosO * 3;
			ObjPrim_SetVertexPosition(objOuterC, vertexIndex, enemyX + effectRadius * cos(angle1) + frameLeft, enemyY + effectRadius * sin(angle1) + frameTop, 0);
			ObjPrim_SetVertexPosition(objOuterC, vertexIndex+1, rectX, rectY, 0);
			ObjPrim_SetVertexPosition(objOuterC, vertexIndex+2, enemyX + effectRadius * cos(angle2) + frameLeft, enemyY + effectRadius * sin(angle2) + frameTop, 0);

			ObjPrim_SetVertexUVT(objOuterC, vertexIndex, enemyX + effectRadius * cos(angle1) + frameLeft, enemyY + effectRadius * sin(angle1) + frameTop);
			ObjPrim_SetVertexUVT(objOuterC, vertexIndex+1, rectX, rectY);
			ObjPrim_SetVertexUVT(objOuterC, vertexIndex+2, enemyX + effectRadius * cos(angle2) + frameLeft, enemyY + effectRadius * sin(angle2) + frameTop);
		}
		

		ObjSpriteList2D_ClearVertexCount(objOuterE);
		ObjRender_SetPosition(objOuterE, -frameLeft, -frameTop, 0);
		ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, frameTop, frameRight, circleTop + 1);
		ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, frameTop, frameRight, circleTop + 1);
		ObjSpriteList2D_AddVertex(objOuterE);

		ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, circleTop, circleLeft + 1, circleBottom);
		ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, circleTop, circleLeft + 1, circleBottom);
		ObjSpriteList2D_AddVertex(objOuterE);

		ObjSpriteList2D_SetSourceRect(objOuterE, circleRight, circleTop, frameRight, circleBottom);
		ObjSpriteList2D_SetDestRect(objOuterE, circleRight, circleTop, frameRight, circleBottom);
		ObjSpriteList2D_AddVertex(objOuterE);

		ObjSpriteList2D_SetSourceRect(objOuterE, frameLeft, circleBottom, frameRight, frameBottom);
		ObjSpriteList2D_SetDestRect(objOuterE, frameLeft, circleBottom, frameRight, frameBottom);
		ObjSpriteList2D_AddVertex(objOuterE);

		frame++;
		yield;
	}

	Obj_Delete(objInnerC);
	Obj_Delete(objOuterC);
	Obj_Delete(objOuterE);
	Obj_Delete(objShadow);
	ClearInvalidRenderPriority;
}

task ObjCutin_SetSpellcardS3(SpellName, R, G, B){
	let r = IntToString(R);
	let g = IntToString(G);
	let b = IntToString(B);
	let boss = GetEnemyBossObjectID[0];
	let spells = Obj_GetValueD(boss, "Spellcards", []);
	spells = spells~[[SpellName, r, g, b, "", ""]];
	Obj_SetValue(boss, "Spellcards", spells);
}

task ObjCutin_SetSpellcardS4(SpellName, image, cuttype, R, G, B){
	let r = IntToString(R);
	let g = IntToString(G);
	let b = IntToString(B);
	let boss = GetEnemyBossObjectID[0];
	let spells = Obj_GetValueD(boss, "Spellcards", []);
	spells = spells~[[SpellName, r, g, b, cuttype, image]];
	Obj_SetValue(boss, "Spellcards", spells);
}

task ObjCutin_LaunchS3(type, image, difficulty){
	CutinS3(type, image, difficulty);
}

task CutinS3(Type, mimage, difficulty){
	let spells = Obj_GetValueD(GetEnemyBossObjectID[0], "Spellcards", []);
	let boss = GetEnemyBossObjectID[0];
	let spcount = length(spells);
	CutinDifficulty = difficulty;
	let IsSpellAttackAnimation = false;
	if(!IsCommonDataAreaExists("cutin_History")){
		CreateCommonDataArea("cutin_History");
	}
	LoadCommonDataAreaA1("cutin_History");


	//if(length(Images)>6)
	//	Images = [Images];
	////	Colors = [Colors];
	//
	//let Colors = [[r, g, b]];

	descent(i in 0..spcount){SpellText(6*i, i);}
	SpawnCutinImage(Type, mimage);
	
	
	let delay = 6;
	while(!Obj_IsDeleted(boss)){
		spells = Obj_GetValueD(GetEnemyBossObjectID[0], "Spellcards", []);
		if(length(spells)!=spcount&&delay==0){
			delay = 6;
			SpellText(0, spcount);
			let newtype = spells[spcount][4];
			if(newtype == ""){newtype = Type;}
			SpawnCutinImage(newtype, spells[spcount][5]);
			spcount++;
		}
		delay = max(delay-1, 0);
		yield;
	}
	
	
	
	task FireCutinA1(x, y, angle, ispeed, itime, mspeed, mtime, img){	
		if(IsSpellAttackAnimation){return;}	
		let SpellCutin = CreateSimple2DImageA1(0.29, img);
		ObjRender_SetPosition(SpellCutin, x, y, 0);
		ObjRender_SetAlpha(SpellCutin, 0);
		
		
		
		let len = itime;
		ascent(x in 0..len){
			let mod = x/len;
			let locs = [ObjRender_GetX(SpellCutin), ObjRender_GetY(SpellCutin)];
			ObjRender_SetPosition(SpellCutin, floor(locs[0]+ispeed*cos(angle)), floor(locs[1]+ispeed*sin(angle)), 0);
			
			let alph = min(255, 255*(mod*2));
			ObjRender_SetAlpha(SpellCutin, alph);
			yield;
		}
		
		len = mtime;
		let nx = ObjRender_GetX(SpellCutin);
		let ny = ObjRender_GetY(SpellCutin);
		ascent(x in 0..len){
			nx += mspeed*cos(angle);
			ny += mspeed*sin(angle);
			ObjRender_SetPosition(SpellCutin, floor(nx), floor(ny), 0);
			yield;
		}
		//return;
		len = mtime;
		ascent(x in 0..len){
			let mod = x/len;
			let locs = [ObjRender_GetX(SpellCutin), ObjRender_GetY(SpellCutin)];
			ObjRender_SetPosition(SpellCutin, floor(locs[0]+ispeed*cos(angle)), floor(locs[1]+ispeed*sin(angle)), 0);
			yield;
		}
		Obj_Delete(SpellCutin);
	}

	task FireCutinA2(x, y, alpha, img, details){
		if(IsSpellAttackAnimation){return;}
		//[spd, spdinc, ang, anginc, alphachange, time]
		let SpellCutin = CreateSimple2DImageA1(0.29, img);
		ObjRender_SetPosition(SpellCutin, x, y, 0);
		ObjRender_SetAlpha(SpellCutin, alpha);
		
		ascent(i in 0..length(details)){
			let nx = ObjRender_GetX(SpellCutin);
			let ny = ObjRender_GetY(SpellCutin);
			let info = details[i];
			let len = info[5];
			let alphinc = -(alpha-info[4])/len;
			let spdinc = -(info[0]-info[1])/len;
			let mspeed = info[0];
			let cangle = info[2];
			ascent(x in 0..len){
				mspeed+=spdinc;
				cangle+=info[3];
				nx += mspeed*cos(cangle);
				ny += mspeed*sin(cangle);
				ObjRender_SetPosition(SpellCutin, nx, ny, 0);
				yield;
				alpha = min(max(alpha+alphinc, 0), 255);
				ObjRender_SetAlpha(SpellCutin, alpha);
			}
		}
		Obj_Delete(SpellCutin);
	}

	function SpawnCutinImage(type, image){
		//We use another "type" variable (lowercase t) so that
		//spellcards set after the root function is called will play the
		//new set cutin type as opposed to the original one
		// same for image
		if(type == "NAZRIN"){
			FireCutinA2(GetStgFrameWidth+208, GetStgFrameHeight/2-144, 0, image,
			[
				[20.6, 20.6, 158, 0, 255, 20],
				[0.65, 0.65, 158, 0, 255, 90],
				[20.6, 20.6, 158, 0, 255, 20]
			]
			);
			SpellAttackEffect(145);
		}
		else if(type == "KANAKO"){
			FireCutinA2(GetStgFrameWidth+180, GetStgFrameHeight/2-190, 0, image,
			[
				[30, 8, 144, 0, 192, 23],
				[8, 0, 144, 0, 255, 10],
				[0, 2.1, 270, 0, 255, 90],
				[2.1, 2.1, 270, 0, 255, 20],
				[2.1, 1, 270, 0, 0, 20]
			]
			);
			SpellAttackEffect(145);
		}
		else if(type == "BYAKUREN"){
			FireCutinA2(-256, GetStgFrameHeight/2, 0, image,
			[
				[14, 14, 0, 0, 255, 30],
				[0.5, 0.5, 0, 0, 255, 90],
				[14, 14, 0, 0, 0, 30]
			]
			);
			SpellAttackEffect(145);
		}
		else if(type == "LENEN" || type == "YABUSAME"){
			FireCutinA2(GetStgFrameWidth+256, GetStgFrameHeight/2+96, 0, image,
			[
				[32, 1, 182, 0.1, 255, 30],
				[1, 1.25, 180, 14, 255, 10],
				[1.25, 1.75, 315, 0, 255, 80],
				[2, 2.5, 340, -15.75, 192, 10],
				[2.5, 31, 182.5, 0, 0, 20],
			]
			);
			SpellAttackEffect(145);
		}
		else if(type == "AYA"){
			SpellAttackEffect(145);
		}
		else if(type == "MOKOU"){
		}
		else{RaiseError("Not a valid cutin type.");}
	}
	
	task SpellText(delay, num){
		let tspell = spells[num];
		let SpellName = tspell[0];
		let r = atoi(tspell[1]);
		let g = atoi(tspell[2]);
		let b = atoi(tspell[3]);
		
		let Colors = [[r,g,b]];
		
		//These are long-looking common data group names
		let SpellDataAttempt = SpellName~"|"~CutinDifficulty~"|"~GetPlayerID~"|"~"Attempt";
		let SpellDataGet = SpellName~"|"~CutinDifficulty~"|"~GetPlayerID~"|"~"Get";
		//This is actually the common data retrieval
		let SpellValueAttempt = GetAreaCommonData("cutin_History", SpellDataAttempt, 0);
		let SpellValueGet = GetAreaCommonData("cutin_History", SpellDataGet, 0);
		
		
		if(!IsReplay&&!DEBUG&&num==0){
			SpellValueAttempt++;
			SetAreaCommonData("cutin_History", SpellDataAttempt, SpellValueAttempt);
			SaveCommonDataAreaA1("cutin_History");
		}
	
	
		let SpellBG = CreateSimple2DImageA2(0.79+0.01*max(0, 1-num), SpellAttack_img, 0, 0, 255, 31);
		ObjSprite2D_SetDestRect(SpellBG, -224, -12, 32, 20);
		ObjRender_SetPosition(SpellBG, 340, 320+40*num, 0);
		ObjRender_SetAlpha(SpellBG, 0);
		ObjRender_SetColor(SpellBG, Colors[0][0], Colors[0][1], Colors[0][2]);
		
		let SpellText = ObjText_Create;
		ObjText_SetText(SpellText,SpellName);
		ObjText_SetFontSize(SpellText,12);
		ObjText_SetFontColorTop(SpellText,255,255,255);
		ObjText_SetFontColorBottom(SpellText, Colors[0][0], Colors[0][1], Colors[0][2]);
		ObjText_SetFontBorderType(SpellText,BORDER_FULL);
		ObjText_SetFontBorderColor(SpellText,32,32,32);
		ObjText_SetFontBorderWidth(SpellText,1);
		ObjText_SetHorizontalAlignment(SpellText, ALIGNMENT_RIGHT);
		ObjText_SetMaxWidth(SpellText, GetStgFrameWidth-24);
		Obj_SetRenderPriority(SpellText, 0.79+0.01*max(0, 1-num));
		ObjRender_SetPosition(SpellText, 0, 320+40*num, 0);
		ObjRender_SetAlpha(SpellText, 0);
		
		
		let SpellInfo = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
		let bonus = 0;
		let count = GetNumSize(bonus);
		let scount = max(2, GetNumSize(SpellValueAttempt));
		ObjPrim_SetTexture(SpellInfo, SpellAttack_img);
		ObjRender_SetBlendType(SpellInfo, BLEND_ALPHA);
		Obj_SetRenderPriority(SpellInfo, 0.8);
		ObjRender_SetY(SpellInfo, 36);
		ObjRender_SetAlpha(SpellInfo, 0);
		
		//-------------Introduction--------------------------
		
		loop(delay){yield;}
		let len = 30;
		ascent(i in 0..len){
			let mod = i/len;
			let tmod = min(1, ((i*2)/len));
			ObjRender_SetScaleXYZ(SpellBG, 4-3*mod, 4-3*mod, 1);
			ObjRender_SetAlpha(SpellBG, 255*mod);
			ObjRender_SetX(SpellText, (GetStgFrameWidth-24)*(1-mod));
			//ObjRender_SetScaleXYZ(SpellText, 4-3*tmod, 4-3*tmod, 1);
			ObjRender_SetAlpha(SpellText, 255*tmod);
			yield;
		}
		loop(40){yield;}
		let mov = 0;
		
		if(Type == "MOKOU"){SpellcardDeclareMovement([ObjRender_GetY(SpellText), 48+12*num, 0.175, 9]);loop(60){yield;}}
		else{RegularSpellCardDeclare([ObjRender_GetY(SpellText), 12+12*num, 0.135, 12]);}
		//32 is the offset from the top of the screen
		//If using a system where the lifebar is on the boss rather than the top of the screen, 12 is a good value

		
		loop(delay*0.65){yield;}
		
		ascent(i in 0..80){
			let endspeed = 0.5+i/2.5;
			ObjRender_SetX(SpellBG, ObjRender_GetX(SpellBG)+endspeed);
			ObjRender_SetX(SpellText, ObjRender_GetX(SpellText)+endspeed);
			yield;
		}
		
		Obj_Delete(SpellBG);
		Obj_Delete(SpellText);
		
		function SpellcardDeclareMovement(dest){
			ObjRender_SetY(SpellInfo, 24+dest[1]);
			while(dest[0]>dest[1]){
				dest[0] = ObjRender_GetY(SpellText);
				mov = min(mov+dest[2], (dest[0]-dest[1])/dest[3]+0.125);
				ObjRender_SetY(SpellBG, dest[0]-mov);
				ObjRender_SetY(SpellText, dest[0]-mov);
				yield;
			}
		}
		
		function RegularSpellCardDeclare(dest){
			if(num!=0){Obj_Delete(SpellInfo);}
			SpellcardDeclareMovement(dest);
			ascent(i in 0..20){
				ObjRender_SetAlpha(SpellInfo, 255/20*i);
				DrawScoreBonus;
				yield;
			}
			let timerf = ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID, INFO_ORGTIMERF);
			let startdiff = timerf-(timerf-5*60);
			while(!Obj_IsDeleted(boss)){
				ObjRender_SetAlpha(SpellBG, Alpha_HUD[0]);
				ObjRender_SetAlpha(SpellText, Alpha_HUD[0]);
				ObjRender_SetAlpha(SpellInfo, Alpha_HUD[0]);
				
			//	let modif = min(1, ((ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID, INFO_TIMERF))/(ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID, INFO_ORGTIMERF)-startdiff)));
			//	bonus = ((sscore*0.20)+(sscore*((modif)*0.80)));
				DrawScoreBonus;
				yield;
			}
			Obj_Delete(SpellInfo);
			
			if(bonus>=1&&ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID, INFO_TIMERF)>0){
			//	GotSpellCard(bonus);
			//	AddScore(bonus);
				if(!IsReplay&&!DEBUG&&num==0){
					SpellValueGet++;
					SetAreaCommonData("cutin_History", SpellDataGet, SpellValueGet);
					SaveCommonDataAreaA1("cutin_History");
				}
			}else{
			//	FailedSpellCard;
			}
		}
		sub DrawScoreBonus{
			if(GetPlayerY<128+32*length(spells)){Alpha_HUD[0] = max(Alpha_HUD[0]-10, 85);}else{Alpha_HUD[0] = min(Alpha_HUD[0]+11, 255);}
			
			ObjSpriteList2D_ClearVertexCount(SpellInfo);
				
			ObjSpriteList2D_SetSourceRect(SpellInfo, 0, 48, 128, 60);
			ObjSpriteList2D_SetDestCenter(SpellInfo);
			ObjRender_SetX(SpellInfo, 382-130);
			ObjSpriteList2D_AddVertex(SpellInfo);
			//Bonus Score
			bonus = ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID, INFO_SPELL_SCORE);
			count = GetNumSize(bonus);
			let listNum = DigitToArray(min(99999999, bonus), count);
			let objScene = GetEnemyBossSceneObjectID;
			if(ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SHOOTDOWN_COUNT) +
			ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SPELL_COUNT) == 0){
				ascent(iObj in 0 .. count){
					let num = listNum[iObj];
					ObjRender_SetX(SpellInfo, 382-94-(8*count) + iObj * 7);
					ObjSpriteList2D_SetSourceRect(SpellInfo, num * 8, 64, (num + 1) * 8, 76);
					ObjSpriteList2D_SetDestCenter(SpellInfo);
					ObjSpriteList2D_AddVertex(SpellInfo);
				}
			}else{
					bonus = 0;
					ObjRender_SetX(SpellInfo, 382-131);
					ObjSpriteList2D_SetSourceRect(SpellInfo, 144, 48, 176, 60);
					ObjSpriteList2D_SetDestCenter(SpellInfo);
					ObjSpriteList2D_AddVertex(SpellInfo);
			}
			//History
			listNum = DigitToArray(SpellValueGet, scount) ~ [10] ~ DigitToArray(SpellValueAttempt, scount);
				
			ascent(iObj in 0 .. scount*2+1){
				let num = listNum[iObj];
				ObjRender_SetX(SpellInfo, 382-58 + iObj * 8);
				ObjSpriteList2D_SetSourceRect(SpellInfo, num * 8, 64, (num + 1) * 8, 76);
				ObjSpriteList2D_SetDestCenter(SpellInfo);
				ObjSpriteList2D_AddVertex(SpellInfo);
			}
		}
	}
	
	task SpellAttackEffect(alphamax){
		if(IsSpellAttackAnimation){return;}
		IsSpellAttackAnimation = true;
		let alpha = 1;
		let GetCenterX = GetStgFrameWidth/2;
		let GetCenterY = GetStgFrameHeight/2;
		Octagon(GetCenterX*2, GetCenterY*2, -1.15, 180, 1);
		Octagon(GetCenterX*2, GetCenterY*2, 1.05, 240, 0);
		Octagon(GetCenterX*2, GetCenterY*2, 1.05, 295, 0);
		Octagon(GetCenterX/5, GetCenterY/5, 0.75, 170, 1);
		
		ascent (i in 0..5){
			Line(GetCenterX, GetCenterY+i*75-75-95, 1.5);
		}
		ascent (i in 0..5){
			Line(GetCenterX, GetCenterY+i*75-37.5-95, -1.5);
		}
		
		loop(15){yield;}
		ascent(i in 0..20){
			alpha = 0.1+alphamax/20*i;
			yield;
		}
		loop(110){yield;}
		descent(i in 0..20){
			alpha = alphamax/20*i;
			yield;
		}
		
		IsSpellAttackAnimation = false;
		
		task Line(mx, my, posinc){
			let objSpellAttack = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(objSpellAttack, BLEND_ALPHA);
			Obj_SetRenderPriority(objSpellAttack, 0.75);
			ObjPrim_SetTexture(objSpellAttack, img_SpellAttack);
			ObjSprite2D_SetSourceRect(objSpellAttack, 0, 0, 512, 16);
			ObjSprite2D_SetDestRect(objSpellAttack, -256, -8, 256, 8);
			let LineX = 0;
			ObjRender_SetPosition(objSpellAttack, mx, my, 0);
			ObjRender_SetAngleZ(objSpellAttack, -35);
			while(alpha>0){
				LineX += posinc;
				ObjSprite2D_SetSourceRect(objSpellAttack, LineX, 0, 512+LineX, 16);
				ObjRender_SetAlpha(objSpellAttack, alpha);
				yield;
			}
			Obj_Delete(objSpellAttack);
		}
	
		task Octagon(mx, my, spininc, dist, size){
		
			let countVertex = 16;
			let listRadius = [];
			loop(countVertex){
				listRadius = listRadius ~ [0];
			}

			let objOutline = ObjPrim_Create(OBJ_PRIMITIVE_2D);
			ObjPrim_SetPrimitiveType(objOutline, PRIMITIVE_TRIANGLESTRIP);
			ObjPrim_SetVertexCount(objOutline, countVertex);
			ObjRender_SetBlendType(objOutline, BLEND_ALPHA);
			Obj_SetRenderPriority(objOutline, 0.76);
			ObjPrim_SetTexture(objOutline, img_SpellAttack);
	
			ascent (iVert in 0..countVertex/2){
				let left = iVert * 128;
				let indexVert = iVert * 2;
				ObjPrim_SetVertexUVT(objOutline, indexVert + 0, left, 0);
				ObjPrim_SetVertexUVT(objOutline, indexVert + 1, left, 16);
			}			
	
			let frame = 0;
			let rRate = 1;
			let spin = 0;
	
			while(alpha>0){
				spin+=spininc;
				VertexSize;
				ObjRender_SetPosition(objOutline, mx, my, 0);
				ObjRender_SetAngleZ(objOutline, spin);
				ObjRender_SetAlpha(objOutline, alpha);
				frame++;
				yield;
			}
			Obj_Delete(objOutline);
			
			task VertexSize{	
				if(frame>=35){return;}
				ascent (iVert in 0..countVertex/2){
					let indexVert = iVert * 2;
					let angle = (360 / (countVertex / 2 - 1) * iVert);

					let vx1 = listRadius[indexVert] * cos(angle);
					let vy1 = listRadius[indexVert] * sin(angle);
					ObjPrim_SetVertexPosition(objOutline, indexVert + 0, vx1, vy1, 0);

					let vx2 = listRadius[indexVert+1] * cos(angle);
					let vy2 = listRadius[indexVert+1] * sin(angle);
					ObjPrim_SetVertexPosition(objOutline, indexVert + 1, vx2, vy2, 0);

					let dr = (dist * rRate - listRadius[indexVert]) / 16;
					listRadius[indexVert] = listRadius[indexVert] + dr;
					if(frame>size){
						listRadius[indexVert + 1] = listRadius[indexVert + 1] + dr;
					}
				}
			}
		}
	}
}

task FadeInA1(obj, ftime){
	ascent(i in 0..ftime){
		ObjRender_SetAlpha(obj, 255/ftime*i);
		yield;
	}
}
task FadeInB1(obj, alpha, ftime){
	ascent(i in 0..ftime){
		ObjRender_SetAlpha(obj, alpha/ftime*i);
		yield;
	}
}

task FadeOutA1(obj, ftime){
	descent(i in 0..ftime){
		ObjRender_SetAlpha(obj, 255/ftime*i);
		yield;
	}
}

task FadeOutB1(obj, initalpha, ftime){
	descent(i in 0..ftime){
		ObjRender_SetAlpha(obj, initalpha/ftime*i);
		yield;
	}
}



function CreateSimple2DImageA1(pri, image){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, pri);
	ObjPrim_SetTexture(obj, image);
	let test = [GetTextureWidth(image), GetTextureHeight(image)];
	ObjSprite2D_SetSourceRect(obj, 0, 0, test[0]-1, test[1]-1);
	ObjSprite2D_SetDestRect(obj, -(test[0]/2+0.5), -(test[1]/2), (test[0]/2), (test[1]/2));
	return obj;
}

function CreateSimple2DImageA2(pri, image, x1, y1, x2, y2){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriority(obj, pri);
	ObjPrim_SetTexture(obj, image);
	ObjSprite2D_SetSourceRect(obj, x1, y1, x2, y2);
	ObjSprite2D_SetDestCenter(obj);
	return obj;
}


function DigitToArray(digit, count){
	let res = [];
	digit = truncate(digit);

	loop{
		let tnum = truncate(digit % 10);
		digit /= 10;
		res = [tnum] ~ res;
		if(truncate(digit) == 0){break;}
	}

	loop(max(0, count - length(res))){
		res = [0] ~ res;
	}

	return res;
}

function GetNumSize(value){
	if(value<=1){return 1;}
	else{return truncate(log10(value))+1;}
}