From 1405bf5ee912dfffcabbda71cf6db5b950438629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Mon, 25 Aug 2025 12:58:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(fight):=20=E9=87=8D=E6=9E=84=E6=88=98?= =?UTF-8?q?=E6=96=97=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 BattleStateMachine 和 BattleUnit 相关代码 - 新增 BattleContainer 和 DamageContext 结构体 - 重构伤害计算逻辑,使用高精度 decimal 进行计算 - 更新随机数生成器,支持基于用户和时间的种子生成 - 优化战斗信息结构,增加 OwnerID 字段 --- logic/controller/fight.go | 1 + .../battle/container/BattleStateMachine.go | 23 -- .../service/fight/battle/container/battle.go | 49 +--- .../fight/battle/container/battle1v1.go | 42 ++- logic/service/fight/battle/damage/d.go | 22 -- logic/service/fight/battle/damage/damage.go | 277 ------------------ logic/service/fight/battle/random/random.go | 7 + .../battle/skill/effect/EffectContainer.go | 4 +- logic/service/fight/info/BattlePetEntity.go | 123 +++++++- .../fight/info/NoteReadyToFightInfo.go | 2 + 10 files changed, 172 insertions(+), 378 deletions(-) delete mode 100644 logic/service/fight/battle/container/BattleStateMachine.go delete mode 100644 logic/service/fight/battle/damage/d.go delete mode 100644 logic/service/fight/battle/damage/damage.go diff --git a/logic/controller/fight.go b/logic/controller/fight.go index efef721be..370b641d9 100644 --- a/logic/controller/fight.go +++ b/logic/controller/fight.go @@ -13,6 +13,7 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn c.IsFighting = true t1 := handler.NewTomeeHeader(2503, c.UserID) ttt := info.NoteReadyToFightInfo{ + OwnerID: data.Head.UserID, FightId: 3, } ttt.OurInfo = info.FightUserInfo{UserID: c.UserID} diff --git a/logic/service/fight/battle/container/BattleStateMachine.go b/logic/service/fight/battle/container/BattleStateMachine.go deleted file mode 100644 index 7ea00ffe1..000000000 --- a/logic/service/fight/battle/container/BattleStateMachine.go +++ /dev/null @@ -1,23 +0,0 @@ -package battle - -const ( - StateStart BattleState = iota - StatePlayerTurn - StateEnemyTurn - StateEnd -) - -type BattleStateMachine struct { - State BattleState -} - -func (fsm *BattleStateMachine) Next() { - switch fsm.State { - case StateStart: - fsm.State = StatePlayerTurn - case StatePlayerTurn: - fsm.State = StateEnemyTurn - case StateEnemyTurn: - fsm.State = StatePlayerTurn - } -} diff --git a/logic/service/fight/battle/container/battle.go b/logic/service/fight/battle/container/battle.go index b807bb068..cc5cf3c2d 100644 --- a/logic/service/fight/battle/container/battle.go +++ b/logic/service/fight/battle/container/battle.go @@ -1,52 +1,13 @@ package battle import ( - "blazing/logic/service/fight/battle/skill/effect" - "math/rand/v2" + "blazing/logic/service/fight/battle/random" + "blazing/logic/service/fight/info" ) -type BattleState int - -// ==== 基础数据结构 ==== - -type BattleUnit struct { - Name string - Level int - Atk int - Def int - MaxHP int - HP int - Buffs map[string]effect.Effect - - IsCritical bool -} - -func NewBattleUnit(name string, level, atk, def, maxHP int) *BattleUnit { - return &BattleUnit{ - Name: name, - Level: level, - Atk: atk, - Def: def, - MaxHP: maxHP, - HP: maxHP, - Buffs: make(map[string]effect.Effect), - } -} - -// ==== 战斗上下文 ==== - type BattleContext struct { - Rand *rand.Rand -} + Rand random.RandomXS128 + same []info.FightUserInfo //同阵营 -// ==== 技能 ==== - -type Skill struct { - Name string - Type SkillType - Power int - IsAttack bool - Attacker *BattleUnit - Defender *BattleUnit - Effects []Effect + opposite []info.FightUserInfo //不同阵营 } diff --git a/logic/service/fight/battle/container/battle1v1.go b/logic/service/fight/battle/container/battle1v1.go index 3e4e27334..79b968c2c 100644 --- a/logic/service/fight/battle/container/battle1v1.go +++ b/logic/service/fight/battle/container/battle1v1.go @@ -1,12 +1,38 @@ package battle +import "blazing/logic/service/fight/info" + type BattleContainer struct { - FightUserInfo + BattleContext + ownerid uint32 } - b.Turn++ - fmt.Printf("=== 回合 %d 开始 ===\n", b.Turn) - b.PublishTrigger(EffectTrigger.TurnStart, containers) - fmt.Println("=== 玩家操作阶段 ===") - b.PublishTrigger(EffectTrigger.TurnEnd, containers) - fmt.Printf("=== 回合 %d 结束 ===\n\n", b.Turn) -} \ No newline at end of file + +//返回房主信息 +func (b *BattleContainer) Owner() *info.FightUserInfo { + + return &b.same[0] +} + +//返回邀请者信息,比如野怪 +func (b *BattleContainer) Target() *info.FightUserInfo { + + return &b.opposite[0] +} +func NewBattleContainer(i info.NoteReadyToFightInfo) *BattleContainer { + + ret := BattleContainer{} + ret.same = make([]info.FightUserInfo, 0) //初始化本阵营 + ret.opposite = make([]info.FightUserInfo, 0) //初始化敌方阵营 + ret.same = append(ret.same, i.OurInfo) + ret.opposite = append(ret.same, i.OpponentInfo) + ret.ownerid = i.OwnerID //房主ID + return &ret +} + +// b.Turn++ +// fmt.Printf("=== 回合 %d 开始 ===\n", b.Turn) +// b.PublishTrigger(EffectTrigger.TurnStart, containers) +// fmt.Println("=== 玩家操作阶段 ===") +// b.PublishTrigger(EffectTrigger.TurnEnd, containers) +// fmt.Printf("=== 回合 %d 结束 ===\n\n", b.Turn) +// } diff --git a/logic/service/fight/battle/damage/d.go b/logic/service/fight/battle/damage/d.go deleted file mode 100644 index d95ed5adc..000000000 --- a/logic/service/fight/battle/damage/d.go +++ /dev/null @@ -1,22 +0,0 @@ -package damage - -import "math/rand" - -// ==== 伤害计算 ==== - -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 -} diff --git a/logic/service/fight/battle/damage/damage.go b/logic/service/fight/battle/damage/damage.go deleted file mode 100644 index 9b42cffc0..000000000 --- a/logic/service/fight/battle/damage/damage.go +++ /dev/null @@ -1,277 +0,0 @@ -package damage - -import ( - "fmt" - "math/rand" - - "github.com/shopspring/decimal" - "github.com/tnnmigga/enum" -) - -// SkillType 技能类型枚举,区分物理和特殊技能 -type SkillType int - -const ( - 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 // 物理伤害减免乘区,默认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: - return "POWER_ADDITION_ZONE" - case DamageMultiplierZoneEnum.POWER_MULTIPLIER_ZONE: - return "POWER_MULTIPLIER_ZONE" - case DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE: - return "ATK_RESISTANCE_ZONE" - case DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE: - return "SP_ATK_RESISTANCE_ZONE" - case DamageMultiplierZoneEnum.SPECIAL_EFFECT_MULTIPLIER_ZONE: - return "SPECIAL_EFFECT_MULTIPLIER_ZONE" - case DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE: - return "ATTACK_COUNT_ZONE" - case DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE: - return "FIX_DAMAGE_RESISTANCE_ZONE" - default: - return fmt.Sprintf("Unknown(DamageMultiplierZone=%d)", z) - } -} - -// FromCode 根据整数值获取枚举 -func FromCode(code int) (DamageMultiplierZone, error) { - switch code { - case 1: - return DamageMultiplierZoneEnum.POWER_ADDITION_ZONE, nil - case 2: - return DamageMultiplierZoneEnum.POWER_MULTIPLIER_ZONE, nil - case 3: - return DamageMultiplierZoneEnum.ATK_RESISTANCE_ZONE, nil - case 4: - return DamageMultiplierZoneEnum.SP_ATK_RESISTANCE_ZONE, nil - case 5: - return DamageMultiplierZoneEnum.SPECIAL_EFFECT_MULTIPLIER_ZONE, nil - case 6: - return DamageMultiplierZoneEnum.ATTACK_COUNT_ZONE, nil - case 7: - return DamageMultiplierZoneEnum.FIX_DAMAGE_RESISTANCE_ZONE, nil - default: - return 0, fmt.Errorf("未知的DamageMultiplierZone代码: %d", code) - } -} - -// Pet 接口,表示战斗中的宠物实体,包含等级、类型和名称等 -type Pet interface { - Level() int64 - Type() SkillType - Name() string -} - -// SkillInterface 接口,表示技能实体,包含技能类型和名称 -type SkillInterface interface { - SkillType() SkillType - Name() string -} - -// DamageContext 伤害计算上下文,包含攻击方、防御方宠物,技能信息,以及各种计算参数 -type DamageContext struct { - attackerPet Pet // 攻击宠物 - defenderPet Pet // 防御宠物 - skill SkillInterface // 技能 - - Type SkillType // 技能属性类型(物理或特殊) - BasePower int64 // 基础威力值 - Attack int64 // 攻击力 - Defense int64 // 防御力 - CriticalRate float64 // 暴击倍率,默认2.0倍 - SameTypeRate float64 // 同系加成倍率,默认1.5倍 - Random int // 随机值,默认-1表示未设置 - - 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, - defenderPet: defenderPet, - skill: skill, - CriticalRate: 2.0, - SameTypeRate: 1.5, - Random: -1, - otherRates: make(map[DamageMultiplierZone]decimal.Decimal), - extraRates: make(map[string]decimal.Decimal), - } - ctx.initOtherRates() - return ctx -} - -// initOtherRates 初始化伤害乘算区的默认倍率值 -func (c *DamageContext) initOtherRates() { - 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 - } - 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) - } - c.otherRates[zone] = r - } - 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 伤害计算函数,返回最终伤害整数值 -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() -} diff --git a/logic/service/fight/battle/random/random.go b/logic/service/fight/battle/random/random.go index 1437b270f..5d0c70c6f 100644 --- a/logic/service/fight/battle/random/random.go +++ b/logic/service/fight/battle/random/random.go @@ -28,6 +28,13 @@ func NewRandomXS128() *RandomXS128 { return NewRandomXS128WithSeed(seed) } +// 基于用户名和时间创建 +func NewRandomXS128WithUser(user, time int64) *RandomXS128 { + + seed := uint64(user)<<32 | uint64(time) + return NewRandomXS128WithSeed(seed) +} + // NewRandomXS128WithSeed 用单个 uint64 种子创建生成器 func NewRandomXS128WithSeed(seed uint64) *RandomXS128 { seed0 := murmurHash3(seed) diff --git a/logic/service/fight/battle/skill/effect/EffectContainer.go b/logic/service/fight/battle/skill/effect/EffectContainer.go index 7d6096dab..cd228d7d8 100644 --- a/logic/service/fight/battle/skill/effect/EffectContainer.go +++ b/logic/service/fight/battle/skill/effect/EffectContainer.go @@ -47,8 +47,8 @@ var LifeType = enum.New[struct { // 容器:存放多个效果 // ======================== type EffectContainer struct { - GlobalEffects []*Effect // 全局常驻/回合/次数效果 - Effects []*Effect //effects + //GlobalEffects []*Effect // 全局常驻/回合/次数效果 + Effects []*Effect //effects 实际上全局就是effect无限回合 } // 添加效果 diff --git a/logic/service/fight/info/BattlePetEntity.go b/logic/service/fight/info/BattlePetEntity.go index 2b1e376c2..ac0b415fd 100644 --- a/logic/service/fight/info/BattlePetEntity.go +++ b/logic/service/fight/info/BattlePetEntity.go @@ -2,9 +2,22 @@ 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 // 唯一标识 @@ -47,8 +60,8 @@ type BattlePetEntity struct { petImmunityEffectIds map[int]int // 免疫效果ID -> 剩余回合 (-1表示永久) petImmunityBuffs map[string]int // 免疫buff效果ID -> 剩余回合 (-1表示永久) - IsDead bool // 是否死亡 - + IsDead bool // 是否死亡 + otherRates map[DamageMultiplierZone]decimal.Decimal // 各伤害乘算区倍率,使用高精度decimal // 战斗开始时拥有的特殊buff //battleStartHavingBuffs []buff.BattleBuffInterface } @@ -85,3 +98,109 @@ func (b *BattlePetEntity) calculateRealValue(value int64, stat int) int64 { 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 +// } diff --git a/logic/service/fight/info/NoteReadyToFightInfo.go b/logic/service/fight/info/NoteReadyToFightInfo.go index efe8b914c..fff871c3a 100644 --- a/logic/service/fight/info/NoteReadyToFightInfo.go +++ b/logic/service/fight/info/NoteReadyToFightInfo.go @@ -6,6 +6,8 @@ import ( // NoteReadyToFightInfo 战斗准备就绪消息结构体,对应Java的NoteReadyToFightInfo type NoteReadyToFightInfo struct { + //战斗发起者ID + OwnerID uint32 `struc:"skip"` // 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用) // 对应Java的@UInt long FightId uint32 `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `