Firstly we have two scripts, 'LockBlock' and 'Copycat'. They work the same way as the built-in combotypes in that respect.
You use them both in the same way, but obviously the LockBlock ffcs can be triggered and the Copycat ffcs only change when their respective LockBlocks do.

To use them, give an ffc a transparent, non-zero graphic and place it directly on top of your top-left lock block.
Set up the graphics of your lockblock on the screen. Make sure there is an 'open' lockblock combo after each 'closed' graphic on your combosheet, and make sure each of them are solid and have combotype 'None'.
The ffc's EffectWidth and EffectHeight denote how large a block to make. Please only set these to be integer multiples of 16, otherwise the script might not work properly.

D0 and D1 of both of the scripts set up 'which LockBlock is being used'. They're like a unique ID given to each set of lockblock/copycat ffcs, which tells ZC whether a lockblock has already been triggered.
D0 should be different for each lockblock, starting at 0 and no more than 18, and if you get to 18 then set D1 to be 1 and start D0 at zero. I would hope most people don't need 18 different types of lockblock per screen however.
If you want to get technical, D1 denotes which D register is being used to store whether a block has been triggered, and D0 is the bit to set from that register.
To make a copycat, give it the same D0/D1 combination as the lockblock you're using.

D2 of the lockblock is which type of key to use to open the block. 0 for a normal (or level if you have any) key, 1 for a boss lock-block and 2 if you can just push to open it and don't use any keys.
D3 is the sound effect to play when the block opens - it defaults to the shutter sound effect (9), and you can make it negative if you don't want a sound effect at all.
D4 is the number of frames you have to push against the block for to make it open - defaulting to 10 frames if you leave it at 0.


Code:
ffc script LockBlock{ void run(int perm, int d, int keytype, int sfx, int pushtime){ if(pushtime == 0) pushtime = 10; int loc = ComboAt(this->X,this->Y); int pushclk = 0; while(!GetScreenDBit(d,perm)){ if(PushingCombo(loc,this)) pushclk++; else pushclk = 0; Waitframe(); if(pushclk == pushtime) Unlock(sfx,keytype,perm,d); } SetGraphic(this); } void Unlock(int sfx, int keytype, int perm, int d){ if(!CheckKeys(keytype)) return; if(sfx == 0) Game->PlaySound(SFX_SHUTTER); else if(sfx > 0) Game->PlaySound(sfx); SetScreenDBit(d,perm,true); if(keytype == 0){ if(Game->LKeys[Game->GetCurLevel()] > 0) Game->LKeys[Game->GetCurLevel()]--; else Game->Counter[CR_KEYS]--; } } bool CheckKeys(int keytype){ return (keytype == 0 && (Game->Counter[CR_KEYS] > 0 || Game->LKeys[Game->GetCurLevel()] > 0)) || (keytype == 1 && GetLevelItem(Game->GetCurLevel(),LI_BOSSKEY)) || keytype == 2; } bool PushingCombo(int loc, ffc size){ int w = Floor(size->EffectWidth/16); int h = Floor(size->EffectHeight/16); int x = ComboX(loc); int y = ComboY(loc); return Link->Z == 0 && ((Link->Dir == DIR_UP && Link->InputUp && Link->Y == y+8+16*(h-1) && Abs((Link->X+8)-(x+8*w)) < 8*w) || (Link->Dir == DIR_DOWN && Link->InputDown && Link->Y == y-16 && Abs((Link->X+8)-(x+8*w)) < 8*w) || (Link->Dir == DIR_LEFT && Link->InputLeft && Link->X == x+16*w && Abs((Link->Y+8)-(y+8*h)) < 8*h) || (Link->Dir == DIR_RIGHT && Link->InputRight && Link->X == x-16 && Abs((Link->Y+8)-(y+8*h)) < 8*h)); } void SetGraphic(ffc size){ int first = ComboAt(size->X,size->Y); int last = ComboAt(size->X+(size->EffectWidth-16),size->Y+(size->EffectHeight-16)); int w = last - first; for(int i=0;i<=last-first;i++) if(i <= w) Screen->ComboD[first+i]++; } } ffc script Copycat{ void run(int perm, int d){ while(!GetScreenDBit(d,perm)) Waitframe(); SetGraphic(this); } void SetGraphic(ffc size){ int first = ComboAt(size->X,size->Y); int last = ComboAt(size->X+(size->EffectWidth-16),size->Y+(size->EffectHeight-16)); int w = last - first; for(int i=0;i<=last-first;i++) if(i <= w) Screen->ComboD[first+i]++; } }
can this script be easily made to add an extra check for level-specific keys? because I'm currently having a key crisis of sorts and I basically want generic keys to stay overworld and become unusable while in dungeons. which I'm doing by instead using level-specific keys. the problem is that if the player lacks any level-specific keys, generic keys will still work, which is what i do not want.