diff options
Diffstat (limited to '')
-rw-r--r-- | src/koopatlas/shop.cpp | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/src/koopatlas/shop.cpp b/src/koopatlas/shop.cpp new file mode 100644 index 0000000..ed64c8e --- /dev/null +++ b/src/koopatlas/shop.cpp @@ -0,0 +1,507 @@ +#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); + } + + layout.drawOrder = 0x01; + + 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_DIALOGUE_OUT_AUTO, 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::specialDraw1() { + OSReport("Lakionnnne...."); + if (!isHidden) { + 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; +} + +void dWMShop_c::specialDraw2() { + OSReport("Lakituuu...."); + if (!isHidden) { + 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; +} + + +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_DIALOGUE_IN, 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; + +} + + + + + + + + + + + + |