Jump to content

Photo

Item Check Treasure Chests


  • Please log in to reply
13 replies to this topic

#1 TheLegend_njf

TheLegend_njf

    Deified

  • Members
  • Real Name:Grant

Posted 01 November 2021 - 12:26 AM

I want a treasure chest that will offer you another item if you already have the item the chest originally offers.

 

For example, in ALTTP, if you are carrying the boomerang, the treasure chest in Thieves Town gives you 300 rupees rather than the magic boomerang. 

 

Also, because my treasure chests are color coded, I would like the chest to represent a different color based on item circumstance as well. (For example, a red treasure chest containing the boomerang will now be a green chest containing a red rupee).


  • Bagu likes this

#2 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 09:25 AM

I have a scripted treasure chest code
(working like engine chests and not causing issues, if combined with real engine chests on the same screen)

I think I could write a modified version, which will offer the features you want.



#3 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 10:38 AM

I guess this will work



Sorry for low video quality
 


Edited by Bagu, 01 November 2021 - 10:39 AM.


#4 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 11:01 AM

Here's the code

With this script you can have (max.) 8 Dummy Chests with individual items + 1 engine chest on the same screen.

This modified version will also check if you already got the contained item and switch color and item, in this case. 
It allows you to differ between Gen Keys and Lvl Keys...
 

import "std.zh"
//remove this line if already imported


void EnemyStun(int stun_time)//a little shortcut to stun enemies during item hold.
{
    for(int i=Screen->NumNPCs(); i>=1; i--){
        npc n = Screen->LoadNPC(i);
        n->Stun = Max(n->Stun, stun_time);
    }
}

//D0 = Screen D0-D7 Attribute, to read and write to.
//checks if the chest has already been opened.
//you can use max 8 chests on 1 screen, each has to check/write to unique ScreenD (0-7) 

//D1 = ID of the open chest combo
//use dummy chests for the UncleBug Chests
//The open chest combo doesn't need to be the next in list.

//D2 = Item (item_a), the chest shall contain

//D3 = alternative Item (item_b, if you already got item_a) 

//D4 = Hold Type (0 = no hold up, 1 = One Hand, 2 = Two Hands)

//D5 = Lock Type/ required Key
//( 0 = unlocked, 1 = General Key, 2 = Lvl specific Key, 3 = Boss Key)
//Gen Keys can not unlock Level specific Chests and Lvl Keys can't unlock General Key chests)

//D6 = CSet of the Chest.

//D7 = Alternative CSet


const int CHEST_SOUND = 4;
//opening chest sfx 
//Boomerang sfx by default

ffc script UncleBugChest_COLOR
{
    void run(int check_d, int open_cmb, int item_a, int item_b, int hld_type, int req_key, int color_a, int color_b)
    {
	unless(Screen->D[check_d] == 0){
	    if(Screen->D[check_d] == 1){
	        Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
	        Screen->ComboC[ComboAt(this->X, this->Y)] = color_a;
	        Quit();
	    }
	    else if(Screen->D[check_d] == 2){
	        Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
	        Screen->ComboC[ComboAt(this->X, this->Y)] = color_b;
	        Quit();
	    }
	}
	if((Screen->D[check_d] == 0) && (!Link->Item[item_a])){
	    Screen->ComboC[ComboAt(this->X, this->Y)] = color_a;
	}
	else if((Screen->D[check_d] == 0) && (Link->Item[item_a])){
	    Screen->ComboC[ComboAt(this->X, this->Y)] = color_b;
	}
	while(true){
	    if(!Link->Item[item_a]){
	        if((Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<=9) && (Link->Y > this->Y+7)&&(Link->Dir ==DIR_UP)){
		    if(req_key == 1 && Game->Counter[CR_KEYS] < 1){return;}
		    else if(req_key == 2 && Game->LKeys[Game->GetCurLevel()] < 1){return;}
		    else if((req_key == 3) && (!Game->LItems[Game->GetCurLevel()] == LI_BOSSKEY)){return;}
		    EnemyStun(18);
		    Audio->PlaySound(CHEST_SOUND);
		    Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
		    if(req_key == 1){Game->Counter[CR_KEYS] -=1;}
		    if(req_key == 2){Game->LKeys[Game->GetCurLevel()] -=1;}
		    WaitNoAction(6);
		    GiveLinkItem(item_a, hld_type);
		    WaitNoAction(12);
		    Screen->D[check_d] += 1;
		    Waitframes(3);
		    Quit();
		}
	    }
	    else if(Link->Item[item_a]){
	        if((Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<=9) && (Link->Y > this->Y+7)&&(Link->Dir ==DIR_UP)){
		    if(req_key == 1 && Game->Counter[CR_KEYS] < 1){return;}
		    else if(req_key == 2 && Game->LKeys[Game->GetCurLevel()] < 1){return;}
		    else if((req_key == 3) && (!Game->LItems[Game->GetCurLevel()] == LI_BOSSKEY)){return;}
		    EnemyStun(18);
		    Audio->PlaySound(CHEST_SOUND);
		    Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
		    if(req_key == 1){Game->Counter[CR_KEYS] -=1;}
		    if(req_key == 2){Game->LKeys[Game->GetCurLevel()] -=1;}
		    WaitNoAction(6);
		    GiveLinkItem(item_b, hld_type);
		    WaitNoAction(12);
		    Screen->D[check_d] += 2;
		    Waitframes(3);
		    Quit();
		}
	    }
	    Waitframe();
	}
    }
}

