
function wait(n){loop(n){yield;}}

function probaRoll(success){let ans = false; if(rand(0,1)<=success){ans = true;} return ans;}


function speak(top, msg, r, g, b){
    let objText = ObjText_Create();
	ObjText_SetText(objText, msg);
	ObjText_SetFontSize(objText, 20);
	ObjText_SetFontType(objText, "MS Gothic");
	ObjText_SetFontColorTop(objText, r, g, b);
	ObjText_SetFontColorBottom(objText, r, g, b);
	ObjText_SetFontBold(objText, true);
    ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	ObjText_SetMaxWidth(objText, 320);
	let y = 300; if(top){y = 200;}
	ObjRender_SetPosition(objText, 222-160, y,1);
	Obj_SetRenderPriorityI(objText, 79);
	return objText;
}

task skip(objBoss){
	let objText = ObjText_Create();
	ObjText_SetText(objText, "(Press the bomb button to skip dialogue)");
	ObjText_SetFontSize(objText, 16);
	ObjText_SetFontType(objText, "Arial");
	ObjText_SetFontColorTop(objText, 255, 255, 255);
	ObjText_SetFontColorBottom(objText, 255, 255, 255);
	ObjText_SetFontBold(objText, false);
    ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	ObjText_SetMaxWidth(objText, 320);
	ObjRender_SetPosition(objText, 222-160, 400,1);
	Obj_SetRenderPriorityI(objText, 79);
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){yield;}
	Obj_Delete(objText);
}








// Name functions, enemy indicators.

task Name(num, objBoss){
	let objText = ObjText_Create();
	if(num==1){ObjText_SetText(objText, "Prof Samir Siksek");}
	else if(num==2){ObjText_SetText(objText, "Dr Saul Schleimer");}
	else{ObjText_SetText(objText, "DUS Dave Wood");}
	ObjText_SetFontSize(objText, 15);
	ObjText_SetFontType(objText, "Arial");
	ObjText_SetFontBold(objText, true);
	ObjText_SetFontColorTop(objText, 255, 255, 255);
	ObjText_SetFontColorBottom(objText, 255, 255, 255);
		
	ObjText_SetMaxWidth(objText, 150);
	Obj_SetRenderPriorityI(objText, 70);
	ObjRender_SetPosition(objText, 10, 15, 1);
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){yield;}
    Obj_Delete(objText);	
}

task Indicator(obj, num){
    let objText = ObjText_Create();
	if(num ==1){ObjText_SetText(objText, "Samir");}
	else if(num ==2){ObjText_SetText(objText, "Saul");}
	else{ObjText_SetText(objText, "Dave");}
	ObjText_SetFontSize(objText, 18);
	ObjText_SetFontType(objText, "MS Gothic");
	ObjText_SetFontBold(objText, true);
	ObjText_SetFontColorTop(objText, 255, 254, 0);
	ObjText_SetFontColorBottom(objText, 255, 254, 0);
		
	ObjText_SetMaxWidth(objText, 100);
	ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	Obj_SetRenderPriorityI(objText, 90);
	while(ObjEnemy_GetInfo(obj, INFO_LIFE)>0){
		ObjRender_SetPosition(objText, ObjMove_GetX(obj), 462, 1);
		yield;
	}
	Obj_Delete(objText);
}


task takeDamage(enemy, scene, lifeB){
    let sound = LoadEffect(GetCurrentScriptDirectory~ "./../SFX/DamageNon.WAV", 90);
	let sound2 = LoadEffect(GetCurrentScriptDirectory~ "./../SFX/DamageSpell.WAV", 90);
    let life; let lifen;
    while(ObjEnemy_GetInfo(enemy, INFO_LIFE)>0){
	    life = ObjEnemy_GetInfo(enemy, INFO_LIFE);
		yield;
		lifen = ObjEnemy_GetInfo(enemy, INFO_LIFE);
		if(lifen< life){
			while(lifen<life){
				if(life<lifeB/8){
				    if(ObjEnemyBossScene_GetInfo(scene, INFO_IS_SPELL)){ObjSound_Play(sound2);}
					else{ObjSound_Play(sound);}
				}
			    life = lifen;
				wait(4);
				lifen = ObjEnemy_GetInfo(enemy,INFO_LIFE);
			}
		}
	}
}








