Copy to Clipboard Test

Resource Upgrade shop Code

//Tiles used for resource icons. Each counter is separate constant.

const int TILE_CR_0 = 25226;

const int TILE_CR_1 = 25225;

const int TILE_CR_2 = 25228;

const int TILE_CR_3 = 25227;

const int TILE_CR_4 = 25229;

const int TILE_CR_5 = 25230;

const int TILE_CR_6 = 25227;

const int TILE_CR_7 = 27533;

const int TILE_CR_8 = 27533;

const int TILE_CR_9 = 27533;

const int TILE_CR_10 = 27533;

const int TILE_CR_11 = 0;

const int TILE_CR_12 = 0;

const int TILE_CR_13 = 0;

const int TILE_CR_14 = 0;

const int TILE_CR_15 = 0;

const int TILE_CR_16 = 0;

const int TILE_CR_17 = 0;

const int TILE_CR_18 = 0;

const int TILE_CR_19 = 0;

const int TILE_CR_20 = 0;

const int TILE_CR_21 = 0;

const int TILE_CR_22 = 0;

const int TILE_CR_23 = 0;

const int TILE_CR_24 = 0;

const int TILE_CR_25 = 0;

const int TILE_CR_26 = 0;

const int TILE_CR_27 = 0;

const int TILE_CR_28 = 0;

const int TILE_CR_29 = 0;

const int TILE_CR_30 = 0;

const int TILE_CR_31 = 0;



//Csets used to render resource icons. Each counter is separate constant.

const int CSET_CR_0 = 8;

const int CSET_CR_1 = 5;

const int CSET_CR_2 = 7;

const int CSET_CR_3 = 1;

const int CSET_CR_4 = 4;

const int CSET_CR_5 = 1;

const int CSET_CR_6 = 8;

const int CSET_CR_7 = 1;

const int CSET_CR_8 = 5;

const int CSET_CR_9 = 7;

const int CSET_CR_10 = 8;

const int CSET_CR_11 = 0;

const int CSET_CR_12 = 0;

const int CSET_CR_13 = 0;

const int CSET_CR_14 = 0;

const int CSET_CR_15 = 0;

const int CSET_CR_16 = 0;

const int CSET_CR_17 = 0;

const int CSET_CR_18 = 0;

const int CSET_CR_19 = 0;

const int CSET_CR_20 = 0;

const int CSET_CR_21 = 0;

const int CSET_CR_22 = 0;

const int CSET_CR_23 = 0;

const int CSET_CR_24 = 0;

const int CSET_CR_25 = 0;

const int CSET_CR_26 = 0;

const int CSET_CR_27 = 0;

const int CSET_CR_28 = 0;

const int CSET_CR_29 = 0;

const int CSET_CR_30 = 0;

const int CSET_CR_31 = 0;



const int SCREEN_D_SOLDOUT = 0;//Scree D register used to track one-time pusrchases for shops.



const int FONT_RESOURCE_SHOP = 0;//Font used to render strings in shop UI

const int C_RESOURCE_CAN_AFFORD = 0x52;//Color used to indicate cost, if Link can afford purchase.

const int C_RESOURCE_CANNOT_AFFORD = 0x81;//Color used to indicate cost, if Link cannot afford purchase.

const int C_RESOURCE_FONT_SHADOW = 0x71;//Shadow for HUD font drawing (Color).



const int TILE_RESOURCE_FRAME = 20052;//Id of top left corner for 3x3 frame used to render UI frame.

const int CSET_RESOURCE_FRAME = 11;//ICSet used to render UI frame.



const int CMB_SOLD_OUT_SIGN = 1011;//Combo used to render "Sold Out" sign after doing one-time purchase.

const int CSET_SOLD_OUT_SIGN = 11;//CSet used to render "Sold Out" sign after doing one-time purchase.



