Copy to Clipboard Test

Dominion Rod Code

//Constants used by Dominion Rod scripts.
const int I_DOMINIONROD = 123; //The ID of the item.
const int LW_DOMINIONSPHERE = 31; //The scripted weapon for the projectile. Legal values 31-40.
const int LW_DAMAGE = 32; //The scripted weapon to use to make the statues do damage. Legal values 31-40.
const int TILE_BLANK = 65519; //A blank tile, legal values 0 - 65519.

//This function should only appear in your script file only once.
bool UsedItem(int id){
	return ((GetEquipmentA() == id && Link->PressA) || (GetEquipmentB() == id && Link->PressB));
}

item script DominionRod{
	void run(int ffcScriptNum, int step, int sprite, int sound, int rotate){
		//Check if the script "DominionSphere" is not already running.
		if(CountFFCsRunning(ffcScriptNum) == 0){
			//Make an ffc run the script or quit if no ffcs are available.
			int args[8] = {step, sprite, sound, rotate};
			RunFFCScriptOrQuit(ffcScriptNum, args);
		}
		else{
			//Find the ffc running the script and end it's execution.
			ffc f = Screen->LoadFFC(FindFFCRunning(ffcScriptNum));
			f->Script = 0;
		}
	}
}

ffc script DominionSphere{
	void run( int step, int sprite, int sound, bool rotate){
		//Create the sphere 8 pixels away from where Link is facing.
		lweapon sphere = NextToLink(LW_DOMINIONSPHERE, 8);
		//Turn off collision for the newly created weapon.
		sphere->CollDetection = false;
		//Set it's sprite, step, and direction,
		sphere->UseSprite(sprite);
		sphere->Step = step;
		sphere->Dir = Link->Dir;
		//Rotate it appropiately based on direction if rotate is true.
		if(rotate){
			if(sphere->Dir == DIR_DOWN) sphere->Flip = 3;
			else if(sphere->Dir == DIR_LEFT) sphere->Flip = 7;
			else if(sphere->Dir == DIR_RIGHT) sphere->Flip = 4;
		}
		//Play the firing sound effect.
		Game->PlaySound(sound);
		//Loop until the sphere becomes invalid.
		while(sphere->isValid()){
			//Kill the lweapon when it reaches the edge of the screen.
			if(sphere->Dir == DIR_UP && sphere->Y - (step/100) < 1) sphere->DeadState = WDS_DEAD;
			else if(sphere->Dir == DIR_DOWN && sphere->Y + (step/100) >= 160) sphere->DeadState = WDS_DEAD;
			else if(sphere->Dir == DIR_LEFT && sphere->X - (step/100) < 1) sphere->DeadState = WDS_DEAD;
			else if(sphere->Dir == DIR_RIGHT && sphere->X + (step/100) >= 240) sphere->DeadState = WDS_DEAD;
			//Waitframe to prevent lagging.
			Waitframe();
		}
	}
}

