#TouhouDanmakufu[Player]
#ScriptVersion[3]
#ID["Ex_Tokiko"]
#Title["Tokiko"]
#Text[""]
#Image["./TokikoImg.png"]
#ReplayName["Tokiko"]

let CSD = GetCurrentScriptDirectory;

let objPlayer = GetPlayerObjectID;

let CanShoot = true;
let t = 0;

let shot = CSD ~ "SFX/pshot.wav";
let shot3 = CSD ~ "SFX/shot3.wav";
let powerup = CSD ~ "SFX/powerup.wav";
let death = CSD ~ "SFX/death.wav";
let item = CSD ~ "SFX/item.wav";
let bombget = CSD ~ "SFX/cardget.wav";
let extend = CSD ~ "SFX/extend.wav";
let graze = CSD ~ "SFX/graze.wav";
let wave = CSD ~ "SFX/wave.wav";
let wave2 = CSD ~ "SFX/wave2.wav";
let effect2 = CSD ~ "SFX/effect2.wav";
let spell = CSD ~ "SFX/spell.wav";
let lockon = CSD ~ "SFX/lockon.wav";

let p2 = true;
let p3 = true;
let p4 = true;
let FastSpeed = 4.8;
let SlowSpeed = 2.2;

@Initialize {
	LoadPlayerShotData(CSD ~ "TokikoShot.dnh"); 
	
	ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 1, 15); 
	SetPlayerSpeed(FastSpeed,SlowSpeed);
	SetPlayerRebirthFrame(15);
	SetPlayerRebirthLossFrame(0);

	LoadSound(shot);
	LoadSound(shot3);
	LoadSound(powerup);
	LoadSound(death);
	LoadSound(bombget);
	LoadSound(extend);
	LoadSound(graze);
	LoadSound(item);
	LoadSound(wave);
	LoadSound(wave2);
	LoadSound(effect2);
	LoadSound(spell);
	LoadSound(lockon);
	
	TMagicCircle;
	RenderPlayer;
	RenderHitbox(1);
	RenderHitbox(-1);
	
	SetPlayerSpell(2);
	SetPlayerPower(4);
	Option(1);
	if(GetPlayerPower>=2) { Option(2); p2 = false; }
	if(GetPlayerPower>=3) { Option(3); p3 = false; }
	if(GetPlayerPower>=4) { Option(4); p4 = false; SetPlayerPower(4); }
	Shot;
}

@MainLoop {
	if(GetPlayerState==STATE_DOWN){ CanShoot = false; }
	if(GetPlayerState==STATE_NORMAL){ CanShoot = true; }
	if(!IsPermitPlayerShot && GetPlayerState==STATE_NORMAL){ CanShoot = false; }
	if(IsPermitPlayerShot && GetPlayerState==STATE_NORMAL){ CanShoot = true; }
	if(IsPlayerSpellActive && GetPlayerState==STATE_NORMAL){ CanShoot = false; }
	
	if(GetPlayerPower>=2 && p2 == true) { 
		// PlaySE(powerup);
		Option(2);
		p2 = false;
	}
	if(GetPlayerPower>=3 && p3 == true) { 
		// PlaySE(powerup);
		Option(3);
		p3 = false;
	}
	if(GetPlayerPower>=4 && p4 == true) { 
		// PlaySE(powerup);
		Option(4);
		p4 = false;
	}
	
	SetPlayerAutoItemCollectLine(128);
	SetPlayerClip(11,11,GetStgFrameWidth-11,GetStgFrameHeight-18);
	if(GetVirtualKeyState(VK_USER1)==KEY_PUSH && GetPlayerPower<4) { SetPlayerPower(GetPlayerPower+1); }
	t++;
	yield;
}

@Finalize {
}

