Browse Source

Introduce GetItemIndexForDroppableItem

pull/5605/head
obligaron 3 years ago committed by Anders Jenbo
parent
commit
79f423191c
  1. 172
      Source/items.cpp

172
Source/items.cpp

@ -1307,37 +1307,24 @@ void GetItemBonus(const Player &player, Item &item, int minlvl, int maxlvl, bool
}
}
_item_indexes RndUItem(Monster *monster)
_item_indexes GetItemIndexForDroppableItem(bool considerDropRate, tl::function_ref<bool(const ItemData &item)> isItemOkay)
{
static std::array<_item_indexes, 512> ril;
static std::array<_item_indexes, IDI_LAST * 2> ril;
int curlv = ItemsGetCurrlevel();
size_t ri = 0;
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) {
if (!IsItemAvailable(i))
continue;
bool okflag = true;
if (AllItemsList[i].iRnd == IDROP_NEVER)
okflag = false;
if (monster != nullptr) {
if (monster->level(sgGameInitInfo.nDifficulty) < AllItemsList[i].iMinMLvl)
okflag = false;
} else {
if (2 * curlv < AllItemsList[i].iMinMLvl)
okflag = false;
}
if (AllItemsList[i].itype == ItemType::Misc)
okflag = false;
if (AllItemsList[i].itype == ItemType::Gold)
okflag = false;
if (AllItemsList[i].iMiscId == IMISC_BOOK)
okflag = true;
if (AllItemsList[i].iSpell == SPL_RESURRECT && !gbIsMultiplayer)
okflag = false;
if (AllItemsList[i].iSpell == SPL_HEALOTHER && !gbIsMultiplayer)
okflag = false;
if (okflag && ri < ril.size()) {
const ItemData &item = AllItemsList[i];
if (item.iRnd == IDROP_NEVER)
continue;
if (IsAnyOf(item.iSpell, SPL_RESURRECT, SPL_HEALOTHER) && !gbIsMultiplayer)
continue;
if (!isItemOkay(item))
continue;
ril[ri] = static_cast<_item_indexes>(i);
ri++;
if (item.iRnd == IDROP_DOUBLE && considerDropRate) {
ril[ri] = static_cast<_item_indexes>(i);
ri++;
}
@ -1346,55 +1333,47 @@ _item_indexes RndUItem(Monster *monster)
return ril[GenerateRnd(static_cast<int>(ri))];
}
_item_indexes RndUItem(Monster *monster)
{
int itemMaxLevel = ItemsGetCurrlevel() * 2;
if (monster != nullptr)
itemMaxLevel = monster->level(sgGameInitInfo.nDifficulty);
return GetItemIndexForDroppableItem(false, [&itemMaxLevel](const ItemData &item) {
if (item.itype == ItemType::Misc && item.iMiscId == IMISC_BOOK)
return true;
if (itemMaxLevel < item.iMinMLvl)
return false;
if (IsAnyOf(item.itype, ItemType::Gold, ItemType::Misc))
return false;
return true;
});
}
_item_indexes RndAllItems()
{
if (GenerateRnd(100) > 25)
return IDI_GOLD;
static std::array<_item_indexes, 512> ril;
int curlv = ItemsGetCurrlevel();
size_t ri = 0;
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] = static_cast<_item_indexes>(i);
ri++;
}
}
return ril[GenerateRnd(static_cast<int>(ri))];
int itemMaxLevel = ItemsGetCurrlevel() * 2;
return GetItemIndexForDroppableItem(false, [&itemMaxLevel](const ItemData &item) {
if (itemMaxLevel < item.iMinMLvl)
return false;
return true;
});
}
_item_indexes RndTypeItems(ItemType itemType, int imid, int lvl)
{
static std::array<_item_indexes, 512> ril;
size_t ri = 0;
for (std::underlying_type_t<_item_indexes> i = IDI_GOLD; i <= IDI_LAST; i++) {
if (!IsItemAvailable(i))
continue;
bool okflag = true;
if (AllItemsList[i].iRnd == IDROP_NEVER)
okflag = false;
if (lvl * 2 < AllItemsList[i].iMinMLvl)
okflag = false;
if (AllItemsList[i].itype != itemType)
okflag = false;
if (imid != -1 && AllItemsList[i].iMiscId != imid)
okflag = false;
if (okflag && ri < ril.size()) {
ril[ri] = static_cast<_item_indexes>(i);
ri++;
}
}
return ril[GenerateRnd(static_cast<int>(ri))];
int itemMaxLevel = lvl * 2;
return GetItemIndexForDroppableItem(false, [&itemMaxLevel, &itemType, &imid](const ItemData &item) {
if (itemMaxLevel < item.iMinMLvl)
return false;
if (item.itype != itemType)
return false;
if (imid != -1 && item.iMiscId != imid)
return false;
return true;
});
}
_unique_items CheckUnique(Item &item, int lvl, int uper, bool recreate)
@ -1873,34 +1852,13 @@ bool SmithItemOk(const Player &player, const ItemData &item)
template <bool (*Ok)(const Player &, const ItemData &), bool ConsiderDropRate = false>
_item_indexes RndVendorItem(const Player &player, int minlvl, int maxlvl)
{
static std::array<_item_indexes, 512> ril;
size_t ri = 0;
for (std::underlying_type_t<_item_indexes> i = IDI_WARRIOR; i <= IDI_LAST; i++) {
if (!IsItemAvailable(i))
continue;
if (AllItemsList[i].iRnd == IDROP_NEVER)
continue;
if (!Ok(player, AllItemsList[i]))
continue;
if (AllItemsList[i].iMinMLvl < minlvl || AllItemsList[i].iMinMLvl > maxlvl)
continue;
ril[ri] = static_cast<_item_indexes>(i);
ri++;
if (ri >= ril.size())
break;
if (!ConsiderDropRate || AllItemsList[i].iRnd != IDROP_DOUBLE)
continue;
ril[ri] = static_cast<_item_indexes>(i);
ri++;
if (ri >= ril.size())
break;
}
return ril[GenerateRnd(static_cast<int>(ri))];
return GetItemIndexForDroppableItem(ConsiderDropRate, [&player, &minlvl, &maxlvl](const ItemData &item) {
if (!Ok(player, item))
return false;
if (item.iMinMLvl < minlvl || item.iMinMLvl > maxlvl)
return false;
return true;
});
}
_item_indexes RndSmithItem(const Player &player, int lvl)
@ -2232,31 +2190,9 @@ _item_indexes RndItemForMonsterLevel(int8_t monsterLevel)
if (GenerateRnd(100) > 25)
return IDI_GOLD;
static std::array<_item_indexes, 512> ril;
size_t ri = 0;
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] = static_cast<_item_indexes>(i);
ri++;
}
if (AllItemsList[i].iRnd != IDROP_NEVER && monsterLevel >= AllItemsList[i].iMinMLvl
&& ri < ril.size()) {
ril[ri] = static_cast<_item_indexes>(i);
ri++;
}
if (AllItemsList[i].iSpell == SPL_RESURRECT && !gbIsMultiplayer)
ri--;
if (AllItemsList[i].iSpell == SPL_HEALOTHER && !gbIsMultiplayer)
ri--;
}
int r = GenerateRnd(static_cast<int>(ri));
return ril[r];
return GetItemIndexForDroppableItem(true, [&monsterLevel](const ItemData &item) {
return item.iMinMLvl <= monsterLevel;
});
}
} // namespace

Loading…
Cancel
Save