let spellDeclareBackground = GetCurrentScriptDirectory ~ "img/eff02.png";
let freezeTexture = GetCurrentScriptDirectory ~ "img/ice00.png";
let bossCircle = GetCurrentScriptDirectory ~ "img/bosscircle.png";
let frogOverlayTexture = GetCurrentScriptDirectory ~ "img/stg7enm2.png";
let concentrationCircleTexture = GetCurrentScriptDirectory ~ "img/ConcentrationCircle.png";
let explosionTexture = GetCurrentScriptDirectory ~ "img/Default_Effect.png";
let bulletBreakTexture = GetCurrentScriptDirectory ~ "img/BulletBreak.png";
let lightTexture = GetCurrentScriptDirectory ~ "img/Light.png";

//constants
let SUMMON_CIRCLE = 1;
let FROG_OVERLAY = 2;
let CONCENTRATION_CIRCLE = 3;
let EXPLOSION = 4;
let LIGHT_EFFECT = 5;
let BULLET_BREAK = 6;


/*
	Below are SINGLE effects. These are called from singles (not NotifyEvent) and require a boss/shot object and usually rely on the boss's health/shot for timing
*/


//displays spell name, like EOSD but with no cutin. SINGLE
task spellName(boss, spellName)
{
	let text = ObjText_Create();
	ObjText_SetText(text, spellName);
	ObjText_SetFontSize(text, 12);
	ObjText_SetFontColorTop(text, 254, 254, 254);
	ObjText_SetFontColorBottom(text, 255, 125, 125);
	ObjText_SetFontBorderType(text, BORDER_FULL);
	ObjText_SetFontBorderColor(text, 0, 0, 64);
	ObjText_SetFontBorderWidth(text, 1);
	ObjText_SetHorizontalAlignment(text, ALIGNMENT_RIGHT);
	ObjText_SetMaxWidth(text, 300);
	ObjRender_SetBlendType(text, BLEND_ALPHA);
	ObjRender_SetAlpha(text, 255);
	
	ObjRender_SetY(text, GetStgFrameHeight * 2 / 3);
	
	let count = 35;
	while (count >= 0) {
		ObjRender_SetX(text, GetStgFrameWidth  * 7 / 8 - 300 + (count * 10));
		count--;
		yield;
	}
	
	let background = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriority(background, 0.22);
	ObjPrim_SetTexture(background, spellDeclareBackground);
	ObjRender_SetBlendType(background, BLEND_ADD_ARGB);
	ObjRender_SetAlpha(background, 0);
	ObjSprite2D_SetSourceRect(background, 0, 0, ObjText_GetTotalWidth(text) + 16, 256);
	ObjSprite2D_SetDestRect(background, GetStgFrameWidth * 7 / 8 - ObjText_GetTotalWidth(text) - 8, GetStgFrameHeight * 1 / 24 - ObjText_GetTotalHeight(text) / 2 + 7, GetStgFrameWidth * 7 / 8 + 8, GetStgFrameHeight * 1 / 24 + ObjText_GetTotalHeight(text) / 2 + 7);
	
	wait(20);
	
	count = 60;
	while (count >= 0) {
		ObjRender_SetAlpha(background, 255 * ((60 - count) / 60));
		ObjRender_SetY(text, (GetStgFrameHeight * 1 / 24) + ((GetStgFrameHeight * 2 / 3) - (GetStgFrameHeight * 1 / 24)) * (count / 60));
		count--;
		yield;
	}
	
	let alpha = 255;
	while (!Obj_IsDeleted(boss)) {
		if (GetPlayerY < 100) {
			if (alpha > 50) {
				alpha -= 205 / 20;
			}
		} else {
			if (alpha < 255) {
				alpha += 205 / 20;
			}
		}
		ObjRender_SetAlpha(text, alpha);
		ObjRender_SetAlpha(background, alpha);
		yield;
	}
	
	Obj_Delete(text);
	Obj_Delete(background);
}


