//---------------------------------------------------------------------------------
// Position Calculation Functions
//---------------------------------------------------------------------------------

function Pos_IsInBoundaries(let pX, let pY, let rLimit){
	if(pX <= MinX-rLimit || pX >= MaxX+rLimit || pY <= MinY-rLimit || pY >= MaxY+rLimit){
		return false;
	}else{
		return true;
	}
}

function Obj_IsInBoundaries(let objTarget, let rLimit){
	let oX = ObjMove_GetX(objTarget);
	let oY = ObjMove_GetY(objTarget);
	if(oX <= MinX-rLimit || oX >= MaxX+rLimit || oY <= MinY-rLimit || oY >= MaxY+rLimit){
		return false;
	}else{
		return true;
	}
}

function Pos_IsInWideScreen(let pX, let pY, let rLimit){
	if(pX <= AbsMinX-rLimit || pX >= AbsMaxX+rLimit || pY <= AbsMinY-rLimit || pY >= AbsMaxY+rLimit){
		return false;
	}else{
		return true;
	}
}

function Obj_IsInWideScreen(let objTarget, let rLimit){
	let oX = ObjMove_GetX(objTarget);
	let oY = ObjMove_GetY(objTarget);
	if(oX <= AbsMinX-rLimit || oX >= AbsMaxX+rLimit || oY <= AbsMinY-rLimit || oY >= AbsMaxY+rLimit){
		return false;
	}else{
		return true;
	}
}

//---------------------------------------------------------------------------------
// ObjMove Functions
//---------------------------------------------------------------------------------

function ObjMove_SetPositionToObj(let objTarget, let objSource){
	let oX = ObjMove_GetX(objSource);
	let oY = ObjMove_GetY(objSource);
	ObjMove_SetPosition(objTarget,oX,oY);
}

function ObjRender_SetPositionToObj(let objTarget, let objSource){
	let oX = ObjMove_GetX(objSource);
	let oY = ObjMove_GetY(objSource);
	ObjRender_SetPosition(objTarget,oX,oY,0);
}

function ObjMove_SetVector(let objTarget, let vtSpeed, let vtAngle){
	ObjMove_SetSpeed(objTarget,vtSpeed);
	ObjMove_SetAngle(objTarget,vtAngle);
}

function ObjMove_SetVirtualSpeed(let objTarget, let vSpeed){
	Obj_SetValue(objTarget,"VIRTUAL_SPEED",vSpeed);
}

function ObjMove_GetVirtualSpeed(let objTarget){
	return Obj_GetValueD(objTarget,"VIRTUAL_SPEED",0);
}

function ObjMove_SetGravityAngle(let objTarget, let gAngle){
	Obj_SetValue(objTarget,"GRAVITY_ANGLE",gAngle);
}

function ObjMove_GetGravityAngle(let objTarget){
	return Obj_GetValueD(objTarget,"GRAVITY_ANGLE",0);
}

task ObjMove_SetHomingToPlayerA1(let objTarget, let maxTurn){
	let setAngle = modc(ObjMove_GetAngle(objTarget),360);
	ObjMove_SetHomingAngle(objTarget,maxTurn);
	while(!Obj_IsDeleted(objTarget)){
		let toPlayer = modc(GetAngleToPlayer(objTarget),360);
		let difAngle = modc(toPlayer-setAngle,360);
		if(absolute(difAngle) < ObjMove_GetHomingAngle(objTarget)){
			setAngle = toPlayer;
		}else{
			if(sin(difAngle) > 0){
				setAngle += ObjMove_GetHomingAngle(objTarget);
			}else{
				setAngle -= ObjMove_GetHomingAngle(objTarget);
			}
		}
		setAngle = modc(setAngle,360);
		ObjMove_SetAngle(objTarget,setAngle);
		yield;
	}
}

