#include "./../lib/lib_file.txt"
#include "./../lib/lib_input.txt"
#include "./../lib/lib_render.txt"
#include "./../lib/lib_calc.txt"

let obj_player = GetPlayerObjectID;
let Player_Speed_Spell_Unfocus = 1;
let Player_Speed_Spell_Focus = 1;
let Respawning = false;
let FireRate = -1;

function _Initalize(img,speed,hitbox,graze,spell){
	//SetCommonData("Player_Speed_Unfocus",speed[0]);
	//SetCommonData("Player_Speed_Focus",speed[1]);
	SetCommonData("Player_Spell",spell);
	RenderPlayer(img);
	ObjPlayer_AddIntersectionCircleA1(obj_player,0,0,1,24);
	SetPlayerClip(GetClipMinX+4,GetClipMinY+4,GetClipMaxX-4,GetClipMaxY-4);
	SetPlayerRebirthFrame(8);
	SetPlayerRebirthLossFrame(0);
	SetPlayerDownStateFrame(45);
	ExclInit;
}

function _MainLoop{
	//Speed

	//Fire Rate
	if(GetPlayerState==STATE_NORMAL && !Respawning){
		if(B_SHOT && FireRate==-1){
			FireRate = 0;
		}
		if(FireRate>=0){
			FireRate++;
		}
		if(FireRate>=30){if(B_SHOT){FireRate=0;}else{FireRate=-1;}}
	}
	if(GetPlayerState==STATE_DOWN || Respawning){FireRate=-1;}
	
	//Invulnerablity Break Circle
	if(GetPlayerInvincibilityFrame>0){
		BreakBulletCircle(GetPlayerX,GetPlayerY,16);
	}
}

task _Event{
	alternative(GetEventType())
	case(EV_HIT){
		SE_Play(se_dead,50,PosToPan(GetPlayerX,50));
		MissEff;
	}case(EV_PLAYER_REBIRTH){
		SetCommonData("Misses",GetCommonData("Misses",0)+1);
		Respawn;
		if(GetPlayerSpell<GetCommonData("Player_Spell",3)){
			SetPlayerSpell(GetCommonData("Player_Spell",3));
		}
		SetPlayerInvincibilityFrame(180+30);
	}case(EV_GRAZE){
		SE_Play(se_graze,50,PosToPan(GetPlayerX,50));
		GrazeEff(GetEventArgument(1));
	}
}

function CreatePlayerShot(x,y,vel,dir,dmg,spr){
	if(!IsPermitPlayerShot){return;}
	let obj = ObjShot_Create(OBJ_SHOT);
	ObjMove_SetPosition(obj,x,y);
	ObjMove_SetSpeed(obj,vel);
	ObjMove_SetAngle(obj,dir);
	ObjShot_SetGraphic(obj,spr);
	ObjShot_SetDamage(obj,dmg);
	ObjShot_SetPenetration(obj,65536);
	Obj_SetRenderPriorityI(obj,47);
	ObjShot_Regist(obj);
	return obj;
}

task Respawn{
	let y = 32;
	Respawning=true;
	loop(30){
		y-=64/30;
		ObjMove_SetPosition(obj_player,GetCenterX,GetClipMaxY+y);
		yield;
	}
	Respawning=false;
}

function BreakBulletCircle(x,y,radi){
	let bullet = GetShotIdInCircleA2(x,y,radi,TARGET_ENEMY);
	ascent(b in 0..length(bullet)){
		if(!ObjShot_IsSpellResist(bullet[b])){
			Obj_SetValue(bullet[b],"break",true);
			ObjShot_ToItem(bullet[b]);
		}
	}
}

task SpellHandler(vm,frame){ //atleast 120
	SetPlayerInvincibilityFrame(frame+90);
	let spell_obj = GetSpellManageObject;
	Player_Speed_Spell_Unfocus=vm[0];
	Player_Speed_Spell_Focus=vm[1];
	wait(frame);
	Player_Speed_Spell_Unfocus=1;
	Player_Speed_Spell_Focus=1;
	Obj_Delete(spell_obj);
}

task MoFBomb{
	SpellHandler([1,1],120);
	SE_Play(se_slash,50,PosToPan(GetPlayerX,25));
	let x = GetPlayerX; let y = GetPlayerY;
	let v = 0;
	let bomb_radi = GetCommonData("BombRadius",160);
	let bomb_radi_over = 32*(bomb_radi/160);
	let bomb_vel = 4*(bomb_radi/160);
	let bomb_damage = (5000/120)*(bomb_radi/160);
	Ring;
	loop(120){
		v+=bomb_vel/120;
		y-=v;
		yield;
	}
	
	task Ring{
		let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
		ObjPrim_SetPrimitiveType(obj,PRIMITIVE_TRIANGLESTRIP);
		ObjPrim_SetVertexCount(obj,64);
		ObjPrim_SetTexture(obj,img_pl_bomb);
		ObjRender_SetPosition(obj,x,y,0);
		ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
		Obj_SetRenderPriorityI(obj,30);
		let radi = 0; let alpha = 255;
		ascent(v in 0..64/2){
			let iv = v*2;
			let ang = (360/(64-2)*iv);
			let uvt = (iv/62);
			ObjPrim_SetVertexUVT(obj,iv,0,1024*uvt);
			ObjPrim_SetVertexUVT(obj,iv+1,32,1024*uvt);
			ObjPrim_SetVertexPosition(obj,iv,(radi+12)*cos(ang),(radi+12)*sin(ang),0);
			ObjPrim_SetVertexPosition(obj,iv+1,(radi-12)*cos(ang),(radi-12)*sin(ang),0);
		}
		
		let obj_spell = ObjSpell_Create;
		ObjSpell_SetDamage(obj_spell,bomb_damage);
		ObjSpell_Regist(obj_spell);
		
		let c = 0; let z = 0; let e1 = 0; let e2 = 0;
		loop(30){
			c+=90/30;
			radi=bomb_radi*sin(c);
			ascent(v in 0..64/2){
				let iv = v*2;
				let ang = (360/(64-2)*iv);
				ObjPrim_SetVertexPosition(obj,iv,(radi+12)*cos(ang),(radi+12)*sin(ang),0);
				ObjPrim_SetVertexPosition(obj,iv+1,(radi-12)*cos(ang),(radi-12)*sin(ang),0);
			}
			z+=8;
			ObjRender_SetAngleZ(obj,-z);
			ObjRender_SetPosition(obj,x,y,0);
			if(e1==0){
				Effect1(0,bomb_radi,128);
			}
			e1++; if(e1==15){e1=0;}
			ObjSpell_SetIntersectionCircle(obj_spell,x,y,radi);
			yield;
		}
		loop(60){
			z+=8;
			ObjRender_SetAngleZ(obj,-z);
			ObjRender_SetPosition(obj,x,y,0);
			if(e1==0){
				Effect1(bomb_radi,bomb_radi_over,255);
				Effect1(0,bomb_radi,128);
			}
			e1++; if(e1==15){e1=0;}
			ObjSpell_SetIntersectionCircle(obj_spell,x,y,radi);
			yield;
		}
		loop(30){
			c+=90/30;
			alpha=255*sin(c);
			ascent(v in 0..64/2){
				let iv = v*2;
				let ang = (360/(64-2)*iv);
				ObjPrim_SetVertexPosition(obj,iv,(radi+12)*cos(ang),(radi+12)*sin(ang),0);
				ObjPrim_SetVertexPosition(obj,iv+1,(radi-12)*cos(ang),(radi-12)*sin(ang),0);
			}
			z+=8;
			ObjRender_SetAngleZ(obj,-z);
			ObjRender_SetAlpha(obj,alpha);
			ObjRender_SetPosition(obj,x,y,0);
			ObjSpell_SetIntersectionCircle(obj_spell,x,y,radi);
			yield;
		}
		Obj_Delete(obj); Obj_Delete(obj_spell);
		
		task Effect1(r1,r2,a){
			let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
			ObjPrim_SetPrimitiveType(obj,PRIMITIVE_TRIANGLESTRIP);
			ObjPrim_SetVertexCount(obj,64);
			ObjPrim_SetTexture(obj,img_pl_bomb);
			ObjRender_SetPosition(obj,x,y,0);
			ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
			ObjRender_SetColor(obj,255,64,255);
			Obj_SetRenderPriorityI(obj,30);
			let radi = 0;
			ascent(v in 0..64/2){
				let iv = v*2;
				let ang = (360/(64-2)*iv);
				let uvt = (iv/62);
				ObjPrim_SetVertexUVT(obj,iv,0,1024*uvt);
				ObjPrim_SetVertexUVT(obj,iv+1,32,1024*uvt);
				ObjPrim_SetVertexPosition(obj,iv,(radi+12)*cos(ang),(radi+12)*sin(ang),0);
				ObjPrim_SetVertexPosition(obj,iv+1,(radi-12)*cos(ang),(radi-12)*sin(ang),0);
			}
			let c = 0; let z = rand(0,360);
			loop(45){
				c+=180/45;
				radi=r1+r2*sin(c/2);
				z+=8;
				ascent(v in 0..64/2){
					let iv = v*2;
					let ang = (360/(64-2)*iv);
					ObjPrim_SetVertexPosition(obj,iv,(radi+12)*cos(ang),(radi+12)*sin(ang),0);
					ObjPrim_SetVertexPosition(obj,iv+1,(radi-12)*cos(ang),(radi-12)*sin(ang),0);
				}
				ObjRender_SetAngleZ(obj,-z);
				ObjRender_SetPosition(obj,x,y,0);
				ObjRender_SetAlpha(obj,(a*(alpha/255))*sin(c));
				yield;
			}
			Obj_Delete(obj);
		}
	}
}