package item import ( "blazing/common/data/xmlres" "blazing/modules/player/model" "errors" "strconv" "strings" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/grand" ) type PetItemHandler func(itemid uint32, ctx *model.PetInfo) bool // RangeHandler 范围ID处理器(用于ID区间匹配) type RangeHandler struct { Start uint32 End uint32 Handler PetItemHandler } // SetHandler 集合ID处理器(用于离散ID匹配) type SetHandler struct { IDs []uint32 Handler PetItemHandler } // PetItemHandlerRegistry 道具处理器注册器 type PetItemHandlerRegistry struct { exactHandlers map[uint32]PetItemHandler // 精确ID映射 rangeHandlers []RangeHandler // 范围ID映射 setHandlers []SetHandler // 集合ID映射 } // 全局注册器实例 var PetItemRegistry = &PetItemHandlerRegistry{ exactHandlers: make(map[uint32]PetItemHandler), } // -------------------------- 4. 注册器方法 -------------------------- // RegisterExact 注册精确ID的处理函数 func (r *PetItemHandlerRegistry) RegisterExact(itemID uint32, handler PetItemHandler) { r.exactHandlers[itemID] = handler } // RegisterRange 注册ID范围的处理函数 func (r *PetItemHandlerRegistry) RegisterRange(start, end uint32, handler PetItemHandler) { r.rangeHandlers = append(r.rangeHandlers, RangeHandler{ Start: start, End: end, Handler: handler, }) } // RegisterSet 注册ID集合的处理函数 func (r *PetItemHandlerRegistry) RegisterSet(ids []uint32, handler PetItemHandler) { r.setHandlers = append(r.setHandlers, SetHandler{ IDs: ids, Handler: handler, }) } // GetHandler 根据ItemID获取对应的处理函数 func (r *PetItemHandlerRegistry) GetHandler(itemID uint32) PetItemHandler { // 1. 优先匹配精确ID if handler, ok := r.exactHandlers[itemID]; ok { return handler } // 2. 匹配范围ID for _, rh := range r.rangeHandlers { if itemID >= rh.Start && itemID <= rh.End { return rh.Handler } } // 3. 匹配集合ID for _, sh := range r.setHandlers { for _, id := range sh.IDs { if itemID == id { return sh.Handler } } } // 4. 无匹配的处理器 return nil } func nvfunc(itemid uint32, onpet *model.PetInfo) bool { // 1. 取出配置(保留你原有的取值方式) itemConf := xmlres.ItemsMAP[int(itemid)] // 2. 分割NatureSet(保留你原有的写法) rr := strings.Split(*itemConf.NatureSet, " ") // 3. 分割NatureProbs(新增概率解析) var probList []string if itemConf.NatureProbs != nil { probList = strings.Split(*itemConf.NatureProbs, " ") } // 4. 按概率选值(核心改造:替换原有随机逻辑) selectedVal, err := randomByProbs(rr, probList) if err != nil { return false } // 5. 赋值(保留你原有的类型转换) onpet.Nature = gconv.Uint32(selectedVal) return true } // -------------------------- 6. 初始化注册器(注册所有处理器) -------------------------- func init() { PetItemRegistry.RegisterRange(300037, 300041, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Ev[itemid-300037+1] = 0 return true }) PetItemRegistry.RegisterExact(300042, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Ev[0] = 0 return true }) PetItemRegistry.RegisterExact(300650, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Ev = [6]uint32{} return true }) PetItemRegistry.RegisterExact(300025, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Nature = (onpet.Nature + uint32(grand.Intn(25))) % 25 return true }) PetItemRegistry.RegisterRange(300081, 300086, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Nature = gconv.Uint32(*xmlres.ItemsMAP[int(itemid)].Nature) return true }) PetItemRegistry.RegisterRange(300602, 300605, nvfunc) //特判转换 PetItemRegistry.RegisterSet([]uint32{300119, 300120}, nvfunc) PetItemRegistry.RegisterExact(300790, func(itemid uint32, onpet *model.PetInfo) bool { r := grand.Intn(2) if r == 0 { if onpet.Dv > 0 { onpet.Dv-- } } else { if onpet.Dv < 31 { onpet.Dv++ } } return true }) //基因重组 PetItemRegistry.RegisterExact(300024, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Downgrade(1) onpet.NextLvExp = 0 onpet.Update(false) onpet.Ev = [6]uint32{} onpet.Dv = uint32(grand.Intn(32)) onpet.Nature = (onpet.Nature + uint32(grand.Intn(25))) % 25 //onpet.CalculatePetPane() return true }) PetItemRegistry.RegisterExact(300668, func(itemid uint32, onpet *model.PetInfo) bool { onpet.Dv = uint32(grand.Intn(32)) return true }) PetItemRegistry.RegisterExact(300791, func(itemid uint32, onpet *model.PetInfo) bool { if onpet.Dv >= 31 { onpet.Dv = 31 return true } onpet.Dv = 31 return true }) PetItemRegistry.RegisterExact(300702, func(itemid uint32, onpet *model.PetInfo) bool { if onpet.Dv >= 31 { onpet.Dv = 31 return true } onpet.Dv = onpet.Dv + uint32(grand.Intn(31-int(onpet.Dv))+1) if onpet.Dv >= 31 { onpet.Dv = 31 //return true } return true }) PetItemRegistry.RegisterExact(300053, func(itemid uint32, onpet *model.PetInfo) bool { _, _, ok := onpet.GetEffect(1) if !ok { onpet.RnadEffect() return true } return false }) PetItemRegistry.RegisterExact(300054, func(itemid uint32, onpet *model.PetInfo) bool { _, _, ok := onpet.GetEffect(1) if ok { onpet.RnadEffect() return true } return false }) } // 替换你原有性格转换的代码段,新增概率解析+权重随机逻辑 // 注:保留你原有的变量名(如rr)、函数调用(grand.Intn),仅扩展概率逻辑 // 先定义一个辅助函数:按概率从列表中选值(贴合你的代码风格) func randomByProbs(natureSet []string, probs []string) (string, error) { // 1. 若概率配置为空/长度不匹配,降级为等概率随机(兼容原有逻辑) if len(probs) == 0 || len(natureSet) != len(probs) { if len(natureSet) == 0 { return "", errors.New("natureSet is empty") } // 修复你原有代码的索引越界问题:grand.Intn(len(rr))-1 → 改为grand.Intn(len(rr)) // 因为grand.Intn(n)返回0~n-1,直接作为索引即可,无需-1 return natureSet[grand.Intn(len(natureSet))], nil } // 2. 解析概率为int数组,校验非负 probInts := make([]int, len(probs)) totalProb := 0 for i, p := range probs { val, err := strconv.Atoi(p) if err != nil || val < 0 { return "", errors.New("invalid prob value: " + p) } probInts[i] = val totalProb += val } // 3. 总概率为0,降级为等概率 if totalProb == 0 { return natureSet[grand.Intn(len(natureSet))], nil } // 4. 计算前缀和(权重随机核心) prefixSum := make([]int, len(probInts)) prefixSum[0] = probInts[0] for i := 1; i < len(probInts); i++ { prefixSum[i] = prefixSum[i-1] + probInts[i] } // 5. 生成随机数匹配前缀和 randVal := grand.Intn(totalProb) for i, sum := range prefixSum { if randVal < sum { return natureSet[i], nil } } // 理论上不会走到这里 return natureSet[0], nil }