Copy to Clipboard Test

Light Puzzles (Mirror Shield) Code

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Simulates beams of light which are reflected by mirrors, including the Mirror Shield.                                                     //

//D0: Combo number to use on transparent layer to simulate Light.                                                                           //

//D1: Layer to place light combos on. Should be a transparent layer.                                                                        //

//D2: Set to how many tiles from the edge of the screen should be immune to light (EX: if set to 1, light will not hit the screen edge.     //

//D3: Set to 1 if you want the light to stop when it hits a solid, or 0 to pass through solids.                                             //

//D4: Set to 1 if you want the light to be a beam of light from the side rather than from the ceiling.                                      //

//D5: If D4 is set to 1, this is the direction it will travel. 0=up, 1=down, 2=left, 3=right.                                               //

// AUTHOR: Emily                                                  //                                               VERSION: 1.0 (1/28/2018) //

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const int LIGHT_TRANSPARENT = 1;//Combo number for transparent combo.

const int LIGHT_COMBO = 0;//Combo number for light on a transparent layer, default. Overridden by the D0 value if it is not 0.

const int LIGHT_LAYER = 5;//Default layer number. Should not ever be 0.

const int LIGHT_MAX_CONSEC = 25; //Max repeats in a row before the script gives up. If you find your light beams ending prematurely, increase this number.

//It should be as low as possible without interfering with your puzzle, as higher numbers increase lag. Too large a number can crash the script.

const int LIGHT_DRmirror = 0; //Combo number for mirror that reflects between Down and Right

const int LIGHT_DLmirror = 0; //Combo number for mirror that reflects between Down and Left

const int LIGHT_URmirror = 0; //Combo number for mirror that reflects between Up and Right

const int LIGHT_ULmirror = 0; //Combo number for mirror that reflects between Up and Left

const int LIGHT_StrMIRROR = 0; //Combo number for mirror that reflects back in any direction

const int LIGHT_4WayPrism = 0; //Combo number for prism that reflects in 4 directions

const int LIGHT_3WayPrism = 0; //Combo number for prism that reflects in 3 directions

const int LIGHT_GLASS = 0; //Combo number for a solid combo light should be allowed to pass through regardless of D3's value.

