Browse Source

Use StaticVector for all vendors

pull/8262/head
Yggdrasill 4 months ago committed by GitHub
parent
commit
753b566350
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 101
      Source/items.cpp
  2. 1
      Source/items.h
  3. 105
      Source/stores.cpp
  4. 9
      Source/stores.h
  5. 316
      test/vendor_test.cpp

101
Source/items.cpp

@ -1901,13 +1901,13 @@ _item_indexes RndSmithItem(const Player &player, int lvl)
return RndVendorItem<SmithItemOk, true>(player, 0, lvl); return RndVendorItem<SmithItemOk, true>(player, 0, lvl);
} }
void SortVendor(Item *itemList, size_t count) void SortVendor(std::span<Item> itemList, size_t PinnedItemCount)
{ {
auto cmp = [](const Item &a, const Item &b) { auto cmp = [](const Item &a, const Item &b) {
return a.IDidx < b.IDidx; return a.IDidx < b.IDidx;
}; };
std::sort(itemList, itemList + count, cmp); std::sort(itemList.begin() + PinnedItemCount, itemList.end(), cmp);
} }
bool PremiumItemOk(const Player & /*player*/, const ItemData &item) bool PremiumItemOk(const Player & /*player*/, const ItemData &item)
@ -4388,10 +4388,11 @@ void SpawnSmith(int lvl)
maxItems = NumSmithBasicItemsHf; maxItems = NumSmithBasicItemsHf;
} }
const int iCnt = RandomIntBetween(10, maxItems); const size_t iCnt = RandomIntBetween(10, maxItems);
for (int i = 0; i < iCnt; i++) { SmithItems.clear();
Item &newItem = SmithItems[i];
while (SmithItems.size() < iCnt) {
Item newItem;
do { do {
newItem = {}; newItem = {};
newItem._iSeed = AdvanceRndSeed(); newItem._iSeed = AdvanceRndSeed();
@ -4402,41 +4403,46 @@ void SpawnSmith(int lvl)
newItem._iCreateInfo = lvl | CF_SMITH; newItem._iCreateInfo = lvl | CF_SMITH;
newItem._iIdentified = true; newItem._iIdentified = true;
SmithItems.push_back(newItem);
} }
for (int i = iCnt; i < NumSmithBasicItemsHf; i++)
SmithItems[i].clear();
SortVendor(SmithItems + PinnedItemCount, iCnt - PinnedItemCount); SortVendor(SmithItems, PinnedItemCount);
}
void ReplacePremium(const Player &player, int idx)
{
int plvl = gbIsHellfire ? itemLevelAddHf[idx] : itemLevelAdd[idx];
plvl += player.getCharacterLevel();
SpawnOnePremium(PremiumItems[idx], plvl, player);
} }
void SpawnPremium(const Player &player) void SpawnPremium(const Player &player)
{ {
const int lvl = player.getCharacterLevel(); const int lvl = player.getCharacterLevel();
const int maxItems = gbIsHellfire ? NumSmithItemsHf : NumSmithItems; const size_t maxItems = gbIsHellfire ? NumSmithItemsHf : NumSmithItems;
if (PremiumItemCount < maxItems) {
for (int i = 0; i < maxItems; i++) { while (PremiumItems.size() < maxItems) {
if (PremiumItems[i].isEmpty()) { int plvl = PremiumItemLevel + (gbIsHellfire ? itemLevelAddHf[PremiumItems.size()] : itemLevelAdd[PremiumItems.size()]);
const int plvl = PremiumItemLevel + (gbIsHellfire ? itemLevelAddHf[i] : itemLevelAdd[i]); Item item = {};
SpawnOnePremium(PremiumItems[i], plvl, player); SpawnOnePremium(item, plvl, player);
} PremiumItems.push_back(item);
}
PremiumItemCount = maxItems;
} }
while (PremiumItemLevel < lvl) { while (PremiumItemLevel < lvl) {
PremiumItemLevel++; PremiumItemLevel++;
Item *ptr = PremiumItems.begin();
if (gbIsHellfire) { if (gbIsHellfire) {
// Discard first 3 items and shift next 10 std::move(ptr + 3, ptr + 13, ptr);
std::move(&PremiumItems[3], &PremiumItems[12] + 1, &PremiumItems[0]);
SpawnOnePremium(PremiumItems[10], PremiumItemLevel + itemLevelAddHf[10], player);
PremiumItems[11] = PremiumItems[13]; PremiumItems[11] = PremiumItems[13];
SpawnOnePremium(PremiumItems[12], PremiumItemLevel + itemLevelAddHf[12], player);
PremiumItems[13] = PremiumItems[14]; PremiumItems[13] = PremiumItems[14];
SpawnOnePremium(PremiumItems[10], PremiumItemLevel + itemLevelAddHf[10], player);
SpawnOnePremium(PremiumItems[12], PremiumItemLevel + itemLevelAddHf[12], player);
SpawnOnePremium(PremiumItems[14], PremiumItemLevel + itemLevelAddHf[14], player); SpawnOnePremium(PremiumItems[14], PremiumItemLevel + itemLevelAddHf[14], player);
} else { } else {
// Discard first 2 items and shift next 3 std::move(ptr + 2, ptr + 5, ptr);
std::move(&PremiumItems[2], &PremiumItems[4] + 1, &PremiumItems[0]);
SpawnOnePremium(PremiumItems[3], PremiumItemLevel + itemLevelAdd[3], player);
PremiumItems[4] = PremiumItems[5]; PremiumItems[4] = PremiumItems[5];
SpawnOnePremium(PremiumItems[3], PremiumItemLevel + itemLevelAdd[3], player);
SpawnOnePremium(PremiumItems[5], PremiumItemLevel + itemLevelAdd[5], player); SpawnOnePremium(PremiumItems[5], PremiumItemLevel + itemLevelAdd[5], player);
} }
} }
@ -4453,16 +4459,17 @@ void SpawnWitch(int lvl)
const int pinnedBookCount = gbIsHellfire ? RandomIntLessThan(MaxPinnedBookCount) : 0; const int pinnedBookCount = gbIsHellfire ? RandomIntLessThan(MaxPinnedBookCount) : 0;
const int itemCount = RandomIntBetween(10, gbIsHellfire ? NumWitchItemsHf : NumWitchItems); const int itemCount = RandomIntBetween(10, gbIsHellfire ? NumWitchItemsHf : NumWitchItems);
const int maxValue = gbIsHellfire ? MaxVendorValueHf : MaxVendorValue; const int maxValue = gbIsHellfire ? MaxVendorValueHf : MaxVendorValue;
WitchItems.clear();
for (int i = 0; i < NumWitchItemsHf; i++) { for (int i = 0; i < itemCount; i++) {
Item &item = WitchItems[i]; Item item = {};
item = {};
if (i < PinnedItemCount) { if (i < PinnedItemCount) {
item._iSeed = AdvanceRndSeed(); item._iSeed = AdvanceRndSeed();
GetItemAttrs(item, PinnedItemTypes[i], 1); GetItemAttrs(item, PinnedItemTypes[i], 1);
item._iCreateInfo = lvl; item._iCreateInfo = lvl;
item._iStatFlag = true; item._iStatFlag = true;
WitchItems.push_back(item);
continue; continue;
} }
@ -4477,16 +4484,12 @@ void SpawnWitch(int lvl)
item._iCreateInfo = lvl | CF_WITCH; item._iCreateInfo = lvl | CF_WITCH;
item._iIdentified = true; item._iIdentified = true;
bookCount++; bookCount++;
WitchItems.push_back(item);
continue; continue;
} }
} }
} }
if (i >= itemCount) {
item.clear();
continue;
}
do { do {
item = {}; item = {};
item._iSeed = AdvanceRndSeed(); item._iSeed = AdvanceRndSeed();
@ -4504,9 +4507,11 @@ void SpawnWitch(int lvl)
item._iCreateInfo = lvl | CF_WITCH; item._iCreateInfo = lvl | CF_WITCH;
item._iIdentified = true; item._iIdentified = true;
WitchItems.push_back(item);
} }
SortVendor(WitchItems + PinnedItemCount, itemCount - PinnedItemCount); SortVendor(WitchItems, PinnedItemCount);
} }
void SpawnBoy(int lvl) void SpawnBoy(int lvl)
@ -4629,34 +4634,30 @@ void SpawnHealer(int lvl)
{ {
constexpr size_t PinnedItemCount = NumHealerPinnedItems; constexpr size_t PinnedItemCount = NumHealerPinnedItems;
constexpr std::array<_item_indexes, PinnedItemCount + 1> PinnedItemTypes = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT }; constexpr std::array<_item_indexes, PinnedItemCount + 1> PinnedItemTypes = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT };
const auto itemCount = static_cast<size_t>(RandomIntBetween(10, gbIsHellfire ? NumHealerItemsHf : NumHealerItems)); const size_t itemCount = static_cast<size_t>(RandomIntBetween(10, gbIsHellfire ? NumHealerItemsHf : NumHealerItems));
HealerItems.clear();
for (size_t i = 0; i < sizeof(HealerItems) / sizeof(HealerItems[0]); ++i) { for (size_t i = 0; i < itemCount; i++) {
Item &item = HealerItems[i]; Item item = {};
item = {};
if (i < PinnedItemCount || (gbIsMultiplayer && i < NumHealerPinnedItemsMp)) { if (i < PinnedItemCount || (gbIsMultiplayer && i < NumHealerPinnedItemsMp)) {
item._iSeed = AdvanceRndSeed(); item._iSeed = AdvanceRndSeed();
GetItemAttrs(item, PinnedItemTypes[i], 1); GetItemAttrs(item, PinnedItemTypes[i], 1);
item._iCreateInfo = lvl; item._iCreateInfo = lvl;
item._iStatFlag = true; item._iStatFlag = true;
continue; } else {
} item._iSeed = AdvanceRndSeed();
SetRndSeed(item._iSeed);
if (i >= itemCount) { const _item_indexes itype = RndHealerItem(*MyPlayer, lvl);
item.clear(); GetItemAttrs(item, itype, lvl);
continue; item._iCreateInfo = lvl | CF_HEALER;
item._iIdentified = true;
} }
item._iSeed = AdvanceRndSeed(); HealerItems.push_back(item);
SetRndSeed(item._iSeed);
const _item_indexes itype = RndHealerItem(*MyPlayer, lvl);
GetItemAttrs(item, itype, lvl);
item._iCreateInfo = lvl | CF_HEALER;
item._iIdentified = true;
} }
SortVendor(HealerItems + PinnedItemCount, itemCount - PinnedItemCount); SortVendor(HealerItems, PinnedItemCount);
} }
void MakeGoldStack(Item &goldItem, int value) void MakeGoldStack(Item &goldItem, int value)

