#TouhouDanmakufu[Player]
#ScriptVersion[3]
#ID["TR_Tricky"]
#Title["Tricky"]
#Text["Unfocus Shot: Conjury &quot;Aero&quot;[r]Simple spread shot.[r]Focus Shot: Conjury &quot;Stone II&quot;[r]Exploding forward-firing shot."]
#Image["./TrickyImg.png"]
#ReplayName["Tricky"]

let CSD = GetCurrentScriptDirectory;
let objPlayer = GetPlayerObjectID;

let CanShoot = true; 
bool pressZ = false;
let t = 0;
let optionScale = 0.8;

let shot = CSD ~ "SFX/pshot.wav";
let slash = CSD ~ "SFX/slash.wav";
let boon = CSD ~ "SFX/boon.wav";
let charge = CSD ~ "SFX/charge.wav";
let powerup = CSD ~ "SFX/powerup.wav";
let death = CSD ~ "SFX/death.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 effect = CSD ~ "SFX/effect.wav";
let spell = CSD ~ "SFX/limitbreak.wav";
let item = CSD ~ "SFX/item.wav";
let cardget = CSD ~ "SFX/cardget.wav";
let wind = CSD ~ "SFX/wind.wav";

let init = true;
let p2 = true;
let p3 = true;
let p4 = true;
let FastSpeed = 4.2;
let SlowSpeed = 1.7;
let GlobalDamage_Shot = 1;
let Damage_Shot_1 = 1.0;
let Damage_Shot_F = 1.0;
let GlobalDamage_Spell = 1.35;

let switch = 1;


@Initialize {
	
	LoadPlayerShotData(CSD ~ "TrickyShot.dnh");
	ObjPlayer_AddIntersectionCircleA1(objPlayer, 0, 0, 0, 20); 
	SetPlayerSpeed(FastSpeed,SlowSpeed);
	SetPlayerDownStateFrame(75);
	SetPlayerRebirthFrame(16);
	SetPlayerRebirthLossFrame(0);
	SetAutoDeleteObject(true);
	
	LoadSound(shot);
	LoadSound(slash);
	LoadSound(charge);
	LoadSound(powerup);
	LoadSound(death);
	LoadSound(extend);
	LoadSound(graze);
	LoadSound(boon);
	LoadSound(wave);
	LoadSound(wave2);
	LoadSound(effect);
	LoadSound(item);
	LoadSound(cardget);
	LoadSound(wind);
	LoadSound(spell);
	LoadTexture(CSD ~ "TrickyPlayer.png");
	LoadTexture(CSD ~ "TrickyCut.png");
	LoadTexture(CSD ~ "ConcentrationCircle.png");
	LoadTexture(CSD ~ "effect.png");
	
	TMagicCircle;
	RenderPlayer;
	RenderHitbox(1);
	RenderHitbox(-1);
	
	SetPlayerSpell(2);
	SetPlayerPower(200);
	Shot;
}

@MainLoop {
	if(GetPlayerState==STATE_DOWN){ CanShoot = false; }
	if(GetPlayerState==STATE_NORMAL){ CanShoot = true; }
	if(IsPermitPlayerShot==false && GetPlayerState==STATE_NORMAL){ CanShoot = false; }
	if(IsPermitPlayerShot==true && GetPlayerState==STATE_NORMAL){ CanShoot = true; }
	if(GetCommonData("OnEvent",false)){ CanShoot = false; SetForbidPlayerSpell(true); }
	if(IsPlayerSpellActive) { CollectAllItems; }

	pressZ = GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD;

	SetPlayerAutoItemCollectLine(GetCommonData("PointOfCollection",150));
	SetPlayerClip(109, 7, GetScreenWidth()-109, GetScreenHeight()-7);
	
	if(GetVirtualKeyState(VK_SLOWMOVE)!=KEY_FREE){CollectItemsInCircle(GetPlayerX, GetPlayerY, 55);} else{ CollectItemsInCircle(GetPlayerX, GetPlayerY, 16); }
	
	t++;
	yield;
}

@Finalize {
}