// Spell attacks.

task Spell(name, objBoss, numBoss){
    ObjSound_Play(LoadEffect(GetCurrentScriptDirectory~ "./../SFX/SPELLCARDNEW.WAV", 100));
    SpellPicture(numBoss);
	SpellWarn(numBoss);
	SpellName(name, objBoss);
}


task SpellPicture(numBoss){
    if(numBoss ==1){
		let im = GetCurrentScriptDirectory~ "./../img/spellPictureSamir.png";
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture(obj, im);
		ObjSprite2D_SetSourceRect(obj, 135, 115, 435, 830);
		ObjSprite2D_SetDestRect(obj, 0,0, 165,340);
		Obj_SetRenderPriorityI(obj, 60);
		ObjRender_SetPosition(obj, 650, 75, 1);
		while(ObjRender_GetX(obj)>180){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -30);
			yield;
		}
		loop(80){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -1);
			yield;
		}
		loop(30){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -30);
			yield;
		}
	}
	else if(numBoss ==2){
		let im = GetCurrentScriptDirectory~ "./../img/spellPicture.png";
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture(obj, im);
		ObjSprite2D_SetSourceRect(obj, 80, 245, 415, 800);
		ObjSprite2D_SetDestRect(obj, 0,0, 170,300);
		Obj_SetRenderPriorityI(obj, 60);
		ObjRender_SetPosition(obj, 650, 88, 1);
		while(ObjRender_GetX(obj)>180){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -30);
			yield;
		}
		loop(80){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -1);
			yield;
		}
		loop(30){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -30);
			yield;
		}
	}
	else{
	    let im = GetCurrentScriptDirectory~ "./../img/NonSpellDave.png";
		let obj = ObjPrim_Create(OBJ_SPRITE_2D);
		ObjPrim_SetTexture(obj, im);
		ObjSprite2D_SetSourceRect(obj, 75, 585, 255, 885);
		ObjSprite2D_SetDestRect(obj, 0,0, 200,300);
		Obj_SetRenderPriorityI(obj, 60);
		ObjRender_SetPosition(obj, 550, 80, 1);
		while(ObjRender_GetX(obj)>160){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -20);
			yield;
		}
		loop(80){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -1);
			yield;
		}
		loop(30){
			ObjRender_SetX(obj, ObjRender_GetX(obj) -20);
			yield;
		}
		Obj_Delete(obj);
	}
}


task SpellWarn(numBoss){
	let objText = ObjText_Create();
	if(numBoss==1){ObjText_SetText(objText, "THE END IS NIGH!");}
	if(numBoss==3){ObjText_SetText(objText, "WARNING!![r]SPELL INCOMING!");}
	if(numBoss==2){ObjText_SetText(objText, "PREPARE TO CRY!");}
	ObjText_SetFontSize(objText, 40);
	ObjText_SetFontType(objText, "MS Gothic");
	ObjText_SetFontBold(objText, true);
	ObjText_SetFontColorTop(objText, 180, 0, 0);
	ObjText_SetFontColorBottom(objText, 80, 0, 120);
	ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	
	ObjText_SetMaxWidth(objText, 360);
	Obj_SetRenderPriorityI(objText, 75);
	ObjRender_SetPosition(objText, -320, 25, 1);
	loop(16){
	    ObjRender_SetX(objText, ObjRender_GetX(objText) +20);
		yield;
	}
	let n=40; if(numBoss==3){n=45;}
	loop(n){
	    ObjRender_SetX(objText, ObjRender_GetX(objText) +1);
		wait(2);
	}
	loop(30){
	    ObjRender_SetX(objText, ObjRender_GetX(objText) +20);
		yield;
	}
	Obj_Delete(objText);
}


