#TouhouDanmakufu[Player]
#ScriptVersion[3]
#ID["Invincible Kid"]
#Title["Invincible Kid"]
#Text["Player character from [r] \"I Wanna Be the Guy \" [r] This character cannot die [r] see the whole script [r] shift: focus/ slowmovement [r] z : shoot (does not hurt boss) [r] esc : pause [r]direction keys : movement"]
#Image["./img/kid_select.png"]
#ReplayName["Kid"]

//#include "./lib/usefulFunctions.dnh"
let CSD = GetCurrentScriptDirectory;
let playerID = GetPlayerObjectID;
let playerObj = ObjPrim_Create(OBJ_SPRITE_2D);
let bowObj = ObjPrim_Create(OBJ_SPRITE_2D);
let hitboxObj = ObjPrim_Create(OBJ_SPRITE_2D);
let count = -1;
let isFocus = false;
let shotSE;
let deathSE;
let spikeSE;
let gameOverSE;
let MovementAngle =0;

//shot sheet
let shotKid = CSD ~ "kidshot.dnh";

//texture sheet
let playerSprite = CSD ~"/img/kid.png";



@Initialize{
	//load player shot data
	LoadPlayerShotData(shotKid);
	
	// set player unfocused and focused speed
	SetPlayerSpeed(4.5, 2.3);
	
	// set player hitbox parameters (playerobject,locationX,locationY,radius,grazeradius)
	ObjPlayer_AddIntersectionCircleA1(playerID, 0, 0, 0, 16);
	SetPlayerInvincibilityFrame(99999);
	
	// set the boundary box for the game field. players cannot move beyond theses points
	// get stgFrame width == 384 stgFrameHeight == 448
	SetPlayerClip(8,8,GetStgFrameWidth-8,GetStgFrameHeight-8);
	
	// set time untill respawn
	SetPlayerDownStateFrame(45);
	
	// deathbomb time frame
	SetPlayerRebirthFrame(20);
	
	// set y coordinate for auto collection
	SetPlayerAutoItemCollectLine(120);
	
	// two tasks to handle the animation
	renderPlayer;
	renderHitBox(GetPlayerX,GetPlayerY);
	
	shotSE = CreateSFX(CSD ~ "./se/sndShoot.wav",45);
	deathSE = CreateSFX(CSD ~ "./se/sndDeath.wav",75);
	spikeSE = CreateSFX(CSD ~ "./se/sndSpikeTrap.wav",80);
	gameOverSE = CreateSFX(CSD ~ "./se/musOnDeath.mp3",85);
	
}

@Event{
	alternative(GetEventType)
	
	//Spell card
	case(EV_REQUEST_SPELL){
		if(GetPlayerSpell > 0){
			SetScriptResult(true);
		}else{
			SetScriptResult(false);
		}
	
	}
	//player dies
	case(EV_PLAYER_SHOOTDOWN){
		SetForbidPlayerShot(true);
		SetForbidPlayerSpell(true);
		ObjRender_SetAlpha(playerObj,0);
		ObjSound_Play(deathSE);
		loop(50){
			bloodEffect(GetPlayerX,GetPlayerY,rand(-3,3),rand(0,360),1,30,0.08);
		}
	
	}
	//player is reviving
	case(EV_PLAYER_REBIRTH){
		SetForbidPlayerShot(false);
		SetForbidPlayerSpell(false);
		SetPlayerInvincibilityFrame(120);
		SetPlayerSpell(3);
		ObjRender_SetAlpha(playerObj,255);
	}
	
}

@MainLoop{
	if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD || GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH){
			isFocus = true;
	}else if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_PULL){
			isFocus = false;
	
	}
	if(IsPermitPlayerShot){
		if(GetVirtualKeyState(VK_SHOT) == KEY_PUSH || GetVirtualKeyState(VK_SHOT) == KEY_HOLD){
			count++;
			if(count>=5){
				let shot = CreatePlayerShotA1(GetPlayerX+6*(-1)^(MovementAngle),GetPlayerY-15,15,270,15,1,1);//~170 dps
				ObjSound_Play(shotSE);
				//ObjRender_SetScaleXYZ(shot, 2, 2, 0);
				count = 0;
			}
		}
		if(GetVirtualKeyState(VK_SHOT) == KEY_PULL){
				count = -1;
		}
		
	
	
	}
	
	
	
	yield;
}