@Event {
	
	alternative(GetEventType)
	case(EV_REQUEST_SPELL){
		let bomb = GetPlayerSpell;
		if(bomb >= 1 && !IsPlayerSpawning){
			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(max(2,GetPlayerSpell));
		if(GetPlayerPower<100) { SetPlayerPower(100); }
		SetPlayerInvincibilityFrame(180);
		PlayerRespawn;
	}
	case(EV_GRAZE){
		PlaySE(graze);
		loop(2) { GrazeEffect; }
	}
	case(EV_GET_ITEM)
		{
			let itemType = GetEventArgument(0);

			alternative(itemType)
			case(ITEM_1UP){
				PlaySE(extend);
				SetPlayerLife(GetPlayerLife + 1);
				//WriteLog("ITEM_1UP");
			}
			case(ITEM_1UP_S){
				PlaySE(extend);
				SetPlayerLife(GetPlayerLife + 1);
				//WriteLog("ITEM_1UP_S");
			}
			case(ITEM_SPELL){
				PlaySE(cardget);
				SetPlayerSpell(GetPlayerSpell + 1);
				//WriteLog("ITEM_SPELL");
			}
			case(ITEM_SPELL_S){
				PlaySE(cardget);
				SetPlayerSpell(GetPlayerSpell + 1);
				//WriteLog("ITEM_SPELL_S");
			}
			case(ITEM_POWER){
				PlaySE(item);
				//WriteLog("ITEM_POWER");
			}
			case(ITEM_POWER_S){
				PlaySE(item);
				//WriteLog("ITEM_POWER_S");
			}
			case(ITEM_POINT){
				PlaySE(item);
				
				//WriteLog("ITEM_POINT");
			}
			case(ITEM_POINT_S){
				PlaySE(item);
				
				//WriteLog("ITEM_POINT_S");
			}
			others{
				PlaySE(item);
			}
		}
}

task homing(){
	int count = 0;
	bool timer;
	loop {
		if(CanShoot) {
			timer = (count % 10 == 0);
			if(pressZ && GetVirtualKeyState(VK_SLOWMOVE) == KEY_FREE && timer){
				ascent(int i in -1..2){
					HomingShot(GetPlayerX + 30*i, GetPlayerY - (|6*i|), 1.0, 0, 1/2, 10, 270+50*i, 1, 1, 10);
				}
			}

			count++;
		}
		else{count = -1;}
		
		yield;
	}
}

task HomingShot(x,y,scale,speed,accel,maxspeed,dir,graphic,pene,dmg) {
	let power_damage = Damage_Shot_1;
	let maxdmg = dmg*GlobalDamage_Shot*power_damage;
	let percent = 0.25;
	let alivetime = 0;
	let obj = CreatePlayerShotObjectA1(x,y,speed,dir,dmg*GlobalDamage_Shot*power_damage,pene,graphic);
	smellBoss(obj, GetClosestEnemyID(ObjMove_GetX(obj), ObjMove_GetY(obj)), 0, 60*1.5);
	ObjMove_SetAcceleration(obj, accel); ObjMove_SetMaxSpeed(obj, maxspeed);
	ObjRender_SetBlendType(obj, BLEND_ALPHA_INV);

	real dirty;
	let ypos = 0; let xpos = 0; bool pass = true;
	ObjRender_SetScaleXYZ(obj,scale,scale,1); 
	while(!Obj_IsDeleted(obj)) {
		xpos = ObjRender_GetX(obj);
		ypos = ObjRender_GetY(obj);
		dirty = ObjMove_GetAngle(obj);
		if(alivetime<=6 && percent<1){
			percent+=(0.75)/6;
			ObjShot_SetDamage(obj, maxdmg*percent);
		}

		alivetime++;
		yield;
	}
	if(graphic==1) { FadeShot(xpos,ypos-10,6,dirty,graphic+1); }
	if(graphic==3) { FadeShot(xpos,ypos-10,0,dirty,graphic+1); }
}

task smellBoss(obj, enemy, timeout, frames){
	int calm = 0; real ang, turn;
	wait(timeout);
	loop(frames){
		if(enemy == ID_INVALID){return;}
		if(Obj_IsDeleted(obj)){break;}
		ang = GetAngleFromTo(ObjMove_GetX(enemy), ObjMove_GetY(enemy), ObjMove_GetX(obj), ObjMove_GetY(obj));

		turn = Interpolate_Smooth(ObjMove_GetAngle(obj), ang, calm/3);

		ObjMove_SetAngle(obj, NormalizeAngle(turn));
		calm++; calm = (calm > 3) ? 3 : calm; 
		yield;
	}
}

task Shot {
	homing();
	let count = -1;
	let count2 = -1;
	loop {
		if(CanShoot) {
			if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD && count == -1 || count > 3) {
				count = 0;
			}
			if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD && count2 == -1 || count2 > 16) {
				count2 = 0;
			}
			if(count==3) {
				PlaySE(shot);
				if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_FREE) {
					ascent(i in -2..3){
						PlayerShot(GetPlayerX,GetPlayerY-5,1.0,23,270+(i*15),1,1,5);
					}
				}
				if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE) {
					ascent(i in -1..2){
						PlayerShot(GetPlayerX,GetPlayerY-5,1.0,23,270+(i*7.5),1,1,4);
					}
				}
				count = -1;
			}
			if(GetVirtualKeyState(VK_SLOWMOVE) != KEY_FREE) {
				if(count2==16) {
					PlaySE(shot);
					ExplodeShot2(GetPlayerX,GetPlayerY-5,0.8,11,270,6,5,5);
					count2 = -1;
				}
				if(count2>=0) {
					count2++;
				}
			}
			else { count2 = -1; }
			if(count>=0) {
				count++;
			}
		}
		else { count = -1; count2 = -1; }
		yield;
	}
}
task PlayerShot(x,y,scale,speed,dir,graphic,pene,dmg) {
	let power_damage = Damage_Shot_1;
	let maxdmg = dmg*GlobalDamage_Shot*power_damage;
	let percent = 0.25;
	let alivetime = 0;
	let obj = CreatePlayerShotObjectA1(x,y,speed,dir,dmg*GlobalDamage_Shot*power_damage,pene,graphic);
	let ypos = 0;
	let xpos = 0;
	ObjRender_SetScaleXYZ(obj,scale,scale,1);
	while(!Obj_IsDeleted(obj)) {
		xpos = ObjRender_GetX(obj);
		ypos = ObjRender_GetY(obj);
		if(alivetime<=6 && percent<1){
			percent+=(0.75)/6;
			ObjShot_SetDamage(obj, maxdmg*percent);
		}
		alivetime++;
		yield;
	}
	if(graphic==1) { FadeShot(xpos,ypos-10,6,dir,graphic+1); }
	if(graphic==3) { FadeShot(xpos,ypos-10,0,dir,graphic+1); }
}

