diff --git a/.vscode/settings.json b/.vscode/settings.json index 58b93b2..02f58fe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -101,6 +101,7 @@ "mprealsupport": "cpp", "matrixfunctions": "cpp", "vips8": "cpp", - "*.inc": "c" + "*.inc": "c", + "filesystem": "cpp" } } \ No newline at end of file diff --git a/source/game/common_data.h b/source/game/common_data.h index 16ee3fe..7a26cb7 100644 --- a/source/game/common_data.h +++ b/source/game/common_data.h @@ -112,7 +112,8 @@ struct EquipmentData { struct InventoryData { std::array items; std::array masks; - std::array item_counts; + std::array bottles; + std::array item_counts; u8 field_48[24]; u8 field_60[24]; union InventoryCountRegister { @@ -191,7 +192,7 @@ struct SaveData { /// 0x0000 is midnight, 0x4000 is 6am, 0x8000 is noon, 0xc000 is 6pm. u16 time; u16 anonymous_3; - u16 anonymous_4; + u16 rupee_accumulator; act::Player::Form player_form; char anonymous_5; char field_20; @@ -235,7 +236,7 @@ struct SaveData { int anonymous_58; u8 gap11EC[36]; union SkulltulaRegister { - int raw; + u32 raw; BitField<0, 16, int> swamp_count; BitField<16, 16, int> ocean_count; @@ -567,7 +568,7 @@ struct RespawnData { u8 btn_i_can_use_item; //u32 stored_mask_id_maybe; u32 temp_collect_flags_maybe; -}; +}; static_assert(sizeof(RespawnData) == 0x20); enum class UsableButton : u8 { diff --git a/source/game/items.cpp b/source/game/items.cpp index e234746..cb5332c 100644 --- a/source/game/items.cpp +++ b/source/game/items.cpp @@ -51,6 +51,36 @@ bool HasOcarina() { return items[0] == ItemId::Ocarina; } +bool HasBottle(ItemId bottle_contents) { + const auto& bottles = GetCommonData().save.inventory.bottles; + return std::any_of(bottles.begin(), bottles.end(), [&](ItemId id) { return bottle_contents == id && bottle_contents != game::ItemId::None; }); +} + +void RemoveBottle(u32 bottle_index) { + auto& bottles = GetCommonData().save.inventory.bottles; + bottles[bottle_index] = ItemId::None; +} + +void GiveBottle(u32 bottle_index, ItemId item_id) { + auto& bottles = GetCommonData().save.inventory.bottles; + game::EquipmentData& mappedEquips = GetCommonData().save.equipment; + if (mappedEquips.data[0].item_btn_y == bottles[bottle_index]) { + mappedEquips.data[0].item_btn_y = item_id; + } else if (mappedEquips.data[0].item_btn_x == bottles[bottle_index]) { + mappedEquips.data[0].item_btn_x = item_id; + } else if (mappedEquips.data[0].item_btn_i == bottles[bottle_index]) { + mappedEquips.data[0].item_btn_i = item_id; + } else if (mappedEquips.data[0].item_btn_ii == bottles[bottle_index]) { + mappedEquips.data[0].item_btn_ii = item_id; + } + bottles[bottle_index] = item_id; + // This pointer fills the next empty bottle. + // rst::util::GetPointer(0x233BEC)( + // gctx, item_id); + +} + + bool HasItem(ItemId item_id) { const auto& items = GetCommonData().save.inventory.items; return std::any_of(items.begin(), items.end(), [&](ItemId id) { return item_id == id; }); diff --git a/source/game/items.h b/source/game/items.h index dde7b54..3707c80 100644 --- a/source/game/items.h +++ b/source/game/items.h @@ -220,6 +220,9 @@ enum class MaskId : u8 { }; bool HasOcarina(); +bool HasBottle(ItemId bottle_contents); +void RemoveBottle(u32 bottle_index); +void GiveBottle(u32 bottle_index, ItemId item_id); bool HasItem(ItemId item_id); void GiveItem(ItemId item_id); void RemoveItem(ItemId item_id); diff --git a/source/msys/inventory.cpp b/source/msys/inventory.cpp index 9e8e168..2a5615f 100644 --- a/source/msys/inventory.cpp +++ b/source/msys/inventory.cpp @@ -7,7 +7,7 @@ static game::ItemId SelectedBottle; -static u32 SelectedBottleIndex; +static u32 SelectedBottleItemIndex; static u32 BottleNumber; void RemoveItemFromButtons(game::ItemId item_id) { @@ -28,7 +28,7 @@ static void DisableMenuToggles(ToggleMenu* menu) { } static void Inventory_ItemsMenuInit(void) { - //game::InventoryData& inventory = game::GetCommonData().save.inventory; + game::InventoryData& inventory = game::GetCommonData().save.inventory; InventoryItemsMenu.items[(u32)game::ItemId::Ocarina].on = game::HasOcarina(); InventoryItemsMenu.items[(u32)game::ItemId::Arrow].on = game::HasItem(game::ItemId::Arrow); InventoryItemsMenu.items[(u32)game::ItemId::FireArrow].on = @@ -60,11 +60,9 @@ static void Inventory_ItemsMenuInit(void) { InventoryItemsMenu.items[(u32)game::ItemId::GreatFairySword - 2].on = game::HasItem(game::ItemId::GreatFairySword); // Loop through bottles and check which ones we have. - // u32 numBottles = - // std::count_if(inventory.items.begin(), inventory.items.end(), game::ItemIsBottled); - // for (u32 i = 0; i < numBottles; i++) { - // InventoryItemsMenu.items[(u32)game::ItemId::Bottle + i - 3].on = true; - // } + for (u32 i = 15; i < 22; i++) { + InventoryItemsMenu.items[i].on = game::HasBottle(inventory.bottles[i-15]); + } } static void Inventory_SongsMenuInit(void) { @@ -335,55 +333,38 @@ void Inventory_ItemsToggle(s32 selected) { } static void Inventory_BottlesMenuInit(void) { - //game::CommonData& cdata = game::GetCommonData(); - for (u32 i = (u32)game::ItemId::RedPotion; i < (u32)game::ItemId::MoonTear; ++i) { - if (game::HasItem(SelectedBottle)) { - InventoryBottlesMenu.items[i].on = game::HasItem((game::ItemId)i); - // Can only have one thing in a selected bottle, no need to continue. - // break; + u32 curIndex = 0; + for (u32 i = (u32)game::ItemId::Bottle; i < (u32)game::ItemId::MoonTear; ++i) { + if (i == (u32)SelectedBottle) { + InventoryBottlesMenu.items[curIndex].on = 1; + } else { + InventoryBottlesMenu.items[curIndex].on = 0; } + ++curIndex; } - InventoryBottlesMenu.items[BottleContents::None].on = !game::HasItem(SelectedBottle); } void Inventory_BottlesMenuFunc(s32 selected) { game::CommonData& cdata = game::GetCommonData(); // Get the selected bottle. - u32 bottle_number = selected - 14; - u32 current_bottle = 0; - // Loop through to the specific selected bottle. - for (u32 i = cdata.save.inventory.items.size(); i < cdata.save.inventory.items.size(); i++) { - if (game::ItemIsBottled(cdata.save.inventory.items[i])) { - if (current_bottle != bottle_number) { - current_bottle++; - } else if (current_bottle == bottle_number) { - SelectedBottle = cdata.save.inventory.items[i]; - SelectedBottleIndex = i; - BottleNumber = current_bottle; - break; - } else { - SelectedBottleIndex = 255; - SelectedBottle = game::ItemId::None; - } - } - - } + BottleNumber = selected - 15; + SelectedBottle = cdata.save.inventory.bottles[BottleNumber]; + SelectedBottleItemIndex = selected; Inventory_BottlesMenuInit(); ToggleMenuShow(&InventoryBottlesMenu); } void Inventory_BottleSelect(s32 selected) { - game::CommonData& cdata = game::GetCommonData(); - if (selected != BottleContents::None) { // selected a bottled content - cdata.save.inventory.items[SelectedBottleIndex] = - game::ItemId((u32)game::ItemId::Bottle + (u32)selected); + u32 newItem = (u32)game::ItemId::Bottle + (u32)selected; + DisableMenuToggles(&InventoryBottlesMenu); + if (selected != 22) { // selected a bottled content + game::GiveBottle(BottleNumber, (game::ItemId)newItem); InventoryBottlesMenu.items[selected].on = 1; - InventoryItemsMenu.items[14 + BottleNumber].on = 1; + InventoryItemsMenu.items[SelectedBottleItemIndex].on = 1; } else { // erase the bottle - cdata.save.inventory.items[SelectedBottleIndex] = game::ItemId::None; - DisableMenuToggles(&InventoryBottlesMenu); - InventoryBottlesMenu.items[InventoryBottlesMenu.nbItems - 1].on = 1; - InventoryItemsMenu.items[14 + BottleNumber].on = 0; + game::RemoveBottle(BottleNumber); + InventoryBottlesMenu.items[selected].on = 1; + InventoryItemsMenu.items[SelectedBottleItemIndex].on = 0; } } @@ -569,7 +550,7 @@ Menu InventoryMenu = { ToggleMenu InventoryItemsMenu = { .title="Items", - .nbItems=15, + .nbItems=22, .items= { {.on=0, .title="Ocarina", .method = Inventory_ItemsToggle}, {.on=0, .title="Hero's Bow", .method = Inventory_ItemsToggle}, @@ -592,6 +573,7 @@ ToggleMenu InventoryItemsMenu = { {.on=0, .title="Bottle #4", .method = Inventory_BottlesMenuFunc}, {.on=0, .title="Bottle #5", .method = Inventory_BottlesMenuFunc}, {.on=0, .title="Bottle #6", .method = Inventory_BottlesMenuFunc}, + {.on=0, .title="Bottle #7", .method = Inventory_BottlesMenuFunc}, } }; @@ -681,7 +663,7 @@ ToggleMenu InventoryShieldsMenu = { ToggleMenu InventoryBottlesMenu = { .title="Choose Bottle Contents", - .nbItems = 14, + .nbItems = 23, .items={ {.on=0, .title="Empty Bottle", .method = Inventory_BottleSelect}, {.on=0, .title="Red Potion", .method = Inventory_BottleSelect},