Browse Source

Merge 8ac618dfcf into 5a08031caf

pull/8306/merge
Eric Robinson 4 days ago committed by GitHub
parent
commit
c5cae82610
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      Source/inv.cpp
  2. 86
      Source/items.cpp
  3. 74
      Source/items.h
  4. 25
      Source/items/validation.cpp
  5. 12
      Source/loadsave.cpp
  6. 24
      Source/lua/modules/dev/items.cpp
  7. 4
      Source/lua/modules/items.cpp
  8. 10
      Source/msg.cpp
  9. 10
      Source/pack.cpp
  10. 5
      Source/player.cpp
  11. 4
      Source/sync.cpp
  12. 60
      test/pack_test.cpp
  13. 32
      test/vendor_test.cpp

4
Source/inv.cpp

@ -1669,7 +1669,7 @@ void InvGetItem(Player &player, int ii)
if (dItem[item.position.x][item.position.y] == 0) if (dItem[item.position.x][item.position.y] == 0)
return; return;
item._iCreateInfo &= ~CF_PREGEN; item.clearCreationFlag(CF_PREGEN);
CheckQuestItem(player, item); CheckQuestItem(player, item);
item.updateRequiredStatsCacheForPlayer(player); item.updateRequiredStatsCacheForPlayer(player);
@ -1740,7 +1740,7 @@ void AutoGetItem(Player &player, Item *itemPointer, int ii)
if (dItem[item.position.x][item.position.y] == 0) if (dItem[item.position.x][item.position.y] == 0)
return; return;
item._iCreateInfo &= ~CF_PREGEN; item.clearCreationFlag(CF_PREGEN);
CheckQuestItem(player, item); CheckQuestItem(player, item);
item.updateRequiredStatsCacheForPlayer(player); item.updateRequiredStatsCacheForPlayer(player);

86
Source/items.cpp

