fix(fight): 修复战斗中属性变化与暴击判定逻辑

- 调整能力提升计算时机,确保命中后再恢复原始属性
- 暴击判断前置,仅在命中时计算暴击翻倍及破防逻辑
- 优化回合结束效果清除逻辑,增加状态存活判断

refactor(controller): 重构擂台相关接口返回结构体类型

- 将 ARENA_SET_OWENR、ARENA_FIGHT_OWENR 等函数的返回值统一改为
  NullOutboundInfo,并移除冗余字段返回
- 广播逻辑调整,统一使用 Broadcast
This commit is contained in:
2025-11-20 05:57:29 +08:00
parent c0b09c92c4
commit 53d6db7e17
37 changed files with 555 additions and 151 deletions

View File

@@ -15,7 +15,7 @@ import (
// 前端到后端无数据内容 空包
// 后端到前端无数据内容 空包
// 都需要通过2419包广播更新擂台状态
func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 0, 1) {
@@ -23,8 +23,9 @@ func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Playe
c.GetSpace().Owner.Nick = c.GetInfo().Nick
c.GetSpace().ARENA_Player = c //添加用户
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
return &c.GetSpace().Owner, 0
c.GetSpace().Broadcast(c, 2419, c.GetSpace().Owner)
c.SendPackCmd(2419, c.GetSpace().Owner)
return
}
return nil, errorcode.ErrorCodes.ErrChampionExists
@@ -36,29 +37,29 @@ func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Playe
// 后端到前端无数据内容 空包
// 还是后端主动发送2503的包给双方前端后 等待前端加载完毕 主动发送2404包通知后端开始战斗
// 并不会通知对方是否接受挑战。只要有人挑战就直接进入对战
func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
s := c.GetSpace()
func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
//原子操作,修改擂台状态
if atomic.CompareAndSwapUint32(&s.Owner.Flag, 1, 2) {
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) {
//成功发起擂台挑战后才修改我放状态
c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER
_, err = fight.NewFight(c, s.ARENA_Player, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手
_, err = fight.NewFight(c, c.GetSpace().ARENA_Player, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手
}) ///开始对战,房主方以及被邀请方
if err <= 0 { //发起战斗成功
atomic.StoreUint32(&s.Owner.ChallengerID, c.GetInfo().UserID) //传回的指针赋值给ID
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 {
//发起失败,改回1
atomic.StoreUint32(&s.Owner.Flag, 1)
atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1)
}
s.Broadcast(c, 2419, &s.Owner)
return &s.Owner, 0
return
}
return nil, errorcode.ErrorCodes.ErrChampionExists
@@ -69,7 +70,8 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P
// 后端到前端
func (h Controller) ARENA_GET_INFO(data *fight.ARENA_GET_INFO, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
return &space.GetSpace(c.Info.MapID).Owner, 0
result = &c.GetSpace().Owner
return
}
// public static const ARENA_UPFIGHT:uint = 2420;
@@ -77,14 +79,16 @@ func (h Controller) ARENA_GET_INFO(data *fight.ARENA_GET_INFO, c *player.Player)
// 前端到后端无数据内容
// 后端到前端无数据内容
// 都需要通过2419包广播更新擂台状态
func (h Controller) ARENA_UPFIGHT(data *fight.ARENA_UPFIGHT, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
func (h Controller) ARENA_UPFIGHT(data *fight.ARENA_UPFIGHT, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
//原子操作,修改擂台状态
s := c.GetSpace()
if atomic.CompareAndSwapUint32(&s.Owner.UserID, c.GetInfo().UserID, 0) {
s.ARENA_Player = nil
s.Broadcast(c, 2419, &s.Owner)
return &s.Owner, 0
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.UserID, c.GetInfo().UserID, 0) {
c.GetSpace().ARENA_Player = nil
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
@@ -96,14 +100,14 @@ func (h Controller) ARENA_UPFIGHT(data *fight.ARENA_UPFIGHT, c *player.Player) (
// 后端到前端无数据内容
// public static const ARENA_OWENR_OUT:uint = 2423;
// 此包不清楚具体怎么触发 但已知此包为后端主动发送。不清楚什么情况下回用到
func (h Controller) ARENA_OWENR_ACCE(data *fight.ARENA_OWENR_ACCE, c *player.Player) (result *space.ARENA, err errorcode.ErrorCode) {
func (h Controller) ARENA_OWENR_ACCE(data *fight.ARENA_OWENR_ACCE, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
s := c.GetSpace()
if atomic.LoadUint32(&s.Owner.UserID) != c.GetInfo().UserID && c.GetInfo().UserID != atomic.LoadUint32(&s.Owner.ChallengerID) { //说明已经有人了
return nil, errorcode.ErrorCodes.Err24hBanCheatTool
return nil, -1
}
if c.GetInfo().UserID == atomic.LoadUint32(&s.Owner.UserID) {
c.Info.MaxArenaWins += 1
s.Owner.HostWins += 1 //连胜+1
} else {
@@ -116,5 +120,7 @@ func (h Controller) ARENA_OWENR_ACCE(data *fight.ARENA_OWENR_ACCE, c *player.Pla
atomic.StoreUint32(&s.Owner.Flag, 1)
s.Broadcast(c, 2419, &s.Owner)
return &s.Owner, 0
c.SendPackCmd(2419, &c.GetSpace().Owner)
return nil, -1
}

View File

@@ -14,9 +14,15 @@ import (
func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
c.Fightinfo.Mode = info.BattleMode.PET_MELEE
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER
c.Fightinfo.PlayerID = 0
c.JoinFight(func(p common.PlayerI) bool {
err = c.JoinFight(func(p common.PlayerI) bool {
fight.NewFight(p, c, func(foi *info.FightOverInfo) {
if foi.Reason == 0 && foi.WinnerId == c.GetInfo().UserID { //我放获胜
c.Info.MessWin += 1
}
}) ///开始对战,房主方以及被邀请方
@@ -28,16 +34,20 @@ func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Play
func (h Controller) PET_King(data *fight.PetKingJoinInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER
c.Fightinfo.PlayerID = 0
switch data.Type {
case 5:
c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE
case 6:
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
}
c.JoinFight(func(p common.PlayerI) bool {
err = c.JoinFight(func(p common.PlayerI) bool {
fight.NewFight(p, c, func(foi *info.FightOverInfo) {
if foi.Reason == 0 && foi.WinnerId == c.GetInfo().UserID { //我放获胜
c.Info.MonKingWin += 1
}
}) ///开始对战,房主方以及被邀请方
return true

View File

@@ -17,8 +17,10 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou
return nil, errorcode.ErrorCodes.ErrInBattle
}
c.Fightinfo.PlayerID = data.UserID
c.Fightinfo.PlayerID = c.Info.UserID
c.Fightinfo.Mode = data.Mode
c.Fightinfo.Status = 1
c.Fightinfo.Type = 0
err = c.AgreeBattle(data.UserID, data.Flag, func(p common.PlayerI) bool {
_, err = fight.NewFight(p, c, func(foi *info.FightOverInfo) {
@@ -34,12 +36,14 @@ func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInf
//进入邀请,以及确认对战模式
if !atomic.CompareAndSwapUint32(&c.Fightinfo.PlayerID, 0, data.UserID) { //邀请前提是自己没邀请别人
return nil, errorcode.ErrorCodes.ErrCannotPerformAction
// if !atomic.CompareAndSwapUint32(&c.Fightinfo.PlayerID, 0, data.UserID) { //邀请前提是自己没邀请别人
// return nil, errorcode.ErrorCodes.ErrCannotPerformAction
}
// }
c.Fightinfo.PlayerID = data.UserID
c.Fightinfo.Mode = data.Mode
c.Fightinfo.Status = 1
c.Fightinfo.Type = 0
c.InvitePlayerToBattle()
return nil, 0
@@ -50,7 +54,7 @@ func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCanc
if atomic.LoadUint32(&c.Fightinfo.Status) != 0 { //如果没有战斗状态,则不做任何处理
atomic.StoreUint32(&c.Fightinfo.Status, 0) //设置状态为0
return nil, 0
}
//否则报错
return nil, errorcode.ErrorCodes.ErrCannotCancelBattle

View File

@@ -64,7 +64,7 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
}
t.Info.UserID = data.Head.UserID
t.Logintime = uint32(time.Now().Unix()) //保存时间戳
t.Changemap = true
cool.Loger.Info(context.Background(), "用户上次重置日期", t.Info.LastResetTime.String())
if !IsToday(t.Info.LastResetTime) { //判断是否是今天
t.Info.LastResetTime = gtime.Now().Time

View File

@@ -2,6 +2,7 @@ package controller
import (
"blazing/common/socket/errorcode"
"sync/atomic"
"blazing/logic/service/maphot"
"blazing/logic/service/maps"
@@ -34,24 +35,25 @@ func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *mapho
return
}
func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *player.Player) (result *info.LeaveMapOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
//result = &maps.LeaveMapOutboundInfo{UserID: c.GetUserID()}
c.Canmon = false
c.Changemap = true //可以刷怪
//data.Broadcast(c.Info.MapID, info.LeaveMapOutboundInfo{UserID: c.Info.UserID}) //同步广播
atomic.StoreUint32(&c.Canmon, 0)
//data.Broadcast(c.Info.MapID, info.LeaveMapOutboundInfo{UserID: c.Info.UserID}) //同步广播
result = &info.LeaveMapOutboundInfo{
UserID: c.Info.UserID,
}
defer c.GetSpace().LeaveMap(c) //玩家离开地图
// 如果有正在运行的刷怪协程,发送停止信号
//c.Info.MapID = 0 // 重置当前地图
return &info.LeaveMapOutboundInfo{UserID: c.Info.UserID}, 0
return
}
func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *player.Player) (result *info.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
result = &info.ListMapPlayerOutboundInfo{
Player: c.GetSpace().GetInfo(),
}
atomic.StoreUint32(&c.Canmon, 2)
c.Canmon = true //可以刷怪
return
}

View File

@@ -13,12 +13,12 @@ func (h *Controller) NonoFollowOrHome(data *nono.NonoFollowOrHomeInInfo, c *play
c.Info.NONO.Flag = data.Flag
result = &nono.NonoFollowOutInfo{
UserID: data.Head.UserID,
UserID: data.Head.UserID,
SuperStage: data.Flag,
Flag: data.Flag,
Nick: "",
Color: 0,
Power: 0,
Flag: data.Flag,
Nick: "",
Color: 0,
Power: 0,
}
return
@@ -44,14 +44,17 @@ func (h *Controller) SwitchFlying(data *nono.SwitchFlyingInboundInfo, c *player.
result = &nono.SwitchFlyingOutboundInfo{
UserId: data.Head.UserID,
Type: data.Type,
Type: data.Type,
}
c.GetSpace().Broadcast(c, data.Head.CMD, result)
return
}
func (h *Controller) PlayerPetCure(data *nono.PetCureInboundInfo, c *player.Player) (result *nono.PetCureOutboundEmpty, err errorcode.ErrorCode) { //这个时候player应该是空的
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotHeal
}
for i := 0; i < len(c.Info.PetList); i++ {
c.Info.PetList[i].Cure()

View File

@@ -63,9 +63,13 @@ func (h *Controller) PetRelease(
err errorcode.ErrorCode) { //这个时候player应该是空的
//放入背包=数据库置1+添加到背包+pet release发包 仓库=数据库置0+移除背包 设置首发等于取到首发精灵后重新排序
//这里只修改,因为添加和移除背包在宠物获取时已经做了
result = &pet.PetReleaseOutboundInfo{}
result.Flag = uint32(data.Flag)
//擂台住不能换精灵
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotSwitch
}
switch data.Flag {
case 0:
var temp []model.PetInfo
@@ -131,7 +135,9 @@ func (h *Controller) PlayerShowPet(
}
func (h *Controller) PetOneCure(
data *pet.PetOneCureInboundInfo, c *player.Player) (result *pet.PetOneCureOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotHeal
}
_, onpet, ok := utils.FindWithIndex(c.Info.PetList, func(item model.PetInfo) bool {
return item.CatchTime == data.CatchTime
})

View File

@@ -98,6 +98,24 @@ func (h Controller) ChangeNONOColor(data *user.ChangeNONOColorInboundInfo, c *pl
Sataus: c.Info.UserID,
Color: c.Info.Color,
}
return result, 0
c.GetSpace().Broadcast(c, data.Head.CMD, result)
return
}
func (h Controller) DANCE_ACTION(data *user.C2SDanceAction, c *player.Player) (result *user.S2CDanceAction, err errorcode.ErrorCode) {
result = &user.S2CDanceAction{
Type: data.Type,
UserID: c.Info.UserID,
}
c.GetSpace().Broadcast(c, data.Head.CMD, result)
return
}
func (h Controller) PEOPLE_TRANSFROM(data *user.C2SPEOPLE_TRANSFROM, c *player.Player) (result *user.S2CPEOPLE_TRANSFROM, err errorcode.ErrorCode) {
result = &user.S2CPEOPLE_TRANSFROM{
SuitID: data.SuitID,
UserID: c.Info.UserID,
}
c.GetSpace().Broadcast(c, data.Head.CMD, result)
return
}