feat: add weaponAttackDamage and weaponAttackSpeed to Equipment
This commit is contained in:
1 parent
f21ca33cdc
commit
c38bf7b07a
1 file changed
+159
@@ -151,3 +151,162 @@ const char* attributeName(AttributeModifier::Attribute attribute) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
float weaponAttackDamage(ItemId item) {
|
||||
if (!isTool(item)) return unarmedAttackDamage;
|
||||
const ItemInfo& info = itemInfo(item);
|
||||
switch (info.toolType) {
|
||||
case ToolType::Sword: return swordDamage(info.toolTier);
|
||||
case ToolType::Axe: return axeDamage(info.toolTier);
|
||||
case ToolType::Pickaxe: return pickaxeDamage(info.toolTier);
|
||||
case ToolType::Shovel: return pickaxeDamage(info.toolTier) + 0.5f;
|
||||
case ToolType::Hoe: return unarmedAttackDamage;
|
||||
case ToolType::None: break;
|
||||
}
|
||||
return unarmedAttackDamage;
|
||||
}
|
||||
|
||||
float weaponAttackSpeed(ItemId item) {
|
||||
if (!isTool(item)) return unarmedAttackSpeed;
|
||||
const ItemInfo& info = itemInfo(item);
|
||||
switch (info.toolType) {
|
||||
case ToolType::Sword: return 1.6f;
|
||||
case ToolType::Axe: return axeSpeed(info.toolTier);
|
||||
case ToolType::Pickaxe: return 1.2f;
|
||||
case ToolType::Shovel: return 1.0f;
|
||||
case ToolType::Hoe: return hoeSpeed(info.toolTier);
|
||||
case ToolType::None: break;
|
||||
}
|
||||
return unarmedAttackSpeed;
|
||||
}
|
||||
|
||||
float weaponAttackReach(ItemId item) {
|
||||
if (!isTool(item)) return unarmedAttackReach;
|
||||
switch (itemInfo(item).toolType) {
|
||||
case ToolType::Sword: return unarmedAttackReach + 0.5f;
|
||||
case ToolType::Axe:
|
||||
case ToolType::Hoe: return unarmedAttackReach + 0.25f;
|
||||
case ToolType::Pickaxe:
|
||||
case ToolType::Shovel:
|
||||
case ToolType::None: break;
|
||||
}
|
||||
return unarmedAttackReach;
|
||||
}
|
||||
|
||||
float armorWeightPenalty(int armorPoints) {
|
||||
if (armorPoints <= 0) return 0.0f;
|
||||
float penalty = 0.01f * static_cast<float>(armorPoints);
|
||||
return penalty > 0.35f ? 0.35f : penalty;
|
||||
}
|
||||
|
||||
void EquipmentStats::applyTo(CombatStats& stats) const {
|
||||
stats.armor = armor;
|
||||
stats.baseAttackDamage = attackDamage;
|
||||
stats.attackSpeed = attackSpeed;
|
||||
}
|
||||
|
||||
bool Equipment::accepts(EquipSlot slot, const MetaStack& stack) const {
|
||||
if (stack.empty()) return false;
|
||||
if (!isHandSlot(slot)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Equipment::equip(EquipSlot slot, const MetaStack& stack) {
|
||||
if (!accepts(slot, stack)) return false;
|
||||
hands[static_cast<std::size_t>(handIndex(slot))] = stack;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Equipment::equipArmor(const Armor& piece) {
|
||||
return equipArmorAt(equipSlotFor(piece.slot), piece);
|
||||
}
|
||||
|
||||
bool Equipment::equipArmorAt(EquipSlot slot, const Armor& piece) {
|
||||
if (!isArmorSlot(slot)) return false;
|
||||
if (piece.material == Armor::Material::None) return false;
|
||||
if (armorSlotFor(slot) != piece.slot) return false;
|
||||
worn.at(piece.slot) = piece;
|
||||
return true;
|
||||
}
|
||||
|
||||
MetaStack Equipment::unequip(EquipSlot slot) {
|
||||
if (!isHandSlot(slot)) return MetaStack{};
|
||||
MetaStack removed = hands[static_cast<std::size_t>(handIndex(slot))];
|
||||
hands[static_cast<std::size_t>(handIndex(slot))].clear();
|
||||
return removed;
|
||||
}
|
||||
|
||||
Armor Equipment::unequipArmor(EquipSlot slot) {
|
||||
if (!isArmorSlot(slot)) return Armor{};
|
||||
Armor& piece = worn.at(armorSlotFor(slot));
|
||||
Armor removed = piece;
|
||||
piece = Armor{};
|
||||
return removed;
|
||||
}
|
||||
|
||||
const MetaStack& Equipment::hand(EquipSlot slot) const {
|
||||
if (!isHandSlot(slot)) return noStack();
|
||||
return hands[static_cast<std::size_t>(handIndex(slot))];
|
||||
}
|
||||
|
||||
const Armor& Equipment::armorPiece(EquipSlot slot) const {
|
||||
Armor::Slot mapped = armorSlotFor(slot);
|
||||
if (mapped == Armor::Slot::Count) return noArmor();
|
||||
return worn.at(mapped);
|
||||
}
|
||||
|
||||
EquipmentStats Equipment::stats() const {
|
||||
EquipmentStats stats;
|
||||
stats.armor = worn;
|
||||
stats.armorPoints = worn.totalPoints();
|
||||
stats.armorToughness = worn.totalToughness();
|
||||
|
||||
for (int i = 0; i < static_cast<int>(Armor::Slot::Count); ++i) {
|
||||
Armor::Slot armorSlot = static_cast<Armor::Slot>(i);
|
||||
const Armor& piece = worn.at(armorSlot);
|
||||
if (!piece.worn()) continue;
|
||||
EquipSlot slot = equipSlotFor(armorSlot);
|
||||
addModifier(stats, AttributeModifier::Attribute::ArmorPoints,
|
||||
AttributeModifier::Operation::Add, static_cast<float>(armorPoints(piece)), slot);
|
||||
addModifier(stats, AttributeModifier::Attribute::ArmorToughness,
|
||||
AttributeModifier::Operation::Add, armorToughness(piece), slot);
|
||||
}
|
||||
|
||||
float weight = armorWeightPenalty(stats.armorPoints);
|
||||
stats.movementSpeed = 1.0f - weight;
|
||||
addModifier(stats, AttributeModifier::Attribute::MovementSpeed,
|
||||
AttributeModifier::Operation::MultiplyTotal, -weight, EquipSlot::Chest);
|
||||
|
||||
const MetaStack& weapon = hands[0];
|
||||
if (!weapon.empty()) {
|
||||
stats.weaponEnchants = weapon.meta.enchants;
|
||||
stats.attackDamage = weaponAttackDamage(weapon.item);
|
||||
stats.attackSpeed = weaponAttackSpeed(weapon.item);
|
||||
stats.attackReach = weaponAttackReach(weapon.item);
|
||||
stats.miningSpeed = toolTierSpeedMultiplier(itemInfo(weapon.item).toolTier);
|
||||
|
||||
int efficiency = weapon.meta.enchants.levelOf(EnchantKind::Efficiency);
|
||||
if (efficiency > 0) {
|
||||
float bonus = static_cast<float>(efficiency * efficiency + 1);
|
||||
stats.miningSpeed += bonus;
|
||||
addModifier(stats, AttributeModifier::Attribute::MiningSpeed,
|
||||
AttributeModifier::Operation::Add, bonus, EquipSlot::MainHand);
|
||||
}
|
||||
|
||||
addModifier(stats, AttributeModifier::Attribute::AttackDamage,
|
||||
AttributeModifier::Operation::Add, stats.attackDamage - unarmedAttackDamage,
|
||||
EquipSlot::MainHand);
|
||||
addModifier(stats, AttributeModifier::Attribute::AttackSpeed,
|
||||
AttributeModifier::Operation::Add, stats.attackSpeed - unarmedAttackSpeed,
|
||||
EquipSlot::MainHand);
|
||||
addModifier(stats, AttributeModifier::Attribute::AttackReach,
|
||||
AttributeModifier::Operation::Add, stats.attackReach - unarmedAttackReach,
|
||||
EquipSlot::MainHand);
|
||||
addModifier(stats, AttributeModifier::Attribute::MiningSpeed,
|
||||
AttributeModifier::Operation::Add,
|
||||
toolTierSpeedMultiplier(itemInfo(weapon.item).toolTier) - 1.0f,
|
||||
EquipSlot::MainHand);
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user