refactor(fight): 重构伤害计算逻辑

- 优化了 DamageContext 结构体,增加了更多注释说明
- 添加了 initOtherRates、GetOtherRate、PutOtherRate 等方法,提高代码可读性和易用性
- 重写了 Calculate 函数,详细注释了伤害计算的每一步骤
- 增加了对随机值、同系加成、属性克制等逻辑的处理
- 优化了代码结构,提高了
This commit is contained in:
2025-08-11 21:40:53 +08:00
parent 37943a0002
commit 2ebec8ed05

View File

@@ -8,31 +8,33 @@ import (
"github.com/tnnmigga/enum"
)
// SkillType 枚举
// SkillType 技能类型枚举,区分物理和特殊技能
type SkillType int
const (
PHYSICAL SkillType = iota + 1
SPECIAL
PHYSICAL SkillType = iota + 1 // 物理技能
SPECIAL // 特殊技能
)
// DamageMultiplierZone 伤害乘算区枚举使用enum包定义
type DamageMultiplierZone int
var DamageMultiplierZoneEnum = enum.New[struct {
POWER_ADDITION_ZONE DamageMultiplierZone
POWER_MULTIPLIER_ZONE DamageMultiplierZone
ATK_RESISTANCE_ZONE DamageMultiplierZone
SP_ATK_RESISTANCE_ZONE DamageMultiplierZone
SPECIAL_EFFECT_MULTIPLIER_ZONE DamageMultiplierZone
ATTACK_COUNT_ZONE DamageMultiplierZone
FIX_DAMAGE_RESISTANCE_ZONE DamageMultiplierZone
POWER_ADDITION_ZONE DamageMultiplierZone // 威力加算区,直接加成威力值
POWER_MULTIPLIER_ZONE DamageMultiplierZone // 威力乘算区,倍率调整(如威力倍数)
ATK_RESISTANCE_ZONE DamageMultiplierZone // 物理伤害减免乘区默认1减伤50%对应0.5
SP_ATK_RESISTANCE_ZONE DamageMultiplierZone // 特殊伤害减免乘区默认1减伤50%对应0.5
SPECIAL_EFFECT_MULTIPLIER_ZONE DamageMultiplierZone // 特殊效果乘算区如Boss减伤等
ATTACK_COUNT_ZONE DamageMultiplierZone // 攻击次数乘算区如攻击2次对应2
FIX_DAMAGE_RESISTANCE_ZONE DamageMultiplierZone // 固定伤害减免区,直接减固定值
}]()
// Code 返回枚举对应整数值
func (z DamageMultiplierZone) Code() int {
return int(z)
}
// String 返回枚举名称字符串,方便调试打印
func (z DamageMultiplierZone) String() string {
switch z {
case DamageMultiplierZoneEnum.POWER_ADDITION_ZONE:
@@ -54,6 +56,7 @@ func (z DamageMultiplierZone) String() string {
}
}
// FromCode 根据整数值获取枚举
func FromCode(code int) (DamageMultiplierZone, error) {
switch code {
case 1:
@@ -75,37 +78,38 @@ func FromCode(code int) (DamageMultiplierZone, error) {
}
}
// Pet接口示例
// Pet 接口,表示战斗中的宠物实体,包含等级、类型和名称等
type Pet interface {
Level() int64
Type() SkillType
Name() string
}
// SkillInterface示例
// SkillInterface 接口,表示技能实体,包含技能类型和名称
type SkillInterface interface {
SkillType() SkillType
Name() string
}
// DamageContext 伤害上下文
// DamageContext 伤害计算上下文,包含攻击方、防御方宠物,技能信息,以及各种计算参数
type DamageContext struct {
attackerPet Pet
defenderPet Pet
skill SkillInterface
attackerPet Pet // 攻击宠物
defenderPet Pet // 防御宠物
skill SkillInterface // 技能
Type SkillType
BasePower int64
Attack int64
Defense int64
CriticalRate float64
SameTypeRate float64
Random int
Type SkillType // 技能属性类型(物理或特殊)
BasePower int64 // 基础威力值
Attack int64 // 攻击力
Defense int64 // 防御力
CriticalRate float64 // 暴击倍率默认2.0倍
SameTypeRate float64 // 同系加成倍率默认1.5倍
Random int // 随机值,默认-1表示未设置
otherRates map[DamageMultiplierZone]decimal.Decimal
extraRates map[string]decimal.Decimal
otherRates map[DamageMultiplierZone]decimal.Decimal // 各伤害乘算区倍率使用高精度decimal
extraRates map[string]decimal.Decimal // 额外倍率支持自定义key
}
// NewDamageContext 构造函数,初始化默认值
func NewDamageContext(attackerPet, defenderPet Pet, skill SkillInterface) *DamageContext {
ctx := &DamageContext{
attackerPet: attackerPet,
@@ -121,16 +125,18 @@ func NewDamageContext(attackerPet, defenderPet Pet, skill SkillInterface) *Damag
return ctx
}
// initOtherRates 初始化伤害乘算区的默认倍率值
func (c *DamageContext) initOtherRates() {
c.otherRates[DamageMultiplierZoneEnum.POWER_ADDITION_ZONE] = decimal.Zero
c.otherRates[DamageMultiplierZoneEnum.POWER_MULTIPLIER_ZONE] = decimal.NewFromInt(1)
c.otherRates[DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE] = decimal.NewFromInt(1)
c.otherRates[DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE] = decimal.NewFromInt(1)
c.otherRates[DamageMultiplierZoneEnum.SPECIAL_EFFECT_MULTIPLIER_ZONE] = decimal.NewFromInt(1)
c.otherRates[DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE] = decimal.NewFromInt(1)
c.otherRates[DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE] = decimal.Zero
c.otherRates[DamageMultiplierZoneEnum.POWER_ADDITION_ZONE] = decimal.Zero // 威力加成默认0
c.otherRates[DamageMultiplierZoneEnum.POWER_MULTIPLIER_ZONE] = decimal.NewFromInt(1) // 威力倍率默认1
c.otherRates[DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE] = decimal.NewFromInt(1) // 物理减伤默认1
c.otherRates[DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE] = decimal.NewFromInt(1) // 特殊减伤默认1
c.otherRates[DamageMultiplierZoneEnum.SPECIAL_EFFECT_MULTIPLIER_ZONE] = decimal.NewFromInt(1) // 特殊效果倍率默认1
c.otherRates[DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE] = decimal.NewFromInt(1) // 攻击次数默认1
c.otherRates[DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE] = decimal.Zero // 固定减伤默认0
}
// GetOtherRate 获取指定伤害乘算区的倍率
func (c *DamageContext) GetOtherRate(zone DamageMultiplierZone) decimal.Decimal {
if val, ok := c.otherRates[zone]; ok {
return val
@@ -138,17 +144,22 @@ func (c *DamageContext) GetOtherRate(zone DamageMultiplierZone) decimal.Decimal
return decimal.NewFromInt(1)
}
// PutOtherRate 设置指定伤害乘算区的倍率,支持链式调用
func (c *DamageContext) PutOtherRate(zone DamageMultiplierZone, value decimal.Decimal) *DamageContext {
switch zone {
case DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE:
// 固定伤害减免区,累加
c.otherRates[zone] = c.GetOtherRate(zone).Add(value)
case DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE:
// 攻击次数区,直接覆盖
c.otherRates[zone] = value
case DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE, DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE:
// 减伤乘算区乘法叠加只当value>0时
if value.GreaterThan(decimal.Zero) {
c.otherRates[zone] = c.GetOtherRate(zone).Mul(value)
}
default:
// 其他乘算区加法叠加且不小于0.1
r := c.GetOtherRate(zone).Add(value)
if r.LessThan(decimal.NewFromFloat(0.1)) {
r = decimal.NewFromFloat(0.1)
@@ -158,36 +169,44 @@ func (c *DamageContext) PutOtherRate(zone DamageMultiplierZone, value decimal.De
return c
}
// RandomValue 获取当前随机值,-1表示未设置
func (c *DamageContext) RandomValue() int {
return c.Random
}
// SetRandomValue 设置随机值,支持链式调用
func (c *DamageContext) SetRandomValue(r int) *DamageContext {
c.Random = r
return c
}
// PutExtraRate 设置自定义额外倍率
func (c *DamageContext) PutExtraRate(key string, value decimal.Decimal) {
c.extraRates[key] = value
}
// GetExtraRate 获取自定义额外倍率,返回倍率和是否存在
func (c *DamageContext) GetExtraRate(key string) (decimal.Decimal, bool) {
val, ok := c.extraRates[key]
return val, ok
}
// Calculate 伤害计算函数
// Calculate 伤害计算函数,返回最终伤害整数值
func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64 {
// 初始化随机值范围217~255
if context.RandomValue() == -1 {
context.SetRandomValue(random.Intn(39) + 217) // 217 ~ 255
context.SetRandomValue(random.Intn(39) + 217)
}
// 1. 计算等级因子 (level * 0.4 + 2)
levelFactor := decimal.NewFromInt(context.attackerPet.Level()).Mul(decimal.NewFromFloat(0.4)).Add(decimal.NewFromInt(2))
// 2. 计算威力因子 (基础威力 + 加算) * 乘算
powerAdd := context.GetOtherRate(DamageMultiplierZoneEnum.POWER_ADDITION_ZONE)
powerMul := context.GetOtherRate(DamageMultiplierZoneEnum.POWER_MULTIPLIER_ZONE)
powerZone := decimal.NewFromInt(context.BasePower).Add(powerAdd).Mul(powerMul)
// 3. 根据技能类型获取对应减伤乘算
damageReduction := decimal.NewFromFloat(1)
switch context.skill.SkillType() {
case PHYSICAL:
@@ -196,11 +215,13 @@ func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64
damageReduction = context.GetOtherRate(DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE)
}
// 4. 攻击次数倍率
attackCount := context.GetOtherRate(DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE)
attackDec := decimal.NewFromInt(context.Attack)
defenseDec := decimal.NewFromInt(context.Defense)
// 5. 基础伤害公式:等级因子 * 威力因子 * 攻击 / 防御 / 50 + 2然后乘以攻击次数
baseDamage := levelFactor.
Mul(powerZone).
Mul(attackDec).
@@ -209,22 +230,28 @@ func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64
Add(decimal.NewFromInt(2)).
Mul(attackCount)
// 6. 同系加成属性相同则乘以同系加成倍率否则1
sameTypeBonus := decimal.NewFromFloat(1.0)
if context.Type == context.attackerPet.Type() {
sameTypeBonus = decimal.NewFromFloat(context.SameTypeRate)
}
typeRate := decimal.NewFromFloat(1.2) // 这里要用你的克制逻辑替换
// 7. 属性克制倍率示例写死1.2,实际业务中请替换成具体逻辑)
typeRate := decimal.NewFromFloat(1.2)
// 8. 暴击倍率暴击时使用暴击倍率否则1
criticalRate := decimal.NewFromFloat(1.0)
if isCritical {
criticalRate = decimal.NewFromFloat(context.CriticalRate)
}
// 9. 技能特殊效果倍率
specialEffect := context.GetOtherRate(DamageMultiplierZoneEnum.SPECIAL_EFFECT_MULTIPLIER_ZONE)
// 10. 随机倍率随机值除以255
randomFactor := decimal.NewFromInt(int64(context.Random)).Div(decimal.NewFromInt(255))
// 11. 计算总伤害
damage := baseDamage.
Mul(sameTypeBonus).
Mul(typeRate).
@@ -233,8 +260,10 @@ func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64
Mul(specialEffect).
Mul(randomFactor)
// 12. 存储真实伤害到额外倍率,方便后续查询
context.PutExtraRate("REAL_DAMAGE", damage)
// 13. 应用固定伤害减免伤害不能低于0
fixReduction := context.GetOtherRate(DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE)
if fixReduction.GreaterThan(decimal.Zero) {
damage = damage.Sub(fixReduction)
@@ -243,5 +272,6 @@ func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64
}
}
// 返回最终伤害(整数部分)
return damage.IntPart()
}