#include"./CutIn.txt"

let playerObject = GetPlayerObjectID();
let playerAlive = true;
let playerHit = false;
let prevAlive = false;
let playerSpellActive = false;


let snowFlakeEffectMain = ID_INVALID;
let snowFlakeEffectBack = ID_INVALID;

let snowFlakeStatus = 2;
let snowFlakeLoopActive = false;

let optionsAlive = false;
let playerPower = 400;
let powerEnabled = true;

let idm = false;
let dp = false;

let deathSound = ObjSound_Create;

let itemSound = ObjSound_Create;
let grazeSound = ObjSound_Create;

let spellGetSound = ObjSound_Create;
let lifeGetSound = ObjSound_Create;
let powerUpSound = ObjSound_Create;

let shotSound = ObjSound_Create;

let spellUseSound = ObjSound_Create;
let spellShotSound = ObjSound_Create;
let tornadoSound = ObjSound_Create;
let cameraChargeSound = ObjSound_Create;
let cameraDeploySound = ObjSound_Create;
let cameraSnap1Sound = ObjSound_Create;
let cameraSnap2Sound = ObjSound_Create;

task LoadSounds{
	ObjSound_Load(deathSound, GetCurrentScriptDirectory ~ "sounds/se_pldead00.wav");
	
	ObjSound_Load(itemSound, GetCurrentScriptDirectory ~ "sounds/se_item00.wav");
	ObjSound_Load(grazeSound, GetCurrentScriptDirectory ~ "sounds/se_graze.wav");
	
	ObjSound_Load(spellGetSound, GetCurrentScriptDirectory ~ "sounds/se_cardget.wav");
	ObjSound_Load(lifeGetSound, GetCurrentScriptDirectory ~ "sounds/se_extend.wav");
	ObjSound_Load(powerUpSound, GetCurrentScriptDirectory ~ "sounds/se_powerup.wav");
	
	ObjSound_Load(shotSound, GetCurrentScriptDirectory ~ "sounds/se_plst00.wav");
	
	ObjSound_Load(spellUseSound, GetCurrentScriptDirectory ~ "sounds/se_cat00.wav");
	ObjSound_Load(spellShotSound, GetCurrentScriptDirectory ~ "sounds/se_tan00.wav");
	ObjSound_Load(tornadoSound, GetCurrentScriptDirectory ~ "sounds/tornado.wav");
	ObjSound_Load(cameraChargeSound, GetCurrentScriptDirectory ~ "sounds/se_power0.wav");
	ObjSound_Load(cameraDeploySound, GetCurrentScriptDirectory ~ "sounds/se_focus.wav");
	ObjSound_Load(cameraSnap1Sound, GetCurrentScriptDirectory ~ "sounds/se_shutter.wav");
	ObjSound_Load(cameraSnap2Sound, GetCurrentScriptDirectory ~ "sounds/se_focusfix.wav");
	
	ObjSound_SetVolumeRate(deathSound, 60);
	ObjSound_SetVolumeRate(grazeSound, 40);
	ObjSound_SetVolumeRate(shotSound, 15);
	ObjSound_SetVolumeRate(spellShotSound, 80);
	ObjSound_SetVolumeRate(cameraSnap2Sound, 80);
}

task DrawSprite{
	
	ObjPrim_SetTexture(playerObject, GetCurrentScriptDirectory ~ "img/player.png");
	
	let changeTime = 4;
	let frame = 0;
	
	let sFrame1 = 0;
	let sFrame2 = 0;
	let sFrame3 = 0;
	
	loop{
		if(dp){
			loop(20){yield;}
			ascent(i in 0..7){
				ObjSprite2D_SetSourceRect(playerObject, 32*i, 208, 32*(i + 1), 256);
				loop(20){yield;}
			}
		}
		
		if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH || GetVirtualKeyState(VK_RIGHT) == KEY_HOLD){
			
			ObjSprite2D_SetSourceRect(playerObject, 32*sFrame2, 96, 32*(sFrame2 + 1), 144);
			
			if(frame >= changeTime){
				sFrame2 += 1;
				
				if(sFrame2 >= 7){
					sFrame2 = 3;
				}
			}
			
			sFrame1 = 0;
			sFrame3 = 0;
		}
		
		else if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH || GetVirtualKeyState(VK_LEFT) == KEY_HOLD){
			
			ObjSprite2D_SetSourceRect(playerObject, 32*sFrame1, 48, 32*(sFrame1 + 1), 96);
			
			if(frame >= changeTime){
				sFrame1 += 1;
				
				if(sFrame1 >= 7){
					sFrame1 = 3;
				}
			}
			
			sFrame2 = 0;
			sFrame3 = 0;
		}
		
		else{
			ObjSprite2D_SetSourceRect(playerObject, 32*sFrame3, 0, 32*(sFrame3 + 1), 48);
			
			if(frame >= changeTime){
				sFrame3 += 1;
			}
			
			if(sFrame3 >= 7 && frame >= changeTime){
				sFrame3 = 0;
			}
			
			sFrame1 = 0;
			sFrame2 = 0;
		}
		
		frame++;
		
		if(frame >= changeTime + 1){
			frame = 0;
		}
		
		ObjSprite2D_SetDestCenter(playerObject);
		
		yield;
	}
}

