Copy to Clipboard Test

Bouncing Sliders puzzle Code

const int CF_SLIDERPUZZLE_BUMPER = 67;//Combo flag used for boundaries.
const int CF_SLIDERPUZZLE_TRIGGER = 66;//Combo flag used for triggers.

const int SFX_SLIDERPUZZLE_START = 21;//Sound to play, when slider starts moving
const int SFX_SLIDERPUZZLE_STOP = 16;//Sound to play, when slider stops moving

//Bouncing sliders puzzle. Stand on control panel, face the given direction, and press EX1, to send all sliders moving. 
//Each slider moves certain amount of combos. If hits obstacle, it reverses direction. Land all sliders on triggers simultaneously to solve.

//SlideBounceController
//
//Effect Width and height are used
//No arguments needed
//
//BouncingSlider
//
//Place and grid-snap at initial position.
//For obstacles, use NoPushblock flags or solid combos.
//For triggers, use BlockTrigger flags.
//D0 - Allowed directions for slider. Add together - 1-Up, 2-Down, 4-Left, 8-Right
//D1 - movement distance per command, in combos.

ffc script SlideBounceController{
	void run (){
		int str[] = "BouncingSlider";
		int scr = Game->GetFFCScript(str);
		bool canmove=true;
		while(true){
			canmove=true;
			for (int i=1;i<=32;i++){
				ffc f = Screen->LoadFFC(i);
				if (f->Script!=scr)continue;
				if (f->InitD[7]>=0){
					canmove=false;
					break;
				}
			}
			if (canmove && Link->PressEx1){
				if (RectCollision(Link->X+7, Link->Y+7, Link->X+8, Link->Y+8, this->X, this->Y, this->X+this->EffectWidth-1, this->Y+this->EffectHeight-1)){
					Game->PlaySound(SFX_SLIDERPUZZLE_START);
					for (int i=1;i<=32;i++){
						ffc f = Screen->LoadFFC(i);
						if (f->Script!=scr)continue;
						f->InitD[7] = Link->Dir;
					}
				}
			}
			Waitframe();
		}
	}
}

ffc script BouncingSlider{
	void run(int dirs, int amount){
		int animcounter=0;
		int counter=0;
		this->InitD[7]=-1;
		while(true){
			if (animcounter==0){
				if (this->InitD[7]>=0){
					if ((dirs&(1<<(this->InitD[7])))>0){
						this->InitD[6]=0;
						animcounter=16;
						counter=amount;
						int cmb = ComboAt(this->X+1, this->Y+1);
						int adjcmb = AdjacentComboFix(cmb, this->InitD[7]);
						if ((Screen->ComboS[adjcmb]>0)||(ComboFI(adjcmb, CF_SLIDERPUZZLE_BUMPER))){
							this->InitD[7] = OppositeDir(this->InitD[7]);
							adjcmb = AdjacentComboFix(cmb, this->InitD[7]);
							if ((Screen->ComboS[adjcmb]>0)||(ComboFI(adjcmb, CF_SLIDERPUZZLE_BUMPER))){
								counter=0;
								animcounter=0;
								this->InitD[7]=-1;
								if (ComboFI(cmb,CF_SLIDERPUZZLE_TRIGGER))this->InitD[6]=1;
							}
						}
					}
					else{
						Game->PlaySound(SFX_SLIDERPUZZLE_STOP);
						this->InitD[7]=-1;
					}
				}
			}
			else{
				if (this->InitD[7]==DIR_UP) this->Y--;
				if (this->InitD[7]==DIR_DOWN) this->Y++;
				if (this->InitD[7]==DIR_LEFT) this->X--;
				if (this->InitD[7]==DIR_RIGHT) this->X++;
				animcounter--;
				if (animcounter==0){
					counter--;
					if (counter>0){
						animcounter=16;						
						int cmb = ComboAt(this->X+1, this->Y+1);
						int adjcmb = AdjacentComboFix(cmb, this->InitD[7]);
						if ((Screen->ComboS[adjcmb]>0)||(ComboFI(adjcmb, CF_SLIDERPUZZLE_BUMPER))) this->InitD[7] = OppositeDir(this->InitD[7]);
					}
					else{
						Game->PlaySound(SFX_SLIDERPUZZLE_STOP);
						int cmb = ComboAt(this->X+1, this->Y+1);
						this->InitD[7]=-1;
						if (ComboFI(cmb,CF_SLIDERPUZZLE_TRIGGER))this->InitD[6]=1;
						for(int i=1;i<=33;i++){
							if (i==33){
								Game->PlaySound(SFX_SECRET);
								Screen->TriggerSecrets();
								Screen->State[ST_SECRET]=true;
								break;
							}
							ffc f = Screen->LoadFFC(i);
							if (f->Script!=this->Script)continue;
							if (SliderCollision(f)) break;
							if (f->InitD[6]==0)break;
						}
					}
				}
			}
			Waitframe();
		}
	}
}


//Fixed variant of AdjacentCombo function from std_extension.zh
int AdjacentComboFix(int cmb, int dir)
{
	int combooffsets[13]={-0x10, 0x10, -1, 1, -0x11, -0x0F, 0x0F, 0x11};
	if ( cmb % 16 == 0 ) combooffsets[9] = -1;//if it's the left edge
	if ( (cmb % 16) == 15 ) combooffsets[10] = -1; //if it's the right edge
	if ( cmb < 0x10 ) combooffsets[11] = -1; //if it's the top row
	if ( cmb > 0x9F ) combooffsets[12] = -1; //if it's on the bottom row
	if ( combooffsets[9]==-1 && ( dir == DIR_LEFT || dir == DIR_LEFTUP || dir == DIR_LEFTDOWN ) ) return -1; //if the left columb
	if ( combooffsets[10]==-1 && ( dir == DIR_RIGHT || dir == DIR_RIGHTUP || dir == DIR_RIGHTDOWN ) ) return -1; //if the right column
	if ( combooffsets[11]==-1 && ( dir == DIR_UP || dir == DIR_RIGHTUP || dir == DIR_LEFTUP ) ) return -1; //if the top row
	if ( combooffsets[12]==-1 && ( dir == DIR_DOWN || dir == DIR_RIGHTDOWN || dir == DIR_LEFTDOWN ) ) return -1; //if the bottom row
	if ( cmb >= 0 && cmb < 176 ) return cmb + combooffsets[dir];
	else return -1;
}

bool SliderCollision(ffc f){
	for(int i=1;i<=32;i++){
		ffc n = Screen->LoadFFC(i);
		if (f==n)continue;
		if (n->Script!=f->Script)continue;
		if (RectCollision(f->X, f->Y, f->X + 15, f->Y +15, n->X, n->Y, n->X +15, n->Y +15))return true;
	}
	return false;
}