feat: add xorshift and unitFloat
This commit is contained in:
1 parent
2e76ff9143
commit
0cc5b9527b
1 file changed
+177
@@ -0,0 +1,177 @@
|
||||
#include "vf/Damage.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace vf {
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t xorshift(uint32_t& state) {
|
||||
state ^= state << 13;
|
||||
state ^= state >> 17;
|
||||
state ^= state << 5;
|
||||
return state;
|
||||
}
|
||||
|
||||
float unitFloat(uint32_t& rng) { return static_cast<float>(xorshift(rng)) / 4294967295.0f; }
|
||||
|
||||
int rollBelow(uint32_t& rng, int bound) {
|
||||
if (bound <= 1) return 0;
|
||||
return static_cast<int>(xorshift(rng) % static_cast<uint32_t>(bound));
|
||||
}
|
||||
|
||||
// Vanilla per-slot durability bases, scaled by the material factor below.
|
||||
int slotDurabilityBase(Armor::Slot slot) {
|
||||
switch (slot) {
|
||||
case Armor::Slot::Helmet: return 11;
|
||||
case Armor::Slot::Chestplate: return 16;
|
||||
case Armor::Slot::Leggings: return 15;
|
||||
case Armor::Slot::Boots: return 13;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int materialDurabilityFactor(Armor::Material material) {
|
||||
switch (material) {
|
||||
case Armor::Material::Leather: return 5;
|
||||
case Armor::Material::Chain: return 15;
|
||||
case Armor::Material::Iron: return 15;
|
||||
case Armor::Material::Gold: return 7;
|
||||
case Armor::Material::Diamond: return 33;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int protectionPointsFor(const EnchantSet& enchants, DamageType type) {
|
||||
int points = 0;
|
||||
int general = enchants.levelOf(EnchantKind::Protection);
|
||||
if (general > 0 && type != DamageType::Void && type != DamageType::Starve) points += general;
|
||||
if (isFireDamage(type)) points += 2 * enchants.levelOf(EnchantKind::FireProtection);
|
||||
if (type == DamageType::Explosion) points += 2 * enchants.levelOf(EnchantKind::BlastProtection);
|
||||
if (isProjectileDamage(type)) {
|
||||
points += 2 * enchants.levelOf(EnchantKind::ProjectileProtection);
|
||||
}
|
||||
if (type == DamageType::Fall) points += 3 * enchants.levelOf(EnchantKind::FeatherFalling);
|
||||
return points;
|
||||
}
|
||||
|
||||
bool unbreakingBlocksWear(int unbreakingLevel, uint32_t& rng) {
|
||||
if (unbreakingLevel <= 0) return false;
|
||||
float ignoreChance = 0.6f + 0.4f / static_cast<float>(unbreakingLevel + 1);
|
||||
return unitFloat(rng) < ignoreChance;
|
||||
}
|
||||
|
||||
Vec3 knockbackAlong(const Vec3& heading, float strength) {
|
||||
Vec3 flat = normalize(Vec3{heading.x, 0.0f, heading.z});
|
||||
if (length(flat) <= 0.0f) flat = {1.0f, 0.0f, 0.0f};
|
||||
float horizontal = 0.4f + strength * 0.5f;
|
||||
return {flat.x * horizontal, 0.4f, flat.z * horizontal};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool bypassesArmor(DamageType type) {
|
||||
switch (type) {
|
||||
case DamageType::Void:
|
||||
case DamageType::Starve:
|
||||
case DamageType::Suffocation:
|
||||
case DamageType::Magic:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool bypassesInvulnerability(DamageType type) {
|
||||
return type == DamageType::Void || type == DamageType::Starve;
|
||||
}
|
||||
|
||||
bool bypassesMitigation(DamageType type) { return type == DamageType::Void; }
|
||||
|
||||
bool isFireDamage(DamageType type) {
|
||||
return type == DamageType::Fire || type == DamageType::Lava;
|
||||
}
|
||||
|
||||
bool isProjectileDamage(DamageType type) { return type == DamageType::Projectile; }
|
||||
|
||||
HurtSource meleeSource(int attackerId, const Vec3& origin, bool byPlayer) {
|
||||
HurtSource source;
|
||||
source.type = DamageType::Melee;
|
||||
source.origin = origin;
|
||||
source.attackerId = attackerId;
|
||||
source.ownerId = attackerId;
|
||||
source.byPlayer = byPlayer;
|
||||
return source;
|
||||
}
|
||||
|
||||
HurtSource projectileSource(int projectileId, int ownerId, const Vec3& origin, bool byPlayer) {
|
||||
HurtSource source;
|
||||
source.type = DamageType::Projectile;
|
||||
source.origin = origin;
|
||||
source.attackerId = projectileId;
|
||||
source.ownerId = ownerId;
|
||||
source.byPlayer = byPlayer;
|
||||
return source;
|
||||
}
|
||||
|
||||
HurtSource environmentSource(DamageType type, const Vec3& origin) {
|
||||
HurtSource source;
|
||||
source.type = type;
|
||||
source.origin = origin;
|
||||
source.fiery = isFireDamage(type);
|
||||
return source;
|
||||
}
|
||||
|
||||
Armor makeArmor(Armor::Material material, Armor::Slot slot) {
|
||||
Armor piece;
|
||||
piece.material = material;
|
||||
piece.slot = slot;
|
||||
piece.maxDurability = slotDurabilityBase(slot) * materialDurabilityFactor(material);
|
||||
piece.durability = piece.maxDurability;
|
||||
return piece;
|
||||
}
|
||||
|
||||
int armorPoints(const Armor& piece) {
|
||||
if (!piece.worn()) return 0;
|
||||
switch (piece.material) {
|
||||
case Armor::Material::Leather:
|
||||
switch (piece.slot) {
|
||||
case Armor::Slot::Helmet: return 1;
|
||||
case Armor::Slot::Chestplate: return 3;
|
||||
case Armor::Slot::Leggings: return 2;
|
||||
default: return 1;
|
||||
}
|
||||
case Armor::Material::Chain:
|
||||
switch (piece.slot) {
|
||||
case Armor::Slot::Helmet: return 2;
|
||||
case Armor::Slot::Chestplate: return 5;
|
||||
case Armor::Slot::Leggings: return 4;
|
||||
default: return 1;
|
||||
}
|
||||
case Armor::Material::Iron:
|
||||
switch (piece.slot) {
|
||||
case Armor::Slot::Helmet: return 2;
|
||||
case Armor::Slot::Chestplate: return 6;
|
||||
case Armor::Slot::Leggings: return 5;
|
||||
default: return 2;
|
||||
}
|
||||
case Armor::Material::Gold:
|
||||
switch (piece.slot) {
|
||||
case Armor::Slot::Helmet: return 2;
|
||||
case Armor::Slot::Chestplate: return 5;
|
||||
case Armor::Slot::Leggings: return 3;
|
||||
default: return 1;
|
||||
}
|
||||
case Armor::Material::Diamond:
|
||||
switch (piece.slot) {
|
||||
case Armor::Slot::Helmet: return 3;
|
||||
case Armor::Slot::Chestplate: return 8;
|
||||
case Armor::Slot::Leggings: return 6;
|
||||
default: return 3;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user