#include_function ".\cutin.dnh"
#include_function ".\lib\SHOT_REPLACE\shot_replace.dnh"
	// cutin function made by Helepolis. I modified it to look more CtC-like.
#include_function ".\animeSEC.dnh"
ACT_IDLE = 4; ACT_SPELL = 1; ACT_SHOOT = 1; ACT_MOVE = 0;
	// Explained inside.


let seCard1 = GetCurrentScriptDirectory ~ "cardcall.wav";
let seCard2 = GetCurrentScriptDirectory ~ "cardget.wav";
let shot = GetCurrentScriptDirectory ~ "shot.wav";
let bounce = GetCurrentScriptDirectory ~ "bounce.wav";
let shot2 = GetCurrentScriptDirectory ~ "shot2.wav";
let spr = GetCurrentScriptDirectory ~ "sprite.png";
let cutcut = GetCurrentScriptDirectory ~ "cutin2.png";
let bg2 = GetCurrentScriptDirectory ~ "bg2.png";
let lifebar = GetCurrentScriptDirectory ~ "lifebar.png";
let name = GetCurrentScriptDirectory ~ "name.png";
let isSurvival = false; let dmgrate = 1; let dmgratemax = 10; let dmgrateup = 1/30; let isaspell = 0;
	// All of this are just the variables for stuff.



@Initialize {
	SetTimer(45);
	LoadGraphic(textdata); LoadGraphic(cut); LoadGraphic(spr); LoadGraphic(lifebar); LoadGraphic(name);
	LoadGraphic(bg2);
		// Loading graphics.
	LoadSE(seCard1); LoadSE(seCard2); LoadSE(shot); LoadSE(shot2); LoadSE(bounce);
		// Loading sounds.
	shotinit; SetEffectForZeroLife(30, 2, 155);
		// Loading shotdata. Setting the effect for when the boss dies at the end of the fight.
	MagicCircle(false); SetEnemyMarker(true);
		// I don't like to see the magic circle, so...
	TMain;
}
@Finalize {
	if(GotSpellCardBonus) {
		loop(30) { CreateItem(ITEM_SCORE, GetX+rand(-75, 75), GetY+rand(-50, 50)); }
		CreateItem(ITEM_1UP, GetX+rand(-75, 75), GetY+rand(-50, 50));
		CreateItem(ITEM_BOMB, GetX+rand(-75, 75), GetY+rand(-50, 50));
		PlaySE(seCard2);
	} else { if(isaspell) { loop(10) { CreateItem(ITEM_SCORE, GetX+rand(-75, 75), GetY+rand(-50, 50)); } } }
		// Creating items at the end is always better than at the beginning of the next step.
	DeleteGraphic(textdata); DeleteGraphic(cut); DeleteGraphic(spr); DeleteGraphic(lifebar); DeleteGraphic(name);
	DeleteGraphic(bg2);
		// Deleting items.
}



function InvincibleConditions { return OnEnemySpell&&(OnBomb || GetTimeOfPlayerInvincibility > 0 || GetTimeOfSuperNaturalBorder > 0); }
	// Setting whether the boss should not be able to be hit.


let overridecollisions = false; let collCheck = false; let collA = 0; let collB = 0; let drA = 0; let drB = 0;
function Override(doOverride, collisions, cA, cB, damageA, damageB) {
	overridecollisions = doOverride;
	collCheck = collisions; collA = cA; collB = cB;
	drA = damageA; drB = damageB;
}
	// Ignore this.



@MainLoop {
	if(!overridecollisions) {
		if(!isSurvival) {
		SetCollisionA(GetX, GetY, 30); SetCollisionB(GetX, GetY, 10);
		SetDamageRate(dmgrate, [10,3][OnEnemySpell]); if(dmgrate<dmgratemax){dmgrate+=dmgrateup;}
		} else { SetDamageRate(0, 0); }
	} else {
		if(collCheck){SetCollisionA(GetX,GetY,collA);SetCollisionB(GetX,GetY,collB);}
		SetDamageRate(drA, drB);
	}
		// Basically, we are making the boss take certain amounts of damage according to however much time has passed.
	yield;
		// And of course, the yield for the boss fight to be a boss fight.
}
@DrawLoop {
	SetColor(255, 255, 255);
	CreateBossAnimation;
		// This one is explained in anime.dnh.
}
let bgy = 0;
@BackGround {
	ascent(i in -1..2) { SetTexture(bg2);
	SetGraphicRect(0, 0, 512, 512);
	SetColor(100, 100, 100);
	SetGraphicAngle(0, 0, 0);
	DrawGraphic(GetCenterX+50, GetCenterY+bgy+512*i); }
	bgy+=3; bgy%=512;
		// I'll just have a very simple background.
		// No extra pretty stuff, unlike my Victini scripts.
}



function wait(w) { loop(w) { yield; } }
function SE(sename) { PlaySE(GetCurrentScriptDirectory~sename~".wav"); }
function waitInv(w) { loop(w) { SetInvincibility(5); yield; } }
	// Waiting functions and sound playing functions.



sub ExMove { ExMove_(GetCenterY-100, 30, rand(15, 30)); }
function ExMove_(height, ud, length) {
	SetBossAnimation(BossMode_MOVE, 20);
	if(GetPlayerX < GetX) {
		if(GetX - length <= GetClipMinX) {
			SetMovePosition03(GetX + length, rand(height - ud, height + ud), 5, 11);
		} else {
			SetMovePosition03(GetX - length, rand(height - ud, height + ud), 5, 11);
		}
	} else {
		if(GetX + length >= GetClipMaxX) {
			SetMovePosition03(GetX - length, rand(height - ud, height + ud), 5, 11);
		} else {
			SetMovePosition03(GetX + length, rand(height - ud, height + ud), 5, 11);
		}
	}
}
	// Movement functions for the boss to move towards the player.

