Browse Source

Introduce GetTranslatedItemName/GetTranslatedItemNameMagical

pull/5745/head^2
obligaron 3 years ago committed by Anders Jenbo
parent
commit
0426908988
  1. 174
      Source/items.cpp
  2. 26
      test/pack_test.cpp

174
Source/items.cpp

@ -42,6 +42,7 @@
#include "stores.h"
#include "utils/format_int.hpp"
#include "utils/language.h"
#include "utils/log.hpp"
#include "utils/math.h"
#include "utils/stdcompat/algorithm.hpp"
#include "utils/str_cat.hpp"
@ -2258,6 +2259,164 @@ _item_indexes RndItemForMonsterLevel(int8_t monsterLevel)
});
}
StringOrView GetTranslatedItemName(const Item &item)
{
const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)];
if (item._iCreateInfo == 0) {
return _(baseItemData.iName);
} else if (item._iMiscId == IMISC_BOOK) {
std::string name;
const string_view spellName = pgettext("spell", GetSpellData(item._iSpell).sNameText);
StrAppend(name, _(baseItemData.iName));
StrAppend(name, spellName);
return name;
} else if (item._iMiscId == IMISC_EAR) {
return fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} will be a Character Name */ "Ear of {:s}")), item._iIName);
} else if (item._iMiscId > IMISC_OILFIRST && item._iMiscId < IMISC_OILLAST) {
for (size_t i = 0; i < 10; i++) {
if (OilMagic[i] != item._iMiscId)
continue;
return _(OilNames[i]);
}
app_fatal("unkown oil");
} else if (item._itype == ItemType::Staff && item._iSpell != SpellID::Null && item._iMagical != ITEM_QUALITY_UNIQUE) {
return GenerateStaffName(baseItemData, item._iSpell, true);
} else {
return _(baseItemData.iName);
}
}
std::string GetTranslatedItemNameMagical(const Item &item)
{
std::string identifiedName;
const auto &baseItemData = AllItemsList[static_cast<size_t>(item.IDidx)];
int lvl = item._iCreateInfo & CF_LEVEL;
bool onlygood = (item._iCreateInfo & (CF_ONLYGOOD | CF_SMITHPREMIUM | CF_BOY | CF_WITCH)) != 0;
uint32_t currentSeed = GetLCGEngineState();
SetRndSeed(item._iSeed);
int minlvl;
int maxlvl;
if ((item._iCreateInfo & CF_SMITHPREMIUM) != 0) {
AdvanceRndSeed(); // RndVendorItem
AdvanceRndSeed(); // GetItemAttrs
minlvl = lvl / 2;
maxlvl = lvl;
} else if ((item._iCreateInfo & CF_BOY) != 0) {
AdvanceRndSeed(); // RndVendorItem
AdvanceRndSeed(); // GetItemAttrs
minlvl = lvl;
maxlvl = lvl * 2;
} else if ((item._iCreateInfo & CF_WITCH) != 0) {
AdvanceRndSeed(); // RndVendorItem
AdvanceRndSeed(); // GetItemAttrs
int iblvl = -1;
if (GenerateRnd(100) <= 5)
iblvl = 2 * lvl;
if (iblvl == -1 && item._iMiscId == IMISC_STAFF)
iblvl = 2 * lvl;
minlvl = iblvl / 2;
maxlvl = iblvl;
} else {
AdvanceRndSeed(); // GetItemAttrs
int iblvl = GetItemBLevel(lvl, item._iMiscId, onlygood, item._iCreateInfo & CF_UPER15);
minlvl = iblvl / 2;
maxlvl = iblvl;
AdvanceRndSeed(); // CheckUnique
}
if (minlvl > 25)
minlvl = 25;
bool hellfireItem = (item.dwBuff & CF_HELLFIRE) == CF_HELLFIRE;
AffixItemType affixItemType = AffixItemType::None;
switch (item._itype) {
case ItemType::Sword:
case ItemType::Axe:
case ItemType::Mace:
affixItemType = AffixItemType::Weapon;
break;
case ItemType::Bow:
affixItemType = AffixItemType::Bow;
break;
case ItemType::Shield:
affixItemType = AffixItemType::Shield;
break;
case ItemType::LightArmor:
case ItemType::Helm:
case ItemType::MediumArmor:
case ItemType::HeavyArmor:
affixItemType = AffixItemType::Armor;
break;
case ItemType::Staff: {
bool allowspells = !hellfireItem || ((item._iCreateInfo & CF_SMITHPREMIUM) == 0);
if (!allowspells)
affixItemType = AffixItemType::Staff;
else if (!hellfireItem && FlipCoin(4)) {
affixItemType = AffixItemType::Staff;
} else {
AdvanceRndSeed(); // Spell
AdvanceRndSeed(); // Charges
int preidx = GetStaffPrefixId(maxlvl, onlygood, hellfireItem);
if (preidx == -1 || item._iSpell == SpellID::Null) {
// This can happen, if the item is hacked or a bug in the logic exists
LogWarn("GetTranslatedItemNameMagical failed for item '{}' with preidx '{}' and spellid '{}'", item._iIName, preidx, static_cast<std::underlying_type_t<SpellID>>(item._iSpell));
identifiedName = item._iIName;
} else {
identifiedName = GenerateStaffNameMagical(baseItemData, item._iSpell, preidx, true);
}
}
break;
}
case ItemType::Ring:
case ItemType::Amulet:
affixItemType = AffixItemType::Misc;
break;
case ItemType::None:
case ItemType::Misc:
case ItemType::Gold:
break;
}
if (affixItemType != AffixItemType::None) {
const PLStruct *pPrefix = nullptr;
const PLStruct *pSufix = nullptr;
GetItemPowerPrefixAndSuffix(
minlvl, maxlvl, affixItemType, onlygood, hellfireItem,
[&pPrefix](const PLStruct &prefix) {
pPrefix = &prefix;
// GenerateRnd(prefix.power.param2 - prefix.power.param2 + 1)
AdvanceRndSeed();
switch (pPrefix->power.type) {
case IPL_TOHIT_DAMP:
AdvanceRndSeed();
AdvanceRndSeed();
break;
case IPL_TOHIT_DAMP_CURSE:
AdvanceRndSeed();
break;
}
},
[&pSufix](const PLStruct &suffix) {
pSufix = &suffix;
});
identifiedName = GenerateMagicItemName(_(baseItemData.iName), pPrefix, pSufix, true);
if (!StringInPanel(identifiedName.c_str())) {
identifiedName = GenerateMagicItemName(_(baseItemData.iSName), pPrefix, pSufix, true);
}
}
SetRndSeed(currentSeed);
return identifiedName;
}
} // namespace
bool IsItemAvailable(int i)
@ -4570,11 +4729,16 @@ void Item::updateRequiredStatsCacheForPlayer(const Player &player)
StringOrView Item::getName() const
{
string_view view;
if (_iIdentified)
view = _iIName;
view = _iName;
return view;
if (isEmpty()) {
return string_view("");
} else if (!_iIdentified || _iCreateInfo == 0 || _iMagical == ITEM_QUALITY_NORMAL) {
return GetTranslatedItemName(*this);
} else if (_iMagical == ITEM_QUALITY_UNIQUE) {
const auto &baseItemData = AllItemsList[static_cast<size_t>(IDidx)];
return _(UniqueItems[_iUid].UIName);
} else {
return GetTranslatedItemNameMagical(*this);
}
}
bool CornerStoneStruct::isAvailable()

