Copy to Clipboard Test

GB / LttP-style Treasure Chest Code

// 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 GBChest
{
	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);
}