function sec(n) { return 1/cos(n); } // secant function
function csc(n) { return 1/sin(n); } // cosecant function
function cot(n) { return 1/tan(n); } // cotangent function


function GetLineBorderPoint(px, py, tx, ty) {
	let ta = atan2(ty-py, tx-px);
	if( ta>= atan2(GetClipMinY - py, GetClipMinX - px) && ta<=  atan2(GetClipMinY - py, GetClipMaxX - px)){
		return [px - (GetClipMinY-py)*tan(ta+90), GetClipMinY];
	}
	if( ta>= atan2(GetClipMinY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMaxX - px)){
		return [GetClipMaxX, py + (GetClipMaxX-px)*tan(ta)];
	}
	if( ta>= atan2(GetClipMaxY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMinX - px)){
		return [px - (GetClipMaxY-py)*tan(ta-90), GetClipMaxY];
	}
	if( ta> atan2(GetClipMaxY - py, GetClipMinX - px) || ta<  atan2(GetClipMinY - py, GetClipMinX - px)){
		return [GetClipMinX, py + (GetClipMinX-px)*tan(ta+180)];
	}
} // a function for getting a point on the border. Iryan coded it, I think.





// The rest of the text file you don't need to look into. ////////////////////////////////////////////////////////////////

function ObjEffect_InitializeRect(texture, layer) { let obj = Obj_Create(OBJ_EFFECT); ObjEffect_SetTexture(obj, texture); ObjEffect_SetLayer(obj, layer); ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN); ObjEffect_CreateVertex(obj, 4); return obj; }
function ObjEffect_SetUVRect(id, left, top, right, bottom) { ObjEffect_SetVertexUV(id, 0, left, top); ObjEffect_SetVertexUV(id, 1, right, top); ObjEffect_SetVertexUV(id, 2, right, bottom); ObjEffect_SetVertexUV(id, 3, left, bottom); }
function ObjEffect_SetXYRect(id, left, top, right, bottom) { ObjEffect_SetVertexXY(id, 0, left, top); ObjEffect_SetVertexXY(id, 1, right, top); ObjEffect_SetVertexXY(id, 2, right, bottom); ObjEffect_SetVertexXY(id, 3, left, bottom); }
function ObjEffect_SetColor(id, vertexes, a, r, g, b) { ascent(i in 0..vertexes) { ObjEffect_SetVertexColor(id, i, a, r, g, b); } }
task EffectObject(img,lyr,xyL,xyT,xyR,xyB,uvL,uvT,uvR,uvB,alpha,r1,g1,b1,r2,g2,b2){let obj=ObjEffect_InitializeRect(img,lyr);ObjEffect_SetXYRect(obj,xyL,xyT,xyR,xyB);ObjEffect_SetUVRect(obj,uvL,uvT,uvR,uvB);ascent(i in 0..2){ObjEffect_SetVertexColor(obj,i,alpha,r1,g1,b1);}ascent(i in 2..4){ObjEffect_SetVertexColor(obj,i,alpha,r2,g2,b2);}wait(2);Obj_Delete(obj);}
let XtoX = (GetClipMaxX-40)-GetClipMinX; let XtoXA = (GetClipMaxX-40)-GetClipMinX;
task CreateLifebar(type, ratio) {
	let firstlife = GetEnemyLife; let fillbar = 0; if(type != 1) { XtoX*=ratio; } yield;

	// Life bar backing
	let objb = ObjEffect_InitializeRect(lifebar, 4);
	Obj_SetPosition(objb, GetClipMinX, GetClipMinY); ObjEffect_SetColor(objb, 4, 255, 100, 100, 100); ObjEffect_SetUVRect(objb, 0, 0, 2, 16);
	ObjEffect_SetXYRect(objb, 0, 0, XtoXA, 16);

	// This life bar
	let obj = ObjEffect_InitializeRect(lifebar, 4); ObjEffect_SetUVRect(obj, 0, 0, 2, 16);
	Obj_SetPosition(obj, GetClipMinX, GetClipMinY); ObjEffect_SetColor(obj, 4, 255, 255, [255, 155, 155, 155][type], [255, 155, 155, 155][type]);
	if(type == 0 || type == 3) { Obj_SetX(obj, GetClipMinX+(XtoXA)*(1-ratio)); }

	// Next life bar (spell card segment)
	let obj2 = ObjEffect_InitializeRect(lifebar, 4);
	Obj_SetPosition(obj2, GetClipMinX, GetClipMinY); ObjEffect_SetColor(obj2, 4, 255, 255, 155, 155); ObjEffect_SetUVRect(obj2, 0, 0, 2, 16);
	ObjEffect_SetXYRect(obj2, 0, 0, (1-ratio)*XtoXA, 16);
	if(type == 1 || type == 2) { Obj_Delete(obj2); }

	// Name drawing
	let nameobj = ObjEffect_InitializeRect(name, 4); ObjEffect_SetUVRect(nameobj, 0, 0, 128, 16); ObjEffect_SetXYRect(nameobj, 0, 0, 128, 16);
	Obj_SetPosition(nameobj, GetClipMinX, GetClipMinY); ObjEffect_SetScale(nameobj, 3/4, 3/4); ObjEffect_SetColor(nameobj, 4, 255, 255, 255, 255);
	loop {
		let nowlife = GetEnemyLife;
		ObjEffect_SetXYRect(obj, 0, 0, fillbar*(nowlife/firstlife), 16);
		if(type == 0 || type == 2 || type == 3) { if(fillbar<XtoX){fillbar+=XtoX/50;} } else { fillbar = XtoX*(1-ratio); }
		yield;
	}
}