Place an invisible (Changer) at a Dummy Chest's X/Y coordiniates (FFC has to be on grid).
...check "Run Script on Screen Init"
...assign the D0-D7 variables and let the script do the rest.


Edited by Bagu, 01 November 2021 - 12:33 PM.


#5 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 11:23 AM

Oh, yeah
...one thing I need to mention.
...not only for this script.

I forgot to tell, cause this is something I fixed in all my zh libraries.

There seems to be a general mistake in the std_extension.zh file.
one line in the "GiveLinkItem" function.

it's :

else holdtype = Link->Action;

...but it should be:
 

else Link->Action = LA_HOLD2LAND;

...so the 2-Hand hold up isn't working with the original "GiveLinkItem" version.



I've fixed that in my libraries.

So if you want to use the UncleBugChests, you'd need to replace this:
(Original Version)

 

void GiveLinkItem(int itm_id, int holdtype)
{
	item i = Screen->CreateItem(itm_id);
	i->X = Link->X;
	i->Y = Link->Y;
	i->Z = Link->Z;
	if ( holdtype == 1 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD1WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD1WATER;
		else Link->Action = LA_HOLD1LAND;
	}
	else if ( holdtype == 2 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD2WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD2WATER;
		else holdtype = Link->Action;
	}
	else
	{
		if ( holdtype == LA_HOLD1LAND || holdtype == LA_HOLD2LAND || holdtype == LA_HOLD1WATER || holdtype == LA_HOLD2WATER ) 
		{
			Link->HeldItem = itm_id;
			Link->Action = holdtype;
		}
	}
}

...with this:
(Fixed Version)
 

void GiveLinkItem(int itm_id, int holdtype)
{
	item i = Screen->CreateItem(itm_id);
	i->X = Link->X;
	i->Y = Link->Y;
	i->Z = Link->Z;
	if ( holdtype == 1 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD1WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD1WATER;
		else Link->Action = LA_HOLD1LAND;
	}
	else if ( holdtype == 2 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD2WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD2WATER;
		else Link->Action = LA_HOLD2LAND;
	}
	else
	{
		if ( holdtype == LA_HOLD1LAND || holdtype == LA_HOLD2LAND || holdtype == LA_HOLD1WATER || holdtype == LA_HOLD2WATER ) 
		{
			Link->HeldItem = itm_id;
			Link->Action = holdtype;
		}
	}
}

...in include->std.zh->std_extension.zh


Edited by Bagu, 01 November 2021 - 01:24 PM.


#6 Emily

Emily

    Scripter / Dev

  • ZC Developers
  • Pronouns:She / Her

Posted 01 November 2021 - 01:23 PM

Oh, yeah
...one thing I need to mention.
...not only for this script.

I forgot to tell, cause this is something I fixed in all my zh libraries.

There seems to be a general mistake in the std_extension.zh file.
one line in the "GiveLinkItem" function.

You should never edit anything in any std_zh files. If you want a version of the function that works differently, make that function as part of your script. Editing std_zh files is poor form, and should never be done. If you were to update to a new ZC build, you would lose those changes; and copying an std_zh file from an old version to a new version is not guaranteed to compile at all.



#7 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 01:32 PM

You should never edit anything in any std_zh files. If you want a version of the function that works differently, make that function as part of your script. Editing std_zh files is poor form, and should never be done. If you were to update to a new ZC build, you would lose those changes; and copying an std_zh file from an old version to a new version is not guaranteed to compile at all.

Well, alright
...this is the only change I ever made

2_Hand Hold Up wasn't working before, with "GiveLinkItem(itm_ID, holdtype);"
...and I never got any issues since I fixed the line.

I thought it would be a bit much to create a copy file or entire folder because of just 1 line.


And I never copied a file to a newer built package.

