```
feat(fight): 优化Boss战奖励发放与经验通知逻辑 - 重构 Boss 怪物掉落物品发放代码,提高可读性与扩展性 - 注释掉宠物经验变化的通知指令(2509),暂不发送给客户端 - 修复战斗模式判断条件,从 Mode 改为 Status 判断 PVE 战斗 - 调整战斗超时逻辑,修改超时原因并增加调试日志输出 - 优化战斗结束回调执行顺序,确保广播前完成状态更新 - 重写 PetInfo.AddEV 方法,支持更安全
This commit is contained in:
@@ -2,8 +2,9 @@ package model
|
||||
|
||||
import (
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/utils"
|
||||
"blazing/cool"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
@@ -96,20 +97,85 @@ type PetInfo struct {
|
||||
// AbilityType uint32 `struc:"skip"` //特性
|
||||
}
|
||||
|
||||
func (pet *PetInfo) ADD_EV(evadd []uint32) {
|
||||
var sum uint32
|
||||
for i := range pet.Ev {
|
||||
sum += pet.Ev[i]
|
||||
// 定义常量,提升可维护性(避免魔法数字)
|
||||
const (
|
||||
maxSingleEV uint32 = 255 // 单个EV最大值
|
||||
maxTotalEV uint32 = 510 // 6个EV总和最大值
|
||||
evFieldCount = 6 // EV字段数量(固定6个)
|
||||
)
|
||||
|
||||
// AddEV 优化后的EV值增加方法(符合Go命名规范:大写导出,动词开头)
|
||||
// 功能:为宠物6个EV值增加增量,保证单个≤255、总和≤510
|
||||
// 参数:evadd - 6个EV字段的增量数组(长度必须为6)
|
||||
// 返回:error - 参数非法/逻辑异常时返回错误;bool - 是否触发了超额削减(方便业务监控)
|
||||
func (pet *PetInfo) AddEV(evadd []uint32) (bool, error) {
|
||||
// 1. 参数安全校验:避免数组越界panic
|
||||
if len(evadd) != evFieldCount {
|
||||
return false, fmt.Errorf("evadd长度必须为%d,当前为%d", evFieldCount, len(evadd))
|
||||
}
|
||||
if len(pet.Ev) != evFieldCount {
|
||||
return false, errors.New("pet.Ev未初始化或长度不为6")
|
||||
}
|
||||
|
||||
cansum := 510 - sum
|
||||
for i := 0; i < 6; i++ {
|
||||
|
||||
pet.Ev[i] += evadd[i]
|
||||
pet.Ev[i] = utils.Min(pet.Ev[i], 255)
|
||||
pet.Ev[i] = utils.Min(pet.Ev[i], cansum)
|
||||
// 2. 预计算:当前EV总和 + 增量后的临时值(先不修改原数据,避免边改边算)
|
||||
var (
|
||||
totalCurrent uint32 // 当前EV总和
|
||||
tempEV [evFieldCount]uint32 // 增量后的临时EV值(避免修改原数组导致计算错误)
|
||||
)
|
||||
// 一次性遍历:计算当前总和 + 初始化临时EV(减少遍历次数)
|
||||
for i := 0; i < evFieldCount; i++ {
|
||||
totalCurrent += pet.Ev[i]
|
||||
// 先计算增量后的值,同时限制单个不超过maxSingleEV
|
||||
tempEV[i] = pet.Ev[i] + evadd[i]
|
||||
if tempEV[i] > maxSingleEV {
|
||||
tempEV[i] = maxSingleEV
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 计算增量后的临时总和,检查是否超过maxTotalEV
|
||||
totalTemp := uint32(0)
|
||||
for _, v := range tempEV {
|
||||
totalTemp += v
|
||||
}
|
||||
|
||||
// 4. 若总和超额,执行削减逻辑(优先削减数值大的字段,保证公平性)
|
||||
hasCut := false
|
||||
if totalTemp > maxTotalEV {
|
||||
overTotal := totalTemp - maxTotalEV // 需要削减的总量
|
||||
hasCut = true
|
||||
|
||||
// 循环削减直到超额量为0(优先削减数值大的字段,避免小值被过度削减)
|
||||
for overTotal > 0 {
|
||||
// 找到当前最大的EV索引
|
||||
maxIdx := 0
|
||||
for i := 1; i < evFieldCount; i++ {
|
||||
if tempEV[i] > tempEV[maxIdx] {
|
||||
maxIdx = i
|
||||
}
|
||||
}
|
||||
|
||||
// 计算该字段可削减的最大值(至少留到原数值,或削减到能覆盖overTotal)
|
||||
cutAble := tempEV[maxIdx] - pet.Ev[maxIdx] // 最多削减增量部分,不低于原值
|
||||
if cutAble == 0 {
|
||||
cutAble = tempEV[maxIdx] // 若增量为0,可削减当前值(根据业务调整,也可panic)
|
||||
}
|
||||
|
||||
// 实际削减量:取可削减量和剩余超额量的较小值
|
||||
cut := cutAble
|
||||
if cut > overTotal {
|
||||
cut = overTotal
|
||||
}
|
||||
|
||||
// 执行削减
|
||||
tempEV[maxIdx] -= cut
|
||||
overTotal -= cut
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 将处理后的临时值赋值给原EV(批量赋值,减少零散操作)
|
||||
copy(pet.Ev[:], tempEV[:])
|
||||
|
||||
return hasCut, nil
|
||||
}
|
||||
func (pet *PetInfo) Cure() {
|
||||
pet.Hp = pet.MaxHp
|
||||
|
||||
Reference in New Issue
Block a user