@ -468,7 +468,7 @@ void AddInitItems()
GetItemAttrs(item, PickRandomlyAmong({ IDI_MANA, IDI_HEAL }), curlv); GetItemAttrs(item, PickRandomlyAmong({ IDI_MANA, IDI_HEAL }), curlv);
item._iCreateInfo = curlv | CF_PREGEN; item.setAllCreationFlags(curlv | CF_PREGEN);
SetupItem(item); SetupItem(item);
item.AnimInfo.currentFrame = static_cast<int8_t>(item.AnimInfo.numberOfFrames - 1); item.AnimInfo.currentFrame = static_cast<int8_t>(item.AnimInfo.numberOfFrames - 1);
item._iAnimFlag = false; item._iAnimFlag = false;
@ -1471,7 +1471,7 @@ void GetUniqueItem(const Player &player, Item &item, _unique_items uid)
item._iUid = uid; item._iUid = uid;
item._iMagical = ITEM_QUALITY_UNIQUE; item._iMagical = ITEM_QUALITY_UNIQUE;
item._iCreateInfo |= CF_UNIQUE; item.setCreationFlag(CF_UNIQUE);
} }
void ItemRndDur(Item &item) void ItemRndDur(Item &item)
@ -1555,7 +1555,7 @@ void SetupAllUseful(Item &item, int iseed, int lvl)
} }
GetItemAttrs(item, idx, lvl); GetItemAttrs(item, idx, lvl);
item._iCreateInfo = lvl | CF_USEFUL; item.setAllCreationFlags(lvl | CF_USEFUL);
SetupItem(item); SetupItem(item);
} }
@ -1604,7 +1604,7 @@ void SpawnRock()
item._iPostDraw = true; item._iPostDraw = true;
item.AnimInfo.currentFrame = 10; item.AnimInfo.currentFrame = 10;
item._iAnimFlag = true; item._iAnimFlag = true;
item._iCreateInfo |= CF_PREGEN; item.setCreationFlag(CF_PREGEN);
DeltaAddItem(ii); DeltaAddItem(ii);
} }
@ -2004,7 +2004,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player)
} }
} }
} }
premiumItem._iCreateInfo = plvl | CF_SMITHPREMIUM; premiumItem.setAllCreationFlags(plvl | CF_SMITHPREMIUM);
premiumItem._iIdentified = true; premiumItem._iIdentified = true;
premiumItem._iStatFlag = player.CanUseItem(premiumItem); premiumItem._iStatFlag = player.CanUseItem(premiumItem);
} }
@ -2084,7 +2084,7 @@ void RecreateSmithItem(const Player &player, Item &item, int lvl, int iseed)
GetItemAttrs(item, itype, lvl); GetItemAttrs(item, itype, lvl);
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = lvl | CF_SMITH; item.setAllCreationFlags(lvl | CF_SMITH);
item._iIdentified = true; item._iIdentified = true;
} }
@ -2096,7 +2096,7 @@ void RecreatePremiumItem(const Player &player, Item &item, int plvl, int iseed)
GetItemBonus(player, item, plvl / 2, plvl, true, !gbIsHellfire); GetItemBonus(player, item, plvl / 2, plvl, true, !gbIsHellfire);
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = plvl | CF_SMITHPREMIUM; item.setAllCreationFlags(plvl | CF_SMITHPREMIUM);
item._iIdentified = true; item._iIdentified = true;
} }
@ -2108,7 +2108,7 @@ void RecreateBoyItem(const Player &player, Item &item, int lvl, int iseed)
GetItemBonus(player, item, lvl, 2 * lvl, true, true); GetItemBonus(player, item, lvl, 2 * lvl, true, true);
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = lvl | CF_BOY; item.setAllCreationFlags(lvl | CF_BOY);
item._iIdentified = true; item._iIdentified = true;
} }
@ -2134,7 +2134,7 @@ void RecreateWitchItem(const Player &player, Item &item, _item_indexes idx, int
} }
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = lvl | CF_WITCH; item.setAllCreationFlags(lvl | CF_WITCH);
item._iIdentified = true; item._iIdentified = true;
} }
@ -2149,7 +2149,7 @@ void RecreateHealerItem(const Player &player, Item &item, _item_indexes idx, int
} }
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = lvl | CF_HEALER; item.setAllCreationFlags(lvl | CF_HEALER);
item._iIdentified = true; item._iIdentified = true;
} }
@ -2214,7 +2214,7 @@ StringOrView GetTranslatedItemName(const Item &item)
{ {
const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)]; const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)];
if (item._iCreateInfo == 0) { if (item.getAllCreationFlags() == 0) {
return _(baseItemData.iName); return _(baseItemData.iName);
} }
if (item._iMiscId == IMISC_BOOK) { if (item._iMiscId == IMISC_BOOK) {
@ -2243,23 +2243,23 @@ std::string GetTranslatedItemNameMagical(const Item &item, bool hellfireItem, bo
std::string identifiedName; std::string identifiedName;
const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)]; const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)];
const int lvl = item._iCreateInfo & CF_LEVEL; const int lvl = item.getItemLevel();
const bool onlygood = (item._iCreateInfo & (CF_ONLYGOOD | CF_SMITHPREMIUM | CF_BOY | CF_WITCH)) != 0; const bool onlygood = item.hasCreationFlag(CF_ONLYGOOD | CF_SMITHPREMIUM | CF_BOY | CF_WITCH);
const uint32_t currentSeed = GetLCGEngineState(); const uint32_t currentSeed = GetLCGEngineState();
SetRndSeed(item._iSeed); SetRndSeed(item._iSeed);
int minlvl; int minlvl;
int maxlvl; int maxlvl;
if ((item._iCreateInfo & CF_SMITHPREMIUM) != 0) { if (item.hasCreationFlag(CF_SMITHPREMIUM)) {
DiscardRandomValues(2); // RndVendorItem and GetItemAttrs DiscardRandomValues(2); // RndVendorItem and GetItemAttrs
minlvl = lvl / 2; minlvl = lvl / 2;
maxlvl = lvl; maxlvl = lvl;
} else if ((item._iCreateInfo & CF_BOY) != 0) { } else if (item.hasCreationFlag(CF_BOY)) {
DiscardRandomValues(2); // RndVendorItem and GetItemAttrs DiscardRandomValues(2); // RndVendorItem and GetItemAttrs
minlvl = lvl; minlvl = lvl;
maxlvl = lvl * 2; maxlvl = lvl * 2;
} else if ((item._iCreateInfo & CF_WITCH) != 0) { } else if (item.hasCreationFlag(CF_WITCH)) {
DiscardRandomValues(2); // RndVendorItem and GetItemAttrs DiscardRandomValues(2); // RndVendorItem and GetItemAttrs
int iblvl = -1; int iblvl = -1;
if (GenerateRnd(100) <= 5) if (GenerateRnd(100) <= 5)
@ -2270,7 +2270,7 @@ std::string GetTranslatedItemNameMagical(const Item &item, bool hellfireItem, bo
maxlvl = iblvl; maxlvl = iblvl;
} else { } else {
DiscardRandomValues(1); // GetItemAttrs DiscardRandomValues(1); // GetItemAttrs
const int iblvl = GetItemBLevel(lvl, item._iMiscId, onlygood, (item._iCreateInfo & CF_UPER15) != 0); const int iblvl = GetItemBLevel(lvl, item._iMiscId, onlygood, item.hasCreationFlag(CF_UPER15));
minlvl = iblvl / 2; minlvl = iblvl / 2;
maxlvl = iblvl; maxlvl = iblvl;
DiscardRandomValues(1); // CheckUnique DiscardRandomValues(1); // CheckUnique
@ -2299,7 +2299,7 @@ std::string GetTranslatedItemNameMagical(const Item &item, bool hellfireItem, bo
affixItemType = AffixItemType::Armor; affixItemType = AffixItemType::Armor;
break; break;
case ItemType::Staff: { case ItemType::Staff: {
const bool allowspells = !hellfireItem || ((item._iCreateInfo & CF_SMITHPREMIUM) == 0); const bool allowspells = !hellfireItem || !item.hasCreationFlag(CF_SMITHPREMIUM);
if (!allowspells) if (!allowspells)
affixItemType = AffixItemType::Staff; affixItemType = AffixItemType::Staff;
@ -2950,7 +2950,7 @@ void InitializeItem(Item &item, _item_indexes itemData)
item._iMagical = ITEM_QUALITY_NORMAL; item._iMagical = ITEM_QUALITY_NORMAL;
item.IDidx = itemData; item.IDidx = itemData;
if (gbIsHellfire) if (gbIsHellfire)
item.dwBuff |= CF_HELLFIRE; item.setCreationFlag2(CF_HELLFIRE);
} }
void GenerateNewSeed(Item &item) void GenerateNewSeed(Item &item)
@ -3139,7 +3139,7 @@ void GetItemAttrs(Item &item, _item_indexes itemData, int lvl)
item._iMinDex = baseItemData.iMinDex; item._iMinDex = baseItemData.iMinDex;
item.IDidx = itemData; item.IDidx = itemData;
if (gbIsHellfire) if (gbIsHellfire)
item.dwBuff |= CF_HELLFIRE; item.setCreationFlag2(CF_HELLFIRE);
item._iPrePower = IPL_INVALID; item._iPrePower = IPL_INVALID;
item._iSufPower = IPL_INVALID; item._iSufPower = IPL_INVALID;
@ -3257,17 +3257,17 @@ void SetupAllItems(const Player &player, Item &item, _item_indexes idx, uint32_t
item._iSeed = iseed; item._iSeed = iseed;
SetRndSeed(iseed); SetRndSeed(iseed);
GetItemAttrs(item, idx, lvl / 2); GetItemAttrs(item, idx, lvl / 2);
item._iCreateInfo = lvl; item.setAllCreationFlags(lvl);
if (pregen) if (pregen)
item._iCreateInfo |= CF_PREGEN; item.setCreationFlag(CF_PREGEN);
if (onlygood) if (onlygood)
item._iCreateInfo |= CF_ONLYGOOD; item.setCreationFlag(CF_ONLYGOOD);
if (uper == 15) if (uper == 15)
item._iCreateInfo |= CF_UPER15; item.setCreationFlag(CF_UPER15);
else if (uper == 1) else if (uper == 1)
item._iCreateInfo |= CF_UPER1; item.setCreationFlag(CF_UPER1);
if (item._iMiscId != IMISC_UNIQUE) { if (item._iMiscId != IMISC_UNIQUE) {
const int iblvl = GetItemBLevel(lvl, item._iMiscId, onlygood, uper == 15); const int iblvl = GetItemBLevel(lvl, item._iMiscId, onlygood, uper == 15);
@ -3301,7 +3301,7 @@ void SetupAllItems(const Player &player, Item &item, _item_indexes idx, uint32_t
void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, bool onlygood, bool pregen) void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper, bool onlygood, bool pregen)
{ {
// If the item is a non-quest unique, find a random valid uid and force generate items to get an item with that uid. // If the item is a non-quest unique, find a random valid uid and force generate items to get an item with that uid.
if ((item._iCreateInfo & CF_UNIQUE) == 0 || item._iMiscId == IMISC_UNIQUE) if (!item.hasCreationFlag(CF_UNIQUE) || item._iMiscId == IMISC_UNIQUE)
return; return;
SetRndSeed(item._iSeed); SetRndSeed(item._iSeed);
@ -3395,7 +3395,7 @@ void TryRandomUniqueItem(Item &item, _item_indexes idx, int8_t mLevel, int uper,
item = {}; // Reset item data item = {}; // Reset item data
item.position = itemPos; item.position = itemPos;
SetupAllItems(*MyPlayer, item, idx, seed, mLevel, uper, onlygood, pregen, uidOffset); SetupAllItems(*MyPlayer, item, idx, seed, mLevel, uper, onlygood, pregen, uidOffset);
item.dwBuff |= (uidOffset << 1) & CF_UIDOFFSET; item.setCreationFlag2((uidOffset << 1) & CF_UIDOFFSET);
assert(item._iUid == uid); assert(item._iUid == uid);
} }
@ -3504,13 +3504,13 @@ void CreateTypeItem(Point position, bool onlygood, ItemType itemType, int imisc,
void RecreateItem(const Player &player, Item &item, _item_indexes idx, uint16_t icreateinfo, uint32_t iseed, int ivalue, uint32_t dwBuff) void RecreateItem(const Player &player, Item &item, _item_indexes idx, uint16_t icreateinfo, uint32_t iseed, int ivalue, uint32_t dwBuff)
{ {
const bool tmpIsHellfire = gbIsHellfire; const bool tmpIsHellfire = gbIsHellfire;
item.dwBuff = dwBuff; item.setAllCreationFlags2(dwBuff);
gbIsHellfire = (item.dwBuff & CF_HELLFIRE) != 0; gbIsHellfire = item.hasCreationFlag2(CF_HELLFIRE);
if (idx == IDI_GOLD) { if (idx == IDI_GOLD) {
InitializeItem(item, IDI_GOLD); InitializeItem(item, IDI_GOLD);
item._iSeed = iseed; item._iSeed = iseed;
item._iCreateInfo = icreateinfo; item.setAllCreationFlags(icreateinfo);
item._ivalue = ivalue; item._ivalue = ivalue;
SetPlrHandGoldCurs(item); SetPlrHandGoldCurs(item);
gbIsHellfire = tmpIsHellfire; gbIsHellfire = tmpIsHellfire;
@ -3549,7 +3549,7 @@ void RecreateItem(const Player &player, Item &item, _item_indexes idx, uint16_t
const bool onlygood = (icreateinfo & CF_ONLYGOOD) != 0; const bool onlygood = (icreateinfo & CF_ONLYGOOD) != 0;
const bool forceNotUnique = (icreateinfo & CF_UNIQUE) == 0; const bool forceNotUnique = (icreateinfo & CF_UNIQUE) == 0;
const bool pregen = (icreateinfo & CF_PREGEN) != 0; const bool pregen = (icreateinfo & CF_PREGEN) != 0;
auto uidOffset = static_cast<int>((item.dwBuff & CF_UIDOFFSET) >> 1); auto uidOffset = static_cast<int>((item.getAllCreationFlags2() & CF_UIDOFFSET) >> 1);
SetupAllItems(player, item, idx, iseed, level, uper, onlygood, pregen, uidOffset, forceNotUnique); SetupAllItems(player, item, idx, iseed, level, uper, onlygood, pregen, uidOffset, forceNotUnique);
SetupItem(item); SetupItem(item);
@ -3567,7 +3567,7 @@ void RecreateEar(Item &item, uint16_t ic, uint32_t iseed, uint8_t bCursval, std:
item._iCurs = ((bCursval >> 6) & 3) + ICURS_EAR_SORCERER; item._iCurs = ((bCursval >> 6) & 3) + ICURS_EAR_SORCERER;
item._ivalue = bCursval & 0x3F; item._ivalue = bCursval & 0x3F;
item._iCreateInfo = ic; item.setAllCreationFlags(ic);
item._iSeed = iseed; item._iSeed = iseed;
} }
@ -3577,7 +3577,7 @@ void CornerstoneSave()
return; return;
if (!CornerStone.item.isEmpty()) { if (!CornerStone.item.isEmpty()) {
ItemPack id; ItemPack id;
PackItem(id, CornerStone.item, (CornerStone.item.dwBuff & CF_HELLFIRE) != 0); PackItem(id, CornerStone.item, CornerStone.item.hasCreationFlag2(CF_HELLFIRE));
const auto *buffer = reinterpret_cast<uint8_t *>(&id); const auto *buffer = reinterpret_cast<uint8_t *>(&id);
for (size_t i = 0; i < sizeof(ItemPack); i++) { for (size_t i = 0; i < sizeof(ItemPack); i++) {
BufCopy(&GetOptions().Hellfire.szItem[i * 2], AsHexPad2(buffer[i], /*uppercase=*/true)); BufCopy(&GetOptions().Hellfire.szItem[i * 2], AsHexPad2(buffer[i], /*uppercase=*/true));
@ -3674,7 +3674,7 @@ void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, Selectio
if (sendmsg) if (sendmsg)
NetSendCmdPItem(true, CMD_SPAWNITEM, item.position, item); NetSendCmdPItem(true, CMD_SPAWNITEM, item.position, item);
else { else {
item._iCreateInfo |= CF_PREGEN; item.setCreationFlag(CF_PREGEN);
DeltaAddItem(ii); DeltaAddItem(ii);
} }
} }
@ -4403,7 +4403,7 @@ void SpawnSmith(int lvl)
GetItemAttrs(newItem, itemData, lvl); GetItemAttrs(newItem, itemData, lvl);
} while (newItem._iIvalue > maxValue); } while (newItem._iIvalue > maxValue);
newItem._iCreateInfo = lvl | CF_SMITH; newItem.setAllCreationFlags(lvl | CF_SMITH);
newItem._iIdentified = true; newItem._iIdentified = true;
SmithItems.push_back(newItem); SmithItems.push_back(newItem);
@ -4469,7 +4469,7 @@ void SpawnWitch(int lvl)
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.setAllCreationFlags(lvl);
item._iStatFlag = true; item._iStatFlag = true;
WitchItems.push_back(item); WitchItems.push_back(item);
continue; continue;
@ -4483,7 +4483,7 @@ void SpawnWitch(int lvl)
SetRndSeed(item._iSeed); SetRndSeed(item._iSeed);
DiscardRandomValues(1); DiscardRandomValues(1);
GetItemAttrs(item, bookType, lvl); GetItemAttrs(item, bookType, lvl);
item._iCreateInfo = lvl | CF_WITCH; item.setAllCreationFlags(lvl | CF_WITCH);
item._iIdentified = true; item._iIdentified = true;
bookCount++; bookCount++;
WitchItems.push_back(item); WitchItems.push_back(item);
@ -4507,7 +4507,7 @@ void SpawnWitch(int lvl)
GetItemBonus(*MyPlayer, item, maxlvl / 2, maxlvl, true, true); GetItemBonus(*MyPlayer, item, maxlvl / 2, maxlvl, true, true);
} while (item._iIvalue > maxValue); } while (item._iIvalue > maxValue);
item._iCreateInfo = lvl | CF_WITCH; item.setAllCreationFlags(lvl | CF_WITCH);
item._iIdentified = true; item._iIdentified = true;
WitchItems.push_back(item); WitchItems.push_back(item);
@ -4627,7 +4627,7 @@ void SpawnBoy(int lvl)
|| BoyItem._iMinDex > dexterity || BoyItem._iMinDex > dexterity
|| BoyItem._iIvalue < ivalue) || BoyItem._iIvalue < ivalue)
&& count < 250)); && count < 250));
BoyItem._iCreateInfo = lvl | CF_BOY; BoyItem.setAllCreationFlags(lvl | CF_BOY);
BoyItem._iIdentified = true; BoyItem._iIdentified = true;
BoyItemLevel = lvl / 2; BoyItemLevel = lvl / 2;
} }
@ -4645,14 +4645,14 @@ void SpawnHealer(int lvl)
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.setAllCreationFlags(lvl);
item._iStatFlag = true; item._iStatFlag = true;
} else { } else {
item._iSeed = AdvanceRndSeed(); item._iSeed = AdvanceRndSeed();
SetRndSeed(item._iSeed); SetRndSeed(item._iSeed);
const _item_indexes itype = RndHealerItem(*MyPlayer, lvl); const _item_indexes itype = RndHealerItem(*MyPlayer, lvl);
GetItemAttrs(item, itype, lvl); GetItemAttrs(item, itype, lvl);
item._iCreateInfo = lvl | CF_HEALER; item.setAllCreationFlags(lvl | CF_HEALER);
item._iIdentified = true; item._iIdentified = true;
} }
@ -5030,7 +5030,7 @@ void UpdateHellfireFlag(Item &item, const char *identifiedItemName)
// But vanilla hellfire items don't have CF_HELLFIRE set in Item::dwBuff // But vanilla hellfire items don't have CF_HELLFIRE set in Item::dwBuff
// This functions tries to set this flag for vanilla hellfire items based on the item name // This functions tries to set this flag for vanilla hellfire items based on the item name
// This ensures that Item::getName() returns the correct translated item name // This ensures that Item::getName() returns the correct translated item name
if ((item.dwBuff & CF_HELLFIRE) != 0U) if (item.hasCreationFlag2(CF_HELLFIRE))
return; // Item is already a hellfire item return; // Item is already a hellfire item
if (item._iMagical != ITEM_QUALITY_MAGIC) if (item._iMagical != ITEM_QUALITY_MAGIC)
return; // Only magic item's name can differ between diablo and hellfire return; // Only magic item's name can differ between diablo and hellfire
@ -5047,7 +5047,7 @@ void UpdateHellfireFlag(Item &item, const char *identifiedItemName)
const std::string hellfireItemNameLong = GetTranslatedItemNameMagical(item, true, false, true); const std::string hellfireItemNameLong = GetTranslatedItemNameMagical(item, true, false, true);
if (hellfireItemNameShort == identifiedItemName || hellfireItemNameLong == identifiedItemName) { if (hellfireItemNameShort == identifiedItemName || hellfireItemNameLong == identifiedItemName) {
// This item should be a vanilla hellfire item that has CF_HELLFIRE missing, cause only then the item name matches // This item should be a vanilla hellfire item that has CF_HELLFIRE missing, cause only then the item name matches
item.dwBuff |= CF_HELLFIRE; item.setCreationFlag2(CF_HELLFIRE);
} }
} }