task freezeFrogEffect(shot, frames)    //frames must be greater than 10.  SINGLE
{
	let ice = ObjPrim_Create(OBJ_SPRITE_2D);
	Obj_SetRenderPriority(ice, 0.31);
	ObjPrim_SetTexture(ice, freezeTexture);
	ObjRender_SetBlendType(ice, BLEND_ADD_ARGB);
	ObjRender_SetAlpha(ice, 5);
	let sourceX = randInt(0, 4) * 32;
	ObjSprite2D_SetSourceRect(ice, sourceX, 128, sourceX + 32, 160);
	let destX = ObjMove_GetX(shot) - 16;
	let destY = ObjMove_GetY(shot) - 16;
	ObjSprite2D_SetDestRect(ice, destX, destY, destX + 32, destY + 32);
		
	ascent (i in 0..11) {
		ObjRender_SetAlpha(ice, 25 * i + 5);
		frames--;
		yield;
	}
	
	while (frames > 0 && !Obj_IsDeleted(shot)) {
		frames--;
		yield;
	}

	Obj_Delete(ice);
}



/*
	Below are PLURAL effects. These are called using notifyEvent for a plural/stage/package to handle (using the constants above)
*/


//uses bossX/bossY in common data, diameter of circle at resting pulse (texture is 128x128), angle change per frame (0 for no spin)
//period of pulse (# of frames for one period), amplitude of pulse (|amplitude| < 1, or texture gets inverted, 0 for no pulse)
task bossSummonCircle(diameter, spin, pulsePeriod, pulseAmplitude)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, bossCircle);
	Obj_SetRenderPriority(obj, 0.22);
	ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
	ObjRender_SetAlpha(obj, 0);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 128, 128);
	ObjSprite2D_SetDestCenter(obj);
	
	let angle = 0;
	let scale = diameter / 128;
	let count = 0;
	let alpha = 0;
	
	while (GetCommonData("summonCircle", true)) {
		ObjRender_SetPosition(obj, GetCommonData("bossX", getCenterX), GetCommonData("bossY", 90), 0);
		ObjRender_SetAngleZ(obj, angle);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		ObjRender_SetAlpha(obj, alpha);
		
		count++;
		angle += spin;
		scale = diameter / 128 + pulseAmplitude * sin((360 * count) / pulsePeriod);
		if (alpha < 150) {alpha += 255 / 60;}
		yield;
	}
	
	while (alpha > 0) {
		ObjRender_SetAlpha(obj, alpha);
		alpha -= 150 / 60;
		yield;
	}
	
	Obj_Delete(obj);
}

task bossSummonCircle2(diameter, spin, pulsePeriod, pulseAmplitude)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, bossCircle);
	Obj_SetRenderPriority(obj, 0.22);
	ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
	ObjRender_SetAlpha(obj, 0);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 128, 128);
	ObjSprite2D_SetDestCenter(obj);
	
	let angle = 0;
	let scale = diameter / 128;
	let count = 0;
	let alpha = 0;
	
	while (GetCommonData("summonCircle", true)) {
		ObjRender_SetPosition(obj, GetCommonData("bossX2", getCenterX), GetCommonData("bossY2", 90), 0);
		ObjRender_SetAngleZ(obj, angle);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		ObjRender_SetAlpha(obj, alpha);
		
		count++;
		angle += spin;
		scale = diameter / 128 + pulseAmplitude * sin((360 * count) / pulsePeriod);
		if (alpha < 150) {alpha += 255 / 60;}
		yield;
	}
	
	while (alpha > 0) {
		ObjRender_SetAlpha(obj, alpha);
		alpha -= 150 / 60;
		yield;
	}
	
	Obj_Delete(obj);
}

