```
feat(fight): 增加战斗模式枚举并重构战斗逻辑判断 - 引入完整的 BattleMode 枚举定义,替代原有的 BattleStatus,明确区分各类战斗场景 - 在多个控制器中替换对旧 Status 字段的依赖,统一使用 Mode 判断战斗状态 - 修复部分函数调用前未检查 FightC 是否为空的问题,增加 ErrBattleEnded 错误返回 - 调整
This commit is contained in:
@@ -11,27 +11,34 @@ import (
|
|||||||
|
|
||||||
// 准备战斗
|
// 准备战斗
|
||||||
func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
if c.FightC == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
|
}
|
||||||
c.FightC.ReadyFight(c)
|
c.FightC.ReadyFight(c)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用技能包
|
// 使用技能包
|
||||||
func (h Controller) UseSkill(data *fight.UseSkillInInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) UseSkill(data *fight.UseSkillInInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if c.FightC != nil {
|
if c.FightC == nil {
|
||||||
c.FightC.UseSkill(c, int32(data.SkillId))
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
c.FightC.UseSkill(c, int32(data.SkillId))
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 战斗逃跑
|
// 战斗逃跑
|
||||||
func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if atomic.LoadUint32(&c.Fightinfo.Status) == 0 {
|
|
||||||
|
if c.FightC == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
|
}
|
||||||
|
|
||||||
|
if atomic.LoadUint32(&c.Fightinfo.Mode) == 0 {
|
||||||
|
|
||||||
return nil, errorcode.ErrorCodes.ErrBattleNotStarted //,没开始对战
|
return nil, errorcode.ErrorCodes.ErrBattleNotStarted //,没开始对战
|
||||||
}
|
}
|
||||||
if atomic.LoadUint32(&c.Fightinfo.Status) == 1 { //用户对战不能逃跑
|
if atomic.LoadUint32(&c.Fightinfo.Mode) == 1 { //用户对战不能逃跑
|
||||||
|
|
||||||
return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle
|
return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle
|
||||||
}
|
}
|
||||||
@@ -41,33 +48,39 @@ func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player)
|
|||||||
|
|
||||||
// 切换精灵
|
// 切换精灵
|
||||||
func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if c.FightC != nil {
|
if c.FightC == nil {
|
||||||
c.FightC.ChangePet(c, data.CatchTime)
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.FightC.ChangePet(c, data.CatchTime)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换精灵
|
// 切换精灵
|
||||||
func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
if c.FightC == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
|
}
|
||||||
c.FightC.Capture(c, data.CapsuleId)
|
c.FightC.Capture(c, data.CapsuleId)
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载进度
|
// 加载进度
|
||||||
func (h Controller) LoadPercent(data *fight.LoadPercentInboundInfo, c *player.Player) (result *info.LoadPercentOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) LoadPercent(data *fight.LoadPercentInboundInfo, c *player.Player) (result *info.LoadPercentOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if c.FightC != nil {
|
if c.FightC == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
c.FightC.LoadPercent(c, int32(data.Percent))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.FightC.LoadPercent(c, int32(data.Percent))
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetIteminfo, 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)
|
if c.FightC == nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrBattleEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.FightC.UseItem(c, data.CatchTime, data.ItemId)
|
||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"blazing/common/data/xmlres"
|
"blazing/common/data/xmlres"
|
||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -97,17 +98,23 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_BOSS
|
c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
|
||||||
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
|
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
|
||||||
|
|
||||||
ai := player.NewAI_player(moinfo)
|
ai := player.NewAI_player(moinfo)
|
||||||
//给予打过一次的奖励
|
//给予打过一次的奖励
|
||||||
event := c.Done.SPT(c.Info.MapID, data.BossId, 1, func() {
|
event := c.Done.SPT(c.Info.MapID, data.BossId, 1, func() bool {
|
||||||
|
fmt.Println("触发事件", "第一次奖励")
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
event1 := c.Done.SPT(c.Info.MapID, data.BossId, 2, func() bool {
|
||||||
|
fmt.Println("触发事件", "第二次奖励")
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
||||||
c.Done.Exec(model.MilestoneMode.BOSS, []uint32{data.BossId})
|
c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId})
|
||||||
event.Cancel() //取消事件
|
event.Cancel() //取消事件
|
||||||
|
event1.Cancel()
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -133,9 +140,10 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn
|
|||||||
moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName
|
moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName
|
||||||
moinfo.PetList = append(moinfo.PetList, *mo)
|
moinfo.PetList = append(moinfo.PetList, *mo)
|
||||||
ai := player.NewAI_player(moinfo)
|
ai := player.NewAI_player(moinfo)
|
||||||
|
ai.CanCapture = handleNPCFightSpecial(mo.ID)
|
||||||
|
|
||||||
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_NPC
|
c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC //打野怪
|
||||||
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
|
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE //多人模式
|
||||||
|
|
||||||
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
||||||
|
|
||||||
@@ -143,3 +151,15 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn
|
|||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
func handleNPCFightSpecial(petid uint32) int {
|
||||||
|
|
||||||
|
npcPetID := int(petid)
|
||||||
|
petCfg, ok := xmlres.PetMAP[npcPetID]
|
||||||
|
if !ok {
|
||||||
|
// log.Error(context.Background(), "NPC宠物配置不存在", "petID", npcPetID)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
catchRate := gconv.Int(petCfg.CatchRate)
|
||||||
|
return catchRate
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ import (
|
|||||||
// 都需要通过2419包广播更新擂台状态
|
// 都需要通过2419包广播更新擂台状态
|
||||||
func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) ARENA_SET_OWENR(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) {
|
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 0, 1) {
|
||||||
|
|
||||||
c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID
|
c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID
|
||||||
@@ -42,14 +46,28 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P
|
|||||||
if !c.CanFight() {
|
if !c.CanFight() {
|
||||||
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Info.UserID == c.GetSpace().Owner.UserID {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
||||||
|
}
|
||||||
//原子操作,修改擂台状态
|
//原子操作,修改擂台状态
|
||||||
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) {
|
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) {
|
||||||
//成功发起擂台挑战后才修改我放状态
|
//成功发起擂台挑战后才修改我放状态
|
||||||
c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE
|
c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE
|
||||||
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER
|
c.Fightinfo.Status = info.BattleMode.FIGHT_ARENA
|
||||||
|
|
||||||
_, err = fight.NewFight(c, c.GetSpace().ARENA_Player, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手
|
_, err = fight.NewFight(c, c.GetSpace().ARENA_Player, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手
|
||||||
|
|
||||||
|
if foi.Reason != 0 && foi.WinnerId == c.GetInfo().UserID { //异常退出
|
||||||
|
c.GetSpace().ARENA_Player = nil
|
||||||
|
c.GetSpace().Owner.Reset()
|
||||||
|
|
||||||
|
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
|
||||||
|
c.SendPackCmd(2419, &c.GetSpace().Owner)
|
||||||
|
|
||||||
|
}
|
||||||
|
//todo 擂主输了,那就直接让他放弃擂台
|
||||||
|
|
||||||
}) ///开始对战,房主方以及被邀请方
|
}) ///开始对战,房主方以及被邀请方
|
||||||
|
|
||||||
if err <= 0 { //发起战斗成功
|
if err <= 0 { //发起战斗成功
|
||||||
@@ -58,10 +76,10 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P
|
|||||||
//c.SendPackCmd(2419, &c.GetSpace().Owner)
|
//c.SendPackCmd(2419, &c.GetSpace().Owner)
|
||||||
} else {
|
} else {
|
||||||
//发起失败,改回1
|
//发起失败,改回1
|
||||||
c.GetSpace().Owner.HostWins = 0 //连胜重置
|
// c.GetSpace().Owner.HostWins = 0 //连胜重置
|
||||||
c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID
|
// c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID
|
||||||
c.GetSpace().Owner.Nick = c.GetInfo().Nick
|
// c.GetSpace().Owner.Nick = c.GetInfo().Nick
|
||||||
c.GetSpace().ARENA_Player = c //添加用户
|
// c.GetSpace().ARENA_Player = c //添加用户
|
||||||
atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1)
|
atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import (
|
|||||||
func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
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.Mode = info.BattleMode.PET_MELEE
|
||||||
c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER
|
c.Fightinfo.Status = info.BattleMode.PET_MELEE
|
||||||
|
|
||||||
err = c.JoinFight(func(p common.PlayerI) bool {
|
err = c.JoinFight(func(p common.PlayerI) bool {
|
||||||
fight.NewFight(p, c, func(foi *info.FightOverInfo) {
|
_, err = fight.NewFight(p, c, func(foi *info.FightOverInfo) {
|
||||||
if foi.Reason == 0 { //我放获胜
|
if foi.Reason == 0 { //我放获胜
|
||||||
|
|
||||||
if foi.WinnerId == c.GetInfo().UserID {
|
if foi.WinnerId == c.GetInfo().UserID {
|
||||||
@@ -29,6 +29,10 @@ func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
}) ///开始对战,房主方以及被邀请方
|
}) ///开始对战,房主方以及被邀请方
|
||||||
|
if err > 0 { //说明有报错
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@@ -37,7 +41,7 @@ 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) {
|
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.Status = info.BattleMode.PET_TOPLEVEL
|
||||||
|
|
||||||
switch data.Type {
|
switch data.Type {
|
||||||
case 5:
|
case 5:
|
||||||
|
|||||||
@@ -12,28 +12,32 @@ import (
|
|||||||
|
|
||||||
// 接收战斗或者取消战斗的包
|
// 接收战斗或者取消战斗的包
|
||||||
func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
if c.GetSpace().Owner.UserID == c.Info.UserID {
|
||||||
if !atomic.CompareAndSwapUint32(&c.Fightinfo.Status, 0, 1) { //邀请前提是自己没在战斗
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
if c.GetSpace().Owner.UserID == data.UserID {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
if !atomic.CompareAndSwapUint32(&c.Fightinfo.Mode, 0, data.Mode) { //邀请前提是自己没在战斗
|
||||||
return nil, errorcode.ErrorCodes.ErrInBattle
|
return nil, errorcode.ErrorCodes.ErrInBattle
|
||||||
|
|
||||||
}
|
}
|
||||||
//c.Fightinfo.PlayerID = c.Info.UserID
|
|
||||||
c.Fightinfo.Mode = data.Mode
|
//c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
|
||||||
c.Fightinfo.Status = 1
|
|
||||||
c.Fightinfo.Type = 0
|
|
||||||
resp := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{
|
resp := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{
|
||||||
UserID: c.Info.UserID,
|
UserID: c.Info.UserID,
|
||||||
Nick: c.Info.Nick,
|
Nick: c.Info.Nick,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range c.HavePVPinfo {
|
for _, v := range c.HavePVPinfo {
|
||||||
if v.GetInfo().UserID == data.UserID {
|
if v.GetInfo().UserID == data.UserID && v.Getfightinfo().Mode == data.Mode {
|
||||||
resp.Result = data.Flag
|
resp.Result = data.Flag
|
||||||
// 检查邀请者的邀请是否有效(对方已取消邀请)
|
// 检查邀请者的邀请是否有效(对方已取消邀请)
|
||||||
if v.Getfightinfo().Status == 0 {
|
if v.Getfightinfo().Status == 0 {
|
||||||
resp.Result = 4 // 邀请已取消
|
resp.Result = 4 // 邀请已取消
|
||||||
v.SendPackCmd(2502, &resp)
|
v.SendPackCmd(2502, &resp)
|
||||||
atomic.StoreUint32(&c.Fightinfo.Status, 0)
|
atomic.StoreUint32(&c.Fightinfo.Mode, 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +51,7 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou
|
|||||||
} else {
|
} else {
|
||||||
resp.Result = 3
|
resp.Result = 3
|
||||||
v.SendPackCmd(2502, &resp)
|
v.SendPackCmd(2502, &resp)
|
||||||
atomic.StoreUint32(&c.Fightinfo.Status, 0)
|
atomic.StoreUint32(&c.Fightinfo.Mode, 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +63,15 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou
|
|||||||
|
|
||||||
// 邀请其他人进行战斗
|
// 邀请其他人进行战斗
|
||||||
func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
if c.GetSpace().Owner.UserID == c.Info.UserID {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
if c.GetSpace().Owner.ChallengerID == c.Info.UserID {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
if c.GetSpace().Owner.UserID == data.UserID {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
// c.Fightinfo.PlayerID = data.UserID
|
// c.Fightinfo.PlayerID = data.UserID
|
||||||
c.Fightinfo.Mode = data.Mode
|
c.Fightinfo.Mode = data.Mode
|
||||||
c.Fightinfo.Status = 1
|
c.Fightinfo.Status = 1
|
||||||
@@ -76,6 +88,6 @@ func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInf
|
|||||||
|
|
||||||
// 取消队列
|
// 取消队列
|
||||||
func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
atomic.StoreUint32(&c.Fightinfo.Status, 0) //设置状态为0
|
atomic.StoreUint32(&c.Fightinfo.Mode, 0) //设置状态为0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ func (h *Controller) GetPetInfo(
|
|||||||
result = &pet.OutInfo{
|
result = &pet.OutInfo{
|
||||||
PetInfo: pi,
|
PetInfo: pi,
|
||||||
}
|
}
|
||||||
|
return result, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package fight
|
package fight
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/data/xmlres"
|
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
|
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/fight/action"
|
"blazing/logic/service/fight/action"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/fight/input"
|
"blazing/logic/service/fight/input"
|
||||||
|
"blazing/logic/service/player"
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
)
|
)
|
||||||
@@ -148,15 +147,20 @@ func (f *FightC) ReadyFight(c common.PlayerI) {
|
|||||||
|
|
||||||
// 3. 根据战斗类型判断是否满足战斗启动条件,满足则启动
|
// 3. 根据战斗类型判断是否满足战斗启动条件,满足则启动
|
||||||
switch f.Info.Status {
|
switch f.Info.Status {
|
||||||
case info.BattleStatus.FIGHT_WITH_PLAYER: // PVP战斗:需双方都准备完成
|
|
||||||
|
case info.BattleMode.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动
|
||||||
|
//f.handleNPCFightSpecial(&fightStartInfo)
|
||||||
|
|
||||||
|
if f.Opp.Player.(*player.AI_player).CanCapture > 0 {
|
||||||
|
f.Opp.CanCapture = f.Opp.Player.(*player.AI_player).CanCapture
|
||||||
|
fightStartInfo.Info2.Catchable = 1 //可以捕捉就置1
|
||||||
|
}
|
||||||
|
f.startBattle(fightStartInfo)
|
||||||
|
default: // PVP战斗:需双方都准备完成
|
||||||
if f.checkBothPlayersReady(c) {
|
if f.checkBothPlayersReady(c) {
|
||||||
f.startBattle(fightStartInfo)
|
f.startBattle(fightStartInfo)
|
||||||
}
|
}
|
||||||
case info.BattleStatus.FIGHT_WITH_BOSS: // BOSS战:单方准备完成即可启动
|
|
||||||
f.startBattle(fightStartInfo)
|
|
||||||
case info.BattleStatus.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动
|
|
||||||
f.handleNPCFightSpecial(&fightStartInfo)
|
|
||||||
f.startBattle(fightStartInfo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,28 +189,6 @@ func (f *FightC) checkBothPlayersReady(currentPlayer common.PlayerI) bool {
|
|||||||
return opponentInput.Finished
|
return opponentInput.Finished
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleNPCFightSpecial 处理NPC战斗的特殊逻辑(如可捕捉标记)
|
|
||||||
func (f *FightC) handleNPCFightSpecial(startInfo *info.FightStartOutboundInfo) {
|
|
||||||
// 检查野怪是否可捕捉(根据宠物ID获取捕捉率)
|
|
||||||
if len(f.ReadyInfo.OpponentPetList) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
npcPetID := int(f.ReadyInfo.OpponentPetList[0].ID)
|
|
||||||
petCfg, ok := xmlres.PetMAP[npcPetID]
|
|
||||||
if !ok {
|
|
||||||
// log.Error(context.Background(), "NPC宠物配置不存在", "petID", npcPetID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
catchRate := gconv.Int(petCfg.CatchRate)
|
|
||||||
if catchRate > 0 {
|
|
||||||
startInfo.Info2.Catchable = 1 // 标记为可捕捉
|
|
||||||
// 标记AI对手允许被捕捉(类型断言确保安全)
|
|
||||||
f.Opp.CanCapture = true
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// startBattle 启动战斗核心逻辑:提交战斗循环任务并通知双方
|
// startBattle 启动战斗核心逻辑:提交战斗循环任务并通知双方
|
||||||
func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) {
|
func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) {
|
||||||
|
|
||||||
|
|||||||
@@ -24,18 +24,44 @@ import (
|
|||||||
|
|
||||||
// 战斗模式
|
// 战斗模式
|
||||||
|
|
||||||
|
// BattleMode 战斗模式(对应AS中的战斗类型常量)
|
||||||
var BattleMode = enum.New[struct {
|
var BattleMode = enum.New[struct {
|
||||||
PET_MELEE uint32 `enum:"3"` //乱斗模式
|
// 基础模式
|
||||||
SINGLE_MODE uint32 `enum:"1"` // 单人模式
|
FIGHT_WITH_NPC uint32 `enum:"0"` //NPC模式
|
||||||
MULTI_MODE uint32 `enum:"2"` // 多人模式
|
SINGLE_MODE uint32 `enum:"1"` // 单人模式
|
||||||
}]()
|
MULTI_MODE uint32 `enum:"2"` // 多人模式
|
||||||
var BattleStatus = enum.New[struct {
|
PET_MELEE uint32 `enum:"3"` // 宠物乱斗模式
|
||||||
// 原ActionScript中的常量映射
|
DARK_FIGHT uint32 `enum:"4"` // 暗黑战斗
|
||||||
|
PET_TOPLEVEL uint32 `enum:"5"` // 宠物顶级战
|
||||||
FIGHT_WITH_NPC uint32 `enum:"3"` // 与NPC战斗
|
PET_ELEMENT_FIGHT uint32 `enum:"6"` // 宠物元素战斗(修正原拼写错误:ELMENT → ELEMENT)
|
||||||
FIGHT_WITH_BOSS uint32 `enum:"2"` // 与BOSS战斗
|
FIGHT_DEMON_SPACE uint32 `enum:"7"` // 魔域战斗
|
||||||
FIGHT_WITH_PLAYER uint32 `enum:"1"` // 与玩家战斗(PVP)
|
BATTLE_LAB uint32 `enum:"8"` // 战斗实验室
|
||||||
Null uint32 `enum:"0"`
|
LUCKY_BATTLE uint32 `enum:"9"` // 幸运战斗
|
||||||
|
FIGHT_ARENA uint32 `enum:"10"` // 竞技场战斗
|
||||||
|
CORE_FIGHT uint32 `enum:"11"` // 核心战斗
|
||||||
|
IMAGE_FIGHT uint32 `enum:"12"` // 镜像战斗
|
||||||
|
TOP_WAR_BEYOND uint32 `enum:"13"` // 巅峰之战·超越
|
||||||
|
HIGHER_FIGHT uint32 `enum:"14"` // 高阶战斗
|
||||||
|
GOLDEN_PALACE_FIGHT uint32 `enum:"15"` // 金殿战斗
|
||||||
|
FANTASY_PET_MELEE uint32 `enum:"16"` // 梦幻宠物乱斗
|
||||||
|
REFRACTIVE_MAGIC uint32 `enum:"17"` // 折射魔法战
|
||||||
|
PET_MELEE_FIGHT_BOSS uint32 `enum:"18"` // 宠物乱斗·打BOSS
|
||||||
|
PET_TRY_FIGHT uint32 `enum:"19"` // 宠物试玩战斗
|
||||||
|
PET_TOPLEVEL_NEW uint32 `enum:"20"` // 宠物顶级战(新版)
|
||||||
|
CATCH_LENNY_GAME uint32 `enum:"21"` // 捕捉莱尼小游戏
|
||||||
|
PEAK_JIHAD_FREE uint32 `enum:"22"` // 巅峰圣战·自由战
|
||||||
|
PEAK_JIHAD_3V3 uint32 `enum:"23"` // 巅峰圣战·3V3
|
||||||
|
GOBLINKING_BATTLE uint32 `enum:"24"` // 哥布林王战斗
|
||||||
|
DOOM_FIGHT uint32 `enum:"25"` // 末日战斗
|
||||||
|
SHOW_ROUND uint32 `enum:"26"` // 展示回合(试玩/演示)
|
||||||
|
PEAK_JIHAD_6V6 uint32 `enum:"27"` // 巅峰圣战·6V6
|
||||||
|
PEAK_JIHAD_FREE_PLAN uint32 `enum:"28"` // 巅峰圣战·自由战(计划版)
|
||||||
|
PEAK_JIHAD_6V6_JJ uint32 `enum:"29"` // 巅峰圣战·6V6(竞技版)
|
||||||
|
WIZARDKING_BIGFIGHT uint32 `enum:"30"` // 法老王大战
|
||||||
|
QINGLONG_COMPLETE_FIGHT uint32 `enum:"83"` // 青龙全套战斗(修正原拼写:COMPLELETE → COMPLETE)
|
||||||
|
PEAK_JIHAD_FIGHT_WITH_FIGURE uint32 `enum:"87"` // 巅峰圣战·角色对战
|
||||||
|
PEAK_JIHAD_BIG_MELEE uint32 `enum:"88"` // 巅峰圣战·大乱斗
|
||||||
|
PEAK_JIHAD_LIMIT_AC uint32 `enum:"999"` // 巅峰圣战·限AC(账号类型限制)
|
||||||
}]()
|
}]()
|
||||||
|
|
||||||
// 玩家离线数据
|
// 玩家离线数据
|
||||||
|
|||||||
@@ -45,11 +45,10 @@ type S2C_NOTE_HANDLE_FIGHT_INVITE struct {
|
|||||||
}
|
}
|
||||||
type Fightinfo struct {
|
type Fightinfo struct {
|
||||||
///PlayerID uint32
|
///PlayerID uint32
|
||||||
// 战斗模式 1 = 1v1 2 = 6v6 3大乱斗
|
// 战斗模式 1 = 1v1 2 = 6v6 3大乱斗 0 什么都不做
|
||||||
Mode uint32
|
Mode uint32
|
||||||
Type uint32 //战斗类型
|
//Type uint32 //战斗类型
|
||||||
|
|
||||||
//0无战斗,1PVP,2,BOOS,3PVE
|
|
||||||
Status uint32
|
Status uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,10 +105,6 @@ func (f *FightC) LoadPercent(c common.PlayerI, percent int32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode) {
|
func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode) {
|
||||||
if len(c.GetInfo().PetList) == 0 {
|
|
||||||
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.CanFight() {
|
if !c.CanFight() {
|
||||||
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
|
||||||
@@ -221,12 +217,12 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err
|
|||||||
|
|
||||||
f.ReadyInfo.OurInfo, f.ReadyInfo.OurPetList = initfightready(f.Our)
|
f.ReadyInfo.OurInfo, f.ReadyInfo.OurPetList = initfightready(f.Our)
|
||||||
f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.Opp)
|
f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.Opp)
|
||||||
|
var loadtime time.Duration = 120 * time.Second
|
||||||
|
//说明是PVE
|
||||||
|
if f.Info.Mode == info.BattleMode.FIGHT_WITH_NPC {
|
||||||
|
|
||||||
switch f.Info.Mode {
|
|
||||||
case info.BattleStatus.FIGHT_WITH_PLAYER:
|
|
||||||
|
|
||||||
default:
|
|
||||||
f.Opp.Finished = true //PVE 默认boss数据直接加载完成
|
f.Opp.Finished = true //PVE 默认boss数据直接加载完成
|
||||||
|
loadtime = 60 * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Broadcast(func(ff *input.Input) {
|
f.Broadcast(func(ff *input.Input) {
|
||||||
@@ -240,16 +236,7 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var t time.Duration
|
cool.Cron.AfterFunc(loadtime, func() {
|
||||||
// 60秒后判断战斗是否开始
|
|
||||||
switch f.Info.Mode {
|
|
||||||
case info.BattleMode.PET_MELEE:
|
|
||||||
t = 120 * time.Second
|
|
||||||
|
|
||||||
default:
|
|
||||||
t = 60 * time.Second
|
|
||||||
}
|
|
||||||
cool.Cron.AfterFunc(t, func() {
|
|
||||||
if !f.Our.Finished || !f.Opp.Finished { //如果有任一没有加载完成
|
if !f.Our.Finished || !f.Opp.Finished { //如果有任一没有加载完成
|
||||||
f.closefight = true //阻止继续添加action
|
f.closefight = true //阻止继续添加action
|
||||||
f.Reason = info.BattleOverReason.PlayerOVerTime
|
f.Reason = info.BattleOverReason.PlayerOVerTime
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type Input struct {
|
|||||||
AllPet []*info.BattlePetEntity
|
AllPet []*info.BattlePetEntity
|
||||||
Player common.PlayerI
|
Player common.PlayerI
|
||||||
Opp *Input
|
Opp *Input
|
||||||
CanCapture bool
|
CanCapture int
|
||||||
Finished bool //是否加载完成
|
Finished bool //是否加载完成
|
||||||
*info.AttackValue
|
*info.AttackValue
|
||||||
FightC common.FightI
|
FightC common.FightI
|
||||||
|
|||||||
@@ -125,8 +125,7 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AI自动技能
|
// AI自动技能
|
||||||
if pid != 0 && (f.Info.Status == info.BattleStatus.FIGHT_WITH_BOSS ||
|
if pid != 0 && (f.Info.Status == info.BattleMode.FIGHT_WITH_NPC) {
|
||||||
f.Info.Status == info.BattleStatus.FIGHT_WITH_NPC) {
|
|
||||||
f.GetInputByAction(paction, true).GetAction(f.Our)
|
f.GetInputByAction(paction, true).GetAction(f.Our)
|
||||||
//panic("AI自动技能")
|
//panic("AI自动技能")
|
||||||
}
|
}
|
||||||
@@ -223,7 +222,8 @@ func (f *FightC) handleItemAction(a *action.UseItemAction) {
|
|||||||
switch {
|
switch {
|
||||||
case gconv.Int(item.Bonus) != 0:
|
case gconv.Int(item.Bonus) != 0:
|
||||||
|
|
||||||
if f.Opp.CanCapture { //可以捕捉
|
if f.Opp.CanCapture > 0 { //可以捕捉
|
||||||
|
f.Opp.CurrentPet.CatchRate = f.Opp.CanCapture
|
||||||
ok, res := f.Our.Capture(f.Opp.CurrentPet, a.ItemID, -1)
|
ok, res := f.Our.Capture(f.Opp.CurrentPet, a.ItemID, -1)
|
||||||
our := f.Our.Player.(*player.Player)
|
our := f.Our.Player.(*player.Player)
|
||||||
if ok {
|
if ok {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
type AI_player struct {
|
type AI_player struct {
|
||||||
baseplayer
|
baseplayer
|
||||||
petinfo []model.PetInfo //精灵信息
|
petinfo []model.PetInfo //精灵信息
|
||||||
|
CanCapture int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AI_player) Getfightinfo() info.Fightinfo {
|
func (p *AI_player) Getfightinfo() info.Fightinfo {
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ func NewDone(P *Player) Done {
|
|||||||
// MAPID 地图ID
|
// MAPID 地图ID
|
||||||
// BOSSID 地图BOSSID
|
// BOSSID 地图BOSSID
|
||||||
// 注册胜利次数
|
// 注册胜利次数
|
||||||
func (d *Done) SPT(mapid, bossid, count uint32, fn func()) *bus.Listener[*model.MilestoneEX] {
|
// 监听器返回奖励是否发送完成,完成就done
|
||||||
|
func (d *Done) SPT(mapid, bossid, count uint32, fn func() bool) *bus.Listener[*model.MilestoneEX] {
|
||||||
return d.Topic.Sub(func(v *model.MilestoneEX) {
|
return d.Topic.Sub(func(v *model.MilestoneEX) {
|
||||||
|
|
||||||
if v.DoneType == model.MilestoneMode.BOSS && EqualBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count {
|
if v.DoneType == model.MilestoneMode.BOSS && EqualBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count {
|
||||||
@@ -34,8 +35,11 @@ func (d *Done) SPT(mapid, bossid, count uint32, fn func()) *bus.Listener[*model.
|
|||||||
return v1 == count
|
return v1 == count
|
||||||
})
|
})
|
||||||
if !ok { //说明没有触发过
|
if !ok { //说明没有触发过
|
||||||
v.Results = append(v.Results, count) //把本次的记录添加
|
|
||||||
fn()
|
if fn() {
|
||||||
|
v.Results = append(v.Results, count) //把本次的记录添加
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,20 @@ import (
|
|||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Player) JoinFight(fn func(p common.PlayerI) bool) errorcode.ErrorCode {
|
func (p *Player) JoinFight(fn func(p common.PlayerI) bool) errorcode.ErrorCode {
|
||||||
|
//加入队列前就开始判断一次
|
||||||
if !p.CanFight() {
|
if !p.CanFight() {
|
||||||
|
|
||||||
return errorcode.ErrorCodes.ErrNoEligiblePokemon
|
return errorcode.ErrorCodes.ErrNoEligiblePokemon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if p.GetSpace().Owner.UserID == p.Info.UserID {
|
||||||
|
return errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
//修复发包进入,如果此时是擂台主
|
||||||
|
|
||||||
p.GetSpace().User.Range(func(key uint32, v common.PlayerI) bool {
|
p.GetSpace().User.Range(func(key uint32, v common.PlayerI) bool {
|
||||||
|
|
||||||
@@ -24,7 +31,11 @@ func (p *Player) JoinFight(fn func(p common.PlayerI) bool) errorcode.ErrorCode {
|
|||||||
ttt := fn(v)
|
ttt := fn(v)
|
||||||
if ttt {
|
if ttt {
|
||||||
|
|
||||||
|
atomic.StoreUint32(&v.(*Player).Fightinfo.Mode, 0)
|
||||||
|
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lw = value
|
// lw = value
|
||||||
return ttt //如果发起成功就停止,否则继续遍历队列
|
return ttt //如果发起成功就停止,否则继续遍历队列
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,8 +103,6 @@ func (p *Player) Getfightinfo() info.Fightinfo {
|
|||||||
return p.Fightinfo
|
return p.Fightinfo
|
||||||
}
|
}
|
||||||
func (p *Player) QuitFight() {
|
func (p *Player) QuitFight() {
|
||||||
//将战斗标记设置为0 这里的标记是
|
|
||||||
atomic.StoreUint32(&p.Fightinfo.Status, 0)
|
|
||||||
|
|
||||||
p.FightC = nil
|
p.FightC = nil
|
||||||
|
|
||||||
@@ -116,11 +114,14 @@ func (p *Player) GetSpace() *space.Space {
|
|||||||
// 0无战斗,1PVP,2,BOOS,3PVE
|
// 0无战斗,1PVP,2,BOOS,3PVE
|
||||||
func (p *Player) CanFight() bool {
|
func (p *Player) CanFight() bool {
|
||||||
|
|
||||||
// if atomic.CompareAndSwapUint32(&p.Fightinfo.Status, 0, staus) { //先判断是否竞态条件被挑战
|
if len(p.Info.PetList) == 0 {
|
||||||
|
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
|
||||||
|
return false
|
||||||
|
|
||||||
//成功,继续判断
|
}
|
||||||
|
|
||||||
if p.FightC != nil {
|
if p.FightC != nil {
|
||||||
|
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,7 @@ func (p *Player) CanFight() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 遍历完所有宠物,都没有血量大于0的,才不能战斗
|
// 遍历完所有宠物,都没有血量大于0的,才不能战斗
|
||||||
|
atomic.StoreUint32(&p.Fightinfo.Mode, 0)
|
||||||
return false
|
return false
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import (
|
|||||||
type EnumMilestone int
|
type EnumMilestone int
|
||||||
|
|
||||||
var MilestoneMode = enum.New[struct {
|
var MilestoneMode = enum.New[struct {
|
||||||
BOSS EnumMilestone //boss类
|
BOSS EnumMilestone //boss类 地图ID->BOSSID
|
||||||
ITEM EnumMilestone //物品类
|
ITEM EnumMilestone //物品类 物品ID 使用精灵
|
||||||
|
Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数
|
||||||
}]()
|
}]()
|
||||||
|
|
||||||
// 里程碑数据结构,与DoneEvent对应,记录单条里程碑的详细信息
|
// 里程碑数据结构,与DoneEvent对应,记录单条里程碑的详细信息
|
||||||
@@ -29,7 +30,7 @@ type Milestone struct {
|
|||||||
*cool.Model
|
*cool.Model
|
||||||
PlayerID uint64 `gorm:"not null;index:idx_milestone_by_player_id;comment:'所属玩家ID'" json:"player_id"`
|
PlayerID uint64 `gorm:"not null;index:idx_milestone_by_player_id;comment:'所属玩家ID'" json:"player_id"`
|
||||||
DoneType EnumMilestone `gorm:"not null;comment:'里程碑类型'" json:"done_type"`
|
DoneType EnumMilestone `gorm:"not null;comment:'里程碑类型'" json:"done_type"`
|
||||||
Args string `gorm:"type:jsonb;not null;comment:'里程碑ID'" json:"args"`
|
Args string `gorm:"type:text;not null;comment:'里程碑ID'" json:"args"`
|
||||||
// 注:不单独设置"里程碑ID",通过 PlayerID + DoneType + IDs 组合唯一标识一个里程碑(更灵活)
|
// 注:不单独设置"里程碑ID",通过 PlayerID + DoneType + IDs 组合唯一标识一个里程碑(更灵活)
|
||||||
Results string `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"`
|
Results string `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"`
|
||||||
Count uint32 `gorm:"not null;comment:'里程碑完成次数'" json:"count"`
|
Count uint32 `gorm:"not null;comment:'里程碑完成次数'" json:"count"`
|
||||||
@@ -38,7 +39,7 @@ type Milestone struct {
|
|||||||
// MilestoneEX 里程碑扩展结构体,用于业务层解析后的数据操作
|
// MilestoneEX 里程碑扩展结构体,用于业务层解析后的数据操作
|
||||||
type MilestoneEX struct {
|
type MilestoneEX struct {
|
||||||
Milestone
|
Milestone
|
||||||
Args []uint32 `json:"args"` // 解析后的里程碑详细数据
|
Args []uint32 // 解析后的里程碑详细数据
|
||||||
Results []uint32 `json:"results"` // 解析后的里程碑详细数据
|
Results []uint32 `json:"results"` // 解析后的里程碑详细数据
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package service
|
|||||||
import (
|
import (
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DoneService struct {
|
type DoneService struct {
|
||||||
@@ -10,15 +13,27 @@ type DoneService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *DoneService) Exec(data model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) bool) {
|
func (s *DoneService) Exec(data model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) bool) {
|
||||||
|
arss := strings.Join(gconv.Strings(id), "-")
|
||||||
m := s.GModel(s.Model).Where("done_type", data).Where("args", id)
|
m := s.GModel(s.Model).Where("done_type", data).Where("args", arss)
|
||||||
var tt model.MilestoneEX
|
var tt *model.MilestoneEX
|
||||||
m.Scan(&tt)
|
m.Scan(&tt)
|
||||||
ook := fn(&tt)
|
if tt == nil {
|
||||||
|
tt = &model.MilestoneEX{
|
||||||
|
Milestone: model.Milestone{
|
||||||
|
DoneType: data,
|
||||||
|
Args: strings.Join(gconv.Strings(id), "-"),
|
||||||
|
Count: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.Args = id
|
||||||
|
ook := fn(tt)
|
||||||
if !ook { //不需要保存
|
if !ook { //不需要保存
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tt.PlayerID = uint64(s.userid)
|
tt.PlayerID = uint64(s.userid)
|
||||||
|
tt.Milestone.Args = strings.Join(gconv.Strings(id), "-")
|
||||||
|
|
||||||
_, err := m.Save(tt)
|
_, err := m.Save(tt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user