task DrawHitbox{
	
	SnowFlakeLoop;
	
	loop{
		if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD){
			if(snowFlakeStatus != 1 && playerAlive){
				SnowFlakeCreate;
			}
		}
		else{
			if(snowFlakeStatus != 2){
				SnowFlakeDelete;
			}
		}
		
		yield;
	}
}

task SnowFlakeCreate{
	
	snowFlakeStatus = 1;
	
	snowFlakeLoopActive = true;
	
	yield;
	
	snowFlakeEffectMain = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(snowFlakeEffectMain, BLEND_ALPHA);
	Obj_SetRenderPriority(snowFlakeEffectMain, 0.31);
	ObjPrim_SetTexture(snowFlakeEffectMain, GetCurrentScriptDirectory() ~ "img/player.png");
	ObjSprite2D_SetSourceRect(snowFlakeEffectMain, 0, 144, 63, 207);
	ObjSprite2D_SetDestCenter(snowFlakeEffectMain);
	ObjRender_SetX(snowFlakeEffectMain, GetPlayerX);
	ObjRender_SetY(snowFlakeEffectMain, GetPlayerY);
	
	snowFlakeEffectBack = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(snowFlakeEffectBack, BLEND_ALPHA);
	Obj_SetRenderPriority(snowFlakeEffectBack, 0.29);
	ObjPrim_SetTexture(snowFlakeEffectBack, GetCurrentScriptDirectory() ~ "img/player.png");
	ObjSprite2D_SetSourceRect(snowFlakeEffectBack, 0, 144, 63, 207);
	ObjSprite2D_SetDestCenter(snowFlakeEffectBack);
	ObjRender_SetX(snowFlakeEffectBack, GetPlayerX);
	ObjRender_SetY(snowFlakeEffectBack, GetPlayerY);
	
	let frame = 0;
	
	let scale = 0;
	
	while(snowFlakeStatus == 1 && frame <= 10){
		
		snowFlakeLoopActive = true;
	
		if(frame < 7){
			scale += 1.5/8;
		}
		
		if(frame >= 7){
			scale -= 0.1/2;
		}
		
		ObjRender_SetScaleXYZ(snowFlakeEffectMain, scale, scale, scale);
		ObjRender_SetScaleXYZ(snowFlakeEffectBack, scale, scale, scale);
		
		frame++;
		
		yield;
	}
	
	ObjRender_SetScaleXYZ(snowFlakeEffectMain, 1, 1, 1);
	ObjRender_SetScaleXYZ(snowFlakeEffectBack, 1, 1, 1);
}

task SnowFlakeDelete{
	
	snowFlakeStatus = 2;
	
	let frame = 0;
	
	let lastScale = ObjRender_GetScaleX(snowFlakeEffectMain);
	let scale = ObjRender_GetScaleX(snowFlakeEffectMain);
	
	while(snowFlakeStatus == 2 && frame <= 10){
		
		snowFlakeLoopActive = true;
		
		scale -= lastScale/10;
		
		ObjRender_SetScaleXYZ(snowFlakeEffectMain, scale, scale, scale);
		ObjRender_SetScaleXYZ(snowFlakeEffectBack, scale, scale, scale);
		
		frame++;
		
		yield;
	}
	
	snowFlakeLoopActive = false;
	
	Obj_Delete(snowFlakeEffectMain);
	Obj_Delete(snowFlakeEffectBack);
}

task SnowFlakeLoop{
	loop{
		if(snowFlakeLoopActive){
			
			ObjRender_SetAngleZ(snowFlakeEffectMain, ObjRender_GetAngleZ(snowFlakeEffectMain) - 3);
			ObjRender_SetX(snowFlakeEffectMain, GetPlayerX);
			ObjRender_SetY(snowFlakeEffectMain, GetPlayerY);
			
			ObjRender_SetAngleZ(snowFlakeEffectBack, ObjRender_GetAngleZ(snowFlakeEffectBack) + 3);
			ObjRender_SetX(snowFlakeEffectBack, GetPlayerX);
			ObjRender_SetY(snowFlakeEffectBack, GetPlayerY);
		}
		
		if(!playerAlive){
			SnowFlakeDelete;
		}
		
		yield;
	}
}

task BlinkEffect{
	
	let changeTime = 4;
	
	ascent(frame in 0..180){
		
		if(frame % changeTime == 0){
			Obj_SetVisible(playerObject, !Obj_IsVisible(playerObject));
			frame = 0;
		}
		
		yield;
	}
	
	Obj_SetVisible(playerObject, true);
}

task CreateShots{
	
	let frame = 0;
	
	loop{
		frame++;
		
		if(frame > 3){
			frame = 3;
		}
		
		if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD){
			
			if(frame >= 3 && IsPermitPlayerShot && playerAlive){
				ObjSound_Play(shotSound);
				BasicShot;
				frame = 0;
			}
		}
		
		yield;
	}
}

task BasicShot{
	
	let x = -8;
	
	loop(2){
		if(IsPermitPlayerShot && !idm){
			BasicShotBullet(GetPlayerX + x, GetPlayerY, 25, 270, 3, 1);
		}
		x = -x;
	}
}

