From 529853153ccc416ea97557ce8675b20a7bce98e2 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Mon, 7 Sep 2026 15:51:15 +0200 Subject: [PATCH] feat: add xorshift and rollBelow --- core/src/Enchant.cpp | 158 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 core/src/Enchant.cpp diff --git a/core/src/Enchant.cpp b/core/src/Enchant.cpp new file mode 100644 index 0000000..7768ab6 --- /dev/null +++ b/core/src/Enchant.cpp @@ -0,0 +1,158 @@ +#include "vf/Enchant.h" + +#include +#include + +namespace vf { + +namespace { + +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(xorshift(rng) % static_cast(bound)); +} + +float unitFloat(uint32_t& rng) { return static_cast(xorshift(rng)) / 4294967295.0f; } + +bool isProtectionFamily(EnchantKind kind) { + return kind == EnchantKind::Protection || kind == EnchantKind::FireProtection || + kind == EnchantKind::BlastProtection || kind == EnchantKind::ProjectileProtection; +} + +bool isDamageFamily(EnchantKind kind) { + return kind == EnchantKind::Sharpness || kind == EnchantKind::Smite || + kind == EnchantKind::BaneOfArthropods; +} + +bool isArmourTarget(Enchantment::Target target) { + return target == Enchantment::Target::Helmet || target == Enchantment::Target::Chestplate || + target == Enchantment::Target::Leggings || target == Enchantment::Target::Boots; +} + +bool isDiggerTarget(Enchantment::Target target) { + return target == Enchantment::Target::Pickaxe || target == Enchantment::Target::Shovel || + target == Enchantment::Target::Axe; +} + +int levelSpan(int base, int step, int level) { return base + (level - 1) * step; } + +} // namespace + +int maxEnchantLevel(EnchantKind kind) { + switch (kind) { + case EnchantKind::Protection: + case EnchantKind::FireProtection: + case EnchantKind::BlastProtection: + case EnchantKind::ProjectileProtection: + case EnchantKind::FeatherFalling: return 4; + case EnchantKind::Respiration: + case EnchantKind::Thorns: + case EnchantKind::Looting: + case EnchantKind::Unbreaking: + case EnchantKind::Fortune: return 3; + case EnchantKind::AquaAffinity: + case EnchantKind::SilkTouch: + case EnchantKind::Flame: + case EnchantKind::Infinity: + case EnchantKind::Mending: return 1; + case EnchantKind::Knockback: + case EnchantKind::FireAspect: + case EnchantKind::Punch: return 2; + case EnchantKind::Sharpness: + case EnchantKind::Smite: + case EnchantKind::BaneOfArthropods: + case EnchantKind::Efficiency: + case EnchantKind::Power: return 5; + default: return 1; + } +} + +int enchantWeight(EnchantKind kind) { + switch (kind) { + case EnchantKind::Protection: + case EnchantKind::Sharpness: + case EnchantKind::Efficiency: + case EnchantKind::Power: return 10; + case EnchantKind::FireProtection: + case EnchantKind::ProjectileProtection: + case EnchantKind::FeatherFalling: + case EnchantKind::Smite: + case EnchantKind::BaneOfArthropods: + case EnchantKind::Knockback: + case EnchantKind::Unbreaking: return 5; + case EnchantKind::BlastProtection: + case EnchantKind::Respiration: + case EnchantKind::AquaAffinity: + case EnchantKind::FireAspect: + case EnchantKind::Looting: + case EnchantKind::Fortune: + case EnchantKind::Punch: + case EnchantKind::Flame: + case EnchantKind::Mending: return 2; + default: return 1; + } +} + +int anvilCostMultiplier(EnchantKind kind) { + switch (enchantWeight(kind)) { + case 10: return 1; + case 5: return 2; + case 2: return 4; + default: return 8; + } +} + +int enchantMinCost(EnchantKind kind, int level) { + switch (kind) { + case EnchantKind::Protection: return levelSpan(1, 11, level); + case EnchantKind::FireProtection: return levelSpan(10, 8, level); + case EnchantKind::BlastProtection: return levelSpan(5, 8, level); + case EnchantKind::ProjectileProtection: return levelSpan(3, 6, level); + case EnchantKind::FeatherFalling: return levelSpan(5, 6, level); + case EnchantKind::Respiration: return 10 * level; + case EnchantKind::AquaAffinity: return 1; + case EnchantKind::Thorns: return levelSpan(10, 20, level); + case EnchantKind::Sharpness: return levelSpan(1, 11, level); + case EnchantKind::Smite: return levelSpan(5, 8, level); + case EnchantKind::BaneOfArthropods: return levelSpan(5, 8, level); + case EnchantKind::Knockback: return levelSpan(5, 20, level); + case EnchantKind::FireAspect: return levelSpan(10, 20, level); + case EnchantKind::Looting: return levelSpan(15, 9, level); + case EnchantKind::Efficiency: return levelSpan(1, 10, level); + case EnchantKind::SilkTouch: return 15; + case EnchantKind::Unbreaking: return levelSpan(5, 8, level); + case EnchantKind::Fortune: return levelSpan(15, 9, level); + case EnchantKind::Power: return levelSpan(1, 10, level); + case EnchantKind::Punch: return levelSpan(12, 20, level); + case EnchantKind::Flame: return 20; + case EnchantKind::Infinity: return 20; + case EnchantKind::Mending: return 25 * level; + default: return 1; + } +} + +int enchantMaxCost(EnchantKind kind, int level) { + switch (kind) { + case EnchantKind::Protection: return enchantMinCost(kind, level) + 11; + case EnchantKind::FireProtection: + case EnchantKind::BlastProtection: return enchantMinCost(kind, level) + 8; + case EnchantKind::ProjectileProtection: + case EnchantKind::FeatherFalling: return enchantMinCost(kind, level) + 6; + case EnchantKind::Respiration: return enchantMinCost(kind, level) + 30; + case EnchantKind::AquaAffinity: return 41; + case EnchantKind::Sharpness: + case EnchantKind::Smite: + case EnchantKind::BaneOfArthropods: return enchantMinCost(kind, level) + 20; + case EnchantKind::Power: return enchantMinCost(kind, level) + 15; + case EnchantKind::Punch: return enchantMinCost(kind, level) + 25; + default: return enchantMinCost(kind, level) + 50; + } +} +