ffc script lightPuzzle{

	void run(int lightCombo, int lightLayer, int screenEdge, bool stopSolid, bool isBeam, int dirBeam){

		if(lightLayer==0)lightLayer=LIGHT_LAYER;

		if(lightCombo==0)lightCombo=LIGHT_COMBO;

		int thisCombo = ComboAt(this->X+8,this->Y+8);

		SetLayerComboD(lightLayer, thisCombo, lightCombo);

		while(!isBeam){

			ClearLight(lightLayer,thisCombo);

			if(Link->Item[I_SHIELD3] && ComboAt(Link->X+8,Link->Y+8)==thisCombo){

				DrawLight(Link->Dir, lightCombo, lightLayer, screenEdge, thisCombo, stopSolid, 0);

			}

			Waitframe();

		}

		while(isBeam){

			ClearLight(lightLayer,thisCombo);

			DrawLightBeam(dirBeam,lightCombo,lightLayer,screenEdge,thisCombo,stopSolid, 0);

			Waitframe();

		}

	}

	

	void ClearLight(int lightLayer, int ffcCombo){

		for(int i = 0 ; i <= 175 ; i++){

			if(i!=ffcCombo){SetLayerComboD(lightLayer, i, LIGHT_TRANSPARENT);}

		}

	}

	

	//start DrawLight

	void DrawLight(int dir, int combo, int layer, int edge, int thisCombo, bool stopSolid, int consec){

		bool first = true;

		if(dir==0){

			for(int i = thisCombo;i>=(edge*16);i-=16){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(!first){

					if(Screen->ComboD[i]==LIGHT_DRmirror){

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DLmirror){

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==1){

			for(int i = thisCombo;i<=(175-(edge*16));i+=16){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(!first){

					if(Screen->ComboD[i]==LIGHT_URmirror){

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_ULmirror){

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==2){

			for(int i = thisCombo;i>=(edge+thisCombo-(thisCombo%16));i--){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(!first){

					if(Screen->ComboD[i]==LIGHT_URmirror){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DRmirror){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==3){

			for(int i = thisCombo;i<=(15-edge+thisCombo-(thisCombo%16));i++){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(!first){

					if(Screen->ComboD[i]==LIGHT_ULmirror){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DLmirror){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLight(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLight(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		}

	}

	//end DrawLight

	//start DrawLightBeam

	void DrawLightBeam(int dir, int combo, int layer, int edge, int thisCombo, bool stopSolid, int consec){

		bool first = true;

		int linkAt = ComboAt(Link->X+8,Link->Y+8);

		if(dir==0){

			for(int i = thisCombo;i>=(edge*16);i-=16){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(Link->Item[I_SHIELD3] && i == linkAt){

					DrawLight(Link->Dir, combo, layer, edge, i, stopSolid, consec);

					break;

				}

				if(!first){

					if(Screen->ComboD[i]==LIGHT_DRmirror){

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DLmirror){

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==1){

			for(int i = thisCombo;i<=(175-(edge*16));i+=16){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(Link->Item[I_SHIELD3] && i == linkAt){

					DrawLight(Link->Dir, combo, layer, edge, i, stopSolid, consec);

					break;

				}

				if(!first){

					if(Screen->ComboD[i]==LIGHT_URmirror){

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_ULmirror){

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==2){

			for(int i = thisCombo;i>=(edge+thisCombo-(thisCombo%16));i--){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(Link->Item[I_SHIELD3] && i == linkAt){

					DrawLight(Link->Dir, combo, layer, edge, i, stopSolid, consec);

					break;

				}

				if(!first){

					if(Screen->ComboD[i]==LIGHT_URmirror){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DRmirror){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		} else if(dir==3){

			for(int i = thisCombo;i<=(15-edge+thisCombo-(thisCombo%16));i++){

				if(GetLayerComboD(layer,i)==combo){consec++;}else{consec=0;}

				if(consec>LIGHT_MAX_CONSEC)break;

				SetLayerComboD(layer, i, combo);

				if(Link->Item[I_SHIELD3] && i == linkAt){

					DrawLight(Link->Dir, combo, layer, edge, i, stopSolid, consec);

					break;

				}

				if(!first){

					if(Screen->ComboD[i]==LIGHT_ULmirror){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_DLmirror){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_StrMIRROR){

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_3WayPrism){

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						break;

					} else if(Screen->ComboD[i]==LIGHT_4WayPrism){

						DrawLightBeam(DIR_UP, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_DOWN, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_LEFT, combo, layer, edge, i, stopSolid, consec);

						DrawLightBeam(DIR_RIGHT, combo, layer, edge, i, stopSolid, consec);

						break;

					}

					if(stopSolid && Screen->ComboS[i]>0 && Screen->ComboD[i]!=LIGHT_GLASS)break;

				}

				first = false;

			}

		}

	}

	//end DrawLightBeam

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Triggers changes on the screen when hit by light from the prior script.                                                                   //

//D0: Combo number to use on transparent layer to simulate Light. Must be same as prior script.                                             //

//D1: Layer to place light combos on. Should be a transparent layer. Must be same as prior script.                                          //

//D2: What set of triggers to use. Set multiple of the same to require hitting multiple at a time. Max 9, Min 0.                            //

//D3: How many light triggers are in the set listed in D2. Must be set for all triggers. Max 20 per set per screen.                         //

//D4: If set to 1, trigger will be permanent. Otherwise, must be re-solved each time the room is entered.                                   //

//D5: The flag number you wish to replace (Ex: 16 for Secret Flag 0)                                                                        //

//D6: The combo you wish to replace into the above flag.                                                                                    //

//D7: Number of trigger. First one placed should be 0, each consecutive should be 1 higher.                                                 //

//WARNING: Uses the first X Screen->D[] variables, X being the number of different D2 numbers are set on the same screen.                   //

// AUTHOR: Emily                                                  //                                               VERSION: 1.0 (1/28/2018) //

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ffc script lightTrigger{

	void run(int lightCombo, int lightLayer, int lightSet, int lightMax, bool perm, int flag, int combo, int triggerNum){

		Waitframes(2);

		int lightTriggers[20];

		lightTriggers = Link->Misc[6+lightSet];

		lightTriggers[triggerNum]=0;

		if(lightLayer==0)lightLayer=LIGHT_LAYER;

		if(lightCombo==0)lightCombo=LIGHT_COMBO;

		int thisCombo = ComboAt(this->X+8,this->Y+8);

		bool triggered = false;

		bool done = false;

		int inactiveCombo = Screen->ComboD[thisCombo];

		while(true){

			if(perm)checkTrigger(flag, combo);

			if(!triggered && GetLayerComboD(lightLayer, thisCombo)==lightCombo){

				triggered = true;

				lightTriggers[triggerNum]++;

				Screen->ComboD[thisCombo]=inactiveCombo+1;

			} else if(triggered && GetLayerComboD(lightLayer, thisCombo)!=lightCombo){

				triggered = false;

				lightTriggers[triggerNum]--;

				if(!done)Screen->ComboD[thisCombo]=inactiveCombo;

			}

			Waitframe();

			if(!done && checkLightTriggers(lightTriggers, lightMax)){

				triggerCombo(flag, combo, true, false, perm);

				done=true;

			}

			Waitframe();

		}

	}

	bool checkLightTriggers(int array, int size){

		for(int i = 0;i<size;i++){

			if(array[i]==0)return false;

		}

		return true;

	}

	void triggerCombo(int flag, int combo, bool secretSFX, bool fromCheck, bool perm){

		for(int i = 0;i<=175;i++){

			if(ComboFI(i,flag)){

				Screen->ComboD[i]=combo;

			}

		}

		if(secretSFX)Game->PlaySound(SFX_SECRET);

		if(fromCheck||!perm)return;

		for(int i = 0;i<8;i++){

			if(Screen->D[i]==0){

				Screen->D[i]=1000+flag;

				return;

			}

		}

		

	}

	

	void checkTrigger(int flag, int combo){

		for(int i = 0;i<8;i++){

			if(Screen->D[i]==(1000+flag)){

				triggerCombo(flag, combo, false, true, true);

				break;

			}

		}

	}

}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Must be placed on screen for the lightPuzzle && lightTrigger scripts to work.                                                             //

//D0: What set of light triggers to set up. Seperate set needed for each. 0-9 only.                                                         //

// AUTHOR: Emily                                                  //                                               VERSION: 1.0 (1/28/2018) //

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ffc script lightTriggerSetup{

	void run(int lightSet){

		int lightTriggers[20];

		Link->Misc[6+lightSet] = lightTriggers;

		while(true){Waitframe();}

	}

}