task BasicShotBullet(x, y, spd, dir, dmg, color){
	
	if(playerSpellActive){dmg = dmg/4;}
	
	let b = ID_INVALID;
	b = CreatePlayerShotA1(x, y, spd, dir, dmg, 1, color);
	
	let alpha = 0;
	let multiplier = 1;
	let z = 0;
	
	while(!Obj_IsDeleted(b)){
		
		x = ObjMove_GetX(b);
		y = ObjMove_GetY(b);
		z = ObjMove_GetAngle(b);
		
		if(multiplier > 0){
			multiplier -= dmg/500;
		}
		
		ObjShot_SetDamage(b, dmg*multiplier);
		
		if(alpha < 120){
			alpha += 60;
		}
		
		ObjRender_SetAlpha(b, alpha);
		
		yield;
	}
	
	let effect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(effect, BLEND_ALPHA);
	Obj_SetRenderPriority(effect, 0.51);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjSprite2D_SetSourceRect(effect, 0, 0, 16, 32);
	ObjSprite2D_SetDestCenter(effect);
	ObjRender_SetAngleZ(effect, 90 + z);
	ObjRender_SetX(effect, x);
	ObjRender_SetY(effect, y);
	
	alpha = 60;
	
	loop(15){
		ObjRender_SetX(effect, ObjRender_GetX(effect) + 2*cos(z));
		ObjRender_SetY(effect, ObjRender_GetY(effect) + 2*sin(z));
		ObjRender_SetAlpha(effect, alpha);
		alpha -= 60/30;
		
		yield;
	}
	
	Obj_Delete(effect);
}

task CreateOptions{
	
	//DebugPower;
	
	loop{
		if(!optionsAlive && playerAlive && !idm){
			
			if(playerPower >= 100 && playerPower < 200 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				Option(1, 1);
			}
			
			else if(playerPower >= 200 && playerPower < 300 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				ascent(optionNum in 0..2){
					Option(2, optionNum);
				}
				
			}
			
			else if(playerPower >= 300 && playerPower < 400 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				let optionNum = 1;
				
				ascent(optionNum in 0..3){
					Option(3, optionNum);
				}
				
			}
			
			else if(playerPower >= 400 || !powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				let optionNum = 1;
				
				ascent(optionNum in 0..4){
					Option(4, optionNum);
				}
			}
			
			optionsAlive = true;
		}
		
		if(!playerAlive){
			optionsAlive = false;
		}
		
		if(playerPower > 400){
			playerPower = 400;
		}
		
		if(playerPower < 0){
			playerPower = 0;
		}
		
		if(!powerEnabled){
			playerPower = 400;
		}
		
		let lp = playerPower;
		
		yield;
		
		if(lp < 100 && playerPower >= 100 && powerEnabled){optionsAlive = false; yield;}
		if(lp < 200 && playerPower >= 200 && powerEnabled){optionsAlive = false; yield;}
		if(lp < 300 && playerPower >= 300 && powerEnabled){optionsAlive = false; yield;}
		if(lp < 400 && playerPower >= 400 && powerEnabled){optionsAlive = false; yield;}
	}
}

task DebugPower{
	
	let powerDisplay = ObjText_Create;
	Obj_SetRenderPriority(powerDisplay, 0.90);
	
	ObjRender_SetX(powerDisplay, 428);
	ObjRender_SetY(powerDisplay, 254);
	
	ObjText_SetFontSize(powerDisplay, 12);
	ObjText_SetFontBold(powerDisplay, true);
	ObjText_SetFontColorTop(powerDisplay, 128, 128, 228);
	
	loop{
		powerEnabled = true;
		
		if(GetKeyState(KEY_C) == KEY_PUSH){
			playerPower += 100;
		}
		
		if(GetKeyState(KEY_V) == KEY_PUSH){
			playerPower -= 100;
		}
		
		ObjText_SetText(powerDisplay, playerPower);
		yield;
	}
}