//uses bossX/bossY in common data, diameter of circle at resting pulse (texture is 256x256), angle change per frame (0 for no spin)
//period of pulse (# of frames for one period, 0 for no pulse), amplitude of pulse (|amplitude| < 1, or texture gets inverted)
task frogOverlay(diameter, pulsePeriod, pulseAmplitude)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, frogOverlayTexture);
	Obj_SetRenderPriority(obj, 0.22);
	ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
	ObjRender_SetAlpha(obj, 0);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 256, 256);
	ObjSprite2D_SetDestCenter(obj);
	
	let scale = diameter / 256;
	let count = 0;
	let alpha = 0;
	
	while (GetCommonData("frogOverlay", true)) {
		ObjRender_SetPosition(obj, GetCommonData("bossX", getCenterX), GetCommonData("bossY", 90), 0);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		ObjRender_SetAlpha(obj, alpha);
		
		count++;
		scale = diameter / 128 - pulseAmplitude * sin((360 * count) / pulsePeriod);
		if (alpha < 225) {alpha += 255 / 60;}
		yield;
	}
	
	while (alpha > 0) {
		ObjRender_SetAlpha(obj, alpha);
		alpha -= 255 / 60;
		yield;
	}
	
	Obj_Delete(obj);
}

//bullet breaking effect (texture is 32x32)
task bulletBreak(x, y, scale)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, bulletBreakTexture);
	Obj_SetRenderPriority(obj, 0.65);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 32, 32);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, x, y, 0);
	ObjRender_SetScaleXYZ(obj, scale, scale, 1);
	
	let frames = 32;
	let count = frames;
	while (count > 0) {
		if (count > frames * (7 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 0, 0, 32, 32);
		} else if (count > frames * (6 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 32, 0, 64, 32);
		} else if (count > frames * (5 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 64, 0, 96, 32);
		} else if (count > frames * (4 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 96, 0, 128, 32);
		} else if (count > frames * (3 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 128, 0, 160, 32);
		} else if (count > frames * (2 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 160, 0, 192, 32);
		} else if (count > frames * (1 / 8)) {
			ObjSprite2D_SetSourceRect(obj, 192, 0, 224, 32);
		} else {
			ObjSprite2D_SetSourceRect(obj, 224, 0, 256, 32);
		}
		
		count--;
		yield;
	}
	
	Obj_Delete(obj);
}

//light concentrating inward (for bullet spawning, effect disappears when scale < 0)
//recommended: scale should be 1.5 - 2.0 times bullet size, frames should be around 10, colors MUST be below 5 if insignificant
task lightEffect(x, y, sScale, frames, r, g, b)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, lightTexture);
	Obj_SetRenderPriority(obj, 0.65);
	ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 64, 64);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, x, y, 0);
	ObjRender_SetColor(obj, r, g, b);
	
	let scale = sScale;
	loop (frames) {
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		
		scale -= sScale / frames;
		yield;
	}
	
	Obj_Delete(obj);
}

//large circle comes out from boss; x, y, increase in scale per frame, decrease in alpha per frame (recommended: 7, 0.1)
task concentrationCircle(x, y, dAlpha, dScale)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, concentrationCircleTexture);
	Obj_SetRenderPriority(obj, 0.65);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 256, 256);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, x, y, 0);
	
	let scale = 0;
	let alpha = 255;
	while (alpha > 0) {
		ObjRender_SetAlpha(obj, alpha);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);
		
		scale += dScale;
		alpha -= dAlpha;
		yield;
	}
	
	Obj_Delete(obj);
}

//x, y, decrease in alpha per frame, increase in scale per frame (recommended: 12, 0.5) (texture is 64 x 64)
task explosionEffect (x, y, dAlpha, dScale)
{
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, explosionTexture);
	Obj_SetRenderPriority(obj, 0.65);
	ObjRender_SetBlendType(obj, BLEND_ADD_RGB);
	ObjSprite2D_SetSourceRect(obj, 1, 1, 63, 63);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, x, y, 0);

	let scale = 0;
	let alpha = 255;
	while(alpha > 0)
	{
		ObjRender_SetColor(obj, alpha, alpha, alpha);
		ObjRender_SetScaleXYZ(obj, scale, scale, 1);

		scale += dScale;
		alpha -= dAlpha;
		yield;
	}
	Obj_Delete(obj);
}























