diff options
Diffstat (limited to '')
| -rw-r--r-- | kamek_pal.x | 1 | ||||
| -rw-r--r-- | koopatlas.yaml | 12 | ||||
| -rw-r--r-- | src/bonusRoom.cpp | 62 | ||||
| -rw-r--r-- | src/koopatlas/core.cpp | 25 | ||||
| -rw-r--r-- | src/koopatlas/core.h | 6 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 8 | ||||
| -rw-r--r-- | src/koopatlas/shop.cpp | 463 | ||||
| -rw-r--r-- | src/koopatlas/shop.h | 60 | 
8 files changed, 606 insertions, 31 deletions
| diff --git a/kamek_pal.x b/kamek_pal.x index 16996cb..1619ca6 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -736,6 +736,7 @@ SECTIONS {  	resetAnim__Q23m2d13EmbedLayout_cFib = 0x800C94C0;  	disableAllAnimations__Q23m2d13EmbedLayout_cFv = 0x800C95F0;  	isAnimOn__Q23m2d13EmbedLayout_cFi = 0x800C9700; +	isAnyAnimOn__Q23m2d13EmbedLayout_cFv = 0x800C9730;  	free__Q23m2d13EmbedLayout_cFv = 0x800C9A20;  	execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9650;  	scheduleForDrawing__Q23m2d6Base_cFv = 0x80163990; diff --git a/koopatlas.yaml b/koopatlas.yaml index c376f51..1bc3466 100644 --- a/koopatlas.yaml +++ b/koopatlas.yaml @@ -12,6 +12,7 @@ source_files:    - ../src/koopatlas/map.cpp    - ../src/koopatlas/mapdata.cpp    - ../src/koopatlas/pathmanager.cpp +  - ../src/koopatlas/shop.cpp  hooks:    - name: BuildWorldMap @@ -39,6 +40,17 @@ hooks:      src_addr_pal: 0x80984710      target_func: 'dWMMap_c::build(void)' +  - name: BuildWMShop +    type: add_func_pointer +    src_addr_pal: 0x80986074 +    target_func: 'dWMShop_c::build(void)' + +  - name: BuildWMdShopItem +    type: add_func_pointer +    src_addr_pal: 0x809894B4 +    target_func: 'dShopItem::build(void)' + +  # fix the STOCK_ITEM references    - name: StockItemFix      type: patch diff --git a/src/bonusRoom.cpp b/src/bonusRoom.cpp index 2b0144d..c4a84cd 100644 --- a/src/bonusRoom.cpp +++ b/src/bonusRoom.cpp @@ -10,6 +10,8 @@ extern "C" void *PlaySoundAsync(dStageActor_c *, int soundID);  extern "C" void *StopBGMMusic();  extern "C" void *StartBGMMusic();  extern "C" dStageActor_c* GetSpecificPlayerActor(int number); +extern "C" void *SoundRelatedClass; +extern "C" void *MapSoundPlayer(void *SoundClass, int soundID, int unk);  int Songs[16][4][16][3] = {  @@ -159,8 +161,8 @@ const char* Prizes[10][4] = {  	{ "I_penguin", 		"g3d/I_penguin.brres", 			"I_penguin", 			"wait2" },  	{ "I_propeller", 	"g3d/I_propeller_model.brres", 	"I_propeller_model", 	"wait2" },  	{ "I_kinoko_bundle","g3d/I_mini_kinoko.brres", 		"I_mini_kinoko", 		"wait2" }, -	{ "I_hammer", 		"g3d/I_hammer.brres", 			"I_hammer", 			"wait2" },  	{ "I_star", 		"g3d/I_star.brres", 			"I_star", 				"wait2" }, +	{ "I_hammer", 		"g3d/I_fireflower.brres", 			"I_hammer", 			"wait2" },  	{ "I_kinoko_bundle","g3d/I_life_kinoko.brres", 		"I_life_kinoko", 		"wait2" },  	{ "obj_coin", 		"g3d/obj_coin.brres", 			"obj_coin", 			"wait2" }  }; @@ -199,30 +201,30 @@ int PrizePacks[16][4] = { // Numbers list prizes for each level  };  int Notes[24] = { -	SE_EMY_PATAMET_STEP,  -	SE_EMY_PATAMET_STEP_2,  -	SE_EMY_PATAMET_STEP_3,  -	SE_EMY_PATAMET_STEP_4,  -	SE_EMY_PATAMET_STEP_5,  -	SE_EMY_PATAMET_STEP_6,  -	SE_EMY_PATAMET_STEP_7,  -	SE_EMY_PATAMET_STEP_8,  -	SE_EMY_PATAMET_STEP,  -	SE_EMY_PATAMET_STEP_2,  -	SE_EMY_PATAMET_STEP_3,  -	SE_EMY_PATAMET_STEP_4,  -	SE_EMY_PATAMET_STEP_5,  -	SE_EMY_PATAMET_STEP_6,  -	SE_EMY_PATAMET_STEP_7,  -	SE_EMY_PATAMET_STEP_8,  -	SE_EMY_PATAMET_STEP,  -	SE_EMY_PATAMET_STEP_2,  -	SE_EMY_PATAMET_STEP_3,  -	SE_EMY_PATAMET_STEP_4,  -	SE_EMY_PATAMET_STEP_5,  -	SE_EMY_PATAMET_STEP_6,  -	SE_EMY_PATAMET_STEP_7,  -	SE_EMY_PATAMET_STEP_8,  +	STRM_BGM_HIKOUSEN_ROUKA, 	// C +	STRM_BGM_HIKOUSEN_ROUKA_FAST,  +	STRM_BGM_LAST_BOSS_FAST, 	// D +	STRM_BGM_LAST_BOSS,  +	STRM_BGM_ROAD_TO_LAST_FAST, 	// E +	STRM_BGM_ROAD_TO_LAST, 	// F +	STRM_BGM_LAST_CASTLE_APPEAR,  +	STRM_BGM_SELECT_W5, 	// G +	STRM_BGM_SELECT_W7, 	 +	STRM_BGM_HIKOUSEN, 		// A +	STRM_BGM_HIKOUSEN_BOSS_FAST, 	 +	STRM_BGM_HIKOUSEN_FAST, 	// B +	STRM_BGM_OBAKE, 	//  C +	STRM_BGM_SHIRO_FAST, 	 +	STRM_BGM_SHIRO, 	//  D +	STRM_BGM_WATER_FAST,  +	STRM_BGM_WATER, 	//  E +	STRM_BGM_TORIDE_BOSS_FAST, 	//  F +	STRM_BGM_TORIDE_BOSS,  +	STRM_BGM_DEMO_ED, 	//  G +	STRM_BGM_DEMO_OP,  +	STRM_BGM_SELECT_W8, 	//  A +	STRM_BGM_MG_BTL,  +	STRM_BGM_OBAKE_FAST, 	//  B  }; @@ -524,10 +526,10 @@ int dSingAlong::onCreate() {  	OSReport("Creating the Sing Along gang.");  	// Load in the settings  	this->song = this->settings & 0xF; -	this->prize[0] = (this->settings >> 16) & 0xF; -	this->prize[1] = (this->settings >> 20) & 0xF; -	this->prize[2] = (this->settings >> 24) & 0xF; -	this->prize[3] = (this->settings >> 28) & 0xF; +	this->prize[0] = (this->settings >> 28) & 0xF; +	this->prize[1] = (this->settings >> 24) & 0xF; +	this->prize[2] = (this->settings >> 20) & 0xF; +	this->prize[3] = (this->settings >> 16) & 0xF;  	this->chorus = -1;  	this->currentNote = 0; @@ -588,7 +590,7 @@ void dSingAlong::RegisterNote(int note) {  		OSReport("State was checked");  		if (note == Songs[song][chorus][currentNote][0]) { -			PlaySoundAsync(this, Notes[Songs[song][chorus][currentNote][1]-1]); +			MapSoundPlayer(SoundRelatedClass, Notes[Songs[song][chorus][currentNote][1]-1], 1);  			OSReport("Note was correct");  			currentNote += 1;  		} diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 42bf7c1..6dba268 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -17,6 +17,7 @@ CREATE_STATE_E(dScKoopatlas_c, TitleConfirmHitWait);  CREATE_STATE_E(dScKoopatlas_c, PlayerChangeWait);  CREATE_STATE_E(dScKoopatlas_c, EasyPairingWait);  CREATE_STATE_E(dScKoopatlas_c, PowerupsWait); +CREATE_STATE_E(dScKoopatlas_c, ShopWait);  CREATE_STATE_E(dScKoopatlas_c, SaveOpen);  CREATE_STATE_E(dScKoopatlas_c, SaveSelect);  CREATE_STATE_E(dScKoopatlas_c, SaveWindowClose); @@ -142,6 +143,15 @@ bool WMInit_LoadSIAnims(void *ptr) {  	DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_star", 0);  	DVD_LoadFile(GetDVDClass(), "Object", "I_hammer", 0);  	DVD_LoadFile(GetDVDClass(), "Object", "cobCourse", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "obj_coin", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_kinoko", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_fireflower", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_iceflower", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_penguin", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_propeller", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_star", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "I_kinoko_bundle", 0); +	DVD_LoadFile(GetDVDClass(), "Object", "lakitu", 0);  	return true;  } @@ -246,6 +256,10 @@ bool WMInit_SetupExtra(void *ptr) {  	// because we require it earlier  	// it is created in dScKoopatlas_c::onCreate +	SpammyReport("creating SHOP\n"); +	wm->shop = (dWMShop_c*)CreateParentedObject(WM_SHOP, wm, 0, 0); + +  	SpammyReport("SetupExtra done\n");  	return true; @@ -649,6 +663,17 @@ void dScKoopatlas_c::executeState_PowerupsWait() {  } + +/**********************************************************************/ +// STATE_ShopWait : Wait for the user to exit the Shop screen. +void dScKoopatlas_c::executeState_ShopWait() { + +	if (shop->isHidden) { +		state.setState(&StateID_Normal); +	} + +} +  /**********************************************************************/  // STATE_SaveOpen : Waiting for the "Save?" YesNoWindow to open  void dScKoopatlas_c::executeState_SaveOpen() { diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h index 55baf95..760de19 100644 --- a/src/koopatlas/core.h +++ b/src/koopatlas/core.h @@ -12,6 +12,7 @@  #include "levelinfo.h"  #include "koopatlas/mapdata.h" +#include "koopatlas/shop.h"  #include "koopatlas/pathmanager.h"  #define WM_DEBUGGING @@ -32,10 +33,13 @@  void NewerMapDrawFunc();  #define WM_HUD WM_DANCE_PAKKUN +#define WM_SHOP WM_TOGEZO +#define WM_SHOPITEM WM_PUKU  class daWMPlayer_c;  class dWMHud_c;  class dWMMap_c; +class dWMShop_c;  class dWorldCamera_c;  class dScKoopatlas_c : public dScene_c { @@ -57,6 +61,7 @@ class dScKoopatlas_c : public dScene_c {  		DECLARE_STATE(PlayerChangeWait);  		DECLARE_STATE(EasyPairingWait);  		DECLARE_STATE(PowerupsWait); +		DECLARE_STATE(ShopWait);  		DECLARE_STATE(SaveOpen);  		DECLARE_STATE(SaveSelect);  		DECLARE_STATE(SaveWindowClose); @@ -92,6 +97,7 @@ class dScKoopatlas_c : public dScene_c {  		daWMPlayer_c *player;  		dWMHud_c *hud;  		dWMMap_c *map; +		dWMShop_c *shop;  		int currentMapID;  		const char *mapPath; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 41515a6..b2d649d 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -340,7 +340,13 @@ void dWMPathManager_c::activatePoint() {  		int w = currentNode->levelNumber[0] - 1;  		int l = currentNode->levelNumber[1] - 1; -		if ((l > 29) && (l < 38)) { +		if (l == 0) { +			dWMShop_c::instance->LoadShopForWorld(w); +			dScKoopatlas_c::instance->state.setState(&dScKoopatlas_c::instance->StateID_ShopWait); +			return; +		} + +		if ((l >= 29) && (l <= 36)) {  			SaveBlock *save = GetSaveFile()->GetBlock(-1);  			u32 conds = save->GetLevelCondition(w, l); diff --git a/src/koopatlas/shop.cpp b/src/koopatlas/shop.cpp new file mode 100644 index 0000000..04d7e54 --- /dev/null +++ b/src/koopatlas/shop.cpp @@ -0,0 +1,463 @@ +#include "koopatlas/shop.h" + + +int getStarCoinCountShop() { +	SaveBlock *save = GetSaveFile()->GetBlock(-1); +	int coinsSpent = save->credits_hiscore; +	int coinsEarned = 0; + +	for (int w = 0; w < 10; w++) { +		for (int l = 0; l < 10; l++) { +			u32 conds = save->GetLevelCondition(w, l); + +			if (conds & COND_COIN1) { coinsEarned++; } +			if (conds & COND_COIN2) { coinsEarned++; } +			if (conds & COND_COIN3) { coinsEarned++; } +		} +	} + +	int coinsLeft = coinsEarned - coinsSpent; +	return coinsLeft; +} + + +const char* Produce[10][4] = {  +	{ "I_kinoko", 		"g3d/I_kinoko.brres", 			"I_kinoko", 			"wait2" }, +	{ "I_fireflower", 	"g3d/I_fireflower.brres", 		"I_fireflower", 		"wait2" }, +	{ "I_iceflower", 	"g3d/I_iceflower.brres", 		"I_iceflower", 			"wait2" }, +	{ "I_penguin", 		"g3d/I_penguin.brres", 			"I_penguin", 			"wait2" }, +	{ "I_propeller", 	"g3d/I_propeller_model.brres", 	"I_propeller_model", 	"wait2" }, +	{ "I_kinoko_bundle","g3d/I_mini_kinoko.brres", 		"I_mini_kinoko", 		"wait2" }, +	{ "I_star", 		"g3d/I_star.brres", 			"I_star", 				"wait2" }, +	{ "I_hammer", 		"g3d/I_hammer.brres", 			"I_hammer", 			"wait2" }, +	{ "I_kinoko_bundle","g3d/I_life_kinoko.brres", 		"I_life_kinoko", 		"wait2" }, +	{ "obj_coin", 		"g3d/obj_coin.brres", 			"obj_coin", 			"wait2" } +}; + +/*****************************************************************************/ +// Shop Model + +class dShopItem: public dActor_c { +public: +	int onCreate(); +	int onDelete(); +	int onExecute(); +	int onDraw(); + +	int p; + +	mHeapAllocator_c allocator; +	nw4r::g3d::ResFile resFile; +	m3d::mdl_c bodyModel; +	m3d::anmChr_c aw; + +	static dShopItem *build(); +}; + +dShopItem *dShopItem::build() { +	void *buffer = AllocFromGameHeap1(sizeof(dShopItem)); +	return new(buffer) dShopItem; +} + +int dShopItem::onCreate() { + +	// Settings +	p = settings & 0xF; + +	// Model creation	 +	allocator.link(-1, GameHeaps[0], 0, 0x20); + +	resFile.data = getResource(Produce[p][0], Produce[p][1]); +	nw4r::g3d::ResMdl mdl = resFile.GetResMdl(Produce[p][2]); +	bodyModel.setup(mdl, &allocator, 0x224, 1, 0); +	SetupTextures_Item(&bodyModel, 0); // 800B42B0 + +	// Animation Assignment +	nw4r::g3d::ResAnmChr anmChr = resFile.GetResAnmChr("wait2"); +	aw.setup(mdl, anmChr, &allocator, 0); +	aw.bind(&bodyModel, anmChr, 1); +	bodyModel.bindAnim(&aw, 0.0); +	aw.setUpdateRate(1.0); +	allocator.unlink(); + +	return true; +} + +int dShopItem::onDelete() { return true; } +int dShopItem::onExecute() { return true; } +int dShopItem::onDraw() { +	if (p == 9) { matrix.translation(pos.x, pos.y + (8.0 * scale.y), pos.z); } +	else { matrix.translation(pos.x, pos.y, pos.z); } + +	matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); + +	bodyModel.setDrawMatrix(matrix); +	bodyModel.setScale(&scale); +	bodyModel.calcWorld(false); +	bodyModel.scheduleForDrawing(); +	bodyModel._vf1C(); + +	if(this->aw.isAnimationDone()) +		this->aw.setCurrentFrame(0.0); + +	return true; +} + + +/*****************************************************************************/ +// Shop Layout +// + + +const char* Lakitu[10] = {  +	"g3d/yoshi.brres", "g3d/desert.brres", "g3d/mountain.brres", "g3d/sakura.brres", "g3d/santa.brres",  +	"g3d/ghost.brres", "g3d/space.brres", "g3d/koopa.brres", "g3d/sewer.brres", "g3d/goldwood.brres"  +}; + + +dWMShop_c *dWMShop_c::instance = 0; + +dWMShop_c *dWMShop_c::build() { +	void *buffer = AllocFromGameHeap1(sizeof(dWMShop_c)); +	dWMShop_c *c = new(buffer) dWMShop_c; + +	instance = c; +	return c; +} + +dWMShop_c::dWMShop_c() { +	layoutLoaded = false; +} + +int dWMShop_c::onCreate() { + +	if (!layoutLoaded) { +		bool gotFile = layout.loadArc("shop.arc", false); +		if (!gotFile) +			return false; + +		currentItem = 0; +		isHidden = true; + +		static const char *brlanNames[5] = {"shop_hitButton.brlan", "shop_offButton.brlan", "shop_onButton.brlan", "shop_inWindow.brlan", "shop_outWindow.brlan"}; +		static const char *groupNames[20] = {"B00_Button", "B01_Button", "B02_Button", "B03_Button", "B05_Button", "B08_Button",  +											"B00_Button", "B01_Button", "B02_Button", "B03_Button", "B05_Button", "B08_Button",  +											"B00_Button", "B01_Button", "B02_Button", "B03_Button", "B05_Button", "B08_Button",  +											"A00_Window", "A00_Window"}; + +		bool output = layout.build("shop.brlyt"); + +		if (!IsWideScreen()) { +			layout.clippingEnabled = true; +			layout.clipX = 0; +			layout.clipY = 52; +			layout.clipWidth = 640; +			layout.clipHeight = 352; +			layout.layout.rootPane->scale.x = 0.7711f; +			layout.layout.rootPane->scale.y = 0.7711f; +		} + +		layout.loadAnimations(brlanNames, 5); +		layout.loadGroups(groupNames, (int[20]){0, 0, 0, 0, 0, 0,  1, 1, 1, 1, 1, 1,  2, 2, 2, 2, 2, 2,  3, 4}, 20); +		layout.disableAllAnimations(); + +		for (int i = 6; i < 12; i++) { +			layout.enableNonLoopAnim(i); +		} + +		layoutLoaded = true; +	} + +	return true; +} + + +int dWMShop_c::onDelete() { +	return layout.free(); +} + + +int dWMShop_c::onExecute() { +	layout.execAnimations(); +	layout.update(); + +	if (!isHidden) { +		int nowPressed = Remocon_GetPressed(GetActiveRemocon()); + +		if (!layout.isAnyAnimOn()) { +			if (nowPressed & WPAD_B) { +				MapSoundPlayer(SoundRelatedClass, SE_SYS_WINDOW_CLOSE, 1); +				CloseUpShop(); +			} else if (nowPressed & WPAD_DOWN) { +				if (currentItem == 6) { return true; } +				MapSoundPlayer(SoundRelatedClass, SE_SYS_CURSOR, 1); +				int last = currentItem; +				if (currentItem == 0)	{ currentItem = 1; } +				else if (currentItem < 5)	{ currentItem = 5; } +				else					{ currentItem = 6; } +				changeItem(last, currentItem); +			} else if (nowPressed & WPAD_UP) { +				if (currentItem == 0) { return true; } +				MapSoundPlayer(SoundRelatedClass, SE_SYS_CURSOR, 1); +				int last = currentItem; +				if (currentItem < 5)	{ currentItem = 0; } +				else if (currentItem == 5)	{ currentItem = 1; } +				else					{ currentItem = 5; } +				changeItem(last, currentItem); +			} else if (nowPressed & WPAD_RIGHT) { +				if (currentItem == 6) { currentItem = 6; return true; } +				MapSoundPlayer(SoundRelatedClass, SE_SYS_CURSOR, 1); +				int last = currentItem; +				currentItem += 1; +				changeItem(last, currentItem); +			} else if (nowPressed & WPAD_LEFT) { +				if (currentItem == 0) { return true; } +				MapSoundPlayer(SoundRelatedClass, SE_SYS_CURSOR, 1); +				int last = currentItem; +				currentItem -= 1; +				changeItem(last, currentItem); +			} else if (nowPressed & WPAD_TWO) { +				BuyItem(currentItem); +			} +		} +	} + +	return true; +} + +int dWMShop_c::onDraw() { +	if (isHidden) { +		if (layout.isAnimOn(19)) { layout.scheduleForDrawing(); } +	} + +	if (!isHidden) { +		layout.scheduleForDrawing(); + +		Vec pos = {layout.posX, layout.posY, 40000.0}; +		S16Vec rot = {0,0,0}; +		Vec scale = {1.0, 1.0, 1.0}; +		matrix.translation(pos.x, pos.y, pos.z); +		matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); + +		shopkeep.setDrawMatrix(matrix); +		shopkeep.setScale(&scale); +		shopkeep.calcWorld(false); +		shopkeep.scheduleForDrawing(); +		shopkeep._vf1C(); + +		if(this->ska.isAnimationDone()) +			this->ska.setCurrentFrame(0.0); +	} + +	return true; +} + + +void dWMShop_c::changeItem(int last, int current) { +	 +	if (last) { layout.enableNonLoopAnim(last - 1 + 6); } +	if (current) { layout.enableNonLoopAnim(current - 1 + 12); } +	 +} + +	// Powerup Listing: +	// 0 = Mushroom		- 1 +		// 1 = Fireflower	- 2 +		// 2 = Iceflower	- 2 +			// 3 = Penguin		- 3 +			// 4 = Propeller	- 3 +		// 5 = MiniShroom	- 2 +		// 6 = Starman		- 2 +			// 7 = Hammer		- 3 +		// 8 = 1-ups		- 2 +	// 9 = Coins		- 1 +	// +	// Format: 1coin, 1coin, 2coins, 3coins, 5coins[3] (Value 6-9), 8coins[5] (Value 10-15) +	// +	// Possible 5 coin combos =  2,2,2  /  1,2,3  /  2,3,2  /  3,2,3  /  3,3,3 +	// Possible 8 coin combos =  1,1,2,3,3  /  1,2,2,3,3  /  1,2,3,3,3  /  2,2,2,3,3  /  2,2,3,3,3  /  1,3,3,3,3  /  2,3,3,3,3  /  3,3,3,3,3 + +int Inventory[10][12] = {  +	{ 9, 0, 1, 4,   1, 2, 1,   0, 0, 8, 4, 4 }, // Yoshi Island Shop +	{ 9, 0, 1, 4,   1, 6, 1,   0, 1, 1, 4, 4 }, // Desert Shop +	{ 9, 0, 5, 4,   0, 5, 4,   0, 5, 4, 4, 7 }, // Mountain Shop +	{ 9, 0, 8, 7,   8, 8, 8,   4, 2, 8, 1, 4 }, // Japan Shop +	{ 9, 0, 2, 3,   2, 3, 2,   2, 3, 3, 3, 2 }, // FreezeFlame Shop +	{ 9, 0, 6, 4,   5, 4, 5,   4, 4, 9, 4, 4 }, // Ghost Shop +	{ 9, 0, 6, 7,   6, 6, 6,   7, 7, 8, 7, 7 }, // Space Shop +	{ 0, 8, 4, 7,   7, 4, 7,   4, 7, 4, 7, 4 }, // Koopa Shop +	{ 9, 0, 1, 3,   0, 0, 0,   0, 0, 0, 0, 0 }, // Sewer Shop? +	{ 0, 8, 1, 5,   1, 4, 1,   1, 1, 6, 1, 1 }, // Goldwood Shop +}; + +void dWMShop_c::LoadShopForWorld(int world) { +	if (!isHidden) { +		return; } + +	// Handle showing it +	MapSoundPlayer(SoundRelatedClass, SE_SYS_WINDOW_OPEN, 1); +	isHidden = false; +	layout.enableNonLoopAnim(18); + +	// Model creation	 +	allocator.link(-1, GameHeaps[0], 0, 0x20); + +	res.data = getResource("lakitu", Lakitu[world]); +	nw4r::g3d::ResMdl mdl = res.GetResMdl("lakitu"); +	shopkeep.setup(mdl, &allocator, 0x224, 1, 0); +	SetupTextures_Item(&shopkeep, 0); // 800B42B0 + +	// Animation Assignment (idle, notenough) +	nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr("idle"); +	ska.setup(mdl, anmChr, &allocator, 0); +	ska.bind(&shopkeep, anmChr, 1); +	shopkeep.bindAnim(&ska, 0.0); +	ska.setUpdateRate(1.0); +	allocator.unlink(); + + +	Vec pos = {layout.posX, layout.posY, 40000.0}; + +	// Setup all the item buttons for sale +	// itemA = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][0], 0, 0); +	// itemB = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][1], 0, 0); +	// itemC = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][2], 0, 0); +	// itemD = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][3], 0, 0); +	// itemEA = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][4], 0, 0); +	// itemEB = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][5], 0, 0); +	// itemEC = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][6], 0, 0); +	// itemFA = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][7], 0, 0); +	// itemFB = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][8], 0, 0); +	// itemFC = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][9], 0, 0); +	// itemFD = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][10], 0, 0); +	// itemFE = (dShopItem*)CreateChildObject(WM_SHOPITEM, this, Inventory[world][11], 0, 0); +} + + +void dWMShop_c::CloseUpShop() { +	isHidden = true;  +	layout.enableNonLoopAnim(19);  +	changeItem(currentItem, 0); +	currentItem = 0; + +	// itemA->Delete(); +	// itemB->Delete(); +	// itemC->Delete(); +	// itemD->Delete(); +	// itemEA->Delete(); +	// itemEB->Delete(); +	// itemEC->Delete(); +	// itemFA->Delete(); +	// itemFB->Delete(); +	// itemFC->Delete(); +	// itemFD->Delete(); +	// itemFE->Delete(); +} + + +void dWMShop_c::BuyItem(int item) { +	OSReport("Buy item %d", item); + +	if (item == 0) { +		MapSoundPlayer(SoundRelatedClass, SE_SYS_INVALID, 1); +		return; +	} + +	layout.enableNonLoopAnim(item-1); + +	int cash = getStarCoinCountShop(); +	int cost; + +	int Powerups[10]; + +	Powerups[0] = 0; // Mushroom +	Powerups[1] = 0; // Fireflower +	Powerups[2] = 0; // Iceflower +	Powerups[3] = 0; // Penguin +	Powerups[4] = 0; // Propeller +	Powerups[5] = 0; // MiniShroom +	Powerups[6] = 0; // Starman +	Powerups[7] = 0; // Hammer +	Powerups[8] = 0; // 1-ups +	Powerups[9] = 0; // Coins + +	switch(item) { +		case 1: +			cost = 1; +			Powerups[Inventory[world][item-1]]++; +			break; +		case 2: +			cost = 1; +			Powerups[Inventory[world][item-1]]++; +			break; +		case 3: +			cost = 2; +			Powerups[Inventory[world][item-1]]++; +			break; +		case 4: +			cost = 3; +			Powerups[Inventory[world][item-1]]++; +			break; +		case 5: +			cost = 5; +			Powerups[Inventory[world][item-1]]++; +			Powerups[Inventory[world][item+0]]++; +			Powerups[Inventory[world][item+1]]++; +			break; +		case 6: +			cost = 8; +			Powerups[Inventory[world][item+1]]++; +			Powerups[Inventory[world][item+2]]++; +			Powerups[Inventory[world][item+3]]++; +			Powerups[Inventory[world][item+4]]++; +			Powerups[Inventory[world][item+5]]++; +			break; +	} + +	if (cost > cash) { +		MapSoundPlayer(SoundRelatedClass, SE_SYS_INVALID, 1); +		return; +	} + +	MapSoundPlayer(SoundRelatedClass, SE_SYS_DECIDE, 1); + + +	SaveFile *file = GetSaveFile(); +	SaveBlock *block = file->GetBlock(file->header.current_file); + +	block->credits_hiscore += cost; + + +	for (int i = 0; i < 7; i++) { // Change this to 8 to support hammers +		block->powerups_available[i] = block->powerups_available[i] + Powerups[i]; + +		if (block->powerups_available[i] > 99) { block->powerups_available[i] = 99; } +	} + +	for (int i = 0; i < 4; i++) { // Make sure all players get the reward! +		block->player_coins[i] = (Powerups[9] * 50) + block->player_coins[i]; + +		for (;block->player_coins[i] < 100; block->player_coins[i] - 100) { +			block->player_coins[i] = 1 + block->player_coins[i]; +		} + +		block->player_lives[i] = Powerups[8] + block->player_lives[i]; +		if (block->player_lives[i] > 99) { block->player_lives[i] = 99; } +	} + +	CloseUpShop(); +	return; + +} + + + + + + + + + + + + diff --git a/src/koopatlas/shop.h b/src/koopatlas/shop.h new file mode 100644 index 0000000..64e4453 --- /dev/null +++ b/src/koopatlas/shop.h @@ -0,0 +1,60 @@ +#ifndef __KOOPATLAS_SHOP_H +#define __KOOPATLAS_SHOP_H + +#include "koopatlas/core.h" + +extern "C" void *SoundRelatedClass; +extern "C" void *MapSoundPlayer(void *SoundClass, int soundID, int unk); + +class dShopItem; + +class dWMShop_c : public dBase_c { +	public: +		dWMShop_c(); + +		int onCreate(); +		int onDelete(); +		int onExecute(); +		int onDraw(); + +		bool layoutLoaded; +		m2d::EmbedLayout_c layout; + +		mHeapAllocator_c allocator; +		nw4r::g3d::ResFile res; +		m3d::mdl_c shopkeep; +		m3d::anmChr_c ska; +		mMtx matrix; + +		char currentItem; +		bool isHidden; +		int world; + +		dShopItem *itemA; +		dShopItem *itemB; +		dShopItem *itemC; +		dShopItem *itemD; + +		dShopItem *itemEA; +		dShopItem *itemEB; +		dShopItem *itemEC; + +		dShopItem *itemFA; +		dShopItem *itemFB; +		dShopItem *itemFC; +		dShopItem *itemFD; +		dShopItem *itemFE; + + +		void LoadShopForWorld(int world); +		void CloseUpShop(); +		void BuyItem(int item); + +		void changeItem(int last, int current); + +		static dWMShop_c *build(); +		static dWMShop_c *instance; +}; + +#endif + | 