1
Source/items.h

@ -557,6 +557,7 @@ void UseItem(Player &player, item_misc_id Mid, SpellID spellID, int spellFrom);
bool UseItemOpensHive(const Item &item, Point position); bool UseItemOpensHive(const Item &item, Point position);
bool UseItemOpensGrave(const Item &item, Point position); bool UseItemOpensGrave(const Item &item, Point position);
void SpawnSmith(int lvl); void SpawnSmith(int lvl);
void ReplacePremium(const Player &player, int idx);
void SpawnPremium(const Player &player); void SpawnPremium(const Player &player);
void SpawnWitch(int lvl); void SpawnWitch(int lvl);
void SpawnBoy(int lvl); void SpawnBoy(int lvl);

105
Source/stores.cpp

@ -40,14 +40,14 @@ int CurrentItemIndex;
int8_t PlayerItemIndexes[48]; int8_t PlayerItemIndexes[48];
Item PlayerItems[48]; Item PlayerItems[48];
Item SmithItems[NumSmithBasicItemsHf]; StaticVector<Item, NumSmithBasicItemsHf> SmithItems;
int PremiumItemCount; int PremiumItemCount;
int PremiumItemLevel; int PremiumItemLevel;
Item PremiumItems[NumSmithItemsHf]; StaticVector<Item, NumSmithItemsHf> PremiumItems;
Item HealerItems[20]; StaticVector<Item, NumHealerItemsHf> HealerItems;
Item WitchItems[NumWitchItemsHf]; StaticVector<Item, NumWitchItemsHf> WitchItems;
int BoyItemLevel; int BoyItemLevel;
Item BoyItem; Item BoyItem;
@ -354,22 +354,18 @@ bool StoreAutoPlace(Item &item, bool persistItem)
return CanFitItemInInventory(player, item); return CanFitItemInInventory(player, item);
} }
void ScrollVendorStore(Item *itemData, int storeLimit, int idx, int selling = true) void ScrollVendorStore(std::span<Item> itemData, int storeLimit, int idx, int selling = true)
{ {
ClearSText(5, 21); ClearSText(5, 21);
PreviousScrollPos = 5; PreviousScrollPos = 5;
for (int l = 5; l < 20 && idx < storeLimit; l += 4) { for (int l = 5; l < 20 && idx < storeLimit; l += 4) {
const Item &item = itemData[idx]; const Item &item = itemData[idx];
if (!item.isEmpty()) { const UiFlags itemColor = item.getTextColorWithStatCheck();
const UiFlags itemColor = item.getTextColorWithStatCheck(); AddSText(20, l, item.getName(), itemColor, true, item._iCurs, true);
AddSText(20, l, item.getName(), itemColor, true, item._iCurs, true); AddSTextVal(l, item._iIdentified ? item._iIvalue : item._ivalue);
AddSTextVal(l, item._iIdentified ? item._iIvalue : item._ivalue); PrintStoreItem(item, l + 1, itemColor, true);
PrintStoreItem(item, l + 1, itemColor, true); NextScrollPos = l;
NextScrollPos = l;
} else {
l -= 4;
}
idx++; idx++;
} }
if (selling) { if (selling) {
@ -399,7 +395,7 @@ void StartSmith()
void ScrollSmithBuy(int idx) void ScrollSmithBuy(int idx)
{ {
ScrollVendorStore(SmithItems, static_cast<int>(std::size(SmithItems)), idx); ScrollVendorStore(SmithItems, static_cast<int>(SmithItems.size()), idx);
} }
uint32_t TotalPlayerGold() uint32_t TotalPlayerGold()
@ -427,9 +423,6 @@ void StartSmithBuy()
CurrentItemIndex = 0; CurrentItemIndex = 0;
for (Item &item : SmithItems) { for (Item &item : SmithItems) {
if (item.isEmpty())
continue;
item._iStatFlag = MyPlayer->CanUseItem(item); item._iStatFlag = MyPlayer->CanUseItem(item);
CurrentItemIndex++; CurrentItemIndex++;
} }
@ -445,16 +438,13 @@ void ScrollSmithPremiumBuy(int boughtitems)
boughtitems--; boughtitems--;
} }
ScrollVendorStore(PremiumItems, static_cast<int>(std::size(PremiumItems)), idx); ScrollVendorStore(PremiumItems, static_cast<int>(PremiumItems.size()), idx);
} }
bool StartSmithPremiumBuy() bool StartSmithPremiumBuy()
{ {
CurrentItemIndex = 0; CurrentItemIndex = 0;
for (Item &item : PremiumItems) { for (Item &item : PremiumItems) {
if (item.isEmpty())
continue;
item._iStatFlag = MyPlayer->CanUseItem(item); item._iStatFlag = MyPlayer->CanUseItem(item);
CurrentItemIndex++; CurrentItemIndex++;
} }
@ -695,7 +685,7 @@ void StartWitch()
void ScrollWitchBuy(int idx) void ScrollWitchBuy(int idx)
{ {
ScrollVendorStore(WitchItems, static_cast<int>(std::size(WitchItems)), idx); ScrollVendorStore(WitchItems, static_cast<int>(WitchItems.size()), idx);
} }
void WitchBookLevel(Item &bookItem) void WitchBookLevel(Item &bookItem)
@ -729,9 +719,6 @@ void StartWitchBuy()
CurrentItemIndex = 0; CurrentItemIndex = 0;
for (Item &item : WitchItems) { for (Item &item : WitchItems) {
if (item.isEmpty())
continue;
WitchBookLevel(item); WitchBookLevel(item);
item._iStatFlag = MyPlayer->CanUseItem(item); item._iStatFlag = MyPlayer->CanUseItem(item);
CurrentItemIndex++; CurrentItemIndex++;
@ -1044,7 +1031,7 @@ void StartHealer()
void ScrollHealerBuy(int idx) void ScrollHealerBuy(int idx)
{ {
ScrollVendorStore(HealerItems, static_cast<int>(std::size(HealerItems)), idx); ScrollVendorStore(HealerItems, static_cast<int>(HealerItems.size()), idx);
} }
void StartHealerBuy() void StartHealerBuy()
@ -1062,9 +1049,6 @@ void StartHealerBuy()
CurrentItemIndex = 0; CurrentItemIndex = 0;
for (Item &item : HealerItems) { for (Item &item : HealerItems) {
if (item.isEmpty())
continue;
item._iStatFlag = MyPlayer->CanUseItem(item); item._iStatFlag = MyPlayer->CanUseItem(item);
CurrentItemIndex++; CurrentItemIndex++;
} }
@ -1322,14 +1306,7 @@ void SmithBuyItem(Item &item)
item._iIdentified = false; item._iIdentified = false;
StoreAutoPlace(item, true); StoreAutoPlace(item, true);
int idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4); int idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4);
if (idx == NumSmithBasicItemsHf - 1) { SmithItems.erase(SmithItems.begin() + idx);
SmithItems[NumSmithBasicItemsHf - 1].clear();
} else {
for (; !SmithItems[idx + 1].isEmpty(); idx++) {
SmithItems[idx] = std::move(SmithItems[idx + 1]);
}
SmithItems[idx].clear();
}
CalcPlrInv(*MyPlayer, true); CalcPlrInv(*MyPlayer, true);
} }
@ -1371,17 +1348,7 @@ void SmithBuyPItem(Item &item)
StoreAutoPlace(item, true); StoreAutoPlace(item, true);
int idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4); int idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4);
int xx = 0; ReplacePremium(*MyPlayer, idx);
for (int i = 0; idx >= 0; i++) {
if (!PremiumItems[i].isEmpty()) {
idx--;
xx = i;
}
}
PremiumItems[xx].clear();
PremiumItemCount--;
SpawnPremium(*MyPlayer);
} }
void SmithPremiumBuyEnter() void SmithPremiumBuyEnter()
@ -1396,14 +1363,7 @@ void SmithPremiumBuyEnter()
OldTextLine = CurrentTextLine; OldTextLine = CurrentTextLine;
OldScrollPos = ScrollPos; OldScrollPos = ScrollPos;
int xx = ScrollPos + ((CurrentTextLine - PreviousScrollPos) / 4); int idx = ScrollPos + ((CurrentTextLine - PreviousScrollPos) / 4);
int idx = 0;
for (int i = 0; xx >= 0; i++) {
if (!PremiumItems[i].isEmpty()) {
xx--;
idx = i;
}
}
if (!PlayerCanAfford(PremiumItems[idx]._iIvalue)) { if (!PlayerCanAfford(PremiumItems[idx]._iIvalue)) {
StartStore(TalkID::NoMoney); StartStore(TalkID::NoMoney);
@ -1574,14 +1534,7 @@ void WitchBuyItem(Item &item)
StoreAutoPlace(item, true); StoreAutoPlace(item, true);
if (idx >= 3) { if (idx >= 3) {
if (idx == NumWitchItemsHf - 1) { WitchItems.erase(WitchItems.begin() + idx);
WitchItems[NumWitchItemsHf - 1].clear();
} else {
for (; !WitchItems[idx + 1].isEmpty(); idx++) {
WitchItems[idx] = std::move(WitchItems[idx + 1]);
}
WitchItems[idx].clear();
}
} }
CalcPlrInv(*MyPlayer, true); CalcPlrInv(*MyPlayer, true);
@ -1747,14 +1700,7 @@ void HealerBuyItem(Item &item)
return; return;
} }
idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4); idx = OldScrollPos + ((OldTextLine - PreviousScrollPos) / 4);
if (idx == 19) { HealerItems.erase(HealerItems.begin() + idx);
HealerItems[19].clear();
} else {
for (; !HealerItems[idx + 1].isEmpty(); idx++) {
HealerItems[idx] = std::move(HealerItems[idx + 1]);
}
HealerItems[idx].clear();
}
CalcPlrInv(*MyPlayer, true); CalcPlrInv(*MyPlayer, true);
} }
@ -2121,8 +2067,10 @@ void InitStores()
PremiumItemCount = 0; PremiumItemCount = 0;
PremiumItemLevel = 1; PremiumItemLevel = 1;
for (auto &premiumitem : PremiumItems) SmithItems.clear();
premiumitem.clear(); WitchItems.clear();
HealerItems.clear();
PremiumItems.clear();
BoyItem.clear(); BoyItem.clear();
BoyItemLevel = 0; BoyItemLevel = 0;
@ -2271,12 +2219,7 @@ void StartStore(TalkID s)
StartSmith(); StartSmith();
break; break;
case TalkID::SmithBuy: { case TalkID::SmithBuy: {
bool hasAnyItems = false; if (!SmithItems.empty())
for (int i = 0; !SmithItems[i].isEmpty(); i++) {
hasAnyItems = true;
break;
}
if (hasAnyItems)
StartSmithBuy(); StartSmithBuy();
else { else {
ActiveStore = TalkID::SmithBuy; ActiveStore = TalkID::SmithBuy;

9
Source/stores.h

@ -14,6 +14,7 @@
#include "engine/surface.hpp" #include "engine/surface.hpp"
#include "game_mode.hpp" #include "game_mode.hpp"
#include "utils/attributes.h" #include "utils/attributes.h"
#include "utils/static_vector.hpp"
namespace devilution { namespace devilution {
@ -72,19 +73,19 @@ extern int8_t PlayerItemIndexes[48];
extern DVL_API_FOR_TEST Item PlayerItems[48]; extern DVL_API_FOR_TEST Item PlayerItems[48];
/** Items sold by Griswold */ /** Items sold by Griswold */
extern DVL_API_FOR_TEST Item SmithItems[NumSmithBasicItemsHf]; extern DVL_API_FOR_TEST StaticVector<Item, NumSmithBasicItemsHf> SmithItems;
/** Number of premium items for sale by Griswold */ /** Number of premium items for sale by Griswold */
extern DVL_API_FOR_TEST int PremiumItemCount; extern DVL_API_FOR_TEST int PremiumItemCount;
/** Base level of current premium items sold by Griswold */ /** Base level of current premium items sold by Griswold */
extern DVL_API_FOR_TEST int PremiumItemLevel; extern DVL_API_FOR_TEST int PremiumItemLevel;
/** Premium items sold by Griswold */ /** Premium items sold by Griswold */
extern DVL_API_FOR_TEST Item PremiumItems[NumSmithItemsHf]; extern DVL_API_FOR_TEST StaticVector<Item, NumSmithItemsHf> PremiumItems;
/** Items sold by Pepin */ /** Items sold by Pepin */
extern DVL_API_FOR_TEST Item HealerItems[20]; extern DVL_API_FOR_TEST StaticVector<Item, NumHealerItemsHf> HealerItems;
/** Items sold by Adria */ /** Items sold by Adria */
extern DVL_API_FOR_TEST Item WitchItems[NumWitchItemsHf]; extern DVL_API_FOR_TEST StaticVector<Item, NumWitchItemsHf> WitchItems;
/** Current level of the item sold by Wirt */ /** Current level of the item sold by Wirt */
extern int BoyItemLevel; extern int BoyItemLevel;

316
test/vendor_test.cpp

@ -81,6 +81,7 @@ public:
Players.resize(1); Players.resize(1);
MyPlayer = &Players[0]; MyPlayer = &Players[0];
gbIsHellfire = false; gbIsHellfire = false;
PremiumItemLevel = 1;
CreatePlayer(*MyPlayer, HeroClass::Warrior); CreatePlayer(*MyPlayer, HeroClass::Warrior);
SetRndSeed(SEED); SetRndSeed(SEED);
} }
@ -149,62 +150,45 @@ std::string misctype_str(item_misc_id type)
TEST_F(VendorTest, SmithGen) TEST_F(VendorTest, SmithGen)
{ {
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
SmithItems.clear();
// Clear global state for test, and force Diablo game mode
for (int i = 0; i < NumSmithBasicItemsHf; i++) {
SmithItems[i].clear();
}
gbIsHellfire = false;
SpawnSmith(16); SpawnSmith(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_ITEMS = RandomIntBetween(10, NumSmithBasicItems); const int N_ITEMS = RandomIntBetween(10, NumSmithBasicItems);
int n_items = 0; EXPECT_EQ(SmithItems.size(), N_ITEMS);
EXPECT_LE(SmithItems.size(), NumSmithBasicItems);
for (int i = 0; i < NumSmithBasicItems; i++) { for (size_t i = 0; i < SmithItems.size(); i++) {
if (SmithItems[i].isEmpty()) break;
EXPECT_THAT(SmithItems[i]._itype, SmithTypeMatch(i)); EXPECT_THAT(SmithItems[i]._itype, SmithTypeMatch(i));
n_items++;
} }
EXPECT_EQ(n_items, N_ITEMS);
} }
TEST_F(VendorTest, SmithGenHf) TEST_F(VendorTest, SmithGenHf)
{ {
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
SmithItems.clear();
// Clear global state for test, and force Hellfire game mode
for (int i = 0; i < NumSmithBasicItemsHf; i++) {
SmithItems[i].clear();
}
gbIsHellfire = true; gbIsHellfire = true;
SpawnSmith(16); SpawnSmith(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_ITEMS = RandomIntBetween(10, NumSmithBasicItemsHf); const int N_ITEMS = RandomIntBetween(10, NumSmithBasicItemsHf);
int n_items = 0; EXPECT_EQ(SmithItems.size(), N_ITEMS);
EXPECT_LE(SmithItems.size(), NumSmithBasicItemsHf);
for (int i = 0; i < NumSmithBasicItemsHf; i++) { for (size_t i = 0; i < SmithItems.size(); i++) {
if (SmithItems[i].isEmpty()) break;
EXPECT_THAT(SmithItems[i]._itype, SmithTypeMatchHf(i)); EXPECT_THAT(SmithItems[i]._itype, SmithTypeMatchHf(i));
n_items++;
} }
EXPECT_EQ(n_items, N_ITEMS);
} }
TEST_F(VendorTest, PremiumQlvl1to5) TEST_F(VendorTest, PremiumQlvl1to5)
{ {
for (int i = 0; i < NumSmithItems; i++) { // Test starting the game as a level 1 character
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
// Test level 1 character item qlvl
MyPlayer->setCharacterLevel(1); MyPlayer->setCharacterLevel(1);
PremiumItems.clear();
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 1, 1, 1, 1, 2, 3 }; constexpr int QLVLS[] = { 1, 1, 1, 1, 2, 3 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
@ -213,7 +197,9 @@ TEST_F(VendorTest, PremiumQlvl1to5)
// Test level ups // Test level ups
MyPlayer->setCharacterLevel(5); MyPlayer->setCharacterLevel(5);
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 4, 4, 5, 5, 6, 7 }; constexpr int QLVLS[] = { 4, 4, 5, 5, 6, 7 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
@ -224,26 +210,24 @@ TEST_F(VendorTest, PremiumQlvl25)
{ {
constexpr int QLVLS[] = { 24, 24, 25, 25, 26, 27 }; constexpr int QLVLS[] = { 24, 24, 25, 25, 26, 27 };
for (int i = 0; i < NumSmithItems; i++) { // Test starting the game as a level 25 character
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
// Test starting game as a level 25 character
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
PremiumItems.clear();
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[3].clear(); ReplacePremium(*MyPlayer, 3);
PremiumItems[5].clear(); ReplacePremium(*MyPlayer, 5);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItems);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -253,26 +237,24 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
{ {
constexpr int QLVLS[] = { 30, 30, 30, 30, 30, 30 }; constexpr int QLVLS[] = { 30, 30, 30, 30, 30, 30 };
for (int i = 0; i < NumSmithItems; i++) {
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
// Finally test level 30+ characters // Finally test level 30+ characters
MyPlayer->setCharacterLevel(31); MyPlayer->setCharacterLevel(31);
PremiumItems.clear();
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[3].clear(); ReplacePremium(*MyPlayer, 3);
PremiumItems[5].clear(); ReplacePremium(*MyPlayer, 5);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItems);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -280,18 +262,20 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
// Test 30+ levelling // Test 30+ levelling
MyPlayer->setCharacterLevel(35); MyPlayer->setCharacterLevel(35);
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[3].clear(); ReplacePremium(*MyPlayer, 3);
PremiumItems[5].clear(); ReplacePremium(*MyPlayer, 5);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItems);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -299,16 +283,14 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
TEST_F(VendorTest, HfPremiumQlvl1to5) TEST_F(VendorTest, HfPremiumQlvl1to5)
{ {
for (int i = 0; i < NumSmithItemsHf; i++) {
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
gbIsHellfire = true;
// Test level 1 character item qlvl // Test level 1 character item qlvl
MyPlayer->setCharacterLevel(1); MyPlayer->setCharacterLevel(1);
PremiumItems.clear();
gbIsHellfire = true;
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4 }; constexpr int QLVLS[] = { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
@ -317,7 +299,9 @@ TEST_F(VendorTest, HfPremiumQlvl1to5)
// Test level ups // Test level ups
MyPlayer->setCharacterLevel(5); MyPlayer->setCharacterLevel(5);
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8 }; constexpr int QLVLS[] = { 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
@ -326,28 +310,26 @@ TEST_F(VendorTest, HfPremiumQlvl1to5)
TEST_F(VendorTest, HfPremiumQlvl25) TEST_F(VendorTest, HfPremiumQlvl25)
{ {
for (int i = 0; i < NumSmithItemsHf; i++) {
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
gbIsHellfire = true;
// Test starting game as a level 25 character // Test starting game as a level 25 character
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
PremiumItems.clear();
gbIsHellfire = true;
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 28 }; constexpr int QLVLS[] = { 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 28 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[7].clear(); ReplacePremium(*MyPlayer, 7);
PremiumItems[14].clear(); ReplacePremium(*MyPlayer, 14);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 24, 23, 23, 24, 24, 24, 25, 26, 25, 26, 26, 26, 27, 27, 28 }; constexpr int QLVLS[] = { 24, 23, 23, 24, 24, 24, 25, 26, 25, 26, 26, 26, 27, 27, 28 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
@ -356,28 +338,26 @@ TEST_F(VendorTest, HfPremiumQlvl25)
TEST_F(VendorTest, HfPremiumQlvl30Plus) TEST_F(VendorTest, HfPremiumQlvl30Plus)
{ {
for (int i = 0; i < NumSmithItemsHf; i++) {
PremiumItems[i].clear();
}
PremiumItemLevel = 1;
gbIsHellfire = true;
// Finally test level 30+ characters // Finally test level 30+ characters
MyPlayer->setCharacterLevel(31); MyPlayer->setCharacterLevel(31);
PremiumItems.clear();
gbIsHellfire = true;
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }; constexpr int QLVLS[] = { 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[7].clear(); ReplacePremium(*MyPlayer, 7);
PremiumItems[14].clear(); ReplacePremium(*MyPlayer, 14);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItemsHf; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
constexpr int QLVLS[] = { 30, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }; constexpr int QLVLS[] = { 30, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 };
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
@ -388,18 +368,20 @@ TEST_F(VendorTest, HfPremiumQlvl30Plus)
// Test 30+ levelling // Test 30+ levelling
MyPlayer->setCharacterLevel(35); MyPlayer->setCharacterLevel(35);
SpawnPremium(*MyPlayer); SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
// Test buying select items // Test buying select items
PremiumItems[0].clear(); ReplacePremium(*MyPlayer, 0);
PremiumItems[7].clear(); ReplacePremium(*MyPlayer, 7);
PremiumItems[14].clear(); ReplacePremium(*MyPlayer, 14);
PremiumItemCount -= 3; EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
SpawnPremium(*MyPlayer);
for (int i = 0; i < NumSmithItems; i++) { for (size_t i = 0; i < PremiumItems.size(); i++) {
EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i; EXPECT_EQ(PremiumItems[i]._iCreateInfo & CF_LEVEL, QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -410,34 +392,24 @@ TEST_F(VendorTest, WitchGen)
constexpr _item_indexes PINNED_ITEMS[] = { IDI_MANA, IDI_FULLMANA, IDI_PORTAL }; constexpr _item_indexes PINNED_ITEMS[] = { IDI_MANA, IDI_FULLMANA, IDI_PORTAL };
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
WitchItems.clear();
// Clear global state for test, and force Diablo game mode
for (int i = 0; i < NumWitchItemsHf; i++) {
WitchItems[i].clear();
}
gbIsHellfire = false;
SpawnWitch(16); SpawnWitch(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_ITEMS = RandomIntBetween(10, NumWitchItems); const int N_ITEMS = RandomIntBetween(10, NumWitchItems);
EXPECT_EQ(WitchItems.size(), N_ITEMS);
int n_items = NumWitchPinnedItems; EXPECT_LE(WitchItems.size(), NumWitchItems);
for (int i = 0; i < NumWitchPinnedItems; i++) { for (size_t i = 0; i < WitchItems.size(); i++) {
EXPECT_EQ(WitchItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i; if (i < NumWitchPinnedItems) {
} EXPECT_EQ(WitchItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i;
} else {
for (int i = NumWitchPinnedItems; i < NumWitchItems; i++) { EXPECT_THAT(WitchItems[i]._itype, WitchTypeMatch(i));
if (WitchItems[i].isEmpty()) break; if (WitchItems[i]._itype == ItemType::Misc) {
EXPECT_THAT(WitchItems[i]._itype, WitchTypeMatch(i)); EXPECT_THAT(WitchItems[i]._iMiscId, WitchMiscMatch(i));
}
if (WitchItems[i]._itype == ItemType::Misc) {
EXPECT_THAT(WitchItems[i]._iMiscId, WitchMiscMatch(i));
} }
n_items++;
} }
EXPECT_EQ(n_items, N_ITEMS);
} }
TEST_F(VendorTest, WitchGenHf) TEST_F(VendorTest, WitchGenHf)
@ -446,38 +418,29 @@ TEST_F(VendorTest, WitchGenHf)
constexpr int MAX_PINNED_BOOKS = 4; constexpr int MAX_PINNED_BOOKS = 4;
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
WitchItems.clear();
gbIsHellfire = true; gbIsHellfire = true;
// Clear global state for test, and force Hellfire game mode
for (int i = 0; i < NumWitchItemsHf; i++) {
WitchItems[i].clear();
}
SpawnWitch(16); SpawnWitch(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_PINNED_BOOKS = RandomIntLessThan(MAX_PINNED_BOOKS); const int N_PINNED_BOOKS = RandomIntLessThan(MAX_PINNED_BOOKS);
const int N_ITEMS = RandomIntBetween(10, NumWitchItemsHf); const int N_ITEMS = RandomIntBetween(10, NumWitchItemsHf);
EXPECT_EQ(WitchItems.size(), N_ITEMS);
EXPECT_LE(WitchItems.size(), NumWitchItemsHf);
int n_books = 0; int n_books = 0;
int n_items = NumWitchPinnedItems; for (size_t i = 0; i < WitchItems.size(); i++) {
if (i < NumWitchPinnedItems) {
for (int i = 0; i < NumWitchPinnedItems; i++) { EXPECT_EQ(WitchItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i;
EXPECT_EQ(WitchItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i; } else {
} EXPECT_THAT(WitchItems[i]._itype, WitchTypeMatch(i));
if (WitchItems[i]._itype == ItemType::Misc) {
for (int i = NumWitchPinnedItems; i < NumWitchItemsHf; i++) { EXPECT_THAT(WitchItems[i]._iMiscId, WitchMiscMatch(i));
if (WitchItems[i].isEmpty()) break; }
EXPECT_THAT(WitchItems[i]._itype, WitchTypeMatch(i)); if (WitchItems[i]._iMiscId == IMISC_BOOK) n_books++;
if (WitchItems[i]._itype == ItemType::Misc) {
EXPECT_THAT(WitchItems[i]._iMiscId, WitchMiscMatch(i));
} }
if (WitchItems[i]._iMiscId == IMISC_BOOK) n_books++;
n_items++;
} }
EXPECT_GE(n_books, N_PINNED_BOOKS); EXPECT_GE(n_books, N_PINNED_BOOKS);
EXPECT_EQ(n_items, N_ITEMS);
} }
TEST_F(VendorTest, HealerGen) TEST_F(VendorTest, HealerGen)
@ -485,30 +448,22 @@ TEST_F(VendorTest, HealerGen)
constexpr _item_indexes PINNED_ITEMS[] = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT }; constexpr _item_indexes PINNED_ITEMS[] = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT };
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
HealerItems.clear();
// Clear global state for test, and force Diablo game mode
for (int i = 0; i < NumHealerItemsHf; i++) {
HealerItems[i].clear();
}
gbIsHellfire = false;
SpawnHealer(16); SpawnHealer(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_ITEMS = RandomIntBetween(10, NumHealerItems); const int N_ITEMS = RandomIntBetween(10, NumHealerItems);
int n_items = NumHealerPinnedItems; EXPECT_EQ(HealerItems.size(), N_ITEMS);
EXPECT_LE(HealerItems.size(), NumHealerItems);
for (int i = 0; i < NumHealerPinnedItems; i++) {
EXPECT_EQ(HealerItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i; for (size_t i = 0; i < HealerItems.size(); i++) {
} if (i < NumHealerPinnedItems) {
EXPECT_EQ(HealerItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i;
for (int i = NumHealerPinnedItems; i < NumHealerItems; i++) { } else {
if (HealerItems[i].isEmpty()) break; EXPECT_THAT(HealerItems[i]._itype, Eq(ItemType::Misc));
EXPECT_THAT(HealerItems[i]._itype, Eq(ItemType::Misc)); EXPECT_THAT(HealerItems[i]._iMiscId, HealerMiscMatch(i));
EXPECT_THAT(HealerItems[i]._iMiscId, HealerMiscMatch(i)); }
n_items++;
} }
EXPECT_EQ(n_items, N_ITEMS);
} }
TEST_F(VendorTest, HealerGenHf) TEST_F(VendorTest, HealerGenHf)
@ -516,30 +471,23 @@ TEST_F(VendorTest, HealerGenHf)
constexpr _item_indexes PINNED_ITEMS[] = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT }; constexpr _item_indexes PINNED_ITEMS[] = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT };
MyPlayer->setCharacterLevel(25); MyPlayer->setCharacterLevel(25);
HealerItems.clear();
// Clear global state for test, and force Hellfire game mode
for (int i = 0; i < NumHealerItemsHf; i++) {
HealerItems[i].clear();
}
gbIsHellfire = true; gbIsHellfire = true;
SpawnHealer(16); SpawnHealer(16);
SetRndSeed(SEED); SetRndSeed(SEED);
const int N_ITEMS = RandomIntBetween(10, NumHealerItemsHf); const int N_ITEMS = RandomIntBetween(10, NumHealerItemsHf);
int n_items = NumHealerPinnedItems; EXPECT_EQ(HealerItems.size(), N_ITEMS);
EXPECT_LE(HealerItems.size(), NumHealerItemsHf);
for (int i = 0; i < NumHealerPinnedItems; i++) {
EXPECT_EQ(HealerItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i; for (size_t i = 0; i < HealerItems.size(); i++) {
} if (i < NumHealerPinnedItems) {
EXPECT_EQ(HealerItems[i].IDidx, PINNED_ITEMS[i]) << "Index: " << i;
for (int i = NumHealerPinnedItems; i < NumHealerItemsHf; i++) { } else {
if (HealerItems[i].isEmpty()) break; EXPECT_THAT(HealerItems[i]._itype, Eq(ItemType::Misc));
EXPECT_THAT(HealerItems[i]._itype, Eq(ItemType::Misc)); EXPECT_THAT(HealerItems[i]._iMiscId, HealerMiscMatch(i));
EXPECT_THAT(HealerItems[i]._iMiscId, HealerMiscMatch(i)); }
n_items++;
} }
EXPECT_EQ(n_items, N_ITEMS);
} }
} // namespace } // namespace

Loading…
Cancel
Save