const int CMB_RESOURCE_SHOP_PROMPT = 911;//Combo ID used to render prompt, when Link steps on shop spot.

const int CSET_RESOURCE_SHOP_PROMPT = 11;//CSet used to render prompt, when Link steps on shop spot.



const int RESOURCE_DISPLAY_X_OFFSET = 0;//Coordinates of rendering item displayed in the screen, relative to FFC`s position.

const int RESOURCE_DISPLAY_Y_OFFSET = -16;



const int RESOURCE_DISPLAY_MENU_X_OFFSET = 64;//Coordinates of rendering item displayed in the menu, relative to FFC`s position.

const int RESOURCE_DISPLAY_MENU_Y_OFFSET = 0;



//Skyward Sword resource upgrade/resource shop.



//An NPC that offers specific service, either new item, item upgrade, or secret trigger, for cost that consist of multiple counters to be paid simultaneously.

//Stand on FFC and press Ex1 to render string and then cost (up to 6 different counters with separate cost for each). If you can afford, press Ex1 to confirm payment, or Ex2 to cancel. If HP is used as part of cost, minimum of 1 heart must be left to afford payment.



//1. Set up graphics:

//   TILE_CR_* for rendering counter icons using CSET_CR_* for shop UI.

//   3x3 frame for TILE_RESOURCE_FRAME. Needed to render UI frame using CSET_RESOURCE_FRAME CSet.

//   Combo for "Sold Out sign".

//   Combo for prompt display, when Link tands on FFC.

//2. Set up constants in script file to match graphics you set up.

//3. Place FFC st shop position.

//   D0-D5 - counter costs, for each counter:

//         #####.____ - ID of counter used to pay. <0 - ID of required item (taken away as part of barter deal)

//         _____.#### - counter amount to pay.

//   D6 #####.____ - String to display as intro when standing on FFC and pressing EX1.

//   D6 _____.#### - String to display on purchase.

//   D7 #####.____ - Screen D bit to track "Sold Out" status. >12 - infinite stock in shop.

//   D7 _____.#### - ID of item sold/upgraded into. If D7<0 - secrets trigger instead on purchase (cash gate, building construction).