task ExplodeShot2(x,y,scale,speed,dir,graphic,pene,dmg) {
	let power_damage = Damage_Shot_1;
	let obj = CreatePlayerShotObjectA1(x,y,speed,dir,dmg*GlobalDamage_Shot*power_damage,pene,graphic);
	let ypos = 0;
	let xpos = 0;
	let r = 15;
	let angle = rand(0,360);
	ObjRender_SetScaleXYZ(obj,scale,scale,1);
	
	while(!Obj_IsDeleted(obj)) {
		xpos = ObjRender_GetX(obj);
		ypos = ObjRender_GetY(obj);
		yield;
	}
	if(ypos>-30) {
		loop(8) {
			Pebble2(xpos+r*cos(angle),ypos+r*sin(angle),angle,scale);
			angle+=360/8;
		}
	}
}
task Pebble2(x,y,dir,scale) {
	let speed = 4;
	let alpha = 255;
	
	let power_damage = Damage_Shot_1;
	if(GetPlayerPower<200) { power_damage = Damage_Shot_1; }
	let obj = CreatePlayerShotObjectA1(x,y,speed,dir,0.8,20,6);
	if(CanShoot) { ObjRender_SetScaleXYZ(obj,0.7*scale,0.7*scale,1); }
	else { Obj_SetVisible(obj,false); }
	
	wait(4);
	while(alpha>0) {
		ObjMove_SetSpeed(obj,speed);
		ObjRender_SetAlpha(obj,alpha);
		alpha-=255/7;
		speed-=4/7;
		yield;
	}
	Obj_SetVisible(obj,false);
	while(!CanShoot) { yield; } 
	Obj_Delete(obj);
}
task FadeShot(x,y,speed,dir,graphic) {
	let obj = CreatePlayerShotObjectA1(x,y,speed,dir,0,10,graphic);
	loop(12){
		yield;
	}
	Obj_SetVisible(obj,false);
	while(!CanShoot) { yield; } 
	Obj_Delete(obj);
}

