Jump to content

Photo

GB / ALttP style chests by Nimono script issue


  • Please log in to reply
9 replies to this topic

#1 Rocksfan13

Rocksfan13

    Looks best in Blue

  • Members
  • Real Name:Doug
  • Location:Earth

Posted 03 October 2018 - 10:37 AM

Hey guys, I am using Nimono's script for chests from the DB. It works great BTW!!!

 

But I found a bug.

 

You can open the chest from the bottom right or left corner as well as directly below it.

Not sure it's supposed to work that way.

 

I have the script here if Nimono or anyone else wants to fix it so it only opens from directly below it.

// GB Treasure Chest by ~Nimono~
// Make sure to set the CSet of the FFC to the CSet you want the chest to be in!
// Variables:
// DValue: Which Screen->D[] to use to track the chests. Make sure to pick one not currently in use by other scripts!
// D0 chestCombo: The starting combo for your chest, used to make sure you can't reopen chests again. The script changes it to its next combo, so make sure the open chest is the very next combo!
// D1 openSFX: What sound effect ID to play upon opening the chest.
// D2 receiveSFX: What sound to play upon receiving the item.
// D3 itemID: The item to give to the player upon opening the chest.
// D4 receiveMessage: Which message to display upon receiving the item.
// D5 itemDisplay: Whether or not to display the item rising from the chest. 0 = do not display, anything else = display.
// D6 lockValue: Whether or not to have the chest be locked. 0 = no lock, 1 = regular key required; 2 = boss key required.
// If you are using ghost.zh, uncomment out SuspendGhostZHScripts() and ResumeGhostZHScripts().

const int DValue = 5; // change this to change which Screen->D value the chest data is stored into, to avoid conflicts with other scripts that use them

ffc script SmallChest
{
    void run(int chestCombo, int openSFX, int receiveSFX, int itemID, int receiveMessage, int itemDisplay, int lockValue)
    {
        if(itemID == 0)
        {
            itemID = Screen->RoomData;
        }
        int holdType = 0;
        while(true)
        {
            if(Screen->D[DValue]&ConvertToBit(GetFFCNum(this)))
            {
                for(int i; i < 16; i++)
                {
                    if(Screen->ComboF[ComboAt(this->X, this->Y)] == i+16)
                    {
                        Screen->ComboF[ComboAt(this->X, this->Y)] = 0;
                    }
                }
                Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), chestCombo+1);
                Game->SetComboCSet(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), this->CSet);
            }
            if(LinkCollision(this))
            {
                if(CenterLinkY() > CenterY(this) && Link->InputA && Screen->ComboD[ComboAt(this->X, this->Y)] == chestCombo && (lockValue == 0 || (lockValue == 1 && Game->Counter[CR_KEYS] > 0) || (lockValue == 1 && Game->LKeys[Game->GetCurLevel()] > 0) || (lockValue == 2 && Game->LItems[Game->GetCurLevel()]&LI_BOSSKEY)))
                {
                    if(lockValue == 1)
                    {
                        if(Game->LKeys[Game->GetCurLevel()] > 0)
                        {
                            Game->LKeys[Game->GetCurLevel()] -= 1;
                        }
                        else
                        {
                            Game->DCounter[CR_KEYS] = -1;
                        }
                    }
                    NoAction();
                    //SuspendGhostZHScripts();
                    Game->PlaySound(openSFX);
                    Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), chestCombo+1);
                    holdType = Screen->ComboT[ComboAt(this->X, this->Y)];
                    Screen->ComboT[ComboAt(this->X, this->Y)] = CT_SCREENFREEZE;
                    Screen->D[DValue] |= ConvertToBit(GetFFCNum(this));
                    int itemRaise = 0;
                    for(int i; i < 28; i++)
                    {
                        if(itemDisplay > 0)
                        {
                            item Temp = CreateItemAt(itemID, 0, 0);
                            Screen->FastTile(2, this->X, this->Y-8+itemRaise, Temp->OriginalTile, Temp->CSet, OP_OPAQUE);
                            Remove(Temp);
                            itemRaise-=0.25;
                        }
                        NoAction();
                        if(i==27)
                        {
                            Screen->ComboT[ComboAt(this->X, this->Y)] = holdType;
                        }
                        Waitframe();
                    }
                    NoAction();
                    item Box = CreateItemAt(itemID, Link->X, Link->Y);
                    if(itemDisplay > 0)
                    {
                        item Temp = CreateItemAt(itemID, 0, 0);
                        Screen->FastTile(2, this->X, this->Y-8+itemRaise, Temp->OriginalTile, Temp->CSet, OP_OPAQUE);
                        Remove(Temp);
                    }
                    if(Screen->Flags[SF_ITEMS]&1)
                    {
                        Box->Pickup|=IP_HOLDUP;
                    }
                    Game->PlaySound(receiveSFX);
                    Screen->Message(receiveMessage);
                    //ResumeGhostZHScripts();
                }
            }
            Waitframe();
        }
    }
}

