summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xinclude/game.h2
-rw-r--r--kamek_pal.x2
-rw-r--r--koopatlas.yaml5
-rw-r--r--src/corseClear.S4
-rw-r--r--src/koopatlas/core.cpp2
-rw-r--r--src/koopatlas/core.h1
-rw-r--r--src/koopatlas/pathmanager.cpp2
-rw-r--r--src/koopatlas/shop.cpp659
-rw-r--r--src/koopatlas/shop.h119
-rw-r--r--src/newer.cpp2
-rw-r--r--tools/UsedProfileAndSpriteList.txt3
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<dWMShop_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