task Option(optionCount, optionNum){
	
	let option = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(option, BLEND_ALPHA);
	ObjRender_SetAlpha(option, 196);
	Obj_SetRenderPriority(option, 0.31);
	ObjPrim_SetTexture(option, GetCurrentScriptDirectory() ~ "img/option.png");
	ObjSprite2D_SetSourceRect(option, 0, 0, 32, 32);
	ObjSprite2D_SetDestCenter(option);
	ObjRender_SetScaleXYZ(option, 0, 0, 0);
	
	let angle = 270;
	let radius = 40;
	let speed = 3;
	angle += (360/optionCount)*(optionNum - 1);
	
	ObjRender_SetX(option, GetPlayerX + radius*cos(angle));
	ObjRender_SetY(option, GetPlayerY + radius*sin(angle));
	
	let travelTime = 3;
	
	let optionPos = CreateShotA1(GetPlayerX + radius*cos(angle), GetPlayerY + radius*sin(angle), 0, 0, 0, 1);
	ObjShot_SetIntersectionEnable(optionPos, false);
	ObjShot_SetAutoDelete(optionPos, false);
	
	let scale = 0;
	let count = 0;
	
	let frame = 0;
	
	let alpha = 196;
	
	yield;
	
	while(optionsAlive && playerAlive){
		
		let focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		ObjRender_SetScaleXYZ(option, scale, scale, scale);
		ObjRender_SetX(option, ObjMove_GetX(optionPos));
		ObjRender_SetY(option, ObjMove_GetY(optionPos));
		
		if(count <= 21){
			count++;
		}
		
		if(count <= 20){
			scale += 0.8/20;
		}
		
		if(focus){
			radius = 20;
			speed = 2;
			
			if(alpha > 98){
				alpha -= 8;
			}
			
			if(alpha < 96){
				alpha = 96;
			}
		}
		else{
			radius = 40;
			speed = 3;
			
			if(alpha < 194){
				alpha += 8;
			}
			
			if(alpha > 196){
				alpha = 196;
			}
		}
		
		ObjRender_SetAlpha(option, alpha);
		ObjMove_SetDestAtFrame(optionPos, GetPlayerX + radius*cos(angle), GetPlayerY + radius*sin(angle), travelTime);
		
		angle += speed;
		
		frame++;
		
		if(frame > 3){
			frame = 3;
		}
		
		if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD){
			if(!focus && frame >= 3){
				
				let dir = angle - 85;
				
				loop(3){
					if(IsPermitPlayerShot){
						BasicShotBullet(ObjRender_GetX(option),  ObjRender_GetY(option), 20, dir, 5, 2);
					}
					dir += 10;
				}
				
				frame = 0;
			}
			
			if(focus && frame >= 3){
				if(IsPermitPlayerShot){
					OptionBullet(ObjRender_GetX(option),  ObjRender_GetY(option), 13, 270);
				}
				frame = 0;
			}
		}
		
		yield;
	}
	
	scale = 0.8;
	
	loop(20){
		
		let focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		scale -= 0.8/20;
		
		ObjRender_SetScaleXYZ(option, scale, scale, scale);
		ObjRender_SetX(option, ObjMove_GetX(optionPos));
		ObjRender_SetY(option, ObjMove_GetY(optionPos));
		
		if(focus){
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX -5, GetPlayerY -5, travelTime);
		}
		else{
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX + radius*cos(angle), GetPlayerY + radius*sin(angle), travelTime);
		}
		
		yield;
	}
	
	Obj_Delete(option);
}

task OptionBullet(x, y, spd, dir){
	
	let dmg = 3;
	if(playerSpellActive){dmg = dmg/5;}
	
	let b = ID_INVALID;
	b = CreatePlayerShotA1(x, y, spd, dir, dmg, 1, 3);
	ObjRender_SetScaleXYZ(b, 0.5, 0.5, 0.5);
	ObjRender_SetAlpha(b, 120);
	
	let multiplier = 1;
	let z = 0;
	
	while(!Obj_IsDeleted(b)){
		
		x = ObjMove_GetX(b);
		y = ObjMove_GetY(b);
		z = ObjMove_GetAngle(b);
		
		if(multiplier > 0){
			multiplier -= dmg/500;
		}
		
		ObjShot_SetDamage(b, dmg*multiplier);
		
		yield;
	}
	
	let effect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(effect, BLEND_ALPHA);
	Obj_SetRenderPriority(effect, 0.51);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjSprite2D_SetDestRect(effect, -32, -32, 32, 32);
	ObjRender_SetScaleXYZ(effect, 0.5, 0.5, 0.5);
	ObjRender_SetAngleZ(effect, 90 + z);
	ObjRender_SetAlpha(effect, 60);
	ObjRender_SetX(effect, x);
	ObjRender_SetY(effect, y);
	
	let xTile = 0;
	
	ascent(i in 0..15){
		ObjSprite2D_SetSourceRect(effect, (xTile*64) + 16, 0, ((xTile + 1)*64) + 16, 64);
		ObjRender_SetX(effect, ObjRender_GetX(effect) + 2*cos(z));
		ObjRender_SetY(effect, ObjRender_GetY(effect) + 2*sin(z));
		
		if(i % 5 == 0){
			xTile++;
		}
		
		yield;
	}
	
	Obj_Delete(effect);
}

task Spell(focus){
	
	let spellObject = GetSpellManageObject;
	playerSpellActive = true;
	
	SpellUseCutIn(GetCurrentScriptDirectory ~ "img/cutIn.png", 0, 0, 240, 480, 0.5);
	ObjSound_Play(spellUseSound);
	SetPlayerSpeed(0.6, 0.6);
	SpellMagicCircle;
	
	if(playerHit){
		playerHit = false;
		
		SpellUseName("Photograph \"Danmaku Panorama\"");
		SetPlayerInvincibilityFrame(600);
		MagicCircle(600);
		
		spell(3);
		
		SetPlayerSpeed(6, 2.5);
		playerSpellActive = false;
		loop(240){yield;}
		
		loop(60){yield;}
		Obj_Delete(spellObject);
	}
	else if(focus){
		SpellUseName("Tornado \"Indication to the Divine\"");
		SetPlayerInvincibilityFrame(300);
		MagicCircle(300);
		
		spell(1);
		SetPlayerSpeed(6, 2.5);
		playerSpellActive = false;
		
		loop(60){yield;}
		Obj_Delete(spellObject);
		ObjSound_SetVolumeRate(spellShotSound, 80);
	}
	else if(!focus){
		SpellUseName("\"Illusionary Dominance\"");
		SetPlayerInvincibilityFrame(680);
		SetPlayerSpeed(0, 0);
		spell(2);
		
		MagicCircle(180);
		SetPlayerSpeed(6, 2.5);
		
		loop(60){yield;}
		playerSpellActive = false;
		Obj_Delete(spellObject);
	}
}

