#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Dj non-spell 05 hard"]
#Text["Dj non-spell 05 hard"]

let famTex = "script/thdcs/system/effects/fammer.png";

#include "script/thdcs/system/shotlibrary.txt"
#include "script/thdcs/functions/function_common.txt"
#include "script/thdcs/functions/function_global.txt"
#include "script/thdcs/functions/function_bosseff.txt"

@Initialize {
	renderBoss(3);
	setAura(bossObj,64,255,128);
	SetCommonData("bossAttackType",1);
	SetCommonData("bossCircleType",0);
	setInvulnerableTime(bossObj,120);	
	
	concenEffect(bossObj,30,5,64,128,64);
	concenEffect(bossObj,30,5,128,128,128);
	concenEffect(bossObj,60,1,64,64,255);
	concenEffect(bossObj,60,1,64,255,64);
	
	ObjMove_SetDestAtSpeed(bossObj,192,120,5);
	SetShotAutoDeleteClip(16,16,16,16);
	SetAutoDeleteObject(true);
	mainTask;
} 

@Event { 
	alternative(GetEventType()) 
	case(EV_REQUEST_LIFE) { 
		SetScriptResult(300);
	}
	case(EV_REQUEST_TIMER) { 
		SetScriptResult(57);
	}
} 

@MainLoop { yield; } 
@Finalize { } 


task mainTask { 
	yield;
	scriptEnding;	
	wait(90);
	control;
	movement;
} 


// control
task control { 
	let dir = 0;
	while(!Obj_IsDeleted(bossObj)) { 
		recordRunBullet(bossX,bossY,5,25,rand_int(247,251),0);
		PlaySFX(SFX_SLASH);	
		movementFX;
		wait(120);
	}
}

// movement
task movement { 
	while(!Obj_IsDeleted(bossObj)) { 
		ObjMove_RandomPosWeight(bossObj,rand(10,20),rand(10,20),10,30,GetClipMinX+72,GetClipMinY+64,GetClipMaxX-72,GetCenterY-120);	
		wait(180);
	}
}

// crazy spin
task movementFX {
	let spin = 0;
	loop(36) { 
		ObjRender_SetAngleZ(bossObj,spin);	
		spin-=20;
		yield;
	}
}

// Record bullet
task recordRunBullet(x,y,v,dir,graphic,delay) {
	let obj = ObjShot_Create(OBJ_SHOT);
	
	let initialBounce = false;		// initial bounce bool
	let numBounce = 0;				// numBounce to track how many corners to check before ignoring
	let adjustDir = [];				// adjust dir array for neatolock function
	let nextx = 0;
	let nexty = 0;
	
	ObjShot_Regist(obj);
	ObjMove_SetPosition(obj,x,y);
	ObjMove_SetSpeed(obj,v);
	ObjMove_SetAngle(obj,dir);
	ObjShot_SetGraphic(obj,graphic);
	ObjShot_SetDelay(obj,delay);
	ObjShot_SetSpellResist(obj,true);
	
	recordFX(obj,graphic);
	
	while(!Obj_IsDeleted(obj)) {	
		// track x y with radius to avoid corners
		nextx = ObjMove_GetX(obj)+14*cos(dir);
		nexty = ObjMove_GetY(obj)+14*sin(dir);	
		ObjMove_SetAngle(obj,dir);	
		
		// after initial bounce, check the walls and apply 
		if(nextx < GetClipMinX || nextx > GetClipMaxX || nexty < GetClipMinY || nexty > GetClipMaxY) { 
			if(initialBounce && numBounce < 4) {
				adjustDir = GetNeatoLockAngle(dir); dir+=adjustDir[1]; 
				numBounce++;
			}
		}
		// initial bounce, apply neato lock function and set angle
		if(ObjMove_GetX(obj) < GetClipMinX+8 || ObjMove_GetX(obj) > GetClipMaxX-8 || ObjMove_GetY(obj) < GetClipMinY+8 || ObjMove_GetY(obj) > GetClipMaxY-8) {
			if(!initialBounce && numBounce < 4) {
				initialBounce = true;			
				adjustDir = GetNeatoLockAngle(dir);
				dir = adjustDir[1];
				recordRunFire(obj,graphic);
				ObjMove_SetSpeed(obj,0);
				ObjMove_SetAcceleration(obj,0.05);
				ObjMove_SetMaxSpeed(obj,8);
				PlaySFX(SFX_CHARGE00);	
				numBounce++;
			}
		}
		yield;
	}
}

// Fire trail
task recordFX(obj,graphic) {
	let dir = 0;
	let r = 0;
	while(!Obj_IsDeleted(obj)) {	
		dir = rand_int(0,360);
		r = rand_int(16,32);
		let effShot = CreateShotA(ObjMove_GetX(obj)+r*cos(dir),ObjMove_GetY(obj)+r*sin(dir),25);
		SetShotDataA(effShot,0,0,0,0,0,0,graphic);
		DeleteShotA(effShot,0);
		yield;
	}
}

// record fire shot
task recordRunFire(obj,graphic) {

	let aaaa = ObjText_Create;
	ObjRender_SetPosition(aaaa,0,400,0);
	
	wait(2);
	let r = 0; let g = 0; let b = 0;
	// LP to amulet shot colour changer
	if(graphic == 247) { graphic = 95; r = 255; g = 255; b = 255; }
	if(graphic == 248) { graphic = 96; r = 255; g = 64; b = 64; }
	if(graphic == 249) { graphic = 99; r = 64; g = 64; b = 255; }
	if(graphic == 250) { graphic = 104; r = 64; g = 255; b = 64; }
	if(graphic == 251) { graphic = 101; r = 64; g = 128; b = 255; }
	if(graphic == 252) { graphic = 97; r = 255; g = 64; b = 255; }
	if(graphic == 253) { graphic = 107; r = 255; g = 128; b = 64; }
	if(graphic == 254) { graphic = 106; r = 255; g = 255; b = 64; }
	wait(25);
	
	ascent(i in 0..128) { 
		if(!Obj_IsDeleted(obj)) { 
			PlaySFX(SFX_TAN00);	
			breakEffectGlitter(ObjMove_GetX(obj)+10*cos(ObjMove_GetAngle(obj)),ObjMove_GetY(obj)+10*sin(ObjMove_GetAngle(obj)),3,ObjMove_GetAngle(obj)+rand_int(-45,45),rand(3.5,4.5),255,r,g,b);
			CreateShotA2(ObjMove_GetX(obj),ObjMove_GetY(obj),0.5,ObjMove_GetAngle(obj)+90,0.01,rand(1,1.5),graphic,0);
		}
		wait(rand_int(6,8));
	}	
}

// Drake's neat lock angle code
function GetNeatoLockAngle(angle) {
    return [round(angle/90)*90 , round((angle%90)/90)*-180+90];
}

task scriptEnding {
	while(ObjEnemy_GetInfo(bossObj, INFO_LIFE) > 0) {
		yield;
	}

	DeleteShotAll(TYPE_ALL, TYPE_ITEM);
	Obj_Delete(bossObj);

	CloseScript(GetOwnScriptID());
}
 