From 9ce6e95ab59d3a5aedd27f273fd7c3947e37cb9f Mon Sep 17 00:00:00 2001 From: Eric Robinson Date: Mon, 11 Nov 2024 22:41:49 -0500 Subject: [PATCH] Shop prices --- Source/items.cpp | 14 +++++++------- Source/items.h | 5 +++++ Source/items/validation.cpp | 16 +++++++++++++++- Source/items/validation.h | 1 + Source/loadsave.cpp | 22 ---------------------- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/Source/items.cpp b/Source/items.cpp index 9129be6fd9d..c90232cae12 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -1958,7 +1958,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player) GetItemBonus(player, premiumItem, plvl / 2, plvl, true, !gbIsHellfire); if (!gbIsHellfire) { - if (premiumItem._iIvalue <= 140000) { + if (premiumItem._iIvalue <= MAX_VENDOR_VALUE) { break; } } else { @@ -1995,7 +1995,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player) break; } itemValue = itemValue * 4 / 5; // avoids forced int > float > int conversion - if (premiumItem._iIvalue <= 200000 + if (premiumItem._iIvalue <= MAX_VENDOR_VALUE_HF && premiumItem._iMinStr <= strength && premiumItem._iMinMag <= magic && premiumItem._iMinDex <= dexterity @@ -4371,10 +4371,10 @@ void SpawnSmith(int lvl) { constexpr int PinnedItemCount = 0; - int maxValue = 140000; + int maxValue = MAX_VENDOR_VALUE; int maxItems = 19; if (gbIsHellfire) { - maxValue = 200000; + maxValue = MAX_VENDOR_VALUE_HF; maxItems = 24; } @@ -4442,7 +4442,7 @@ void SpawnWitch(int lvl) int bookCount = 0; const int pinnedBookCount = gbIsHellfire ? RandomIntLessThan(MaxPinnedBookCount) : 0; const int itemCount = RandomIntBetween(10, gbIsHellfire ? 24 : 17); - const int maxValue = gbIsHellfire ? 200000 : 140000; + const int maxValue = gbIsHellfire ? MAX_VENDOR_VALUE_HF : MAX_VENDOR_VALUE; for (int i = 0; i < WITCH_ITEMS; i++) { Item &item = WitchItems[i]; @@ -4527,7 +4527,7 @@ void SpawnBoy(int lvl) GetItemBonus(*MyPlayer, BoyItem, lvl, 2 * lvl, true, true); if (!gbIsHellfire) { - if (BoyItem._iIvalue > 90000) { + if (BoyItem._iIvalue > MAX_BOY_VALUE) { keepgoing = true; // prevent breaking the do/while loop too early by failing hellfire's condition in while continue; } @@ -4602,7 +4602,7 @@ void SpawnBoy(int lvl) } } while (keepgoing || (( - BoyItem._iIvalue > 200000 + BoyItem._iIvalue > MAX_BOY_VALUE_HF || BoyItem._iMinStr > strength || BoyItem._iMinMag > magic || BoyItem._iMinDex > dexterity diff --git a/Source/items.h b/Source/items.h index 014f90e415f..3315241b306 100644 --- a/Source/items.h +++ b/Source/items.h @@ -29,6 +29,11 @@ namespace devilution { // Item indestructible durability #define DUR_INDESTRUCTIBLE 255 +#define MAX_VENDOR_VALUE 140000 +#define MAX_VENDOR_VALUE_HF 200000 +#define MAX_BOY_VALUE 90000 +#define MAX_BOY_VALUE_HF 200000 + enum item_quality : uint8_t { ITEM_QUALITY_NORMAL, ITEM_QUALITY_MAGIC, diff --git a/Source/items/validation.cpp b/Source/items/validation.cpp index fd397f0dfd0..158e6044e02 100644 --- a/Source/items/validation.cpp +++ b/Source/items/validation.cpp @@ -56,6 +56,20 @@ bool IsTownItemValid(uint16_t iCreateInfo, uint8_t maxCharacterLevel) return level <= maxTownItemLevel; } +bool IsShopPriceValid(const Item &item) +{ + const int boyPriceLimit = gbIsHellfire ? MAX_BOY_VALUE_HF : MAX_BOY_VALUE; + if ((item._iCreateInfo & CF_BOY) != 0 && item._iIvalue > boyPriceLimit) + return false; + + const uint16_t smithOrWitch = CF_SMITH | CF_SMITHPREMIUM | CF_WITCH; + const int smithAndWitchPriceLimit = gbIsHellfire ? MAX_VENDOR_VALUE_HF : MAX_VENDOR_VALUE; + if ((item._iCreateInfo & smithOrWitch) != 0 && item._iIvalue > smithAndWitchPriceLimit) + return false; + + return true; +} + bool IsUniqueMonsterItemValid(uint16_t iCreateInfo, uint32_t dwBuff) { const uint8_t level = iCreateInfo & CF_LEVEL; @@ -127,7 +141,7 @@ bool IsItemValid(const Player &player, const Item &item) isValid = isValid && IsCreationFlagComboValid(item._iCreateInfo); if ((item._iCreateInfo & CF_TOWN) != 0) - isValid = isValid && IsTownItemValid(item._iCreateInfo, player.getMaxCharacterLevel()); + isValid = isValid && IsTownItemValid(item._iCreateInfo, player.getMaxCharacterLevel()) && IsShopPriceValid(item); else if ((item._iCreateInfo & CF_USEFUL) == CF_UPER15) isValid = isValid && IsUniqueMonsterItemValid(item._iCreateInfo, item.dwBuff); diff --git a/Source/items/validation.h b/Source/items/validation.h index 5a7346cf7c0..ba66195b741 100644 --- a/Source/items/validation.h +++ b/Source/items/validation.h @@ -14,6 +14,7 @@ namespace devilution { bool IsCreationFlagComboValid(uint16_t iCreateInfo); bool IsTownItemValid(uint16_t iCreateInfo, uint8_t maxCharacterLevel); +bool IsShopPriceValid(const Item &item); bool IsUniqueMonsterItemValid(uint16_t iCreateInfo, uint32_t dwBuff); bool IsDungeonItemValid(uint16_t iCreateInfo, uint32_t dwBuff); bool IsItemValid(const Player &player, const Item &item); diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index dd57a29467d..d604ab1f53f 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -969,24 +969,6 @@ bool LevelFileExists(SaveWriter &archive) return archive.HasFile(szName); } -bool IsShopPriceValid(const Item &item) -{ - const int boyPriceLimit = 90000; - if (!gbIsHellfire && (item._iCreateInfo & CF_BOY) != 0 && item._iIvalue > boyPriceLimit) - return false; - - const int premiumPriceLimit = 140000; - if (!gbIsHellfire && (item._iCreateInfo & CF_SMITHPREMIUM) != 0 && item._iIvalue > premiumPriceLimit) - return false; - - const uint16_t smithOrWitch = CF_SMITH | CF_WITCH; - const int smithAndWitchPriceLimit = gbIsHellfire ? 200000 : 140000; - if ((item._iCreateInfo & smithOrWitch) != 0 && item._iIvalue > smithAndWitchPriceLimit) - return false; - - return true; -} - void LoadMatchingItems(LoadHelper &file, const Player &player, const int n, Item *pItem) { Item heroItem; @@ -1012,10 +994,6 @@ void LoadMatchingItems(LoadHelper &file, const Player &player, const int n, Item unpackedItem._iMaxCharges = std::clamp(heroItem._iMaxCharges, 0, unpackedItem._iMaxCharges); unpackedItem._iCharges = std::clamp(heroItem._iCharges, 0, unpackedItem._iMaxCharges); } - if (!IsShopPriceValid(unpackedItem)) { - unpackedItem.clear(); - continue; - } if (gbIsHellfire) { unpackedItem._iPLToHit = ClampToHit(unpackedItem, heroItem._iPLToHit); // Oil of Accuracy unpackedItem._iMaxDam = ClampMaxDam(unpackedItem, heroItem._iMaxDam); // Oil of Sharpness