Copy to Clipboard Test

GB Chest DX Code

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



const int GBCHEST_PRIZE_RENDER_TIMER = 30; //Time to render prize before acquisition, in frames.

const int GBCHEST_PRIZE_RENDER_SPEED = 0.25; //Rising speed of revealed item during display.



const int SPR_GBCHEST_ENEMY_SPAWN = 22;//Sprite to display, when enemy jumps out of chest.

const int SPR_GBCHEST_ENEMY_MERCY_INVINCIBILITY = 90;//Time, in frames, before enemy starts dealing collision damage after popping out of chest.



//Reworked GB styled treasure chest, originally made by Nimono. Can spawn enemies, instead of items.

//Place invisible FFC on top left corner of treasure chest. Set TileWidth and TileHeight to match chest size 

// Variables:

// SCREEN_D_GBCHEST_DATA: 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. When chest is open, the script changes all combos overlapped by FFC to their next ones in combo data table. If left at 0, it uses combo underneath top left corner of FFC. Otherwise, it cannot be open, until combo underneath top left corner of FFC changes to combo, whose ID is stated in D0, usually via secrets. 

// D1 openSFX: What sound effect ID to play upon opening the chest. <0 - No Hold Up on item acquisition.

// D2 receiveSFX: What sound to play upon receiving the item.

// D3 itemID: The item to give to the player upon opening the chest. < 0 - Id of enemy to spawn instead. 

// D4 receiveMessage: Which message to display upon receiving the item. If D3 <0 -> enemy jump speed/100.

// 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. Original script had no support for Magic Key, this script allows using Magic Key to unlock GB chests.

// D7 Quake power on opening chest. 



// If you are using ghost.zh, uncomment out SuspendGhostZHScripts() and ResumeGhostZHScripts().



ffc script GBChest{

	void run(int chestCombo, int openSFX, int receiveSFX, int itemID, int receiveMessage, int itemDisplay, int lockValue, int quake){

		int cmb = ComboAt(this->X+1, this->Y+1);

		if (Screen->D[SCREEN_D_GBCHEST_DATA]&ConvertToBit(FFCNum(this)) && Screen->ComboD[cmb] == chestCombo){

			GBChestReplaceCombosUnderFFC(this,0);

			Quit();

		}

		

		if (chestCombo==0)chestCombo = Screen->ComboD[cmb];

		if(itemID == 0)itemID = Screen->RoomData;

		int holdType = 0;

		int itemRaise = 0;

		int itemtile = 0;

		int itemcset = 0;

		if (itemID>=0){

			item Temp = CreateItemAt(itemID, 0, 0);

			itemtile = Temp->OriginalTile;

			itemcset = Temp->CSet;		

			Remove(Temp);

		}

		

		while(true){

			if (Screen->D[SCREEN_D_GBCHEST_DATA]&ConvertToBit(FFCNum(this)) && Screen->ComboD[cmb] == chestCombo){

				GBChestReplaceCombosUnderFFC(this,0);

				Quit();

			}

			if(Link->X >= this->X-8 && Link->X <= this->X+this->TileWidth*16-8 && Link->Y >= this->Y+4 && Link->Y <= this->Y+this->TileHeight*16-8){

				if(CenterLinkY() > CenterY(this) && Link->Dir==DIR_UP && Screen->ComboD[cmb] == chestCombo && (lockValue == 0 || (lockValue == 1 && Game->Counter[CR_KEYS] > 0) || (lockValue == 1 && (Game->LKeys[Game->GetCurLevel()] > 0 || Link->Item[I_MAGICKEY])) || (lockValue == 2 && Game->LItems[Game->GetCurLevel()]&LI_BOSSKEY)) && Link->InputUp){

					if(lockValue == 1 && !Link->Item[I_MAGICKEY]){

						if(Game->LKeys[Game->GetCurLevel()] > 0){

							Game->LKeys[Game->GetCurLevel()] -= 1;

						}

						else{

							Game->DCounter[CR_KEYS] = -1;

						}

					}

					NoAction();

					//SuspendGhostZHScripts();

					Game->PlaySound(Abs(openSFX));

					Screen->Quake+=Abs(quake);

					GBChestReplaceCombosUnderFFC(this,0);

					holdType = Screen->ComboT[ComboAt(this->X, this->Y)];

					if (quake==0&&itemID>0)Screen->ComboT[ComboAt(this->X, this->Y)] = CT_SCREENFREEZE;

					Screen->D[SCREEN_D_GBCHEST_DATA] |= ConvertToBit(FFCNum(this));

					for(int i=0; i < GBCHEST_PRIZE_RENDER_TIMER; i++){

						if (itemID<0) break;

						if (itemDisplay==0){

							itemRaise-=GBCHEST_PRIZE_RENDER_SPEED*GBCHEST_PRIZE_RENDER_TIMER;

							break;

						}

						if(itemDisplay > 0)	{

							Screen->FastTile(1, CenterX(this)-8, CenterY(this)-8+itemRaise, itemtile, itemcset, OP_OPAQUE);

							itemRaise-=GBCHEST_PRIZE_RENDER_SPEED;

						}

						NoAction();

						Waitframe();

					}

					

					//NoAction();

					//ResumeGhostZHScripts();

					Screen->ComboT[ComboAt(this->X, this->Y)] = holdType;

					if (itemID>=0){

						item Box = CreateItemAt(itemID, CenterX(this)-8, CenterY(this)-8+itemRaise);						

						Game->PlaySound(receiveSFX);

						Screen->Message(receiveMessage);

						NoAction();

						Waitframe();

						if((Screen->Flags[SF_ITEMS]&1)&&(openSFX>=0))Box->Pickup|=IP_HOLDUP;

						Box->X = Link->X;

						Box->Y = Link->Y;

					}

					else {

						npc n = CreateNPCAt(Abs(itemID), this->X+this->TileWidth*8-8, this->Y+this->TileHeight*8-8);

						lweapon s = CreateLWeaponAt(LW_SPARKLE,this->X+this->TileWidth*8-8, this->Y+this->TileHeight*8-8);

						s->UseSprite(SPR_GBCHEST_ENEMY_SPAWN);

						s->CollDetection=false;

						n->CollDetection=false;

						n->Jump=receiveMessage/100;

						Waitframes(SPR_GBCHEST_ENEMY_MERCY_INVINCIBILITY);

						if (n->isValid())n->CollDetection=true;

					}

					NoAction();				

					Quit();

				}

			}

			Waitframe();

		}

	}

}





int ConvertToBit(int num){

	return 1 << (num-1);

}



//Change combos under FFC to next in list.

void GBChestReplaceCombosUnderFFC(ffc this, int flag){

	int x1 = this->X+1;

	int y1 = this->Y+1;

	int x2 = x1+(this->TileWidth*16)-2;

	int y2 = y1+(this->TileHeight*16)-2;

	for (int i=0;i<176;i++){

		int cx1 = ComboX(i);

		int cy1 = ComboY(i);

		int cx2 = cx1+15;

		int cy2 = cy1+15;

		if (!RectCollision(x1,y1,x2,y2,cx1,cy1,cx2,cy2))continue;

		Screen->ComboD[i]++;

		Screen->ComboF[i]=flag;

	}

}