feat(fight): 添加捕捉宠物功能并优化物品系统

- 新增 Capture 函数处理捕捉宠物逻辑
- 修改 ChangePet 函数返回值
- 优化物品添加和查询逻辑
- 增加新消息类型 CatchMonsterOutboundInfo
- 调整战斗循环处理捕捉逻辑
待修复技能丢失问题
This commit is contained in:
2025-09-11 02:44:21 +08:00
parent 53df18c1e1
commit 0ca743a592
9 changed files with 123 additions and 20 deletions

View File

@@ -89,5 +89,12 @@ func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *service.Player
func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
c.FightC.ChangePet(c, int32(data.CatchTime))
return nil, 0
return nil, -1
}
// 切换精灵
func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *service.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) {
c.FightC.Capture(c, (data.CapsuleId))
return nil, -1
}

View File

@@ -14,7 +14,7 @@ func (h Controller) UserItemList(data *item.ItemListInboundInfo, c *service.Play
re := c.Service.ItemCheak()
for _, v := range re {
if int32(v.ItemId) > int32(data.Param1) && int32(v.ItemId) < int32(data.Param2) {
if int32(v.ItemId) >= int32(data.Param1) && int32(v.ItemId) <= int32(data.Param2) {
v.LeftTime = 360000
result.ItemList = append(result.ItemList, v)
}

View File

@@ -16,15 +16,24 @@ func (h *Controller) GetPetInfo(
data *pet.InInfo,
c *service.Player) (result *pet.OutInfo,
err errorcode.ErrorCode) { //这个时候player应该是空的
for _, pi := range c.Info.PetList {
if pi.CatchTime == data.CatchTime {
return &pet.OutInfo{
result = &pet.OutInfo{
PetInfo: pi,
}, 0
}
}
}
return result, errorcode.ErrorCodes.ErrNoPrerequisiteFacility
if result == nil {
result = &pet.OutInfo{
PetInfo: c.Service.GetPetInfo(data.CatchTime),
}
}
return result, 0
}
// 获取仓库列表

View File

@@ -53,3 +53,9 @@ type ChangePetInboundInfo struct {
// CatchTime 捕捉时间
CatchTime uint32 `json:"catchTime"`
}
type CatchMonsterInboundInfo struct {
Head service.TomeeHeader `cmd:"2409" struc:"[0]pad"`
// CapsuleId 胶囊id
// 对应Java的@UInt long类型映射为uint64
CapsuleId uint32 `json:"capsuleId" fieldDescription:"胶囊id" uint:"true"`
}

View File

@@ -106,20 +106,22 @@ func (a *ActiveSwitchAction) GetPlayerID() uint32 {
}
// UsePotionAction 使用药剂的战斗动作
type UsePotionAction struct {
PlayerID uint32 // 玩家ID
PotionID uint32 // 药剂ID
PotionName string // 药剂名称
TargetPet BattlePetEntity // 药剂作用目标宠物
type UseItemAction struct {
PlayerID uint32 // 玩家ID
ItemID uint32 // 药剂ID
TargetPet BattlePetEntity // 药剂作用目标宠物
}
type PlayerI interface {
SendPack(b []byte) error
}
// Priority 返回动作优先级
func (u *UsePotionAction) Priority() int {
func (u *UseItemAction) Priority() int {
return int(PlayerOperations.UsePotion)
}
func (e *UseItemAction) GetPlayerID() uint32 {
return e.PlayerID
}
// EscapeAction 逃跑的战斗动作
type EscapeAction struct {

View File

@@ -228,6 +228,11 @@ type ReadyFightPetInfo struct {
// FightOverInfo 战斗结束信息结构体 2506
type FightOverInfo struct {
//1=isPlayerLost 对方玩家退出
// 2=isOvertime 正常对战结束?有质疑
// 3=isDraw 双方平手
// 4=isSysError 系统错误
// 5=isNpcEscape 精灵主动逃跑
Reason uint32 // 固定值0
WinnerId uint32 // 胜者的米米号 野怪为0
TwoTimes uint32 // 双倍经验剩余次数
@@ -236,3 +241,14 @@ type FightOverInfo struct {
EnergyTimes uint32 // 能量吸收器剩余次数
LearnTimes uint32 // 双倍学习器剩余次数
}
// CatchMonsterOutboundInfo 捕捉怪物的出站消息结构体
// 对应Java的CatchMonsterOutboundInfo类
type CatchMonsterOutboundInfo struct {
// CatchTime 捕捉时间
// 对应Java的@UInt long类型映射为uint64
CatchTime uint32 `json:"catchTime" fieldDescription:"捕捉时间" uint:"true"`
// PetId 宠物编号
// 对应Java的@UInt long类型映射为uint64
PetId uint32 `json:"petId" fieldDescription:"宠物编号" uint:"true"`
}

View File

@@ -26,6 +26,7 @@ type PlayerI interface {
SendReadyToFightInfo(info.FightStartOutboundInfo)
SendNoteReadyToFightInfo(info.NoteReadyToFightInfo)
SendFightEndInfo(info.FightOverInfo)
SendAttackValue(info.AttackValueS)
SendChangePet(info.ChangePetInfo)
SetFightC(*FightC)
@@ -103,8 +104,9 @@ func (f *FightC) ChangePet(c PlayerI, id int32) {
rett := func(t *Input) *info.BattlePetEntity {
for _, v := range t.AllPet {
if v.Info.CatchTime == uint32(id) {
copier.Copy(&ret.Reason, &v)
copier.Copy(&ret.Reason, &v.Info)
ret.Reason.UserId = c.ID()
return v
}
@@ -139,6 +141,12 @@ func (f *FightC) UseSkill(c PlayerI, id int32) {
f.actionChan <- ret
}
// 玩家使用技能
func (f *FightC) Capture(c PlayerI, id uint32) {
f.actionChan <- &info.UseItemAction{PlayerID: c.ID(), ItemID: id}
}
// 战斗准备
func (f *FightC) ReadyFight(c PlayerI) {
rett := info.FightStartOutboundInfo{}
@@ -331,6 +339,39 @@ func (f *FightC) battleLoop() {
case *info.ActiveSwitchAction: //切换上场的
f.enterturn(BattleActionI[1], nil) //切换,相当于后手直接出手
case *info.UseItemAction: //使用道具
fmt.Println(faction.ItemID)
switch {
case faction.ItemID >= 30001 && faction.ItemID <= 300010: //胶囊
f.Broadcast(func(ff *Input) {
//todo 将血量和技能pp传回enterturn
tt, ok := ff.Player.(*Player)
if ok {
tt.Service.PetAdd(*f.Opp.CurrentPet.Info)
tt.CatchPetInfo(info.CatchMonsterOutboundInfo{
CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime),
PetId: uint32(f.Opp.CurrentPet.ID),
})
}
ff.Player.SendFightEndInfo(info.FightOverInfo{
WinnerId: f.OwnerID,
})
})
// 当 ItemID 在 30001-300010 之间时执行的逻辑
fmt.Println("ItemID 在范围内")
case faction.ItemID == 300001:
// 原来的单个值判断(如果还需要保留)
fmt.Println("ItemID 是 300001")
default:
// 其他情况
fmt.Println("ItemID 不在指定范围内")
}
case *info.SelectSkillAction: //选择技能
//回合前操作,比如挂载buff

View File

@@ -134,7 +134,13 @@ func (p *Player) GetAction() {
func (p *Player) ItemAdd(t []model.SingleItemInfo) {
var ttt []model.SingleItemInfo
for _, v := range t {
if v.ItemId > 10000 {
switch v.ItemId {
case 1: //塞尔豆
p.Info.Coins = p.Info.Coins + v.ItemCnt
case 3: //累计经验
p.Info.ExpPool = p.Info.ExpPool + int64(v.ItemCnt)
default:
ttt = append(ttt, v)
}
@@ -199,6 +205,12 @@ func (p *Player) GetPetInfo() []model.PetInfo {
return p.Info.PetList
}
func (p *Player) CatchPetInfo(b info.CatchMonsterOutboundInfo) {
t1 := NewTomeeHeader(2409, p.Info.UserID)
p.SendPack(t1.Pack(&b))
}
func (f *Player) SetFightC(ff *FightC) {
f.FightC = ff
}

View File

@@ -19,12 +19,12 @@ func (s *UserService) ItemExec(t func([]model.SingleItemInfo) []model.SingleItem
m1.Save(player)
}
func (s *UserService) ItemCheak() []model.SingleItemInfo {
func (s *UserService) ItemCheak() map[uint32]model.SingleItemInfo {
//todo待测试
var player model.Item
m1 := cool.DBM(s.item.Model).Where("player_id", s.userid)
var rer []model.SingleItemInfo
var rer map[uint32]model.SingleItemInfo
m1.Scan(&player)
json.Unmarshal([]byte(player.Data), &rer)
//return gjson.Parse(player.Data)
@@ -35,13 +35,13 @@ func (s *UserService) ItemAdd(t []model.SingleItemInfo) {
//todo待测试
var player model.Item
m1 := cool.DBM(s.item.Model).Where("player_id", s.userid)
var rer []model.SingleItemInfo
var rer map[uint32]model.SingleItemInfo
rer = make(map[uint32]model.SingleItemInfo)
m1.Scan(&player)
json.Unmarshal([]byte(player.Data), &rer)
player.PlayerID = uint64(s.userid)
if len(rer) == 0 {
fff, _ := json.Marshal(append(rer, t...))
fff, _ := json.Marshal(rer)
player.Data = string(fff)
_, err := m1.Insert(player)
@@ -49,10 +49,20 @@ func (s *UserService) ItemAdd(t []model.SingleItemInfo) {
panic(err)
}
return
}
fff, _ := json.Marshal(append(rer, t...))
for _, v := range t {
tt, ok := rer[v.ItemId]
if ok {
tt.ItemCnt += v.ItemCnt
rer[v.ItemId] = tt
} else {
rer[v.ItemId] = v
}
}
fff, _ := json.Marshal(rer)
player.Data = string(fff)
_, err := m1.Update(player)