feat(fight): 完善战斗系统中道具使用逻辑与血量恢复机制

- 修改 item.go 中 Item 结构体,将 Bonus 字段类型由 string
This commit is contained in:
2025-11-08 16:38:41 +08:00
parent ca005bdb56
commit c916440033
21 changed files with 437 additions and 71 deletions

View File

@@ -11,27 +11,42 @@ type Items struct {
}
type Item struct {
ID int `xml:"ID,attr"` // 物品ID与items.xml一致
Name string `xml:"Name,attr"` // 物品名称
Rarity int `xml:"Rarity,attr,omitempty"` // 稀有度
ItemType int `xml:"ItemType,attr"` // 物品类型
Max int `xml:"Max,attr"` // 最大堆叠数量
Price int `xml:"Price,attr"` // 价格
Bonus string `xml:"Bonus,attr"` // 倍率(如捕捉胶囊的加成倍数)
Tradability int `xml:"Tradability,attr"` // 可交易性0/1
VipTradability int `xml:"VipTradability,attr"` // VIP可交易性0/1
DailyKey int `xml:"DailyKey,attr,omitempty"` // 每日限制键值
DailyOutMax int `xml:"DailyOutMax,attr,omitempty"` // 每日最大产出
Wd int `xml:"wd,attr"` // 未知属性
UseMax int `xml:"UseMax,attr"` // 最大使用次数
LifeTime int `xml:"LifeTime,attr"` // 生命周期0为永久
Purpose int `xml:"purpose,attr"` // 用途标识
Bean int `xml:"Bean,attr,omitempty"` // 豆子数量
Hide int `xml:"Hide,attr"` // 是否隐藏0/1
Sort int `xml:"Sort,attr,omitempty"` // 排序序号
Des string `xml:"des,attr"` // 物品用途
Color string `xml:"color,attr,omitempty"` // 装备名字颜色
Level int `xml:"level,attr,omitempty"` // 装备等级(星星)
ID int `xml:"ID,attr"` // 物品ID与items.xml一致
Name string `xml:"Name,attr"` // 物品名称
Rarity int `xml:"Rarity,attr,omitempty"` // 稀有度
ItemType int `xml:"ItemType,attr"` // 物品类型0胶囊 1体力药剂 2活力药剂
Max int `xml:"Max,attr"` // 最大堆叠数量
Price int `xml:"Price,attr"` // 价格
Bonus float64 `xml:"Bonus,attr,omitempty"` // 倍率(如捕捉胶囊的加成倍数,修正为浮点型
Tradability int `xml:"Tradability,attr"` // 可交易性0/1
VipTradability int `xml:"VipTradability,attr"` // VIP可交易性0/1
DailyKey int `xml:"DailyKey,attr,omitempty"` // 每日限制键值
DailyOutMax int `xml:"DailyOutMax,attr,omitempty"` // 每日最大产出
Wd int `xml:"wd,attr"` // 未知属性
UseMax int `xml:"UseMax,attr"` // 最大使用次数
LifeTime int `xml:"LifeTime,attr"` // 生命周期0为永久
Purpose int `xml:"purpose,attr"` // 用途标识
Bean int `xml:"Bean,attr,omitempty"` // 豆子数量
Hide int `xml:"Hide,attr"` // 是否隐藏0/1
Sort int `xml:"Sort,attr,omitempty"` // 排序序号
Des string `xml:"des,attr,omitempty"` // 物品用途XML中无该属性保留字段供自定义
Color string `xml:"color,attr,omitempty"` // 装备名字颜色
Level int `xml:"level,attr,omitempty"` // 装备等级(星星)
VipOnly int `xml:"VipOnly,attr,omitempty"` // VIP专属标识0/1如超能胶囊
HP int `xml:"HP,attr,omitempty"` // 体力恢复量(体力药剂专属)
PP int `xml:"PP,attr,omitempty"` // 活力恢复量(活力药剂专属)
MaxHPUp int `xml:"MaxHPUp,attr,omitempty"` // 体力上限提升值(如初级体力上限提升药剂Ω)
MonAttrReset int `xml:"MonAttrReset,attr,omitempty"` // 精灵属性重置标识(精灵还原药剂)
MonNatureReset int `xml:"MonNatureReset,attr,omitempty"` // 精灵性格重置标识(性格重塑胶囊)
DecreMonLv int `xml:"DecreMonLv,attr,omitempty"` // 精灵降级数值(降级秘药)
DualEffectTimes int `xml:"DualEffectTimes,attr,omitempty"` // 双倍效果次数(双倍经验加速器)
AutoBtlTimes int `xml:"AutoBtlTimes,attr,omitempty"` // 自动战斗次数自动战斗器S型
EnergyAbsorbTimes int `xml:"EnergyAbsorbTimes,attr,omitempty"` // 能量吸收次数(能量吸收器)
NewSeIdx int `xml:"NewSeIdx,attr,omitempty"` // 能量珠索引(各类能量珠)
DualEvTimes int `xml:"DualEvTimes,attr,omitempty"` // 双倍学习力次数(学习力双倍仪)
YuanshenDegrade int `xml:"YuanshenDegrade,attr,omitempty"` // 融合精灵还原标识(融合精灵还原药剂)
EvRemove int `xml:"EvRemove,attr,omitempty"` // 学习力遗忘类型(各类学习力遗忘剂)
bShowPetBag int `xml:"bShowPetBag,attr,omitempty"` // 宠物背包显示标识(副融合精灵保留药剂等)
Pet *Pet `xml:"pet,omitempty"` // 精灵属性子节点
TeamPK *TeamPK `xml:"teamPK,omitempty"` // 要塞保卫战子节点

View File

@@ -198,7 +198,7 @@ func (h Controller) LoadPercent(data *fight.LoadPercentInboundInfo, c *player.Pl
return nil, -1
}
func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetItemOutboundInfo, err errorcode.ErrorCode) {
func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetIteminfo, err errorcode.ErrorCode) {
if c.FightC != nil {
c.FightC.UseItem(c, data.CatchTime, data.ItemId)

View File

@@ -15,6 +15,7 @@ type PlayerI interface {
GetInfo() *model.PlayerInfo
SendAttackValue(info.AttackValueS)
SendChangePet(info.ChangePetInfo)
SendUsePetItemInfo(info.UsePetIteminfo)
SendLoadPercent(info.LoadPercentOutboundInfo)
SetFightC(FightI)
}

View File

@@ -0,0 +1,37 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/brunoga/deep"
"github.com/shopspring/decimal"
)
/**
* 降低对方 1/n 的 体力
*/
func init() {
input.InitEffect(input.EffectType.Skill, 28, &Effect28{
EffectNode: node.EffectNode{},
})
}
type Effect28 struct {
node.EffectNode
}
func (e *Effect28) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
eff := deep.MustCopy(ctx)
eff.DamageZone.Type = info.DamageType.Fixed
ctx.DamageZone.Damage = decimal.NewFromInt(int64(eff.CurrentPet.Info.Hp)).Div(decimal.NewFromInt(int64(e.SideEffectArgs[0])))
ctx.Input.Damage(eff)
return true
}

