From 63bde25084daafeb0aeaa584d3624f0c77ec043d Mon Sep 17 00:00:00 2001 From: Treeki Date: Thu, 25 Oct 2012 00:05:35 +0200 Subject: committing my untested and slightly unfinished shop --- include/game.h | 2 +- kamek_pal.x | 2 +- koopatlas.yaml | 5 - src/corseClear.S | 4 +- src/koopatlas/core.cpp | 2 +- src/koopatlas/core.h | 1 - src/koopatlas/pathmanager.cpp | 2 +- src/koopatlas/shop.cpp | 659 +++++++++++++++++++------------------ src/koopatlas/shop.h | 119 ++++--- src/newer.cpp | 2 +- tools/UsedProfileAndSpriteList.txt | 3 +- 11 files changed, 416 insertions(+), 385 deletions(-) diff --git a/include/game.h b/include/game.h index 15178f7..48c7f65 100755 --- a/include/game.h +++ b/include/game.h @@ -2916,7 +2916,7 @@ namespace m2d { void setLangStrings(const char **names, const int *msgIDs, int category, int count); void loadAnimations(const char **names, int count); - void loadGroups(const char **names, int *animLinkIDs, int count); + void loadGroups(const char **names, const int *animLinkIDs, int count); void enableNonLoopAnim(int num, bool goToLastFrame = false); void enableLoopAnim(int num); diff --git a/kamek_pal.x b/kamek_pal.x index 6dd0473..7cfd502 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -782,7 +782,7 @@ SECTIONS { getTextBoxes__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt7TextBoxi = 0x800C8FA0; setLangStrings__Q23m2d13EmbedLayout_cFPPCcPCiii = 0x800C9010; loadAnimations__Q23m2d13EmbedLayout_cFPPCci = 0x800C90A0; - loadGroups__Q23m2d13EmbedLayout_cFPPCcPii = 0x800C91E0; + loadGroups__Q23m2d13EmbedLayout_cFPPCcPCii = 0x800C91E0; enableNonLoopAnim__Q23m2d13EmbedLayout_cFib = 0x800C93E0; enableLoopAnim__Q23m2d13EmbedLayout_cFi = 0x800C9470; resetAnim__Q23m2d13EmbedLayout_cFib = 0x800C94C0; diff --git a/koopatlas.yaml b/koopatlas.yaml index 22ac054..eea87e6 100644 --- a/koopatlas.yaml +++ b/koopatlas.yaml @@ -45,11 +45,6 @@ hooks: src_addr_pal: 0x80986074 target_func: 'dWMShop_c::build(void)' - - name: BuildWMdShopItem # WM_BOARD - type: add_func_pointer - src_addr_pal: 0x80981CA0 - target_func: 'dShopItem::build(void)' - - name: BuildWMdStarCoin # WM_GHOST type: add_func_pointer src_addr_pal: 0x80982D1C diff --git a/src/corseClear.S b/src/corseClear.S index 5ea8336..95bd92e 100644 --- a/src/corseClear.S +++ b/src/corseClear.S @@ -1,7 +1,7 @@ .text .extern loadArc__Q23m2d13EmbedLayout_cFPCcb .extern loadAnimations__Q23m2d13EmbedLayout_cFPPCci -.extern loadGroups__Q23m2d13EmbedLayout_cFPPCcPii +.extern loadGroups__Q23m2d13EmbedLayout_cFPPCcPCii .extern getPanes__Q23m2d13EmbedLayout_cCFPPCcPPQ34nw4r3lyt4Panei .global GenericCorseClear @@ -44,7 +44,7 @@ didLoad: lis r5, CorseClearGroupAnimIDs@h ori r5, r5, CorseClearGroupAnimIDs@l li r6, 3 - bl loadGroups__Q23m2d13EmbedLayout_cFPPCcPii + bl loadGroups__Q23m2d13EmbedLayout_cFPPCcPCii lwz r3, 0x90(r31) stw r3, 0x36C(r31) diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index f7622f6..6fb030a 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -797,7 +797,7 @@ void dScKoopatlas_c::executeState_PowerupsWait() { // STATE_ShopWait : Wait for the user to exit the Shop screen. void dScKoopatlas_c::executeState_ShopWait() { - if (shop->isHidden) { + if (!shop->visible) { state.setState(&StateID_Normal); } diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h index eddb870..e4e0254 100644 --- a/src/koopatlas/core.h +++ b/src/koopatlas/core.h @@ -36,7 +36,6 @@ void NewerMapDrawFunc(); #define WM_HUD WM_DANCE_PAKKUN #define WM_SHOP WM_TOGEZO -#define WM_SHOPITEM WM_BOARD #define WM_STARCOIN WM_GHOST class daWMPlayer_c; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 87725bd..fa2a862 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -748,7 +748,7 @@ void dWMPathManager_c::activatePoint() { int l = currentNode->levelNumber[1] - 1; if (l == 98) { - dWMShop_c::instance->LoadShopForWorld(w); + dWMShop_c::instance->show(w); dScKoopatlas_c::instance->state.setState(&dScKoopatlas_c::instance->StateID_ShopWait); return; } diff --git a/src/koopatlas/shop.cpp b/src/koopatlas/shop.cpp index cd20ddb..a5300f6 100644 --- a/src/koopatlas/shop.cpp +++ b/src/koopatlas/shop.cpp @@ -1,98 +1,88 @@ #include "koopatlas/shop.h" +CREATE_STATE(dWMShop_c, Hidden); +CREATE_STATE(dWMShop_c, ShowWait); +CREATE_STATE(dWMShop_c, ButtonActivateWait); +CREATE_STATE(dWMShop_c, Wait); +CREATE_STATE(dWMShop_c, HideWait); + +void dWMShop_c::ShopModel_c::setupItem(float x, float y, ItemTypes type) { + static const char* Produce[ITEM_TYPE_COUNT][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.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" } + }; + + this->x = x; + this->y = y; + + int id = (int)type; -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; + allocator.link(-1, GameHeaps[0], 0, 0x20); - mHeapAllocator_c allocator; - nw4r::g3d::ResFile resFile; - m3d::mdl_c bodyModel; - m3d::anmChr_c aw; + res.data = getResource(Produce[id][0], Produce[id][1]); + nw4r::g3d::ResMdl mdlRes = res.GetResMdl(Produce[id][2]); + model.setup(mdlRes, &allocator, ANM_VTX, 1, 0); + SetupTextures_Item(&model, 1); - static dShopItem *build(); -}; + nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr(Produce[id][3]); + animation.setup(mdlRes, anmChr, &allocator, 0); + playAnim(Produce[id][3], 1.0f); -dShopItem *dShopItem::build() { - void *buffer = AllocFromGameHeap1(sizeof(dShopItem)); - return new(buffer) dShopItem; + allocator.unlink(); } -int dShopItem::onCreate() { - - // Settings - p = settings & 0xF; +void dWMShop_c::ShopModel_c::setupLakitu(int id) { + static const char* models[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" + }; - // 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); } + res.data = getResource("lakitu", models[id]); + nw4r::g3d::ResMdl mdlRes = res.GetResMdl("lakitu"); + model.setup(mdlRes, &allocator, ANM_VTX, 1, 0); + SetupTextures_Item(&model, 1); - matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); + nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr("idle"); + animation.setup(mdlRes, anmChr, &allocator, 0); - bodyModel.setDrawMatrix(matrix); - bodyModel.setScale(&scale); - bodyModel.calcWorld(false); - bodyModel.scheduleForDrawing(); - bodyModel._vf1C(); + playAnim("idle", 1.0f); - if(this->aw.isAnimationDone()) - this->aw.setCurrentFrame(0.0); + allocator.unlink(); +} - return true; +void dWMShop_c::ShopModel_c::playAnim(const char *name, float rate) { + nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr(name); + animation.bind(&model, anmChr, 1); + model.bindAnim(&animation, 0.0f); + animation.setUpdateRate(rate); } +void dWMShop_c::ShopModel_c::execute() { + model._vf1C(); +} -/*****************************************************************************/ -// Shop Layout -// +void dWMShop_c::ShopModel_c::draw() { + mMtx mtx; + Vec pos = {250.0f, 170.0f, 3000.0f}; + Vec scale = {1.0f, 1.0f, 1.0f}; + mtx.translation(pos.x, pos.y, pos.z); + model.setDrawMatrix(mtx); + model.setScale(&scale); + model.calcWorld(false); + model.scheduleForDrawing(); +} -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; @@ -105,30 +95,26 @@ dWMShop_c *dWMShop_c::build() { return c; } -dWMShop_c::dWMShop_c() { +dWMShop_c::dWMShop_c() : state(this, &StateID_Hidden) { layoutLoaded = false; - isHidden = true; + visible = false; } int dWMShop_c::onCreate() { - if (!layoutLoaded) { bool gotFile = layout.loadArc("shop.arc", false); if (!gotFile) return false; - currentItem = 0; - wasOff = false; + selected = 0; + lastTopRowChoice = 0; - 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"}; + layout.build("shop.brlyt"); - bool output = layout.build("shop.brlyt"); - - if (!IsWideScreen()) { + layout.layout.rootPane->trans.x = -112.0f; + if (IsWideScreen()) { + layout.layout.rootPane->scale.x = 0.735f; + } else { layout.clippingEnabled = true; layout.clipX = 0; layout.clipY = 52; @@ -138,15 +124,35 @@ int dWMShop_c::onCreate() { 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); + static const char *brlanNames[] = { + "shop_Show.brlan", + "shop_Hide.brlan", + "shop_ActivateButton.brlan", + "shop_DeactivateButton.brlan" + }; + static const char *groupNames[] = { + "BaseGroup", "BaseGroup", + "GBtn00", "GBtn01", "GBtn02", "GBtn03", "GBtn1", "GBtn2", + "GBtn00", "GBtn01", "GBtn02", "GBtn03", "GBtn1", "GBtn2", + }; + static const int brlanIDs[] = { + 0, 1, + 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, + }; + + layout.loadAnimations(brlanNames, 4); + layout.loadGroups(groupNames, brlanIDs, 14); layout.disableAllAnimations(); - for (int i = 6; i < 12; i++) { - layout.enableNonLoopAnim(i); - } + layout.drawOrder = 1; - layout.drawOrder = 0x01; + static const char *tbNames[] = { + "Title", "TitleShadow", + "CoinCount", "CoinCountShadow", + "BackText", "BuyText", + }; + layout.getTextBoxes(tbNames, &Title, 6); layoutLoaded = true; } @@ -156,261 +162,262 @@ int dWMShop_c::onCreate() { int dWMShop_c::onDelete() { + deleteModels(); return layout.free(); } int dWMShop_c::onExecute() { - layout.execAnimations(); - layout.update(); + state.execute(); - 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); - } - } + if (visible) { + layout.execAnimations(); + layout.update(); + + lakituModel->execute(); - shopkeep._vf1C(); + for (int i = 0; i < 12; i++) + itemModels[i].execute(); } + layout.execAnimations(); + layout.update(); + return true; } int dWMShop_c::onDraw() { - if (isHidden) { - if (layout.isAnimOn(19)) { layout.scheduleForDrawing(); } - } - - if (!isHidden) { + if (visible) layout.scheduleForDrawing(); - } return true; } void dWMShop_c::specialDraw1() { - if (!isHidden && !layout.isAnimOn(18) && !layout.isAnimOn(19)) { - - Vec pos = {250.0f, 170.0f, 1000.0f}; - S16Vec rot = {0,0,0}; - Vec scale = {1.0f, 1.0f, 1.0f}; - 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(); + if (visible) { + lakituModel->draw(); + for (int i = 0; i < 12; i++) + itemModels[i].draw(); - if (wasOff) { effect.spawn("Wm_ob_greencoinkira", 0, &pos, &rot, &scale); wasOff = false; } +// if (wasOff) { effect.spawn("Wm_ob_greencoinkira", 0, &pos, &rot, &scale); wasOff = false; } - if(this->ska.isAnimationDone()) - this->ska.setCurrentFrame(0.0); +// 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); } - +void dWMShop_c::show(int shopNumber) { + shopKind = shopNumber; + state.setState(&StateID_ShowWait); } - // 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; } +// Hidden +void dWMShop_c::beginState_Hidden() { } +void dWMShop_c::executeState_Hidden() { } +void dWMShop_c::endState_Hidden() { } - wasOff = true; - - // Handle showing it +// ShowWait +void dWMShop_c::beginState_ShowWait() { 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, 1); - - // 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(); + layout.disableAllAnimations(); + layout.enableNonLoopAnim(SHOW_ALL); + visible = true; + loadModels(); +} +void dWMShop_c::executeState_ShowWait() { + if (!layout.isAnimOn(SHOW_ALL)) { + selected = 0; + layout.enableNonLoopAnim(ACTIVATE_BUTTON); + state.setState(&StateID_ButtonActivateWait); + } +} +void dWMShop_c::endState_ShowWait() { } - 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); +// ButtonActivateWait +void dWMShop_c::beginState_ButtonActivateWait() { } +void dWMShop_c::executeState_ButtonActivateWait() { + if (!layout.isAnyAnimOn()) + state.setState(&StateID_Wait); } +void dWMShop_c::endState_ButtonActivateWait() { } + +// Wait +void dWMShop_c::beginState_Wait() { } +void dWMShop_c::executeState_Wait() { + int nowPressed = Remocon_GetPressed(GetActiveRemocon()); + + int newSelection = -1; + + if (nowPressed & WPAD_ONE) { + // Hide the thing + state.setState(&StateID_HideWait); + + } else if (nowPressed & WPAD_UP) { + // Move up + if (selected == 4) + newSelection = lastTopRowChoice; + else if (selected == 5) + newSelection = 4; + + } else if (nowPressed & WPAD_DOWN) { + // Move down + if (selected <= 3) + newSelection = 4; + else if (selected == 4) + newSelection = 5; + + } else if (nowPressed & WPAD_LEFT) { + // Just use the previous choice + if (selected > 0) + newSelection = selected - 1; + + } else if (nowPressed & WPAD_RIGHT) { + // Just use the next choice + if (selected < 5) + newSelection = selected + 1; + + } else if (nowPressed & WPAD_TWO) { + buyItem(selected); + } + + if (newSelection > -1) { + MapSoundPlayer(SoundRelatedClass, SE_SYS_CURSOR, 1); + layout.enableNonLoopAnim(DEACTIVATE_BUTTON+selected); + layout.enableNonLoopAnim(ACTIVATE_BUTTON+newSelection); -void dWMShop_c::CloseUpShop() { - isHidden = true; - layout.enableNonLoopAnim(19); - changeItem(currentItem, 0); - currentItem = 0; - - effect.spawn("Wm_ob_greencoinkira", 0, &pos, &rot, &scale); - - // itemA->Delete(); - // itemB->Delete(); - // itemC->Delete(); - // itemD->Delete(); - // itemEA->Delete(); - // itemEB->Delete(); - // itemEC->Delete(); - // itemFA->Delete(); - // itemFB->Delete(); - // itemFC->Delete(); - // itemFD->Delete(); - // itemFE->Delete(); + selected = newSelection; + if (newSelection <= 3) + lastTopRowChoice = newSelection; + } } +void dWMShop_c::endState_Wait() { } +// HideWait +void dWMShop_c::beginState_HideWait() { + MapSoundPlayer(SoundRelatedClass, SE_SYS_DIALOGUE_OUT_AUTO, 1); + layout.enableNonLoopAnim(HIDE_ALL); +} +void dWMShop_c::executeState_HideWait() { + if (!layout.isAnimOn(HIDE_ALL)) + state.setState(&StateID_Hidden); +} +void dWMShop_c::endState_HideWait() { + visible = false; +} -void dWMShop_c::BuyItem(int item) { - OSReport("Buy item %d", item); - if (item == 0) { - MapSoundPlayer(SoundRelatedClass, SE_SYS_INVALID, 1); - 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 + +const dWMShop_c::ItemTypes dWMShop_c::Inventory[10][12] = { + { // Yoshi's Island + COINS, MUSHROOM, FIRE_FLOWER, PROPELLER, + FIRE_FLOWER, ICE_FLOWER, FIRE_FLOWER, + MUSHROOM, MUSHROOM, ONE_UP, PROPELLER, PROPELLER + }, + { // Desert + COINS, MUSHROOM, FIRE_FLOWER, PROPELLER, + FIRE_FLOWER, STARMAN, FIRE_FLOWER, + MUSHROOM, FIRE_FLOWER, FIRE_FLOWER, PROPELLER, PROPELLER + }, + { // Mountain + COINS, MUSHROOM, MINI_SHROOM, PROPELLER, + MUSHROOM, MINI_SHROOM, PROPELLER, + MUSHROOM, MINI_SHROOM, PROPELLER, PROPELLER, HAMMER + }, + { // Japan + COINS, MUSHROOM, ONE_UP, HAMMER, + ONE_UP, ONE_UP, ONE_UP, + PROPELLER, ICE_FLOWER, ONE_UP, FIRE_FLOWER, PROPELLER + }, + { // FreezeFlame + COINS, MUSHROOM, ICE_FLOWER, PENGUIN, + ICE_FLOWER, PENGUIN, ICE_FLOWER, + ICE_FLOWER, PENGUIN, PENGUIN, PENGUIN, ICE_FLOWER + }, + { // Ghost + COINS, MUSHROOM, STARMAN, PROPELLER, + MINI_SHROOM, PROPELLER, MINI_SHROOM, + PROPELLER, PROPELLER, COINS, PROPELLER, PROPELLER + }, + { // Space + COINS, MUSHROOM, STARMAN, HAMMER, + STARMAN, STARMAN, STARMAN, + HAMMER, HAMMER, ONE_UP, HAMMER, HAMMER + }, + { // Koopa + MUSHROOM, ONE_UP, PROPELLER, HAMMER, + HAMMER, PROPELLER, HAMMER, + PROPELLER, HAMMER, PROPELLER, HAMMER, PROPELLER + }, + { // Unknown + COINS, MUSHROOM, FIRE_FLOWER, PENGUIN, + MUSHROOM, MUSHROOM, MUSHROOM, + MUSHROOM, MUSHROOM, MUSHROOM, MUSHROOM, MUSHROOM + }, + { // Goldwood + MUSHROOM, ONE_UP, FIRE_FLOWER, MINI_SHROOM, + FIRE_FLOWER, PROPELLER, FIRE_FLOWER, + FIRE_FLOWER, FIRE_FLOWER, STARMAN, FIRE_FLOWER, FIRE_FLOWER } +}; + +void dWMShop_c::loadModels() { + lakituModel = new ShopModel_c; + lakituModel->setupLakitu(shopKind); + + itemModels = new ShopModel_c[ITEM_COUNT]; + for (int i = 0; i < ITEM_COUNT; i++) + itemModels[i].setupItem(0.0f, 0.0f, Inventory[shopKind][i]); +} +void dWMShop_c::deleteModels() { + if (lakituModel) + delete lakituModel; + lakituModel = 0; + + if (itemModels) + delete[] itemModels; + itemModels = 0; +} - layout.enableNonLoopAnim(item-1); - - int cash = getStarCoinCount(); - 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; - } + +void dWMShop_c::buyItem(int item) { + static int itemDefs[6][3] = { + // Cost, Start Index, Count + {1, 0, 1}, {1, 1, 1}, {2, 2, 1}, {3, 3, 1}, + {5, 4, 3}, {8, 7, 5} + }; + + int cost = itemDefs[item][0], cash = getStarCoinCount(); if (cost > cash) { + lakituModel->playAnim("notenough", 1.0f); MapSoundPlayer(SoundRelatedClass, SE_SYS_INVALID, 1); return; } @@ -421,39 +428,37 @@ void dWMShop_c::BuyItem(int item) { SaveFile *file = GetSaveFile(); SaveBlock *block = file->GetBlock(file->header.current_file); - block->credits_hiscore += cost; + block->spentStarCoins += cost; + + // Work out what we need to apply + int appliedItems[ITEM_TYPE_COUNT]; + for (int i = 0; i < ITEM_TYPE_COUNT; i++) + appliedItems[i] = 0; + int invStartIndex = itemDefs[item][1], invCount = itemDefs[item][2]; + for (int i = 0; i < invCount; i++) + appliedItems[(int)Inventory[shopKind][invStartIndex]]++; - for (int i = 0; i < 7; i++) { // Change this to 8 to support hammers - block->powerups_available[i] = block->powerups_available[i] + Powerups[i]; + // TODO: Make this work with hammers + for (int i = 0; i < 7; i++) { + block->powerups_available[i] += appliedItems[i]; - if (block->powerups_available[i] > 99) { block->powerups_available[i] = 99; } + 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]; + // Apply coins and lives to everyone + for (int i = 0; i < 4; i++) { + block->player_coins[i] += (appliedItems[(int)COINS] * 50); - for (;block->player_coins[i] < 100; block->player_coins[i] - 100) { + /*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; } + if (block->player_lives[i] > 99) { block->player_lives[i] = 99; }*/ } - CloseUpShop(); - return; - + state.setState(&StateID_HideWait); } - - - - - - - - - - - diff --git a/src/koopatlas/shop.h b/src/koopatlas/shop.h index cf78b36..719a087 100644 --- a/src/koopatlas/shop.h +++ b/src/koopatlas/shop.h @@ -3,13 +3,11 @@ #include "koopatlas/core.h" -extern "C" void *SoundRelatedClass; -extern "C" void *MapSoundPlayer(void *SoundClass, int soundID, int unk); - -class dShopItem; - -class dWMShop_c : public dActor_c { +class dWMShop_c : public dBase_c { public: + static dWMShop_c *build(); + static dWMShop_c *instance; + dWMShop_c(); int onCreate(); @@ -21,43 +19,78 @@ class dWMShop_c : public dActor_c { bool layoutLoaded; m2d::EmbedLayout_c layout; - mHeapAllocator_c allocator; - nw4r::g3d::ResFile res; - m3d::mdl_c shopkeep; - m3d::anmChr_c ska; - mMtx matrix; - - mEf::es2 effect; - - char currentItem; - bool isHidden; - bool wasOff; - 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; + bool visible; + + int selected, lastTopRowChoice; + int shopKind; + + enum Animation { + SHOW_ALL = 0, + HIDE_ALL = 1, + ACTIVATE_BUTTON = 2, // 3, 4, 5, 6, 7 + DEACTIVATE_BUTTON = 8, // 9, 10, 11, 12, 13 + }; + + enum ItemTypes { + MUSHROOM = 0, + FIRE_FLOWER, + ICE_FLOWER, + PENGUIN, + PROPELLER, + MINI_SHROOM, + STARMAN, + HAMMER, + ONE_UP, + COINS, + ITEM_TYPE_COUNT + }; + + enum _Constants { + ITEM_COUNT = 12, + }; + + static const ItemTypes Inventory[10][12]; + + nw4r::lyt::TextBox + *Title, *TitleShadow, + *CoinCount, *CoinCountShadow, + *BackText, *BuyText; + + class ShopModel_c { + public: + mHeapAllocator_c allocator; + + nw4r::g3d::ResFile res; + m3d::mdl_c model; + m3d::anmChr_c animation; + + float x, y; + + void setupItem(float x, float y, ItemTypes type); + void setupLakitu(int id); + void execute(); + void draw(); + void playAnim(const char *name, float rate); + }; + + ShopModel_c *itemModels; + ShopModel_c *lakituModel; + + void show(int shopNumber); + + void loadModels(); + void deleteModels(); + + void buyItem(int item); + + dStateWrapper_c state; + + USING_STATES(dWMShop_c); + DECLARE_STATE(Hidden); + DECLARE_STATE(ShowWait); + DECLARE_STATE(ButtonActivateWait); + DECLARE_STATE(Wait); + DECLARE_STATE(HideWait); }; #endif diff --git a/src/newer.cpp b/src/newer.cpp index 7c4ce11..0830988 100644 --- a/src/newer.cpp +++ b/src/newer.cpp @@ -61,7 +61,7 @@ void getNewerLevelNumberString(int world, int level, wchar_t *dest) { int getUnspentStarCoinCount() { SaveBlock *save = GetSaveFile()->GetBlock(-1); - int coinsSpent = save->credits_hiscore; + int coinsSpent = save->spentStarCoins; return getStarCoinCount() - coinsSpent; } diff --git a/tools/UsedProfileAndSpriteList.txt b/tools/UsedProfileAndSpriteList.txt index 4f606ed..1b4ba12 100644 --- a/tools/UsedProfileAndSpriteList.txt +++ b/tools/UsedProfileAndSpriteList.txt @@ -1,6 +1,5 @@ [Commented] 210 : TARZAN_ROPE : Pengi --- : MOVIE : Cut Scene ---- : WM_BOARD : Shop Item --- : WM_DANCE_PAKKUN : HUD --- : WM_GHOST : Star Coin Screen --- : WM_MAP : Map @@ -84,7 +83,6 @@ TARZAN_ROPE WALLINSECT_MGR WM_ANCHOR WM_ANTLION -WM_BOARD WM_BOSS_IGGY WM_CLOUD WM_DANCE_PAKKUN @@ -111,6 +109,7 @@ WORLD_MAP -- World Map Processes Free for Use: -- WM_ANTLION_MNG +WM_BOARD WM_BOSS_BASE WM_BOSS_KAMECK WM_BOSS_LARRY -- cgit v1.2.3