- 移除 BattleStateMachine 和 BattleUnit 相关代码 - 新增 BattleContainer 和 DamageContext 结构体 - 重构伤害计算逻辑,使用高精度 decimal 进行计算 - 更新随机数生成器,支持基于用户和时间的种子生成 - 优化战斗信息结构,增加 OwnerID 字段
207 lines
6.3 KiB
Go
207 lines
6.3 KiB
Go
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
|
||
// }
|