function spell(type){
	
	if(type == 1){
		ObjSound_Play(tornadoSound);
		
		let dmg = ID_INVALID;
		
		if(IsPermitPlayerSpell){
			dmg = ObjSpell_Create;
			ObjSpell_Regist(dmg);
		}
		
		let frame = 0;
		let alpha = 0;
		let time = 1;
		
		let vDmg = 0;
		
		let vol = 80;
		
		screenShake;
		
		ascent(i in 0..304){
			
			if(vDmg != 0 && IsPermitPlayerSpell){
				ObjSpell_SetIntersectionCircle(dmg, GetStgFrameWidth/2, GetStgFrameHeight/2, 512);
			}
			if(i < 40){
				vDmg += 0.25;
			}
			
			if(i > 240 && vDmg > 0){
				vDmg -= 0.25;
			}
				
			ObjSpell_SetDamage(dmg, vDmg);
			
			frame++;
			
			if(i < 240){
				alpha += 1;
			}
			else{
				alpha -= 1;
			}
			
			if(alpha > 64){
				alpha = 64;
			}
			
			if(frame == time){
				ObjSound_Play(spellShotSound);
				
				if(i > 260){
					vol -= 1;
					ObjSound_SetVolumeRate(spellShotSound, vol);
				}
				
				windEffect(1, alpha);
			}
			else if(frame == time*2){
				windEffect(2, alpha);
			}
			else if(frame == time*3){
				windEffect(3, alpha);
				frame = 0;
			}
			
			yield;
		}
		
		task windEffect(type, alpha){
			let effect = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(effect, BLEND_ALPHA);
			Obj_SetRenderPriority(effect, rand(0.2, 0.6));
			ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
			ObjSprite2D_SetDestRect(effect, -512, -512, 512, 512);
			ObjSprite2D_SetSourceRect(effect, 0, 64, 256, 316);
			ObjRender_SetAlpha(effect, alpha);
			
			let spd = 40;
			let xAdd = spd;
			let yAdd = spd/10;
			
			if(type == 2){
				ObjSprite2D_SetSourceRect(effect, 256, 64, 512, 316);
			}
			else if(type == 3){
				ObjSprite2D_SetSourceRect(effect, 0, 316, 256, 572);
			}
			
			let x = GetStgFrameLeft - 1024;
			
			if(trunc(rand(0, 2)) == 1){
				x = GetStgFrameWidth + 1024;
				xAdd = -xAdd;
			}
			
			ObjRender_SetX(effect, x);
			ObjRender_SetY(effect, GetStgFrameHeight/2 + rand(-16, 16));
			xAdd += rand(-1, 1);
			yAdd += rand(-(spd/5 + 1), 1);
			
			loop(180){
				ObjRender_SetX(effect, ObjRender_GetX(effect) + xAdd);
				ObjRender_SetY(effect, ObjRender_GetY(effect) + yAdd);
				yield;
			}
			
			Obj_Delete(effect);
		}
		
		task screenShake{
			
			let x = Get2DCameraX;
			let y = Get2DCameraY;
			
			let o = 5;
			
			ascent(i in 0..300){
				let xOff = rand(-o, o);
				let yOff = rand(-o, o);
				
				Set2DCameraFocusX(x + xOff);
				Set2DCameraFocusY(y + yOff);
				
				o += 0.1;
				
				if(i > 240){
					o -= 0.6;
				}
				
				yield;
			}
			
			Reset2DCamera;
		}
	}
	else if(type == 2){
		
		idm = true;
		optionsAlive = false;
		SetPlayerClip(GetStgFrameLeft - 64, GetStgFrameTop, GetStgFrameWidth + 64, GetStgFrameHeight);
		
		let inv = trunc(rand(0, 2)) == 1;
		
		let spd = 6;
		let dir = rand(180, 200);
		
		if(inv){
			dir += 160;
		}
		
		let dmg = ID_INVALID;
		
		if(IsPermitPlayerSpell){
			dmg = ObjSpell_Create;
			ObjSpell_SetDamage(dmg, 20);
			ObjSpell_Regist(dmg);
		}
		
		let count = 0;
		
		ascent(i in 0..60){
			
			if(i == 10){
				Obj_SetVisible(playerObject, false);
			}
			
			while(GetPlayerX > GetStgFrameLeft - 64 && GetPlayerX < GetStgFrameWidth + 64){
				
				if(i < 10){
					ObjMove_SetPosition(playerObject, GetPlayerX + spd*cos(dir), GetPlayerY + spd*sin(dir));
				}
				else{
					ObjMove_SetPosition(playerObject, GetPlayerX + spd*cos(dir), GetPlayerY);
				}
				
				if(IsPermitPlayerSpell){
					ObjSpell_SetIntersectionCircle(dmg, GetPlayerX, GetPlayerY, 16);
				}
				
				if(i > 10){
					
					count++;
					
					if(count >= 5){
						laser(GetPlayerY);
						count = 0;
					}
					
					if(GetVirtualKeyState(VK_DOWN) == KEY_PUSH || GetVirtualKeyState(VK_DOWN) == KEY_HOLD){
						ObjMove_SetY(playerObject, GetPlayerY + 10);
					}
					
					if(GetVirtualKeyState(VK_UP) == KEY_PUSH || GetVirtualKeyState(VK_UP) == KEY_HOLD){
						ObjMove_SetY(playerObject, GetPlayerY - 10);
					}
				}
				
				yield;
			}
			
			if(GetPlayerX <= GetStgFrameLeft - 64){
				ObjMove_SetX(playerObject, GetStgFrameLeft + 1);
			}
			
			else if(GetPlayerX >= GetStgFrameWidth + 64){
				ObjMove_SetX(playerObject, GetStgFrameWidth - 1);
			}
			
			inv = !inv;
			dir = rand(160, 200);
			
			if(i >= 10){
				dir = 180
			}
			if(inv){
				dir += 180;
			}
			
			if(GetPlayerY < GetStgFrameTop + 64){
				dir = rand(160, 170);
				
				if(inv){
					dir -= 180;
				}
			}
			
			if(GetPlayerY > GetStgFrameHeight - 64){
				dir = rand(190, 200);
				
				if(inv){
					dir += 180;
				}
			}
			
			if(i < 10){
				spd += 7;
			}
			
			if(i == 11){
				Obj_Delete(dmg);
			}
			
			ObjSound_Play(spellShotSound);
			yield;
			
			if(i >= 10){
				ObjSound_Play(spellShotSound);
			}
		}
		
		idm = false;
		SetPlayerClip(0, 0, GetStgFrameWidth, GetStgFrameHeight);
		Obj_SetVisible(playerObject, true);
		ObjMove_SetX(playerObject, GetStgFrameWidth/2);
		Obj_Delete(dmg);
		
		task laser(y){
			
			let l = ID_INVALID;
			
			let spellOn = IsPermitPlayerSpell;
			
			if(spellOn){
				l = ObjSpell_Create;
				ObjSpell_SetDamage(l, 10);
				ObjSpell_Regist(l);
			}
			
			let effect = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(effect, BLEND_ALPHA);
			Obj_SetRenderPriority(effect, 0.60);
			ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
			ObjSprite2D_SetDestRect(effect, -512, -12, 512, 12);
			ObjSprite2D_SetSourceRect(effect, 272, 1, 288, 16);
			
			let x = GetStgFrameWidth + 256;
			let dir = rand(170, 190);
			let spd = 100;
			
			if(trunc(rand(0, 2)) == 1){
				x = GetStgFrameLeft - 256;
				dir += 180;
			}
			
			ObjRender_SetX(effect, x);
			ObjRender_SetY(effect, y + rand(-80, 80));
			ObjRender_SetAngleZ(effect, dir);
			
			loop(60){
				ObjRender_SetX(effect, ObjRender_GetX(effect) + spd*cos(dir));
				ObjRender_SetY(effect, ObjRender_GetY(effect) + spd*sin(dir));
				
				if(spellOn){
					ObjSpell_SetIntersectionLine(l, ObjRender_GetX(effect) + 512*cos(dir), ObjRender_GetY(effect) + 512*sin(dir), ObjRender_GetX(effect) - 512*cos(dir), ObjRender_GetY(effect) - 512*sin(dir), 24);
				}
				
				yield;
			}
			
			Obj_Delete(l);
			Obj_Delete(effect);
		}
	}
	else if(type == 3){
		
		ObjSound_Play(cameraChargeSound);
		chargeUp;
		
		loop(30){yield;}
		
		let enemy = GetAllEnemyID;
		
		let dir = 270;
		
		let savedENum = 0;
		let eNum = 0;
		
		if(length(enemy) > 0){
			
			let lastDistance = 10000;
			
			loop(length(enemy)){
				let distance = GetObjectDistance(playerObject, enemy[eNum]);
				
				if(distance < lastDistance && distance != -1){
					savedENum = eNum;
				}
				
				lastDistance = distance;
				
				eNum++;
			}
			
			let x = ObjMove_GetX(enemy[savedENum]);
			let y = ObjMove_GetY(enemy[savedENum]);
			
			let boss = GetEnemyBossObjectID;
			
			if(length(boss) > 0){
				x = ObjMove_GetX(boss[0]);
				y = ObjMove_GetY(boss[0]);
			}
			
			dir = atan2(y - GetPlayerY, x - GetPlayerX);
		}
		
		dp = true;
		
		loop(8){
			picture(dir);
			dir += 360/8;
			
			loop(20){yield;}
		}
		
		dp = false;
		
		task picture(dir){
			let effect = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(effect, BLEND_ALPHA);
			Obj_SetRenderPriority(effect, 0.60);
			ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
			ObjSprite2D_SetDestRect(effect, -128, -98, 128, 98);
			ObjSprite2D_SetSourceRect(effect, 0, 576, 256, 768);
			ObjRender_SetAngleZ(effect, dir);
			ObjRender_SetX(effect, GetPlayerX + 100*cos(dir));
			ObjRender_SetY(effect, GetPlayerY + 100*sin(dir));
			ObjRender_SetScaleXYZ(effect, 0.8, 0, 0.8);
			
			let scale = 0;
			let alpha = 256;
			
			ObjSound_Play(cameraDeploySound);
			
			ascent(i in 0..120){
				
				if(i < 110){
					ObjRender_SetX(effect, ObjRender_GetX(effect) + 1*cos(dir));
					ObjRender_SetY(effect, ObjRender_GetY(effect) + 1*sin(dir));
				}
				
				if(i <= 30){
					scale += 0.8/30;
					ObjRender_SetScaleY(effect, scale);
				}
				
				if(i >= 110){
					alpha -= 256/10;
					ObjRender_SetAlpha(effect, alpha);
				}
				
				if(i == 110){
					pictureSnap(ObjRender_GetX(effect), ObjRender_GetY(effect), dir);
				}
				
				yield;
			}
			
			task pictureSnap(x, y, dir){
				let effect = ObjPrim_Create(OBJ_SPRITE_2D);
				ObjRender_SetBlendType(effect, BLEND_ALPHA);
				Obj_SetRenderPriority(effect, 0.60);
				ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
				ObjSprite2D_SetDestRect(effect, -128, -98, 128, 98);
				ObjSprite2D_SetSourceRect(effect, 256, 576, 512, 768);
				ObjRender_SetAngleZ(effect, dir);
				ObjRender_SetScaleXYZ(effect, 0.8, 0.8, 0.8);
				ObjRender_SetX(effect, x);
				ObjRender_SetY(effect, y);
				
				let alpha = 0;
				let dmg = ID_INVALID;
				
				ObjSound_Play(cameraSnap1Sound);
				ObjSound_Play(cameraSnap2Sound);
				
				ascent(i in 0..40){
					ObjRender_SetAlpha(effect, alpha);
					
					if(i < 10){
						alpha += 256/10;
					}
					
					if(i >= 10){
						alpha -= 256/30;
					}
					
					if(i == 10){
						if(IsPermitPlayerSpell){
							dmg = ObjSpell_Create;
							ObjSpell_SetDamage(dmg, 10000);
							ObjSpell_SetIntersectionLine(dmg, x + 102*cos(dir), y + 102*sin(dir), x - 102*cos(dir), y - 102*sin(dir), 78);
							ObjSpell_Regist(dmg);
						}
					}
					else if(i == 11){
						Obj_Delete(dmg);
					}
					
					yield;
				}
				
				Obj_Delete(effect);
			}
			
			Obj_Delete(effect);
		}
		
		function chargeUp{
			
			loop(40){
				chargePart;
				loop(2){yield;}
			}
			
			task chargePart{
				let effect = ObjPrim_Create(OBJ_SPRITE_2D);
				ObjRender_SetBlendType(effect, BLEND_ALPHA);
				Obj_SetRenderPriority(effect, 0.40);
				ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/option.png");
				ObjSprite2D_SetSourceRect(effect, 0, 0, 32, 32);
				ObjSprite2D_SetDestCenter(effect);
				
				let dir = rand(0, 360);
				
				ObjRender_SetX(effect, GetPlayerX + 120*cos(dir + 180));
				ObjRender_SetY(effect, GetPlayerY + 120*sin(dir + 180));
				
				let xr = 1;
				let yr = 1;
				let zr = 1;
				
				let xa = 0;
				let ya = 0;
				let za = 0;
				
				xa = rand(0, 360);
				ya = rand(0, 360);
				za = rand(0, 360);
				
				let xd = round(rand(1, 2));
				let yd = round(rand(1, 2));
				let zd = round(rand(1, 2));
				
				if(xd == 2){xr = -xr;}
				if(yd == 2){yr = -yr;}
				if(zd == 2){zr = -zr;}
				
				if(xa < 180){xr = -xa/40;}
				if(ya < 180){yr = -ya/40;}
				if(za < 180){zr = -za/40;}
				
				if(xa >= 180){xr = (360 - xa)/40;}
				if(ya >= 180){yr = (360 - ya)/40;}
				if(za >= 180){zr = (360 - za)/40;}
				
				let spd = 0;
				let alpha = 0;
				let scale = 0;
				
				loop(40){
					ObjRender_SetX(effect, ObjRender_GetX(effect) + spd*cos(dir));
					ObjRender_SetY(effect, ObjRender_GetY(effect) + spd*sin(dir));
					ObjRender_SetScaleXYZ(effect, scale, scale, scale);
					ObjRender_SetAngleXYZ(effect, xa, ya, za);
					ObjRender_SetAlpha(effect, alpha);
					
					scale += 0.04;
					
					if(spd < 4){
						spd += 0.2;
					}
					
					alpha += 6;
					
					xa += xr;
					ya += yr;
					za += zr;
					yield;
				}
				
				Obj_Delete(effect);
			}
		}
	}
}