@Event {
	alternative(GetEventType)
	case(EV_REQUEST_SPELL){
		let bomb = GetPlayerSpell;
		if(bomb >= 1){
			SetScriptResult(true);
			PlaySE(spell);
			SetPlayerSpell(bomb-1);
			Spell;
		}
		else {
			SetScriptResult(false);
		}
	}
	case(EV_PLAYER_SHOOTDOWN){
		ClearBullets;
		CanShoot = false;
	}
	case(EV_HIT){
		PlaySE(death);
		DeathExplosion;
		if(GetPlayerLife<0){ CanShoot = false; }
	}
	case(EV_PLAYER_REBIRTH){
		SetPlayerSpell(3);
		// SetPlayerPower(GetPlayerPower-1);
		if(GetPlayerPower<1) { SetPlayerPower(1); }
		p4 = true;
		Option(1);
		if(GetPlayerPower>=2) { Option(2); } else { p2 = true; }
		if(GetPlayerPower>=3) { Option(3); } else { p3 = true; }
		SetPlayerInvincibilityFrame(180);
	}
	case(EV_GRAZE){
		PlaySE(graze);
		loop(2) { GrazeEffect; }
	}
}
task OptionShot(obj,power) {
let count = -1;
	while(!Obj_IsDeleted(obj)) {
		if(CanShoot) {
			if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_FREE) {
				if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD && count == -1 || count > 3) {
					count = 0;
				}
				if(count==3) {
					if(GetPlayerPower<2) {
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,282,3,2,0.4);
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,276,3,2,0.4);
						PlayerShot(ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,3,2,0.4);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,264,3,2,0.4);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,258,3,2,0.4);
					}
					if(GetPlayerPower>=2 && GetPlayerPower<3) {
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,294,3,2,0.5);
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,282,3,2,0.5);
						PlayerShot(ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,3,2,0.5);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,258,3,2,0.5);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,246,3,2,0.5);
					}
					if(GetPlayerPower>=3 && GetPlayerPower<4) {
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,306,3,2,0.6);
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,288,3,2,0.6);
						PlayerShot(ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,3,2,0.6);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,252,3,2,0.6);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,234,3,2,0.6);
					}
					if(GetPlayerPower==4) {
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,318,3,2,0.7);
						PlayerShot(ObjRender_GetX(obj)+2,ObjRender_GetY(obj),18,294,3,2,0.7);
						PlayerShot(ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,3,2,0.7);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,246,3,2,0.7);
						PlayerShot(ObjRender_GetX(obj)-2,ObjRender_GetY(obj),18,222,3,2,0.7);
					}
					count = -1;
				}
				if(count>=0) {
					count++;
				}
			}
			else {
				if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD && count == -1 || count > 5) {
					count = 0;
				}
				if(count==5) {
					if(GetPlayerPower<2) {	
						AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,1.9);
						AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,1.9);
						AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,1.9);
					}
					if(GetPlayerPower>=2 && GetPlayerPower<3) {
						AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,1.5);
						AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,1.5);
						AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,1.5);
					}
					if(GetPlayerPower>=3 && GetPlayerPower<4) {
						if(power==1) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,1.05);
						}
						if(power==2) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,1.05);
						}
						if(power==3) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,1.05);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,1.05);
						}
					}
					if(GetPlayerPower==4) {
						if(power==1) {	
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,0.7);
						}
						if(power==2) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,0.7);
						}
						if(power==3) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,0.7);
						}
						if(power==4) {
							AimedShot(obj,ObjRender_GetX(obj)+8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj)-8,ObjRender_GetY(obj),18,270,4,2,0.7);
							AimedShot(obj,ObjRender_GetX(obj),ObjRender_GetY(obj),18,270,4,2,0.7);
						}
					}
					count = -1;
				}
				if(count>=0) {
					count++;
				}
			}
		}
		yield;
	}
}
task Shot {
let count = -1;
	loop {
		if(CanShoot) {
			if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD && count == -1 || count > 2) {
				count = 0;
			}
			if(count==2) {
				PlaySE(shot);
				PlayerShot(GetPlayerX+10,GetPlayerY-5,23,270,1,1,0.9);
				PlayerShot(GetPlayerX-10,GetPlayerY-5,23,270,1,1,0.9);
				count = -1;
			}
			if(count>=0) {
				count++;
			}
		}
		yield;
	}
}
task PlayerShot(x,y,speed,dir,graphic,pene,dmg) {
	let obj = CreatePlayerShotA1(x,y,speed,dir,dmg,pene,graphic);
	let ypos = 0;
	let xpos = 0;
	
	while(!Obj_IsDeleted(obj)) {
		if(GetCommonData("TimeStop",false)) { Obj_SetRenderPriorityI(obj,34); }
		xpos = ObjRender_GetX(obj);
		ypos = ObjRender_GetY(obj);
		yield;
	}
	if(graphic==1) { FadeShot(xpos,ypos-10,3,dir,graphic+1); }
	if(graphic==3) { FadeShot(xpos,ypos-10,3,dir,graphic); }
	if(graphic==4) { FadeShot(xpos,ypos-10,3,dir,graphic+1); }
}
task AimedShot(objoption,x,y,speed,dir,graphic,pene,dmg) {
	let obj = CreatePlayerShotA1(x,y,speed,dir,dmg,pene,graphic);
	let ypos = 0;
	let xpos = 0;
	let TargetDistance = 280;
	let TargetAngle = 270;
	let TargetEnemy;
	
	let EnemyArray = GetAllEnemyID;
	
	ascent(i in 0..length(EnemyArray)) {
		if(GetObjectDistance(objoption,EnemyArray[i]) < TargetDistance) {
			TargetDistance = GetObjectDistance(objoption,EnemyArray[i]);
			TargetEnemy = EnemyArray[i];
			TargetAngle = atan2(ObjMove_GetY(TargetEnemy) - ObjRender_GetY(objoption), ObjMove_GetX(TargetEnemy) - ObjRender_GetX(objoption));
		}
	}
	if(TargetDistance < 280) {
		if(NormalizeAngle(TargetAngle) < 295 && NormalizeAngle(TargetAngle) > 245) {
			dir = TargetAngle;
			ObjMove_SetAngle(obj,dir);
		}
	}
	while(!Obj_IsDeleted(obj)) {
		if(GetCommonData("TimeStop",false)) { Obj_SetRenderPriorityI(obj,34); }
		xpos = ObjRender_GetX(obj);
		ypos = ObjRender_GetY(obj);
		yield;
	}
	FadeShot(xpos,ypos-10,5,dir,graphic+1);
}
task FadeShot(x,y,speed,dir,graphic) {
		let obj = CreatePlayerShotA1(x,y,speed,dir,0,10,graphic);
		let alpha = 200;
		loop(12){
			if(GetCommonData("TimeStop",false)) { Obj_SetRenderPriorityI(obj,34); }
			if(graphic == 3 || graphic == 5) {
				if(CanShoot) { ObjRender_SetAlpha(obj,alpha); }
				alpha-=255/12;
			}
			yield;
		}
		if(CanShoot) { Obj_Delete(obj); }
		if(GetPlayerState==STATE_DOWN) { Obj_Delete(obj); }
	}