task Spell {
	let objManage = GetSpellManageObject;
	let r = 15;
	let spl;
	let dir = 0;
	let focus = true;
	if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_FREE) { focus = false; }
	SetForbidPlayerShot(true);

	if(!GetCommonData("PlayerOP", false)){SetPlayerInvincibilityFrame(390);}
	
	if(focus){ spl = "Stonesword Volley"; SetPlayerSpeed(SlowSpeed*0.5,SlowSpeed*0.5); }
	else{ spl = "Aerostorm"; SetPlayerSpeed(SlowSpeed,SlowSpeed); }
	cutin(objManage,"Conjury \""~spl~"\"",CSD ~ "TrickyCut.png",0,0,512,512);
	SpellBurst;
	if(!focus){
		wait(90);
		PlaySE(wind);
		loop(42) {
			PlaySE(effect);
			loop(5) {
				SpellAero(GetPlayerX+r*cos(dir), GetPlayerY+r*sin(dir), 10, dir, dir);
				dir+=360/5;
			}
			dir+=14.65*switch;
			wait(4);
		}
		switch*=-1;
		wait(60);
	}
	else{
		wait(45);
		ascent(i in 0..3){
			ascent(j in -((i*2)/2)..((i*2)/2)+1){
				SpellSword(j*10, -90+(j*5));
			}
			wait(40);
		}
	}
	SetForbidPlayerShot(false);
	SetPlayerSpeed(FastSpeed,SlowSpeed);
	Obj_Delete(objManage);
}

task SpellAero(x, y, speed, dir, graphicangle){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objHitbox = ObjSpell_Create;
	let alpha = 100;
	let currdamage = 4;
	
	ObjPrim_SetTexture(obj, CSD ~ "PlayerShot.png");
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 50);
	ObjSprite2D_SetSourceRect(obj, 400, 252, 432, 284);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetAlpha(obj, 0);
	ObjRender_SetScaleXYZ(obj, 1.5, 1.5, 1);
	ObjSpell_SetDamage(objHitbox, currdamage);
	ObjSpell_Regist(objHitbox);
	
	AeroMovement;
	
	while(!Obj_IsDeleted(obj)){
		if(alpha<175){
			alpha+=75/15;
			ObjRender_SetAlpha(obj, alpha);
		}
		ObjRender_SetPosition(obj,x,y,0);
		ObjRender_SetPosition(objHitbox, x, y, 0);
		ObjRender_SetAngleZ(obj, graphicangle);
		ObjSpell_SetIntersectionCircle(objHitbox,ObjRender_GetX(obj),ObjRender_GetY(obj),24);
		yield;
	}
	
	task AeroMovement{
		while(ObjRender_GetX(obj)>-20 && ObjRender_GetX(obj)<GetStgFrameWidth+20 && ObjRender_GetY(obj)>-20 && ObjRender_GetY(obj)<GetStgFrameHeight+20) {
			x+=speed*cos(dir);
			y+=speed*sin(dir);
			graphicangle+=speed;
			if(currdamage<16){ currdamage+=12/10; }
			ObjSpell_SetDamage(objHitbox, currdamage);
			yield;
		}
		Obj_Delete(obj);
		Obj_Delete(objHitbox);
	}
	
}