...I just changed that line in the new version, too.


Edited by Bagu, 01 November 2021 - 01:33 PM.


#8 Emily

Emily

    Scripter / Dev

  • ZC Developers
  • Pronouns:She / Her

Posted 01 November 2021 - 01:33 PM

Well, alright
...this is the only change I ever made

2_Hand Hold Up wasn't working before, with "GiveLinkItem(itm_ID, holdtype);"
...and I never got any issues since I fixed the line.

I thought it would be a bit much to create a copy file or entire folder because of just 1 line.


And I never copied a file to a newer built package.

...I just changed that line in the new version.

You don't need to copy the file or folder, just write your own function, in your own script file where you are writing the script. You know, like you would write any function in a script....


  • Bagu likes this

#9 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 01:35 PM

That's what I made first time


...but then I wanted it to work in the "original" version...

...cause why having an alternative function, when there's already a function, that only needs one line to be fixed?

...but yeah, I would never suggest to mess around with libraries, for sure.
...although I still don't think that this certain modification was a mistake.


Edited by Bagu, 01 November 2021 - 01:39 PM.


#10 Emily

Emily

    Scripter / Dev

  • ZC Developers
  • Pronouns:She / Her

Posted 01 November 2021 - 01:39 PM

That's what I made first time


...but then I wanted it to work in the "original" version...

...cause why having an alternative function, when thee's already a function, that only needs one line to be fixed?

because you don't edit standard libraries. Every time you update ZC you would need to re-fix the function, and if you give your script to someone else, you would require them to do the same fix (which is exactly what you were doing in this thread, telling them to edit their std_extension). If you include a copy function in your script, then other people won't need to edit anything to make the script work.


  • Bagu likes this

#11 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 01:44 PM

This is absolutely right.

...and yes, I guess I should rather offer it with a seperate (simply renamed) function void.

...or it could be changed in the default std_extension.zh file :) .

...the only thing that really amazes me, is that no one else has mentioned problems with this single line before.
 


Edited by Bagu, 01 November 2021 - 01:49 PM.


#12 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 02:01 PM

Here's the script, with a seperate void for the function.
...so, no further modification is required.


everything else, same as before:
You can have (max.) 8 Dummy Chests with individual items + 1 engine chest on the same screen.

This (advanced) version of my UncleBugChests will also check if you already got the contained item and switch color and item, in this case. 
It allows you to differ between Gen Keys and Lvl Keys...

Place an invisible (Changer) FFC at a Dummy Chest's X/Y coordiniates (FFC has to be on grid).
...check "Run Script on Screen Init"
...assign the D0-D7 variables and let the script do the rest.
 

import "std.zh"
//remove this line if already imported


void EnemyStun(int stun_time)//a little shortcut to stun enemies during item hold. Inspired by MooshPit.
{
    for(int i=Screen->NumNPCs(); i>=1; i--){
        npc n = Screen->LoadNPC(i);
        n->Stun = Max(n->Stun, stun_time);
    }
}

void GiveItem(int itm_id, int holdtype)//Fixed version of the std_extension "GiveLinkItem".
{
	item i = Screen->CreateItem(itm_id);
	i->X = Link->X;
	i->Y = Link->Y;
	i->Z = Link->Z;
	if ( holdtype == 1 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD1WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD1WATER;
		else Link->Action = LA_HOLD1LAND;
	}
	else if ( holdtype == 2 )
	{
		Link->HeldItem = itm_id;
		if ( Link->Action == LA_SWIMMING ) Link->Action = LA_HOLD2WATER;
		else if ( Link->Action == LA_DIVING ) Link->Action = LA_HOLD2WATER;
		else Link->Action = LA_HOLD2LAND;
	}
	else
	{
		if ( holdtype == LA_HOLD1LAND || holdtype == LA_HOLD2LAND || holdtype == LA_HOLD1WATER || holdtype == LA_HOLD2WATER ) 
		{
			Link->HeldItem = itm_id;
			Link->Action = holdtype;
		}
	}
}


//D0 = Screen D0-D7 Attribute, to read and write to.
//checks if the chest has already been opened.
//you can use max 8 chests on 1 screen, each has to check/write to unique ScreenD (0-7) 

//D1 = ID of the open chest combo
//use dummy chests for the UncleBug Chests
//The open chest combo doesn't need to be the next in list.

//D2 = Item (item_a), the chest shall contain

//D3 = alternative Item (item_b, if you already got item_a) 

//D4 = Hold Type (0 = no hold up, 1 = One Hand, 2 = Two Hands)

