#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["Ballerina spell 02 normal"]
#Text["Ballerina spell 02 normal"]

let tornadoanim = 0;
let flipper = 0;
let graaftrigger = 0;
let zuigrichting = 0;
let firsttime = true;

#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 {
	SetCommonData("spellScriptID",GetOwnScriptID);
	
	renderBoss(1);
	setAura(bossObj,255,64,255);
	SetCommonData("bossCircleType",1);
	SetCommonData("bossAttackType",2);
	SetCommonData("bossBgType",1);
	if(GetAreaCommonData("system","gameLang",0) == 0) { SetCommonData("cardName","sGbguFv"); } 
	if(GetAreaCommonData("system","gameLang",0) == 1) { SetCommonData("cardName","Pirouette uEastern Tornadov"); } 	
	setInvulnerableTime(bossObj,120);	
	
	concenEffect(bossObj,60,2,255,64,128);
	ObjMove_SetDestAtSpeed(bossObj,192,120,5);
	SetAutoDeleteObject(true);
	mainTask;
} 

@Event { 
	alternative(GetEventType()) 
	case(EV_REQUEST_LIFE) { 
		SetScriptResult(200);
	}
	case(EV_REQUEST_TIMER) { 
		SetScriptResult(65);
	}
	case(EV_REQUEST_SPELL_SCORE) {
	    let spellCardBonus = calculateAndGetSpellCardBonus();
		SetScriptResult(spellCardBonus);
	}
	case(EV_USER+9999) {
		SetCommonData("spellcardID","pierre02norm"); 
	}	
}

@MainLoop { yield; } 
@Finalize { }  

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

// Movement pattern 
task movement { 
	let pinpointX = 0;
	let randwacht = 0;
	hurricane(GetEnemyX,GetEnemyY-128);
	tornadoanim = 0;
	
	while(!Obj_IsDeleted(bossObj)) {
		// primary attack pattern, only executed once.
		if(firsttime) { 			
			bossAttack = 1;
			concenEffect(bossObj,20,2,255,64,128);
			concenEffect(bossObj,20,1,255,64,255);
			PlaySFX(SFX_POWER0);
			wait(60);
			tornadoanim = 1; bossAttack = 9;
			if(GetPlayerX > GetCenterX && firsttime) { 	
				ObjMove_SetDestAtWeight(bossObj,GetCenterX-150,GetClipMaxY-48,10,30);
				wait(15);
				impact; 
				graaftrigger = 1;
				wait(15);
				ObjMove_SetDestAtSpeed(bossObj,GetClipMaxX-32,GetEnemyY,3);
				wait(100);
				graaftrigger = 0;
				ObjMove_SetDestAtWeight(bossObj,ObjMove_GetX(bossObj),120,10,30);
				tornadoanim = 0; bossAttack = 0;
				wait(60);
				firsttime = false;	
			} 
			if(GetPlayerX <= GetCenterX && firsttime) { 
				ObjMove_SetDestAtWeight(bossObj,GetCenterX+150,GetClipMaxY-48,10,30); 
				wait(15);
				impact;
				graaftrigger = 1;
				wait(15);
				ObjMove_SetDestAtSpeed(bossObj,GetClipMinX-32,GetEnemyY,3);
				wait(100);
				graaftrigger = 0;
				ObjMove_SetDestAtWeight(bossObj,ObjMove_GetX(bossObj),120,10,30);
				tornadoanim = 0; bossAttack = 0;
				wait(60);
				firsttime = false;					
			}
			concenEffect(bossObj,60,2,255,64,128);
			PlaySFX(SFX_POWER0);			
			wait(45);
			concenEffect(bossObj,45,1,255,64,255);
			concenEffect(bossObj,45,1,64,64,255);
			concenEffect(bossObj,45,1,64,255,255);
			PlaySFX(SFX_CH02);	
			wait(15);
		}
		randwacht = rand(45,90);
		loop(randwacht) { 
			ObjMove_SetDestAtWeight(bossObj,GetPlayerX,48,10,30);
			yield;
		}
		tornadoanim = 0; bossAttack = 1;
		concenEffect(bossObj,20,2,255,64,128);
		concenEffect(bossObj,20,1,255,64,255);
		PlaySFX(SFX_CH02);
		pinpointX = GetPlayerX;
		wait(60);
		impact;
		tornadoanim = 1; bossAttack = 9;
		ObjMove_SetDestAtWeight(bossObj,pinpointX,GetClipMaxY-48,10,30);
		wait(30);
		graaftrigger = 1;
		loop(180) { 
			ObjMove_SetDestAtSpeed(bossObj,GetPlayerX,GetEnemyY,1);
			yield;
		}
		tornadoanim = 0; bossAttack = 0; graaftrigger = 0;
		wait(30);
		ObjMove_SetDestAtWeight(bossObj,ObjMove_GetX(bossObj),120,10,30);
		wait(120);
	}
}