task SpellSword(xoffset, designatedangle){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let objHitbox = ObjSpell_Create;
	let alpha = 0;
	
	ObjPrim_SetTexture(obj, CSD ~ "ShotsheetSpecial.png");
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 50);
	ObjSprite2D_SetSourceRect(obj, 16, 113, 31, 145);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetAlpha(obj, 0);
	ObjRender_SetScaleXYZ(obj, 1.5, 1.5*1.375, 1);
	ObjSpell_SetDamage(objHitbox, 10);
	ObjSpell_Regist(objHitbox);
	
	let angle3 = designatedangle;
	let angle = angle3;
	let var_max = 55;
	let multiplier = 60/var_max;
	let wonj = switch;
	let initx = (GetPlayerX + xoffset);
	let inity = GetPlayerY;
	let angle2 = angle3;
	let count = 0;
	let count2 = 0;
	let radius = 45;
	let TargetAngle = 0;
	let diff = 0;
	let ang2acc = 0;
	let radacc = 1;
	let avmax = 2;
	let targetx = 0;
	let targety = 0;
	
	let targetEnemy;
	let attachedToPlayer = true;
	
	SwordMovement(obj);
	PlaySE(boon);
	loop(45){
		ObjSpell_SetIntersectionCircle(objHitbox,initx+radius*cos(angle),inity+(radius*1.25)*sin(angle), 26);
		alpha+=255/45;
		ObjRender_SetAlpha(obj, alpha);
		ObjMove_SetPosition(objHitbox, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle));
		ObjRender_SetPosition(obj, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle), 0);
		wait(1);
		ObjRender_SetAngleZ(obj, angle+90);
	}
	
	PlaySE(slash);
	ObjSpell_SetDamage(objHitbox, 20);
	attachedToPlayer = false;
	//PlaySoundEx(SE_SHOT, 80, (ObjMove_GetX(objBoss)-320)/4.8);
	loop(30){
		ObjSpell_SetIntersectionCircle(objHitbox,initx+radius*cos(angle),inity+(radius*1.25)*sin(angle), 26);
		ObjRender_SetPosition(obj, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle), 0);
		ObjMove_SetPosition(objHitbox, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle));
		ObjRender_SetAngleZ(obj, angle2+90);
		angle2+=ang2acc;
		if(ang2acc<35){
			ang2acc+=0.55;
		}
		if(radacc<4){ radacc+=0.05; }
		radius+=radacc;
		yield;
	}
		//radacc = 2.5;
	loop(240){
		if(radacc<4){ radacc+=0.05; }
		radius+=radacc;
		ObjRender_SetPosition(obj, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle), 0);
		ObjMove_SetPosition(objHitbox, initx+radius*cos(angle), inity+(radius*1.25)*sin(angle));
		ObjRender_SetAngleZ(obj, angle2+90);
		if(ang2acc<15){ ang2acc+=0.55; }
	angle2+=ang2acc;
	wait(1);
	}
	Obj_Delete(obj);
	Obj_Delete(objHitbox);
	
	task SwordMovement(obj){
		while(!Obj_IsDeleted(obj)){
			if(attachedToPlayer){
				initx = GetPlayerX+xoffset;
				inity = GetPlayerY;
			}
			ObjSpell_SetIntersectionCircle(objHitbox,initx+radius*cos(angle),inity+(radius*1.25)*sin(angle), 26);
			/*
			if(alpha<175){
				alpha+=75/15;
				ObjRender_SetAlpha(obj, alpha);
			}
			ObjRender_SetPosition(obj,x,y,0);
			ObjRender_SetPosition(objHitbox, x, y, 0);
			ObjRender_SetAngleZ(obj, graphicangle);
			ObjSpell_SetIntersectionCircle(objHitbox,ObjRender_GetX(obj),ObjRender_GetY(obj),24);
			*/
			yield;
		}	
	}
	
	function GetBestSwordTarget{
		if(GetEnemyBossSceneObjectID!=ID_INVALID){
			//WriteLog(GetEnemyBossObjectID);
			if(length(GetEnemyBossObjectID)>0){ return GetEnemyBossObjectID[0]; }
		}
		else if(length(GetIntersectionRegistedEnemyID)>0){
			//WriteLog(GetIntersectionRegistedEnemyID[0]);
			return GetIntersectionRegistedEnemyID[0];
		}
		return ID_INVALID;
	}
}

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.05;
	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, 255*alpha, 30*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 DelayedPenalty {
	yield;
	SetCommonData("Balance",GetCommonData("Balance",0)-1200);
	SetCommonData("Discord Resource Bonus",floor(GetCommonData("Discord Resource Bonus",0)/100)*100);
	if(GetCommonData("Balance",0)<0) { SetCommonData("Balance",0); }
}
task RenderPlayer {
	let count = 0;
	let type = 0;
	ObjPrim_SetTexture(objPlayer, CSD ~ "TrickyPlayer.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(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; }
		}
		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 ~ "PlayerShot.png");
	ObjSprite2D_SetSourceRect(obj, 448, 0, 511, 63);
	ObjSprite2D_SetDestCenter(obj);
	
	while(!Obj_IsDeleted(obj)){
		if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH){ 
			scale = 2;
			alpha = 0;
		}
		if(scale>0.8) {
			scale-=1.2/10;
			alpha+=255/10;
			count+=4;
		}
		if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_FREE){
			if(scale<=0.8 && scale>0) {
				scale-=0.8/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.55;
	let f = 0;
	let g = 0;

	x = GetStgFrameWidth+20;
	y = (GetStgFrameHeight/2)-120;

	ObjRender_SetBlendType(obj,BLEND_ALPHA);
	ObjPrim_SetTexture(obj,CutImg);
	Obj_SetRenderPriorityI(obj,29);
	ObjSprite2D_SetSourceRect(obj,left,top,right,bottom);
	ObjSprite2D_SetDestRect(obj,-GetTextureWidth(CutImg)/2,-GetTextureHeight(CutImg)/2+250,GetTextureWidth(CutImg)/2,GetTextureHeight(CutImg)/2+250);


	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 = 97;
		let y1 = 360;
		let a = 0;
		let scale = 1.5;
		
		SpellBG;
		
		ObjText_SetText(objtext,SpellCardName);
		ObjText_SetFontSize(objtext,13);
		ObjText_SetFontType(objtext, "MeiryoKe_PGothic");
		ObjText_SetFontBold(objtext, true);
		ObjText_SetFontColorTop(objtext,255,255,255);
		ObjText_SetFontColorBottom(objtext,255,255,255);
		ObjText_SetFontBorderType(objtext,BORDER_FULL);
		ObjText_SetFontBorderWidth(objtext,1);
		ObjText_SetFontBorderColor(objtext,0,0,0);
		ObjText_SetHorizontalAlignment(objtext,ALIGNMENT_LEFT);
		ObjText_SetMaxWidth(objtext,320);
		Obj_SetRenderPriorityI(objtext,70);
		
		loop(20) {
			ObjRender_SetPosition(objtext,x1,y1,0);
			ObjRender_SetAlpha(objtext,a);
			if(a<255) { a+=255/20; }
			if(x1<97) { x1+=97/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 = 97+10;
			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_SetY(objbg, y2);
				y2+=60/30;
				yield;
			}
			while(!Obj_IsDeleted(objspell)) { yield; }
			loop(20) {
				ObjRender_SetX(objbg,x2);
				x2-=15;
				yield;
			}
			Obj_Delete(objbg);
		}
	}
}
task ClearBullets {
	wait(15);
	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_ADD_RGB);
	Obj_SetRenderPriorityI(obj,60);
	ObjPrim_SetTexture(obj, CSD ~ "PlayerShot.png");
	ObjSprite2D_SetSourceRect(obj, 448, 448, 510, 510);
	ObjSprite2D_SetDestCenter(obj);
	
	loop(30) { ParticleEffect(rand(0,360)); ObjectEffect(rand(0,360)); }
	ObjRender_SetPosition(obj, GetPlayerX, GetPlayerY, 0);
	
	let alpha = 120;
	let scale = 0;
	let maxscale = 4;
	let RGB = [255,64,64];
	ascent(i in 0..20) {
		scale = maxscale*sin(90*i/20);
		alpha -= 120/20;
		// if(dscale>0){ dscale = dscale^1.10; }
		ObjRender_SetColor(obj,RGB[0]*(alpha/255),RGB[1]*(alpha/255),RGB[2]*(alpha/255));
		
		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 ObjectEffect(angX) {
		let deX = GetPlayerX;
		let deY = GetPlayerY;
		let deAlpha = rand(85, 185);
		let deScale = 2.8;
		deScale = deScale*1.25;
		let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D); 
		ObjRender_SetBlendType(obj, BLEND_ALPHA);
		Obj_SetRenderPriorityI(obj, 60);
		ObjPrim_SetTexture(obj, CSD ~ "star.png");
		ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
		ObjSpriteList2D_SetSourceRect(obj, 0, 0, 32, 32);
		ObjSpriteList2D_SetDestCenter(obj);
		ObjRender_SetAngleXYZ(obj, 0, 0, angX);
		ObjRender_SetPosition(obj, deX, deY, 0);
		
		let RGB = [255, 64, 64];
		
		ObjRender_SetColor(obj,RGB[0]*(deAlpha/255),RGB[1]*(deAlpha/255),RGB[2]*(deAlpha/255));

		let scale = deScale;
		let randX = rand(-105, 105);
		let randY = rand(-105, 105);
		let	ang2 = rand(0, 360);
		
		while(scale>0.01){
			scale += (-0.2)/2;
			deX += randX/20;
			deY += randY/20;
			angX += randX/15;
			ang2 += randX/15;
			ObjSpriteList2D_ClearVertexCount(obj);
			ObjSpriteList2D_SetSourceRect(obj, 0, 0, 32, 32);
			ObjSpriteList2D_SetDestCenter(obj);
			ObjSpriteList2D_AddVertex(obj);
			
			ObjRender_SetPosition(obj, deX, deY, 0);
			ObjRender_SetAngleXYZ(obj, ang2, angX, (ang2+angX)/2);
			ObjRender_SetScaleXYZ(obj, scale, scale, scale);
			ObjRender_SetAlpha(obj, deAlpha-scale*20);
			yield;
		}
		Obj_Delete(obj);
	}
}
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 {
	//NotifyEventAll(EV_USER + 16,[3,GetPlayerX,GetPlayerY,400]);
}


