diff --git a/Runtime/AutoMapper/CMapWorldInfo.hpp b/Runtime/AutoMapper/CMapWorldInfo.hpp index 2cb325fa4..4ab9a31a4 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.hpp +++ b/Runtime/AutoMapper/CMapWorldInfo.hpp @@ -29,6 +29,7 @@ public: bool IsWorldVisible(TAreaId aid) const; bool IsAreaVisible(TAreaId aid) const; bool IsAnythingSet() const; + bool GetMapStationUsed() const { return x38_mapStationUsed; } void SetMapStationUsed(bool isUsed) { x38_mapStationUsed = isUsed; } }; } // namespace metaforce diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index 6b5ee1fa0..0d04b879f 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -450,4 +450,89 @@ CPlayerState::EItemType CPlayerState::ItemNameToType(std::string_view name) { return iter->second; } +std::string_view CPlayerState::ItemTypeToName(CPlayerState::EItemType type) { + switch (type) { + case EItemType::PowerBeam: + return "Power Beam"sv; + case EItemType::IceBeam: + return "Ice Beam"sv; + case EItemType::WaveBeam: + return "Wave Beam"sv; + case EItemType::PlasmaBeam: + return "Plasma Beam"sv; + case EItemType::Missiles: + return "Missiles"sv; + case EItemType::ScanVisor: + return "Scan Visor"sv; + case EItemType::MorphBallBombs: + return "Morph Ball Bombs"sv; + case EItemType::PowerBombs: + return "Power Bombs"sv; + case EItemType::Flamethrower: + return "Flamethrower"sv; + case EItemType::ThermalVisor: + return "Thermal Visor"sv; + case EItemType::ChargeBeam: + return "Charge Beam"sv; + case EItemType::SuperMissile: + return "Super Missile"sv; + case EItemType::GrappleBeam: + return "Grapple Beam"sv; + case EItemType::XRayVisor: + return "XRay Visor"sv; + case EItemType::IceSpreader: + return "Ice Spreader"sv; + case EItemType::SpaceJumpBoots: + return "Space Jump Boots"sv; + case EItemType::MorphBall: + return "Morph Ball"sv; + case EItemType::CombatVisor: + return "Combat Visor"sv; + case EItemType::BoostBall: + return "Boost Ball"sv; + case EItemType::SpiderBall: + return "Spider Ball"sv; + case EItemType::PowerSuit: + return "Power Suit"sv; + case EItemType::GravitySuit: + return "Gravity Suit"sv; + case EItemType::VariaSuit: + return "Varia Suit"sv; + case EItemType::PhazonSuit: + return "Phazon Suit"sv; + case EItemType::EnergyTanks: + return "Energy Tanks"sv; + case EItemType::HealthRefill: + return "Health Refill"sv; + case EItemType::Wavebuster: + return "Wavebuster"sv; + case EItemType::Truth: + return "Artifact of Truth"sv; + case EItemType::Strength: + return "Artifact of Strength"sv; + case EItemType::Elder: + return "Artifact of Elder"sv; + case EItemType::Wild: + return "Artifact of Wild"sv; + case EItemType::Lifegiver: + return "Artifact of Lifegiver"sv; + case EItemType::Warrior: + return "Artifact of Warrior"sv; + case EItemType::Chozo: + return "Artifact of Chozo"sv; + case EItemType::Nature: + return "Artifact of Nature"sv; + case EItemType::Sun: + return "Artifact of Sun"sv; + case EItemType::World: + return "Artifact of World"sv; + case EItemType::Spirit: + return "Artifact of Spirit"sv; + case EItemType::Newborn: + return "Artifact of Newborn"sv; + default: + return "[unknown]"sv; + } +} + } // namespace metaforce diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index e989d771f..72ae5b136 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -168,6 +168,7 @@ public: void PutTo(CBitStreamWriter& stream); static u32 GetPowerUpMaxValue(EItemType type); static EItemType ItemNameToType(std::string_view name); + static std::string_view ItemTypeToName(EItemType type); bool CanTakeDamage() const { return m_canTakeDamage; } void SetCanTakeDamage(bool c) { m_canTakeDamage = c; } }; diff --git a/Runtime/GuiSys/CHudVisorBeamMenu.cpp b/Runtime/GuiSys/CHudVisorBeamMenu.cpp index b0e882ae1..7a930efab 100644 --- a/Runtime/GuiSys/CHudVisorBeamMenu.cpp +++ b/Runtime/GuiSys/CHudVisorBeamMenu.cpp @@ -288,6 +288,10 @@ void CHudVisorBeamMenu::SetPlayerHas(const rstl::reserved_vector& enabl if (item.xc_opacity == 0.f && enables[i]) { item.xc_opacity = FLT_EPSILON; } + // Metaforce addition + else if (!enables[i]) { + item.xc_opacity = 0.f; + } } } diff --git a/Runtime/ImGuiConsole.cpp b/Runtime/ImGuiConsole.cpp index 869c99858..b3cf64c2c 100644 --- a/Runtime/ImGuiConsole.cpp +++ b/Runtime/ImGuiConsole.cpp @@ -570,6 +570,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) { } if (ImGui::BeginMenu("Tools")) { ImGui::MenuItem("Inspect", nullptr, &m_showInspectWindow, canInspect); + ImGui::MenuItem("Items", nullptr, &m_showItemsWindow, canInspect); ImGui::Separator(); ImGui::MenuItem("Demo", nullptr, &m_showDemoWindow); ImGui::EndMenu(); @@ -634,6 +635,9 @@ void ImGuiConsole::PreUpdate() { } } } + if (canInspect && m_showItemsWindow) { + ShowItemsWindow(); + } if (m_showAboutWindow) { ShowAboutWindow(); } @@ -673,4 +677,104 @@ ImGuiConsole::~ImGuiConsole() { dummyWorlds.clear(); stringTables.clear(); } + +static constexpr std::array ItemOrder{ + CPlayerState::EItemType::PowerBeam, + CPlayerState::EItemType::ChargeBeam, + CPlayerState::EItemType::IceBeam, + CPlayerState::EItemType::WaveBeam, + CPlayerState::EItemType::PlasmaBeam, + CPlayerState::EItemType::EnergyTanks, + CPlayerState::EItemType::Missiles, + CPlayerState::EItemType::SuperMissile, + CPlayerState::EItemType::Flamethrower, + CPlayerState::EItemType::IceSpreader, + CPlayerState::EItemType::Wavebuster, + CPlayerState::EItemType::CombatVisor, + CPlayerState::EItemType::ScanVisor, + CPlayerState::EItemType::ThermalVisor, + CPlayerState::EItemType::XRayVisor, + CPlayerState::EItemType::MorphBall, + CPlayerState::EItemType::MorphBallBombs, + CPlayerState::EItemType::PowerBombs, + CPlayerState::EItemType::BoostBall, + CPlayerState::EItemType::SpiderBall, + CPlayerState::EItemType::GrappleBeam, + CPlayerState::EItemType::SpaceJumpBoots, + CPlayerState::EItemType::PowerSuit, + CPlayerState::EItemType::VariaSuit, + CPlayerState::EItemType::GravitySuit, + CPlayerState::EItemType::PhazonSuit, + CPlayerState::EItemType::Truth, + CPlayerState::EItemType::Strength, + CPlayerState::EItemType::Elder, + CPlayerState::EItemType::Wild, + CPlayerState::EItemType::Lifegiver, + CPlayerState::EItemType::Warrior, + CPlayerState::EItemType::Chozo, + CPlayerState::EItemType::Nature, + CPlayerState::EItemType::Sun, + CPlayerState::EItemType::World, + CPlayerState::EItemType::Spirit, + CPlayerState::EItemType::Newborn, +}; + +void ImGuiConsole::ShowItemsWindow() { + CPlayerState& pState = *g_StateManager->GetPlayerState(); + if (ImGui::Begin("Items", &m_showItemsWindow)) { + if (ImGui::Button("Refill")) { + for (const auto itemType : ItemOrder) { + u32 maxValue = CPlayerState::GetPowerUpMaxValue(itemType); + pState.ResetAndIncrPickUp(itemType, maxValue); + } + } + { + ImGui::SameLine(); + auto& mapWorldInfo = *g_GameState->CurrentWorldState().MapWorldInfo(); + bool mapStationUsed = mapWorldInfo.GetMapStationUsed(); + if (ImGui::Checkbox("Area map", &mapStationUsed)) { + mapWorldInfo.SetMapStationUsed(mapStationUsed); + } + } + if (ImGui::Button("All")) { + for (const auto itemType : ItemOrder) { + u32 maxValue = CPlayerState::GetPowerUpMaxValue(itemType); + pState.ReInitializePowerUp(itemType, maxValue); + pState.ResetAndIncrPickUp(itemType, maxValue); + } + } + ImGui::SameLine(); + if (ImGui::Button("None")) { + for (const auto itemType : ItemOrder) { + pState.ReInitializePowerUp(itemType, 0); + } + } + for (const auto itemType : ItemOrder) { + u32 maxValue = CPlayerState::GetPowerUpMaxValue(itemType); + std::string name{CPlayerState::ItemTypeToName(itemType)}; + if (maxValue == 1) { + bool enabled = pState.GetItemCapacity(itemType) == 1; + if (ImGui::Checkbox(name.c_str(), &enabled)) { + if (enabled) { + pState.ReInitializePowerUp(itemType, 1); + pState.ResetAndIncrPickUp(itemType, 1); + } else { + pState.ReInitializePowerUp(itemType, 0); + } + if (itemType == CPlayerState::EItemType::VariaSuit || itemType == CPlayerState::EItemType::PowerSuit || + itemType == CPlayerState::EItemType::GravitySuit || itemType == CPlayerState::EItemType::PhazonSuit) { + g_StateManager->Player()->AsyncLoadSuit(*g_StateManager); + } + } + } else if (maxValue > 1) { + int capacity = int(pState.GetItemCapacity(itemType)); + if (ImGui::SliderInt(name.c_str(), &capacity, 0, int(maxValue), "%d", ImGuiSliderFlags_AlwaysClamp)) { + pState.ReInitializePowerUp(itemType, u32(capacity)); + pState.ResetAndIncrPickUp(itemType, u32(capacity)); + } + } + } + } + ImGui::End(); +} } // namespace metaforce diff --git a/Runtime/ImGuiConsole.hpp b/Runtime/ImGuiConsole.hpp index c26846d2d..d3b1aa3bb 100644 --- a/Runtime/ImGuiConsole.hpp +++ b/Runtime/ImGuiConsole.hpp @@ -55,6 +55,7 @@ private: bool m_showInspectWindow = false; bool m_showDemoWindow = false; bool m_showAboutWindow = false; + bool m_showItemsWindow = false; bool m_paused = false; bool m_stepFrame = false; @@ -86,5 +87,6 @@ private: void UpdateEntityEntries(); void ShowAboutWindow(); void ShowDebugOverlay(); + void ShowItemsWindow(); }; } // namespace metaforce