Untested.
const int DigComboStart=12;
const int DigComboEnd=19;
// The following combos are similarly diggable, but turn into a different kind of combo and
// do not give item drops. You can use this to have secret stairs, for example.
// Important: Make sure these combos directly follow the DigComboEnd one.
const int DigSpecialStart=20;
const int DigSpecialEnd=23;
// A regular diggable combo will turn into this combo when you use the shovel on it.
const int DugComboNormal=24;
// A special combo will turn into this combo when you use the shovel on it.
// You can, for example, make it a tile warp, so the player can dig for secret entrances.
// Set up the warps and the arrival points on your ZQuest screen as usual.
const int DugComboSpecial=25;
// This is the sound to be played when you successfully dig.
const int ShovelSound=100;
// The sound to be played when you attempt to dig an undiggable combo.
const int ShovelFail=101;
// The secret sound to be played when you dig a special combo.
const int SecretSound=27;
const int ShovelCombo = ?,
bool active = false;
item script itmShovel{
void run(){
if(Link->Z <= 0 && active == false){
int ffcScriptName[] = "Shovel";
int ffcScriptNum = Game->GetFFCScript(ffcScriptName);
RunFFCScript(ffcScriptNum, 0);
active = true;
Quit();
}
else Quit();
}
}
ffc script Shovel{
void run(){
int chance;
int itemdrop;
int itemlocx;
int itemlocy;
int X = 0;
int Y = 0;
int combo = 0;
int delay = 60;
Link->Action=LA_ATTACKING;
if(Link->Dir == 0){
combo = 0;
X = 0;
Y = 0;
}
else if(Link->Dir == 1){
combo = 1;
X = 0;
Y = 16;
}
else if(Link->Dir == 2){
combo = 2;
X = 0;
Y = 0;
}
else if(Link->Dir == 3){
combo = 3;
X = 16;
Y = 0;
}
while(true){
if(delay > 0){
Link->InputA = false;
Link->PressA = false;
Link->InputB = false;
Link->PressB = false;
Screen->FastCombo(2, Link->X+X, Link->Y+Y, ShovelCombo+combo, 0, 128);
delay --;
}
else{
if((Link->Dir==0&&(Screen->ComboD[ComboAt(Link->X+8,Link->Y-8)]<DigComboStart||Screen->ComboD[ComboAt(Link->X+8,Link->Y-8)]>DigSpecialEnd))
||(Link->Dir==1&&(Screen->ComboD[ComboAt(Link->X+8,Link->Y+24)]<DigComboStart||Screen->ComboD[ComboAt(Link->X+8,Link->Y+24)]>DigSpecialEnd))
||(Link->Dir==2&&(Screen->ComboD[ComboAt(Link->X-8,Link->Y+8)]<DigComboStart||Screen->ComboD[ComboAt(Link->X-8,Link->Y+8)]>DigSpecialEnd))
||(Link->Dir==3&&(Screen->ComboD[ComboAt(Link->X+24,Link->Y+8)]<DigComboStart||Screen->ComboD[ComboAt(Link->X+24,Link->Y+8)]>DigSpecialEnd))){
Game->PlaySound(ShovelFail);
active = false;
break;
}
else{
Game->PlaySound(ShovelSound);
chance=Rand(100)+1;
if(Link->Dir==0){
if(Screen->ComboD[ComboAt(Link->X+8,Link->Y-8)]<DigSpecialStart){
Screen->ComboD[ComboAt(Link->X+8,Link->Y-8)]=DugComboNormal;
}
else{
Game->PlaySound(SecretSound);
Screen->ComboD[ComboAt(Link->X+8,Link->Y-8)]=DugComboSpecial;
chance=101;
}
}
if(Link->Dir==1){
if(Screen->ComboD[ComboAt(Link->X+8,Link->Y+24)]<DigSpecialStart){
Screen->ComboD[ComboAt(Link->X+8,Link->Y+24)]=DugComboNormal;
}
else{
Game->PlaySound(SecretSound);
Screen->ComboD[ComboAt(Link->X+8,Link->Y+24)]=DugComboSpecial;
chance=101;
}
}
if(Link->Dir==2){
if(Screen->ComboD[ComboAt(Link->X-8,Link->Y+8)]<DigSpecialStart){
Screen->ComboD[ComboAt(Link->X-8,Link->Y+8)]=DugComboNormal;
}
else{
Game->PlaySound(SecretSound);
Screen->ComboD[ComboAt(Link->X-8,Link->Y+8)]=DugComboSpecial;
chance=101;
}
}
if(Link->Dir==3){
if(Screen->ComboD[ComboAt(Link->X+24,Link->Y+8)]<DigSpecialStart){
Screen->ComboD[ComboAt(Link->X+24,Link->Y+8)]=DugComboNormal;
}
else{
Game->PlaySound(SecretSound);
Screen->ComboD[ComboAt(Link->X+24,Link->Y+8)]=DugComboSpecial;
chance=101;
}
}
// The item drops are currently set to be the same as the default tall grass combo drops.
// The variable "chance" is a randomly generated number between 1 and 100.
// It determines whether you will get an item, and if so, which one.
// Here, you have a 20% chance to spawn 1 rupee, and a 15% chance to spawn a heart.
// If you want, edit this or add more lines to spawn more drops.
// You can use this line as a template: if(chance>=21&&chance<=35)itemdrop=2;
// The "chance" variable determines the chance you have of obtaining the item, as we've
// seen before, and the "itemdrop" variable is the number of the item in ZQuest.
if(chance<=20)itemdrop=0;
if(chance>=21&&chance<=35)itemdrop=2;
// NB: If you dug a special combo, the "chance" variable is automatically set to 101 so
// the script won't spawn drops on top of special combos like stairs.
if(Link->Dir==0){
itemlocx=Link->X;
itemlocy=Link->Y-16;
}
if(Link->Dir==1){
itemlocx=Link->X;
itemlocy=Link->Y+16;
}
if(Link->Dir==2){
itemlocx=Link->X-16;
itemlocy=Link->Y;
}
if(Link->Dir==3){
itemlocx=Link->X+16;
itemlocy=Link->Y;
}
// This is the part of the code that spawns the item.
// If you have edited the default item drops, change "35" and set it according to your drops.
if(chance<=35){
item i=Screen->CreateItem(itemdrop);
i->X=itemlocx;
i->Y=itemlocy;
i->Z=10;
i->Pickup=IP_TIMEOUT;
}
}
active = false;
break;
}
Waitframe();
}
}
}
1 Make 4 Combos Shovel : Top, Bot, Left, Right
2 Set Combo 'top' :
const int ShovelCombo = ?;
3 Compile and set ffc script and item script
DrawTile would be better for this. The issue with LTMs, is that you need to waste many tile pages adding sets of them. You could make Link invisible and draw a specific digging tile (or combo, if you do not wan to code the animation) in his place for a few frames.
One pointer, for Link visibility, is that you want all code that can make him invisible to be parsed through a single source. You do not, for example, want three items that can make him invisible, each writing to Link->Invisible. Instead, you want any of those to set a bit in a global flag, and if that flag is not 0, then he is invisible. When the item is done making him invisible, unset the flag. That gives you a single source to control visibility, and thus, you avoid conflicts.
For dropsets, what I do, is this:
//dropset arrays
int dropset[100]={
//list items, with each slot being an item ID, or -1.
//each index is a 1% drop chance, and you can spread these out to manipulate RNG luck.
}
//Drop function, that takes the array pointer as its argument.
void DropItem(int dropset){
item drop = Screen->CreateItem(dropset[Rand(0,99)]);
}
This is far cleaner than hardcoding drops.
One last thing, is that I would add some code to check for a specific flag. I would use the Dive Secret flag, as this otherwise does nothing on solid ground, and if that flag is on the screen where the player digs (and some predetermined Screen->D register bit is false) , then spawn the special item for the screen instead of a dropset item, and set a Screen->D register bit to true.
This allows digging for special items, such as the flute in Z3.
This works best if the Screen->D bit is set by the item via a pick-up script, so that the player cannot dig it, walk offscreen, and be unable to re-spawn it. You also do not want to set IP_TIMEOUT on a special item.
Another fun trick, is to change the Layer 1 combos to the holes. This keeps all holes that the player digs, static, so that if the player leaves a screen and returns, the holes are still present; and this remains valid until the player resets the game.
Last, i would make the diggable combos an array inside the dig function, so that it is easy to add them in an arbitrary manner, rather than needing to be in sequence.
Rather than a first and last combo, you can do this:
bool CanDig(int pos, int layer){
int digCombos[20,21,22,23,406,90,2250};
for ( int q = SizeOfArray(digCombos); q >=0; q-- ) {
if ( GetLayerComboD(layer, pos) == digCombos[q] ) return true;
}
return false;
}
That makes it much easier to expand the list of dig spots. You can similarly do this for special dig spots with a second function:
bool CanDigSpecialItem(int pos, int layer){
int digCombos[29, 30, 450};
for ( int q = SizeOfArray(digCombos); q >=0; q-- ) {
if ( GetLayerComboD(layer, pos) == digCombos[q] ) return true;
}
return false;
}
Edited by ZoriaRPG, 20 August 2017 - 09:18 PM.