int GetFFCNum(ffc thisffc)
{
    for(int i = 1; i < 32; i++)
    {
        ffc checkffc = Screen->LoadFFC(i);
        if(checkffc == thisffc)
        {
            if(i < 17)
            {
                return i;
            }
            else
            {
                return i-16;
            }
        }
    }
    return NULL;
}

int ConvertToBit(int num)
{
    return 1 << (num-1);
}

Otherwise, this is an awesome script.



#2 Avaro

Avaro

    o_o

  • Members
  • Real Name:Robin
  • Location:Germany

Posted 03 October 2018 - 10:46 AM

 

You can open the chest from the bottom right or left corner as well as directly below it.

 

What you mean to say is the collision detection is extremely loose. Yeah.



#3 Gégé

Gégé

    Senior

  • Members
  • Real Name:Gérard
  • Location:France

Posted 03 October 2018 - 11:14 AM

Maybe with
 

if(ChestCollision(this){
bool ChestCollision(ffc this){
    if(Link->Dir == 0){
        if(Link->X+8 >= this->X){
            if(Link->X+8 <= this->X+16){
                if(Link->Y+8 == this->Y+8)return true;
            }
        }
    }
    return false;
}

Edited by Gégé, 03 October 2018 - 11:14 AM.

  • Avaro likes this

#4 Rocksfan13

Rocksfan13

    Looks best in Blue

  • Members
  • Real Name:Doug
  • Location:Earth

Posted 04 October 2018 - 11:31 AM

Ok.

 

Not sure how that would get put in and where.

 

I don't know scripting, unfortunately. :(



#5 Gégé

Gégé

    Senior

  • Members
  • Real Name:Gérard
  • Location:France

Posted 04 October 2018 - 01:37 PM

// GB Treasure Chest by ~Nimono~
// Make sure to set the CSet of the FFC to the CSet you want the chest to be in!
// Variables:
// DValue: Which Screen->D[] to use to track the chests. Make sure to pick one not currently in use by other scripts!
// D0 chestCombo: The starting combo for your chest, used to make sure you can't reopen chests again. The script changes it to its next combo, so make sure the open chest is the very next combo!
// D1 openSFX: What sound effect ID to play upon opening the chest.
// D2 receiveSFX: What sound to play upon receiving the item.
// D3 itemID: The item to give to the player upon opening the chest.
// D4 receiveMessage: Which message to display upon receiving the item.
// D5 itemDisplay: Whether or not to display the item rising from the chest. 0 = do not display, anything else = display.
// D6 lockValue: Whether or not to have the chest be locked. 0 = no lock, 1 = regular key required; 2 = boss key required.
// If you are using ghost.zh, uncomment out SuspendGhostZHScripts() and ResumeGhostZHScripts().

const int DValue = 5; // change this to change which Screen->D value the chest data is stored into, to avoid conflicts with other scripts that use them

ffc script SmallChest
{
    void run(int chestCombo, int openSFX, int receiveSFX, int itemID, int receiveMessage, int itemDisplay, int lockValue)
    {
        if(itemID == 0)
        {
            itemID = Screen->RoomData;
        }
        int holdType = 0;
        while(true)
        {
            if(Screen->D[DValue]&ConvertToBit(GetFFCNum(this)))
            {
                for(int i; i < 16; i++)
                {
                    if(Screen->ComboF[ComboAt(this->X, this->Y)] == i+16)
                    {
                        Screen->ComboF[ComboAt(this->X, this->Y)] = 0;
                    }
                }
                Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), chestCombo+1);
                Game->SetComboCSet(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), this->CSet);
            }
            if(ChestCollision(this))
            {
                if(Link->InputA && Screen->ComboD[ComboAt(this->X, this->Y)] == chestCombo && (lockValue == 0 || (lockValue == 1 && Game->Counter[CR_KEYS] > 0) || (lockValue == 1 && Game->LKeys[Game->GetCurLevel()] > 0) || (lockValue == 2 && Game->LItems[Game->GetCurLevel()]&LI_BOSSKEY)))
                {
                    if(lockValue == 1)
                    {
                        if(Game->LKeys[Game->GetCurLevel()] > 0)
                        {
                            Game->LKeys[Game->GetCurLevel()] -= 1;
                        }
                        else
                        {
                            Game->DCounter[CR_KEYS] = -1;
                        }
                    }
                    NoAction();
                    //SuspendGhostZHScripts();
                    Game->PlaySound(openSFX);
                    Game->SetComboData(Game->GetCurMap(), Game->GetCurScreen(), ComboAt(this->X, this->Y), chestCombo+1);
                    holdType = Screen->ComboT[ComboAt(this->X, this->Y)];
                    Screen->ComboT[ComboAt(this->X, this->Y)] = CT_SCREENFREEZE;
                    Screen->D[DValue] |= ConvertToBit(GetFFCNum(this));
                    int itemRaise = 0;
                    for(int i; i < 28; i++)
                    {
                        if(itemDisplay > 0)
                        {
                            item Temp = CreateItemAt(itemID, 0, 0);
                            Screen->FastTile(2, this->X, this->Y-8+itemRaise, Temp->OriginalTile, Temp->CSet, OP_OPAQUE);
                            Remove(Temp);
                            itemRaise-=0.25;
                        }
                        NoAction();
                        if(i==27)
                        {
                            Screen->ComboT[ComboAt(this->X, this->Y)] = holdType;
                        }
                        Waitframe();
                    }
                    NoAction();
                    item Box = CreateItemAt(itemID, Link->X, Link->Y);
                    if(itemDisplay > 0)
                    {
                        item Temp = CreateItemAt(itemID, 0, 0);
                        Screen->FastTile(2, this->X, this->Y-8+itemRaise, Temp->OriginalTile, Temp->CSet, OP_OPAQUE);
                        Remove(Temp);
                    }
                    if(Screen->Flags[SF_ITEMS]&1)
                    {
                        Box->Pickup|=IP_HOLDUP;
                    }
                    Game->PlaySound(receiveSFX);
                    Screen->Message(receiveMessage);
                    //ResumeGhostZHScripts();
                }
            }
            Waitframe();
        }
    }
}

