summaryrefslogtreecommitdiff
path: root/src/koopatlas/shop.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/koopatlas/shop.cpp463
1 files changed, 463 insertions, 0 deletions
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;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+