Files
bl/logic/service/fight/info/BattlePetEntity.go
昔念 1405bf5ee9 refactor(fight): 重构战斗模块
- 移除 BattleStateMachine 和 BattleUnit 相关代码
- 新增 BattleContainer 和 DamageContext 结构体
- 重构伤害计算逻辑,使用高精度 decimal 进行计算
- 更新随机数生成器,支持基于用户和时间的种子生成
- 优化战斗信息结构,增加 OwnerID 字段
2025-08-25 12:58:08 +08:00

207 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package info
import (
"blazing/modules/blazing/model"
"math/rand/v2"
"sync"
"github.com/shopspring/decimal"
"github.com/tnnmigga/enum"
)
// DamageMultiplierZone 伤害乘算区枚举使用enum包定义
type DamageMultiplierZone int
var DamageMultiplierZoneEnum = enum.New[struct {
POWER_ADDITION_ZONE DamageMultiplierZone // 威力加算区,直接加成威力值
POWER_MULTIPLIER_ZONE DamageMultiplierZone // 威力乘算区,倍率调整(如威力倍数)
}]()
type BattlePetEntity struct {
// /host *BattleInputSourceEntity // 宠物的主人(输入源)
//uuid string // 唯一标识
*model.PetInfo
GainHp int64 // 获得的生命值
Capturable bool // 是否可捕获
// 状态条件(如中毒、烧伤等)
statusConditions sync.Map // key: StatusCondition, value: int (剩余回合)
// 状态变化值
attackStat int
defenseStat int
specialAttackStat int
specialDefenseStat int
speedStat int
accuracyStat int
skills [4]*BattleSkillEntity // 技能槽最多4个技能
// 特殊属性
Perseverance int // 毅力值:抵消致命伤
Stubborn bool // 顽强特性
StubbornProbability int // 顽强触发概率
Revival bool // 回神特性
RevivalProbability int // 回神触发概率
Definitely int // 必定命中概率
Dodge int // 闪避概率
// 护盾相关
MaxShield int64 // 最大护盾值
Shield int64 // 当前护盾值
CountShield int // 次数盾
// 属性变化回合
//petAttributeRound map[BattleRoundStarEffect]int // 属性变化类型 -> 剩余回合
petImmunityEffectIds map[int]int // 免疫效果ID -> 剩余回合 (-1表示永久)
petImmunityBuffs map[string]int // 免疫buff效果ID -> 剩余回合 (-1表示永久)
IsDead bool // 是否死亡
otherRates map[DamageMultiplierZone]decimal.Decimal // 各伤害乘算区倍率使用高精度decimal
// 战斗开始时拥有的特殊buff
//battleStartHavingBuffs []buff.BattleBuffInterface
}
func (b *BattlePetEntity) GetSpeed() uint32 {
b.calculateRealValue(int64(b.Speed), b.speedStat)
return 0
}
// calculateRealValue 计算实际属性值根据状态变化计算实际值
// value 基础属性值
// stat 状态变化值(可正可负)
// 返回// 返回计算后的实际属性值确保结果至少为1
func (b *BattlePetEntity) calculateRealValue(value int64, stat int) int64 {
if stat == 0 {
if value <= 0 {
return 1
}
return value
} else if stat > 0 {
r := int64(float64(value) * (float64(stat+2) / 2.0))
if r <= 0 {
return 1
}
return r
} else {
r := int64(float64(value) * (2.0 / float64(2-stat)))
if r <= 0 {
return 1
}
return r
}
}
func CalculatePower(random *rand.Rand, context *DamageContext, isCritical bool) int64 {
}
// Calculate 伤害计算函数,返回最终伤害整数值
func Calculate(random *rand.Rand, context *DamageContext, isCritical bool) int64 {
// 初始化随机值范围217~255
if context.RandomValue() == -1 {
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:
damageReduction = context.GetOtherRate(DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE)
case SPECIAL:
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).
Div(defenseDec).
Div(decimal.NewFromInt(50)).
Add(decimal.NewFromInt(2)).
Mul(attackCount)
// 6. 同系加成属性相同则乘以同系加成倍率否则1
sameTypeBonus := decimal.NewFromFloat(1.0)
if context.Type == context.attackerPet.Type() {
sameTypeBonus = decimal.NewFromFloat(context.SameTypeRate)
}
// 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).
Mul(criticalRate).
Mul(damageReduction).
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)
if damage.LessThan(decimal.Zero) {
damage = decimal.Zero
}
}
// 返回最终伤害(整数部分)
return damage.IntPart()
}
// func CalculateDamage(attacker, defender *BattleUnit, power int, isCritical bool, r *rand.Rand) int {
// randomFactor := float64(r.Intn(39)+217) / 255.0
// levelZone := float64(attacker.Level*2) / float64(attacker.Level+defender.Level)
// base := ((float64(attacker.Atk) * float64(power) / float64(defender.Def)) / 50.0) + 2
// crit := 1.0
// if isCritical {
// crit = 1.5
// }
// damage := int((base*levelZone*randomFactor)*crit + 0.5)
// if damage < 1 {
// damage = 1
// }
// return damage
// }