//render the player
task renderPlayer{
	let RectX =0;
	let RectY = 0;
	let A_time = 0;
	let PastPositionX =0;
	let PastPositionY =0;
	
	ObjPrim_SetTexture(playerObj, playerSprite);
	Obj_SetRenderPriorityI(playerObj, 35);
	ObjRender_SetBlendType(playerObj,BLEND_ALPHA);
	ObjRender_SetAngleXYZ(playerObj, 0,0,0);
	ObjRender_SetScaleXYZ(playerObj, 1, 1, 0);
	ObjRender_SetAlpha(playerObj, 255);
	ObjSprite2D_SetSourceRect(playerObj, 0, 0, 32,32);
	ObjSprite2D_SetDestCenter(playerObj);
	//ObjSprite2D_SetDestRect(playerObj, -16+28, -16, 16+28, 16);
	ObjRender_SetPosition(playerObj,GetPlayerX,GetPlayerY,0);
	bow();	
	
	while(!Obj_IsDeleted(playerObj)){
	
		if(GetVirtualKeyState(GetVirtualKeyState(VK_LEFT) == KEY_HOLD || VK_LEFT) == KEY_PUSH){
			RectY = 0;
			RectX = 1;
			MovementAngle = 1;
			A_time = 0;
			XRender();
		}else if(GetVirtualKeyState(VK_RIGHT) == KEY_HOLD || GetVirtualKeyState(VK_RIGHT) == KEY_PUSH){
			RectY = 0;
			MovementAngle = 0;
			A_time = 0;
			XRender();
		}else{
			RectY = 0
		}
		if(GetVirtualKeyState(VK_SHOT) == KEY_HOLD || GetVirtualKeyState(VK_SHOT) == KEY_PUSH){
			RectY = 1;
			A_time = 0;
			XRender();
		}

		//let InvFrame = GetPlayerInvincibilityFrame()%2;
		let RectX = (truncate(A_time/6))%2;
		A_time++;
		
		ObjSprite2D_SetSourceRect(playerObj, 32*RectX, 32*RectY, 32*RectX + 32, 32*RectY + 32);
		ObjRender_SetScaleXYZ(playerObj, 1, 1, 0);
		ObjRender_SetAngleY(playerObj, 180*MovementAngle);
		ObjSprite2D_SetDestCenter(playerObj);

		//ObjRender_SetAlpha(playerObj, 255-223*InvFrame);
				
		function XRender(){
			if(A_time >= 32){
				A_time -= 20;
			}
		}
	
		ObjRender_SetPosition(playerObj,GetPlayerX,GetPlayerY,0);
		PastPositionX = GetPlayerX;
		PastPositionY = GetPlayerY;
		yield;
	
	
	
	}
	
	task bow(){
			let BowAngle = 0;
			
			ObjPrim_SetTexture(bowObj, playerSprite);
			Obj_SetRenderPriorityI(bowObj, 36);
			ObjRender_SetBlendType(bowObj,BLEND_ALPHA);
			ObjRender_SetAngleXYZ(bowObj, 0,0,0);
			ObjRender_SetScaleXYZ(bowObj, 1, 1, 0);
			ObjRender_SetAlpha(bowObj, 255);
			ObjSprite2D_SetSourceRect(bowObj, 82, 0, 114, 32);
			ObjSprite2D_SetDestCenter(bowObj);
			ObjRender_SetPosition(bowObj,GetPlayerX,GetPlayerY,0);
		
			while(!Obj_IsDeleted(playerObj)){
				ObjRender_SetPosition(bowObj,PastPositionX-1+2*MovementAngle,PastPositionY-4,0);
				if(GetVirtualKeyState(GetVirtualKeyState(VK_LEFT) == KEY_HOLD || VK_LEFT) == KEY_PUSH){
					BowAngle = 1;
				}else if(GetVirtualKeyState(VK_RIGHT) == KEY_HOLD || GetVirtualKeyState(VK_RIGHT) == KEY_PUSH){
					BowAngle = 0;
				}
				ObjRender_SetAngleY(bowObj, 180*BowAngle);
				yield;
			}		
			
		}

}

//render the hitbox
task renderHitBox(x,y){
	let alpha = 0;
	let spin = 0;
	
	ObjPrim_SetTexture(hitboxObj,playerSprite);
	ObjRender_SetBlendType(hitboxObj,BLEND_ALPHA);
	Obj_SetRenderPriorityI(hitboxObj,50);
	ObjRender_SetAlpha(hitboxObj,0);
	ObjRender_SetScaleXYZ(hitboxObj,1,1,0);
	ObjSprite2D_SetSourceRect(hitboxObj, 0, 192, 64, 255);
	ObjSprite2D_SetDestCenter(hitboxObj);
	
	while(!Obj_IsDeleted(hitboxObj)){
		if(GetVirtualKeyState(VK_SLOWMOVE) == KEY_HOLD || GetVirtualKeyState(VK_SLOWMOVE) == KEY_PUSH){
			// fade in alpha
			alpha = min(alpha+7.5,255);
		}else{
			alpha = 0;
		}
		ObjRender_SetPosition(hitboxObj,GetPlayerX,GetPlayerY,0);
		ObjRender_SetAngleZ(hitboxObj,spin);
		ObjRender_SetAlpha(hitboxObj,alpha);
		
		//makes hitbox rotate
		spin+=2;
		
		
		
		yield;
	
	}
	
}

function CreateSFX(path, volume){
    let obj = ObjSound_Create();
    ObjSound_Load(obj, path);
    ObjSound_SetSoundDivision(obj, SOUND_SE);
    ObjSound_SetVolumeRate(obj, volume);
    return obj;
}

task bloodEffect(startX,startY,startSpeed,angle,graphic,time,gravConst){
	let randI = floor(rand(0,3));
	let bloodObj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(bloodObj,playerSprite);
	Obj_SetRenderPriorityI(bloodObj,50);
	ObjRender_SetAlpha(bloodObj,255);
	ObjRender_SetScaleXYZ(bloodObj,2,2,0);
	ObjSprite2D_SetSourceRect(bloodObj, 64+randI, 36, 68+randI, 40);
	ObjSprite2D_SetDestCenter(bloodObj);

	
	let timer =0;
	
	while(timer<=time){
		ObjRender_SetPosition(bloodObj,startX+cos(angle)*timer*startSpeed,startY+sin(angle)*(-startSpeed*timer)+gravConst*(timer^2),0);
		timer++;
		if(timer == time){
			Obj_Delete(bloodObj);
		}
		yield;
	}
}


@Finalize{}