task SpellName(name, objBoss){
	let objText = ObjText_Create();
	ObjText_SetText(objText, name);
	ObjText_SetFontSize(objText, 20);
	ObjText_SetFontType(objText, "Arial");
	ObjText_SetFontColorTop(objText, 250, 0, 0);
	ObjText_SetFontColorBottom(objText, 250, 0, 0);
	ObjText_SetFontBold(objText, true);
    ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	ObjText_SetMaxWidth(objText, 300);
	Obj_SetRenderPriorityI(objText, 61);
	
	ObjRender_SetPosition(objText, 3*384/4- 170, 300, 1);
	wait(120);
	Obj_SetRenderPriorityI(objText, 25);
	ObjText_SetMaxWidth(objText, 260);
	ObjText_SetHorizontalAlignment(objText, ALIGNMENT_RIGHT);
	ObjRender_SetPosition(objText, 400-260, 15, 1);
	while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){yield;}
	Obj_Delete(objText);
}


task failBonus{
    let objText = ObjText_Create();
	ObjText_SetText(objText, "SPELL BONUS[r]FAILED..");
	Obj_SetRenderPriorityI(objText, 80);
	ObjText_SetFontSize(objText, 40);
	ObjText_SetFontType(objText, "MS Gothic");
	ObjText_SetFontBold(objText, true);
	ObjText_SetFontColorTop(objText, 200, 0, 0);
	ObjText_SetFontColorBottom(objText, 100, 0, 150);
	ObjText_SetHorizontalAlignment(objText, ALIGNMENT_CENTER);
	
	ObjText_SetMaxWidth(objText, 360);
	Obj_SetRenderPriorityI(objText, 80);
	ObjRender_SetPosition(objText, 222-180, 20, 1);
	wait(120);
	Obj_Delete(objText);
}










// Animation.


task animNon(objBoss, num){
    alternative(num)
	case(1){
		let img = GetCurrentScriptDirectory() ~ "../img/NonSpellSamir.png";
		let i=0;
		ObjPrim_SetTexture(objBoss, img);
		Obj_SetRenderPriorityI(objBoss, 24);
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2==0){
			    ObjSprite2D_SetSourceRect(objBoss, 125, 110, 445, 840); 
				ObjSprite2D_SetDestRect(objBoss, -34, -75, 34, 75);
			}
			else{
			    ObjSprite2D_SetSourceRect(objBoss, 725, 120, 1085, 830); 
				ObjSprite2D_SetDestRect(objBoss, -39, -75, 39, 75);
			}
			i++;
			wait(30);
		}
	}
	case(2){
		let img = GetCurrentScriptDirectory() ~ "../img/NonSpellSaul.png";
		let i=0;
		ObjPrim_SetTexture(objBoss, img);
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2==0){
			    ObjSprite2D_SetSourceRect(objBoss, 96, 245, 396, 800); 
				ObjSprite2D_SetDestRect(objBoss, -35, -75, 45, 75);
			}
			else{
			    ObjSprite2D_SetSourceRect(objBoss, 65+512, 260, 415+512, 790); 
				ObjSprite2D_SetDestRect(objBoss, -45, -75, 55, 75);
			}
			i++;
			wait(30);
		}
	}
	case(3){
	    let img = GetCurrentScriptDirectory() ~ "../img/NonSpellDave.png";
		let i=0;
		ObjPrim_SetTexture(objBoss, img);
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2 ==0){
				ObjSprite2D_SetSourceRect(objBoss, 78, 85, 270, 385); 
				ObjSprite2D_SetDestRect(objBoss, -47, -70, 47, 70);
			}
			else{
				ObjSprite2D_SetSourceRect(objBoss, 78, 580, 270, 890); 
				ObjSprite2D_SetDestRect(objBoss, -47, -70, 47, 70);
			}
			i++;
			wait(30);
		}
	}
}