74
Source/items.h

@ -188,7 +188,11 @@ struct Player;
struct Item { struct Item {
/** Randomly generated identifier */ /** Randomly generated identifier */
uint32_t _iSeed = 0; uint32_t _iSeed = 0;
private:
uint16_t _iCreateInfo = 0; uint16_t _iCreateInfo = 0;
public:
ItemType _itype = ItemType::None; ItemType _itype = ItemType::None;
bool _iAnimFlag = false; bool _iAnimFlag = false;
Point position = { 0, 0 }; Point position = { 0, 0 };
@ -254,8 +258,11 @@ struct Item {
int8_t _iMinDex = 0; int8_t _iMinDex = 0;
bool _iStatFlag = false; bool _iStatFlag = false;
ItemSpecialEffectHf _iDamAcFlags = ItemSpecialEffectHf::None; ItemSpecialEffectHf _iDamAcFlags = ItemSpecialEffectHf::None;
private:
uint32_t dwBuff = 0; uint32_t dwBuff = 0;
public:
/** /**
* @brief Clears this item and returns the old value * @brief Clears this item and returns the old value
*/ */
@ -466,6 +473,73 @@ struct Item {
{ {
return { -CalculateSpriteTileCenterX(sprite.width()), 0 }; return { -CalculateSpriteTileCenterX(sprite.width()), 0 };
} }
bool hasCreationFlag(uint16_t flag) const
{
return (_iCreateInfo & flag) != 0;
}
bool matchesCreationFlags(uint16_t mask, uint16_t value) const
{
return (_iCreateInfo & mask) == value;
}
void setCreationFlag(uint16_t flag)
{
_iCreateInfo |= flag;
}
void clearCreationFlag(uint16_t flag)
{
_iCreateInfo &= ~flag;
}
void setAllCreationFlags(uint16_t value)
{
_iCreateInfo = value;
}
uint16_t getAllCreationFlags() const
{
return _iCreateInfo;
}
void setItemLevel(uint8_t level)
{
std::min(level, static_cast<uint8_t>(63)); // ilvl is only a 6-bit integer
_iCreateInfo &= ~CF_LEVEL;
_iCreateInfo |= (level & CF_LEVEL);
}
int getItemLevel() const
{
return _iCreateInfo & CF_LEVEL;
}
bool hasCreationFlag2(uint16_t flag) const
{
return (dwBuff & flag) != 0;
}
void setCreationFlag2(uint16_t flag)
{
dwBuff |= flag;
}
void clearCreationFlag2(uint16_t flag)
{
dwBuff &= ~flag;
}
void setAllCreationFlags2(uint16_t value)
{
dwBuff = value;
}
uint16_t getAllCreationFlags2() const
{
return dwBuff;
}
}; };
struct ItemGetRecordStruct { struct ItemGetRecordStruct {

25
Source/items/validation.cpp

@ -63,16 +63,15 @@ bool IsTownItemValid(uint16_t iCreateInfo, const Player &player)
bool IsShopPriceValid(const Item &item) bool IsShopPriceValid(const Item &item)
{ {
const int boyPriceLimit = MaxBoyValue; const int boyPriceLimit = MaxBoyValue;
if (!gbIsHellfire && (item._iCreateInfo & CF_BOY) != 0 && item._iIvalue > boyPriceLimit) if (!gbIsHellfire && item.hasCreationFlag(CF_BOY) && item._iIvalue > boyPriceLimit)
return false; return false;
const int premiumPriceLimit = MaxVendorValue; const int premiumPriceLimit = MaxVendorValue;
if (!gbIsHellfire && (item._iCreateInfo & CF_SMITHPREMIUM) != 0 && item._iIvalue > premiumPriceLimit) if (!gbIsHellfire && item.hasCreationFlag(CF_SMITHPREMIUM) && item._iIvalue > premiumPriceLimit)
return false; return false;
const uint16_t smithOrWitch = CF_SMITH | CF_WITCH;
const int smithAndWitchPriceLimit = gbIsHellfire ? MaxVendorValueHf : MaxVendorValue; const int smithAndWitchPriceLimit = gbIsHellfire ? MaxVendorValueHf : MaxVendorValue;
if ((item._iCreateInfo & smithOrWitch) != 0 && item._iIvalue > smithAndWitchPriceLimit) if ((item.hasCreationFlag(CF_SMITH) || item.hasCreationFlag(CF_WITCH)) && item._iIvalue > smithAndWitchPriceLimit)
return false; return false;
return true; return true;
@ -150,12 +149,12 @@ bool IsHellfireSpellBookValid(const Item &spellBook)
// CreateSpellBook() adds 1 to the spell level for ilvl // CreateSpellBook() adds 1 to the spell level for ilvl
spellBookLevel++; spellBookLevel++;
if (spellBookLevel >= 1 && (spellBook._iCreateInfo & CF_LEVEL) == spellBookLevel * 2) { if (spellBookLevel >= 1 && spellBook.getItemLevel() == spellBookLevel * 2) {
// The ilvl matches the result for a spell book drop, so we confirm the item is legitimate // The ilvl matches the result for a spell book drop, so we confirm the item is legitimate
return true; return true;
} }
return IsDungeonItemValid(spellBook._iCreateInfo, spellBook.dwBuff); return IsDungeonItemValid(spellBook.getAllCreationFlags(), spellBook.getAllCreationFlags2());
} }
bool IsItemValid(const Player &player, const Item &item) bool IsItemValid(const Player &player, const Item &item)
@ -165,16 +164,16 @@ bool IsItemValid(const Player &player, const Item &item)
if (item.IDidx == IDI_EAR) if (item.IDidx == IDI_EAR)
return true; return true;
if (item.IDidx != IDI_GOLD && !IsCreationFlagComboValid(item._iCreateInfo)) if (item.IDidx != IDI_GOLD && !IsCreationFlagComboValid(item.getAllCreationFlags()))
return false; return false;
if ((item._iCreateInfo & CF_TOWN) != 0) if (item.hasCreationFlag(CF_TOWN))
return IsTownItemValid(item._iCreateInfo, player) && IsShopPriceValid(item); return IsTownItemValid(item.getAllCreationFlags(), player) && IsShopPriceValid(item);
if ((item._iCreateInfo & CF_USEFUL) == CF_UPER15) if (item.matchesCreationFlags(CF_USEFUL, CF_UPER15))
return IsUniqueMonsterItemValid(item._iCreateInfo, item.dwBuff); return IsUniqueMonsterItemValid(item.getAllCreationFlags(), item.getAllCreationFlags2());
if ((item.dwBuff & CF_HELLFIRE) != 0 && AllItemsList[item.IDidx].iMiscId == IMISC_BOOK) if (item.hasCreationFlag2(CF_HELLFIRE) && AllItemsList[item.IDidx].iMiscId == IMISC_BOOK)
return IsHellfireSpellBookValid(item); return IsHellfireSpellBookValid(item);
return IsDungeonItemValid(item._iCreateInfo, item.dwBuff); return IsDungeonItemValid(item.getAllCreationFlags(), item.getAllCreationFlags2());
} }
bool IsItemDeltaValid(const TCmdPItem &itemDelta) bool IsItemDeltaValid(const TCmdPItem &itemDelta)

12
Source/loadsave.cpp

@ -268,7 +268,7 @@ struct LevelConversionData {
[[nodiscard]] bool LoadItemData(LoadHelper &file, Item &item) [[nodiscard]] bool LoadItemData(LoadHelper &file, Item &item)
{ {
item._iSeed = file.NextLE<uint32_t>(); item._iSeed = file.NextLE<uint32_t>();
item._iCreateInfo = file.NextLE<uint16_t>(); item.setAllCreationFlags(file.NextLE<uint16_t>());
file.Skip(2); // Alignment file.Skip(2); // Alignment
item._itype = static_cast<ItemType>(file.NextLE<uint32_t>()); item._itype = static_cast<ItemType>(file.NextLE<uint32_t>());
item.position.x = file.NextLE<int32_t>(); item.position.x = file.NextLE<int32_t>();
@ -369,7 +369,7 @@ struct LevelConversionData {
const _item_indexes itemIndex = static_cast<_item_indexes>(findIt->second); const _item_indexes itemIndex = static_cast<_item_indexes>(findIt->second);
item.IDidx = itemIndex; item.IDidx = itemIndex;
item.dwBuff = file.NextLE<uint32_t>(); item.setAllCreationFlags2(file.NextLE<uint32_t>());
if (gbIsHellfireSaveGame) if (gbIsHellfireSaveGame)
item._iDamAcFlags = static_cast<ItemSpecialEffectHf>(file.NextLE<uint32_t>()); item._iDamAcFlags = static_cast<ItemSpecialEffectHf>(file.NextLE<uint32_t>());
else else
@ -1096,9 +1096,9 @@ void LoadMatchingItems(LoadHelper &file, const Player &player, const int n, Item
if (gbIsMultiplayer) { if (gbIsMultiplayer) {
// Ensure that the unpacked item was regenerated using the appropriate // Ensure that the unpacked item was regenerated using the appropriate
// game's item generation logic before attempting to use it for validation // game's item generation logic before attempting to use it for validation
if ((heroItem.dwBuff & CF_HELLFIRE) != (unpackedItem.dwBuff & CF_HELLFIRE)) { if (heroItem.hasCreationFlag2(CF_HELLFIRE) != unpackedItem.hasCreationFlag2(CF_HELLFIRE)) {
unpackedItem = {}; unpackedItem = {};
RecreateItem(player, unpackedItem, heroItem.IDidx, heroItem._iCreateInfo, heroItem._iSeed, heroItem._ivalue, heroItem.dwBuff); RecreateItem(player, unpackedItem, heroItem.IDidx, heroItem.getAllCreationFlags(), heroItem._iSeed, heroItem._ivalue, heroItem.getAllCreationFlags2());
unpackedItem._iIdentified = heroItem._iIdentified; unpackedItem._iIdentified = heroItem._iIdentified;
unpackedItem._iMaxDur = heroItem._iMaxDur; unpackedItem._iMaxDur = heroItem._iMaxDur;
unpackedItem._iDurability = ClampDurability(unpackedItem, heroItem._iDurability); unpackedItem._iDurability = ClampDurability(unpackedItem, heroItem._iDurability);
@ -1169,7 +1169,7 @@ void SaveItem(SaveHelper &file, const Item &item)
} }
file.WriteLE<uint32_t>(item._iSeed); file.WriteLE<uint32_t>(item._iSeed);
file.WriteLE<int16_t>(item._iCreateInfo); file.WriteLE<int16_t>(item.getAllCreationFlags());
file.Skip(2); // Alignment file.Skip(2); // Alignment
file.WriteLE<int32_t>(static_cast<int32_t>(iType)); file.WriteLE<int32_t>(static_cast<int32_t>(iType));
file.WriteLE<int32_t>(item.position.x); file.WriteLE<int32_t>(item.position.x);
@ -1243,7 +1243,7 @@ void SaveItem(SaveHelper &file, const Item &item)
file.Skip(1); // Alignment file.Skip(1); // Alignment
file.WriteLE<uint32_t>(item._iStatFlag ? 1 : 0); file.WriteLE<uint32_t>(item._iStatFlag ? 1 : 0);
file.WriteLE<int32_t>(idx); file.WriteLE<int32_t>(idx);
file.WriteLE<uint32_t>(item.dwBuff); file.WriteLE<uint32_t>(item.getAllCreationFlags2());
if (gbIsHellfire) if (gbIsHellfire)
file.WriteLE<uint32_t>(static_cast<uint32_t>(item._iDamAcFlags)); file.WriteLE<uint32_t>(static_cast<uint32_t>(item._iDamAcFlags));
} }

24
Source/lua/modules/dev/items.cpp

@ -54,18 +54,18 @@ std::string DebugCmdItemInfo()
return StrCat("Name: ", pItem->_iIName, return StrCat("Name: ", pItem->_iIName,
"\nIDidx: ", pItem->IDidx, " (", AllItemsList[pItem->IDidx].iName, ")", "\nIDidx: ", pItem->IDidx, " (", AllItemsList[pItem->IDidx].iName, ")",
"\nSeed: ", pItem->_iSeed, "\nSeed: ", pItem->_iSeed,
"\nCreateInfo: ", pItem->_iCreateInfo, "\nCreateInfo: ", pItem->getAllCreationFlags(),
"\nLevel: ", pItem->_iCreateInfo & CF_LEVEL, "\nLevel: ", pItem->getItemLevel(),
"\nOnly Good: ", ((pItem->_iCreateInfo & CF_ONLYGOOD) == 0) ? "False" : "True", "\nOnly Good: ", pItem->hasCreationFlag(CF_ONLYGOOD) ? "False" : "True",
"\nUnique Monster: ", ((pItem->_iCreateInfo & CF_UPER15) == 0) ? "False" : "True", "\nUnique Monster: ", pItem->hasCreationFlag(CF_UPER15) ? "False" : "True",
"\nDungeon Item: ", ((pItem->_iCreateInfo & CF_UPER1) == 0) ? "False" : "True", "\nDungeon Item: ", pItem->hasCreationFlag(CF_UPER1) ? "False" : "True",
"\nUnique Item: ", ((pItem->_iCreateInfo & CF_UNIQUE) == 0) ? "False" : "True", "\nUnique Item: ", pItem->hasCreationFlag(CF_UNIQUE) ? "False" : "True",
"\nSmith: ", ((pItem->_iCreateInfo & CF_SMITH) == 0) ? "False" : "True", "\nSmith: ", pItem->hasCreationFlag(CF_SMITH) ? "False" : "True",
"\nSmith Premium: ", ((pItem->_iCreateInfo & CF_SMITHPREMIUM) == 0) ? "False" : "True", "\nSmith Premium: ", pItem->hasCreationFlag(CF_SMITHPREMIUM) ? "False" : "True",
"\nBoy: ", ((pItem->_iCreateInfo & CF_BOY) == 0) ? "False" : "True", "\nBoy: ", pItem->hasCreationFlag(CF_BOY) ? "False" : "True",
"\nWitch: ", ((pItem->_iCreateInfo & CF_WITCH) == 0) ? "False" : "True", "\nWitch: ", pItem->hasCreationFlag(CF_WITCH) ? "False" : "True",
"\nHealer: ", ((pItem->_iCreateInfo & CF_HEALER) == 0) ? "False" : "True", "\nHealer: ", pItem->hasCreationFlag(CF_HEALER) ? "False" : "True",
"\nPregen: ", ((pItem->_iCreateInfo & CF_PREGEN) == 0) ? "False" : "True", "\nPregen: ", pItem->hasCreationFlag(CF_PREGEN) ? "False" : "True",
"\nNet Validation: ", netPackValidation); "\nNet Validation: ", netPackValidation);
} }
return StrCat("Num items: ", ActiveItemCount); return StrCat("Num items: ", ActiveItemCount);

4
Source/lua/modules/items.cpp

@ -23,7 +23,7 @@ void InitItemUserType(sol::state_view &lua)
// Member variables // Member variables
LuaSetDocProperty(itemType, "seed", "number", "Randomly generated identifier", &Item::_iSeed); LuaSetDocProperty(itemType, "seed", "number", "Randomly generated identifier", &Item::_iSeed);
LuaSetDocProperty(itemType, "createInfo", "number", "Creation flags", &Item::_iCreateInfo); LuaSetDocProperty(itemType, "createInfo", "number", "Creation flags", &Item::getAllCreationFlags);
LuaSetDocProperty(itemType, "type", "ItemType", "Item type", &Item::_itype); LuaSetDocProperty(itemType, "type", "ItemType", "Item type", &Item::_itype);
LuaSetDocProperty(itemType, "animFlag", "boolean", "Animation flag", &Item::_iAnimFlag); LuaSetDocProperty(itemType, "animFlag", "boolean", "Animation flag", &Item::_iAnimFlag);
LuaSetDocProperty(itemType, "position", "Point", "Item world position", &Item::position); LuaSetDocProperty(itemType, "position", "Point", "Item world position", &Item::position);
@ -86,7 +86,7 @@ void InitItemUserType(sol::state_view &lua)
LuaSetDocProperty(itemType, "minDex", "number", "Minimum dexterity required", &Item::_iMinDex); LuaSetDocProperty(itemType, "minDex", "number", "Minimum dexterity required", &Item::_iMinDex);
LuaSetDocProperty(itemType, "statFlag", "boolean", "Equippable flag", &Item::_iStatFlag); LuaSetDocProperty(itemType, "statFlag", "boolean", "Equippable flag", &Item::_iStatFlag);
LuaSetDocProperty(itemType, "damAcFlags", "ItemSpecialEffectHf", "Secondary special effect flags", &Item::_iDamAcFlags); LuaSetDocProperty(itemType, "damAcFlags", "ItemSpecialEffectHf", "Secondary special effect flags", &Item::_iDamAcFlags);
LuaSetDocProperty(itemType, "buff", "number", "Secondary creation flags", &Item::dwBuff); LuaSetDocProperty(itemType, "buff", "number", "Secondary creation flags", &Item::getAllCreationFlags2);
// Member functions // Member functions
LuaSetDocFn(itemType, "pop", "() -> Item", "Clears this item and returns the old value", &Item::pop); LuaSetDocFn(itemType, "pop", "() -> Item", "Clears this item and returns the old value", &Item::pop);

10
Source/msg.cpp

@ -1312,7 +1312,7 @@ bool IsPItemValid(const TCmdPItem &message, const Player &player)
void PrepareItemForNetwork(const Item &item, TCmdGItem &message) void PrepareItemForNetwork(const Item &item, TCmdGItem &message)
{ {
message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx)); message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx));
message.def.wCI = Swap16LE(item._iCreateInfo); message.def.wCI = Swap16LE(item.getAllCreationFlags());
message.def.dwSeed = Swap32LE(item._iSeed); message.def.dwSeed = Swap32LE(item._iSeed);
if (item.IDidx == IDI_EAR) if (item.IDidx == IDI_EAR)
@ -1324,7 +1324,7 @@ void PrepareItemForNetwork(const Item &item, TCmdGItem &message)
void PrepareItemForNetwork(const Item &item, TCmdPItem &message) void PrepareItemForNetwork(const Item &item, TCmdPItem &message)
{ {
message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx)); message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx));
message.def.wCI = Swap16LE(item._iCreateInfo); message.def.wCI = Swap16LE(item.getAllCreationFlags());
message.def.dwSeed = Swap32LE(item._iSeed); message.def.dwSeed = Swap32LE(item._iSeed);
if (item.IDidx == IDI_EAR) if (item.IDidx == IDI_EAR)
@ -1336,7 +1336,7 @@ void PrepareItemForNetwork(const Item &item, TCmdPItem &message)
void PrepareItemForNetwork(const Item &item, TCmdChItem &message) void PrepareItemForNetwork(const Item &item, TCmdChItem &message)
{ {
message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx)); message.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx));
message.def.wCI = Swap16LE(item._iCreateInfo); message.def.wCI = Swap16LE(item.getAllCreationFlags());
message.def.dwSeed = Swap32LE(item._iSeed); message.def.dwSeed = Swap32LE(item._iSeed);
if (item.IDidx == IDI_EAR) if (item.IDidx == IDI_EAR)
@ -2667,7 +2667,7 @@ void PrepareItemForNetwork(const Item &item, TItem &messageItem)
messageItem.wValue = Swap16LE(item._ivalue); messageItem.wValue = Swap16LE(item._ivalue);
messageItem.wToHit = Swap16LE(item._iPLToHit); messageItem.wToHit = Swap16LE(item._iPLToHit);
messageItem.wMaxDam = Swap16LE(item._iMaxDam); messageItem.wMaxDam = Swap16LE(item._iMaxDam);
messageItem.dwBuff = Swap32LE(item.dwBuff); messageItem.dwBuff = Swap32LE(item.getAllCreationFlags2());
} }
void PrepareEarForNetwork(const Item &item, TEar &ear) void PrepareEarForNetwork(const Item &item, TEar &ear)
@ -2881,7 +2881,7 @@ void DeltaAddItem(int ii)
for (const TCmdPItem &item : deltaLevel.item) { for (const TCmdPItem &item : deltaLevel.item) {
if (item.bCmd != CMD_INVALID if (item.bCmd != CMD_INVALID
&& static_cast<_item_indexes>(Swap16LE(item.def.wIndx)) == Items[ii].IDidx && static_cast<_item_indexes>(Swap16LE(item.def.wIndx)) == Items[ii].IDidx
&& Swap16LE(item.def.wCI) == Items[ii]._iCreateInfo && Swap16LE(item.def.wCI) == Items[ii].getAllCreationFlags()
&& static_cast<uint32_t>(Swap32LE(item.def.dwSeed)) == Items[ii]._iSeed && static_cast<uint32_t>(Swap32LE(item.def.dwSeed)) == Items[ii]._iSeed
&& IsAnyOf(item.bCmd, TCmdPItem::PickedUpItem, TCmdPItem::FloorItem)) { && IsAnyOf(item.bCmd, TCmdPItem::PickedUpItem, TCmdPItem::FloorItem)) {
return; return;

10
Source/pack.cpp

@ -91,14 +91,14 @@ bool RecreateHellfireSpellBook(const Player &player, const TItem &packedItem, It
// CreateSpellBook() adds 1 to the spell level for ilvl // CreateSpellBook() adds 1 to the spell level for ilvl
spellBookLevel++; spellBookLevel++;
if (spellBookLevel >= 1 && (spellBook._iCreateInfo & CF_LEVEL) == spellBookLevel * 2) { if (spellBookLevel >= 1 && spellBook.getItemLevel() == spellBookLevel * 2) {
// The ilvl matches the result for a spell book drop, so we confirm the item is legitimate // The ilvl matches the result for a spell book drop, so we confirm the item is legitimate
if (item != nullptr) if (item != nullptr)
*item = spellBook; *item = spellBook;
return true; return true;
} }
ValidateFields(spellBook._iCreateInfo, spellBook.dwBuff, IsDungeonItemValid(spellBook._iCreateInfo, spellBook.dwBuff)); ValidateFields(spellBook.getAllCreationFlags(), spellBook.getAllCreationFlags2(), IsDungeonItemValid(spellBook.getAllCreationFlags(), spellBook.getAllCreationFlags2()));
if (item != nullptr) if (item != nullptr)
*item = spellBook; *item = spellBook;
return true; return true;
@ -131,7 +131,7 @@ void PackItem(ItemPack &packedItem, const Item &item, bool isHellfire)
packedItem.dwBuff = Swap32LE(LoadBE32(&item._iIName[12])); packedItem.dwBuff = Swap32LE(LoadBE32(&item._iIName[12]));
} else { } else {
packedItem.iSeed = Swap32LE(item._iSeed); packedItem.iSeed = Swap32LE(item._iSeed);
packedItem.iCreateInfo = Swap16LE(item._iCreateInfo); packedItem.iCreateInfo = Swap16LE(item.getAllCreationFlags());
packedItem.bId = (item._iMagical << 1) | (item._iIdentified ? 1 : 0); packedItem.bId = (item._iMagical << 1) | (item._iIdentified ? 1 : 0);
if (item._iMaxDur > 255) if (item._iMaxDur > 255)
packedItem.bMDur = 254; packedItem.bMDur = 254;
@ -143,7 +143,7 @@ void PackItem(ItemPack &packedItem, const Item &item, bool isHellfire)
packedItem.bMCh = item._iMaxCharges; packedItem.bMCh = item._iMaxCharges;
if (item.IDidx == IDI_GOLD) if (item.IDidx == IDI_GOLD)
packedItem.wValue = Swap16LE(item._ivalue); packedItem.wValue = Swap16LE(item._ivalue);
packedItem.dwBuff = item.dwBuff; packedItem.dwBuff = item.getAllCreationFlags2();
} }
} }
} }
@ -208,7 +208,7 @@ void PackNetItem(const Item &item, ItemNetPack &packedItem)
return; return;
} }
packedItem.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx)); packedItem.def.wIndx = static_cast<_item_indexes>(Swap16LE(item.IDidx));
packedItem.def.wCI = Swap16LE(item._iCreateInfo); packedItem.def.wCI = Swap16LE(item.getAllCreationFlags());
packedItem.def.dwSeed = Swap32LE(item._iSeed); packedItem.def.dwSeed = Swap32LE(item._iSeed);
if (item.IDidx != IDI_EAR) if (item.IDidx != IDI_EAR)
PrepareItemForNetwork(item, packedItem.item); PrepareItemForNetwork(item, packedItem.item);

