Files
bl/logic/service/item/petuse.go
xinian 99748ba41e
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
refactor: 重构奖励发放逻辑并支持签到默认奖励
2026-04-06 03:42:48 +08:00

326 lines
8.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
})
}