View File

@@ -0,0 +1,36 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/brunoga/deep"
"github.com/shopspring/decimal"
)
/**
* 额外增加n点固定伤害
*/
func init() {
input.InitEffect(input.EffectType.Skill, 29, &Effect29{
EffectNode: node.EffectNode{},
})
}
type Effect29 struct {
node.EffectNode
}
func (e *Effect29) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
eff := deep.MustCopy(ctx)
eff.DamageZone.Type = info.DamageType.Fixed
ctx.DamageZone.Damage = decimal.NewFromInt(int64(e.SideEffectArgs[0]))
ctx.Input.Damage(eff)
return true
}

View File

@@ -0,0 +1,38 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/shopspring/decimal"
)
/**
* 1回合做m~n次攻击
*/
func init() {
input.InitEffect(input.EffectType.Skill, 31, &Effect31{
EffectNode: node.EffectNode{},
})
}
type Effect31 struct {
node.EffectNode
}
func (e *Effect31) Damage_Floor(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
if ctx.DamageZone.Type == info.DamageType.Red {
n := int(e.Input.FightC.GetRand().Int31n(int32(e.SideEffectArgs[1]-e.SideEffectArgs[0]+1))) + e.SideEffectArgs[0]
ctx.DamageZone.Damage = ctx.DamageZone.Damage.Mul(decimal.NewFromInt(int64(n)))
}
return true
}

