Files
bl/logic/service/item/petuse.go

270 lines
6.9 KiB
Go
Raw Normal View History

package item
import (
"blazing/common/data/xmlres"
"blazing/modules/blazing/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_EXP()
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.RnadAN()
return true
}
return false
})
PetItemRegistry.RegisterExact(300054, func(itemid uint32, onpet *model.PetInfo) bool {
_, _, ok := onpet.GetEffect(1)
if ok {
onpet.RnadAN()
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
}