From b749ebb84f835acf67c3f7996f067e4e5231f126 Mon Sep 17 00:00:00 2001 From: Emmanuel Jacyna Date: Sun, 30 Jun 2024 00:53:37 +1000 Subject: [PATCH] Closes #108 Fix teleport costs (#195) --- bak/temple.cpp | 33 +++++++++++++++------------------ bak/temple.hpp | 8 +++++++- gui/IGuiManager.hpp | 2 +- gui/gdsScene.cpp | 4 +++- gui/guiManager.hpp | 4 ++-- gui/teleportScreen.hpp | 24 +++++++++++++++++++++--- 6 files changed, 49 insertions(+), 26 deletions(-) diff --git a/bak/temple.cpp b/bak/temple.cpp index 11d6c70a..c18c9394 100644 --- a/bak/temple.cpp +++ b/bak/temple.cpp @@ -40,25 +40,22 @@ void RemoveBlessing(BAK::InventoryItem& item) } } -Royals CalculateTeleportCost(unsigned source, unsigned dest) +Royals CalculateTeleportCost( + unsigned srcTemple, + unsigned dstTemple, + glm::vec2 srcPos, + glm::vec2 dstPos, + unsigned teleportMultiplier, + unsigned teleportConstant) { - ASSERT(source > 0 && dest > 0); - ASSERT(source <= 13 && dest <= 13); - static constexpr unsigned costMatrix[12][12] = { - {0, 85, 88, 112, 167, 149, 172, 184, 106, 159, 120, 158}, - {85, 0, 70, 105, 136, 123, 138, 139, 61, 113, 119, 129}, - {88, 70, 0, 84, 129, 111, 140, 152, 83, 127, 99, 120}, - {88, 70, 105, 0, 99, 81, 134, 146, 103, 134, 59, 91}, - {88, 70, 105, 99, 0, 70, 102, 131, 129, 124, 105, 61}, - {88, 70, 105, 99, 70, 0, 102, 131, 115, 121, 75, 49}, - {88, 70, 105, 99, 70, 102, 0, 89, 137, 97, 151, 120}, - {88, 70, 105, 99, 70, 102, 89, 0, 128, 75, 161, 140}, - {88, 70, 105, 99, 70, 102, 89, 128, 0, 102, 121, 131}, - {88, 70, 105, 99, 70, 102, 89, 128, 102, 0, 151, 129}, - {88, 70, 105, 99, 70, 102, 89, 128, 102, 151, 0, 63}, - {88, 70, 105, 99, 70, 102, 89, 128, 102, 151, 63, 0} - }; - return GetRoyals(Sovereigns{costMatrix[source - 1][dest - 1]}); + ASSERT(srcTemple > 0 && dstTemple > 0); + ASSERT(srcTemple <= 13 && dstTemple <= 13); + auto xDiff = static_cast(std::abs(srcPos.x - dstPos.x)); + auto yDiff = static_cast(std::abs(srcPos.y - dstPos.y)); + auto cost = std::max(xDiff, yDiff) + (std::min(xDiff, yDiff) * 3) / 8; + cost = ((cost * teleportMultiplier) + teleportConstant) * 10; + cost = (cost + 5) / 10; + return Royals{cost}; } Royals CalculateCureCost( diff --git a/bak/temple.hpp b/bak/temple.hpp index 98c51925..2a886351 100644 --- a/bak/temple.hpp +++ b/bak/temple.hpp @@ -17,7 +17,13 @@ Royals CalculateBlessPrice(const BAK::InventoryItem& item, const ShopStats& shop void BlessItem(BAK::InventoryItem& item, const ShopStats& shop); void RemoveBlessing(BAK::InventoryItem& item); -Royals CalculateTeleportCost(unsigned source, unsigned dest); +Royals CalculateTeleportCost( + unsigned srcTemple, + unsigned dstTemple, + glm::vec2 srcPos, + glm::vec2 dstPos, + unsigned teleportMultiplier, + unsigned teleportConstant); Royals CalculateCureCost( unsigned cureFactor, diff --git a/gui/IGuiManager.hpp b/gui/IGuiManager.hpp index d1c35a12..4d0388cf 100644 --- a/gui/IGuiManager.hpp +++ b/gui/IGuiManager.hpp @@ -45,7 +45,7 @@ class IGuiManager virtual void ShowCast(bool inCombat) = 0; virtual void ShowFullMap() = 0; virtual void ShowGameStartMap() = 0; - virtual void ShowTeleport(unsigned sourceTemple) = 0; + virtual void ShowTeleport(unsigned sourceTemple, BAK::ShopStats* temple) = 0; virtual void ShowCureScreen( unsigned templeNumber, unsigned cureFactor, diff --git a/gui/gdsScene.cpp b/gui/gdsScene.cpp index 0c26b2d8..94f6d271 100644 --- a/gui/gdsScene.cpp +++ b/gui/gdsScene.cpp @@ -520,7 +520,9 @@ void GDSScene::DoTeleport() if (mGameState.GetMoreThanOneTempleSeen()) { assert(mSceneHotspots.GetTempleNumber()); - mGuiManager.ShowTeleport(*mSceneHotspots.GetTempleNumber()); + mGuiManager.ShowTeleport( + *mSceneHotspots.GetTempleNumber(), + &mGameState.GetContainerForGDSScene(mReference)->GetShop()); } else { diff --git a/gui/guiManager.hpp b/gui/guiManager.hpp index 65273e83..2e67ab67 100644 --- a/gui/guiManager.hpp +++ b/gui/guiManager.hpp @@ -641,9 +641,9 @@ class GuiManager final : public Widget, public IGuiManager }); } - void ShowTeleport(unsigned sourceTemple) override + void ShowTeleport(unsigned sourceTemple, BAK::ShopStats* temple) override { - mTeleportScreen.SetSourceTemple(sourceTemple); + mTeleportScreen.SetSourceTemple(sourceTemple, temple); DoFade(.8, [this]{ mCursor.PopCursor(); mScreenStack.PushScreen(&mTeleportScreen); diff --git a/gui/teleportScreen.hpp b/gui/teleportScreen.hpp index 722de2b7..4febe4a4 100644 --- a/gui/teleportScreen.hpp +++ b/gui/teleportScreen.hpp @@ -5,6 +5,7 @@ #include "bak/dialogSources.hpp" #include "bak/encounter/teleport.hpp" #include "bak/layout.hpp" +#include "bak/shop.hpp" #include "bak/sounds.hpp" #include "bak/temple.hpp" @@ -179,9 +180,11 @@ class TeleportScreen : public Widget, public IDialogScene } } - void SetSourceTemple(unsigned sourceTemple) + void SetSourceTemple(unsigned sourceTemple, BAK::ShopStats* temple) { mState = State::Idle; + assert(temple); + mTemple = temple; mSource = sourceTemple; mChosenDest = std::nullopt; for (unsigned i = 0; i < mTeleportDests.size(); i++) @@ -230,7 +233,7 @@ class TeleportScreen : public Widget, public IDialogScene } else { - const auto cost = BAK::Temple::CalculateTeleportCost(mSource, templeNumber); + const auto cost = CalculateCost(templeNumber); if (cost < mGameState.GetMoney()) { mGameState.GetParty().LoseMoney(cost); @@ -275,7 +278,7 @@ class TeleportScreen : public Widget, public IDialogScene std::string MakeCostString(unsigned templeNumber) { std::stringstream ss{}; - ss << "Cost: " << BAK::ToShopDialogString(BAK::Temple::CalculateTeleportCost(mSource, templeNumber)); + ss << "Cost: " << BAK::ToShopDialogString(CalculateCost(templeNumber)); return ss.str(); } @@ -308,6 +311,20 @@ class TeleportScreen : public Widget, public IDialogScene } private: + BAK::Royals CalculateCost(unsigned templeNumber) + { + assert(mTemple); + const auto srcPos = mLayout.GetWidget(mSource - 1).mPosition; + const auto dstPos = mLayout.GetWidget(templeNumber - 1).mPosition; + return BAK::Temple::CalculateTeleportCost( + mSource, + templeNumber, + srcPos, + dstPos, + mTemple->mHaggleAnnoyanceFactor, + mTemple->mCategories); + } + IGuiManager& mGuiManager; const Font& mFont; BAK::GameState& mGameState; @@ -317,6 +334,7 @@ class TeleportScreen : public Widget, public IDialogScene State mState; unsigned mSource; + BAK::ShopStats* mTemple; std::optional mHighlightedDest; std::optional mChosenDest; bool mNeedRefresh;