Skip to content

Instantly share code, notes, and snippets.

@SephirothWS
Created February 10, 2021 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SephirothWS/52db1a6f09aa90c54a4cfc1d607eed21 to your computer and use it in GitHub Desktop.
Save SephirothWS/52db1a6f09aa90c54a4cfc1d607eed21 to your computer and use it in GitHub Desktop.
zcriptbuffer.zs
import "std.zh"
//=============================================================================================
//======================================= *Global Constants* ==================================
//=============================================================================================
const int OWL_FLYING_DATA = 48;
const int OWL_STILL_DATA = 165;
const int OWL_CSET = 6;
const int SHADOW_TILE_DATA = 13;
const int SHADOW_CSET = 6;
const int OWL_MUSIC = 2;
//=============================================================================================
//======================================= *Global Variables* ==================================
//=============================================================================================
bool saveStringDisplayed = false;
int saveString = 1;
//=============================================================================================
//======================================= *Global Functions* ==================================
//=============================================================================================
bool SelectPressInput(int input){
if(input == 0) return Link->PressA;
else if(input == 1) return Link->PressB;
else if(input == 2) return Link->PressL;
else if(input == 3) return Link->PressR;
}
void SetInput(int input, bool state){
if(input == 0) Link->InputA = state;
else if(input == 1) Link->InputB = state;
else if(input == 2) Link->InputL = state;
else if(input == 3) Link->InputR = state;
}
//=============================================================================================
//======================================= *FFC Scripts* =======================================
//=============================================================================================
// 1 - Signpost Script by Joe123
//FUNCTIONALITY: Attach this script to an FFC and edit its Arguments to your needs.
ffc script Signpost {
void run(int m,int input) {
int loc = ComboAt(this->X,this->Y);
while(true) {
while(!AgainstComboBase(loc) || !SelectPressInput(input)) Waitframe();
SetInput(input,false);
Screen->Message(m);
Waitframe();
}
}
bool AgainstComboBase(int loc) {
return Link->Z == 0 && (Link->Dir == DIR_UP && Link->Y == ComboY(loc)+8 && Abs(Link->X-ComboX(loc)) < 8);
}
}
//----------------------------------------------------------------------------------
// 2 - Save Point SFX Script by Joe123
//FUNCTIONALITY: Attach this script to an FFC and edit its Arguments to your needs.
ffc script SavePointSFX {
void run(int sfx) {
int X = this->TileWidth;
int Y = this->TileHeight;
while(true) {
while(Abs(Link->X - (this->X+8*(X-1))) > 8*X || Abs(Link->Y - (this->Y+8*(Y-1))) > 8*Y) Waitframe();
Game->PlaySound(sfx);
if (saveStringDisplayed == false) {
Screen->Message(saveString);
saveStringDisplayed = true;
}
while(Abs(Link->X - (this->X+8*(X-1))) <= 8*X && Abs(Link->Y - (this->Y+8*(Y-1))) <= 8*Y) Waitframe();
}
}
}
//----------------------------------------------------------------------------------
// 3 - Flying Owl Script by lucas92
//FUNCTIONALITY: Attach this script to an FFC and edit its Arguments to your needs.
//D0-D3 : Bounding rectangle
//D4-D5 : Owl posing coordinates
//D6 : The message
//D7 : The screen flag to activate when the owl has been encountered, value go 0 to 7
ffc script owl {
void run(int x1,int y1,int x2,int y2,int owl_final_x,int owl_final_y,int message_id,int flag) {
this->X = 0;
this->Y = 0;
bool activated = false;
float angle = 90;
bool owl_posed = false;
bool owl_quitting = false;
bool message = false;
int lastMidi = Game->GetMIDI();
if(Screen->D[flag]==0) {
while(true) {
if(Link->X > x1 && Link->Y > y1 && Link->X < x2 && Link->Y < y2) {
activated = true;
Game->PlayMIDI(OWL_MUSIC);
}
if(activated) {
this->CSet = OWL_CSET;
if(!owl_posed && !owl_quitting) {
angle--;
this->X = owl_final_x*Cos(angle);
this->Y = -owl_final_y*Sin(angle)+owl_final_y;
if(angle<=0)
owl_posed = true;
if(!owl_posed) {
this->Data = OWL_FLYING_DATA;
this->TileWidth = 2;
Screen->DrawCombo(3, this->X+8, owl_final_y, SHADOW_TILE_DATA, 1, 1,SHADOW_CSET, -1, -1, 0, 0, 0,0, 0, true, 64);
}
NoAction();
}
if(owl_posed) {
this->Data = OWL_STILL_DATA;
this->TileWidth = 1;
if(!message) {
message = true;
Screen->Message(message_id);
}
else {
owl_quitting = true;
owl_posed = false;
angle = -90;
Game->PlayMIDI(lastMidi);
}
NoAction();
}
if(owl_quitting) {
angle++;
Game->PlayMIDI(lastMidi);
this->X = (248-owl_final_x)*Cos(angle)+owl_final_x;
this->Y = -owl_final_y*Sin(angle);
this->TileWidth = 2;
Screen->DrawCombo(3, this->X+8, owl_final_y, SHADOW_TILE_DATA, 1, 1,SHADOW_CSET, -1, -1, 0, 0, 0,0, 0, true, 64);
this->Data = OWL_FLYING_DATA;
if(this->Y < 0) {
activated = false;
Screen->D[flag] = 1;
this->Data = 0;
}
}
}
if(Screen->D[flag]==1)
break;
Waitframe();
}
}
}
}
//----------------------------------------------------------------------------------
//==============================================================================================
//======================================= *Item Scripts* =======================================
//==============================================================================================
// 1 - Item Pickup Sting by Joe123
//FUNCTIONALITY: Attach this script to the Action slot of an Item within the Scripts Tab.
// D0 is the string to display for a certain item.
item script Message {
void run(int m) {
Screen->Message(m);
}
}
//----------------------------------------------------------------------------------
// 2 - Heart Piece Message by Moscowmodder
//FUNCTIONALITY: Attach this to the Pickup script slot of an item within its Scripts Tab.
// Set the arguments to your needs.
//Old version: supports only 4-piece heart containers
//Messages can be set automatically or manually
//D0 = First message
//D1-3 = Second-fourth messages; default to strings after D0
item script heartPieceMessage {
void run (int m1, int m2, int m3, int m4) {
//Set m2-4 to follow m1 if not set explicitly
if ( m2 == 0 ) m2 = m1+1;
if ( m3 == 0 ) m3 = m1+2;
if ( m4 == 0 ) m4 = m1+3;
//Play the appropriate message
if ( Game->Generic[GEN_HEARTPIECES] == 0 )
Screen->Message(m1);
if ( Game->Generic[GEN_HEARTPIECES] == 1 )
Screen->Message(m2);
if ( Game->Generic[GEN_HEARTPIECES] == 2 )
Screen->Message(m3);
if ( Game->Generic[GEN_HEARTPIECES] == 3 )
Screen->Message(m4);
}
}
//-----------------------------------------------------------------------------
// 3 - Item Bundle Script by Nick
//FUNCTIONALITY: Attach this to the Pickup script slot of an item within its Scripts Tab.
// Set the arguments to your needs.
// This script is a pickup script that will give some items.
// This was mostly made to bundle the Bow and Arrows into one item,
// but it could have other uses.
// Bundle this with an item that increases a counter to also increase counters.
// D0-D7: Items to give.
// D0: If D0 is negative, it will display an item pickup message containing the positive version of the number entered...
item script itemBundle {
void run(int item1, int item2, int item3, int item4, int item5, int item6, int item7, int item8) {
if(item1 > 0)
Link->Item[item1] = true;
if(item2 > 0)
Link->Item[item2] = true;
if(item3 > 0)
Link->Item[item3] = true;
if(item4 > 0)
Link->Item[item4] = true;
if(item5 > 0)
Link->Item[item5] = true;
if(item6 > 0)
Link->Item[item6] = true;
if(item7 > 0)
Link->Item[item7] = true;
if(item8 > 0)
Link->Item[item8] = true;
// Display Item pickup message?
if(item1 < 0)
{
Screen->Message(item1 * -1);
}
}
}
//----------------------------------------------------------------------------
// Uncategorized Things
//----------------------------------------------------------------------------
//import "std.zh"
//VERSION A BY DEMONLINK:
const int COMPASS_BEEP = 65; //Set this to the SFX id you want to hear when you have the compass,
//Instructions:
//1.- Compile and add this to your ZQuest buffer.
//2.- Add an FFC with this script attached to the screen where you want to hear the compass beep.
//3.- Let the script do the rest.
//How does it work:
//The script checks if ANY of the following has been done:
//a) Item or Special Item has been picked up.
//b) Any type of chest has been opened.
//c) If NOTHING of the above has been done, the script runs. Otherwise, no SFX is heard.
ffc script CompassBeep{
void run(){
if(!Screen->State[ST_ITEM] &&
!Screen->State[ST_CHEST] &&
!Screen->State[ST_LOCKEDCHEST] &&
!Screen->State[ST_BOSSCHEST] &&
!Screen->State[ST_SPECIALITEM] && (Game->LItems[Game->GetCurLevel()] & LI_COMPASS)){
Game->PlaySound(COMPASS_BEEP);
}
}
}
//VERSION B BY NYROX
const int COMPASS_SFX = 65; //Set this to the SFX id you want to hear when you have the compass.
//Instructions:
//1.- Compile and add this to your ZQuest buffer.
//2.- Add an FFC with this script attached to the screen where you want to hear the compass beep.
//3.- The following arguments are for cases where you have more than one item on a same screen (YES, it is possible).
// D0: Set this to 1 if you have a Normal Item set.
// D1: Set this to 1 if you have a Special Item set.
// D2: Set this to 1 if you have a Normal Chest set.
// D3: Set this to 1 if you have a Locked Chest set.
// D4: Set this to 1 if you have a Boss Chest set.
//How does it work:
//The script checks if ANY of the following is true.
//a) Depending on the Argument settings, it will check if the condition is met.
//b) If so, it will play the sound.
ffc script NyroxCompassBeep{
void run(int arg1, int arg2, int arg3, int arg4, int arg5){
if(GetLevelItem(LI_COMPASS)){
if(!Screen->State[ST_ITEM] && (arg1 == 1)){
Game->PlaySound(COMPASS_SFX);
}
else if(!Screen->State[ST_SPECIALITEM]&& (arg2 == 1)){
Game->PlaySound(COMPASS_SFX);
}
else if(!Screen->State[ST_CHEST]&& (arg3 == 1)){
Game->PlaySound(COMPASS_SFX);
}
else if (!Screen->State[ST_LOCKEDCHEST] && (arg4 == 1)){
Game->PlaySound(COMPASS_SFX);
}
else if(!Screen->State[ST_BOSSCHEST]&& (arg5 == 1)){
Game->PlaySound(COMPASS_SFX);
}
}
}
}
//----------------------------------------------------------------------------
// This mimics a GB Locked Dungeon, which only opens when the player has a special item
// d0 = The combo of the lock block
// d1 = The item required to open the lock block
// d2 = The message that is displayed if you do not have the lock block
// d3 = The sound effect played when opening the lock block
// d4 = Set to 1 if you want the item to be removed from Link's inventory
ffc script LockedDungeonEntrance
{
void run(int dgnlock, int key, int msg, int sfx, int removeItem)
{
// This this ffc to ethereal to make sure that the cave/stairs still work
this->Flags[FFCF_ETHEREAL] = true;
int loc = ComboAt(this->X+8, this->Y+8);
int numKeys = -1;
// If lockblocks haven't been activated yet
if(!Screen->State[ST_LOCKBLOCK])
{
// This basically monitors to make sure the user pushes against the lock block a few moments before unlocking it
int pressDelay = 0;
while(true)
{
// If Link is pushing up against the lock block
if(ComboAt(Link->X+8, Link->Y+7) == loc && Screen->ComboD[loc] == dgnlock && Link->InputUp)
{
pressDelay++;
// If they have waited enough time
if(pressDelay >= 5)
{
// If they have a key, unlock it
if(Link->Item[key])
{
Screen->State[ST_LOCKBLOCK] = true;
Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), loc, Screen->ComboD[loc]+1);
if(sfx == 0)
Game->PlaySound(SFX_SHUTTER);
else
Game->PlaySound(sfx);
if(removeItem)
Link->Item[key] = false;
break;
}
// Otherwise display an error message
else if(msg > 0)
{
pressDelay = -5;
Screen->Message(msg);
}
}
}
else
pressDelay = 0;
// Trigger this lock block if other lock blocks have been opened
if(Screen->State[ST_LOCKBLOCK])
{
Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), loc, Screen->ComboD[loc]+1);
break;
}
Waitframe();
} //! End of while(true)
} //! End of if(!Screen->State[ST_LOCKBLOCK])
// Else lock blocks were already activated, so change the combo if needed
else if(Screen->ComboD[loc] == dgnlock)
Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), loc, Screen->ComboD[loc]+1);
} //! End of void run(int dgnlock, int key, int msg, int sfx)
} //! End of ffc script LockedDungeonEntrance
//----------------------------------------------------------------------------
global script ActiveScript{
void run(){
while(true){
Waitframe();
}
}
}
//----------------------------------------------------------------------------
//D0 = combo for triggers (they need combo type NONE, only place them on layer 0)
//D1 = combo for activated triggers
//D2 = sfx for stepping on trigger (leave at 0 if not needed)
//D3 = secret sfx (leave at 0 if not needed)
ffc script StepTriggersComboSecret{
void run(int triggerOff, int triggerOn, int triggerSFX, int secretSFX){
if ( Screen->State[ST_SECRET] == true )
Quit();
int numberOfTriggers = 0;
for(int i = 0; i < 175; i++){
if ( Screen->ComboD[i] == triggerOff )
numberOfTriggers ++;
}
while(true){
if ( Screen->ComboD[ComboAt(Link->X+8, Link->Y+12)] == triggerOff && Link->Z == 0 ) {
Game->PlaySound(triggerSFX);
Screen->ComboD[ComboAt(Link->X+8, Link->Y+12)] = triggerOn;
numberOfTriggers --;
}
if ( numberOfTriggers == 0 ) {
Game->PlaySound(secretSFX);
Screen->TriggerSecrets();
Screen->State[ST_SECRET] = true;
Quit();
}
Waitframe();
}
}
}
//----------------------------------------------------------------------------
//////////////////////////
/// Title Screen FFC ///
/// By: ZoriaRPG ///
/// With Assistance ///
/// From: MasterManiac ///
//////////////////////////////////////////////////////////////////////////////
/// This script is used to run a title screen, using FFCs, and uses one ///
/// FFC to establish the functions of the title screen, which begins the ///
/// game by pressing the START button, as one might expect to happen in ///
/// games that actually *have* a START button. ///
/// ///
/// You may change the button to suit your game, by replacing ImputStart ///
/// with the desired input, such as InputEx1, if you want a game to start ///
/// by pressing SELECT, such as a few Kusoge titles do, that I can recall. ///
/// ///
/// Set to 'Run at Screen init' in FFC Flags! ///
//////////////////////////////////////////////////////////////////////////////
/// ............... ///
/// FFC ARGUMENTS ///
/// ............... ///
///---------------------------{ D0: Start SFX }----------------------------///
/// D0: SFX to play when the player presses 'START'. ///
/// Set from Quest->Audio->SFX Data. ///
///---------------------------{ D1: Delay Time }---------------------------///
/// D1: Length of time, between pressing start, and the game starting. ///
/// Time this to match your SFX, where 60 = 1-second. ///
/// (240, would therefore be four-seconds, and is my default value.) ///
///----------------------{ D2/D3: Warp Destinations }----------------------///
/// D2: If using a direct warp, set this to the DMAP number for the warp ///
/// (not the 'Map' number, but the 'DMAP' number), stating at 0. ///
/// D3: If using direct warps, set this to the screen number for the ///
/// warp destination. This will use WARP RETURN 'A'. ///
///------------------------{ D4: Secret Warp Mode }------------------------///
/// D4: If you are going to use a SENSITIVE WARP tile, placed under the ///
/// player, to control the warp (and thus, control fade effects), then ///
/// set this to a value of '1' (or greater). Set warp destinations from ///
/// Screen->Tilewarp, and set your tile warp combo in Screen->Secrets, as ///
/// SECRET TILE 0, then place Flag-16 over where the player is caged on ///
/// your title screen. ///
//////////////////////////////////////////////////////////////////////////////
ffc script titleScreen {
void run(int SFX, int timeValue, int W_DMAP_NUMBER, int W_SREEN_NUMBER, int secrets) {
Link->InputStart = false; //present subscreen from falling.
bool waiting = true; //Establish main while loop.
bool pressed = false; //Establish timer requirements.
int timer = 0; //Set timer to exist.
while(waiting){ //The main while loop.
if (Link->InputStart) { //Is the player presses START
Link->InputStart = false; //Keep subscreen from falling.
pressed = true; //Initiate countdown timer.
Game->PlaySound(SFX); //Play SFX set in D0.
}
if(pressed){ //Run Timer
timer++; //Timer counts up, until it reaches amount set in D1.
}
if(timer >= timeValue){ //if timer is equal to, or greater than value of D1.
if ( secrets > 0 ) { //If D4 is set to 1 or higher...
Screen->TriggerSecrets(); //Trigger secret combos. Use this if using a warp combo.
}
else { //If D4 is set to 0, and we are using direct warps...
Link->Warp(W_DMAP_NUMBER, W_SREEN_NUMBER); //Warp Link to the DMAP set in D2, and the screen set in D3, using Warp Return A.
}
}
Waitframe(); //Pause, to cycle the loop.
}
}
}
//----------------------------------------------------------------------------
ffc script TallPushCombo
{
void run()
{
while(true)
{
while(Screen->ComboD[ComboAt(this->X, this->Y+(this->TileHeight*16))] != Screen->UnderCombo)
Waitframe();
//We need to know what direction the block is going to move ahead of time as waitdraw cannot be used.
float xstep;
float ystep;
if(Link->Dir==DIR_UP)
ystep = -.5;
else if(Link->Dir==DIR_DOWN)
ystep = .5;
else if(Link->Dir==DIR_LEFT)
xstep = -.5;
else if(Link->Dir==DIR_RIGHT)
xstep = .5;
for(int i; i < 32; i++) //Blocks are pushed for 32 frames.
{
this->X += xstep;
this->Y += ystep;
Waitframe();
}
this->X = GridX(this->X);
this->Y = GridY(this->Y);
Waitframe();
}
}
}
//----------------------------------------------------------------------------
ffc script Locked{
void run(int dir, int offset, int adjacent, bool boss, bool big){
//Wait until the door is unlocked by Link if not already unlocked on screen init.
while(!GetScreenDBit(0, dir) && !OpeningDoor(this, dir%4, boss)) Waitframe();
//Initialize a variable as the location of combo the ffc is placed at.
int comboLoc = ComboAt(this->X, this->Y);
//Change the variable we just initialized according to the dir and big arguments.
if(dir%4 == 0 || big) comboLoc -= 16;
if(dir%4 == 2) comboLoc -= 1;
//Loop through the horizontal combos.
for(int i; i < 2; i++){
//In each iteration of the loop, loop through the vertical combos.
for(int j; (big && j < 3) || j < 2; j++){
//Increment the combo data of the combo by the offset argument.
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] += offset;
}
}
//Check the screen D bit (dir) on register 0, and if it's already set skip the rest of the script.
if(!GetScreenDBit(0, dir)){
//It wasn't set which means Link just opened the door. So set it so it opens on screen init.
SetScreenDBit(0, dir, true);
//For back to back doors we need to set the screen bit on the adjacent screen.
SetScreenDBit(adjacent, 0, AdjacentDir(dir), true);
//If not a boss door subtract 1 key from Link's inventory.
if(!boss){
if(Game->LKeys[Game->GetCurLevel()] > 0) Game->LKeys[Game->GetCurLevel()]--;
else Game->Counter[CR_KEYS]--;
}
//Lastly play a sound effect.
Game->PlaySound(SFX_SHUTTER);
}
}
//This function checks if link is trying to open the door, and meets the requirements to do so.
bool OpeningDoor(ffc this, int dir, bool boss){
//If a boss door and the player has no boss key return false;
if(boss && !GetLevelItem(LI_BOSSKEY)) return false;
//If not a boss door and the player has no keys return false;
else if(!boss && Game->Counter[CR_KEYS] == 0 && Game->LKeys[Game->GetCurLevel()] == 0) return false;
//Check if Link is near-centered with the door nonfacing central axis.
else if(dir < 2 && Abs(Link->X - this->X) >= 4) return false;
else if(dir >= 2 && Abs(Link->Y - this->Y) >= 4) return false;
//Lastly return whether or not Link is next to the door and pushing against it.
else if(dir == 0) return (Link->Y == this->Y + 8 && Link->InputUp);
else if(dir == 1) return (Link->Y == this->Y - 16 && Link->InputDown);
else if(dir == 2) return (Link->X == this->X + 16 && Link->InputLeft);
else if(dir == 3) return (Link->X == this->X - 16 && Link->InputRight);
}
//This Function returns the direction of the adjacent screens locked door.
int AdjacentDir(int dir){
//We need a variable for both loops which is the number of doors
int i;
//dir%4 incrementing i by one each time we wrap.
for(; dir >= 4; i++) dir -= 4;
//Flip dir around so we have the opposite direction.
dir = OppositeDir(dir);
//Now add i4 to dir.
dir += (i*4);
//Lastly return dir.
return dir;
}
}
ffc script Shutter{
void run(int dir, int offset, int type, bool oneway, bool big){
bool cancelSound = false;
if (type == 4 && Screen->State[ST_SECRET]) {
cancelSound = true;
}
//Check if Link is in the doorway.
if(InDoorway(this, OppositeDir(dir))){
//Link is in the doorway so open the shutter, copy & pasted from above.
int comboLoc = ComboAt(this->X, this->Y);
if(dir == 0 || big) comboLoc -= 16;
if(dir == 2) comboLoc -= 1;
for(int i; i < 2; i++){
for(int j; (big && j < 3) || j < 2; j++){
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] += offset;
}
}
//Wait until the screen finishes scrolling.
do{
Waitframe(); //The scrolling doesn't start on screen init but one frame afterwards.
} while(Link->Action == LA_SCROLLING);
//Force Link into the room by nulling all controls accept the correct arrow key.
if (type == 4 && Screen->State[ST_SECRET]) {
Quit();
}
else {
while(InDoorway(this, dir)){
NoAction();
if(dir == 0) Link->InputDown = true;
else if(dir == 1) Link->InputUp = true;
else if(dir == 2) Link->InputRight = true;
else if(dir == 3) Link->InputLeft = true;
Waitframe();
}
//Close the shutter behind Link, copy & pasted from above.
for(int i; i < 2; i++){
for(int j; (big && j < 3) || j < 2; j++){
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] -= offset;
}
}
//Play the shutter sound effect.
if (cancelSound != true) {
Game->PlaySound(SFX_SHUTTER);
}
}
}
//Otherwise wait a while. "Makes it so all shutters open simultaneously if the condition is fulfilled on screen init."
else{
if (type != 4) {
do{
Waitframe();
} while(Link->Action == LA_SCROLLING);
Waitframes(25);
}
}
//End the script here if it's a one way shutter.
if(oneway) Quit();
//Initialize blocks as the number of blocks on the screen.
int blocks = NumBlocks();
//Wait until the condition for opening the shutter is fulfilled.
while(true){
if(type == 0 && NoEnemies()) break;
else if(type == 1 && NumBlocks() != blocks) break;
else if(type == 2 && LastComboFlagOf(CF_BLOCKTRIGGER, 0) == -1) break;
else if(type == 3 && Screen->State[ST_SECRET]) break;
else if(type == 4 && Screen->State[ST_SECRET]) break;
//If you need a custom condition for the shutter just add a else if at the end of the loop and assign it a number other than 0-3.
Waitframe();
}
//If it's a block->shutter wait 20 frames.
if(type == 1) Waitframes(20);
//Else if it's a secret->shutter set the secret screen state to false.
else if(type == 3) Screen->State[ST_SECRET] = false;
//Open the shutter, copy and pasted from above.
int comboLoc = ComboAt(this->X, this->Y);
if(dir == 0 || big) comboLoc -= 16;
if(dir == 2) comboLoc -= 1;
for(int i; i < 2; i++){
for(int j; (big && j < 3) || j < 2; j++){
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] += offset;
}
}
//Lastly play the shutter sound since it just opened.
if (cancelSound != true) {
Game->PlaySound(SFX_SHUTTER);
}
}
//This function checks if link is in the doorway.
bool InDoorway(ffc this, int dir){
//Simply check link's position relative to the number and the location of the ffc.
if(dir == 0) return(Link->X == this->X && Link->Y < 32);
else if(dir == 1) return(Link->X == this->X && Link->Y > 128);
else if(dir == 2) return(Link->Y == this->Y && Link->X < 32);
else if(dir == 3) return(Link->Y == this->Y && Link->X > 208);
}
//This function check if all enemies have been defeated as if it was a normal shutter room.
bool NoEnemies(){
//Initialize a boolean as true.
bool condition = true;
//Loop through every npc.
for(int i = Screen->NumNPCs(); i > 0; i--){
//Load each npc to a pointer.
npc n = Screen->LoadNPC(i);
//Continue if the enemy is a item fairy.
if(n->ID == NPC_ITEMFAIRY) continue;
//Continue if the enemy has the "Doesn't count as beatable enemy" flag.
else if(GetNPCMiscFlag(n, 8)) continue;
//Since a beatable enemy exists, set condition to false and break out of the loop.
condition = false;
break;
}
return condition;
}
//This function returns the number of combos with push _ trigger flags.
int NumBlocks(){
//Declare the blocks variable.
int blocks;
//Loop through all 176 combos.
for(int i; i < 176; i++){
//If the inherited or placement flag is 1, 2, or 47 - 51 increment blocks.
if(ComboFI(i, 1)) blocks++;
else if(ComboFI(i, 2)) blocks++;
else if(ComboFI(i, 47)) blocks++;
else if(ComboFI(i, 48)) blocks++;
else if(ComboFI(i, 49)) blocks++;
else if(ComboFI(i, 50)) blocks++;
else if(ComboFI(i, 51)) blocks++;
}
//Return the blocks variable.
return blocks;
}
}
ffc script Bombable{
void run(int dir, int offset, int adjacent, int dustdata, int dustloc, bool big){
//Check if the wall was already bombed by checking screen d bit (dir) on register 0.
if(GetScreenDBit(0, dir)){
//Open a hole in the wall, copy and pasted from above.
int comboLoc = ComboAt(this->X, this->Y);
if(dir == 0 || big) comboLoc -= 16;
if(dir == 2) comboLoc -= 1;
for(int i; i < 2; i++){
for(int j; (big && j < 3) || j < 2; j++){
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] += offset;
}
}
//Change the ffc's data to dustdata and reposition it.
this->Data = dustdata;
this->X = ComboX(dustloc);
this->Y = ComboY(dustloc);
//Check if Link is in the doorway.
if(InDoorway(this, OppositeDir(dir), big)){
//The following is copy and pasted from the shutter script.
do{
Waitframe();
} while(Link->Action == LA_SCROLLING);
while(InDoorway(this, dir, big)){
NoAction();
if(dir%4 == 0) Link->InputDown = true;
else if(dir%4 == 1) Link->InputUp = true;
else if(dir%4 == 2) Link->InputRight = true;
else if(dir%4 == 3) Link->InputLeft = true;
Waitframe();
}
}
//Since there's nothing else to do end the script.
Quit();
}
//Declare the bombed variable.
bool bombed;
//Loop until bombed becomes true.
while(!bombed){
//Loop through each lweapon on screen.
for(int i = Screen->NumLWeapons(); i > 0 && !bombed; i--){
//Load the lweapon to a pointer.
lweapon l = Screen->LoadLWeapon(i);
//If the weapon is not a bomb blast or super bomb blast end this iteration of the loop.
if(l->ID != LW_BOMBBLAST && l->ID != LW_SBOMBBLAST) continue;
//If collision for the weapon is on and it collided with the ffc set bombed to true.
if(Collision(this, l) && l->CollDetection) bombed = true;
}
Waitframe();
}
//copy and pasted from locked script.
int comboLoc = ComboAt(this->X, this->Y);
if(dir == 0 || big) comboLoc -= 16;
if(dir == 2) comboLoc -= 1;
for(int i; i < 2; i++){
for(int j; (big && j < 3) || j < 2; j++){
int combo = comboLoc + i + (16 * j);
Screen->ComboD[combo] += offset;
}
}
//copy and pasted from above.
this->Data = dustdata;
this->X = ComboX(dustloc);
this->Y = ComboY(dustloc);
//Set the screen D bit for (dir) on register 0.
SetScreenDBit(0, dir, true);
//Set the screen D bit for the adjacent screen.
SetScreenDBit(adjacent, 0, AdjacentDir(dir), true);
}
//Function copy and pasted from shutter script.
bool InDoorway(ffc this, int dir, bool big){
int mod = 0;
if(dir < 2 || !big) mod = 8;
if(dir == 0) return(Link->X == this->X+mod && Link->Y < 32);
else if(dir == 1) return(Link->X == this->X+mod && Link->Y > 128);
else if(dir == 2) return(Link->Y == this->Y+mod && Link->X < 32);
else if(dir == 3) return(Link->Y == this->Y+mod && Link->X > 208);
}
//Function copy and pasted from locked script.
int AdjacentDir(int dir){
int i;
for(; dir >= 4; i++) dir -= 4;
dir = OppositeDir(dir);
dir += (i*4);
return dir;
}
}
//----------------------------------------------------------------------------
ffc script EnemyMusic
{
void run(int bmidi, int nmidi)
{
while(true)
{
if (Screen->NumNPCs() != 0)
{
Game->PlayMIDI(bmidi);
}
else
{
Game->PlayMIDI(nmidi);
}
Waitframe();
}
}
}
//----------------------------------------------------------------------------
ffc script ScreenSecretSFX
{
void run()
{
Game->PlaySound(27);
}
}
//----------------------------------------------------------------------------
ffc script blockPermSecrets{
void run(){
int thisCombo = this->Data;
while(!Screen->State[ST_SECRET]){
if(this->Data != thisCombo) Screen->State[ST_SECRET] = true;
Waitframe();
}
}
}
//----------------------------------------------------------------------------
ffc script doNoAction{
void run(){
while(true){
NoAction();
Waitframe();
}
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment