feat: implement xorshift and rollBelow
This commit is contained in:
1 parent
35644f9771
commit
2e927d1f6c
1 file changed
+152
@@ -0,0 +1,152 @@
|
|||||||
|
#include "vf/LootTables.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace vf {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr uint32_t defaultLootSeed = 0x9e3779b9u;
|
||||||
|
|
||||||
|
uint32_t xorshift(uint32_t& state) {
|
||||||
|
state ^= state << 13;
|
||||||
|
state ^= state >> 17;
|
||||||
|
state ^= state << 5;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rollBelow(uint32_t& rng, int bound) {
|
||||||
|
if (bound <= 1) return 0;
|
||||||
|
return static_cast<int>(xorshift(rng) % static_cast<uint32_t>(bound));
|
||||||
|
}
|
||||||
|
|
||||||
|
int rollBetween(uint32_t& rng, int low, int high) {
|
||||||
|
if (high <= low) return low;
|
||||||
|
return low + rollBelow(rng, high - low + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendPool(LootTable& table, const LootEntry& entry) {
|
||||||
|
LootPool pool;
|
||||||
|
pool.entries.push_back(entry);
|
||||||
|
table.pools.push_back(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDropRule plainRule(Block block, ItemId drop, ToolType tool) {
|
||||||
|
BlockDropRule rule;
|
||||||
|
rule.block = block;
|
||||||
|
rule.drop = drop;
|
||||||
|
rule.harvestTool = tool;
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDropRule selfRule(Block block, ToolType tool) {
|
||||||
|
return plainRule(block, itemForBlock(block), tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDropRule gatedRule(Block block, ItemId drop, ToolType tool, ToolTier tier) {
|
||||||
|
BlockDropRule rule = plainRule(block, drop, tool);
|
||||||
|
rule.minimumTier = tier;
|
||||||
|
rule.toolRequiredForDrop = true;
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDropRule selfGatedRule(Block block, ToolType tool, ToolTier tier) {
|
||||||
|
return gatedRule(block, itemForBlock(block), tool, tier);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockDropRule oreRule(Block block, ItemId raw, int minCount, int maxCount, ToolTier tier) {
|
||||||
|
BlockDropRule rule = gatedRule(block, raw, ToolType::Pickaxe, tier);
|
||||||
|
rule.minCount = minCount;
|
||||||
|
rule.maxCount = maxCount;
|
||||||
|
rule.silkDrop = itemForBlock(block);
|
||||||
|
rule.fortuneMultiplies = true;
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blocks the palette has no item for still carry a rule: it names the tool class
|
||||||
|
// and harvest level, and records that the block yields nothing rather than
|
||||||
|
// inventing an item that Item.h does not have.
|
||||||
|
BlockDropRule barrenRule(Block block, ToolType tool) { return plainRule(block, ItemId::None, tool); }
|
||||||
|
|
||||||
|
BlockDropRule barrenGatedRule(Block block, ToolType tool, ToolTier tier) {
|
||||||
|
return gatedRule(block, ItemId::None, tool, tier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wooden crafted blocks salvage back to the planks they were built from.
|
||||||
|
BlockDropRule plankSalvage(Block block, int count = 1) {
|
||||||
|
BlockDropRule rule = plainRule(block, ItemId::Planks, ToolType::Axe);
|
||||||
|
rule.minCount = count;
|
||||||
|
rule.maxCount = count;
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The palette carries exactly one broken stone item, so the overworld stone
|
||||||
|
// family salvages to cobblestone.
|
||||||
|
BlockDropRule stoneSalvage(Block block) {
|
||||||
|
return gatedRule(block, ItemId::Cobblestone, ToolType::Pickaxe, ToolTier::Wood);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BlockDropRule> buildBlockRules() {
|
||||||
|
std::vector<BlockDropRule> rules;
|
||||||
|
rules.reserve(static_cast<std::size_t>(Block::Count));
|
||||||
|
auto add = [&rules](const BlockDropRule& rule) { rules.push_back(rule); };
|
||||||
|
|
||||||
|
add(barrenRule(Block::Air, ToolType::None));
|
||||||
|
|
||||||
|
BlockDropRule grass = plainRule(Block::Grass, ItemId::Dirt, ToolType::Shovel);
|
||||||
|
grass.silkDrop = ItemId::Grass;
|
||||||
|
add(grass);
|
||||||
|
|
||||||
|
add(selfRule(Block::Dirt, ToolType::Shovel));
|
||||||
|
|
||||||
|
BlockDropRule stone = gatedRule(Block::Stone, ItemId::Cobblestone, ToolType::Pickaxe,
|
||||||
|
ToolTier::Wood);
|
||||||
|
stone.silkDrop = ItemId::Stone;
|
||||||
|
stone.firedDrop = ItemId::Stone;
|
||||||
|
add(stone);
|
||||||
|
|
||||||
|
add(selfRule(Block::Sand, ToolType::Shovel));
|
||||||
|
add(selfRule(Block::Wood, ToolType::Axe));
|
||||||
|
|
||||||
|
// No sapling in the palette, so a wood cutting stands in as the replantable
|
||||||
|
// drop, the way the salvaged leaf table already does.
|
||||||
|
BlockDropRule leaves = plainRule(Block::Leaves, ItemId::Wood, shearToolType);
|
||||||
|
leaves.dropChance = 0.05f;
|
||||||
|
leaves.chancePerFortune = 0.04f;
|
||||||
|
leaves.silkDrop = ItemId::Leaves;
|
||||||
|
leaves.shearHarvest = true;
|
||||||
|
leaves.bonusDrop = ItemId::Stick;
|
||||||
|
leaves.bonusChance = 0.02f;
|
||||||
|
leaves.bonusMax = 2;
|
||||||
|
add(leaves);
|
||||||
|
|
||||||
|
add(barrenRule(Block::Water, ToolType::None));
|
||||||
|
add(selfRule(Block::Snow, ToolType::Shovel));
|
||||||
|
add(oreRule(Block::CoalOre, ItemId::CoalLump, 1, 1, ToolTier::Wood));
|
||||||
|
|
||||||
|
BlockDropRule ironOre = oreRule(Block::IronOre, ItemId::IronOre, 1, 1, ToolTier::Stone);
|
||||||
|
ironOre.firedDrop = ItemId::IronIngot;
|
||||||
|
add(ironOre);
|
||||||
|
|
||||||
|
BlockDropRule goldOre = oreRule(Block::GoldOre, ItemId::GoldOre, 1, 1, ToolTier::Iron);
|
||||||
|
goldOre.firedDrop = ItemId::GoldIngot;
|
||||||
|
add(goldOre);
|
||||||
|
|
||||||
|
add(selfRule(Block::Gravel, ToolType::Shovel));
|
||||||
|
|
||||||
|
BlockDropRule glowstone = oreRule(Block::Glowstone, ItemId::Glowstone, 2, 4, ToolTier::None);
|
||||||
|
glowstone.toolRequiredForDrop = false;
|
||||||
|
add(glowstone);
|
||||||
|
|
||||||
|
BlockDropRule cobblestone = selfGatedRule(Block::Cobblestone, ToolType::Pickaxe, ToolTier::Wood);
|
||||||
|
cobblestone.firedDrop = ItemId::Stone;
|
||||||
|
add(cobblestone);
|
||||||
|
|
||||||
|
add(selfRule(Block::Planks, ToolType::Axe));
|
||||||
|
add(selfGatedRule(Block::Sandstone, ToolType::Pickaxe, ToolTier::Wood));
|
||||||
|
|
||||||
|
// Ice melts away unless it is taken whole.
|
||||||
|
BlockDropRule ice = barrenRule(Block::Ice, ToolType::Pickaxe);
|
||||||
|
ice.silkDrop = ItemId::Ice;
|
||||||
|
add(ice);
|
||||||
|
|
||||||
Reference in new issue
Block a user