View File

@@ -0,0 +1,34 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/shopspring/decimal"
)
/**
* 恢复自身最大体力的1/n
*/
func init() {
input.InitEffect(input.EffectType.Skill, 43, &Effect43{
EffectNode: node.EffectNode{},
})
}
type Effect43 struct {
node.EffectNode
}
func (e *Effect43) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
e.Input.Heal(&action.SelectSkillAction{}, decimal.NewFromInt(int64(e.Input.MaxHp)).Div(decimal.NewFromInt(int64(e.SideEffectArgs[0]))))
return true
}

View File

@@ -0,0 +1,32 @@
package effect
import (
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/brunoga/deep"
"github.com/shopspring/decimal"
)
/**
* 对方所受伤害的1/n会反弹给自己
*/
func init() {
input.InitEffect(input.EffectType.Skill, 6, &Effect6{
EffectNode: node.EffectNode{},
})
}
type Effect6 struct {
node.EffectNode
}
func (e *Effect6) Skill_Useed(ctx input.Ctx) bool {
eff := deep.MustCopy(ctx)
ctx.DamageZone.Damage = eff.DamageZone.Damage.Div(decimal.NewFromInt(int64(e.SideEffectArgs[0])))
e.Input.Damage(eff)
return true
}

View File

@@ -0,0 +1,48 @@
package effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
)
/**
* 下n回合对手使用体力药剂时效果变成减少相应的体力
*/
type Effect69 struct {
node.EffectNode
}
type Effect69_1 struct {
node.EffectNode
}
func init() {
t := &Effect69{
EffectNode: node.EffectNode{},
}
//t.Owner(true)
//t.Duration(5)
input.InitEffect(input.EffectType.Skill, 69, t)
}
func (e *Effect69) OnSkill(ctx input.Ctx) bool {
t := &Effect69_1{
EffectNode: node.EffectNode{},
}
t.SetArgs(e.Input, e.SideEffectArgs...)
t.Duration(e.SideEffectArgs[0])
ctx.AddEffect(t)
return true
}
func (e *Effect69_1) Heal_Pre(f action.BattleActionI, t *int) bool {
if _, ok := f.(*action.UseItemAction); ok {
*t = -*t // 把t指向的值取反直接作用于外部变量
}
return true
}

View File

@@ -0,0 +1,43 @@
package effect
import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/shopspring/decimal"
)
/**
* 对方体力高于自己时才能命中,将对方体力减到和自己相同
*/
func init() {
input.InitEffect(input.EffectType.Skill, 7, &Effect7{
EffectNode: node.EffectNode{},
})
}
type Effect7 struct {
node.EffectNode
}
func (e *Effect7) Skill_Hit_Pre(ctx input.Ctx) bool {
if ctx.CurrentPet.Info.Hp <= e.Input.CurrentPet.Info.Hp {
ctx.SkillEntity.Accuracy = 0
}
return true
}
func (e *Effect7) Damage_Floor(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
if ctx.DamageZone.Type == info.DamageType.Red {
ctx.DamageZone.Damage = decimal.NewFromInt(int64(ctx.CurrentPet.Info.Hp - e.Input.CurrentPet.Info.Hp))
}
return true
}

View File