task animSpell(objBoss, num){
    alternative(num)
	case(1){
		let img = GetCurrentScriptDirectory() ~ "../img/SpellSamir.png";
		ObjPrim_SetTexture(objBoss, img);
		Obj_SetRenderPriorityI(objBoss, 24);
		let i=0;
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2 ==0){
			    ObjSprite2D_SetSourceRect(objBoss, 135, 120, 430, 825); 
				ObjSprite2D_SetDestRect(objBoss, -32, -75, 32, 75);
			}
			else{
			    ObjSprite2D_SetSourceRect(objBoss, 730, 100, 1150, 830); 
				ObjSprite2D_SetDestRect(objBoss, -43, -75, 43, 75);
			}
			i++;
			wait(30);
		}
	}
	case(2){
		let img = GetCurrentScriptDirectory() ~ "../img/SpellSaul.png";
		ObjPrim_SetTexture(objBoss, img);
		let i=0;
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2 ==0){
			    ObjSprite2D_SetSourceRect(objBoss, 55, 245, 390, 795); 
				ObjSprite2D_SetDestRect(objBoss, -45, -75, 45, 75);
			}
			else{
			    ObjSprite2D_SetSourceRect(objBoss, 60+512, 270, 445+512, 800); 
				ObjSprite2D_SetDestRect(objBoss, -54, -75, 54, 75);
			}
			i++;
			wait(30);
		}
	}
	case(3){
	    let img = GetCurrentScriptDirectory() ~ "../img/SpellDave.png";
		ObjPrim_SetTexture(objBoss, img);
		let i=0;
		while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
			if(i%2 ==0){
				ObjSprite2D_SetSourceRect(objBoss, 100, 60, 290, 380); 
				ObjSprite2D_SetDestRect(objBoss, -47, -70, 47, 70);
			}
			else{
				ObjSprite2D_SetSourceRect(objBoss, 50, 520, 310, 980); 
				ObjSprite2D_SetDestRect(objBoss, -85, -95, 40, 80);
			}
			i++;
			wait(30);
		}
	}
}











// Finalise.

task TFinalizeNon(scene, objBoss) {
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){yield;}
	ObjSound_Play(LoadEffect(GetCurrentScriptDirectory~ "./../SFX/ATTACK3.WAV", 100));
    DeleteShotAll(TYPE_ALL, TYPE_FADE);
	if(ObjEnemyBossScene_GetInfo(scene, INFO_PLAYER_SHOOTDOWN_COUNT)      
      +ObjEnemyBossScene_GetInfo(scene, INFO_PLAYER_SPELL_COUNT) == 0 && ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)>0){
		SetPlayerSpell(GetPlayerSpell+1);
    }
	wait(30);
	Obj_Delete(objBoss);
    SetAutoDeleteObject(true);
    CloseScript(GetOwnScriptID());
    return;
}

task TFinalize(objBoss) {   
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){yield;}
	Obj_Delete(objBoss);
    CloseScript(GetOwnScriptID());
    return;
}



task TFinalizeSpell(scene, objBoss, timeout, destroy) {
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0){yield;}
	if(destroy){
	    StartSlow(TARGET_ALL, 30);
		let a = LoadEffect(GetCurrentScriptDirectory~ "./../SFX/ATTACK3.WAV", 70);
		loop(4){ObjSound_Play(a); wait(20);}
		StopSlow(TARGET_ALL);
	}
    Obj_Delete(objBoss);
    DeleteShotAll(TYPE_ALL, TYPE_IMMEDIATE);
	if(ObjEnemyBossScene_GetInfo(scene, INFO_PLAYER_SHOOTDOWN_COUNT)      
      +ObjEnemyBossScene_GetInfo(scene, INFO_PLAYER_SPELL_COUNT) == 0){
	    if((!timeout && ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)>0) || timeout){
			ObjSound_Play(LoadEffect(GetCurrentScriptDirectory ~"./../SFX/BONUS3.WAV", 100));
			SetPlayerLife(GetPlayerLife()+1);
		}
		else{
		    ObjSound_Play(LoadEffect(GetCurrentScriptDirectory~ "./../SFX/ATTACK3.WAV", 80));
	        failBonus;
		}
    }   
	else{
	      ObjSound_Play(LoadEffect(GetCurrentScriptDirectory~ "./../SFX/ATTACK3.WAV", 80));
	      failBonus;
    }
	if(destroy){ObjSound_Play(LoadEffect(GetCurrentScriptDirectory~ "./../SFX/DEFEATED.WAV", 100));}
	wait(240);
    SetAutoDeleteObject(true);
    CloseScript(GetOwnScriptID());
    return;
}









