52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package combat
|
|
|
|
import (
|
|
"math/rand"
|
|
)
|
|
|
|
const (
|
|
critChance = 0.15 // 15% crit chance
|
|
critMultiplier = 1.5
|
|
)
|
|
|
|
// DamageResult holds the outcome of a damage calculation.
|
|
type DamageResult struct {
|
|
FinalDamage int32
|
|
IsCritical bool
|
|
}
|
|
|
|
// CalcDamage computes final damage from base damage and attacker/defender stats.
|
|
// Formula: base * (1 + attackerStr/100) * (1 - defenderDex/200)
|
|
// Then roll for crit.
|
|
func CalcDamage(baseDamage int32, attackerStr, defenderDex int32) DamageResult {
|
|
attack := float64(baseDamage) * (1.0 + float64(attackerStr)/100.0)
|
|
defense := 1.0 - float64(defenderDex)/200.0
|
|
if defense < 0.1 {
|
|
defense = 0.1 // minimum 10% damage
|
|
}
|
|
|
|
dmg := attack * defense
|
|
isCrit := rand.Float64() < critChance
|
|
if isCrit {
|
|
dmg *= critMultiplier
|
|
}
|
|
|
|
final := int32(dmg)
|
|
if final < 1 {
|
|
final = 1
|
|
}
|
|
|
|
return DamageResult{FinalDamage: final, IsCritical: isCrit}
|
|
}
|
|
|
|
// CalcHeal computes final healing.
|
|
// Formula: base * (1 + casterInt/100)
|
|
func CalcHeal(baseHeal int32, casterInt int32) int32 {
|
|
heal := float64(baseHeal) * (1.0 + float64(casterInt)/100.0)
|
|
result := int32(heal)
|
|
if result < 1 {
|
|
result = 1
|
|
}
|
|
return result
|
|
}
|