|
|
|
|
@ -452,7 +452,7 @@ void AddInitItems()
|
|
|
|
|
|
|
|
|
|
void SpawnNote() |
|
|
|
|
{ |
|
|
|
|
int id; |
|
|
|
|
_item_indexes id; |
|
|
|
|
|
|
|
|
|
switch (currlevel) { |
|
|
|
|
case 22: |
|
|
|
|
@ -1306,16 +1306,16 @@ void GetItemBonus(const Player &player, Item &item, int minlvl, int maxlvl, bool
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndUItem(Monster *monster) |
|
|
|
|
_item_indexes RndUItem(Monster *monster) |
|
|
|
|
{ |
|
|
|
|
if (monster != nullptr && (monster->data().treasure & T_UNIQ) != 0 && !gbIsMultiplayer) |
|
|
|
|
return -((monster->data().treasure & T_MASK) + 1); |
|
|
|
|
return static_cast<_item_indexes>(-((monster->data().treasure & T_MASK) + 1)); |
|
|
|
|
|
|
|
|
|
static std::array<int, 512> ril; |
|
|
|
|
static std::array<_item_indexes, 512> ril; |
|
|
|
|
|
|
|
|
|
int curlv = ItemsGetCurrlevel(); |
|
|
|
|
size_t ri = 0; |
|
|
|
|
for (int i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) { |
|
|
|
|
if (!IsItemAvailable(i)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
@ -1340,7 +1340,7 @@ int RndUItem(Monster *monster)
|
|
|
|
|
if (AllItemsList[i].iSpell == SPL_HEALOTHER && !gbIsMultiplayer) |
|
|
|
|
okflag = false; |
|
|
|
|
if (okflag && ri < ril.size()) { |
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1348,23 +1348,23 @@ int RndUItem(Monster *monster)
|
|
|
|
|
return ril[GenerateRnd(static_cast<int>(ri))]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndAllItems() |
|
|
|
|
_item_indexes RndAllItems() |
|
|
|
|
{ |
|
|
|
|
if (GenerateRnd(100) > 25) |
|
|
|
|
return IDI_GOLD; |
|
|
|
|
|
|
|
|
|
static std::array<int, 512> ril; |
|
|
|
|
static std::array<_item_indexes, 512> ril; |
|
|
|
|
|
|
|
|
|
int curlv = ItemsGetCurrlevel(); |
|
|
|
|
size_t ri = 0; |
|
|
|
|
for (int i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) { |
|
|
|
|
if (!IsItemAvailable(i)) |
|
|
|
|
continue; |
|
|
|
|
if (IsAnyOf(AllItemsList[i].iSpell, SPL_RESURRECT, SPL_HEALOTHER) && !gbIsMultiplayer) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (AllItemsList[i].iRnd != IDROP_NEVER && 2 * curlv >= AllItemsList[i].iMinMLvl && ri < ril.size()) { |
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1372,12 +1372,12 @@ int RndAllItems()
|
|
|
|
|
return ril[GenerateRnd(static_cast<int>(ri))]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndTypeItems(ItemType itemType, int imid, int lvl) |
|
|
|
|
_item_indexes RndTypeItems(ItemType itemType, int imid, int lvl) |
|
|
|
|
{ |
|
|
|
|
static std::array<int, 512> ril; |
|
|
|
|
static std::array<_item_indexes, 512> ril; |
|
|
|
|
|
|
|
|
|
size_t ri = 0; |
|
|
|
|
for (int i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) { |
|
|
|
|
if (!IsItemAvailable(i)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
@ -1391,7 +1391,7 @@ int RndTypeItems(ItemType itemType, int imid, int lvl)
|
|
|
|
|
if (imid != -1 && AllItemsList[i].iMiscId != imid) |
|
|
|
|
okflag = false; |
|
|
|
|
if (okflag && ri < ril.size()) { |
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -1460,7 +1460,7 @@ void ItemRndDur(Item &item)
|
|
|
|
|
item._iDurability = GenerateRnd(item._iMaxDur / 2) + (item._iMaxDur / 4) + 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SetupAllItems(const Player &player, Item &item, int idx, int iseed, int lvl, int uper, bool onlygood, bool recreate, bool pregen) |
|
|
|
|
void SetupAllItems(const Player &player, Item &item, _item_indexes idx, int iseed, int lvl, int uper, bool onlygood, bool recreate, bool pregen) |
|
|
|
|
{ |
|
|
|
|
item._iSeed = iseed; |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
@ -1513,7 +1513,7 @@ void SetupAllItems(const Player &player, Item &item, int idx, int iseed, int lvl
|
|
|
|
|
SetupItem(item); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SetupBaseItem(Point position, int idx, bool onlygood, bool sendmsg, bool delta) |
|
|
|
|
void SetupBaseItem(Point position, _item_indexes idx, bool onlygood, bool sendmsg, bool delta) |
|
|
|
|
{ |
|
|
|
|
if (ActiveItemCount >= MAXITEMS) |
|
|
|
|
return; |
|
|
|
|
@ -1533,14 +1533,13 @@ void SetupBaseItem(Point position, int idx, bool onlygood, bool sendmsg, bool de
|
|
|
|
|
|
|
|
|
|
void SetupAllUseful(Item &item, int iseed, int lvl) |
|
|
|
|
{ |
|
|
|
|
int idx; |
|
|
|
|
|
|
|
|
|
item._iSeed = iseed; |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
|
|
|
|
|
_item_indexes idx; |
|
|
|
|
|
|
|
|
|
if (gbIsHellfire) { |
|
|
|
|
idx = GenerateRnd(7); |
|
|
|
|
switch (idx) { |
|
|
|
|
switch (GenerateRnd(7)) { |
|
|
|
|
case 0: |
|
|
|
|
idx = IDI_PORTAL; |
|
|
|
|
if (lvl <= 1) |
|
|
|
|
@ -1871,12 +1870,12 @@ bool SmithItemOk(const Player &player, int i)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <bool (*Ok)(const Player &, int), bool ConsiderDropRate = false> |
|
|
|
|
int RndVendorItem(const Player &player, int minlvl, int maxlvl) |
|
|
|
|
_item_indexes RndVendorItem(const Player &player, int minlvl, int maxlvl) |
|
|
|
|
{ |
|
|
|
|
static std::array<int, 512> ril; |
|
|
|
|
static std::array<_item_indexes, 512> ril; |
|
|
|
|
|
|
|
|
|
size_t ri = 0; |
|
|
|
|
for (int i = 1; AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
for (std::underlying_type_t<_item_indexes> i = IDI_WARRIOR; i <= IDI_LAST && AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
if (!IsItemAvailable(i)) |
|
|
|
|
continue; |
|
|
|
|
if (AllItemsList[i].iRnd == IDROP_NEVER) |
|
|
|
|
@ -1886,7 +1885,7 @@ int RndVendorItem(const Player &player, int minlvl, int maxlvl)
|
|
|
|
|
if (AllItemsList[i].iMinMLvl < minlvl || AllItemsList[i].iMinMLvl > maxlvl) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
if (ri >= ril.size()) |
|
|
|
|
break; |
|
|
|
|
@ -1894,7 +1893,7 @@ int RndVendorItem(const Player &player, int minlvl, int maxlvl)
|
|
|
|
|
if (!ConsiderDropRate || AllItemsList[i].iRnd != IDROP_DOUBLE) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
if (ri >= ril.size()) |
|
|
|
|
break; |
|
|
|
|
@ -1903,7 +1902,7 @@ int RndVendorItem(const Player &player, int minlvl, int maxlvl)
|
|
|
|
|
return ril[GenerateRnd(static_cast<int>(ri))]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndSmithItem(const Player &player, int lvl) |
|
|
|
|
_item_indexes RndSmithItem(const Player &player, int lvl) |
|
|
|
|
{ |
|
|
|
|
return RndVendorItem<SmithItemOk, true>(player, 0, lvl); |
|
|
|
|
} |
|
|
|
|
@ -1942,7 +1941,7 @@ bool PremiumItemOk(const Player &player, int i)
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndPremiumItem(const Player &player, int minlvl, int maxlvl) |
|
|
|
|
_item_indexes RndPremiumItem(const Player &player, int minlvl, int maxlvl) |
|
|
|
|
{ |
|
|
|
|
return RndVendorItem<PremiumItemOk>(player, minlvl, maxlvl); |
|
|
|
|
} |
|
|
|
|
@ -1968,7 +1967,7 @@ void SpawnOnePremium(Item &premiumItem, int plvl, const Player &player)
|
|
|
|
|
premiumItem = {}; |
|
|
|
|
premiumItem._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(premiumItem._iSeed); |
|
|
|
|
int itemType = RndPremiumItem(player, plvl / 4, plvl); |
|
|
|
|
_item_indexes itemType = RndPremiumItem(player, plvl / 4, plvl); |
|
|
|
|
GetItemAttrs(premiumItem, itemType, plvl); |
|
|
|
|
GetItemBonus(player, premiumItem, plvl / 2, plvl, true, !gbIsHellfire); |
|
|
|
|
|
|
|
|
|
@ -2051,12 +2050,12 @@ bool WitchItemOk(const Player &player, int i)
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndWitchItem(const Player &player, int lvl) |
|
|
|
|
_item_indexes RndWitchItem(const Player &player, int lvl) |
|
|
|
|
{ |
|
|
|
|
return RndVendorItem<WitchItemOk>(player, 0, lvl); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndBoyItem(const Player &player, int lvl) |
|
|
|
|
_item_indexes RndBoyItem(const Player &player, int lvl) |
|
|
|
|
{ |
|
|
|
|
return RndVendorItem<PremiumItemOk>(player, 0, lvl); |
|
|
|
|
} |
|
|
|
|
@ -2090,7 +2089,7 @@ bool HealerItemOk(const Player &player, int i)
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndHealerItem(const Player &player, int lvl) |
|
|
|
|
_item_indexes RndHealerItem(const Player &player, int lvl) |
|
|
|
|
{ |
|
|
|
|
return RndVendorItem<HealerItemOk>(player, 0, lvl); |
|
|
|
|
} |
|
|
|
|
@ -2098,7 +2097,7 @@ int RndHealerItem(const Player &player, int lvl)
|
|
|
|
|
void RecreateSmithItem(const Player &player, Item &item, int lvl, int iseed) |
|
|
|
|
{ |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
int itype = RndSmithItem(player, lvl); |
|
|
|
|
_item_indexes itype = RndSmithItem(player, lvl); |
|
|
|
|
GetItemAttrs(item, itype, lvl); |
|
|
|
|
|
|
|
|
|
item._iSeed = iseed; |
|
|
|
|
@ -2109,7 +2108,7 @@ void RecreateSmithItem(const Player &player, Item &item, int lvl, int iseed)
|
|
|
|
|
void RecreatePremiumItem(const Player &player, Item &item, int plvl, int iseed) |
|
|
|
|
{ |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
int itype = RndPremiumItem(player, plvl / 4, plvl); |
|
|
|
|
_item_indexes itype = RndPremiumItem(player, plvl / 4, plvl); |
|
|
|
|
GetItemAttrs(item, itype, plvl); |
|
|
|
|
GetItemBonus(player, item, plvl / 2, plvl, true, !gbIsHellfire); |
|
|
|
|
|
|
|
|
|
@ -2121,7 +2120,7 @@ void RecreatePremiumItem(const Player &player, Item &item, int plvl, int iseed)
|
|
|
|
|
void RecreateBoyItem(const Player &player, Item &item, int lvl, int iseed) |
|
|
|
|
{ |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
int itype = RndBoyItem(player, lvl); |
|
|
|
|
_item_indexes itype = RndBoyItem(player, lvl); |
|
|
|
|
GetItemAttrs(item, itype, lvl); |
|
|
|
|
GetItemBonus(player, item, lvl, 2 * lvl, true, true); |
|
|
|
|
|
|
|
|
|
@ -2130,7 +2129,7 @@ void RecreateBoyItem(const Player &player, Item &item, int lvl, int iseed)
|
|
|
|
|
item._iIdentified = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RecreateWitchItem(const Player &player, Item &item, int idx, int lvl, int iseed) |
|
|
|
|
void RecreateWitchItem(const Player &player, Item &item, _item_indexes idx, int lvl, int iseed) |
|
|
|
|
{ |
|
|
|
|
if (IsAnyOf(idx, IDI_MANA, IDI_FULLMANA, IDI_PORTAL)) { |
|
|
|
|
GetItemAttrs(item, idx, lvl); |
|
|
|
|
@ -2140,7 +2139,7 @@ void RecreateWitchItem(const Player &player, Item &item, int idx, int lvl, int i
|
|
|
|
|
GetItemAttrs(item, idx, lvl); |
|
|
|
|
} else { |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
int itype = RndWitchItem(player, lvl); |
|
|
|
|
_item_indexes itype = RndWitchItem(player, lvl); |
|
|
|
|
GetItemAttrs(item, itype, lvl); |
|
|
|
|
int iblvl = -1; |
|
|
|
|
if (GenerateRnd(100) <= 5) |
|
|
|
|
@ -2156,13 +2155,13 @@ void RecreateWitchItem(const Player &player, Item &item, int idx, int lvl, int i
|
|
|
|
|
item._iIdentified = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RecreateHealerItem(const Player &player, Item &item, int idx, int lvl, int iseed) |
|
|
|
|
void RecreateHealerItem(const Player &player, Item &item, _item_indexes idx, int lvl, int iseed) |
|
|
|
|
{ |
|
|
|
|
if (IsAnyOf(idx, IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT)) { |
|
|
|
|
GetItemAttrs(item, idx, lvl); |
|
|
|
|
} else { |
|
|
|
|
SetRndSeed(iseed); |
|
|
|
|
int itype = RndHealerItem(player, lvl); |
|
|
|
|
_item_indexes itype = RndHealerItem(player, lvl); |
|
|
|
|
GetItemAttrs(item, itype, lvl); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -2171,7 +2170,7 @@ void RecreateHealerItem(const Player &player, Item &item, int idx, int lvl, int
|
|
|
|
|
item._iIdentified = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RecreateTownItem(const Player &player, Item &item, int idx, uint16_t icreateinfo, int iseed) |
|
|
|
|
void RecreateTownItem(const Player &player, Item &item, _item_indexes idx, uint16_t icreateinfo, int iseed) |
|
|
|
|
{ |
|
|
|
|
if ((icreateinfo & CF_SMITH) != 0) |
|
|
|
|
RecreateSmithItem(player, item, icreateinfo & CF_LEVEL, iseed); |
|
|
|
|
@ -2192,7 +2191,7 @@ void CreateMagicItem(Point position, int lvl, ItemType itemType, int imid, int i
|
|
|
|
|
|
|
|
|
|
int ii = AllocateItem(); |
|
|
|
|
auto &item = Items[ii]; |
|
|
|
|
int idx = RndTypeItems(itemType, imid, lvl); |
|
|
|
|
_item_indexes idx = RndTypeItems(itemType, imid, lvl); |
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
item = {}; |
|
|
|
|
@ -2224,7 +2223,7 @@ void NextItemRecord(int i)
|
|
|
|
|
itemrecord[i].nIndex = itemrecord[gnNumGetRecords].nIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int RndItemForMonsterLevel(int8_t monsterLevel) |
|
|
|
|
_item_indexes RndItemForMonsterLevel(int8_t monsterLevel) |
|
|
|
|
{ |
|
|
|
|
if (GenerateRnd(100) > 40) |
|
|
|
|
return IDI_NONE; |
|
|
|
|
@ -2232,21 +2231,21 @@ int RndItemForMonsterLevel(int8_t monsterLevel)
|
|
|
|
|
if (GenerateRnd(100) > 25) |
|
|
|
|
return IDI_GOLD; |
|
|
|
|
|
|
|
|
|
static std::array<int, 512> ril; |
|
|
|
|
static std::array<_item_indexes, 512> ril; |
|
|
|
|
|
|
|
|
|
size_t ri = 0; |
|
|
|
|
for (int i = 0; AllItemsList[i].iLoc != ILOC_INVALID; i++) { |
|
|
|
|
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) { |
|
|
|
|
if (!IsItemAvailable(i)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (AllItemsList[i].iRnd == IDROP_DOUBLE && monsterLevel >= AllItemsList[i].iMinMLvl |
|
|
|
|
&& ri < ril.size()) { |
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
} |
|
|
|
|
if (AllItemsList[i].iRnd != IDROP_NEVER && monsterLevel >= AllItemsList[i].iMinMLvl |
|
|
|
|
&& ri < ril.size()) { |
|
|
|
|
ril[ri] = i; |
|
|
|
|
ril[ri] = static_cast<_item_indexes>(i); |
|
|
|
|
ri++; |
|
|
|
|
} |
|
|
|
|
if (AllItemsList[i].iSpell == SPL_RESURRECT && !gbIsMultiplayer) |
|
|
|
|
@ -2747,9 +2746,9 @@ void CalcPlrInv(Player &player, bool loadgfx)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void InitializeItem(Item &item, int itemData) |
|
|
|
|
void InitializeItem(Item &item, _item_indexes itemData) |
|
|
|
|
{ |
|
|
|
|
auto &pAllItem = AllItemsList[itemData]; |
|
|
|
|
auto &pAllItem = AllItemsList[static_cast<size_t>(itemData)]; |
|
|
|
|
|
|
|
|
|
// zero-initialize struct
|
|
|
|
|
item = {}; |
|
|
|
|
@ -2963,29 +2962,30 @@ Point GetSuperItemLoc(Point position)
|
|
|
|
|
return itemPosition.value_or(Point { 0, 0 }); // TODO handle no space for dropping items
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GetItemAttrs(Item &item, int itemData, int lvl) |
|
|
|
|
{ |
|
|
|
|
item._itype = AllItemsList[itemData].itype; |
|
|
|
|
item._iCurs = AllItemsList[itemData].iCurs; |
|
|
|
|
CopyUtf8(item._iName, _(AllItemsList[itemData].iName), sizeof(item._iName)); |
|
|
|
|
CopyUtf8(item._iIName, _(AllItemsList[itemData].iName), sizeof(item._iIName)); |
|
|
|
|
item._iLoc = AllItemsList[itemData].iLoc; |
|
|
|
|
item._iClass = AllItemsList[itemData].iClass; |
|
|
|
|
item._iMinDam = AllItemsList[itemData].iMinDam; |
|
|
|
|
item._iMaxDam = AllItemsList[itemData].iMaxDam; |
|
|
|
|
item._iAC = AllItemsList[itemData].iMinAC + GenerateRnd(AllItemsList[itemData].iMaxAC - AllItemsList[itemData].iMinAC + 1); |
|
|
|
|
item._iFlags = AllItemsList[itemData].iFlags; |
|
|
|
|
item._iMiscId = AllItemsList[itemData].iMiscId; |
|
|
|
|
item._iSpell = AllItemsList[itemData].iSpell; |
|
|
|
|
void GetItemAttrs(Item &item, _item_indexes itemData, int lvl) |
|
|
|
|
{ |
|
|
|
|
auto &baseItemData = AllItemsList[static_cast<size_t>(itemData)]; |
|
|
|
|
item._itype = baseItemData.itype; |
|
|
|
|
item._iCurs = baseItemData.iCurs; |
|
|
|
|
CopyUtf8(item._iName, _(baseItemData.iName), sizeof(item._iName)); |
|
|
|
|
CopyUtf8(item._iIName, _(baseItemData.iName), sizeof(item._iIName)); |
|
|
|
|
item._iLoc = baseItemData.iLoc; |
|
|
|
|
item._iClass = baseItemData.iClass; |
|
|
|
|
item._iMinDam = baseItemData.iMinDam; |
|
|
|
|
item._iMaxDam = baseItemData.iMaxDam; |
|
|
|
|
item._iAC = baseItemData.iMinAC + GenerateRnd(baseItemData.iMaxAC - baseItemData.iMinAC + 1); |
|
|
|
|
item._iFlags = baseItemData.iFlags; |
|
|
|
|
item._iMiscId = baseItemData.iMiscId; |
|
|
|
|
item._iSpell = baseItemData.iSpell; |
|
|
|
|
item._iMagical = ITEM_QUALITY_NORMAL; |
|
|
|
|
item._ivalue = AllItemsList[itemData].iValue; |
|
|
|
|
item._iIvalue = AllItemsList[itemData].iValue; |
|
|
|
|
item._iDurability = AllItemsList[itemData].iDurability; |
|
|
|
|
item._iMaxDur = AllItemsList[itemData].iDurability; |
|
|
|
|
item._iMinStr = AllItemsList[itemData].iMinStr; |
|
|
|
|
item._iMinMag = AllItemsList[itemData].iMinMag; |
|
|
|
|
item._iMinDex = AllItemsList[itemData].iMinDex; |
|
|
|
|
item.IDidx = static_cast<_item_indexes>(itemData); |
|
|
|
|
item._ivalue = baseItemData.iValue; |
|
|
|
|
item._iIvalue = baseItemData.iValue; |
|
|
|
|
item._iDurability = baseItemData.iDurability; |
|
|
|
|
item._iMaxDur = baseItemData.iDurability; |
|
|
|
|
item._iMinStr = baseItemData.iMinStr; |
|
|
|
|
item._iMinMag = baseItemData.iMinMag; |
|
|
|
|
item._iMinDex = baseItemData.iMinDex; |
|
|
|
|
item.IDidx = itemData; |
|
|
|
|
if (gbIsHellfire) |
|
|
|
|
item.dwBuff |= CF_HELLFIRE; |
|
|
|
|
item._iPrePower = IPL_INVALID; |
|
|
|
|
@ -3049,36 +3049,36 @@ void SpawnUnique(_unique_items uid, Point position)
|
|
|
|
|
GetSuperItemSpace(position, ii); |
|
|
|
|
int curlv = ItemsGetCurrlevel(); |
|
|
|
|
|
|
|
|
|
int idx = 0; |
|
|
|
|
std::underlying_type_t<_item_indexes> idx = 0; |
|
|
|
|
while (AllItemsList[idx].iItemId != UniqueItems[uid].UIItemId) |
|
|
|
|
idx++; |
|
|
|
|
|
|
|
|
|
GetItemAttrs(item, idx, curlv); |
|
|
|
|
GetItemAttrs(item, static_cast<_item_indexes>(idx), curlv); |
|
|
|
|
GetUniqueItem(*MyPlayer, item, uid); |
|
|
|
|
SetupItem(item); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SpawnItem(Monster &monster, Point position, bool sendmsg) |
|
|
|
|
{ |
|
|
|
|
int idx; |
|
|
|
|
_item_indexes idx; |
|
|
|
|
bool onlygood = true; |
|
|
|
|
|
|
|
|
|
if (monster.isUnique() || ((monster.data().treasure & T_UNIQ) != 0 && gbIsMultiplayer)) { |
|
|
|
|
idx = RndUItem(&monster); |
|
|
|
|
if (idx < 0) { |
|
|
|
|
if (idx < IDI_GOLD) { |
|
|
|
|
SpawnUnique(static_cast<_unique_items>(-(idx + 1)), position); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
onlygood = true; |
|
|
|
|
} else if (Quests[Q_MUSHROOM]._qactive != QUEST_ACTIVE || Quests[Q_MUSHROOM]._qvar1 != QS_MUSHGIVEN) { |
|
|
|
|
idx = RndItem(monster); |
|
|
|
|
if (idx == 0) |
|
|
|
|
int optionalIndexOrUniqueIndex = RndItem(monster); |
|
|
|
|
if (optionalIndexOrUniqueIndex == 0) // No drop
|
|
|
|
|
return; |
|
|
|
|
if (idx > 0) { |
|
|
|
|
idx--; |
|
|
|
|
if (optionalIndexOrUniqueIndex > 0) { // Item index
|
|
|
|
|
idx = static_cast<_item_indexes>(optionalIndexOrUniqueIndex - 1); |
|
|
|
|
onlygood = false; |
|
|
|
|
} else { |
|
|
|
|
SpawnUnique(static_cast<_unique_items>(-(idx + 1)), position); |
|
|
|
|
} else { // Unique item index
|
|
|
|
|
SpawnUnique(static_cast<_unique_items>(-(optionalIndexOrUniqueIndex + 1)), position); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
@ -3106,7 +3106,7 @@ void SpawnItem(Monster &monster, Point position, bool sendmsg)
|
|
|
|
|
|
|
|
|
|
void CreateRndItem(Point position, bool onlygood, bool sendmsg, bool delta) |
|
|
|
|
{ |
|
|
|
|
int idx = onlygood ? RndUItem(nullptr) : RndAllItems(); |
|
|
|
|
_item_indexes idx = onlygood ? RndUItem(nullptr) : RndAllItems(); |
|
|
|
|
|
|
|
|
|
SetupBaseItem(position, idx, onlygood, sendmsg, delta); |
|
|
|
|
} |
|
|
|
|
@ -3128,7 +3128,7 @@ void CreateRndUseful(Point position, bool sendmsg)
|
|
|
|
|
|
|
|
|
|
void CreateTypeItem(Point position, bool onlygood, ItemType itemType, int imisc, bool sendmsg, bool delta) |
|
|
|
|
{ |
|
|
|
|
int idx; |
|
|
|
|
_item_indexes idx; |
|
|
|
|
|
|
|
|
|
int curlv = ItemsGetCurrlevel(); |
|
|
|
|
if (itemType != ItemType::Gold) |
|
|
|
|
@ -3139,7 +3139,7 @@ void CreateTypeItem(Point position, bool onlygood, ItemType itemType, int imisc,
|
|
|
|
|
SetupBaseItem(position, idx, onlygood, sendmsg, delta); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RecreateItem(const Player &player, Item &item, int idx, uint16_t icreateinfo, int iseed, int ivalue, bool isHellfire) |
|
|
|
|
void RecreateItem(const Player &player, Item &item, _item_indexes idx, uint16_t icreateinfo, int iseed, int ivalue, bool isHellfire) |
|
|
|
|
{ |
|
|
|
|
bool tmpIsHellfire = gbIsHellfire; |
|
|
|
|
gbIsHellfire = isHellfire; |
|
|
|
|
@ -3260,7 +3260,7 @@ void CornerstoneLoad(Point position)
|
|
|
|
|
CornerStone.item = item; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SpawnQuestItem(int itemid, Point position, int randarea, int selflag) |
|
|
|
|
void SpawnQuestItem(_item_indexes itemid, Point position, int randarea, int selflag) |
|
|
|
|
{ |
|
|
|
|
if (randarea > 0) { |
|
|
|
|
int tries = 0; |
|
|
|
|
@ -3307,7 +3307,7 @@ void SpawnQuestItem(int itemid, Point position, int randarea, int selflag)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SpawnRewardItem(int itemid, Point position, bool sendmsg) |
|
|
|
|
void SpawnRewardItem(_item_indexes itemid, Point position, bool sendmsg) |
|
|
|
|
{ |
|
|
|
|
if (ActiveItemCount >= MAXITEMS) |
|
|
|
|
return; |
|
|
|
|
@ -4016,7 +4016,7 @@ void SpawnSmith(int lvl)
|
|
|
|
|
newItem = {}; |
|
|
|
|
newItem._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(newItem._iSeed); |
|
|
|
|
int itemData = RndSmithItem(*MyPlayer, lvl); |
|
|
|
|
_item_indexes itemData = RndSmithItem(*MyPlayer, lvl); |
|
|
|
|
GetItemAttrs(newItem, itemData, lvl); |
|
|
|
|
} while (newItem._iIvalue > maxValue); |
|
|
|
|
|
|
|
|
|
@ -4065,9 +4065,9 @@ void SpawnPremium(const Player &player)
|
|
|
|
|
void SpawnWitch(int lvl) |
|
|
|
|
{ |
|
|
|
|
constexpr int PinnedItemCount = 3; |
|
|
|
|
constexpr std::array<int, PinnedItemCount> PinnedItemTypes = { IDI_MANA, IDI_FULLMANA, IDI_PORTAL }; |
|
|
|
|
constexpr std::array<_item_indexes, PinnedItemCount> PinnedItemTypes = { IDI_MANA, IDI_FULLMANA, IDI_PORTAL }; |
|
|
|
|
constexpr int MaxPinnedBookCount = 4; |
|
|
|
|
constexpr std::array<int, MaxPinnedBookCount> PinnedBookTypes = { IDI_BOOK1, IDI_BOOK2, IDI_BOOK3, IDI_BOOK4 }; |
|
|
|
|
constexpr std::array<_item_indexes, MaxPinnedBookCount> PinnedBookTypes = { IDI_BOOK1, IDI_BOOK2, IDI_BOOK3, IDI_BOOK4 }; |
|
|
|
|
|
|
|
|
|
int bookCount = 0; |
|
|
|
|
const int pinnedBookCount = gbIsHellfire ? GenerateRnd(MaxPinnedBookCount) : 0; |
|
|
|
|
@ -4089,7 +4089,7 @@ void SpawnWitch(int lvl)
|
|
|
|
|
|
|
|
|
|
if (gbIsHellfire) { |
|
|
|
|
if (i < PinnedItemCount + MaxPinnedBookCount && bookCount < pinnedBookCount) { |
|
|
|
|
int bookType = PinnedBookTypes[i - PinnedItemCount]; |
|
|
|
|
_item_indexes bookType = PinnedBookTypes[i - PinnedItemCount]; |
|
|
|
|
if (lvl >= AllItemsList[bookType].iMinMLvl) { |
|
|
|
|
item._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(item._iSeed); |
|
|
|
|
@ -4111,7 +4111,7 @@ void SpawnWitch(int lvl)
|
|
|
|
|
item = {}; |
|
|
|
|
item._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(item._iSeed); |
|
|
|
|
int itemData = RndWitchItem(*MyPlayer, lvl); |
|
|
|
|
_item_indexes itemData = RndWitchItem(*MyPlayer, lvl); |
|
|
|
|
GetItemAttrs(item, itemData, lvl); |
|
|
|
|
int maxlvl = -1; |
|
|
|
|
if (GenerateRnd(100) <= 5) |
|
|
|
|
@ -4152,7 +4152,7 @@ void SpawnBoy(int lvl)
|
|
|
|
|
boyitem = {}; |
|
|
|
|
boyitem._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(boyitem._iSeed); |
|
|
|
|
int itype = RndBoyItem(*MyPlayer, lvl); |
|
|
|
|
_item_indexes itype = RndBoyItem(*MyPlayer, lvl); |
|
|
|
|
GetItemAttrs(boyitem, itype, lvl); |
|
|
|
|
GetItemBonus(*MyPlayer, boyitem, lvl, 2 * lvl, true, true); |
|
|
|
|
|
|
|
|
|
@ -4246,7 +4246,7 @@ void SpawnBoy(int lvl)
|
|
|
|
|
void SpawnHealer(int lvl) |
|
|
|
|
{ |
|
|
|
|
constexpr int PinnedItemCount = 2; |
|
|
|
|
constexpr std::array<int, PinnedItemCount + 1> PinnedItemTypes = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT }; |
|
|
|
|
constexpr std::array<_item_indexes, PinnedItemCount + 1> PinnedItemTypes = { IDI_HEAL, IDI_FULLHEAL, IDI_RESURRECT }; |
|
|
|
|
const int itemCount = GenerateRnd(gbIsHellfire ? 10 : 8) + 10; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 20; i++) { |
|
|
|
|
@ -4268,7 +4268,7 @@ void SpawnHealer(int lvl)
|
|
|
|
|
|
|
|
|
|
item._iSeed = AdvanceRndSeed(); |
|
|
|
|
SetRndSeed(item._iSeed); |
|
|
|
|
int itype = RndHealerItem(*MyPlayer, lvl); |
|
|
|
|
_item_indexes itype = RndHealerItem(*MyPlayer, lvl); |
|
|
|
|
GetItemAttrs(item, itype, lvl); |
|
|
|
|
item._iCreateInfo = lvl | CF_HEALER; |
|
|
|
|
item._iIdentified = true; |
|
|
|
|
@ -4307,7 +4307,7 @@ void CreateSpellBook(Point position, spell_id ispell, bool sendmsg, bool delta)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int idx = RndTypeItems(ItemType::Misc, IMISC_BOOK, lvl); |
|
|
|
|
_item_indexes idx = RndTypeItems(ItemType::Misc, IMISC_BOOK, lvl); |
|
|
|
|
if (ActiveItemCount >= MAXITEMS) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
@ -4427,7 +4427,7 @@ std::string DebugSpawnItem(std::string itemName)
|
|
|
|
|
return StrCat("Item not found in ", max_iter, " tries!"); |
|
|
|
|
|
|
|
|
|
const int8_t monsterLevel = dist(BetterRng) % CF_LEVEL + 1; |
|
|
|
|
int idx = RndItemForMonsterLevel(monsterLevel); |
|
|
|
|
_item_indexes idx = RndItemForMonsterLevel(monsterLevel); |
|
|
|
|
if (IsAnyOf(idx, IDI_NONE, IDI_GOLD)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
@ -4455,7 +4455,6 @@ std::string DebugSpawnUniqueItem(std::string itemName)
|
|
|
|
|
std::transform(itemName.begin(), itemName.end(), itemName.begin(), [](unsigned char c) { return std::tolower(c); }); |
|
|
|
|
UniqueItem uniqueItem; |
|
|
|
|
bool foundUnique = false; |
|
|
|
|
int uniqueBaseIndex = 0; |
|
|
|
|
int uniqueIndex = 0; |
|
|
|
|
for (int j = 0; UniqueItems[j].UIItemId != UITYPE_INVALID; j++) { |
|
|
|
|
if (!IsUniqueAvailable(j)) |
|
|
|
|
@ -4474,11 +4473,12 @@ std::string DebugSpawnUniqueItem(std::string itemName)
|
|
|
|
|
if (!foundUnique) |
|
|
|
|
return "No unique found!"; |
|
|
|
|
|
|
|
|
|
for (int j = 0; AllItemsList[j].iLoc != ILOC_INVALID; j++) { |
|
|
|
|
_item_indexes uniqueBaseIndex = IDI_GOLD; |
|
|
|
|
for (std::underlying_type_t<_item_indexes> j = IDI_GOLD; j <= IDI_LAST; j++) { |
|
|
|
|
if (!IsItemAvailable(j)) |
|
|
|
|
continue; |
|
|
|
|
if (AllItemsList[j].iItemId == uniqueItem.UIItemId) |
|
|
|
|
uniqueBaseIndex = j; |
|
|
|
|
uniqueBaseIndex = static_cast<_item_indexes>(j); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int ii = AllocateItem(); |
|
|
|
|
|