// Sound.

function LoadEffect(sound, volume){
    let obj1 = ObjSound_Create();
	ObjSound_Load(obj1, sound);
	ObjSound_SetRestartEnable(obj1, true);
	ObjSound_SetVolumeRate(obj1, volume);
	return(obj1);
}

task shotSound(obj, time, volume, delay, enemy, delete, limit, scene, timeLimit){
    ObjSound_SetVolumeRate(obj, volume);
	ObjSound_SetRestartEnable(obj, true);
	if(time<0){
	    if(delete){
			while(!Obj_IsDeleted(enemy) && ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)>timeLimit){
				ObjSound_Play(obj);
				wait(delay);
			}
		}
		else{
		    while(ObjEnemy_GetInfo(enemy, INFO_LIFE) > limit && ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)>timeLimit){
				ObjSound_Play(obj);
				wait(delay);
			}
		}
	}
	else{
		let t=0;
		while(t<time){
			if(ObjEnemy_GetInfo(enemy, INFO_LIFE) <= limit || ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)<= timeLimit ){return;}
			ObjSound_Play(obj);
			wait(delay);
			t+=delay;
		}
	}
}	




// Useful shot functions.


/* Useful for making helices. Speed is in frames/ second, but that does NOT mean that the helix will move at that speed
   (only the bullets will). Radius half the width of the helix, delay is the delay between bullets spawning. */

task helix(x, y, speed, angle, radius, gapLength, numBul, delay, topGraphic, bottomGraphic, enemy, limit){
    if(numBul<0){
	    while(ObjEnemy_GetInfo(enemy, INFO_LIFE)>limit){
		    if(topGraphic>0){
			    if(ObjEnemy_GetInfo(enemy, INFO_LIFE)<=limit){return;}
				let obj1 = CreateShotA1(x,y, 0,0, topGraphic, 0);
				sinePattern(obj1, x, y, speed, angle, radius, gapLength, 1);
		    }
			if(bottomGraphic>0){
			    if(ObjEnemy_GetInfo(enemy, INFO_LIFE)<=limit){return;}
				let obj2= CreateShotA1(x,y, 0,0, bottomGraphic, 0);
				sinePattern(obj2, x, y, speed, angle, radius, gapLength, -1);
			}
			wait(delay);
		}
	}
	loop(numBul){
	    if(topGraphic>0){
		    if(ObjEnemy_GetInfo(enemy, INFO_LIFE)<=limit){return;}
			let obj1 = CreateShotA1(x,y, 0,0, topGraphic, 0);
			sinePattern(obj1, x, y, speed, angle, radius, gapLength, 1);
		}
		if(bottomGraphic>0){
		    if(ObjEnemy_GetInfo(enemy, INFO_LIFE)<=limit){return;}
			let obj2= CreateShotA1(x,y, 0,0, bottomGraphic, 0);
			sinePattern(obj2, x, y, speed, angle, radius, gapLength, -1);
		}
		wait(delay);
	}
}

task sinePattern(obj, xini, yini, speed, angle, radius, gapLength, dir){
    let x; let y; let t = 1; let c = cos(angle); let s = sin(angle);
	while(!Obj_IsDeleted(obj)){
	    x = xini+ gapLength/180 * t *c -radius* dir* sin(t)*s;
		y = yini+ gapLength/180 * t *s +radius* dir* sin(t)*c;
		ObjMove_SetDestAtFrame(obj, x,y,1);
		t+=speed; yield;
	}
}






// Movement functions/ functions relating to movement.

function X(obj){return ObjMove_GetX(obj);}

function Y(obj){return ObjMove_GetY(obj);}

