const int SFX_PUSHBLOCK_SEQUENCE_TRIGGER_CORRECT = 7;//Sound to play, when pushable was pushed on correct trigger.
const int SFX_PUSHBLOCK_SEQUENCE_TRIGGER_WRONG = 32;//Sound to play, when pushable was pushed on wrong trigger.
const int PUSHBLOCK_SEQUENCE_TRIGGER_COOLDOWN = 30;//Cooldown between release and press the same trigger.
//Sequential pushblock triggers.
//Push block on triggers in specific order to trigger secrets. Block must be the same size (effect width and height in pixels) as trigger in both dimensions to trigger. In case of tall pushblocks, footprint size is checked. Iceblocks must land on trigger to count, not just passing over.
//Place FFC on each trigger spot. Effect Width and Height are used to determine size of the block that can trigger this spot.
//D0 - ID of trigger in sequence 1->2->3->secret. Max 32. Same ID - any can be triggered to advance in solution input.
//D1 - unused
//D2 - Script ID used by triggering FFC block. By default, it searches for //Large Pushable blocks + Tall pushables// script.
ffc script PushblockSequenceTrigger{
void run(int step, int id, int scr2){
int str1[]="LargeTallPushBlock";
int scr1 = scr2;
if (scr1==0) scr1 = Game->GetFFCScript(str1);
this->InitD[7]=0;
int curblock = 0;
ffc f;
int cooldown=0;
while(true){
if (Screen->State[ST_SECRET])Quit();
curblock = TriggerOccupied(this, scr1);
if (curblock>0){
if (cooldown==0){
if (step==this->InitD[7]){
Game->PlaySound(SFX_PUSHBLOCK_SEQUENCE_TRIGGER_CORRECT);
for (int i=1;i<=32;i++){
f=Screen->LoadFFC(i);
if (f->Script!=this->Script)continue;
f->InitD[7]++;
}
while(!FindTargetFFCTrigger(this->Script)){
for (int i=1;i<=32;i++){
f=Screen->LoadFFC(i);
if (f->Script!=this->Script)continue;
f->InitD[7]++;
if (f->InitD[7]>32){
Game->PlaySound(SFX_SECRET);
Screen->TriggerSecrets();
Screen->State[ST_SECRET]=true;
Quit();
}
}
}
cooldown = PUSHBLOCK_SEQUENCE_TRIGGER_COOLDOWN;
}
else{
Game->PlaySound(SFX_PUSHBLOCK_SEQUENCE_TRIGGER_WRONG);
for (int i=1;i<=32;i++){
f=Screen->LoadFFC(i);
if (f->Script!=this->Script)continue;
f->InitD[7]=0;
}
}
cooldown=PUSHBLOCK_SEQUENCE_TRIGGER_COOLDOWN;
}
}
else {
if (cooldown>0){
cooldown--;
}
}
Waitframe();
}
}
int TriggerOccupied(ffc this, int scr1){
ffc f;
for (int i=1;i<=32;i++){
if (this->InitD[1]>0 && i!=this->InitD[1])continue;
f=Screen->LoadFFC(i);
if (f->Script!=scr1)continue;
if (f->EffectWidth!=this->EffectWidth)continue;
if (f->EffectHeight!=this->EffectHeight)continue;
if (f->X!=this->X)continue;
if (f->Y!=this->Y)continue;
if (f->InitD[7]>=0)continue;
return i;
}
return 0;
}
bool FindTargetFFCTrigger(int scr1){
ffc f;
for (int i=1;i<=32;i++){
f=Screen->LoadFFC(i);
if (f->Script!=scr1)continue;
if (f->InitD[7]==f->InitD[0]) return true;
}
return false;
}
}