Files
bl/logic/controller/fight_leitai.go
昔念 e341623fc0 ```
refactor(fight): 修正战斗回调函数参数类型

- 修正所有战斗相关控制器中的回调函数参数类型
- 将 func(*info.FightOverInfo) 改为 func(info.FightOverInfo)
- 保持代码逻辑不变,仅修复类型声明

feat(pet): 实现精灵图鉴功能

- 添加精灵捕捉和击杀数量统计功能
- 实现 GetPetBargeList 接口返回图鉴列表
- 在战斗胜利后自动更新图鉴状态

refactor(fight): 优化战斗循环逻辑

- 重构
2026-01-03 02:18:31 +08:00

159 lines
5.4 KiB
Go

package controller
import (
"blazing/common/socket/errorcode"
"sync/atomic"
"blazing/logic/service/fight"
"blazing/logic/service/fight/info"
"blazing/logic/service/player"
"blazing/logic/service/space"
)
// ArenaSetOwner 处理玩家占据擂台的请求
// public static const ARENA_SET_OWENR:uint = 2417;
// 如果星际擂台上无人,站到星际擂台的包
// 前端到后端无数据内容 空包
// 后端到前端无数据内容 空包
// ArenaSetOwner 都需要通过2419包广播更新擂台状态
func (h Controller) ArenaSetOwner(data *fight.ARENA_SET_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrPokemonNotEligible
}
c.Fightinfo.Mode = 0 //取消队列匹配
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 0, 1) {
c.GetSpace().Owner.Set(c)
c.GetSpace().Broadcast(c, 2419, c.GetSpace().Owner)
c.SendPackCmd(2419, c.GetSpace().Owner)
return
}
return nil, errorcode.ErrorCodes.ErrChampionExists
}
// ArenaFightOwner 挑战擂台的包
// 前端到后端无数据内容 空包
// 后端到前端无数据内容 空包
// 还是后端主动发送2503的包给双方前端后 等待前端加载完毕 主动发送2404包通知后端开始战斗
// ArenaFightOwner 并不会通知对方是否接受挑战。只要有人挑战就直接进入对战
func (h Controller) ArenaFightOwner(data *fight.ARENA_FIGHT_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
if c.Info.UserID == c.GetSpace().Owner.UserID {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
if c.GetSpace().Owner.ARENA_Player == nil {
return nil, errorcode.ErrorCodes.ErrSystemError200007
}
if !c.GetSpace().Owner.ARENA_Player.CanFight() {
c.GetSpace().Owner.Set(c)
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
return
}
//原子操作,修改擂台状态
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) {
//成功发起擂台挑战后才修改我放状态
c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE
c.Fightinfo.Status = info.BattleMode.FIGHT_ARENA
_, err = fight.NewFight(c, c.GetSpace().Owner.ARENA_Player, func(foi info.FightOverInfo) { //我方邀请擂主挑战,我方先手
if foi.Reason != 0 && foi.WinnerId == c.GetInfo().UserID { //异常退出
c.GetSpace().Owner.Reset()
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
}
if foi.Reason == 0 { //异常退出
if foi.WinnerId == c.GetInfo().UserID {
c.Info.MaxArenaWins += 1
} else {
c.GetSpace().Owner.ARENA_Player.GetInfo().MaxArenaWins += 1
}
}
//todo 擂主输了,那就直接让他放弃擂台
}) ///开始对战,房主方以及被邀请方
if err <= 0 { //发起战斗成功
atomic.StoreUint32(&c.GetSpace().Owner.ChallengerID, c.GetInfo().UserID) //传回的指针赋值给ID
//c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
//c.SendPackCmd(2419, &c.GetSpace().Owner)
} else {
atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1)
}
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
return
}
return nil, errorcode.ErrorCodes.ErrChampionExists
}
// ArenaGetInfo 获取星际擂台信息的包 进入空间站地图前端会发送请求包 或者 有人站到星际擂台上后 广播回包
// 前端到后端无数据内容
// ArenaGetInfo 后端到前端
func (h Controller) ArenaGetInfo(data *fight.ARENA_GET_INFO, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
result = &c.GetSpace().Owner
return
}
// ArenaUpfight 放弃擂台挑战的包
// 前端到后端无数据内容
// 后端到前端无数据内容
// ArenaUpfight 都需要通过2419包广播更新擂台状态
func (h Controller) ArenaUpfight(data *fight.ARENA_UPFIGHT, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
//原子操作,修改擂台状态
if atomic.LoadUint32(&c.GetSpace().Owner.UserID) != c.GetInfo().UserID { //说明已经有人了
return nil, errorcode.ErrorCodes.ErrChampionCannotCancel
}
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.UserID, c.GetInfo().UserID, 0) {
c.GetSpace().Owner.Reset()
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
return nil, -1
}
return nil, errorcode.ErrorCodes.ErrChampionCannotCancel
}
// ArenaOwnerAcce 此包为擂台战对战结束后 胜方前端会发送给后端 具体作用为通知后端发送2419包更新擂台信息。
// 前端到后端无数据内容
// 后端到前端无数据内容
// public static const ARENA_OWENR_OUT:uint = 2423;
// ArenaOwnerAcce 此包不清楚具体怎么触发 但已知此包为后端主动发送。不清楚什么情况下回用到
func (h Controller) ArenaOwnerAcce(data *fight.ARENA_OWENR_ACCE, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
s := c.GetSpace()
if atomic.LoadUint32(&c.GetSpace().Owner.UserID) != c.GetInfo().UserID && c.GetInfo().UserID != atomic.LoadUint32(&c.GetSpace().Owner.ChallengerID) { //说明已经有人了
return nil, -1
}
s.Owner.Set(c)
atomic.StoreUint32(&s.Owner.Flag, 1)
s.Broadcast(c, 2419, &s.Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
return nil, -1
}