26
test/pack_test.cpp

@ -110,6 +110,21 @@ typedef struct TestItemStruct {
int IDidx;
} TestItemStruct;
static void TestItemNameGeneration(const Item &item)
{
bool allowIdentified = (item._iMiscId != IMISC_EAR); // Ears can't be identified. Item::getName() doesn't handle it, so don't test it.
ASSERT_EQ(allowIdentified & item._iIdentified, item._iIdentified);
Item testItem = item;
testItem._iIdentified = false;
ASSERT_STREQ(testItem.getName().str().data(), testItem._iName) << "unidentified name";
if (allowIdentified) {
testItem._iIdentified = true;
ASSERT_STREQ(testItem.getName().str().data(), testItem._iIName) << "identified name";
}
}
static void CompareItems(const Item &item1, const TestItemStruct &item2)
{
ASSERT_STREQ(item1._iIName, item2._iIName);
@ -378,6 +393,7 @@ TEST_F(PackTest, UnPackItem_diablo)
const ItemPack packed = SwappedLE(PackedDiabloItems[i]);
UnPackItem(packed, *MyPlayer, id, false);
CompareItems(id, DiabloItems[i]);
TestItemNameGeneration(id);
PackItem(is, id, gbIsHellfire);
ComparePackedItems(is, packed);
@ -450,6 +466,7 @@ TEST_F(PackTest, UnPackItem_spawn)
const ItemPack packed = SwappedLE(PackedSpawnItems[i]);
UnPackItem(packed, *MyPlayer, id, false);
CompareItems(id, SpawnItems[i]);
TestItemNameGeneration(id);
PackItem(is, id, gbIsHellfire);
ComparePackedItems(is, packed);
@ -495,6 +512,7 @@ TEST_F(PackTest, UnPackItem_diablo_multiplayer)
const ItemPack packed = SwappedLE(PackedDiabloMPItems[i]);
UnPackItem(packed, *MyPlayer, id, false);
CompareItems(id, DiabloMPItems[i]);
TestItemNameGeneration(id);
PackItem(is, id, gbIsHellfire);
ComparePackedItems(is, packed);
@ -576,7 +594,7 @@ const ItemPack PackedHellfireItems[] = {
{ 1403842263, 858, 70, 5, 90, 90, 0, 0, 0, 0 }, // Demon Plate Armor
{ 1543909415, 284, 86, 0, 0, 0, 0, 0, 0, 0 }, // Oil of Fortitude
{ 1572202402, 769, 157, 5, 0, 0, 0, 0, 0, 0 }, // Ring of Regha
{ 1572202657, 257, 156, 5, 0, 0, 0, 0, 0, 0 }, // Bronze Ring of dexterity
{ 1572202657, 257, 156, 3, 0, 0, 0, 0, 0, 0 }, // Bronze Ring of dexterity
{ 1642077210, 264, 84, 0, 0, 0, 0, 0, 0, 0 }, // Oil of Accuracy
{ 2049461998, 388, 35, 0, 0, 0, 0, 0, 0, 0 }, // Blacksmith Oil
{ 2054447852, 2050, 151, 3, 25, 25, 0, 0, 0, 0 }, // Spider's Staff of devastation
@ -709,6 +727,7 @@ TEST_F(PackTest, UnPackItem_hellfire)
const ItemPack packed = SwappedLE(PackedHellfireItems[i]);
UnPackItem(packed, *MyPlayer, id, true);
CompareItems(id, HellfireItems[i]);
TestItemNameGeneration(id);
PackItem(is, id, gbIsHellfire);
is.dwBuff &= ~CF_HELLFIRE;
@ -726,6 +745,7 @@ TEST_F(PackTest, UnPackItem_diablo_strip_hellfire_items)
gbIsSpawn = false;
UnPackItem(is, *MyPlayer, id, true);
TestItemNameGeneration(id);
ASSERT_EQ(id._itype, ItemType::None);
}
@ -736,6 +756,7 @@ TEST_F(PackTest, UnPackItem_empty)
Item id;
UnPackItem(is, *MyPlayer, id, false);
TestItemNameGeneration(id);
ASSERT_EQ(id._itype, ItemType::None);
}
@ -752,6 +773,7 @@ TEST_F(PackTest, PackItem_empty)
// Copy the value out before comparing to avoid loading a misaligned address.
const auto idx = is.idx;
ASSERT_EQ(SDL_SwapLE16(idx), 0xFFFF);
TestItemNameGeneration(id);
}
static void compareGold(const ItemPack &is, int iCurs)
@ -765,6 +787,7 @@ static void compareGold(const ItemPack &is, int iCurs)
ASSERT_EQ(id._ivalue, wvalue);
ASSERT_EQ(id._itype, ItemType::Gold);
ASSERT_EQ(id._iClass, ICLASS_GOLD);
TestItemNameGeneration(id);
ItemPack is2;
PackItem(is2, id, gbIsHellfire);
@ -797,6 +820,7 @@ TEST_F(PackTest, UnPackItem_ear)
UnPackItem(is, *MyPlayer, id, false);
ASSERT_STREQ(id._iName, "Ear of Dead-RogueDM");
ASSERT_EQ(id._ivalue, 3);
TestItemNameGeneration(id);
ItemPack is2;
PackItem(is2, id, gbIsHellfire);

Loading…
Cancel
Save