task move(obj, xmin, xmax, ymin, ymax, iniDel, time, delay, objBoss, limit, scene, timeLimit){
    wait(iniDel);
    while(ObjEnemy_GetInfo(objBoss, INFO_LIFE) > limit && ObjEnemyBossScene_GetInfo(scene, INFO_TIMER)>timeLimit){
	    ObjMove_SetDestAtFrame(obj, rand(xmin, xmax), rand(ymin, ymax), time);
		wait(time+delay);
	}
}


task DelayLaser(obj, x, y, ang, len, wid, graph, time){ 
	let objlaser = CreateStraightLaserA1(x, y, ang, len, wid, 1, graph, time);
	ObjStLaser_SetSource(objlaser, false);
	loop(time-1){if(!Obj_IsDeleted(obj)){yield;}};
	Obj_Delete(objlaser);
}


function findAngRad(xdest, x, ydest, y){
    let rad = power((x-xdest)^2 +(y-ydest)^2, 1/2); let angle = atan((ydest-y)/(xdest-x));
	if(xdest<x){angle = angle+180;}
	return [angle, rad];
}


function findAngFal(obj){
	let ang = ObjMove_GetAngle(obj);
	if(ang<=270){ang = 90+ (3*180-2*ang)/4;}
	else{ang= 360-ang;}
}


task wavy(obj, wvel, pause){
    let t=0; ObjMove_SetAngularVelocity(obj, wvel); let speed = ObjMove_GetSpeed(obj);
    while(!Obj_IsDeleted(obj)){
	    while(t<pause){if(ObjMove_GetSpeed(obj) < speed){ObjMove_SetAngularVelocity(obj,0); return;}t++; yield;}
		wvel*=-1;
	    ObjMove_SetAngularVelocity(obj, wvel);
		yield; t=0;
	}
}


// Used for spinning patterns.


task spinRing(xini, yini, numBul, rad, ang, speed, angSpeed, dir, graphic, delay){
	ascent(i in 0..numBul){
	    let obj =CreateShotA1(xini + rad*cos(360/numBul *i), yini + rad*sin(360/numBul *i), 0,0, graphic, delay);
		spin(obj, i, xini, yini, numBul, rad, ang, speed, angSpeed, dir, delay);
	}
}


	
task spin(obj, i, xini, yini, numBul, rad, ang, speed, angSpeed, dir, delay){
	let x; let y; let j =0; let c = cos(ang); let s = sin(ang); let inc=0; let xn; let yn;
	loop(delay){
		x = j + rad*cos(360/numBul *i);
		y =  rad*sin(360/numBul *i);
		xn = xini + c*x -s*y;
		yn = yini + s*x + c*y;
		ObjMove_SetPosition(obj, xn, yn);
		j+= speed;
		yield;
	}
	while(!Obj_IsDeleted(obj)){
		x = j + rad*cos(360/numBul *i + inc);
		y =  rad*sin(360/numBul *i +inc);
		xn = xini + c*x - s*y;
		yn = yini + s*x + c *y;
		ObjMove_SetPosition(obj, xn, yn);
		j+= speed; inc+= dir* angSpeed;
		yield;
	}
}


task Com(obj, centre, incAng, rad){
	let ang = ObjMove_GetAngle(obj); let x; let y;
    while(!Obj_IsDeleted(centre)){
	    x = X(centre) + rad*cos(ang); y = Y(centre) + rad*sin(ang);
		ObjMove_SetPosition(obj, x,y);
		ang+= incAng; yield; ObjMove_SetAngle(obj, ang + 90*incAng/absolute(incAng) - incAng);
	}
	Obj_Delete(obj);
}


task ScreenShake(period, intensity){
    let t=0;
    while(t <period){
        Set2DCameraFocusX(GetStgFrameWidth/2 + rand(-intensity, intensity));
        Set2DCameraFocusY(GetStgFrameHeight/2 + rand(-intensity, intensity));
        t++;
        yield;
    }
    Set2DCameraFocusX(GetStgFrameWidth/2);
    Set2DCameraFocusY(GetStgFrameHeight/2);
    yield;
}