//D5 = Lock Type/ required Key
//( 0 = unlocked, 1 = General Key, 2 = Lvl specific Key, 3 = Boss Key)
//Gen Keys can not unlock Level specific Chests and Lvl Keys can't unlock General Key chests)

//D6 = CSet of the Chest.

//D7 = Alternative CSet


const int CHEST_SOUND = 4; //Boomerang sfx by default

ffc script UncleBugChest_COLOR
{
    void run(int check_d, int open_cmb, int item_a, int item_b, int hld_type, int req_key, int color_a, int color_b)
    {
	unless(Screen->D[check_d] == 0){
	    if(Screen->D[check_d] == 1){
	        Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
	        Screen->ComboC[ComboAt(this->X, this->Y)] = color_a;
	        Quit();
	    }
	    else if(Screen->D[check_d] == 2){
	        Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
	        Screen->ComboC[ComboAt(this->X, this->Y)] = color_b;
	        Quit();
	    }
	}
	if((Screen->D[check_d] == 0) && (!Link->Item[item_a])){
	    Screen->ComboC[ComboAt(this->X, this->Y)] = color_a;
	}
	else if((Screen->D[check_d] == 0) && (Link->Item[item_a])){
	    Screen->ComboC[ComboAt(this->X, this->Y)] = color_b;
	}
	while(true){
	    if(!Link->Item[item_a]){
	        if((Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<=9) && (Link->Y > this->Y+7)&&(Link->Dir ==DIR_UP)){
		    if(req_key == 1 && Game->Counter[CR_KEYS] < 1){return;}
		    else if(req_key == 2 && Game->LKeys[Game->GetCurLevel()] < 1){return;}
		    else if((req_key == 3) && (!Game->LItems[Game->GetCurLevel()] == LI_BOSSKEY)){return;}
		    EnemyStun(18);
		    Audio->PlaySound(CHEST_SOUND);
		    Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
		    if(req_key == 1){Game->Counter[CR_KEYS] -=1;}
		    if(req_key == 2){Game->LKeys[Game->GetCurLevel()] -=1;}
		    WaitNoAction(6);
		    GiveItem(item_a, hld_type);
		    WaitNoAction(12);
		    Screen->D[check_d] += 1;
		    Waitframes(3);
		    Quit();
		}
	    }
	    else if(Link->Item[item_a]){
	        if((Distance(CenterLinkX(), CenterLinkY(), CenterX(this), CenterY(this))<=9) && (Link->Y > this->Y+7)&&(Link->Dir ==DIR_UP)){
		    if(req_key == 1 && Game->Counter[CR_KEYS] < 1){return;}
		    else if(req_key == 2 && Game->LKeys[Game->GetCurLevel()] < 1){return;}
		    else if((req_key == 3) && (!Game->LItems[Game->GetCurLevel()] == LI_BOSSKEY)){return;}
		    EnemyStun(18);
		    Audio->PlaySound(CHEST_SOUND);
		    Screen->ComboD[ComboAt(this->X, this->Y)] = open_cmb;
		    if(req_key == 1){Game->Counter[CR_KEYS] -=1;}
		    if(req_key == 2){Game->LKeys[Game->GetCurLevel()] -=1;}
		    WaitNoAction(6);
		    GiveItem(item_b, hld_type);
		    WaitNoAction(12);
		    Screen->D[check_d] += 2;
		    Waitframes(3);
		    Quit();
		}
	    }
	    Waitframe();
	}
    }
}

Edited by Bagu, 01 November 2021 - 02:39 PM.


#13 Emily

Emily

    Scripter / Dev

  • ZC Developers
  • Pronouns:She / Her

Posted 01 November 2021 - 02:09 PM

This is absolutely right.

...and yes, I guess I should rather offer it with an seperate (simply renamed) function void.

...or it could be changed in the default std_extension.zh file :) .

...the only thing that really amazes me, is that no one else has mentioned problems with this single line before.
 

Most people don't use *anything* in std_extension, at least as far as I know. They just write their own copies anyway, which would be why no one would have reported an issue. The correct way to handle this would be to file a bug report. (No need to report this one, as I'm fixing it for next build)


  • Bagu likes this

#14 Bagu

Bagu

    Fandomizer

  • Members
  • Real Name:A.I. Bot Bottomheimer
  • Location:Germany

Posted 01 November 2021 - 02:16 PM

I always wanted to post it in Bug Reports
...but since this was a small fix for me and I never exchanged codes, using this function (before today), I always forgot to write a post


BTW, I didn't want to act like Brainy Smurf :)


But I'm happy that this is finally reported.
Sorry that I always forgot it before


Edited by Bagu, 01 November 2021 - 02:18 PM.



1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users