PDA

View Full Version : Multiblock, multitrigger block puzzle



ScaryBinary
01-06-2008, 01:35 AM
...I'm confident that my approach wasn't the best, and I'm sure there are all sorts of limitations to it, but I felt it was interesting none-the-less --- and it's my first FFC script, so I'm compelled to post it even if it totally sucks --- so here's one possible way to have a push block puzzle where certain blocks have to be on certain triggers to solve the puzzle. (What an introduction...:eyebrow:)

http://img125.imageshack.us/img125/516/zelda001vw2.gif
Figure 1: On this screen, the secret is only triggered when the red block is on the red rug and green block is on the green rug.

My scripts are shown below. The basic approach is that you create various Push Block combos. Each one is of type Push (Heavy), and each one has an Inherent Flag set to one of the General Purpose flags (98 through 102). So hypothetically you could have 5 different block-trigger pairs.

The "triggers" are actually FFCs. So instead of placing the typical Block Trigger flags on the screen, you're going to create and place FFCs as your triggers. Each "trigger FFC" uses one of the "Block*Detect" scripts shown below. You pass in the Inherent Flag number that should trigger the secret. One additional FFC monitors global flags to detect when all the blocks are in the proper positions.

http://img215.imageshack.us/img215/4194/zelda002jx7.gif
Figure 2: Flags for the puzzle.

To trigger the secret, once all the blocks are in the proper spot an enemy is killed. Since the screen has the Enemies -> Secret flag checked the secret is then revealed. This is why I had to use Push (Heavy) combos, versus Push (Wait) combos (man, I wish the ZC developers would just create a Push No-Wait combo...or did I miss it?).

At any rate, that's it in a nutshell. I've coded it for a two block puzzle (not much of a puzzle), but you can see that it would be very easy to add any number of blocks (remembering you only get 5 distinct "flavors" of block, but you could have several blocks with the same Inherent flag I suppose).

The main "pro" is that since the Push Blocks are real Push Blocks and not FFCs, you don't have to deal with walkability issues at all. A downside is that since I had to use Push (Heavy) combos, you have to give Link the power bracelet. Also, the way I coded it you have to use the typical 16x16, single-tile combos.

Here's the code listing:

import "std.zh"

//================================================== ============================
// Global Variables
//================================================== ============================
bool Block1Detected;
bool Block2Detected;
bool Block3Detected = true; // DEBUG!
bool Block4Detected = true; // DEBuG!

//================================================== ============================
// FFC Scripts
//================================================== ============================

//------------------------------------------------------------------------------
// Script : CheckAllBlocks
// Purpose : Checks the Block*Detected global
// variables. If they are all true,
// the secrets on the screen
// are triggered.
// Run Args : None.
// Use : Assign this script to an invisible FFC on the screen.
//------------------------------------------------------------------------------
ffc script CheckAllBlocks{
void run(){

// This really only needs to run
// until the secret is triggered.
bool SecretTriggered = false;
npc TriggerNPC;

while(!SecretTriggered){

SecretTriggered = Block1Detected && Block2Detected &&
Block3Detected && Block4Detected;

if(SecretTriggered){
// Show the secrets.
TriggerNPC = Screen->LoadNPC(1);
TriggerNPC->HP = 0;
Trace(-1);
}

// Process other events.
Waitframe();

} // while !SecretTriggered
} // run
} // CheckAllBlocks


//------------------------------------------------------------------------------
// Script : Block1Detect
// Purpose : Determines if a block with the specified inherent flag has been
// pushed under this FFC. If so, a global flag is set to notify
// the CheckAllBlocks script.
// Run Args : LookForFlag - the inherent flag number to look for. Typically
// this will be one of the custom flags ranging from 98 and up.
// Use : Assign this script to an FFC on the screen. The FFC essentially
// takes the place of the Block Trigger flag, so the FFC must be
// located where the Push Block should trigger the secret.
//------------------------------------------------------------------------------
ffc script Block1Detect{
void run(int LookForFlag){

// Initialization. This block detector
// hasn't detected a block yet.
Block1Detected = false;

// Now just loop and look for a pushblock that
// has the specified inherent flag to be
// pushed under this FFC.
while(true){

Block1Detected = (Screen->ComboI[ComboAt(this->X, this->Y)] == LookForFlag);

// Process other events.
Waitframe();

} // while true

} // run
} // Block1Detect


//------------------------------------------------------------------------------
// Script : Block2Detect
// Purpose : Determines if a block with the specified inherent flag has been
// pushed under this FFC. If so, a global flag is set to notify
// the CheckAllBlocks script.
// Run Args : LookForFlag - the inherent flag number to look for. Typically
// this will be one of the custom flags ranging from 98 and up.
// Use : Assign this script to an FFC on the screen. The FFC essentially
// takes the place of the Block Trigger flag, so the FFC must be
// located where the Push Block should trigger the secret.
//------------------------------------------------------------------------------
ffc script Block2Detect{
void run(int LookForFlag){

// Initialization. This block detector
// hasn't detected a block yet.
Block2Detected = false;

// Now just loop and look for a pushblock that
// has the specified inherent flag to be
// pushed under this FFC.
while(true){

Block2Detected = (Screen->ComboI[ComboAt(this->X, this->Y)] == LookForFlag);

// Process other events.
Waitframe();

} // while true

} // run
} // Block2Detect

Russ
01-06-2008, 01:41 AM
Neat. Very neat. But you do not have to use push (heavy) combos. There is a push (no wait) combo. Well sort of. Just set the combo type to "none". It will still be pushable as long as the push flag is on it. But this is a very impressive script. Nice work.

ScaryBinary
01-06-2008, 01:50 AM
There is a push (no wait) combo. Well sort of. Just set the combo type to "none". It will still be pushable as long as the push flag is on it.

:eek: So that's the trick!

That must have been the 1 thing I didn't try during my 4 or 5 hours of trying to piece all this together..:D Thanks for the comments.

pkmnfrk
01-06-2008, 04:47 AM
Hmm, interesting. Make way for the Circle, Square and Triangle blocks ;)

As an aside, this might've been better posted in the Script Showcase forum

Purplemandown
08-10-2008, 01:10 AM
WOW!

Earlyer today I was sitting around, wondering how to make a puzzle just like this. Good thing I checked here.

pkmnfrk
08-10-2008, 02:00 AM
Oh, hey, I forgot about this.

Interestingly, I've written a newer version of this, which should be ready to release along with my other scripts... Monday? Hopefully.

ShadowTiger
08-10-2008, 07:46 AM
Cool. :) Does it tackle the concern about overwriting the Freeform Combos with anything pushable though?

pkmnfrk
08-12-2008, 02:52 AM
I am not aware of this issue, but it works like this:

Each trigger is given the number of a combo to "look" for. When you push a combo onto the square which contains the trigger, one of two things can happen:

1. if it's the correct combo, it removes the push flag from the block and sets one of the Screen->D[] values (of your choice). It also changes its graphic to the next combo. This could represent, say, a pit being filled.
2. if it's the incorrect combo, nothing happens.