ffc script ResourceUpgradeShop{

	void run (int cost1, int cost2, int cost3, int cost4, int cost5, int cost6, int req, int award){

		int CR_TILES[32] = {TILE_CR_0,TILE_CR_1,TILE_CR_2,TILE_CR_3, TILE_CR_4,TILE_CR_5,TILE_CR_6,TILE_CR_7,TILE_CR_8,TILE_CR_9,

			TILE_CR_10,TILE_CR_11,TILE_CR_12,TILE_CR_13, TILE_CR_14,TILE_CR_15,TILE_CR_16,TILE_CR_17,TILE_CR_18,TILE_CR_19,

			TILE_CR_20,TILE_CR_21,TILE_CR_22,TILE_CR_23, TILE_CR_24,TILE_CR_25,TILE_CR_26,TILE_CR_27,TILE_CR_28,TILE_CR_29,

		TILE_CR_30,TILE_CR_31};

		int CR_CSETS[32] = {CSET_CR_0,CSET_CR_1,CSET_CR_2,CSET_CR_3, CSET_CR_4,CSET_CR_5,CSET_CR_6,CSET_CR_7,CSET_CR_8,CSET_CR_9,

			CSET_CR_10,CSET_CR_11,CSET_CR_12,CSET_CR_13, CSET_CR_14,CSET_CR_15,CSET_CR_16,CSET_CR_17,CSET_CR_18,CSET_CR_19,

			CSET_CR_20,CSET_CR_21,CSET_CR_22,CSET_CR_23, CSET_CR_24,CSET_CR_25,CSET_CR_26,CSET_CR_27,CSET_CR_28,CSET_CR_29,

		CSET_CR_30,CSET_CR_31};

		int RawCosts[6] = {cost1, cost2, cost3, cost4, cost5, cost6};

		int COSTS[6];

		int REQS[6];

		int ITEMTILE[6];

		int ITEMCSET[6];

		for (int i=0; i<SizeOfArray(COSTS);i++){

			REQS[i] =  GetHighFloat(RawCosts[i]);

			COSTS[i] = GetLowFloat(RawCosts[i]);

			if (RawCosts[i]<0){

				item it = Screen->CreateItem(Abs(REQS[i]));

				ITEMTILE[i] = it->OriginalTile;

				ITEMCSET[i] = it->CSet;

				Remove(it);

			}

		}

		int itm = Abs(GetLowFloat(award));

		int ScreenD = Abs(GetHighFloat(award));

		int EndStr = Abs(GetLowFloat(req));

		int InfoString = Abs(GetHighFloat(req));

		if (ScreenD<13){

			if (GetScreenDBit(SCREEN_D_SOLDOUT, ScreenD)){

				this->Data = CMB_SOLD_OUT_SIGN;

				this->CSet = CSET_SOLD_OUT_SIGN;

				Quit();

			}

		}

		int AwarditemTile = GetItemTile(itm);

		int AwarditemCSet = GetItemCSet(itm);		

		int cmb = 0;

		int origcmb = ComboAt(CenterX(this), CenterY(this));

		int state = 0;

		int counter = 0;

		int cost = 0;

		int hpused = 0;

		bool canafford = true;

		int str1[] = "/";

		

		int str2[] = "Not enough";

		int str3[] = "Ex1-Confirm";

		int str4[] = "OK";

		

		int str5[] = "resources";

		int str6[] = "Missing";

		int str7[] = "Ex2-Cancel";

		int str8[] = "1 heart";

		int str9[] = "must left";

		

		

		while(true){

			if (state==0){

				if ( award>0)Screen->FastTile(3,this->X+RESOURCE_DISPLAY_X_OFFSET, this->Y+RESOURCE_DISPLAY_Y_OFFSET,AwarditemTile, AwarditemCSet, OP_OPAQUE);

				cmb = ComboAt(CenterLinkX(), CenterLinkY()-2);

				if (cmb==origcmb){

					Screen->FastCombo(6, Link->X,Link->Y-15,CMB_RESOURCE_SHOP_PROMPT, CSET_RESOURCE_SHOP_PROMPT,OP_OPAQUE);

					if (Link->PressEx1){

						Screen->Message(InfoString);

						state=1;

					}

				}

			}

			else if (state==1){

				hpused=0;

				if ( award>0){

					Screen->FastTile(3,this->X+RESOURCE_DISPLAY_X_OFFSET, this->Y+RESOURCE_DISPLAY_Y_OFFSET,AwarditemTile, AwarditemCSet, OP_OPAQUE);

					}

				DrawFrame(6,TILE_RESOURCE_FRAME,64,16,8,9,CSET_RESOURCE_FRAME,OP_OPAQUE);

				if ( award>0){

					DrawFrame(6,TILE_RESOURCE_FRAME,112+RESOURCE_DISPLAY_MENU_X_OFFSET,0+RESOURCE_DISPLAY_MENU_Y_OFFSET,2,2,CSET_RESOURCE_FRAME,OP_OPAQUE);

					Screen->FastTile(6,120+RESOURCE_DISPLAY_MENU_X_OFFSET, 8+RESOURCE_DISPLAY_MENU_Y_OFFSET,AwarditemTile, AwarditemCSet, OP_OPAQUE);

				}				

				for (int i=0;i<SizeOfArray(REQS);i++){

					counter = REQS[i];

					cost = COSTS[i];

					if (REQS[i]<0){

						Screen->FastTile(6, 80,28+17*i, ITEMTILE[i], ITEMCSET[i], OP_OPAQUE);

						int itm = Abs(REQS[i]);

						if (C_RESOURCE_FONT_SHADOW>0){

							if (Link->Item[itm]) Screen->DrawString(6,105, 33+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str4, OP_OPAQUE);

							else Screen->DrawString(6,105, 33+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str6, OP_OPAQUE);

						}

						if (Link->Item[itm]) Screen->DrawString(6,104, 32+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_CAN_AFFORD, -1, 0, str4, OP_OPAQUE);

						else Screen->DrawString(6,104, 32+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_CANNOT_AFFORD, -1, 0, str6, OP_OPAQUE);

						continue;

					}

					if (cost==0)continue;

					if (counter==CR_LIFE && cost>0)hpused=cost;

					if (C_RESOURCE_FONT_SHADOW>0){

						Screen->DrawInteger(6,99, 33+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0,0, Game->Counter[counter],0, OP_OPAQUE);

						Screen->DrawString(6,131, 33+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str1, OP_OPAQUE);

						Screen->DrawInteger(6,139, 33+17*i,FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0,0, cost,0, OP_OPAQUE);

					}

					Screen->FastTile(6, 80,28+17*i, CR_TILES[counter], CR_CSETS[counter], OP_OPAQUE);

					Screen->DrawInteger(6,98, 32+17*i,FONT_RESOURCE_SHOP, Cond(Game->Counter[counter]>=cost,C_RESOURCE_CAN_AFFORD,C_RESOURCE_CANNOT_AFFORD), -1, 0,0, Game->Counter[counter],0, OP_OPAQUE);

					Screen->DrawString(6,130, 32+17*i,FONT_RESOURCE_SHOP, 1, -1, 0, str1, OP_OPAQUE);

					Screen->DrawInteger(6,138, 32+17*i,FONT_RESOURCE_SHOP, 1, -1, 0,0, cost,0, OP_OPAQUE);

				}

				if (hpused>0 && Link->HP < hpused+16){

					if (C_RESOURCE_FONT_SHADOW>0){

						Screen->DrawString(6,85, 135, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str8, OP_OPAQUE);

						Screen->DrawString(6,85, 143, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str9, OP_OPAQUE);

					}

					Screen->DrawString(6,84, 134, FONT_RESOURCE_SHOP, 1, -1, 0, str8, OP_OPAQUE);

					Screen->DrawString(6,84, 142, FONT_RESOURCE_SHOP, 1, -1, 0, str9, OP_OPAQUE);

				}

				else if (!CanAfford(COSTS, REQS)){

					if (C_RESOURCE_FONT_SHADOW>0){

						Screen->DrawString(6,89, 135, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str2, OP_OPAQUE);

						Screen->DrawString(6,89, 143, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str5, OP_OPAQUE);

					}

					Screen->DrawString(6,88, 134, FONT_RESOURCE_SHOP, 1, -1, 0, str2, OP_OPAQUE);

					Screen->DrawString(6,88, 142, FONT_RESOURCE_SHOP, 1, -1, 0, str5, OP_OPAQUE);

				}

				else{

					if (C_RESOURCE_FONT_SHADOW>0){

						Screen->DrawString(6,81, 135, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str3, OP_OPAQUE);

						Screen->DrawString(6,81, 143, FONT_RESOURCE_SHOP, C_RESOURCE_FONT_SHADOW, -1, 0, str7, OP_OPAQUE);

					}

					Screen->DrawString(6,80, 134, FONT_RESOURCE_SHOP, 1, -1, 0, str3, OP_OPAQUE);

					Screen->DrawString(6,80, 142, FONT_RESOURCE_SHOP, 1, -1, 0, str7, OP_OPAQUE);

				}

				if (Link->PressEx2) state=0;

				if (Link->PressEx1){

					if (CanAfford(COSTS,REQS)){

						for (int i=0;i<SizeOfArray(REQS);i++){

							if (REQS[i]<0){

								int itm = Abs(REQS[i]);

								Link->Item[itm]=false;

							}

							else{

								counter = REQS[i];

								cost = COSTS[i];

								Game->DCounter[counter]-=cost;

							}

						}

						Screen->Message(EndStr);

						if (award<0){

							Game->PlaySound(SFX_SECRET);

							Screen->TriggerSecrets();

							Screen->State[ST_SECRET]=true;

						}

						else{

							item it = CreateItemAt(itm, Link->X, Link->Y);

							it->Pickup +=IP_HOLDUP;

						}

						if (ScreenD<13){

							SetScreenDBit(SCREEN_D_SOLDOUT, ScreenD, true);

							this->Data = CMB_SOLD_OUT_SIGN;

							this->CSet = CSET_SOLD_OUT_SIGN;

							Quit();

						}

						else state=0;

					}

					else state=0;

				}

				NoAction();

			}

			Waitframe();

		}

	}

	

	bool CanAfford(int costs, int reqs){

		for (int i=0;i<SizeOfArray(reqs);i++){

			int counter = reqs[i];

			int cost = costs[i];

			if (counter<0){

				int itm = Abs(counter);

				if (!Link->Item[itm])return false;

			}

			if (Game->Counter[counter]<cost) return false;

			if (counter== CR_LIFE && Game->Counter[counter]<cost+16) return false;

		}

		return true;

	}

	

	void DrawFrame(int layer, int tile, int posx, int posy, int sizex, int sizey, int CSet, int opacity){

		int drawx = posx;

		int drawy = posy;

		int xoffset=0;

		int yoffset=0;

		for (int w=0; w<sizex; w++){

			drawx = posx+16*w;

			xoffset=0;

			if (w>0)xoffset=1;

			if (w==sizex-1) xoffset=2;

			for (int h=0; h<sizey; h++){

				drawy = posy+16*h;

				yoffset=0;

				if (h>0)yoffset=1;

				if (h==sizey-1) yoffset=2;

				Screen->FastTile(layer, drawx, drawy, tile +xoffset+20*yoffset, CSet, opacity);

			}

		}

	}

	

	int GetItemTile(int itm){

		item it =Screen->CreateItem(itm);

		int ret = it->OriginalTile;

		Remove(it);

		return ret;

	}

	

	int GetItemCSet(int itm){

		item it =Screen->CreateItem(itm);

		int ret = it->CSet;

		Remove(it);

		return ret;

	}

}



// Shop cleanout reward.

//Rewards player for doing all one-time purchases in shop using "ResourceUpgradeShop" script within current screen. Shops with infinite stock are ignored.

//Place invisible FFC anywhere in the screen.

//D0 - String to display on accomplishment.

//D1 - Reward. >0 - Item ID, <0 - permanent secrets.

ffc script ResourceShopCleanoutReward{

	void run(int string, int reward){

		if (reward>=0){

			if (Screen->State[ST_SPECIALITEM])Quit();

		}

		else{

			if (Screen->State[ST_SECRET])Quit();

		}

		while(!ResourceShopCleaned())Waitframe();

		Waitframe();

		Screen->Message(string);

		Waitframe();

		if (reward>=0){

			item it = CreateItemAt(reward, Link->X, Link->Y);

			it->Pickup +=0x802;

		}

		else{

			Game->PlaySound(SFX_SECRET);

			Screen->TriggerSecrets();

			Screen->State[ST_SECRET]=true;

		}

	}

	

	bool ResourceShopCleaned(){

		int str[] = "ResourceUpgradeShop";

		int scr = Game->GetFFCScript(str);

		for (int i = 1; i<=32;i++){

			ffc f = Screen->LoadFFC(i);

			if (f->Script!=scr) continue;

			int ScreenD = Abs(GetHighFloat(f->InitD[7]));

			if (ScreenD>12) continue;

			if (!GetScreenDBit(SCREEN_D_SOLDOUT, ScreenD)) return false;

		}

		return true;

	}

}