int GetFFCNum(ffc thisffc)
{
    for(int i = 1; i < 32; i++)
    {
        ffc checkffc = Screen->LoadFFC(i);
        if(checkffc == thisffc)
        {
            if(i < 17)
            {
                return i;
            }
            else
            {
                return i-16;
            }
        }
    }
    return NULL;
}

int ConvertToBit(int num)
{
    return 1 << (num-1);
}

bool ChestCollision(ffc this){
    if(Link->Dir == 0){
        if(Link->X+8 >= this->X){
            if(Link->X+8 <= this->X+16){
                if(Link->Y+8 == this->Y+8)return true;
            }
        }
    }
    return false;
}

Edited by Gégé, 04 October 2018 - 01:39 PM.


#6 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 05 October 2018 - 07:47 AM

Ugh. This is why I wrote Below(ffc) and DistXY(ffc, max), as general utilities. :/

 

You'd just call:

if ( Below(this) )
{
    if ( DIstX, this, 4 )
    {
        if ( DistY(this, 18) )
        {
            //do open check here
        }
    }
}

@Gégé

 

You don't ultimately want equality here:

if(Link->X+8 >= this->X){
            if(Link->X+8 <= this->X+16){
                if(Link->Y+8 == this->Y+8)return true;

Instead, you want something like this:

bool TriedToOpenChect(ffc f)
{
    //My logic here could be arranged in any manner, but this is the most efficient for this application. -Z
 
    if ( Link->Y >= f->Y + 7 ) //most relevant coordinate, so check it first
    {    
        if ( Link->Y <= f->Y + 18 ) //lighter to check than Abs()
        {
            if ( Abs(Link->X - f->X <= 4 )
            {  
                if ( PressedChestButton() ) //if you map only one button to this, eval it first.
                {
                    return true;
                }
            }
        }
    }
    return false;
}

bool PressedChestButton() //define what buttons can open chests
{
    if ( Link->PressA ) return true;
    if ( Link->PressB ) return true;
    return false;
}

This clamps the check to a mapped area based around the ratio of Link's coordinates to the object coordinates, four pixels off-centre, and between 2 pixels under the chest, and overlapping it by half, without making the check pixel-perfect.


  • ShadowTiger likes this

#7 Rocksfan13

Rocksfan13

    Looks best in Blue

  • Members
  • Real Name:Doug
  • Location:Earth

Posted 09 October 2018 - 12:00 PM

Sorry to be so late in this discussion. Been bombed this week.

 

Will the script edit that Gege made do the trick or does this require something else?



#8 Rocksfan13

Rocksfan13

    Looks best in Blue

  • Members
  • Real Name:Doug
  • Location:Earth

Posted 23 October 2018 - 09:42 AM

Ok. Figured it was long enough to double post here.

 

So, I tried the fix Gege' posted and it does not work.

You can't open the chest now.

 

ZoriaRPG, any way you can show me how to effect the changes you posted?

I'd like to get this corrected so the chests don't open from the side.



#9 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 24 October 2018 - 03:11 AM

Ok. Figured it was long enough to double post here.

 

So, I tried the fix Gege' posted and it does not work.

You can't open the chest now.

 

ZoriaRPG, any way you can show me how to effect the changes you posted?

I'd like to get this corrected so the chests don't open from the side.

 

 

Post the script that you are using now, precisely. Describe what it is doing that you want changed, and I'll have a look.

 

How many chests do you need per screen, at most; and are they always aligned to the grid?



#10 Rocksfan13

Rocksfan13

    Looks best in Blue

  • Members
  • Real Name:Doug
  • Location:Earth

Posted 24 October 2018 - 07:34 AM

It's the same exact script as I posted in the first post.

 

Everything should be aligned.

I have one particular room that has a chest directly to the left of a non-walkable tile. If you walk down around that tile, you can open the chest from the bottom right side of the chest.

I have another room that the chest is on the left and it opens from the bottom left side.

Testing the theory, I placed several in a room (and you can pretty much fill a room with chests) and all of them can be opened by the bottom left or right side of the chest. They can also be opened from below, which is what they are supposed to do and not from the side.

It's not a quest breaker, but very annoying to say the least.

 

I actually was toying with another idea too.

I had wondered if I could take this script and change it to have an enemy come out instead of an item.

I tried to adjust it myself to make it work and it went horribly wrong.

 

BTW, Zoria, thank you for the help and everyone else that has helped me with these things.


Edited by Rocksfan13, 24 October 2018 - 07:35 AM.



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users