326 lines
8.0 KiB
Go
326 lines
8.0 KiB
Go
package item
|
||
|
||
import (
|
||
"blazing/common/data/xmlres"
|
||
"blazing/common/socket/errorcode"
|
||
"blazing/common/utils"
|
||
"blazing/modules/player/model"
|
||
"strings"
|
||
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
"github.com/gogf/gf/v2/util/grand"
|
||
"github.com/samber/lo"
|
||
)
|
||
|
||
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
|
||
}
|
||
|
||
var fallbackPetItemNewSeIdx = map[uint32]int{
|
||
300741: 1103, // 瞬杀能量珠
|
||
300854: 1103, // 瞬杀能量珠Ω
|
||
}
|
||
|
||
// 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 := utils.RandomByProbs(rr, probList)
|
||
if err != nil {
|
||
return false
|
||
}
|
||
|
||
// 5. 赋值(保留你原有的类型转换)
|
||
onpet.Nature = gconv.Uint32(selectedVal)
|
||
return true
|
||
}
|
||
|
||
func resolvePetItemNewSeIdx(itemid uint32) (itemCfg xmlres.Item, newSeIdx int, ok bool) {
|
||
itemCfg, ok = xmlres.ItemsMAP[int(itemid)]
|
||
if ok && itemCfg.NewSeIdx != 0 {
|
||
return itemCfg, itemCfg.NewSeIdx, true
|
||
}
|
||
|
||
if newSeIdx, ok = fallbackPetItemNewSeIdx[itemid]; ok {
|
||
return itemCfg, newSeIdx, true
|
||
}
|
||
|
||
for idx, effectCfg := range xmlres.EffectMAP {
|
||
if effectCfg.ItemId == nil || gconv.Uint32(*effectCfg.ItemId) != itemid {
|
||
continue
|
||
}
|
||
return itemCfg, idx, true
|
||
}
|
||
|
||
return itemCfg, 0, false
|
||
}
|
||
|
||
func handleNewSeIdxPetItem(itemid uint32, onpet *model.PetInfo) errorcode.ErrorCode {
|
||
itemCfg, newSeIdx, ok := resolvePetItemNewSeIdx(itemid)
|
||
if ok && newSeIdx == 0 {
|
||
if itemCfg.MaxHPUp > 0 {
|
||
if !onpet.AddMaxHPUpEffect(itemid, itemCfg.MaxHPUp) {
|
||
return errorcode.ErrorCodes.ErrCannotInjectPillAgain
|
||
}
|
||
return 0
|
||
}
|
||
return errorcode.ErrorCodes.ErrItemUnusable
|
||
}
|
||
if !ok {
|
||
return errorcode.ErrorCodes.ErrItemUnusable
|
||
}
|
||
|
||
effectCfg, ok := xmlres.EffectMAP[newSeIdx]
|
||
if !ok {
|
||
return errorcode.ErrorCodes.ErrSystemError
|
||
}
|
||
|
||
effectStatus := byte(gconv.Int(effectCfg.Stat))
|
||
effectIdx := uint16(newSeIdx)
|
||
leftCount := 1
|
||
if effectCfg.Times != nil && *effectCfg.Times != "" {
|
||
leftCount = gconv.Int(*effectCfg.Times)
|
||
if leftCount <= 0 {
|
||
leftCount = 1
|
||
}
|
||
}
|
||
|
||
limitedCount := 0
|
||
for _, eff := range onpet.EffectInfo {
|
||
if eff.Idx == effectIdx {
|
||
return errorcode.ErrorCodes.ErrCannotInjectPillAgain
|
||
}
|
||
if eff.Status == 2 {
|
||
limitedCount++
|
||
}
|
||
}
|
||
if effectStatus == 2 && limitedCount >= 2 {
|
||
return errorcode.ErrorCodes.ErrTooManyEnergyOrbs
|
||
}
|
||
|
||
onpet.EffectInfo = append(onpet.EffectInfo, model.PetEffectInfo{
|
||
ItemID: itemid,
|
||
Idx: effectIdx,
|
||
Status: effectStatus,
|
||
LeftCount: byte(leftCount),
|
||
EID: uint16(gconv.Int(effectCfg.Eid)),
|
||
Args: effectCfg.ArgsS,
|
||
})
|
||
return 0
|
||
}
|
||
|
||
func (r *PetItemHandlerRegistry) Handle(itemID uint32, onpet *model.PetInfo) errorcode.ErrorCode {
|
||
handler := r.GetHandler(itemID)
|
||
if handler != nil {
|
||
if handler(itemID, onpet) {
|
||
return 0
|
||
}
|
||
return errorcode.ErrorCodes.ErrItemUnusable
|
||
}
|
||
return handleNewSeIdxPetItem(itemID, onpet)
|
||
}
|
||
|
||
// -------------------------- 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 {
|
||
if onpet.Dv >= 31 {
|
||
return false
|
||
}
|
||
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.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
|
||
})
|
||
|
||
//形态固定
|
||
PetItemRegistry.RegisterExact(300152, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.SkinID = onpet.ID
|
||
onpet.ExtSkin = append(onpet.ExtSkin, onpet.ID) //添加到拓展皮肤列表
|
||
lo.Uniq(onpet.ExtSkin)
|
||
return true
|
||
})
|
||
//形态固定
|
||
PetItemRegistry.RegisterExact(300153, func(itemid uint32, onpet *model.PetInfo) bool {
|
||
onpet.SkinID = 0
|
||
return true
|
||
})
|
||
|
||
}
|