#include"./CutIn.txt"

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


let playerSpriteFrame1;
let playerSpriteFrame2;
let playerSpriteFrame3;
let playerSpriteY;


let snowFlakeEffectMain = ID_INVALID;
let snowFlakeEffectBack = ID_INVALID;

let snowFlakeStatus = 2;
let snowFlakeLoopActive = false;


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

let o1x = 0;
let o1y = 0;

let o2x = 0;
let o2y = 0;

let o3x = 0;
let o3y = 0;

let o4x = 0;
let o4y = 0;


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 laserSound = ObjSound_Create;
let laserFireSound = ObjSound_Create;

let spellUseSound = ObjSound_Create;
let spellShotSound = ObjSound_Create;
let spellMoveSound = ObjSound_Create;
let spellLaserSound = ObjSound_Create;

let bgSound = 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(laserSound, GetCurrentScriptDirectory ~ "sounds/se_lazer02.wav");
	ObjSound_Load(laserFireSound, GetCurrentScriptDirectory ~ "sounds/se_kira02.wav");
	
	ObjSound_Load(spellUseSound, GetCurrentScriptDirectory ~ "sounds/se_ufo.wav");
	ObjSound_Load(spellShotSound, GetCurrentScriptDirectory ~ "sounds/se_tan00.wav");
	ObjSound_Load(spellMoveSound, GetCurrentScriptDirectory ~ "sounds/se_boon00.wav");
	ObjSound_Load(spellLaserSound, GetCurrentScriptDirectory ~ "sounds/se_lazer00.wav");
	
	ObjSound_Load(bgSound, GetCurrentScriptDirectory ~ "sounds/se_boon01.wav");
	
	
	ObjSound_SetVolumeRate(deathSound, 80);
	ObjSound_SetVolumeRate(grazeSound, 80);
	ObjSound_SetVolumeRate(shotSound, 80);
	ObjSound_SetVolumeRate(laserSound, 60);
	ObjSound_SetVolumeRate(laserFireSound, 80);
	ObjSound_SetVolumeRate(spellShotSound, 80);
}

task DrawSprite{
	
	ObjPrim_SetTexture(playerObject, GetCurrentScriptDirectory ~ "img/player.png");
	
	let changeTime = 4;
	let frame = 0;
	
	playerSpriteFrame1 = 0;
	playerSpriteFrame2 = 0;
	playerSpriteFrame3 = 0;
	playerSpriteY = 0;
	
	loop{
		if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH || GetVirtualKeyState(VK_LEFT) == KEY_HOLD){
			
			ObjSprite2D_SetSourceRect(playerObject, 32*playerSpriteFrame1, 48, 32*(playerSpriteFrame1 + 1), 96);
			
			playerSpriteY = 2;
			
			if(frame >= changeTime){
				playerSpriteFrame1 += 1;
				
				if(playerSpriteFrame1 >= 7){
					playerSpriteFrame1 = 3;
				}
			}
			
			playerSpriteFrame2 = 0;
			playerSpriteFrame3 = 0;
		}
		
		else if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH || GetVirtualKeyState(VK_RIGHT) == KEY_HOLD){
			
			ObjSprite2D_SetSourceRect(playerObject, 32*playerSpriteFrame2, 96, 32*(playerSpriteFrame2 + 1), 144);
			
			playerSpriteY = 3;
			
			if(frame >= changeTime){
				playerSpriteFrame2 += 1;
				
				if(playerSpriteFrame2 >= 7){
					playerSpriteFrame2 = 3;
				}
			}
			
			playerSpriteFrame1 = 0;
			playerSpriteFrame3 = 0;
		}
		
		else{
			ObjSprite2D_SetSourceRect(playerObject, 32*playerSpriteFrame3, 0, 32*(playerSpriteFrame3 + 1), 48);
			
			playerSpriteY = 1;
			
			if(frame >= changeTime){
				playerSpriteFrame3 += 1;
			}
			
			if(playerSpriteFrame3 >= 7 && frame >= changeTime){
				playerSpriteFrame3 = 0;
			}
			
			playerSpriteFrame1 = 0;
			playerSpriteFrame2 = 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_SetDestRect(snowFlakeEffectMain, -32, -32, 32, 32);
	ObjSprite2D_SetSourceRect(snowFlakeEffectMain, 0, 144, 63, 207);
	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_SetDestRect(snowFlakeEffectBack, -32, -32, 32, 32);
	ObjSprite2D_SetSourceRect(snowFlakeEffectBack, 0, 144, 63, 207);
	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;
	let frame = 0;
	
	loop(240){
		
		frame++;
		
		if(frame >= changeTime){
			Obj_SetVisible(playerObject, !Obj_IsVisible(playerObject));
			frame = 0;
		}
		
		yield;
	}
}

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

task BasicShot{
	BasicShotBullet(GetPlayerX + 10, GetPlayerY, 20, 270, 6, 2);
	BasicShotBullet(GetPlayerX - 10, GetPlayerY, 20, 270, 6, 2);
}

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 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.55);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjSprite2D_SetDestRect(effect, -8, -8, 8, 8);
	ObjSprite2D_SetSourceRect(effect, 48, 32, 64, 48);
	ObjRender_SetX(effect, x);
	ObjRender_SetY(effect, y);
	
	if(color == 9){
		ObjSprite2D_SetDestRect(effect, -4, -4, 4, 4);
		ObjSprite2D_SetSourceRect(effect, 32, 16, 40, 24);
	}
	
	if(color == 10){
		ObjSprite2D_SetDestRect(effect, -8, -8, 8, 8);
		ObjSprite2D_SetSourceRect(effect, 48, 16, 64, 32);
	}
	
	if(color == 12){
		ObjSprite2D_SetDestRect(effect, -8, -8, 8, 8);
		ObjSprite2D_SetSourceRect(effect, 80, 16, 96, 32);
	}
	
	let alpha = 128;
	z += 90;
	
	loop(15){
		ObjRender_SetX(effect, ObjRender_GetX(effect) + 2*cos(dir));
		ObjRender_SetY(effect, ObjRender_GetY(effect) + 2*sin(dir));
		ObjRender_SetAlpha(effect, alpha);
		
		if(color < 9){
			ObjRender_SetAngleZ(effect, z);
		}
		
		alpha -= 128/30;
		z += 5;
		
		yield;
	}
	
	Obj_Delete(effect);
}

