test: add more cases for testLootTables
This commit is contained in:
1 parent
2d5ad51975
commit
d87424e3c4
1 file changed
+165
@@ -478,3 +478,168 @@ VF_TEST(ironGolemsIgnoreLootingWhileZombiesDoNot) {
|
|||||||
LootContext looted = plain;
|
LootContext looted = plain;
|
||||||
addEnchant(looted.toolEnchants, EnchantKind::Looting, 3);
|
addEnchant(looted.toolEnchants, EnchantKind::Looting, 3);
|
||||||
|
|
||||||
|
int golem = registry.rollMob(Species::IronGolem, plain).countOf(ItemId::IronIngot);
|
||||||
|
golemLowest = std::min(golemLowest, golem);
|
||||||
|
golemHighest = std::max(golemHighest, golem);
|
||||||
|
golemLootedHighest = std::max(golemLootedHighest,
|
||||||
|
registry.rollMob(Species::IronGolem, looted)
|
||||||
|
.countOf(ItemId::IronIngot));
|
||||||
|
|
||||||
|
zombieHighest = std::max(zombieHighest,
|
||||||
|
registry.rollMob(Species::Zombie, plain)
|
||||||
|
.countOf(ItemId::RottenFlesh));
|
||||||
|
zombieLootedHighest = std::max(zombieLootedHighest,
|
||||||
|
registry.rollMob(Species::Zombie, looted)
|
||||||
|
.countOf(ItemId::RottenFlesh));
|
||||||
|
}
|
||||||
|
CHECK_EQ(golemLowest, 3);
|
||||||
|
CHECK_EQ(golemHighest, 5);
|
||||||
|
CHECK_EQ(golemLootedHighest, 5);
|
||||||
|
CHECK_EQ(zombieHighest, 2);
|
||||||
|
CHECK_EQ(zombieLootedHighest, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(villagersLeaveNothingBehindAndSayItInTheirRule) {
|
||||||
|
const LootRegistry& registry = lootRegistry();
|
||||||
|
const MobDropRule& villager = registry.mobRule(Species::Villager);
|
||||||
|
CHECK_EQ(villager.drop, ItemId::None);
|
||||||
|
CHECK_EQ(villager.rareDrop, ItemId::None);
|
||||||
|
CHECK(!villager.hostile);
|
||||||
|
CHECK(mobRuleTable(villager).empty());
|
||||||
|
|
||||||
|
for (int i = 0; i < 200; ++i) {
|
||||||
|
LootContext context = enchantedWith(ItemId::DiamondSword, EnchantKind::Looting, 3,
|
||||||
|
seedFor(i));
|
||||||
|
context.playerKill = true;
|
||||||
|
CHECK(registry.rollMob(Species::Villager, context).empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(everyStructureChestFillsInsideItsDeclaredBoundsAndOnlyFromItsOwnPool) {
|
||||||
|
const LootRegistry& registry = lootRegistry();
|
||||||
|
const struct { Structure structure; int lowest; int highest; } bounds[] = {
|
||||||
|
{Structure::Village, 3, 20}, {Structure::Dungeon, 2, 16},
|
||||||
|
{Structure::Mineshaft, 3, 40}, {Structure::Temple, 2, 32},
|
||||||
|
{Structure::NetherFortress, 2, 20}, {Structure::EndShip, 2, 18},
|
||||||
|
};
|
||||||
|
for (const auto& entry : bounds) {
|
||||||
|
const ChestFill& fill = registry.chestFill(entry.structure);
|
||||||
|
CHECK_EQ(fill.structure, entry.structure);
|
||||||
|
CHECK(!fill.pool.entries.empty());
|
||||||
|
|
||||||
|
int seenLowest = 1000;
|
||||||
|
int seenHighest = 0;
|
||||||
|
int strayItems = 0;
|
||||||
|
for (int i = 0; i < 700; ++i) {
|
||||||
|
LootRoll roll = registry.rollChest(entry.structure, contextWith(ItemId::None,
|
||||||
|
seedFor(i)));
|
||||||
|
seenLowest = std::min(seenLowest, roll.totalCount());
|
||||||
|
seenHighest = std::max(seenHighest, roll.totalCount());
|
||||||
|
for (const ItemSlot& stack : roll.items) {
|
||||||
|
if (!poolCanYield(fill.pool, stack.item)) ++strayItems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK_EQ(strayItems, 0);
|
||||||
|
CHECK(seenLowest >= entry.lowest);
|
||||||
|
CHECK(seenHighest <= entry.highest);
|
||||||
|
CHECK(seenHighest > seenLowest);
|
||||||
|
}
|
||||||
|
CHECK(registry.rollChest(Structure::Count, contextWith(ItemId::None, 1u)).empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(structureChestCountsStayInsideTheRangeTheStructureDeclares) {
|
||||||
|
const LootRegistry& registry = lootRegistry();
|
||||||
|
for (int index = 0; index < static_cast<int>(Structure::Count); ++index) {
|
||||||
|
Structure structure = static_cast<Structure>(index);
|
||||||
|
const ChestFill& fill = registry.chestFill(structure);
|
||||||
|
CHECK(fill.chestsMin >= 1);
|
||||||
|
CHECK(fill.chestsMax >= fill.chestsMin);
|
||||||
|
|
||||||
|
int seenLowest = 1000;
|
||||||
|
int seenHighest = 0;
|
||||||
|
for (int i = 0; i < 400; ++i) {
|
||||||
|
int count = registry.chestCountFor(structure, seedFor(i));
|
||||||
|
seenLowest = std::min(seenLowest, count);
|
||||||
|
seenHighest = std::max(seenHighest, count);
|
||||||
|
}
|
||||||
|
CHECK_EQ(seenLowest, fill.chestsMin);
|
||||||
|
CHECK_EQ(seenHighest, fill.chestsMax);
|
||||||
|
CHECK_EQ(registry.chestCountFor(structure, 77u), registry.chestCountFor(structure, 77u));
|
||||||
|
}
|
||||||
|
CHECK_EQ(registry.chestCountFor(Structure::Count, 5u), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(diamondGearOnlyTurnsUpInTheEndShipAndPickaxesOnlyInMineshafts) {
|
||||||
|
const LootRegistry& registry = lootRegistry();
|
||||||
|
int endShipSwords = 0;
|
||||||
|
int mineshaftPickaxes = 0;
|
||||||
|
int elsewhereGear = 0;
|
||||||
|
|
||||||
|
for (int index = 0; index < static_cast<int>(Structure::Count); ++index) {
|
||||||
|
Structure structure = static_cast<Structure>(index);
|
||||||
|
for (int i = 0; i < 600; ++i) {
|
||||||
|
LootRoll roll = registry.rollChest(structure, contextWith(ItemId::None, seedFor(i)));
|
||||||
|
int swords = roll.countOf(ItemId::DiamondSword);
|
||||||
|
int pickaxes = roll.countOf(ItemId::IronPickaxe);
|
||||||
|
if (structure == Structure::EndShip) {
|
||||||
|
endShipSwords += swords;
|
||||||
|
} else {
|
||||||
|
elsewhereGear += swords;
|
||||||
|
}
|
||||||
|
if (structure == Structure::Mineshaft) {
|
||||||
|
mineshaftPickaxes += pickaxes;
|
||||||
|
} else {
|
||||||
|
elsewhereGear += pickaxes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK(endShipSwords > 0);
|
||||||
|
CHECK(mineshaftPickaxes > 0);
|
||||||
|
CHECK_EQ(elsewhereGear, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(fishingSplitsIntoThreePoolsAndLuckShiftsTheWeightsAwayFromJunk) {
|
||||||
|
const LootRegistry& registry = lootRegistry();
|
||||||
|
int plainFish = 0;
|
||||||
|
int plainTreasure = 0;
|
||||||
|
int plainJunk = 0;
|
||||||
|
int luckyTreasure = 0;
|
||||||
|
int luckyJunk = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4000; ++i) {
|
||||||
|
FishingLoot plain = registry.rollFishing(contextWith(ItemId::WoodHoe, seedFor(i)));
|
||||||
|
CHECK_EQ(plain.fishWeight, fishingFishWeight);
|
||||||
|
CHECK_EQ(plain.treasureWeight, fishingTreasureWeight);
|
||||||
|
CHECK_EQ(plain.junkWeight, fishingJunkWeight);
|
||||||
|
if (plain.pool == FishingLoot::Pool::Fish) ++plainFish;
|
||||||
|
if (plain.pool == FishingLoot::Pool::Treasure) ++plainTreasure;
|
||||||
|
if (plain.pool == FishingLoot::Pool::Junk) ++plainJunk;
|
||||||
|
|
||||||
|
FishingLoot lucky = registry.rollFishing(
|
||||||
|
enchantedWith(ItemId::WoodHoe, EnchantKind::Fortune, 3, seedFor(i)));
|
||||||
|
CHECK_EQ(lucky.treasureWeight, fishingTreasureWeight + 3 * fishingLuckWeightShift);
|
||||||
|
CHECK_EQ(lucky.junkWeight, fishingJunkWeight - 3 * fishingLuckWeightShift);
|
||||||
|
if (lucky.pool == FishingLoot::Pool::Treasure) ++luckyTreasure;
|
||||||
|
if (lucky.pool == FishingLoot::Pool::Junk) ++luckyJunk;
|
||||||
|
}
|
||||||
|
CHECK(plainFish > plainTreasure + plainJunk);
|
||||||
|
CHECK(plainTreasure > 0);
|
||||||
|
CHECK(plainJunk > 0);
|
||||||
|
CHECK(luckyTreasure > plainTreasure);
|
||||||
|
CHECK(luckyJunk < plainJunk);
|
||||||
|
|
||||||
|
// An over-cap Fortune cannot come from addEnchant, but it can be placed on
|
||||||
|
// a set by hand, and it must clamp the junk weight at nothing rather than
|
||||||
|
// going negative and eating the treasure band.
|
||||||
|
int junkAtHighLuck = 0;
|
||||||
|
for (int i = 0; i < 500; ++i) {
|
||||||
|
LootContext overCharged = contextWith(ItemId::WoodHoe, seedFor(i));
|
||||||
|
overCharged.toolEnchants.entries.push_back({EnchantKind::Fortune, 9});
|
||||||
|
FishingLoot outcome = registry.rollFishing(overCharged);
|
||||||
|
CHECK_EQ(outcome.junkWeight, 0);
|
||||||
|
CHECK_EQ(outcome.treasureWeight, fishingTreasureWeight + 9 * fishingLuckWeightShift);
|
||||||
|
if (outcome.pool == FishingLoot::Pool::Junk) ++junkAtHighLuck;
|
||||||
|
}
|
||||||
|
CHECK_EQ(junkAtHighLuck, 0);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user