task ObjMove_SetHomingToPlayerA2(let objTarget, let maxTurn, let frameTime){
	let setAngle = modc(ObjMove_GetAngle(objTarget),360);
	ObjMove_SetHomingAngle(objTarget,maxTurn);
	loop(frameTime){
		let toPlayer = modc(GetAngleToPlayer(objTarget),360);
		let difAngle = modc(toPlayer-setAngle,360);
		if(absolute(difAngle) < ObjMove_GetHomingAngle(objTarget)){
			setAngle = toPlayer;
		}else{
			if(sin(difAngle) > 0){
				setAngle += ObjMove_GetHomingAngle(objTarget);
			}else{
				setAngle -= ObjMove_GetHomingAngle(objTarget);
			}
		}
		setAngle = modc(setAngle,360);
		ObjMove_SetAngle(objTarget,setAngle);
		yield;
		if(Obj_IsDeleted(objTarget)){ return; }
	}
}

function ObjMove_SetHomingAngle(let objTarget, let maxTurn){
	Obj_SetValue(objTarget,"MAX_TURN",maxTurn);
}

function ObjMove_GetHomingAngle(let objTarget){
	return Obj_GetValueD(objTarget,"MAX_TURN",0);
}

//---------------------------------------------------------------------------------
// ObjLaser Functions
//---------------------------------------------------------------------------------

// ObjStLaser ------------------------------------

task ObjStLaser_SetLightSource(let objTarget, let delTime){
	yield;
	let RGB = ObjVar_GetColorValue(objTarget);
	let objMain = ObjDelay_SetPropertiesA1(RGB,BLEND_ADD_ARGB);
	
	let zAngle = rand_deg;
	ascent(let a in 0..delTime){
		let sinScale = GetGapY(0.75,0.1,a*45);
		ObjRender_SetPositionToObj(objMain,objTarget);
		ObjRender_SetScaleXYZ(objMain,sinScale,sinScale,0.00);
		ObjRender_SetAngleXYZ(objMain,0,0,zAngle);
		zAngle = modc(zAngle+75,360);
		yield;
		if(Obj_IsDeleted(objTarget)){ break; }
	}
	Obj_Delete(objMain);
}
	
task ObjStLaser_SetExtensionAtFrame(let objTarget, let finLength, let extCount){
	let initLength = ObjLaser_GetLength(objTarget);
	ascent(let a in 1..extCount+1){
		let extLength = initLength+a*(finLength-initLength)/extCount;
		ObjLaser_SetLength(objTarget,extLength);
		yield;
	}
}

task ObjStLaser_SetExtensionAtSpeed(let objTarget, let extSpeed, let extCount){
	let extLength = ObjLaser_GetLength(objTarget);
	loop(extCount){
		extLength += extSpeed;
		ObjLaser_SetLength(objTarget,extLength);
		yield;
	}
}

task ObjStLaser_SetDeleteRoutine(let objTarget){
	while(ObjEnemy_IsAlive(objBoss)){
		if(Obj_IsDeleted(objTarget)){ return; }
		yield;
	}
	yield;
	if(Obj_GetValueD(objTarget,"DELETE_FLAG",false)){ return; }
	let initWidth = ObjLaser_GetRenderWidth(objTarget);
	ObjShot_SetIntersectionEnable(objTarget,false);
	descent(let d in 1..21){
		let decWidth = d*initWidth/20;
		ObjLaser_SetRenderWidth(objTarget,decWidth);
		yield;
	}
	Obj_Delete(objTarget);
}

function ObjStLaser_EndDeleteRoutine(let objTarget, let endFlag){
	Obj_SetValue(objTarget,"DELETE_FLAG",true);
	if(endFlag){
		Obj_SetValue(objTarget,"IS_STRAIGHT_LASER",false);
	}
}

task ObjStLaser_ReduceDelete(let objTarget, let wtTime, let delTime){
	wait(wtTime);
	if(!ObjEnemy_IsAlive(objBoss)){ return; }
	if(Obj_IsDeleted(objTarget)){ return; }
	let initWidth = ObjLaser_GetRenderWidth(objTarget);
	ObjShot_SetIntersectionEnable(objTarget,false);
	descent(let d in 1..delTime+1){
		let decWidth = d*initWidth/delTime;
		ObjLaser_SetRenderWidth(objTarget,decWidth);
		yield;
	}
	Obj_Delete(objTarget);
}