5
Source/player.cpp

@ -2764,11 +2764,12 @@ StartPlayerKill(Player &player, DeathReason deathReason)
break; break;
} }
ear._iCreateInfo = player._pName[0] << 8 | player._pName[1]; // This is a hack that uses creation bits, seed, and value as characters for storing the name of the player.
ear.setAllCreationFlags(player._pName[0] << 8 | player._pName[1]);
ear._iSeed = player._pName[2] << 24 | player._pName[3] << 16 | player._pName[4] << 8 | player._pName[5]; ear._iSeed = player._pName[2] << 24 | player._pName[3] << 16 | player._pName[4] << 8 | player._pName[5];
ear._ivalue = player.getCharacterLevel(); ear._ivalue = player.getCharacterLevel();
if (FindGetItem(ear._iSeed, IDI_EAR, ear._iCreateInfo) == -1) { if (FindGetItem(ear._iSeed, IDI_EAR, ear.getAllCreationFlags()) == -1) {
DeadItem(player, std::move(ear), { 0, 0 }); DeadItem(player, std::move(ear), { 0, 0 });
} }
} }

4
Source/sync.cpp

@ -124,7 +124,7 @@ void SyncPlrInv(TSyncHeader *pHdr)
pHdr->wItemVal = Swap16LE((item._iIName[11] << 8) | ((item._iCurs - ICURS_EAR_SORCERER) << 6) | item._ivalue); pHdr->wItemVal = Swap16LE((item._iIName[11] << 8) | ((item._iCurs - ICURS_EAR_SORCERER) << 6) | item._ivalue);
pHdr->dwItemBuff = Swap32LE((item._iIName[12] << 24) | (item._iIName[13] << 16) | (item._iIName[14] << 8) | item._iIName[15]); pHdr->dwItemBuff = Swap32LE((item._iIName[12] << 24) | (item._iIName[13] << 16) | (item._iIName[14] << 8) | item._iIName[15]);
} else { } else {
pHdr->wItemCI = Swap16LE(item._iCreateInfo); pHdr->wItemCI = Swap16LE(item.getAllCreationFlags());
pHdr->dwItemSeed = Swap32LE(item._iSeed); pHdr->dwItemSeed = Swap32LE(item._iSeed);
pHdr->bItemId = item._iIdentified ? 1 : 0; pHdr->bItemId = item._iIdentified ? 1 : 0;
pHdr->bItemDur = item._iDurability; pHdr->bItemDur = item._iDurability;
@ -143,7 +143,7 @@ void SyncPlrInv(TSyncHeader *pHdr)
if (!item.isEmpty()) { if (!item.isEmpty()) {
pHdr->bPInvLoc = sgnSyncPInv; pHdr->bPInvLoc = sgnSyncPInv;
pHdr->wPInvIndx = Swap16LE(item.IDidx); pHdr->wPInvIndx = Swap16LE(item.IDidx);
pHdr->wPInvCI = Swap16LE(item._iCreateInfo); pHdr->wPInvCI = Swap16LE(item.getAllCreationFlags());
pHdr->dwPInvSeed = Swap32LE(item._iSeed); pHdr->dwPInvSeed = Swap32LE(item._iSeed);
pHdr->bPInvId = item._iIdentified ? 1 : 0; pHdr->bPInvId = item._iIdentified ? 1 : 0;
} }

60
test/pack_test.cpp

@ -168,13 +168,13 @@ static void TestItemNameGeneration(const Item &item)
// Check that UpdateHellfireFlag ensures that dwBuff is updated to get the correct name // Check that UpdateHellfireFlag ensures that dwBuff is updated to get the correct name
if (item._iMagical == ITEM_QUALITY_MAGIC) { if (item._iMagical == ITEM_QUALITY_MAGIC) {
const bool isHellfireItem = (testItem.dwBuff & CF_HELLFIRE); const bool isHellfireItem = testItem.hasCreationFlag2(CF_HELLFIRE);
testItem.dwBuff = 0; testItem.setAllCreationFlags2(0);
UpdateHellfireFlag(testItem, testItem._iIName); UpdateHellfireFlag(testItem, testItem._iIName);
testItem._iIdentified = true; testItem._iIdentified = true;
ASSERT_STREQ(testItem.getName().str().data(), testItem._iIName) << "identified name with UpdateHellfireFlag"; ASSERT_STREQ(testItem.getName().str().data(), testItem._iIName) << "identified name with UpdateHellfireFlag";
ASSERT_TRUE(isHellfireItem || ((item.dwBuff & CF_HELLFIRE) != CF_HELLFIRE)) << "item was wrongly converted to hellfire"; ASSERT_TRUE(isHellfireItem || !item.hasCreationFlag2(CF_HELLFIRE)) << "item was wrongly converted to hellfire";
} }
} }
} }
@ -1335,10 +1335,10 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_pregenItemFlags)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
item._iCreateInfo |= CF_PREGEN; item.setCreationFlag(CF_PREGEN);
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
count++; count++;
} }
ASSERT_GT(count, 0); ASSERT_GT(count, 0);
@ -1353,12 +1353,12 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_usefulItemFlags)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
if ((item._iCreateInfo & CF_USEFUL) != CF_USEFUL) if (!item.matchesCreationFlags(CF_USEFUL, CF_USEFUL))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
item._iCreateInfo |= CF_ONLYGOOD; item.setCreationFlag(CF_ONLYGOOD);
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
count++; count++;
} }
ASSERT_GT(count, 0); ASSERT_GT(count, 0);
@ -1373,12 +1373,12 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_townItemFlags)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
if ((item._iCreateInfo & CF_TOWN) == 0) if (!item.hasCreationFlag(CF_TOWN))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
item._iCreateInfo |= CF_ONLYGOOD; item.setCreationFlag(CF_ONLYGOOD);
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
count++; count++;
} }
ASSERT_GT(count, 0); ASSERT_GT(count, 0);
@ -1394,14 +1394,14 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_townItemLevel)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
if ((item._iCreateInfo & CF_TOWN) == 0) if (!item.hasCreationFlag(CF_TOWN))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
const bool BoyItem = (item._iCreateInfo & CF_BOY) != 0; const bool BoyItem = item.hasCreationFlag(CF_BOY);
item._iCreateInfo &= ~CF_LEVEL; item.clearCreationFlag(CF_LEVEL);
item._iCreateInfo |= BoyItem ? MyPlayer->getMaxCharacterLevel() + 1 : 31; item.setCreationFlag(BoyItem ? MyPlayer->getMaxCharacterLevel() + 1 : 31);
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
size_t &count = BoyItem ? boyCount : otherCount; size_t &count = BoyItem ? boyCount : otherCount;
count++; count++;
@ -1419,13 +1419,12 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_uniqueMonsterItemLevel)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
if ((item._iCreateInfo & CF_USEFUL) != CF_UPER15) if (!item.matchesCreationFlags(CF_USEFUL, CF_UPER15))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
item._iCreateInfo &= ~CF_LEVEL; item.setItemLevel(31);
item._iCreateInfo |= 31;
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
count++; count++;
} }
ASSERT_GT(count, 0); ASSERT_GT(count, 0);
@ -1440,15 +1439,14 @@ TEST_F(NetPackTest, UnPackNetPlayer_invalid_monsterItemLevel)
continue; continue;
if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR)) if (IsAnyOf(item.IDidx, IDI_GOLD, IDI_EAR))
continue; continue;
if ((item._iCreateInfo & CF_TOWN) != 0) if (item.hasCreationFlag(CF_TOWN))
continue; continue;
if ((item._iCreateInfo & CF_USEFUL) == CF_UPER15) if (item.matchesCreationFlags(CF_USEFUL, CF_UPER15))
continue; continue;
const uint16_t createInfo = item._iCreateInfo; const uint16_t createInfo = item.getAllCreationFlags();
item._iCreateInfo &= ~CF_LEVEL; item.setItemLevel(31);
item._iCreateInfo |= 31;
ASSERT_FALSE(TestNetPackValidation()); ASSERT_FALSE(TestNetPackValidation());
item._iCreateInfo = createInfo; item.setAllCreationFlags(createInfo);
count++; count++;
} }
ASSERT_GT(count, 0); ASSERT_GT(count, 0);