task SpellMagicCircle{
	
	let magicCircle = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(magicCircle, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(magicCircle, 66);
	ObjRender_SetBlendType(magicCircle, BLEND_ALPHA);
	Obj_SetRenderPriority(magicCircle, 0.30);
	ObjPrim_SetTexture(magicCircle, GetCurrentScriptDirectory() ~ "img/circle.png");
	
	let width = 10;
	
	let alt = true;
	
	let dir = 0;
	let r = 0;
	let x = 0;
	
	ascent(i in 0..66){
		ObjPrim_SetVertexPosition(magicCircle, i, r*cos(dir), r*sin(dir), 0);
		ObjPrim_SetVertexUVT(magicCircle, i, x, i*8);
		ObjRender_SetX(magicCircle, GetPlayerX);
		ObjRender_SetY(magicCircle, GetPlayerY);
		
		if(!alt){r += width; x = 0;}
		if(alt){r -= width; x = 16;}
		alt = !alt;
		
		dir += 360/64;
	}
	
	let alpha = 0;
	let z = 0;
	
	ascent(i in 0..90){
		
		ObjRender_SetX(magicCircle, GetPlayerX);
		ObjRender_SetY(magicCircle, GetPlayerY);
		ObjRender_SetAlpha(magicCircle, alpha);
		ObjRender_SetAngleZ(magicCircle, z);
		
		DeleteShotInCircle(TYPE_ALL, TYPE_IMMEDIATE, GetPlayerX, GetPlayerY, r);
		
		if(i > 70){
			alpha -= 32/5;
		}
		else if(alpha < 128){
			alpha += 2;
		}
		
		z += 3;
		
		alt = true;
		dir = 0;
		r += 1.5;
		
		ascent(i in 0..66){
			
			let rOriginal = r;
			
			if(r < 0){
				r = 0;
			}
			
			ObjPrim_SetVertexPosition(magicCircle, i, r*cos(dir), r*sin(dir), 0);
			
			r = rOriginal;
		
			if(!alt){r += width; x = 0;}
			if(alt){r -= width; x = 16;}
			alt = !alt;
			
			dir += 360/64;
		}
		
		yield;
	}
	
	Obj_Delete(magicCircle);
}

task MagicCircle(time){
	
	let magicCircle = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(magicCircle, PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(magicCircle, 66);
	ObjRender_SetBlendType(magicCircle, BLEND_ALPHA);
	Obj_SetRenderPriority(magicCircle, 0.30);
	ObjPrim_SetTexture(magicCircle, GetCurrentScriptDirectory() ~ "img/circle.png");
	
	let width = 10;
	
	let alt = true;
	
	let dir = 0;
	let r = 100;
	let x = 0;
	
	ascent(i in 0..66){
		ObjPrim_SetVertexPosition(magicCircle, i, r*cos(dir), r*sin(dir), 0);
		ObjPrim_SetVertexUVT(magicCircle, i, x, i*8);
		ObjRender_SetX(magicCircle, GetPlayerX);
		ObjRender_SetY(magicCircle, GetPlayerY);
		
		if(!alt){r += width; x = 0;}
		if(alt){r -= width; x = 16;}
		alt = !alt;
		
		dir += 360/64;
	}
	
	let alpha = 0;
	let z = 0;
	
	loop(time){
		
		ObjRender_SetX(magicCircle, GetPlayerX);
		ObjRender_SetY(magicCircle, GetPlayerY);
		ObjRender_SetAlpha(magicCircle, alpha);
		ObjRender_SetAngleZ(magicCircle, z);
		
		if(alpha < 128){
			alpha += 2;
		}
		
		z += 3;
		
		alt = true;
		dir = 0;
		r -= 100/time;
		
		ascent(i in 0..66){
			
			let rOriginal = r;
			
			if(r < 0){
				r = 0;
			}
			
			ObjPrim_SetVertexPosition(magicCircle, i, r*cos(dir), r*sin(dir), 0);
			
			r = rOriginal;
		
			if(!alt){r += width; x = 0;}
			if(alt){r -= width; x = 16;}
			alt = !alt;
			
			dir += 360/64;
		}
		
		yield;
	}
	
	Obj_Delete(magicCircle);
}

task DisableSpell(time){
	SetForbidPlayerSpell(true);
	loop(time){yield;}
	SetForbidPlayerSpell(false);
}

task DeathItem(type, x, y, xd, yd){
	let i = CreateItemA1(type, x, y, 0);
	
	let dir = atan2(yd - y, xd - x);
	
	loop(240){
		ObjMove_SetX(i, ObjMove_GetX(i) + cos(dir));
		ObjMove_SetY(i, ObjMove_GetY(i) + sin(dir));
		yield;
	}
}

task GrazeEffect{
	
	let effect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(effect, BLEND_ALPHA);
	Obj_SetRenderPriority(effect, 0.35);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/graze.png");
	ObjSprite2D_SetSourceRect(effect, 0, 0, 32, 32);
	ObjSprite2D_SetDestCenter(effect);
	ObjRender_SetColor(effect, 255, 160, 100);
	ObjRender_SetAlpha(effect, 164);
	
	let dir = rand(0, 360);
	let scale = 0.5;
	
	ObjRender_SetX(effect, GetPlayerX + 10*cos(dir));
	ObjRender_SetY(effect, GetPlayerY + 10*sin(dir));
	
	loop(15){
		ObjRender_SetX(effect, ObjRender_GetX(effect) + 4*cos(dir));
		ObjRender_SetY(effect, ObjRender_GetY(effect) + 4*sin(dir));
		ObjRender_SetScaleXYZ(effect, scale, scale, scale);
		
		scale -= 0.5/15;
		
		yield;
	}
	
	Obj_Delete(effect);
}

task ExplosionEffect{
	
	let effect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(effect, BLEND_ALPHA);
	Obj_SetRenderPriority(effect, 0.50);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/effect.png");
	ObjSprite2D_SetSourceRect(effect, 0, 0, 64, 64);
	ObjSprite2D_SetDestCenter(effect);
	ObjRender_SetX(effect, GetPlayerX);
	ObjRender_SetY(effect, GetPlayerY);
	
	let alpha = 255;
	let scale = 0;
	
	while(alpha > 0){
		
		ObjRender_SetScaleXYZ(effect, scale, scale, scale);
		ObjRender_SetAlpha(effect, alpha);
		
		alpha -= 8;
		scale += 0.15;
		
		yield;
	}
	
	Obj_Delete(effect);
}