@@ -317,11 +317,11 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
//这里实现应该参考本地技能是否命中,然后
e.Hit(a.AttackTime != 0) //我方效果命中
}
for _, t := range defender.EffectCache {
if t.GetInput() == attacker { //如果取反,说明是给对方添加的回合效果
t.Hit(a.AttackTime != 0)
}
}
// for _, t := range defender.EffectCache {
// if t.GetInput() == attacker { //如果取反,说明是给对方添加的回合效果
// t.Hit(a.AttackTime != 0)
// }
// }
// 扣减防御方血量
attacker.Exec(func(t input.Effect) bool {
@@ -501,7 +501,10 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
//技能使用后
attacker.Exec(func(t input.Effect) bool { //技能使用后的我方效果
t.Skill_Useed(input.Ctx{Input: defender, SelectSkillAction: currentskill})
t.Skill_Useed(input.Ctx{Input: defender, SelectSkillAction: currentskill, DamageZone: &info.DamageZone{
Type: info.DamageType.Red,
Damage: attacker.DamageZone.Damage,
}})
return true
})

View File

@@ -150,12 +150,14 @@ func getSkillName(move *SkillEntity) string {
// 计算是否命中
func (s *SkillEntity) AttackTimeC(level int) {
//s.AttackTime = 0 //先重置上一次的
s.AttackTime = 0 //先重置上一次的
if s.MustHit != 0 {
s.AttackTime = 2
}
if int64(s.GetAccuracy(level)) >= s.Rand.Int63n(100) {
a := int64(s.GetAccuracy(level))
r := s.Rand.Int63n(100)
if a >= r {
s.AttackTime = 1
}

View File

@@ -1,7 +1,7 @@
package info
// UsePetItemOutboundInfo 对应Java的UsePetItemOutboundInfo实现OutboundMessage接口
type UsePetItemOutboundInfo struct {
// UsePetIteminfo 对应Java的UsePetIteminfo实现OutboundMessage接口
type UsePetIteminfo struct {
UserID uint32 `description:"玩家ID" codec:"userId"` // @UInt long 对应Go的uint32无符号64位
ItemID uint32 `description:"使用的物品ID" codec:"itemId"` // 结构体标签模拟@FieldDescription和@AutoCodec注解
UserHp uint32 `description:"用户血量 这里是原始HP+药剂回复的HP总和 比如我只有20血使用了150药剂 这里应该是170 使用PP药剂 这里为原始HP" codec:"userHp"`

View File

@@ -47,8 +47,8 @@ type Effect interface {
SetArgs(input *Input, param ...int)
GetArgs() []int
// 治疗相关触发
Heal_Pre(action.BattleActionI) bool // 治疗前触发 回复翻倍效果
Heal(action.BattleActionI) bool // 治疗生效时触发 药剂反噬
Heal_Pre(action.BattleActionI, *int) bool // 治疗前触发 回复翻倍效果
//Heal(action.BattleActionI) bool // 治疗生效时触发 药剂反噬
//回合数,然后次数另外维护
Duration(...int) int
@@ -57,7 +57,7 @@ type Effect interface {
Stack(...int) int
MaxStack(...int) int
Owner(...bool) bool // 技能属主,比如寄生和镇魂歌,属主是对方)
//Owner(...bool) bool // 技能属主,比如寄生和镇魂歌,属主是对方)
GetInput() *Input
ID(...int) int
//GetSkill() *BattleSkillEntity //获得技能ctx

View File

@@ -46,9 +46,35 @@ func (u *Input) UseSkill(opp *Input, skill *action.SelectSkillAction) {
// 恢复血量
func (u *Input) Heal(ac action.BattleActionI, value decimal.Decimal) {
u.CurrentPet.Info.Hp += uint32(value.IntPart())
u.AttackValue.GainHp = int32(value.IntPart())
u.CurrentPet.Info.Hp = utils.Min(u.CurrentPet.Info.Hp, u.CurrentPet.Info.MaxHp)
//使用道具回血
if _, ok := ac.(*action.UseItemAction); !ok {
u.AttackValue.GainHp = int32(value.IntPart()) //道具有专门的回血包
}
if value.IsPositive() {
u.CurrentPet.Info.Hp += uint32(value.IntPart())
u.CurrentPet.Info.Hp = utils.Min(u.CurrentPet.Info.Hp, u.CurrentPet.Info.MaxHp)
} else {
if uint32(value.Abs().IntPart()) > u.CurrentPet.Info.Hp {
u.CurrentPet.Info.Hp = 0
} else {
u.CurrentPet.Info.Hp += uint32(value.IntPart())
}
}
}
func (u *Input) HealPP(value int) {
for i := 0; i < len(u.CurrentPet.Skills); i++ {
u.CurrentPet.Skills[i].Info.PP += uint32(value)
u.CurrentPet.Skills[i].Info.PP = utils.Min(u.SkillList[i].PP, uint32(u.CurrentPet.Skills[i].MaxPP))
}
}
// 伤害落实 // 血量扣减节点比如触发回神,反弹也在这里实现

View File

@@ -119,15 +119,15 @@ func (i *Input) Parseskill(defender *Input, skill *action.SelectSkillAction) {
if t != nil {
t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
if t.Owner() { //如果取反,说明是给对方添加的回合效果
//实际上,owner永远为反,说明是对方给我添加的
t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
//给双方添加
defender.AddEffect(t)
} else {
t.SetArgs(i, temparg[:args]...) //设置入参
i.AddEffect(t)
}
// if t.Owner() { //如果取反,说明是给对方添加的回合效果
// //实际上,owner永远为反,说明是对方给我添加的
// t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
// //给双方添加
// defender.AddEffect(t)
// } else {
//t.SetArgs(i, temparg[:args]...) //设置入参
i.AddEffect(t)
// }
//这里是临时缓存buff,后面确认命中后修改HIT状态
i.EffectCache = append(i.EffectCache, t)

View File

@@ -34,7 +34,7 @@ func Geteffect(etype EnumEffectType, id int) Effect {
//todo 获取前GetEffect
eff := deep.MustCopy(ret)
eff.Alive(true) //添加后默认激活
return eff
//todo 获取后GetEffect
}
@@ -117,7 +117,7 @@ func equalInts(a, b []int) bool {
}
func (c *Input) AddEffect(e Effect) {
e.Alive(true) //添加后默认激活
//todo 免疫
//TODO 先激活
fmt.Println("产生回合数", e.ID(), e.Duration())

View File

@@ -1,6 +1,7 @@
package fight
import (
"blazing/common/data/xmlres"
"blazing/logic/service/common"
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
@@ -8,6 +9,9 @@ import (
"blazing/logic/service/player"
"fmt"
"time"
"github.com/gogf/gf/v2/util/gconv"
"github.com/shopspring/decimal"
)
func (f *FightC) battleLoop() {
@@ -134,11 +138,21 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
if _, ok := b2.(*action.SelectSkillAction); ok {
f.enterturn(b2.(*action.SelectSkillAction), nil)
} else {
f.enterturn(nil, nil)
}
case *action.UseItemAction:
f.handleItemAction(a, b2)
f.handleItemAction(a)
if _, ok := b2.(*action.SelectSkillAction); ok {
f.enterturn(b2.(*action.SelectSkillAction), nil)
} else {
if a1, ok := b2.(*action.UseItemAction); ok {
f.handleItemAction(a1)
}
f.enterturn(nil, nil)
}
default:
f.handleSkillActions(b1, b2)
@@ -146,9 +160,15 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
}
// 使用道具的逻辑封装
func (f *FightC) handleItemAction(a *action.UseItemAction, other action.BattleActionI) {
func (f *FightC) handleItemAction(a *action.UseItemAction) {
item, ok := xmlres.ItemsMAP[int(a.ItemID)]
if !ok {
f.enterturn(nil, nil)
return
}
switch {
case a.ItemID >= 30001 && a.ItemID <= 300010:
case gconv.Int(item.Bonus) != 0:
our, ok1 := f.Our.Player.(*player.Player)
opp, ok2 := f.Opp.Player.(*player.AI_player)
if ok1 && ok2 && opp.CanCapture {
@@ -167,17 +187,39 @@ func (f *FightC) handleItemAction(a *action.UseItemAction, other action.BattleAc
our.CatchPetInfo(info.CatchMonsterOutboundInfo{})
}
}
case gconv.Int(item.HP) != 0:
addhp := item.HP
f.GetInputByAction(a, false).Exec(func(rr input.Effect) bool {
rr.Heal_Pre(a, &addhp)
return true
})
f.GetInputByAction(a, false).Heal(a, decimal.NewFromInt(int64(addhp)))
f.Broadcast(func(ff *input.Input) {
ff.Player.SendUsePetItemInfo(info.UsePetIteminfo{
UserID: f.GetInputByAction(a, false).UserID,
ChangeHp: int32(addhp),
ItemID: uint32(item.ID),
UserHp: uint32(f.GetInputByAction(a, false).CurrentPet.Info.Hp),
})
})
case gconv.Int(item.PP) != 0:
f.GetInputByAction(a, false).HealPP(item.PP)
f.Broadcast(func(ff *input.Input) {
ff.Player.SendUsePetItemInfo(info.UsePetIteminfo{
UserID: f.GetInputByAction(a, false).UserID,
ItemID: uint32(item.ID),
UserHp: uint32(f.GetInputByAction(a, false).CurrentPet.Info.Hp),
})
})
default:
f.enterturn(nil, nil)
fmt.Println("ItemID 不在指定范围内")
fmt.Println(a.ItemID, "ItemID 不在指定范围内")
}
if _, ok := other.(*action.SelectSkillAction); ok {
f.enterturn(other.(*action.SelectSkillAction), nil)
} else {
f.enterturn(nil, nil)
}
}
// 双方都是技能时的结算逻辑

View File

@@ -1,13 +1,12 @@
package node
import "blazing/logic/service/fight/action"
import (
"blazing/logic/service/fight/action"
)
// 治疗相关触发
// 治疗前触发 回复翻倍效果
func (e *EffectNode) Heal_Pre(action.BattleActionI) bool {
panic("not implemented") // TODO: Implement
}
func (e *EffectNode) Heal(_ action.BattleActionI) bool {
panic("not implemented") // TODO: Implement
func (e *EffectNode) Heal_Pre(action.BattleActionI, *int) bool {
//panic("not implemented") // TODO: Implement
return true
}

View File

@@ -31,6 +31,11 @@ func (f *AI_player) SendFightEndInfo(_ info.FightOverInfo) {
//fmt.Println("战斗结束")
}
func (f *AI_player) SendUsePetItemInfo(_ info.UsePetIteminfo) {
//fmt.Println("战斗结束")
}
func (p *AI_player) GetPetInfo() []model.PetInfo {

View File

@@ -25,12 +25,11 @@ func (p *Player) SendNoteReadyToFightInfo(b info.NoteReadyToFightInfo) {
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
}
func (p *Player) SendFightEndInfo(b info.FightOverInfo) {
t1 := NewTomeeHeader(2506, p.Info.UserID)
p.SendPack(t1.Pack(&b))
p.FightC = nil
t1 := NewTomeeHeader(2506, p.Info.UserID)
p.SendPack(t1.Pack(&b))
p.FightC = nil
}
@@ -39,3 +38,9 @@ func (p *Player) CatchPetInfo(b info.CatchMonsterOutboundInfo) {
p.SendPack(t1.Pack(&b))
}
func (f *Player) SendUsePetItemInfo(b info.UsePetIteminfo) {
t1 := NewTomeeHeader(2406, f.Info.UserID)
f.SendPack(t1.Pack(&b))
}