task Option(power){
	let count = 60;
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 41);
	ObjPrim_SetTexture(obj, CSD ~ "TokikoShot.png");
	ObjSprite2D_SetSourceRect(obj, 95, 67, 112, 85);
	ObjSprite2D_SetDestCenter(obj);
	
	let objeffect = ObjPrim_Create(OBJ_SPRITE_2D);
	
	ObjRender_SetBlendType(objeffect, BLEND_ALPHA);
	Obj_SetRenderPriorityI(objeffect, 41);
	ObjPrim_SetTexture(objeffect, CSD ~ "TokikoShot.png");
	//ObjSprite2D_SetSourceRect(objeffect, 95, 67, 112, 85);
	ObjSprite2D_SetDestCenter(objeffect);
	
	let DestinationX = 0;
	let DestinationY = 0;
	let DistanceToPoint = 0;
	let AngleToPoint = 0;
	let scale = 0.95;
	
	//AnimateOption;
	OptionShot(obj,power);
	
	ObjRender_SetScaleXYZ(objeffect,1.2,1.2,1);
	ObjRender_SetAlpha(objeffect,120);
	ObjRender_SetPosition(obj,GetPlayerX,GetPlayerY,0);
	ObjRender_SetPosition(objeffect,GetPlayerX,GetPlayerY,0);
	
	while(!Obj_IsDeleted(obj)) {
		while(GetCommonData("TimeStop",false)) { yield; }
		if(power == 1) {
			if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_FREE) {
				if(GetPlayerPower<2) {
					DestinationX = GetPlayerX;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=2 && GetPlayerPower<3) {
					DestinationX = GetPlayerX-12;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX-24;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX-36;
					DestinationY = GetPlayerY-34;
				}
			}
			else {
				if(GetPlayerPower<2) {
					DestinationX = GetPlayerX;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=2 && GetPlayerPower<3) {
					DestinationX = GetPlayerX-12;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX-24;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX-36;
					DestinationY = GetPlayerY-34;
				}
			}
		}
		if(power == 2) {
			if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_FREE) {
				if(GetPlayerPower>=2 && GetPlayerPower<3) {
					DestinationX = GetPlayerX+12;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX-12;
					DestinationY = GetPlayerY-34;
				}
			}
			else {
				if(GetPlayerPower>=2 && GetPlayerPower<3) {
					DestinationX = GetPlayerX+12;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX-12;
					DestinationY = GetPlayerY-34;
				}
			}
		}
		if(power == 3) {
			if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_FREE) {
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX+24;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX+12;
					DestinationY = GetPlayerY-34;
				}
			}
			else {
				if(GetPlayerPower>=3 && GetPlayerPower<4) {
					DestinationX = GetPlayerX+24;
					DestinationY = GetPlayerY-34;
				}
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX+12;
					DestinationY = GetPlayerY-34;
				}
			}
		}
		if(power == 4) {
			if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_FREE) {
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX+36;
					DestinationY = GetPlayerY-34;
				}
			}
			else {
				if(GetPlayerPower==4) {
					DestinationX = GetPlayerX+36;
					DestinationY = GetPlayerY-34;
				}
			}
		}
		DistanceToPoint = GetDistance(DestinationX, DestinationY, ObjRender_GetX(obj), ObjRender_GetY(obj));
		AngleToPoint = atan2(DestinationY-ObjRender_GetY(obj),DestinationX-ObjRender_GetX(obj));
		if (DistanceToPoint >= 0){
			if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_FREE) {
				if(count>=20) {
					ObjRender_SetPosition(obj,ObjRender_GetX(obj)+cos(AngleToPoint)*DistanceToPoint*0.4,ObjRender_GetY(obj)+ sin(AngleToPoint)*DistanceToPoint*0.4,0);
					ObjRender_SetPosition(objeffect,ObjRender_GetX(objeffect)+cos(AngleToPoint)*DistanceToPoint*0.4,ObjRender_GetY(objeffect)+ sin(AngleToPoint)*DistanceToPoint*0.4,0);
				}
				count++;
			}
			else { count = 0; }
		}
		if(GetPlayerState==STATE_DOWN || GetPlayerState==STATE_END){ Obj_Delete(obj); Obj_Delete(objeffect); }
		yield;
	}
	task AnimateOption {
		while(!Obj_IsDeleted(obj)) {
			ObjRender_SetScaleXYZ(obj,scale,scale,1);
			scale-=0.007*sin(4.5*t);
			yield;
		}
	}
}
task Spell {
	let objManage = GetSpellManageObject;
	let dir = 0;
	let num = 0;
	let targetList = [];
	SetPlayerInvincibilityFrame(565);
	SetPlayerSpeed(SlowSpeed-0.5,SlowSpeed-0.5);
	let spl = "100% Off EVERYTHING";
	cutin(objManage,"Clearance \""~spl~"\"",CSD ~ "TokikoCut.png",0,0,500,600);
	SpellBurst;
	wait(60);
	PlaySE(effect2);
	loop(8) {
		SpellBook(num,dir);
		dir+=360/8;
		num++;
	}
	wait(300);
	SpellRinnosuke(GetPlayerX,GetPlayerY-10,5);
	wait(90);
	SetPlayerSpeed(FastSpeed,SlowSpeed);
	Obj_Delete(objManage);
	task SpellBook(num,dir) {
		let objBook = ObjPrim_Create(OBJ_SPRITE_2D);
		let objhitbox = ObjSpell_Create;
	
		ObjPrim_SetTexture(objBook, CSD ~ "SpellBook.png");
		ObjRender_SetBlendType(objBook, BLEND_ALPHA);
		ObjSprite2D_SetSourceRect(objBook,0,0,30,30);
		ObjSprite2D_SetDestCenter(objBook);
		Obj_SetRenderPriorityI(objBook, 50);
		ObjRender_SetAlpha(objBook, 255);
		ObjRender_SetScaleXYZ(objBook,1.5,1.5,1.5);
		
		ObjSpell_SetDamage(objhitbox,1);
		
		let r = 0;
		let x = GetPlayerX + r*cos(dir);
		let y = GetPlayerY + r*sin(dir);
		
		loop(60) {
			ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(objBook),ObjRender_GetY(objBook),35);
			ObjRender_SetPosition(objBook,x,y,0);
			x = GetPlayerX + r*cos(dir);
			y = GetPlayerY + r*sin(dir);
			if(r<80) { r+=3; }
			dir+=4;
			yield;
		}
		loop(num*8) {
			ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(objBook),ObjRender_GetY(objBook),35);
			ObjRender_SetPosition(objBook,x,y,0);
			x = GetPlayerX + r*cos(dir);
			y = GetPlayerY + r*sin(dir);
			yield;
		}
		let enm = GetAllEnemyID;
		TargetEnemy(num);
		loop(240-num*8) {
			ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(objBook),ObjRender_GetY(objBook),35);
			ObjRender_SetPosition(objBook,x,y,0);
			x = GetPlayerX + r*cos(dir);
			y = GetPlayerY + r*sin(dir);
			yield;
		}
		Obj_Delete(objBook);
		Obj_Delete(objhitbox);
		
		function CheckBlackList(value,blklist) {
			let check = 0;
			ascent(i in 0..length(blklist)) {
				if(value==blklist[i]) { check++; }
			}
			return check;
		}
		task TargetEnemy(w) {
			let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		
			ObjPrim_SetTexture(obj, CSD ~ "crosshairs.png");
			ObjRender_SetBlendType(obj, BLEND_ALPHA);
			ObjSprite2D_SetSourceRect(obj,0,0,256,256);
			ObjSprite2D_SetDestCenter(obj);
			Obj_SetRenderPriorityI(obj, 50);
			ObjRender_SetAlpha(obj, 255);
			
			
			let scale = 0.9;
			let angle = dir;
			let objEnemy = ID_INVALID;
			
			let enm = GetAllEnemyID;
			FindTarget(enm,0);
			
			targetList = targetList ~ [objEnemy];
			
			ManageTarget;
			
			if(objEnemy!=ID_INVALID) { PlaySE(lockon); }
			loop(15) {
				if(objEnemy!=ID_INVALID && !Obj_IsDeleted(objEnemy)) { 
					ObjRender_SetPosition(obj,ObjMove_GetX(objEnemy),ObjMove_GetY(objEnemy),0);
					ObjRender_SetScaleXYZ(obj,scale,scale,scale);
					angle = atan2(ObjMove_GetY(objEnemy)-ObjRender_GetY(objBook),ObjMove_GetX(objEnemy)-ObjRender_GetX(objBook));
				}
				else {
					ObjRender_SetPosition(obj,-200,200,0);
					angle = dir;
				}
				scale-=0.4/15;
				yield;
			}
			loop(80-w*8) {
				if(objEnemy!=ID_INVALID && !Obj_IsDeleted(objEnemy)) { 
					ObjRender_SetPosition(obj,ObjMove_GetX(objEnemy),ObjMove_GetY(objEnemy),0);
					angle = atan2(ObjMove_GetY(objEnemy)-ObjRender_GetY(objBook),ObjMove_GetX(objEnemy)-ObjRender_GetX(objBook));
				}
				else {
					ObjRender_SetPosition(obj,-200,200,0);
					angle = dir;
				}
				yield;
			}
			FireSpell;
			loop(120) {
				if(objEnemy!=ID_INVALID && !Obj_IsDeleted(objEnemy)) { 
					ObjRender_SetPosition(obj,ObjMove_GetX(objEnemy),ObjMove_GetY(objEnemy),0);
					angle = atan2(ObjMove_GetY(objEnemy)-ObjRender_GetY(objBook),ObjMove_GetX(objEnemy)-ObjRender_GetX(objBook));
				}
				else {
					ObjRender_SetPosition(obj,-200,200,0);
					angle = dir;
				}
				yield;
			}
			Obj_Delete(obj);
			
			task ManageTarget {
				loop {
					if(Obj_IsDeleted(objEnemy)) {
						let enm = GetAllEnemyID;
						FindTarget(enm,0);
					}
					yield;
				}
			}
			function FindTarget(enemyList,target) {
				ascent(i in 0..length(enemyList)) {
					if(CheckBlackList(enemyList[i],targetList)==target) { objEnemy = enemyList[i]; break; }
					else if(i==length(enemyList)-1) { FindTarget(enemyList,target+1); }
				}
			}
			task FireSpell {
				loop(6) {
					PlaySE(shot3);
					SpellItem(1,ObjRender_GetX(objBook),ObjRender_GetY(objBook),15,angle);
					wait(5);
				}
				loop(6) {
					PlaySE(shot3);
					SpellItem(2,ObjRender_GetX(objBook),ObjRender_GetY(objBook),15,angle);
					wait(5);
				}
				loop(6) {
					PlaySE(shot3);
					SpellItem(3,ObjRender_GetX(objBook),ObjRender_GetY(objBook),15,angle);
					wait(5);
				}
				loop(6) {
					PlaySE(shot3);
					SpellItem(4,ObjRender_GetX(objBook),ObjRender_GetY(objBook),13,angle);
					wait(5);
				}
			}
		}
	}
}
task SpellRinnosuke(x,y,speed) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objhitbox = CreatePlayerShotA1(x,y,0,0,170,2,1);
	let objhitbox2 = ObjSpell_Create;
	
	ObjPrim_SetTexture(obj, CSD ~ "RinnosukeSprite.png");
	ObjSprite2D_SetSourceRect(obj,0,0,128,128);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 50);
	ObjRender_SetAlpha(obj, 200);
	
	Obj_SetVisible(objhitbox,false);
	ObjSpell_SetDamage(objhitbox2,0);
	ObjRender_SetScaleXYZ(obj,0.7,0.7,0.7);
	
	PlaySE(shot3);
	
	let enm = GetAllEnemyID;
	let objEnemy = ID_INVALID;
	if(length(enm)>0) { objEnemy = enm[0]; }
	let dir = 270;
	let angle = rand(0,360);
	let spin = 0;
	
	while(!Obj_IsDeleted(obj)) {
		ObjSpell_SetIntersectionCircle(objhitbox2,ObjRender_GetX(obj),ObjRender_GetY(obj),24);
		ObjMove_SetPosition(objhitbox,ObjRender_GetX(obj),ObjRender_GetY(obj));
		ObjRender_SetAngleXYZ(obj,0,0,spin);
		ObjRender_SetPosition(obj,x,y,0);
		if(objEnemy!=ID_INVALID) { dir = atan2(ObjMove_GetY(objEnemy)-GetPlayerY,ObjMove_GetX(objEnemy)-GetPlayerX); }
		x+=speed*cos(dir);
		y+=speed*sin(dir);
		spin+=5;
		
		if(Obj_IsDeleted(objhitbox)) {
			PlaySE(death);
			DeathExplosion2(ObjRender_GetX(obj),ObjRender_GetY(obj));
			loop(14) {
				SpellItem2(1,ObjRender_GetX(obj),ObjRender_GetY(obj),rand(3,6),angle+rand(-18,18));
				angle+=360/14;
			}
			loop(14) {
				SpellItem2(2,ObjRender_GetX(obj),ObjRender_GetY(obj),rand(3,6),angle+rand(-18,18));
				angle+=360/14;
			}
			break;
		}
		if(ObjRender_GetX(obj)<-20 || ObjRender_GetX(obj)>GetStgFrameWidth+20 || ObjRender_GetY(obj)<-20 || ObjRender_GetY(obj)>GetStgFrameHeight+20) {
			Obj_Delete(objhitbox);
			Obj_Delete(objhitbox2);
			Obj_Delete(obj);
		}
		yield;
	}
	Obj_Delete(obj);
	Obj_Delete(objhitbox2);
}
task SpellItem(type,x,y,speed,dir) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objhitbox = ObjSpell_Create;
	
	ObjPrim_SetTexture(obj, CSD ~ "TokikoSpell.png");
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 50);
	ObjRender_SetAlpha(obj, 200);
	
	ObjSpell_SetDamage(objhitbox,0.4);
	ObjSpell_Regist(objhitbox);
	
	let spin = 0;
	let dspin = 0;
	let count = 0;
	
	if(type==1) { ObjSprite2D_SetSourceRect(obj,11,73,47,128); dspin = 1; }
	if(type==2) { ObjSprite2D_SetSourceRect(obj,63,10,125,49); dspin = -1; }
	if(type==3) { ObjSprite2D_SetSourceRect(obj,65,56,125,126); dspin = 1; }
	if(type==4) { ObjSprite2D_SetSourceRect(obj,0,0,61,71); dspin = -1; }
	ObjSprite2D_SetDestCenter(obj);
	
	while(!Obj_IsDeleted(obj)) {
		ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(obj),ObjRender_GetY(obj),60);
		ObjRender_SetAngleXYZ(obj,0,0,spin);
		ObjRender_SetPosition(obj,x,y,0);
		x+=speed*cos(dir);
		y+=speed*sin(dir);
		spin+=12*dspin;
		count++;
		if(ObjRender_GetX(obj)<-20 || ObjRender_GetX(obj)>GetStgFrameWidth+20 || ObjRender_GetY(obj)<-20 || ObjRender_GetY(obj)>GetStgFrameHeight+20) {
			if(count>30) {
				Obj_Delete(obj);
			}
		}
		yield;
	}
}
task SpellItem2(type,x,y,speed,dir) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objhitbox = ObjSpell_Create;
	
	ObjPrim_SetTexture(obj, CSD ~ "Item.png");
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 50);
	ObjRender_SetAlpha(obj, 255);
	
	ObjSpell_SetDamage(objhitbox,1.1);
	ObjSpell_Regist(objhitbox);
	
	let spin = 0;
	let dspin = 0;
	
	if(type==1) { ObjSprite2D_SetSourceRect(obj,0,0,16,17); }
	if(type==2) { ObjSprite2D_SetSourceRect(obj,16,0,32,17); }
	ObjSprite2D_SetDestCenter(obj);
	
	while(!Obj_IsDeleted(obj)) {
		ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(obj),ObjRender_GetY(obj),15);
		ObjRender_SetAngleXYZ(obj,0,0,spin);
		ObjRender_SetPosition(obj,x,y,0);
		x+=speed*cos(dir);
		y+=speed*sin(dir);
		if(ObjRender_GetX(obj)<-15 || ObjRender_GetX(obj)>GetStgFrameWidth+15 || ObjRender_GetY(obj)<-15 || ObjRender_GetY(obj)>GetStgFrameHeight+15) {
			Obj_Delete(obj);
		}
		yield;
	}
}
task SpellBurst {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objhitbox = ObjSpell_Create;
	
	ObjPrim_SetTexture(obj, CSD ~ "ConcentrationCircle.png");
	ObjSprite2D_SetSourceRect(obj,0,0,256,256);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriorityI(obj, 50);
	ObjRender_SetAlpha(obj, 200);
	
	ObjSpell_SetDamage(objhitbox,0);
	ObjSpell_Regist(objhitbox);
	
	let alpha = 1;
	let scale = 0;
	let dscale = 0.15;
	loop(30){
		scale += dscale;
		if(dscale>0){ dscale = dscale^1.05; }
		if(alpha>0) { alpha -= 1/15; }
		else { alpha = 0; }
		ObjRender_SetColor(obj, 30*alpha, 30*alpha, 255*alpha);
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		ObjSpell_SetIntersectionCircle(objhitbox,ObjRender_GetX(obj),ObjRender_GetY(obj),scale*128);
		yield;
	}
	Obj_Delete(obj);
	Obj_Delete(objhitbox);
}
task RenderPlayer {
	let count = 0;
	let type = 0;
	let x = 0;
	let y = 0;
	ObjPrim_SetTexture(objPlayer, CSD ~ "TokikoPlayer.png");
	loop {
		if(GetVirtualKeyState(VK_RIGHT) == KEY_FREE && GetVirtualKeyState(VK_LEFT) == KEY_FREE){
			if(type != 0){
				count = 0;
				type = 0;
			}
		}
		if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH || GetVirtualKeyState(VK_LEFT) == KEY_HOLD){
			if(GetVirtualKeyState(VK_RIGHT) != KEY_HOLD && type != -1){
				count = 0;
				type = -1;
			}
		}
		if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH || GetVirtualKeyState(VK_RIGHT) == KEY_HOLD){
			if(type != 1){
				count = 0;
				type = 1;
			}
		}
		if(!GetCommonData("TimeStop",false)) {
			if(type==0){
				if(count == 1){ ObjSprite2D_SetSourceRect(objPlayer, 2, 0, 30, 48); }
				if(count == 7){ ObjSprite2D_SetSourceRect(objPlayer, 33, 0, 61, 48); }
				if(count == 13){ ObjSprite2D_SetSourceRect(objPlayer, 63, 0, 91, 48); }
				if(count == 19){ ObjSprite2D_SetSourceRect(objPlayer, 93, 0, 121, 48); }
				if(count == 25){ count = 0; }
			}
			if(type==-1){
				if(count == 1){ ObjSprite2D_SetSourceRect(objPlayer, 0, 48, 34, 96); }
				if(count == 7){ ObjSprite2D_SetSourceRect(objPlayer, 36, 48, 70, 96); }
				if(count == 13){ ObjSprite2D_SetSourceRect(objPlayer, 70, 48, 108, 96); }
				if(count == 19){ ObjSprite2D_SetSourceRect(objPlayer, 107, 48, 143, 96); }
				if(count == 25){ count = 0; }
			}
			if(type==1){
				if(count == 1){ ObjSprite2D_SetSourceRect(objPlayer, 6, 96, 37, 144); }
				if(count == 7){ ObjSprite2D_SetSourceRect(objPlayer, 39, 96, 76, 144); }
				if(count == 13){ ObjSprite2D_SetSourceRect(objPlayer, 76, 96, 111, 144); }
				if(count == 19){ ObjSprite2D_SetSourceRect(objPlayer, 114, 96, 149, 144); }
				if(count == 25){ count = 0; }
			}
			x = GetPlayerX;
			y = GetPlayerY;
		}
		else {
			ObjMove_SetPosition(GetPlayerObjectID, x, y);
		}
		Obj_SetRenderPriorityI(objPlayer, 41);
		ObjSprite2D_SetDestCenter(objPlayer);
		ObjRender_SetScaleXYZ(objPlayer,1.05,1.05,0);
		count++;
		yield;
	}
}
task RenderHitbox(rot){

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let count = 0;
	
	let alpha = 0;
	let scale = 0;
	
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 69);
	ObjRender_SetAlpha(obj, 255);
	ObjPrim_SetTexture(obj, CSD ~ "TokikoShot.png");
	ObjSprite2D_SetSourceRect(obj, 64, 0, 127, 63);
	ObjSprite2D_SetDestCenter(obj);
	
	while(!Obj_IsDeleted(obj)){
		while(GetCommonData("TimeStop",false)) { yield; }
		if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH){ 
			scale = 2;
			alpha = 0;
		}
		if(scale>1) {
			scale-=1/10;
			alpha+=255/10;
			count+=4;
		}
		if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_FREE){
			if(scale<=1 && scale>0) {
				scale-=1/10;
				alpha-=255/10;
			}
		}
		ObjRender_SetAngleXYZ(obj, 0, 0, count*rot);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 0);
		ObjRender_SetAlpha(obj, alpha);
		
		if(GetPlayerState==STATE_DOWN||GetPlayerState==STATE_END){ObjRender_SetAlpha(obj, 0);}
		
		count+=3.5;
		yield;
	}
}
task cutin(objspell,SpellCardName,CutImg,left,top,right,bottom) {
	SpellText;
	

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let alpha = 220;
	let count = 0;
	let x = 0;
	let y = 0;

	let s = 0.8;
	let f = 0;
	let g = 0;


	x = GetStgFrameWidth+40;
	y = GetStgFrameHeight/2+10;

	ObjRender_SetBlendType(obj,BLEND_ALPHA);
	ObjPrim_SetTexture(obj,CutImg);
	Obj_SetRenderPriorityI(obj,27);
	ObjSprite2D_SetSourceRect(obj,left,top,right,bottom);
	ObjSprite2D_SetDestCenter(obj);


	while(!Obj_IsDeleted(obj)){
		if(count<30){ x-=20-g; g+=20/30; }
		if(count>=70){ s+=0.02-f; f+=0.0005; alpha-=220/40; }
		if(count>160){ Obj_Delete(obj); }
		ObjRender_SetScaleXYZ(obj,s,s,0);
		ObjRender_SetPosition(obj,x,y,0);
		ObjRender_SetAlpha(obj,alpha);
		count++;
		yield;
	}
	task SpellText {
		let objtext = ObjText_Create;
		let x1 = 0;
		let y1 = 360;
		let a = 0;
		let scale = 1.5;
		
		SpellBG;
		
		ObjText_SetText(objtext,SpellCardName);
		ObjText_SetFontSize(objtext,12);
		ObjText_SetFontColorTop(objtext,255,255,255);
		ObjText_SetFontColorBottom(objtext,0,0,255);
		ObjText_SetFontBorderType(objtext,BORDER_SHADOW);
		ObjText_SetFontBorderWidth(objtext,1);
		ObjText_SetFontBorderColor(objtext,0,0,0);
		ObjText_SetHorizontalAlignment(objtext,ALIGNMENT_LEFT);
		ObjText_SetMaxWidth(objtext,250);
		Obj_SetRenderPriorityI(objtext,70);
		
		loop(20) {
			ObjRender_SetPosition(objtext,x1,y1,0);
			ObjRender_SetAlpha(objtext,a);
			if(a<255) { a+=255/20; }
			if(x1<30) { x1+=30/20; }
			if(scale>1) { scale-=0.5/20; }
			yield;
		}
		wait(45);
		loop(30) {
			ObjRender_SetPosition(objtext,x1,y1,0);
			y1+=60/30;
			yield;
		}
		while(!Obj_IsDeleted(objspell)) { yield; }
		loop(20) {
			ObjRender_SetX(objtext,x1);
			x1-=15;
			yield;
		}
		Obj_Delete(objtext);
		
		task SpellBG {
			let objbg = ObjPrim_Create(OBJ_SPRITE_2D);
			let x2 = 30;
			let y2 = 347;
			ObjRender_SetBlendType(objbg,BLEND_ALPHA);
			Obj_SetRenderPriorityI(objbg,69);
			ObjPrim_SetTexture(objbg,CSD ~ "SpellBG.png");
			ObjSprite2D_SetSourceRect(objbg,0,0,256,35);
			ObjSprite2D_SetDestRect(objbg,-15,0,241,35);
			
			loop(20) {
				ObjRender_SetPosition(objbg,x2,y2,0);
				ObjRender_SetAlpha(objbg,a);
				ObjRender_SetScaleXYZ(objbg,scale,scale,0);
				yield;
			}
			wait(45);
			loop(30) {
				ObjRender_SetPosition(objbg,30,y2,0);
				y2+=60/30;
				yield;
			}
			while(!Obj_IsDeleted(objspell)) { yield; }
			loop(20) {
				ObjRender_SetX(objbg,x2);
				x2-=15;
				yield;
			}
			Obj_Delete(objbg);
		}
	}
}
task ClearBullets {
	wait(30);
	while(GetPlayerState==STATE_DOWN){
		DeleteEnemyBullets;
		yield;
	}
	loop(30) {
		DeleteEnemyBullets;
		yield;
	}
}
task GrazeEffect {
	let x = GetPlayerX;
	let y = GetPlayerY;
	let scale = 1;
	let dir = rand(0,360);

	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj,CSD ~ "effect.png");
	ObjSprite2D_SetSourceRect(obj,0,0,128,128);
	ObjSprite2D_SetDestRect(obj,-4,-4,4,4);
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	ObjRender_SetAngleZ(obj,rand(0,360));
	ObjRender_SetAlpha(obj,192);
	ObjRender_SetPosition(obj,x,y,0);
	loop(15){
		x += 5*cos(dir);
		y += 5*sin(dir);
		ObjRender_SetPosition(obj,x,y,0);

		scale -= 1/15;
		ObjRender_SetScaleXYZ(obj,scale,scale,1);

		yield;
	}
	Obj_Delete(obj);
}
task DeathExplosion {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj,60);
	ObjPrim_SetTexture(obj, CSD ~ "TokikoShot.png");
	ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 64);
	ObjSprite2D_SetDestCenter(obj);
	
	loop(30) { ParticleEffect(rand(0,360)); }

	let alpha = 200;
	let scale = 0;
	let dscale = 0.5;
	loop(40){
		scale += dscale;
		alpha -= 6;
		if(dscale>0){ dscale = dscale^1.10; }
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		yield;
	}
	Obj_Delete(obj);
	
	task ParticleEffect(angle) {
		let objEffect = ObjPrim_Create(OBJ_SPRITE_2D);
		
		ObjRender_SetBlendType(objEffect, BLEND_ADD_RGB);
		Obj_SetRenderPriorityI(objEffect,60);
		ObjPrim_SetTexture(objEffect, CSD ~ "effect.png");
		ObjSprite2D_SetSourceRect(objEffect, 0, 0, 128, 128);
		ObjSprite2D_SetDestCenter(objEffect);
		
		let x = GetPlayerX;
		let y = GetPlayerY;
		let speed = rand(4,8);
		let alpha = 255;
		let scale = rand(0.01,0.06);
		
		while(!Obj_IsDeleted(objEffect)) {
			ObjRender_SetColor(objEffect,alpha,alpha,alpha);
			ObjRender_SetPosition(objEffect, x, y, 0);
			ObjRender_SetScaleXYZ(objEffect,scale,scale,scale);
			x+=speed*cos(angle);
			y+=speed*sin(angle);
			if(speed>1) { speed-=0.20; }
			if(speed<=2.5) { alpha-=255/10; }
			if(alpha<=0) { Obj_Delete(objEffect); }
			yield;
		}
	}
}
task DeathExplosion2(xpos,ypos) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj,60);
	ObjPrim_SetTexture(obj, CSD ~ "TokikoShot.png");
	ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 64);
	ObjSprite2D_SetDestCenter(obj);
	
	loop(30) { ParticleEffect(rand(0,360)); }

	let alpha = 200;
	let scale = 0;
	let dscale = 0.5;
	loop(40){
		scale += dscale;
		alpha -= 6;
		if(dscale>0){ dscale = dscale^1.10; }
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetPosition(obj, xpos, ypos, 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		yield;
	}
	Obj_Delete(obj);
	
	task ParticleEffect(angle) {
		let objEffect = ObjPrim_Create(OBJ_SPRITE_2D);
		
		ObjRender_SetBlendType(objEffect, BLEND_ADD_RGB);
		Obj_SetRenderPriorityI(objEffect,60);
		ObjPrim_SetTexture(objEffect, CSD ~ "effect.png");
		ObjSprite2D_SetSourceRect(objEffect, 0, 0, 128, 128);
		ObjSprite2D_SetDestCenter(objEffect);
		
		let x = xpos;
		let y = ypos;
		let speed = rand(4,8);
		let alpha = 255;
		let scale = rand(0.01,0.06);
		
		while(!Obj_IsDeleted(objEffect)) {
			ObjRender_SetColor(objEffect,alpha,alpha,alpha);
			ObjRender_SetPosition(objEffect, x, y, 0);
			ObjRender_SetScaleXYZ(objEffect,scale,scale,scale);
			x+=speed*cos(angle);
			y+=speed*sin(angle);
			if(speed>1) { speed-=0.20; }
			if(speed<=2.5) { alpha-=255/10; }
			if(alpha<=0) { Obj_Delete(objEffect); }
			yield;
		}
	}
}
task TMagicCircle {
	let countVertex = 64;
	let listRadius = [];
	loop(countVertex)
	{
		listRadius = listRadius ~ [0];
	}

	let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(obj, countVertex);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	Obj_SetRenderPriority(obj, 0.60);
	ObjPrim_SetTexture(obj,CSD ~ "Default_Player_MagicCircle.png");
	ascent(iVert in 0..countVertex / 2)
	{
		let left = iVert * 128;
		let indexVert = iVert * 2;
		ObjPrim_SetVertexUVT(obj, indexVert + 0, left, 0);
		ObjPrim_SetVertexUVT(obj, indexVert + 1, left, 64);		
	}

	let cx = 0;
	let cy = 0;
	let maxRadius = 128;
	let alpha = 0;
	let frame = 0;
	let angleRender = 0;
	let frameInvOld = 0;

	while(true)
	{
		let frameInv = GetPlayerInvincibilityFrame();

		if(frameInv <= 0)
		{
			Obj_SetVisible(obj, false);
			frameInvOld = 0;
		}
		else
		{
			if(frameInvOld == 0)
			{
				ascent(iVert in 0..countVertex)
				{
					listRadius[iVert] = 0;
				}
				alpha = 0;
				frame = 0;
			}
			frameInvOld = frameInv;

			let px = GetPlayerX();
			let py = GetPlayerY();

			alpha += 1 / 120;
			alpha = min(alpha, 1);
			angleRender += 360 / countVertex / 2;
			Obj_SetVisible(obj, true);

			frameInv = min(100, frameInv);
			let rRate = frameInv / 100;

			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(obj, indexVert + 0, vx1, vy1, 0);

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

				if(frame >= 0)
				{
					let dr = (maxRadius * rRate - listRadius[indexVert]) / 8;
					listRadius[indexVert] = listRadius[indexVert] + dr;
				}
				if(frame > 10)
				{
					let rRateIn = rRate - 0.12;
					if(rRateIn < 0){rRateIn=0;}
					let dr= (maxRadius * rRateIn - listRadius[indexVert + 1]) / 16;
					listRadius[indexVert + 1] = listRadius[indexVert + 1] + dr;
				}

			}

			ObjRender_SetColor(obj, 192 * alpha, 192 * alpha, 255 * alpha);
			ObjRender_SetPosition(obj, px, py, 0);
			ObjRender_SetAngleZ(obj, angleRender);

			frame++;
		}

		yield;
	}
}
function DeleteEnemyBullets {
let Bullets = GetShotIdInCircleA1(GetPlayerX,GetPlayerY,10000);
	ascent(i in 0..length(Bullets)) {
		if(!ObjShot_IsSpellResist(Bullets[i])) {
			if(GetCommonData("EUB",true)) {
				NotifyEventAll(EV_USER + 9,[ObjMove_GetX(Bullets[i]),ObjMove_GetY(Bullets[i]),ObjShot_GetImageID(Bullets[i])]);
				Obj_Delete(Bullets[i]);
			}
			else { ObjShot_FadeDelete(Bullets[i]); }
		}
	}
}
function wait(w) {
	loop(w) { yield; }
}
function GetDistance(x1,y1,x2,y2) {
	return ((x1-x2)^2+(y1-y2)^2)^(1/2);
}
function NormalizeAngle(angle){
  angle %= 360;
  if(angle<0){ angle += 360; }
  return angle;
}