ffc script DominionStatue{
	void run(float velocity, int damage, int sound1, int sound2){
		//Declare a boolean to track whether it's active or not.
		bool active;
		//Declare a lweapon to be used to damage enemies;
		lweapon edamage;
		//Initialize a variable to store the starting data for the ffc.
		int combo = this->Data;
		//Loop indefinately;
		while(true){
			//Load the dominion sphere to a pointer.
			lweapon sphere = LoadLWeaponOf(LW_DOMINIONSPHERE);
			if(edamage->isValid()) edamage->DeadState = WDS_DEAD;
			//Check if the statue is being controlled.
			if(active){
				//Check if Link did NOT just use the Dominion Rod.
				if(!UsedItem(I_DOMINIONROD)){
					//Check if the statue can move in the direction link is facing.
					if(CanMove(this, velocity, Link->Dir)){
						//Change the ffc's combo to the moving combo.
						this->Data = combo + Link->Dir + 8;
						//Move in the direction Link is facing.
						if(Link->Dir == 0) this->Y -= velocity;
						else if(Link->Dir == 1) this->Y += velocity;
						else if(Link->Dir == 2) this->X -= velocity;
						else if(Link->Dir == 3) this->X += velocity;
					}
					else{
						//Change the ffc's combo to the idle combo.
						this->Data = combo + Link->Dir + 4;
					}
				}
				else{
					//Change the ffc's combo to the deactivated combo;
					this->Data = combo + Link->Dir;
					//Remove the sphere lweapon.
					sphere->DeadState = WDS_DEAD;
					//Set the flag active to false.
					active = false;
					//Play the deactivation sound.
					Game->PlaySound(sound2);
				}
				//Create an lweapon at the ffc's position to damage enemies.
				if(damage > -1){
					edamage = Screen->CreateLWeapon(LW_DAMAGE);
					edamage->X = this->X;
					edamage->Y = this->Y;
					edamage->Tile = TILE_BLANK;
					edamage->Damage = damage;
				}
			}
			//Otherwise check if sphere is valid.
			else if(sphere->isValid()){
				//Check if the sphere collided with the ffc.
				if(Collision(sphere, this)){
					//Set the sphere's step to 0, change it's tile to blank, and null it's animation.
					sphere->Step = 0;
					sphere->OriginalTile = TILE_BLANK;
					sphere->Tile = TILE_BLANK;
					sphere->NumFrames = 1;
					//Set active to true.
					active = true;
					//Change the ffc's combo to the active combo.
					this->Data = combo + 4;
					//Play the activation sound.
					Game->PlaySound(sound1);
				}
			}
			//Waitframe to prevent lagging.
			Waitframe();
		}
	}
	//This function is used to determine if the statue can move in the given direction.
	bool CanMove(ffc this, float velocity, int dir){
		//Initialize a boolean as true.
		bool condition = true;
		//Go through the loop 16 times.
		for(int i; i < 16; i++){
			//Check for solidity.
			if(dir == 0 && Screen->isSolid(this->X + i, this->Y - velocity)) condition = false;
			else if(dir == 1 && Screen->isSolid(this->X + i, this->Y + 15 + velocity)) condition = false;
			else if(dir == 2 && Screen->isSolid(this->X - velocity, this->Y + i)) condition = false;
			else if(dir == 3 && Screen->isSolid(this->X + 15 + velocity, this->Y + i)) condition = false;
			//Only do the rest of the loop for the first and last iteration of the loop.
			if(i == 0 || i == 15){
				//Check for water.
				if(dir == 0 && IsWater(ComboAt(this->X + i, this->Y - velocity))) condition = false;
				else if(dir == 1 && IsWater(ComboAt(this->X + i, this->Y + 15 + velocity))) condition = false;
				else if(dir == 2 && IsWater(ComboAt(this->X - velocity, this->Y + i))) condition = false;
				else if(dir == 3 && IsWater(ComboAt(this->X + 15 + velocity, this->Y + i))) condition = false;
				//Check for pits.
				if(dir == 0 && IsPit(ComboAt(this->X + i, this->Y - velocity))) condition = false;
				else if(dir == 1 && IsPit(ComboAt(this->X + i, this->Y + 15 + velocity))) condition = false;
				else if(dir == 2 && IsPit(ComboAt(this->X - velocity, this->Y + i))) condition = false;
				else if(dir == 3 && IsPit(ComboAt(this->X + 15 + velocity, this->Y + i))) condition = false;
			}
		}
		//Return the boolean we declared at the beginning of the function.
		return condition;
	}
}

ffc script DominionSwitch{
	void run(int ffcScriptNum, int data, int cset, bool permanent){
		//Initialize a boolean as the state of permanent secrets.
		bool gothit = Screen->State[ST_SECRET];
		//Loop until gothit is true.
		while(!gothit){
			//Loop through each ffc.
			for(int i = 1; i <= 32; i++){
				//Load the ffc to a pointer.
				ffc f = Screen->LoadFFC(i);
				//Continue if the script number of the ffc we loaded and ffcScriptNum don't Match.
				if(f->Script != ffcScriptNum) continue;
				//Continue if there's no collision between the two ffcs.
				if(!SquareCollision(f->X, f->Y, 16, this->X + 4, this->Y + 4, 8)) continue;
				//Set gothit to true.
				gothit = true;
				//Break out of the loop.
				break;
			}
			//Waitframe to prevent lagging.
			Waitframe();
		}
		//Change the combo data and cset of the combo beneath this ffc to data and cset respectfully.
		int comboLoc = ComboAt(this->X, this->Y);
		Screen->ComboD[comboLoc] = data;
		Screen->ComboC[comboLoc] = cset;
		//Quit if there are more switches or if screen secrets is true.
		if(Screen->State[ST_SECRET] || CountFFCsRunning(this->Script) > 1) Quit();
		//Trigger Secrets, and make them permanent if they need to be.
		Screen->TriggerSecrets();
		if(permanent)Screen->State[ST_SECRET] = true;
		//Play the secret sound.
		Game->PlaySound(SFX_SECRET);
	}
}