function CreatePlayerShotObjectA1(x, y, spd, ang, dmg, pen, graph){
	if(!IsPermitPlayerShot || GetCommonData("OnEvent",false)){return ID_INVALID;}
	let obj = CreatePlayerShotA1((x), (y), spd, ang, dmg, pen, graph);
	Obj_SetRenderPriorityI(obj,46); 
	return obj;
}

function GetAngleFromTo(xPos, yPos, xOrig, yOrig){return atan2(yPos - yOrig, xPos - xOrig);}
function AngleBetweenPoints(x1, y1, x2, y2){ //get angle from (x1, y1) to (x2, y2)
return atan2(y2-y1, x2-x1);
}

//--
let IsPlayerSpawning = false;
task PlayerRespawn{
	let obj = GetPlayerObjectID;
	let y = 0;
	ObjRender_SetX(obj, GetStgFrameWidth/2);
	ObjRender_SetY(obj, GetStgFrameHeight-32);
	SetPlayerSpeed(0,0);
	IsPlayerSpawning = true;
	
	// yield;
	SetPlayerInvincibilityFrame(GetPlayerInvincibilityFrame+58);
	
	while(y<GetStgFrameHeight/4){
		SetPlayerClip(11,11,GetStgFrameWidth-11,GetStgFrameHeight+64);	
		SetPlayerSpeed(0,0);
		ObjRender_SetY(obj, GetStgFrameHeight+32-y);
		y+=2.5;
		yield;
	}
	IsPlayerSpawning = false;
	
	SetPlayerSpeed(FastSpeed,SlowSpeed);
}

function GetClosestEnemyID(x1, y1){
	let earray = GetAllEnemyID;
	if(GetEnemyBossSceneObjectID != ID_INVALID){earray = GetIntersectionRegistedEnemyID;}
	let objid = ID_INVALID;
	let dist = max(GetStgFrameWidth, GetStgFrameHeight)*1.25;
	let size = max(-1, length(earray));
	if(size >= 0){
		ascent(int b in 0..size){
			let eID = earray[b];
			let edist = distance(x1, y1, ObjMove_GetX(eID), ObjMove_GetY(eID));
			if(edist < dist){dist = edist; objid = eID;}
		}
	}
	return objid;
}