task CreateOptions{
	
	//DebugPower;
	
	loop{
		if(!optionsAlive && playerAlive){
			
			if(playerPower >= 100 && playerPower < 200 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				if(shotType == 1){
					Option(1, 0, -40, 0, -25, 271.5, 270, 4, 1, 2, 1);
				}
				
				if(shotType == 2){
					Option(1, 0, 37, 0, 28, 90, 270, 5, 4, 3, 1);
				}
				
				if(shotType == 3){
					Option(1, 0, -40, 0, 15, 277, 270, 4, 9, 3, 1);
				}
			}
			
			if(playerPower >= 200 && playerPower < 300 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				
				if(shotType == 1){
					Option(1, 20, -40, 10, -25, 274, 268, 4, 1, 2, 1);
					Option(2, -20, -40, -10, -25, 266, 272, 4, 1, 2, 1);
				}
				
				if(shotType == 2){
					Option(1, 25, 37, 20, 28, 80, 270, 5, 4, 3, 1);
					Option(2, -25, 37, -20, 28, 100, 270, 5, 4, 3, 1);
				}
				
				if(shotType == 3){
					Option(1, 30, -40, 20, -10, 280, 275, 4, 9, 3, 1);
					Option(2, -30, -40, -20, -10, 260, 265, 4, 9, 3, 1);
				}
			}
			
			if(playerPower >= 300 && playerPower < 400 && powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				
				if(shotType == 1){
					Option(1, 0, -40, 0, -25, 271.5, 270, 8, 2, 2, 1);
					
					Option(2, 40, -10, 20, -5, 290, 275, 3.5, 1.5, 3, 2);
					Option(3, -40, -10, -20, -5, 250, 265, 3.5, 1.5, 3, 2);
				}
				
				if(shotType == 2){
					Option(1, 0, 37, 0, 28, 90, 270, 5, 4, 3, 1);
					
					Option(3, 45, -17.5, 34, -12, 330, 270, 5, 4, 3, 2);
					Option(4, -45, -17.5, -34, -12, 210, 270, 5, 4, 3, 2);
				}
				
				if(shotType == 3){
					Option(1, 0, -40, 0, 15, 277, 270, 5, 10, 3, 1);
					
					Option(3, 40, 20, 40, 10, 330, 294, 3.5, 9, 5, 2);
					Option(4, -40, 20, -40, 10, 210, 246, 3.5, 9, 5, 2);
				}
			}
			
			if(playerPower >= 400 || !powerEnabled){
				if(prevAlive){ObjSound_Play(powerUpSound);}
				
				
				if(shotType == 1){
					Option(1, 20, -40, 10, -25, 274, 268, 4, 1, 2, 1);
					Option(2, -20, -40, -10, -25, 266, 272, 4, 1, 2, 1);
					
					Option(3, 40, -10, 20, -5, 290, 275, 3.5, 1.5, 3, 2);
					Option(4, -40, -10, -20, -5, 250, 265, 3.5, 1.5, 3, 2);
				}
				
				if(shotType == 2){
					OptionBackground;
					
					Option(1, 25, 37, 20, 28, 80, 270, 5, 4, 3, 1);
					Option(2, -25, 37, -20, 28, 100, 270, 5, 4, 3, 1);
					
					Option(3, 45, -17.5, 34, -12, 330, 270, 5, 4, 3, 2);
					Option(4, -45, -17.5, -34, -12, 210, 270, 5, 4, 3, 2);
				}
				
				if(shotType == 3){
					Option(1, 30, -40, 20, -10, 280, 275, 4, 7, 3, 1);
					Option(2, -30, -40, -20, -10, 260, 265, 4, 7, 3, 1);
					
					Option(3, 40, 20, 40, 10, 330, 294, 3.5, 7, 5, 2);
					Option(4, -40, 20, -40, 10, 210, 246, 3.5, 7, 5, 2);
				}
			}
			
			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;}
		if(!optionsAlive && powerEnabled){lasersSpawned = false;}
	}
}

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 OptionBackground{
	
	ObjSound_Play(bgSound);
	
	let bgEffect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(bgEffect, BLEND_ALPHA);
	Obj_SetRenderPriority(bgEffect, 0.27);
	ObjPrim_SetTexture(bgEffect, GetCurrentScriptDirectory() ~ "img/option.png");
	ObjSprite2D_SetDestRect(bgEffect, -192, -128, 192, 128);
	ObjSprite2D_SetSourceRect(bgEffect, 0, 0, 384, 256);
	ObjRender_SetScaleXYZ(bgEffect, 0, -0.4, 0.4);
	
	ObjRender_SetX(bgEffect, GetPlayerX);
	ObjRender_SetY(bgEffect, GetPlayerY);
	
	let bgPos = CreateShotA1(GetPlayerX, GetPlayerY, 0, 0, 0, 0);
	ObjShot_SetIntersectionEnable(bgPos, false);
	ObjShot_SetAutoDelete(bgPos, false);
	
	let travelTime = 2;
	
	let scale = 0;
	let scale2 = 0;
	let frame = 0;
	
	loop(40){
		
		scale2 += (0.4 - (0.1*(frame/5)))/40;
		
		ObjRender_SetScaleX(bgEffect, scale2);
		ObjMove_SetDestAtFrame(bgPos, GetPlayerX, GetPlayerY, travelTime);
		ObjRender_SetX(bgEffect, ObjMove_GetX(bgPos));
		ObjRender_SetY(bgEffect, ObjMove_GetY(bgPos));
		
		focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		if(focus){
			frame++;
		}
		
		if(!focus){
			frame--;
		}
		
		if(frame > 5){
			frame = 5;
		}
		
		if(frame < 0){
			frame = 0;
		}
		
		scale = 0.4 - (0.1*(frame/5));
		ObjRender_SetScaleY(bgEffect, -scale);
		
		yield;
	}
	
	let focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
	scale = 0.4;
	
	while(playerPower >= 400){
		
		ObjMove_SetDestAtFrame(bgPos, GetPlayerX, GetPlayerY, travelTime);
		ObjRender_SetX(bgEffect, ObjMove_GetX(bgPos));
		ObjRender_SetY(bgEffect, ObjMove_GetY(bgPos));
		
		focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		if(focus){
			frame++;
		}
		
		if(!focus){
			frame--;
		}
		
		if(frame > 5){
			frame = 5;
		}
		
		if(frame < 0){
			frame = 0;
		}
		
		scale = 0.4 - (0.1*(frame/5));
		ObjRender_SetScaleXYZ(bgEffect, scale, -scale, scale);
		
		yield;
		
	}
	
	scale2 = 0.4;
	
	loop(40){
		
		scale2 -= (0.4 - (0.1*(frame/5)))/40;
		
		ObjRender_SetScaleX(bgEffect, scale2);
		ObjMove_SetDestAtFrame(bgPos, GetPlayerX, GetPlayerY, travelTime);
		ObjRender_SetX(bgEffect, ObjMove_GetX(bgPos));
		ObjRender_SetY(bgEffect, ObjMove_GetY(bgPos));
		
		focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		if(focus){
			frame++;
		}
		
		if(!focus){
			frame--;
		}
		
		if(frame > 5){
			frame = 5;
		}
		
		if(frame < 0){
			frame = 0;
		}
		
		scale = 0.4 - (0.1*(frame/5));
		ObjRender_SetScaleY(bgEffect, -scale);
		
		yield;
	}
	
	Obj_Delete(bgEffect);
}