task impact {
	let speed = 0;
	quakeCam2D(15,30);
	PlaySFX(SFX_INFERNO);
	PlaySFX(SFX_QUAKE);
	if(firsttime) { 
		ascent(i in 0..8) { 
			speed = rand_int(-2,-6);
			CreateShotB2(GetEnemyX,GetClipMaxY,rand(-3,3),speed,0,rand(0.04,0.08),0,rand(0.3,3),203,5);
			CreateShotB2(GetEnemyX,GetClipMaxY,rand(-3,3),speed,0,rand(0.04,0.08),0,rand(0.3,3),94,5);
			yield;
		}
	}
	if(!firsttime) { 
		ascent(i in 0..24) { 
			speed = rand_int(-1,-7);
			CreateShotB2(GetEnemyX,GetClipMaxY,rand(-3,3),speed,0,rand(0.04,0.08),0,rand(0.3,3),203,5);
			CreateShotB2(GetEnemyX,GetClipMaxY,rand(-3,3),speed,0,rand(0.04,0.08),0,rand(0.3,3),94,5);
			yield;
		}	
	}
	yield;
}

task digger {
	let speed = 0;
	while(!Obj_IsDeleted(bossObj)) {
		if(firsttime) { 
			while(graaftrigger == 1) {
				speed = rand_int(-1,-4);
				CreateShotB2(GetEnemyX,GetClipMaxY,rand(-2,3),speed,0,0.04,0,rand(0.3,3),203,5);
				CreateShotB2(GetEnemyX,GetClipMaxY,rand(-2,3),speed,0,0.04,0,rand(0.3,3),94,5);
				wait(5);
			}
		}
		if(!firsttime) { 
			while(graaftrigger == 1) {
				speed = rand(-1,-6.5);
				CreateShotB2(GetEnemyX,GetClipMaxY,rand(-2,3),speed,0,0.04,0,rand(0.3,3),203,5);
				CreateShotB2(GetEnemyX,GetClipMaxY,rand(-2,3),speed,0,0.04,0,rand(0.3,3),94,5);
				wait(5);
			}		
		}
		yield;
	}
}

// Suction for the hurricane attack
task suction {

	let v = 0;		// adjust the suction strenght with this. 
	let dir = 0;
	
	let vx = v * cos(dir);
	let vy = v * sin(dir);
	let x = GetPlayerX;
	let y = GetPlayerY;
	
	// required to locate playerID
	let locPlayerID = GetPlayerObjectID;

	while(!Obj_IsDeleted(bossObj)) {
		x = GetPlayerX;
		y = GetPlayerY;
		
		// calculate angle between player and boss and set direction proper
		dir = GetPointToPointAngle(GetEnemyX,GetEnemyY,GetPlayerX,GetPlayerY);
		ObjMove_SetAngle(locPlayerID,dir);
		vx = v * cos(dir);
		vy = v * sin(dir);
		
		// while hurricane is active, move the player towards the boss (suction)
		if(graaftrigger == 1) { 
			ObjRender_SetPosition(locPlayerID,x+vx,y+vy,0);
			yield;
		} 
		yield;
	}
}

// tornado animatie
task hurricane(x,y){
	let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);

	let i = 0;
	let alphaValue = 0;
	let blaas = 0;
	
	ObjRender_SetPosition(obj,x,y,0);
	ObjPrim_SetTexture(obj,hurri);
	ObjPrim_SetPrimitiveType(obj,PRIMITIVE_TRIANGLESTRIP);
	ObjPrim_SetVertexCount(obj,8);
	ObjRender_SetBlendType(obj,BLEND_ADD_ARGB);
	Obj_SetRenderPriority(obj,0.4);

	while(!Obj_IsDeleted(obj)) {

		// rebuild de tornado
		ObjPrim_SetVertexPosition(obj, 0, -112+rand_int(1,10), -192,0);
		ObjPrim_SetVertexUVT(obj, 0, 0+blaas, 0);	
		ObjPrim_SetVertexPosition(obj, 1, 112+rand_int(1,10), -192,0);
		ObjPrim_SetVertexUVT(obj, 1, 128+blaas, 0);
		ObjPrim_SetVertexPosition(obj, 2, -72+rand_int(1,10), -64,0);
		ObjPrim_SetVertexUVT(obj, 2, 0+blaas, 128);
		ObjPrim_SetVertexPosition(obj, 3, 72+rand_int(1,10), -64,0);
		ObjPrim_SetVertexUVT(obj, 3, 128+blaas, 128);	
		ObjPrim_SetVertexPosition(obj, 4, -48+rand_int(1,10), 64,0);
		ObjPrim_SetVertexUVT(obj, 4, 0+blaas, 0);	
		ObjPrim_SetVertexPosition(obj, 5, 48+rand_int(1,10), 64,0);
		ObjPrim_SetVertexUVT(obj, 5, 128+blaas, 0);	
		ObjPrim_SetVertexPosition(obj, 6, -16+rand_int(1,10), 224,0);
		ObjPrim_SetVertexUVT(obj, 6, 0+blaas, 128);	
		ObjPrim_SetVertexPosition(obj, 7, 16+rand_int(1,10), 224,0);
		ObjPrim_SetVertexUVT(obj, 7, 128+blaas, 128);
		
		ObjRender_SetAlpha(obj,alphaValue);

		blaas -= 10;
		
		if(tornadoanim == 1) { if (alphaValue < 240) { alphaValue += 2; } } 
		if(tornadoanim == 0) { if (alphaValue > 0) { alphaValue -= 10; } } 
		ObjRender_SetPosition(obj,GetEnemyX,GetEnemyY-128,0);
		yield;
	}
}

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

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

	CloseScript(GetOwnScriptID());
}



