Repository navigation
Expand file tree
/
Copy pathitems_test.cpp
More file actions
120 lines (92 loc) · 3.04 KB
/
Copy pathitems_test.cpp
File metadata and controls
120 lines (92 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <gtest/gtest.h>
#include <random>
#include "engine/random.hpp"
#include "items.h"
#include "player.h"
#include "spells.h"
#include "utils/str_cat.hpp"
namespace devilution {
namespace {
class ItemsTest : public ::testing::Test {
public:
void SetUp() override
{
Players.resize(1);
MyPlayer = &Players[0];
for (auto &flag : UniqueItemFlags)
flag = false;
}
static void SetUpTestSuite()
{
LoadItemData();
LoadSpellData();
gbIsSpawn = false;
gbIsMultiplayer = false; // to also test UniqueItemFlags
}
};
void GenerateAllUniques(bool hellfire, const size_t expectedUniques)
{
gbIsHellfire = hellfire;
std::mt19937 betterRng;
std::uniform_int_distribution<uint32_t> dist(0, std::numeric_limits<uint32_t>::max());
// Get seed for test run from time. If a test run fails, remember the seed and hardcode it here.
uint32_t testRunSeed = static_cast<uint32_t>(time(nullptr));
betterRng.seed(testRunSeed);
std::set<int> foundUniques;
constexpr int max_iterations = 1000000;
int iteration = 0;
for (int uniqueIndex = 0, n = static_cast<int>(UniqueItems.size()); uniqueIndex < n; ++uniqueIndex) {
if (!IsUniqueAvailable(uniqueIndex))
continue;
if (foundUniques.contains(uniqueIndex))
continue;
auto &uniqueItem = UniqueItems[uniqueIndex];
_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)
continue;
if (AllItemsList[j].iRnd != IDROP_NEVER)
uniqueBaseIndex = static_cast<_item_indexes>(j);
break;
}
if (uniqueBaseIndex == IDI_GOLD)
continue; // Unique not dropable (Quest-Unique)
auto &baseItemData = AllItemsList[static_cast<size_t>(uniqueBaseIndex)];
while (true) {
iteration += 1;
if (iteration > max_iterations)
FAIL() << StrCat("Item ", uniqueItem.UIName, " not found in ", max_iterations, " tries with test run seed ", testRunSeed);
Item testItem = {};
testItem._iMiscId = baseItemData.iMiscId;
std::uniform_int_distribution<int32_t> dist(0, INT_MAX);
SetRndSeed(dist(betterRng));
int targetLvl = uniqueItem.UIMinLvl;
int uper = 1;
if (uniqueItem.UIMinLvl - 4 > 0) {
uper = 15;
targetLvl = uniqueItem.UIMinLvl - 4;
}
SetupAllItems(*MyPlayer, testItem, uniqueBaseIndex, AdvanceRndSeed(), targetLvl, uper, true, false);
TryRandomUniqueItem(testItem, uniqueBaseIndex, targetLvl, uper, true, false);
SetupItem(testItem);
if (testItem._iMagical != ITEM_QUALITY_UNIQUE)
continue;
foundUniques.insert(testItem._iUid);
if (testItem._iUid == uniqueIndex)
break;
}
}
EXPECT_EQ(foundUniques.size(), expectedUniques) << StrCat("test run seed ", testRunSeed);
}
TEST_F(ItemsTest, AllDiabloUniquesCanDrop)
{
GenerateAllUniques(false, 79);
}
TEST_F(ItemsTest, AllHellfireUniquesCanDrop)
{
GenerateAllUniques(true, 99);
}
} // namespace
} // namespace devilution