task Option(id, xn, yn, xf, yf, dirN, dirF, dmgN, dmgF, shotNum, color){
	
	let option = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(option, BLEND_ALPHA);
	Obj_SetRenderPriority(option, 0.31);
	ObjPrim_SetTexture(option, GetCurrentScriptDirectory() ~ "img/option.png");
	ObjSprite2D_SetDestRect(option, -40, -40, 40, 40);
	ObjRender_SetScaleXYZ(option, 0, 0, 0);
	ObjRender_SetX(option, GetPlayerX + xn);
	ObjRender_SetY(option, GetPlayerY + yn);
	ObjRender_SetAlpha(option, 150);
	
	let travelTime = 2;
	
	if(shotType == 2){
		travelTime = 2;
	}
	
	let optionPos = CreateShotA1(GetPlayerX + xn, GetPlayerY + yn, 0, 0, 0, 0);
	ObjShot_SetIntersectionEnable(optionPos, false);
	ObjShot_SetAutoDelete(optionPos, false);
	
	let angleAdd = 5;
	
	if(color == 1){
		ObjSprite2D_SetSourceRect(option, 0, 256, 80, 336);
	}
	
	if(color == 2){
		ObjSprite2D_SetSourceRect(option, 80, 256, 160, 336);
		angleAdd = -angleAdd;
	}
	
	let z = 0 - (angleAdd*20);
	let scale = 0;
	let count = 0;
	
	let frame = 0;
	let frame2 = -1;
	let frame3 = 0;
	
	let frame4 = 0;
	let frame5 = 0;
	
	let offSetTime = 40;
	
	let zOffSetAdd = rand(-0.2, 0.2);
	let zOffSet = 0;
	
	let offSetDir = rand(0, 360);
	let offSet = 0;
	
	let shotColor = 1;
	if(color == 2){shotColor = 3;}
	
	if(shotType == 3){
		if(color == 1){shotColor = 9;}
		if(color == 2){shotColor = 9;}
	}
	
	let shotSpace = 3;
	
	if(shotType == 2){
		shotSpace = 5;
	}
	
	if(shotType == 3){
		shotSpace = 7;
	}
	
	let fall = false;
	let dir2 = 270;
	
	if(id == 1 || id == 3){
		fall = true;
		dir2 = 270;
	}
	
	let laserDir = 270;
	let lFall = false;
	let lAdd = 0.02;
	
	if(color == 2){lFall = true;}
	if(id == 2 || id == 4){lAdd = -lAdd;}
	
	let l = false;
	
	yield;
	
	while(optionsAlive && playerAlive){
		
		let focus = GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD;
		
		ObjRender_SetScaleXYZ(option, scale, scale, scale);
		ObjRender_SetAngleZ(option, z);
		ObjRender_SetX(option, ObjMove_GetX(optionPos));
		ObjRender_SetY(option, ObjMove_GetY(optionPos));
		
		if(id == 1){o1x = ObjRender_GetX(option); o1y = ObjRender_GetY(option);}
		if(id == 2){o2x = ObjRender_GetX(option); o2y = ObjRender_GetY(option);}
		if(id == 3){o3x = ObjRender_GetX(option); o3y = ObjRender_GetY(option);}
		if(id == 4){o4x = ObjRender_GetX(option); o4y = ObjRender_GetY(option);}
		
		if(count <= 21){
			count++;
		}
		
		if(count <= 20){
			z += angleAdd;
			scale += 0.3/20;
		}
		
		if(focus){
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX + xf, GetPlayerY + yf, travelTime);
		}
		else{
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX + xn, GetPlayerY + yn, travelTime);
		}
		
		frame++;
		
		if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD){
			if(!focus){
				
				if(shotType == 1 || shotType == 3){
					if(frame >= 5){
						let dir = dirN;
						
						if(dirN > 270){dir -= ((shotNum - 1)*shotSpace);}
						if(dirN < 270){dir += ((shotNum - 1)*shotSpace);}
						
						loop(shotNum){
							if(IsPermitPlayerShot){
								BasicShotBullet(ObjRender_GetX(option), ObjRender_GetY(option), 20, dir, dmgN, shotColor);
							}
							
							if(dirN > 270){dir += shotSpace;}
							if(dirN < 270){dir -= shotSpace;}
						}
						
						lasersSpawned = false;
						frame3 = 0;
						l = false;
						
						frame = 0;
					}
				}
				
				if(shotType == 2){
					if(frame >= 60 && IsPermitPlayerShot){
						
						ObjSound_Play(laserFireSound);
						LaserGlow(id, 2, 10);
						
						let dir = dirN;
						
						if(color == 1){
							if(dirN < 90){dir -= ((shotNum - 1)*shotSpace);}
							if(dirN > 90){dir += ((shotNum - 1)*shotSpace);}
							if(dirN == 90){dir -= 7;}
						}
						
						if(color == 2){
							if(dirN < 270){dir -= ((shotNum - 1)*shotSpace);}
							if(dirN > 270){dir += ((shotNum - 1)*shotSpace);}
						}
						
						loop(shotNum){
							Laser2(ObjRender_GetX(option), ObjRender_GetY(option), dir, dmgN);
							
							if(color == 1){
								if(dirN < 90){dir += shotSpace;}
								if(dirN > 90){dir -= shotSpace;}
								if(dirN == 90){dir += 7;}
							}
							
							if(color == 2){
								if(dirN < 270){dir += shotSpace;}
								if(dirN > 270){dir -= shotSpace;}
							}
						}
						
						frame = 0;
					}
					
					lasersSpawned = false;
					frame3 = 0;
					l = false;
				}
			}
			
			if(focus){
				
				if(shotType == 1){
					if(!l && IsPermitPlayerShot && playerAlive){
						
						l = true;
						lasersSpawned = true;
						
						Laser(id, 256*cos(dirF), 256*sin(dirF), dirF, 1, false);
						LaserGlow(id, 1, 0);
					}
					
					if(IsPermitPlayerShot && playerAlive){
						
						let b = ID_INVALID;
						
						let dmg = dmgF;
						if(playerSpellActive){dmg = dmg/4;}
						
						b = CreatePlayerShotA1(ObjRender_GetX(option), ObjRender_GetY(option), 55, dirF, dmg, 10000, 1);
						Obj_SetVisible(b, false);
					}
					
					frame3++;
					
					if(frame3 >= 10 && IsPermitPlayerShot && playerAlive){
						ObjSound_Play(laserSound);
						frame3 = 0;
					}
					
					frame = 0;
				}
				
				if(shotType == 2){
					
					if(!l && IsPermitPlayerShot && playerAlive){
						
						laserDir = 270;
						
						l = true;
						lasersSpawned = true;
						
						Laser(id, 256*cos(dirF), 256*sin(dirF), dirF, 2, true);
						LaserGlow(id, 3, 0);
					}
					
					if(IsPermitPlayerShot && playerAlive){
						
						if(!lFall){laserDir += lAdd;}
						if(lFall){laserDir -= lAdd;}
						if(laserDir >= 272 || laserDir <= 268){lFall = !lFall;}
						
						let b = ID_INVALID;
						
						let dmg = dmgF/2;
						if(playerSpellActive){dmg = dmg/4;}
						
						b = CreatePlayerShotA1(ObjRender_GetX(option), ObjRender_GetY(option), 55, laserDir, dmg, 10000, 1);
						Obj_SetVisible(b, false);
					}
					
					frame3++;
					
					if(frame3 >= 10 && IsPermitPlayerShot && playerAlive){
						ObjSound_Play(laserSound);
						frame3 = 0;
					}
					
					if(frame >= 5){
						if(IsPermitPlayerShot){
							
							let range = 10;
							let dirAdd = 1;
							
							if(color == 2){dirAdd = 0.8; range = 8;}
							
							if(dir2 >= 270 + range){fall = true;}
							if(dir2 <= 270 - range){fall = false;}
							
							if(!fall){
								dir2 += dirAdd;
							}
							
							if(fall){
								dir2 -= dirAdd;
							}
							
							let dir = dir2 - 60;
							
							loop(3){
								BasicShotBullet(ObjRender_GetX(option), ObjRender_GetY(option), 10, dir, dmgF, 12);
								dir += 60;
							}
						}
						frame = 0;
					}
				}
				
				if(shotType == 3){
					if(frame >= 5 && IsPermitPlayerShot){
						
						let dir = dirF;
						
						if(dirN > 270){dir -= 4;}
						if(dirN < 270){dir += 4;}
						
						loop(2){
							BasicShotBullet(ObjRender_GetX(option), ObjRender_GetY(option), 20, dir, dmgF, 10);
							
							if(dirN > 270){dir += 8;}
							if(dirN < 270){dir -= 8;}
						}
						frame = 0;
					}
				}
			}
		}
		else{
			lasersSpawned = false;
			frame3 = 0;
			l = false;
		}
		
		if(count > 20){frame2++;}
		
		if(frame2 <= offSetTime && frame2 != -1){
			
			zOffSet += zOffSetAdd;
			offSet += 0.04;
			
			ObjRender_SetX(option, ObjMove_GetX(optionPos) + offSet*cos(offSetDir));
			ObjRender_SetY(option, ObjMove_GetY(optionPos) + offSet*sin(offSetDir));
			ObjRender_SetAngleZ(option, zOffSet);
		}
		
		if(frame2 > offSetTime){
			
			zOffSet -= zOffSetAdd;
			offSet -= 0.04;
			
			ObjRender_SetX(option, ObjMove_GetX(optionPos) + offSet*cos(offSetDir));
			ObjRender_SetY(option, ObjMove_GetY(optionPos) + offSet*sin(offSetDir));
			ObjRender_SetAngleZ(option, zOffSet);
		}
		
		if(frame2 >= (offSetTime*2)){
			offSetDir = rand(0, 360);
			zOffSetAdd = rand(-0.2, 0.2);
			frame2 = 0;
		}
		
		yield;
	}
	
	scale = 0.3;
	z = 0;
	
	loop(20){
		
		scale -= 0.3/20;
		z -= angleAdd;
		
		ObjRender_SetScaleXYZ(option, scale, scale, scale);
		ObjRender_SetAngleZ(option, z);
		
		ObjRender_SetX(option, ObjMove_GetX(optionPos));
		ObjRender_SetY(option, ObjMove_GetY(optionPos));
		
		if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD){
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX + xf, GetPlayerY + yf, travelTime);
		}
		else{
			ObjMove_SetDestAtFrame(optionPos, GetPlayerX + xn, GetPlayerY + yn, travelTime);
		}
		
		yield;
	}
	
	Obj_Delete(option);
}