task ObjStLaser_FadeDelete(let objTarget, let wtTime, let initAlpha, let delTime){
	wait(wtTime);
	if(Obj_IsDeleted(objTarget)){ return; }
	ObjShot_SetIntersectionEnable(objTarget,false);
	descent(let d in 1..delTime+1){
		let decAlpha = d*initAlpha/delTime;
		ObjRender_SetAlpha(objTarget,decAlpha);
		yield;
	}
	Obj_Delete(objTarget);
}

function ObjStLaser_GetEndX(let objTarget){
	let pX = GetGapX(ObjMove_GetX(objTarget),ObjLaser_GetLength(objTarget),ObjStLaser_GetAngle(objTarget));
	return pX;
}

function ObjStLaser_GetEndY(let objTarget){
	let pY = GetGapY(ObjMove_GetY(objTarget),ObjLaser_GetLength(objTarget),ObjStLaser_GetAngle(objTarget));
	return pY;
}

// ObjLaser --------------------------------------

task ObjLaser_HeadControl(let objTarget, let headGraph){
	let objColor = ObjVar_GetColorValue(objTarget);
	let objMain = CreateShotS1(ObjMove_GetX(objTarget),ObjMove_GetY(objTarget),0,0,headGraph,0,objColor);
	ObjShot_SetAutoDelete(objMain,false);
	Obj_SetValue(objTarget,"LASER_HEAD_ID",objMain);
	local{
		let ccCount = 0;
		while(!Obj_IsDeleted(objTarget)){
			let cosAlpha = GetGapX(192,64,ccCount*75);
			ObjMove_SetPositionToObj(objMain,objTarget);
			ObjRender_SetAlpha(objMain,cosAlpha);
			ccCount++;
			yield;
			if(Obj_IsDeleted(objMain)){ return; }
		}
		Obj_Delete(objMain);
	}
}

function ObjLaser_GetHeadObjectID(let objTarget){
	return Obj_GetValueD(objTarget,"LASER_HEAD_ID",objTarget);
}

//---------------------------------------------------------------------------------
// ObjNuke Functions
//---------------------------------------------------------------------------------

function ObjNuke_SetObjectRadius(let objTarget, let nRadius){
	Obj_SetValue(objTarget,"NUKE_RADIUS",nRadius);
}

function ObjNuke_GetObjectRadius(let objTarget){
	return Obj_GetValueD(objTarget,"NUKE_RADIUS",0);
}

task ObjNuke_SetExpandAtFrame(let objTarget, let wtTime, let finRadius, let expCount){
	wait(wtTime);
	let iniRadius = ObjNuke_GetObjectRadius(objTarget);
	ascent(let a in 1..expCount+1){
		let expRadius = iniRadius+a*(finRadius-iniRadius)/expCount;
		ObjNuke_SetObjectRadius(objTarget,expRadius);
		yield;
		if(Obj_IsDeleted(objTarget)){ return; }
	}
}

task ObjNuke_SetExpandAtSpeed(let objTarget, let wtTime, let expSpeed, let expCount){
	let expRadius = ObjNuke_GetObjectRadius(objTarget);
	loop(expCount){
		expRadius += expSpeed;
		ObjNuke_SetObjectRadius(objTarget,expRadius);
		yield;
		if(Obj_IsDeleted(objTarget)){ return; }
	}
}

//---------------------------------------------------------------------------------
// Other Functions
//---------------------------------------------------------------------------------

task Obj_WaitDelete(let objTarget, let wtTime){
	wait(wtTime);
	if(Obj_IsDeleted(objTarget)){ return; }
	Obj_Delete(objTarget);
}

task Obj_SetValueAtFrame(let objTarget, let wtTime, let valueID, let objValue){
	wait(wtTime);
	if(Obj_IsDeleted(objTarget)){ return; }
	Obj_SetValue(objTarget,valueID,objValue);
}

function ObjRender_SetColorArray(let objTarget, let RGB){
	ObjRender_SetColor(objTarget,RGB[0],RGB[1],RGB[2]);
}

function ObjRender_SetAlphaFromRGB(let objTarget, let RGB, let addAlpha){
	let R = RGB[0]*(addAlpha/255);
	let G = RGB[1]*(addAlpha/255);
	let B = RGB[2]*(addAlpha/255);
	ObjRender_SetColor(objTarget,R,G,B);
}