32
test/vendor_test.cpp

@ -203,7 +203,7 @@ TEST_F(VendorTest, PremiumQlvl1to5)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -214,7 +214,7 @@ TEST_F(VendorTest, PremiumQlvl1to5)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
} }
@ -230,7 +230,7 @@ TEST_F(VendorTest, PremiumQlvl25)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -241,7 +241,7 @@ TEST_F(VendorTest, PremiumQlvl25)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
} }
@ -257,7 +257,7 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -268,7 +268,7 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -278,7 +278,7 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
@ -289,7 +289,7 @@ TEST_F(VendorTest, PremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItems); EXPECT_EQ(PremiumItems.size(), NumSmithItems);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatch(i), PremiumTypeMatch(i)));
} }
} }
@ -305,7 +305,7 @@ TEST_F(VendorTest, HfPremiumQlvl1to5)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -316,7 +316,7 @@ TEST_F(VendorTest, HfPremiumQlvl1to5)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
} }
@ -332,7 +332,7 @@ TEST_F(VendorTest, HfPremiumQlvl25)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -344,7 +344,7 @@ TEST_F(VendorTest, HfPremiumQlvl25)
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
} }
@ -360,7 +360,7 @@ TEST_F(VendorTest, HfPremiumQlvl30Plus)
for (size_t i = 0; i < PremiumItems.size(); i++) { 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -372,7 +372,7 @@ TEST_F(VendorTest, HfPremiumQlvl30Plus)
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -384,7 +384,7 @@ TEST_F(VendorTest, HfPremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf); EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
@ -395,7 +395,7 @@ TEST_F(VendorTest, HfPremiumQlvl30Plus)
EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf); EXPECT_EQ(PremiumItems.size(), NumSmithItemsHf);
for (size_t i = 0; i < PremiumItems.size(); 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].getItemLevel(), QLVLS[i]) << "Index: " << i;
EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i))); EXPECT_THAT(PremiumItems[i]._itype, AnyOf(SmithTypeMatchHf(i), PremiumTypeMatch(i)));
} }
} }

Loading…
Cancel
Save