task Laser(id, x, y, dir, color, shiftAngle){
	
	let laser = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(laser, BLEND_ALPHA);
	Obj_SetRenderPriority(laser, 0.56);
	ObjPrim_SetTexture(laser, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjSprite2D_SetDestRect(laser, -256, -8, 256, 8);
	ObjRender_SetAngleZ(laser, dir);
	ObjRender_SetAlpha(laser, 200);
	
	let spriteY1 = 0;
	let spriteY2 = 16;
	
	if(color == 2){
		ObjSprite2D_SetDestRect(laser, -256, -6, 256, 6);
		ObjRender_SetAlpha(laser, 96);
		spriteY1 = 96;
		spriteY2 = 128;
	}
	
	if(shiftAngle){
		dir = 270;
	}
	
	let fall = false;
	let dirAdd = 0.02;
	
	if(id == 3 || id == 4){
		fall = true;
	}
	
	if(id == 2 || id == 4){
		dirAdd = -dirAdd;
	}
	
	let spriteX = 0;
	let scale = 0;
	
	while(lasersSpawned && IsPermitPlayerShot && playerAlive && optionsAlive){
		ObjSprite2D_SetSourceRect(laser, spriteX + 256, spriteY1, spriteX, spriteY2);
		ObjRender_SetScaleXYZ(laser, 1, scale, 1);
		
		if(id == 1){ObjRender_SetX(laser, o1x + x); ObjRender_SetY(laser, o1y + y);}
		if(id == 2){ObjRender_SetX(laser, o2x + x); ObjRender_SetY(laser, o2y + y);}
		if(id == 3){ObjRender_SetX(laser, o3x + x); ObjRender_SetY(laser, o3y + y);}
		if(id == 4){ObjRender_SetX(laser, o4x + x); ObjRender_SetY(laser, o4y + y);}
		
		if(shiftAngle){
			if(id == 1){ObjRender_SetX(laser, o1x + 256*cos(dir)); ObjRender_SetY(laser, o1y + 256*sin(dir));}
			if(id == 2){ObjRender_SetX(laser, o2x + 256*cos(dir)); ObjRender_SetY(laser, o2y + 256*sin(dir));}
			if(id == 3){ObjRender_SetX(laser, o3x + 256*cos(dir)); ObjRender_SetY(laser, o3y + 256*sin(dir));}
			if(id == 4){ObjRender_SetX(laser, o4x + 256*cos(dir)); ObjRender_SetY(laser, o4y + 256*sin(dir));}
			
			ObjRender_SetAngleZ(laser, dir);
			
			if(!fall){dir += dirAdd;}
			if(fall){dir -= dirAdd;}
			if(dir >= 272 || dir <= 268){fall = !fall;}
		}
		
		spriteX += 8;
		
		if(spriteX >= 256){
			spriteX = 0;
		}
		
		if(scale < 1){
			scale += 0.1;
		}
		
		yield;
	}
	
	while(scale > 0){
		scale -= 0.1;
		
		if(id == 1){ObjRender_SetX(laser, o1x + x); ObjRender_SetY(laser, o1y + y);}
		if(id == 2){ObjRender_SetX(laser, o2x + x); ObjRender_SetY(laser, o2y + y);}
		if(id == 3){ObjRender_SetX(laser, o3x + x); ObjRender_SetY(laser, o3y + y);}
		if(id == 4){ObjRender_SetX(laser, o4x + x); ObjRender_SetY(laser, o4y + y);}
		
		if(shiftAngle){
			if(id == 1){ObjRender_SetX(laser, o1x + 256*cos(dir)); ObjRender_SetY(laser, o1y + 256*sin(dir));}
			if(id == 2){ObjRender_SetX(laser, o2x + 256*cos(dir)); ObjRender_SetY(laser, o2y + 256*sin(dir));}
			if(id == 3){ObjRender_SetX(laser, o3x + 256*cos(dir)); ObjRender_SetY(laser, o3y + 256*sin(dir));}
			if(id == 4){ObjRender_SetX(laser, o4x + 256*cos(dir)); ObjRender_SetY(laser, o4y + 256*sin(dir));}
			
			ObjRender_SetAngleZ(laser, dir);
			
			if(!fall){dir += dirAdd;}
			if(fall){dir -= dirAdd;}
			if(dir >= 272){fall = true;}
			if(dir <= 268){fall = false;}
		}
		
		spriteX += 8;
		
		if(spriteX >= 256){
			spriteX = 0;
		}
		
		ObjSprite2D_SetSourceRect(laser, spriteX + 256, spriteY1, spriteX, spriteY2);
		ObjRender_SetScaleXYZ(laser, 1, scale, 1);
		
		yield;
	}
	
	Obj_Delete(laser);
}

task Laser2(x, y, dir, dmg){
	
	let spd = 8;
	let size = 100;
	let width = 20;
	
	let l = CreateLooseLaserA1(x, y, spd, dir, size, width, 11, 5);
	ObjStLaser_SetSource(l, true);
	ObjShot_SetDamage(l, dmg);
	
	let b = false;
	
	while(!Obj_IsDeleted(l)){
		if(ObjMove_GetY(l) < 0 || ObjMove_GetY(l) > 448){
			if(!b){
				let l2 = CreateLooseLaserA1(ObjMove_GetX(l), ObjMove_GetY(l), spd, -dir, size, width, 11, 5);
				ObjStLaser_SetSource(l2, true);
				ObjShot_SetDamage(l2, dmg);
				
				b = true;
			}
		}
		
		if(ObjMove_GetX(l) < 0 || ObjMove_GetX(l) > 384){
			if(!b){
				let l2 = CreateLooseLaserA1(ObjMove_GetX(l), ObjMove_GetY(l), spd, -dir + 180, size, width, 11, 5);
				ObjStLaser_SetSource(l2, true);
				ObjShot_SetDamage(l2, dmg);
				
				b = true;
			}
		}
		
		yield;
	}
}

task LaserGlow(id, color, time){
	
	let glow = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(glow, BLEND_ADD_RGB);
	Obj_SetRenderPriority(glow, 0.57);
	ObjPrim_SetTexture(glow, GetCurrentScriptDirectory() ~ "img/effect.png");
	ObjSprite2D_SetDestRect(glow, -16, -16, 16, 16);
	
	if(color == 1){
		ObjSprite2D_SetSourceRect(glow, 128, 104, 160, 136);
	}
	
	if(color == 2){
		ObjSprite2D_SetSourceRect(glow, 32, 104, 64, 136);
	}
	
	if(color == 3){
		ObjSprite2D_SetSourceRect(glow, 0, 104, 32, 136);
	}
	
	let frame = 0;
	let scale = 0;
	
	while(IsPermitPlayerShot && playerAlive && optionsAlive){
		ObjRender_SetScaleXYZ(glow, scale, scale, scale);
		
		if(id == 1){ObjRender_SetX(glow, o1x); ObjRender_SetY(glow, o1y);}
		if(id == 2){ObjRender_SetX(glow, o2x); ObjRender_SetY(glow, o2y);}
		if(id == 3){ObjRender_SetX(glow, o3x); ObjRender_SetY(glow, o3y);}
		if(id == 4){ObjRender_SetX(glow, o4x); ObjRender_SetY(glow, o4y);}
		
		if(scale < 0.6){
			scale += 0.2;
		}
		
		if(time == 0 && !lasersSpawned){
			break;
		}
		
		if(time > 0){
			frame++;
			
			if(frame >= time){
				break;
			}
		}
		
		yield;
	}
	
	while(scale > 0){
		scale -= 0.05;
		
		if(id == 1){ObjRender_SetX(glow, o1x); ObjRender_SetY(glow, o1y);}
		if(id == 2){ObjRender_SetX(glow, o2x); ObjRender_SetY(glow, o2y);}
		if(id == 3){ObjRender_SetX(glow, o3x); ObjRender_SetY(glow, o3y);}
		if(id == 4){ObjRender_SetX(glow, o4x); ObjRender_SetY(glow, o4y);}
		ObjRender_SetScaleXYZ(glow, scale, scale, scale);
		
		yield;
	}
	
	Obj_Delete(glow);
}

task Spell(focus){
	
	let spellObject = GetSpellManageObject;
	playerSpellActive = true;
	
	SpellUseCutIn(GetCurrentScriptDirectory ~ "img/cutIn.png", 0, 0, 359, 512, 0.5);
	ObjSound_Play(spellUseSound);
	
	if(shotType == 1){
		SetPlayerInvincibilityFrame(460);
		SetPlayerSpeed(0.6, 0.6);
		MagicCircle(460);
	}
	
	if(!focus){
		if(shotType == 1){
			SetPlayerInvincibilityFrame(380);
			SpellUseName("Magic \"Makai Butterfly\"");
			SetForbidPlayerSpell(true);
			SpellBackground(1);
			loop(400){yield;}
			SetForbidPlayerSpell(false);
		}
		
		if(shotType == 2){
			SetPlayerInvincibilityFrame(580);
			SetPlayerSpeed(0.6, 0.6);
			MagicCircle(580);
			
			SpellUseName("Flying Object \"Legendary Flying Saucer\"");
			SpellBackground(3);
			loop(580){yield;}
		}
		
		if(shotType == 3){
			SetPlayerInvincibilityFrame(600);
			MagicCircle(600);
			
			SpellUseName("Superhuman \"Byakuren Hijiri\"");
			Spellcard(1);
			
			loop(480){yield;}
		}
	}
	
	if(focus){
		if(shotType == 1){
			SpellUseName("Light Magic \"Magic Milky Way\"");
			SetForbidPlayerSpell(true);
			SpellBackground(2);
			MagicCircle(400);
			SetPlayerInvincibilityFrame(400);
			loop(400){yield;}
			SetForbidPlayerSpell(false);
		}
		
		if(shotType == 2){
			SetPlayerInvincibilityFrame(700);
			SetPlayerSpeed(0.6, 0.6);
			MagicCircle(700);
			
			SpellUseName("Great Magic \"Devil's Recitation\"");
			SpellBackground(4);
			loop(660){yield;}
		}
		
		if(shotType == 3){
			SetPlayerSpeed(0.6, 0.6);
			
			SetPlayerInvincibilityFrame(420);
			MagicCircle(420);
			
			SpellUseName("Omen \"Cloudy Way in Purple\"");
			Spellcard(2);
			
			loop(300){yield;}
		}
	}
	
	SetPlayerSpeed(4, 1.8);
	playerSpellActive = false;
	Obj_Delete(spellObject);
}

task SpellBackground(type){
	
	let bgEffect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(bgEffect, BLEND_ALPHA);
	Obj_SetRenderPriority(bgEffect, 0.27);
	ObjPrim_SetTexture(bgEffect, GetCurrentScriptDirectory() ~ "img/option.png");
	ObjSprite2D_SetDestRect(bgEffect, -192, -128, 192, 128);
	ObjSprite2D_SetSourceRect(bgEffect, 0, 0, 384, 256);
	ObjRender_SetScaleXYZ(bgEffect, 0, -0.8, 0.8);
	
	ObjRender_SetX(bgEffect, GetPlayerX);
	ObjRender_SetY(bgEffect, GetPlayerY);
	
	let scale = 0;
	
	loop(40){
		
		scale += 0.8/40;
		
		ObjRender_SetScaleX(bgEffect, scale);
		ObjRender_SetX(bgEffect, GetPlayerX);
		ObjRender_SetY(bgEffect, GetPlayerY);
		
		yield;
	}
	
	let fall = false;
	
	loop(20){
		ObjRender_SetX(bgEffect, GetPlayerX);
		ObjRender_SetY(bgEffect, GetPlayerY);
		
		if(!fall){ObjRender_SetScaleX(bgEffect, ObjRender_GetScaleX(bgEffect) + 0.005);}
		if(fall){ObjRender_SetScaleX(bgEffect, ObjRender_GetScaleX(bgEffect) - 0.005);}
		if(ObjRender_GetScaleX(bgEffect) <= 0.75){fall = false;}
		if(ObjRender_GetScaleX(bgEffect) >= 0.85){fall = true;}
		
		yield;
	}
	
	SpellOption(1, type, 1, 50, 70);
	SpellOption(2, type, 1, -50, 70);
	
	SpellOption(3, type, 2, 90, -35);
	SpellOption(4, type, 2, -90, -35);
	
	let time = 300;
	
	if(type == 3){
		time = 420;
	}
	
	if(type == 4){
		time = 540;
	}
	
	loop(time){
		ObjRender_SetX(bgEffect, GetPlayerX);
		ObjRender_SetY(bgEffect, GetPlayerY);
		
		if(!fall){ObjRender_SetScaleX(bgEffect, ObjRender_GetScaleX(bgEffect) + 0.001);}
		if(fall){ObjRender_SetScaleX(bgEffect, ObjRender_GetScaleX(bgEffect) - 0.001);}
		if(ObjRender_GetScaleX(bgEffect) <= 0.75){fall = false;}
		if(ObjRender_GetScaleX(bgEffect) >= 0.85){fall = true;}
		
		yield;
	}
	
	scale = 0.8;
	
	loop(40){
		
		scale -= 0.8/40;
		
		ObjRender_SetScaleX(bgEffect, scale);
		ObjRender_SetX(bgEffect, GetPlayerX);
		ObjRender_SetY(bgEffect, GetPlayerY);
		
		yield;
	}
	
	Obj_Delete(bgEffect);
}

task SpellOption(id, type, color, xOff, yOff){
	
	let spellOption = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(spellOption, BLEND_ALPHA);
	Obj_SetRenderPriority(spellOption, 0.28);
	ObjPrim_SetTexture(spellOption, GetCurrentScriptDirectory() ~ "img/option.png");
	ObjSprite2D_SetDestRect(spellOption, -40, -40, 40, 40);
	ObjRender_SetX(spellOption, GetPlayerX + xOff);
	ObjRender_SetY(spellOption, GetPlayerY + yOff);
	
	let dir = atan2(-yOff, -xOff);
	
	let angleAdd = 5;
	
	if(color == 1){
		ObjSprite2D_SetSourceRect(spellOption, 0, 256, 80, 336);
		angleAdd = -angleAdd;
	}
	
	if(color == 2){
		ObjSprite2D_SetSourceRect(spellOption, 80, 256, 160, 336);
	}
	
	let z = 0 - (angleAdd*20);
	
	let scale = 0;
	
	loop(20){
		
		scale += 0.8/20;
		z += angleAdd;
		
		ObjRender_SetScaleXYZ(spellOption, scale, scale, scale);
		ObjRender_SetAngleZ(spellOption, z);
		
		ObjRender_SetX(spellOption, GetPlayerX + xOff);
		ObjRender_SetY(spellOption, GetPlayerY + yOff);
		
		yield;
	}
	
	let frame = 0;
	let frame2 = 0;
	let frame3 = 0;
	
	let offSetTime = 40;
	
	let zOffSetAdd = rand(-0.5, 0.5);
	let zOffSet = 0;
	
	let offSetDir = rand(0, 360);
	let offSet = 0;
	
	let dirAdd = 5;
	
	if(xOff > 0){
		dirAdd = -dirAdd;
	}
	
	let fall = false;
	let dir2 = 260;
	
	if(id == 1 || id == 3){
		fall = true;
		dir2 = 280;
	}
	
	let laserEffect = ID_INVALID;
	let laser = ID_INVALID;
	
	let lFrame = 0;
	
	let lDir = 270;
	let lFall = false;
	let lAdd = 0.1;
	
	let lScale = 0;
	let spriteX = 0;
	
	if(id == 3 || id == 4){
		lFall = true;
	}
	
	if(id == 2 || id == 4){
		lAdd = -lAdd;
	}
	
	let dirAdd2 = 0.4;
	let color2 = 13;
	let c = 24;
	
	if(id == 2 || id == 4){
		dirAdd2 = -dirAdd2;
	}
	
	let time = 240;
	
	if(type == 3){
		time = 360;
	}
	
	if(type == 4){
		time = 480;
	}
	
	loop(time){
		
		let cx = GetPlayerX + xOff;
		let cy = GetPlayerY + yOff;
		
		frame++;
		frame2++;
		
		if(type == 1 && frame >= 4){
			
			ObjSound_Play(spellShotSound);
			
			loop(4){
				SpellShot(ObjRender_GetX(spellOption), ObjRender_GetY(spellOption), 8, dir, 3, 5, false, true);
				dir += 90;
			}
			
			frame = 0;
			
			dir += dirAdd;
		}
		
		if(type == 2 && frame >= 4){
			ObjSound_Play(spellShotSound);
			SpellShot(ObjRender_GetX(spellOption), ObjRender_GetY(spellOption), 10, rand(250, 290), 5, 4, true, true);
			frame = 0;
		}
		
		if(type == 3 && frame == 1){
			dir = rand(0, 360);
			ObjSound_Play(spellShotSound);
			
			let clearShots = false;
			
			if(color2 == 15){clearShots = true};
			
			loop(c){
				if(IsPermitPlayerSpell){SpellShot3(ObjRender_GetX(spellOption), ObjRender_GetY(spellOption), dir, dirAdd2, color2, clearShots);}
				dir += 360/c;
			}
			
			color2++;
			c += 8;
		}
		
		if(type == 3 && frame >= 120){
			frame = 0;
		} 
		
		if(type == 4 && frame >= 2){
			
			frame3++;
			
			let c = 1;
			
			if(frame3 >= 20){c = 2;}
			if(frame3 >= 80){c = 3;}
			
			if(frame3 == 80){
				fall = false;
				dir2 = 260;
				
				if(id == 1 || id == 3){
					fall = true;
					dir2 = 280;
				}
			}
			
			let range = 25;
			let dirAdd = 1;
			let baseDir = 260;
			
			if(id == 1 || id == 3){baseDir = 280;}
			if(id == 3 || id == 4){dirAdd = 0.6; range = 15;}
			
			if(dir2 >= baseDir + range){fall = true;}
			if(dir2 <= baseDir - range){fall = false;}
			
			if(!fall){
				dir2 += dirAdd;
			}
			
			if(fall){
				dir2 -= dirAdd;
			}
			
			let dir3 = dir2 - 60;
			
			if(frame3 < 20){
				dir3 = 90;
			}
			
			if(frame3 >= 20 && frame3 < 80){
				dir3 = 90 + (120*((frame3 - 20)/60));
			}
			
			ObjSound_Play(spellShotSound);
			
			loop(c){
				if(IsPermitPlayerSpell){SpellShot(ObjRender_GetX(spellOption), ObjRender_GetY(spellOption), 10, dir3, 2, 17, false, true);}
				dir3 += 60;
				
				if(frame3 >= 20 && frame3 < 80){
					dir3 = 90 - (120*((frame3 - 20)/60));
				}
			}
			
			frame = 0;
		}
		
		if(frame3 == 80){
			laser = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(laser, BLEND_ALPHA);
			Obj_SetRenderPriority(laser, 0.57);
			ObjPrim_SetTexture(laser, GetCurrentScriptDirectory() ~ "img/shot.png");
			ObjSprite2D_SetDestRect(laser, -300, -16, 300, 16);
			ObjRender_SetScaleXYZ(laser, 1, 0.1, 1);
			ObjRender_SetAngleZ(laser, 270);
			
			laserEffect = ObjPrim_Create(OBJ_SPRITE_2D);
			ObjRender_SetBlendType(laserEffect, BLEND_ALPHA);
			Obj_SetRenderPriority(laserEffect, 0.58);
			ObjPrim_SetTexture(laserEffect, GetCurrentScriptDirectory() ~ "img/shot.png");
			ObjSprite2D_SetSourceRect(laserEffect, 0, 128, 124, 272);
			ObjRender_SetAngleZ(laserEffect, 270);
		}
		
		if(frame3 > 80 && frame3 < 110){
			ObjSprite2D_SetSourceRect(laser, spriteX + 256, 96, spriteX, 128);
			ObjRender_SetX(laser, ObjRender_GetX(spellOption) + 256*cos(lDir));
			ObjRender_SetY(laser, ObjRender_GetY(spellOption) + 256*sin(lDir));
			
			spriteX += 8;
			
			if(spriteX >= 256){
				spriteX = 0;
			}
		}
		
		if(frame3 > 80){
			ObjRender_SetX(laserEffect, ObjRender_GetX(spellOption));
			ObjRender_SetY(laserEffect, ObjRender_GetY(spellOption));
			ObjRender_SetAngleZ(laserEffect, lDir);
			
			lFrame++;
			
			if(lFrame == 1){
				ObjSprite2D_SetDestRect(laserEffect, 0, -72, 124, 72);
				ObjSprite2D_SetSourceRect(laserEffect, 0, 128, 123, 272);
			}
			
			if(lFrame == 2){
				ObjSprite2D_SetDestRect(laserEffect, 0, -72, 132, 72);
				ObjSprite2D_SetSourceRect(laserEffect, 124, 128, 255, 272);
			}
			
			if(lFrame >= 3){
				lFrame = 0;
			}
		}
		
		if(frame3 == 110){
			ObjSound_Play(spellLaserSound);
		}
		
		if(frame3 >= 110 && frame3 <= 225){
			ObjSprite2D_SetSourceRect(laser, spriteX + 256, 96, spriteX, 128);
			ObjRender_SetScaleXYZ(laser, 1, lScale, lScale);
			ObjRender_SetX(laser, ObjRender_GetX(spellOption) + 300*cos(lDir));
			ObjRender_SetY(laser, ObjRender_GetY(spellOption) + 300*sin(lDir));
			
			ObjRender_SetAngleZ(laser, lDir);
			
			if(!lFall){lDir += lAdd;}
			if(lFall){lDir -= lAdd;}
			if(lDir >= 275 || lDir <= 265){lFall = !lFall;}
			
			spriteX += 8;
			
			if(spriteX >= 256){
				spriteX = 0;
			}
			
			if(lScale < 1){
				lScale += 0.05;
			}
			
			if(IsPermitPlayerSpell){SpellShot(ObjRender_GetX(spellOption), ObjRender_GetY(spellOption), 50, lDir, 4, 6, false, false);}
		}
		
		if(frame3 > 225){
			ObjRender_SetScaleXYZ(laserEffect, 1, lScale, lScale);
			ObjRender_SetScaleXYZ(laser, 1, lScale, lScale);
			
			lScale -= 1/30;
		}
		
		if(frame2 <= offSetTime){
			
			zOffSet += zOffSetAdd;
			offSet += 0.1;
			
			ObjRender_SetX(spellOption, cx + offSet*cos(offSetDir));
			ObjRender_SetY(spellOption, cy + offSet*sin(offSetDir));
			ObjRender_SetAngleZ(spellOption, zOffSet);
		}
		
		if(frame2 > offSetTime){
			
			zOffSet -= zOffSetAdd;
			offSet -= 0.1;
			
			ObjRender_SetX(spellOption, cx + offSet*cos(offSetDir));
			ObjRender_SetY(spellOption, cy + offSet*sin(offSetDir));
			ObjRender_SetAngleZ(spellOption, zOffSet);
		}
		
		if(frame2 >= (offSetTime*2)){
			offSetDir = rand(0, 360);
			zOffSet = rand(-0.5, 0.5);
			frame2 = 0;
		}
		
		yield;
	}
	
	Obj_Delete(laserEffect);
	Obj_Delete(laser);
	
	scale = 0.8;
	z = 0;
	
	loop(20){
		
		scale -= 0.8/20;
		z -= angleAdd;
		
		ObjRender_SetScaleXYZ(spellOption, scale, scale, scale);
		ObjRender_SetAngleZ(spellOption, z);
		
		ObjRender_SetX(spellOption, GetPlayerX + xOff);
		ObjRender_SetY(spellOption, GetPlayerY + yOff);
		
		yield;
	}
	
	Obj_Delete(spellOption);
}

task SpellShot(x, y, spd, dir, dmg, color, trail, visible){
	 
		let b = ID_INVALID;
		b = CreatePlayerShotA1(x, y, spd, dir, dmg, 10000, color); 
		ObjShot_SetEraseShot(b, true);
		Obj_SetVisible(b, visible);
		
		let frame = 0;
		
		while(!Obj_IsDeleted(b) && trail){
			
			frame++;
			
			if(frame >= round(rand(2, 16))){
				SpellShotTrail(ObjMove_GetX(b), ObjMove_GetY(b), ObjRender_GetAngleZ(b));
				frame = 0;
			}
			
			yield;
		}
}

task SpellShotTrail(x, y, angle){
	while(!IsPermitPlayerShot){yield;}
	
	let trailEffect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(trailEffect, BLEND_ADD_RGB);
	Obj_SetRenderPriority(trailEffect, 0.25);
	ObjPrim_SetTexture(trailEffect, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjSprite2D_SetDestRect(trailEffect, -32, -32, 32, 32);
	ObjSprite2D_SetSourceRect(trailEffect, 64, 32, 96, 64);
	ObjRender_SetScaleXYZ(trailEffect, 0.5, 0.5, 0.5);
	ObjRender_SetAngleZ(trailEffect, angle);
	ObjRender_SetX(trailEffect, x);
	ObjRender_SetY(trailEffect, y);
	
	let color = 96;
	
	while(color > 0){
		
		color -= 8;
		
		ObjRender_SetColor(trailEffect, color, color, color);
		
		yield;
	}
	
	Obj_Delete(trailEffect);
}

task SpellShot3(x, y, dir, dirAdd, color, clearShots){
	let b = ID_INVALID;
	b = CreatePlayerShotA1(x, y, 1, dir + 90, 2, 10000, color);
	ObjShot_SetEraseShot(b, clearShots);
	
	let r = 0;
	
	loop(120){
		ObjMove_SetX(b, x + r*cos(dir));
		ObjMove_SetY(b, y + r*sin(dir));
		ObjMove_SetAngle(b, dir + 70);
		
		dir += dirAdd;
		r += 1;
		
		yield;
	}
	
	yield;
	
	let yAdd = 0;
	
	while(!Obj_IsDeleted(b)){
		ObjMove_SetX(b, x + r*cos(dir));
		ObjMove_SetY(b, y + r*sin(dir) - yAdd);
		ObjMove_SetAngle(b, dir + 70);
		
		dir += dirAdd;
		yAdd += 0.2;
		r += 1;
		
		yield;
	}
}

task Spellcard(type){
	
	if(type == 1){
		SetPlayerSpeed(6, 2.7);
		
		let frame = 0;
		
		let dirChanged = false;
		
		let x = GetPlayerX;
		let y = GetPlayerY;
		
		let playerMoving = false;
		let playerAngle = 0;
		let prevAngle = 0;
		
		let spd = 1.5;
		
		loop(480){
			
			if(dirChanged){
				ObjSound_Play(spellShotSound);
				ObjSound_Play(spellMoveSound);
				
				spd += 0.2;
				
				if(spd > 6){
					spd = 6;
				}
				
				loop(2){
					if(IsPermitPlayerSpell){
						let b = ID_INVALID;
						b = CreatePlayerShotA1(GetPlayerX, GetPlayerY, 0, 0, spd*15, 10000, 16); 
						ObjShot_SetEraseShot(b, true);
						ObjShot_SetDeleteFrame(b, 1);
						Obj_SetVisible(b, false);
					}
				}
				
				dirChanged = false;
			}
			
			if(playerMoving && IsPermitPlayerSpell){
				let b = ID_INVALID;
				b = CreatePlayerShotA1(GetPlayerX, GetPlayerY, 0, 0, spd*15, 10000, 6);
				ObjShot_SetEraseShot(b, true);
				ObjShot_SetDeleteFrame(b, 1);
				Obj_SetVisible(b, false);
				
				let b2 = ID_INVALID;
				b2 = CreatePlayerShotA1(GetPlayerX, GetPlayerY, 0, 0, 0, 10000, 16);
				ObjShot_SetEraseShot(b2, true);
				ObjShot_SetDeleteFrame(b2, 1);
				Obj_SetVisible(b2, false);
			}
			
			SetPlayerSpeed(4*spd, 4*spd);
			
			if(!playerMoving){
				spd = 1.5;
			}
			
			if(playerMoving){
				frame++;
				
				if(frame >= 1){
					TrailEffect;
					frame = 0;
				}
			}
			
			x = GetPlayerX;
			y = GetPlayerY;
			
			prevAngle = playerAngle;
			
			yield;
			
			if(x != GetPlayerX || y != GetPlayerY){
				playerMoving = true;
			}
			else{
				playerMoving = false;
			}
			
			playerAngle = atan2(GetPlayerY - y, GetPlayerX - x);
			
			let dirChange = playerAngle - prevAngle;
			
			if(dirChange > 60 && playerMoving){
				dirChanged = true;
			}
			
			if(dirChange < -60 && playerMoving){
				dirChanged = true;
			}
		}
	}
	
	if(type == 2){
		
		let frame = 0;
		
		let dir1 = rand(0, 360);
		let dir2 = rand(0, 360);
		let r = 100;
		
		loop(140){
			
			ObjSound_Play(spellShotSound);
			
			let spd1 = 2;
			let spd2 = 1;
			
			loop(4){
				if(IsPermitPlayerSpell){SpellShot2(GetPlayerX + r*cos(dir1), GetPlayerY + r*sin(dir1), spd1, dir1, 7);}
				spd1 += 0.5;
				dir1 += 1.5;
				
				if(IsPermitPlayerSpell){SpellShot2(GetPlayerX + r*cos(dir2), GetPlayerY + r*sin(dir2), spd2, dir2, 8);}
				spd2 += 0.5;
				dir2 -= 1.5;
			}
			
			dir1 += 4;
			dir2 -= 3;
			
			frame++;
			
			if(frame < 40){
				r -= 1;
				loop(2){yield;}
			}
			
			if(frame >= 80 && frame < 100){
				r -= 1;
				loop(2){yield;}
			}
			
			if(frame >= 40 && frame < 80){
				r -= 2;
				dir1 += 2;
				dir2 -= 3;
				loop(1){yield;}
			}
			
			if(frame >= 100){
				r -= 2;
				dir1 += 2;
				dir2 -= 3;
				loop(1){yield;}
			}
		}
	}
}

task SpellShot2(x, y, spd, dir, color){
	
	let b = ID_INVALID;
	b = CreatePlayerShotA1(x, y, spd, dir, 6, 20, color);
	ObjShot_SetEraseShot(b, true);
	
	let z = 0;
	
	while(!Obj_IsDeleted(b)){
		
		x = ObjMove_GetX(b);
		y = ObjMove_GetY(b);
		z = ObjMove_GetAngle(b);
		
		yield;
	}
	
	let effect = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriority(effect, 0.60);
	ObjPrim_SetTexture(effect, GetCurrentScriptDirectory() ~ "img/shot.png");
	ObjRender_SetAngleZ(effect, z + 90);
	ObjRender_SetX(effect, x);
	ObjRender_SetY(effect, y);
	
	if(color == 7){
		ObjSprite2D_SetDestRect(effect, -16, -16, 16, 16);
		ObjSprite2D_SetSourceRect(effect, 128, 32, 160, 64);
		ObjRender_SetBlendType(effect, BLEND_ADD_RGB);
	}
	
	if(color == 8){
		ObjSprite2D_SetDestRect(effect, -8, -8, 8, 8);
		ObjSprite2D_SetSourceRect(effect, 0, 16, 16, 32);
		ObjRender_SetBlendType(effect, BLEND_ALPHA);
	}
	
	let alpha = 256;
	let color2 = 256;
	
	loop(10){
		
		ObjRender_SetX(effect, ObjRender_GetX(effect) + spd*cos(dir));
		ObjRender_SetY(effect, ObjRender_GetY(effect) + spd*sin(dir));
		
		if(color == 7){
			ObjRender_SetColor(effect, color2, color2, color2);
		}
		
		if(color == 8){
			ObjRender_SetAlpha(effect, alpha);
		}
		
		alpha -= 256/10;
		color2 -= 256/10;
		
		yield;
	}
	
	Obj_Delete(effect);
}

task TrailEffect{
	
	let trailEffect = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjRender_SetBlendType(trailEffect, BLEND_ADD_ARGB);
	Obj_SetRenderPriority(trailEffect, 0.25);
	ObjPrim_SetTexture(trailEffect, GetCurrentScriptDirectory() ~ "img/player2.png");
	ObjSprite2D_SetDestRect(trailEffect, -16, -24, 16, 24);
	ObjRender_SetX(trailEffect, GetPlayerX);
	ObjRender_SetY(trailEffect, GetPlayerY);
	
	if(playerSpriteY == 1){
		ObjSprite2D_SetSourceRect(trailEffect, 32*playerSpriteFrame1, 0, 32*(playerSpriteFrame1 + 1), 48);
	}
	
	if(playerSpriteY == 2){
		ObjSprite2D_SetSourceRect(trailEffect, 32*playerSpriteFrame2, 48, 32*(playerSpriteFrame2 + 1), 96);
	}
	
	if(playerSpriteY == 3){
		ObjSprite2D_SetSourceRect(trailEffect, 32*playerSpriteFrame3, 96, 32*(playerSpriteFrame3 + 1), 144);
	}
	
	let color = 128;
	
	while(color > 0){
		
		color -= 2;
		
		ObjRender_SetColor(trailEffect, color, color, color*2);
		
		yield;
	}
	
	Obj_Delete(trailEffect);
}

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;
	
	let v = 0;
	
	loop(66){
		ObjPrim_SetVertexPosition(magicCircle, v, r*cos(dir), r*sin(dir), 0);
		ObjPrim_SetVertexUVT(magicCircle, v, x, v*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;
		
		v++;
	}
	
	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;
		v = 0;
		
		loop(66){
			
			let rOriginal = r;
			
			if(r < 0){
				r = 0;
			}
			
			ObjPrim_SetVertexPosition(magicCircle, v, 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;
			
			v++;
		}
		
		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_SetDestRect(effect, -16, -16, 16, 16);
	ObjSprite2D_SetSourceRect(effect, 0, 0, 32, 32);
	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_SetDestRect(effect, -32, -32, 32, 32);
	ObjSprite2D_SetSourceRect(effect, 0, 0, 64, 64);
	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);
}