refactor(fight): 重构战斗模块
- 移除未使用的结构体和接口 - 优化战斗准备和邀请逻辑 - 调整玩家和怪物信息的处理方式 - 更新战斗相关的数据结构 - 重构战斗模式和邀请相关代码
This commit is contained in:
@@ -2,9 +2,9 @@ package socket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/utils"
|
"blazing/common/utils"
|
||||||
|
|
||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
"blazing/modules/blazing/service"
|
"blazing/modules/blazing/service"
|
||||||
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -41,6 +41,16 @@ func (c *Conn) SendPack(bytes []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OgreInfo struct {
|
||||||
|
Data [9]OgrePetInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type OgrePetInfo struct {
|
||||||
|
Id uint32
|
||||||
|
Shiny uint32
|
||||||
|
Lv uint32 `struc:"skip"` //等级
|
||||||
|
}
|
||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
MainConn *Conn
|
MainConn *Conn
|
||||||
|
|
||||||
@@ -54,6 +64,9 @@ type Player struct {
|
|||||||
context.Context
|
context.Context
|
||||||
Playerinvite uint32 //当前邀请的玩家ID
|
Playerinvite uint32 //当前邀请的玩家ID
|
||||||
Onlinetime uint32 //当前登录时间
|
Onlinetime uint32 //当前登录时间
|
||||||
|
OgreInfo *OgreInfo
|
||||||
|
FightID string //绑定战斗标识
|
||||||
|
//FightInfo info.NoteReadyToFightInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlayerOption 定义配置 Player 的函数类型
|
// PlayerOption 定义配置 Player 的函数类型
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import (
|
|||||||
"blazing/common/data/socket"
|
"blazing/common/data/socket"
|
||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
"blazing/common/socket/handler"
|
"blazing/common/socket/handler"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
"blazing/logic/service/fight"
|
"blazing/logic/service/fight"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
@@ -11,15 +14,15 @@ import (
|
|||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *socket.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerFightNpcMonster(data *info.FightNpcMonsterInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
c.IsFighting = true
|
c.IsFighting = true
|
||||||
t1 := handler.NewTomeeHeader(2503, c.Info.UserID)
|
|
||||||
ttt := info.NoteReadyToFightInfo{
|
ttt := info.NoteReadyToFightInfo{
|
||||||
OwnerID: data.Head.UserID,
|
OwnerID: data.Head.UserID,
|
||||||
FightId: 3,
|
FightId: 3,
|
||||||
}
|
}
|
||||||
ttt.OurInfo = info.FightUserInfo{UserID: c.Info.UserID, Nick: c.Info.Nick}
|
|
||||||
|
|
||||||
|
copier.Copy(&ttt.OurInfo, &c.Info)
|
||||||
len := len(c.Info.PetList)
|
len := len(c.Info.PetList)
|
||||||
ttt.OurPetList = make([]info.ReadyFightPetInfo, len)
|
ttt.OurPetList = make([]info.ReadyFightPetInfo, len)
|
||||||
for i := 0; i < len; i++ {
|
for i := 0; i < len; i++ {
|
||||||
@@ -31,61 +34,49 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
ttt.OpponentInfo = info.FightUserInfo{UserID: 0}
|
ttt.OpponentInfo = info.FightUserInfo{UserID: 0}
|
||||||
ttt.OpponentPetList = []info.ReadyFightPetInfo{{ID: 1,
|
refpet := c.OgreInfo.Data[data.Number]
|
||||||
Level: 100,
|
|
||||||
MaxHp: 100,
|
dv := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(32)
|
||||||
SkillListLen: 4,
|
mo := model.GenPetInfo(refpet.Id, uint32(dv), 0, 1006, refpet.Shiny, refpet.Lv)
|
||||||
Hp: 100}}
|
ttt.OpponentPetList = make([]info.ReadyFightPetInfo, 1)
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
ttt.OpponentPetList[0].SkillList[i] = model.SkillInfo{ID: 10001, Pp: 1}
|
err1 := copier.CopyWithOption(&ttt.OpponentPetList[0], &mo, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
||||||
|
if err1 != nil {
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
c.SendPack(t1.Pack(&ttt))
|
|
||||||
|
fight.NewFight(&ttt, c) //把两个玩家都传进去
|
||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 准备战斗
|
// 准备战斗
|
||||||
func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *socket.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnReadyToFight(data *info.ReadyToFightInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
t1 := handler.NewTomeeHeader(2504, c.Info.UserID)
|
fight.ReadyFight(c)
|
||||||
rett := fight.FightStartOutboundInfo{
|
|
||||||
IsCanAuto: 0,
|
|
||||||
|
|
||||||
Info2: fight.FightPetInfo{
|
|
||||||
UserID: 0,
|
|
||||||
ID: 1,
|
|
||||||
Hp: 1000,
|
|
||||||
MaxHp: 1000,
|
|
||||||
Level: 1,
|
|
||||||
CatchTime: 0,
|
|
||||||
Catchable: 1,
|
|
||||||
BattleLV: [6]byte{1, 1, 1, 1, 1, 1}},
|
|
||||||
}
|
|
||||||
copier.Copy(&rett.Info1, &c.Info.PetList[0])
|
|
||||||
rett.Info1.UserID = c.Info.UserID
|
|
||||||
c.SendPack(t1.Pack(&rett))
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 接收战斗或者取消战斗的包
|
// 接收战斗或者取消战斗的包
|
||||||
func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *socket.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnPlayerHandleFightInvite(data *info.HandleFightInviteInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
return nil, -1
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用技能包
|
// 使用技能包
|
||||||
func (h Controller) UseSkill(data *fight.UseSkillInboundInfo, c *socket.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) UseSkill(data *info.UseSkillInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 战斗逃跑
|
// 战斗逃跑
|
||||||
func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *socket.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) Escape(data *info.EscapeFightInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
//战斗结束Escape
|
//战斗结束Escape
|
||||||
ttt := handler.NewTomeeHeader(2506, c.Info.UserID)
|
ttt := handler.NewTomeeHeader(2506, c.Info.UserID)
|
||||||
|
|
||||||
c.SendPack(ttt.Pack(&fight.FightOverInfo{
|
c.SendPack(ttt.Pack(&info.FightOverInfo{
|
||||||
Reason: 0,
|
Reason: 0,
|
||||||
}))
|
}))
|
||||||
c.IsFighting = false
|
c.IsFighting = false
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func (h Controller) OnGetRoomPetShowInfo(data *room.PetRoomListInboundInfo, c *s
|
|||||||
// 获取自己房间的家具
|
// 获取自己房间的家具
|
||||||
func (h Controller) OnGetFitmentAll(data *room.FitmentAllInboundEmpty, c *socket.Player) (result *room.FitmentAllOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) OnGetFitmentAll(data *room.FitmentAllInboundEmpty, c *socket.Player) (result *room.FitmentAllOutboundInfo, err errorcode.ErrorCode) {
|
||||||
result = &room.FitmentAllOutboundInfo{}
|
result = &room.FitmentAllOutboundInfo{}
|
||||||
result.Fitments = make([]room.FitmentShowInfo, 0)
|
result.Fitments = make([]room.FitmentItemInfo, 0)
|
||||||
result.Fitments = append(result.Fitments, room.FitmentShowInfo{Id: 500001, Status: 1, X: 1, Y: 1, Dir: 1})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package fight
|
|
||||||
|
|
||||||
import "blazing/logic/service/fight/info"
|
|
||||||
|
|
||||||
func NewBattle(i info.NoteReadyToFightInfo) {
|
|
||||||
//调用技能产生effect参数后,创建effect实例,而非技能创建
|
|
||||||
c := info.NewBattleContainer1v1(i) //创建战斗容器
|
|
||||||
t := info.BattleSkillEntity{} //
|
|
||||||
t.SideEffectArgs = []int{1, 2, 3}
|
|
||||||
//先提交effecet后然后计算伤害
|
|
||||||
|
|
||||||
//物理和特殊,百分比和固定伤害也算,真实伤害不分类别,故直接扣血就行,不需要计算
|
|
||||||
if t.Category() == info.Category.PHYSICAL || t.Category() == info.Category.SPECIAL {
|
|
||||||
c.Effects.Exec(func(e info.Effect) bool {
|
|
||||||
return e.PreDamage() //执行预处理效果
|
|
||||||
})
|
|
||||||
|
|
||||||
// Apply pre-damage effects for pet sources
|
|
||||||
// battle.applyEffects(context, EffectTrigger.PreDamage)
|
|
||||||
// if (context.crit) {
|
|
||||||
// battle.applyEffects(context, EffectTrigger.OnCritPreDamage) // Trigger crit pre-damage effects
|
|
||||||
// }
|
|
||||||
//假如说这里需要能力提升
|
|
||||||
// c.Exec(func(e Effect) func() {
|
|
||||||
// return e.OnBeforeAddMark()
|
|
||||||
// })
|
|
||||||
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
|
||||||
//这里能力提升
|
|
||||||
// c.Exec(func(e Effect) bool {
|
|
||||||
// return e.OnAnyMarkAdded()
|
|
||||||
// })
|
|
||||||
|
|
||||||
// var candidates []*Effect
|
|
||||||
// for _, eff := range c.Effects {
|
|
||||||
// if eff.Trigger == trigger {
|
|
||||||
// candidates = append(candidates, eff)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 按优先级排序
|
|
||||||
// sort.SliceStable(candidates, func(i, j int) bool {
|
|
||||||
// return candidates[i].Priority > candidates[j].Priority
|
|
||||||
// })
|
|
||||||
|
|
||||||
// // 执行
|
|
||||||
// for _, eff := range candidates {
|
|
||||||
// ctx.Effect = eff
|
|
||||||
// keep := eff.Apply(ctx)
|
|
||||||
|
|
||||||
// if !keep {
|
|
||||||
// // 持续回合结束 / 返回 false 的 effect 删除
|
|
||||||
// c.removeEffect(eff)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if ctx.Done {
|
|
||||||
// break // 被拦截
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,102 +1,127 @@
|
|||||||
package fight
|
package fight
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blazing/common/data/socket"
|
||||||
"blazing/common/socket/handler"
|
"blazing/common/socket/handler"
|
||||||
"blazing/modules/blazing/model"
|
"blazing/logic/service/fight/info"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 野怪对战包
|
var FightCache = make(map[string]*info.NoteReadyToFightInfo) //默认our是房主
|
||||||
type FightNpcMonsterInboundInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2408" struc:"[0]pad"`
|
func ReadyFight(c *socket.Player) {
|
||||||
// Number 地图刷新怪物结构体对应的序号(1-9的位置序号)
|
tt, _ := FightCache[c.FightID]
|
||||||
// @UInt long类型,使用uint32保持无符号特性
|
t1 := handler.NewTomeeHeader(2504, c.Info.UserID)
|
||||||
Number uint32 `fieldDesc:"地图刷新怪物结构体对应的序号 1 - 9 的位置序号" `
|
rett := info.FightStartOutboundInfo{
|
||||||
|
IsCanAuto: 0,
|
||||||
|
}
|
||||||
|
copier.Copy(&rett.Info1, &c.Info.PetList[0]) //复制自己的信息
|
||||||
|
switch tt.FightId { //判断战斗类型
|
||||||
|
case 1:
|
||||||
|
//1v1
|
||||||
|
|
||||||
|
if c.Info.UserID == tt.OwnerID { //这个时候是房主发来的消息
|
||||||
|
tt.AFinished = true
|
||||||
|
if tt.BFinished {
|
||||||
|
|
||||||
|
copier.Copy(&rett.Info2, &tt.OpponentPetList[0]) //复制对方信息
|
||||||
|
c.SendPack(t1.Pack(&rett)) //给自己发
|
||||||
|
tt.Opp.SendPack(t1.Pack(&rett)) //给对方发
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
tt.BFinished = true
|
||||||
|
if tt.AFinished { //如果房主完成
|
||||||
|
|
||||||
|
copier.Copy(&rett.Info2, &tt.OurPetList[0]) //复制房主信息,因为这时候不是房主发来的消息
|
||||||
|
c.SendPack(t1.Pack(&rett)) //给自己发
|
||||||
|
tt.Our.SendPack(t1.Pack(&rett)) //给房主发
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: //野怪战斗
|
||||||
|
|
||||||
|
copier.Copy(&rett.Info2, &tt.OpponentPetList[0])
|
||||||
|
rett.Info1.UserID = c.Info.UserID //用户ID复制进去
|
||||||
|
c.SendPack(t1.Pack(&rett))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func NewFight(i *info.NoteReadyToFightInfo, plays *socket.Player) {
|
||||||
|
|
||||||
|
t12, _ := uuid.NewV7()
|
||||||
|
uuid := strings.Replace(t12.String(), "-", "", -1) //绑定战斗ID
|
||||||
|
FightCache[uuid] = i
|
||||||
|
//先发送战斗准备包
|
||||||
|
switch i.FightId {
|
||||||
|
case 1:
|
||||||
|
//1v1
|
||||||
|
|
||||||
|
case 3: //野怪战斗
|
||||||
|
|
||||||
|
t1 := handler.NewTomeeHeader(2503, plays.Info.UserID)
|
||||||
|
|
||||||
|
plays.FightID = uuid //绑定战斗ID
|
||||||
|
plays.SendPack(t1.Pack(i)) //准备包由各自发,因为协议不一样
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//调用技能产生effect参数后,创建effect实例,而非技能创建
|
||||||
|
c := info.NewBattleContainer1v1(*i) //创建战斗容器
|
||||||
|
t := info.BattleSkillEntity{} //
|
||||||
|
t.SideEffectArgs = []int{1, 2, 3}
|
||||||
|
//先提交effecet后然后计算伤害
|
||||||
|
|
||||||
|
//物理和特殊,百分比和固定伤害也算,真实伤害不分类别,故直接扣血就行,不需要计算
|
||||||
|
if t.Category() == info.Category.PHYSICAL || t.Category() == info.Category.SPECIAL {
|
||||||
|
c.Effects.Exec(func(e info.Effect) bool {
|
||||||
|
return e.PreDamage() //执行预处理效果
|
||||||
|
})
|
||||||
|
|
||||||
|
// Apply pre-damage effects for pet sources
|
||||||
|
// battle.applyEffects(context, EffectTrigger.PreDamage)
|
||||||
|
// if (context.crit) {
|
||||||
|
// battle.applyEffects(context, EffectTrigger.OnCritPreDamage) // Trigger crit pre-damage effects
|
||||||
|
// }
|
||||||
|
//假如说这里需要能力提升
|
||||||
|
// c.Exec(func(e Effect) func() {
|
||||||
|
// return e.OnBeforeAddMark()
|
||||||
|
// })
|
||||||
|
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
||||||
|
//这里能力提升
|
||||||
|
// c.Exec(func(e Effect) bool {
|
||||||
|
// return e.OnAnyMarkAdded()
|
||||||
|
// })
|
||||||
|
|
||||||
|
// var candidates []*Effect
|
||||||
|
// for _, eff := range c.Effects {
|
||||||
|
// if eff.Trigger == trigger {
|
||||||
|
// candidates = append(candidates, eff)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 按优先级排序
|
||||||
|
// sort.SliceStable(candidates, func(i, j int) bool {
|
||||||
|
// return candidates[i].Priority > candidates[j].Priority
|
||||||
|
// })
|
||||||
|
|
||||||
|
// // 执行
|
||||||
|
// for _, eff := range candidates {
|
||||||
|
// ctx.Effect = eff
|
||||||
|
// keep := eff.Apply(ctx)
|
||||||
|
|
||||||
|
// if !keep {
|
||||||
|
// // 持续回合结束 / 返回 false 的 effect 删除
|
||||||
|
// c.removeEffect(eff)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if ctx.Done {
|
||||||
|
// break // 被拦截
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
type NullOutboundInfo struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// 准备战斗包
|
|
||||||
type ReadyToFightInboundInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2404" struc:"[0]pad"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FightStartOutboundInfo struct {
|
|
||||||
// @UInt long类型
|
|
||||||
IsCanAuto uint32 `fieldDesc:"是否自动 默认给0 怀疑是自动战斗器使用的" `
|
|
||||||
|
|
||||||
// 当前战斗精灵信息1(前端通过userid判断是否为我方)
|
|
||||||
Info1 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
|
||||||
|
|
||||||
// 当前战斗精灵信息2(前端通过userid判断是否为我方)
|
|
||||||
Info2 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FightPetInfo 战斗精灵信息结构体,FightPetInfo类
|
|
||||||
type FightPetInfo struct {
|
|
||||||
// 用户ID(野怪为0),@UInt long
|
|
||||||
UserID uint32 `fieldDesc:"用户ID 野怪为0" `
|
|
||||||
|
|
||||||
// 当前对战精灵ID,@UInt long
|
|
||||||
ID uint32 `fieldDesc:"当前对战精灵ID" `
|
|
||||||
|
|
||||||
Name string `struc:"[16]byte"`
|
|
||||||
// 精灵的捕获时间,@UInt long
|
|
||||||
CatchTime uint32 `fieldDesc:"精灵的捕获时间" `
|
|
||||||
|
|
||||||
// 当前HP,@UInt long
|
|
||||||
Hp uint32 `fieldDesc:"当前HP" `
|
|
||||||
|
|
||||||
// 最大HP,@UInt long
|
|
||||||
MaxHp uint32 `fieldDesc:"最大HP" `
|
|
||||||
|
|
||||||
// 当前等级,@UInt long
|
|
||||||
Level uint32 `fieldDesc:"当前等级" `
|
|
||||||
|
|
||||||
// 精灵是否能捕捉(1为能捕捉,0为不能捕捉),@UInt long
|
|
||||||
Catchable uint32 `fieldDesc:"精灵是否能捕捉. 1为能捕捉 0为不能捕捉" `
|
|
||||||
|
|
||||||
// 战斗属性等级数组(6个单字节)
|
|
||||||
// byte[],固定长度6,存储buff等级、攻击、速度等属性
|
|
||||||
BattleLV [6]byte `fieldDesc:"这里实际上应该是6个单字节byte, 内容为buff等级 攻击 速度 特攻 防御 特防 命中等.但具体顺序未知可能需要测试. 具体数值为1-6等级" serialize:"fixedLength=6,type=byteArray"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AttackValue 战斗中的攻击数值信息
|
|
||||||
type AttackValue struct {
|
|
||||||
UserID uint32 `json:"userId" fieldDescription:"玩家的米米号 与野怪对战userid = 0"`
|
|
||||||
SkillID uint32 `json:"skillId" fieldDescription:"使用技能的id"`
|
|
||||||
AttackTime uint32 `json:"attackTime" fieldDescription:"是否击中 如果为0 则miss 如果为1 则击中"`
|
|
||||||
LostHp uint32 `json:"lostHp" fieldDescription:"我方造成的伤害"`
|
|
||||||
GainHp uint32 `json:"gainHp" fieldDescription:"我方获得血量"`
|
|
||||||
RemainHp uint32 `json:"remainHp" fieldDescription:"我方剩余血量"`
|
|
||||||
MaxHp uint32 `json:"maxHp" fieldDescription:"我方最大血量"`
|
|
||||||
State uint32 `json:"state" fieldDescription:"固定值0 需要后续测试"`
|
|
||||||
SkillList []model.SkillInfo `json:"skillList" fieldDescription:"根据精灵的数据插入技能 最多4条 不定长"`
|
|
||||||
IsCritical uint32 `json:"isCritical" fieldDescription:"是否暴击"`
|
|
||||||
Status [20]byte `json:"status" fieldDescription:"20个字节 各种状态: 0:\"麻痹\",1:\"中毒\",2:\"烧伤\",4:\"寄生\",5:\"冻伤\",6:\"害怕\",7:\"疲惫\",8:\"睡眠\",9:\"石化\",10:\"混乱\",15:\"冰封\",16:\"流血\""`
|
|
||||||
BattleLv [6]byte `json:"battleLv" fieldDescription:"6个单字节byte, 内容为buff等级 攻击 速度 特攻 防御 特防命中等. 但具体顺序未知可能需要测试. 具体数值为1-6等级"`
|
|
||||||
// OwnerMaxShield uint32 `json:"ownerMaxShield" fieldDescription:"我方最大护盾"`
|
|
||||||
// OwnerCurrentShield uint32 `json:"ownerCurrentShield" fieldDescription:"我方当前护盾"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NoteUseSkillOutboundInfo 战斗技能使用通知的出站信息结构体
|
|
||||||
type NoteUseSkillOutboundInfo struct {
|
|
||||||
FirstAttackInfo AttackValue // 本轮先手的精灵在释放技能结束后的状态
|
|
||||||
SecondAttackInfo AttackValue // 本轮后手的精灵在释放技能结束后的状态
|
|
||||||
}
|
|
||||||
|
|
||||||
// 战斗逃跑
|
|
||||||
type EscapeFightInboundInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2410" struc:"[0]pad"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FightOverInfo 战斗结束信息结构体 2506
|
|
||||||
type FightOverInfo struct {
|
|
||||||
Reason uint32 // 固定值0
|
|
||||||
WinnerId uint32 // 胜者的米米号 野怪为0
|
|
||||||
TwoTimes uint32 // 双倍经验剩余次数
|
|
||||||
ThreeTimes uint32 // 三倍经验剩余次数
|
|
||||||
AutoFightTimes uint32 // 自动战斗剩余次数
|
|
||||||
EnergyTimes uint32 // 能量吸收器剩余次数
|
|
||||||
LearnTimes uint32 // 双倍学习器剩余次数
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
const Input_ctx = "player"
|
const Input_ctx = "player"
|
||||||
|
|
||||||
type BattleInputSourceEntity struct {
|
type BattleInputSourceEntity struct {
|
||||||
FightUserInfo //用户信息
|
FightUserInfo //用户信息
|
||||||
PetEntities []*BattlePetEntity //宠物信息
|
PetEntities []*BattlePetEntity //宠物信息
|
||||||
ctx context.Context //输入源的上下文
|
ctx context.Context //输入源的上下文
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package info
|
|
||||||
|
|
||||||
import (
|
|
||||||
"blazing/modules/blazing/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FightUserInfo struct {
|
|
||||||
// 用户ID(野怪为0),@UInt long
|
|
||||||
UserID uint32 `fieldDesc:"userID 如果为野怪则为0" `
|
|
||||||
|
|
||||||
// 玩家名称(野怪为UTF-8的'-',固定16字节)
|
|
||||||
// 使用[16]byte存储固定长度的字节数组
|
|
||||||
Nick string `struc:"[16]byte"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NoteReadyToFightInfo 战斗准备就绪消息结构体,NoteReadyToFightInfo
|
|
||||||
type NoteReadyToFightInfo struct {
|
|
||||||
//战斗发起者ID
|
|
||||||
OwnerID uint32 `struc:"skip"`
|
|
||||||
// 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用)
|
|
||||||
// @UInt long
|
|
||||||
FightId uint32 `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `
|
|
||||||
|
|
||||||
// 我方信息
|
|
||||||
OurInfo FightUserInfo `fieldDesc:"我方信息" serialize:"struct"`
|
|
||||||
OurPetListLen uint32 `struc:"sizeof=OurPetList"`
|
|
||||||
// 我方携带精灵的信息
|
|
||||||
// ArrayList<ReadyFightPetInfo>,使用切片模拟动态列表
|
|
||||||
OurPetList []ReadyFightPetInfo `fieldDesc:"我方携带精灵的信息" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
|
||||||
|
|
||||||
// 对方信息
|
|
||||||
OpponentInfo FightUserInfo `fieldDesc:"对方信息" serialize:"struct"`
|
|
||||||
OpponentPetListLen uint32 `struc:"sizeof=OpponentPetList"`
|
|
||||||
// 敌方的精灵信息
|
|
||||||
// 野怪战斗时:客户端接收此包前已生成精灵PetInfo,将部分信息写入该列表
|
|
||||||
OpponentPetList []ReadyFightPetInfo `fieldDesc:"敌方的精灵信息 如果是野怪 那么再给客户端发送这个包体时就提前生成好了这只精灵的PetInfo,然后把从PetInfo中把部分信息写入到这个敌方的精灵信息中再发送这个包结构体" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadyFightPetInfo 准备战斗的精灵信息结构体,ReadyFightPetInfo类
|
|
||||||
type ReadyFightPetInfo struct {
|
|
||||||
// 精灵ID,@UInt long
|
|
||||||
ID uint32 `fieldDesc:"精灵ID" `
|
|
||||||
|
|
||||||
// 精灵等级,@UInt long
|
|
||||||
Level uint32 `fieldDesc:"精灵等级" `
|
|
||||||
|
|
||||||
// 精灵当前HP,@UInt long
|
|
||||||
Hp uint32 `fieldDesc:"精灵HP" `
|
|
||||||
|
|
||||||
// 精灵最大HP,@UInt long
|
|
||||||
MaxHp uint32 `fieldDesc:"最大HP" `
|
|
||||||
SkillListLen uint32
|
|
||||||
// 技能信息列表(固定4个元素,技能ID和剩余PP,无技能则为0)
|
|
||||||
// List<SkillInfo>,初始化容量为4
|
|
||||||
SkillList [4]model.SkillInfo `fieldDesc:"技能信息 技能ID跟剩余PP 固定32字节 没有给0" serialize:"fixedLength=4,type=structArray"`
|
|
||||||
|
|
||||||
// 精灵捕获时间,@UInt long
|
|
||||||
CatchTime uint32 `fieldDesc:"精灵捕获时间" `
|
|
||||||
|
|
||||||
// 捕捉地图(固定给0),@UInt long
|
|
||||||
CatchMap uint32 `fieldDesc:"捕捉地图 给0" `
|
|
||||||
|
|
||||||
// 固定给0,@UInt long
|
|
||||||
CatchRect uint32 `fieldDesc:"给0" `
|
|
||||||
|
|
||||||
// 固定给0,@UInt long
|
|
||||||
CatchLevel uint32 `fieldDesc:"给0" `
|
|
||||||
SkinID uint32 `fieldDesc:"精灵皮肤ID" `
|
|
||||||
Shiny uint32 `fieldDesc:"精灵是否闪" `
|
|
||||||
}
|
|
||||||
@@ -65,3 +65,16 @@ var BattleOverReason = enum.New[struct {
|
|||||||
PlayerCaptureSuccess EnumBattleOverReason `enum:"3"` //捕捉成功
|
PlayerCaptureSuccess EnumBattleOverReason `enum:"3"` //捕捉成功
|
||||||
DefaultEnd EnumBattleOverReason `enum:"4"` //默认结束
|
DefaultEnd EnumBattleOverReason `enum:"4"` //默认结束
|
||||||
}]()
|
}]()
|
||||||
|
|
||||||
|
// 战斗模式
|
||||||
|
|
||||||
|
var BattleMode_PVP = enum.New[struct {
|
||||||
|
PVP_1V1 EnumBattleMode `enum:"1"`
|
||||||
|
PVP_6V6 EnumBattleMode `enum:"2"`
|
||||||
|
}]()
|
||||||
|
var Playerinvitemap map[uint32][]Playerinvite = make(map[uint32][]Playerinvite) //玩家邀请信息 ,比如一个玩家被多人邀请对战
|
||||||
|
|
||||||
|
type Playerinvite struct { //挂载到[]Playerinvite上? 被邀请者->邀请者
|
||||||
|
InviteID uint32 // 邀请者
|
||||||
|
InviteTime EnumBattleMode //游戏模式
|
||||||
|
}
|
||||||
|
|||||||
203
logic/service/fight/info/fight.go
Normal file
203
logic/service/fight/info/fight.go
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
package info
|
||||||
|
|
||||||
|
import (
|
||||||
|
"blazing/common/data/socket"
|
||||||
|
"blazing/common/socket/handler"
|
||||||
|
"blazing/modules/blazing/model"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 野怪对战包
|
||||||
|
type FightNpcMonsterInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2408" struc:"[0]pad"`
|
||||||
|
// Number 地图刷新怪物结构体对应的序号(1-9的位置序号)
|
||||||
|
// @UInt long类型,使用uint32保持无符号特性
|
||||||
|
Number uint32 `fieldDesc:"地图刷新怪物结构体对应的序号 1 - 9 的位置序号" `
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullOutboundInfo struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备战斗包
|
||||||
|
type ReadyToFightInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2404" struc:"[0]pad"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FightStartOutboundInfo struct {
|
||||||
|
// @UInt long类型
|
||||||
|
IsCanAuto uint32 `fieldDesc:"是否自动 默认给0 怀疑是自动战斗器使用的" `
|
||||||
|
|
||||||
|
// 当前战斗精灵信息1(前端通过userid判断是否为我方)
|
||||||
|
Info1 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||||
|
|
||||||
|
// 当前战斗精灵信息2(前端通过userid判断是否为我方)
|
||||||
|
Info2 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FightPetInfo 战斗精灵信息结构体,FightPetInfo类
|
||||||
|
type FightPetInfo struct {
|
||||||
|
// 用户ID(野怪为0),@UInt long
|
||||||
|
UserID uint32 `fieldDesc:"用户ID 野怪为0" `
|
||||||
|
|
||||||
|
// 当前对战精灵ID,@UInt long
|
||||||
|
ID uint32 `fieldDesc:"当前对战精灵ID" `
|
||||||
|
|
||||||
|
Name string `struc:"[16]byte"`
|
||||||
|
// 精灵的捕获时间,@UInt long
|
||||||
|
CatchTime uint32 `fieldDesc:"精灵的捕获时间" `
|
||||||
|
|
||||||
|
// 当前HP,@UInt long
|
||||||
|
Hp uint32 `fieldDesc:"当前HP" `
|
||||||
|
|
||||||
|
// 最大HP,@UInt long
|
||||||
|
MaxHp uint32 `fieldDesc:"最大HP" `
|
||||||
|
|
||||||
|
// 当前等级,@UInt long
|
||||||
|
Level uint32 `fieldDesc:"当前等级" `
|
||||||
|
|
||||||
|
// 精灵是否能捕捉(1为能捕捉,0为不能捕捉),@UInt long
|
||||||
|
Catchable uint32 `fieldDesc:"精灵是否能捕捉. 1为能捕捉 0为不能捕捉" `
|
||||||
|
|
||||||
|
// 战斗属性等级数组(6个单字节)
|
||||||
|
// byte[],固定长度6,存储buff等级、攻击、速度等属性
|
||||||
|
BattleLV [6]byte `fieldDesc:"这里实际上应该是6个单字节byte, 内容为buff等级 攻击 速度 特攻 防御 特防 命中等.但具体顺序未知可能需要测试. 具体数值为1-6等级" serialize:"fixedLength=6,type=byteArray"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttackValue 战斗中的攻击数值信息
|
||||||
|
type AttackValue struct {
|
||||||
|
UserID uint32 `json:"userId" fieldDescription:"玩家的米米号 与野怪对战userid = 0"`
|
||||||
|
SkillID uint32 `json:"skillId" fieldDescription:"使用技能的id"`
|
||||||
|
AttackTime uint32 `json:"attackTime" fieldDescription:"是否击中 如果为0 则miss 如果为1 则击中"`
|
||||||
|
LostHp uint32 `json:"lostHp" fieldDescription:"我方造成的伤害"`
|
||||||
|
GainHp uint32 `json:"gainHp" fieldDescription:"我方获得血量"`
|
||||||
|
RemainHp uint32 `json:"remainHp" fieldDescription:"我方剩余血量"`
|
||||||
|
MaxHp uint32 `json:"maxHp" fieldDescription:"我方最大血量"`
|
||||||
|
State uint32 `json:"state" fieldDescription:"固定值0 需要后续测试"`
|
||||||
|
SkillList []model.SkillInfo `json:"skillList" fieldDescription:"根据精灵的数据插入技能 最多4条 不定长"`
|
||||||
|
IsCritical uint32 `json:"isCritical" fieldDescription:"是否暴击"`
|
||||||
|
Status [20]byte `json:"status" fieldDescription:"20个字节 各种状态: 0:\"麻痹\",1:\"中毒\",2:\"烧伤\",4:\"寄生\",5:\"冻伤\",6:\"害怕\",7:\"疲惫\",8:\"睡眠\",9:\"石化\",10:\"混乱\",15:\"冰封\",16:\"流血\""`
|
||||||
|
BattleLv [6]byte `json:"battleLv" fieldDescription:"6个单字节byte, 内容为buff等级 攻击 速度 特攻 防御 特防命中等. 但具体顺序未知可能需要测试. 具体数值为1-6等级"`
|
||||||
|
// OwnerMaxShield uint32 `json:"ownerMaxShield" fieldDescription:"我方最大护盾"`
|
||||||
|
// OwnerCurrentShield uint32 `json:"ownerCurrentShield" fieldDescription:"我方当前护盾"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoteUseSkillOutboundInfo 战斗技能使用通知的出站信息结构体
|
||||||
|
type NoteUseSkillOutboundInfo struct {
|
||||||
|
FirstAttackInfo AttackValue // 本轮先手的精灵在释放技能结束后的状态
|
||||||
|
SecondAttackInfo AttackValue // 本轮后手的精灵在释放技能结束后的状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// 战斗逃跑
|
||||||
|
type EscapeFightInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2410" struc:"[0]pad"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FightOverInfo 战斗结束信息结构体 2506
|
||||||
|
type FightOverInfo struct {
|
||||||
|
Reason uint32 // 固定值0
|
||||||
|
WinnerId uint32 // 胜者的米米号 野怪为0
|
||||||
|
TwoTimes uint32 // 双倍经验剩余次数
|
||||||
|
ThreeTimes uint32 // 三倍经验剩余次数
|
||||||
|
AutoFightTimes uint32 // 自动战斗剩余次数
|
||||||
|
EnergyTimes uint32 // 能量吸收器剩余次数
|
||||||
|
LearnTimes uint32 // 双倍学习器剩余次数
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleFightInviteInboundInfo 处理战斗邀请的入站消息
|
||||||
|
// 回空包就行
|
||||||
|
type HandleFightInviteInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2403" struc:"[0]pad"`
|
||||||
|
UserID uint32 `json:"userId" codec:"userId,uint"` // 邀请我对战人的userid
|
||||||
|
Flag uint32 `json:"flag" codec:"flag,uint"` // 1为同意对战 0为取消对战
|
||||||
|
Mode uint32 `json:"mode" codec:"mode,uint"` // 战斗类型 1 = 1v1 2 = 6v6
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2502的回复包 PVP邀请消息
|
||||||
|
type NoteHandleFightInviteOutboundInfo struct {
|
||||||
|
UserID uint32
|
||||||
|
Nickname string `struc:"[16]byte"` // 固定长度16字节
|
||||||
|
Result uint32 // 0=拒绝 1=同意 2=在线超6小时 3=无出战精灵 4=不在线
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现入站消息接口(Go中通过方法集隐式实现)
|
||||||
|
type UseSkillInboundInfo struct {
|
||||||
|
Head handler.TomeeHeader `cmd:"2405" struc:"[0]pad"`
|
||||||
|
// 技能id,
|
||||||
|
SkillId uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type FightUserInfo struct {
|
||||||
|
// 用户ID(野怪为0),@UInt long
|
||||||
|
UserID uint32 `fieldDesc:"userID 如果为野怪则为0" `
|
||||||
|
|
||||||
|
// 玩家名称(野怪为UTF-8的'-',固定16字节)
|
||||||
|
// 使用[16]byte存储固定长度的字节数组
|
||||||
|
Nick string `struc:"[16]byte"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoteReadyToFightInfo 战斗准备就绪消息结构体,NoteReadyToFightInfo
|
||||||
|
type NoteReadyToFightInfo struct {
|
||||||
|
MAXPET uint32 `struc:"skip"` //,最大精灵数
|
||||||
|
//战斗发起者ID
|
||||||
|
OwnerID uint32 `struc:"skip"`
|
||||||
|
|
||||||
|
AFinished bool `struc:"skip"`
|
||||||
|
BFinished bool `struc:"skip"`
|
||||||
|
// 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用)
|
||||||
|
// @UInt long
|
||||||
|
FightId EnumBattleMode `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `
|
||||||
|
|
||||||
|
// 我方信息
|
||||||
|
OurInfo FightUserInfo `fieldDesc:"我方信息" serialize:"struct"`
|
||||||
|
Our *socket.Player `struc:"skip"`
|
||||||
|
OurPetListLen uint32 `struc:"sizeof=OurPetList"`
|
||||||
|
// 我方携带精灵的信息
|
||||||
|
// ArrayList<ReadyFightPetInfo>,使用切片模拟动态列表
|
||||||
|
OurPetList []ReadyFightPetInfo `fieldDesc:"我方携带精灵的信息" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
||||||
|
|
||||||
|
// 对方信息
|
||||||
|
OpponentInfo FightUserInfo `fieldDesc:"对方信息" serialize:"struct"`
|
||||||
|
Opp *socket.Player `struc:"skip"`
|
||||||
|
OpponentPetListLen uint32 `struc:"sizeof=OpponentPetList"`
|
||||||
|
// 敌方的精灵信息
|
||||||
|
// 野怪战斗时:客户端接收此包前已生成精灵PetInfo,将部分信息写入该列表
|
||||||
|
OpponentPetList []ReadyFightPetInfo `fieldDesc:"敌方的精灵信息 如果是野怪 那么再给客户端发送这个包体时就提前生成好了这只精灵的PetInfo,然后把从PetInfo中把部分信息写入到这个敌方的精灵信息中再发送这个包结构体" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当A和B都 这时候给双方回复开始战斗包
|
||||||
|
func (t *NoteReadyToFightInfo) onBothFinished() {
|
||||||
|
fmt.Println("A和B都已完成,触发onBothFinished")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadyFightPetInfo 准备战斗的精灵信息结构体,ReadyFightPetInfo类
|
||||||
|
type ReadyFightPetInfo struct {
|
||||||
|
// 精灵ID,@UInt long
|
||||||
|
ID uint32 `fieldDesc:"精灵ID" `
|
||||||
|
|
||||||
|
// 精灵等级,@UInt long
|
||||||
|
Level uint32 `fieldDesc:"精灵等级" `
|
||||||
|
|
||||||
|
// 精灵当前HP,@UInt long
|
||||||
|
Hp uint32 `fieldDesc:"精灵HP" `
|
||||||
|
|
||||||
|
// 精灵最大HP,@UInt long
|
||||||
|
MaxHp uint32 `fieldDesc:"最大HP" `
|
||||||
|
SkillListLen uint32
|
||||||
|
// 技能信息列表(固定4个元素,技能ID和剩余PP,无技能则为0)
|
||||||
|
// List<SkillInfo>,初始化容量为4
|
||||||
|
SkillList [4]model.SkillInfo `fieldDesc:"技能信息 技能ID跟剩余PP 固定32字节 没有给0" serialize:"fixedLength=4,type=structArray"`
|
||||||
|
|
||||||
|
// 精灵捕获时间,@UInt long
|
||||||
|
CatchTime uint32 `fieldDesc:"精灵捕获时间" `
|
||||||
|
|
||||||
|
// 捕捉地图(固定给0),@UInt long
|
||||||
|
CatchMap uint32 `fieldDesc:"捕捉地图 给0" `
|
||||||
|
|
||||||
|
// 固定给0,@UInt long
|
||||||
|
CatchRect uint32 `fieldDesc:"给0" `
|
||||||
|
|
||||||
|
// 固定给0,@UInt long
|
||||||
|
CatchLevel uint32 `fieldDesc:"给0" `
|
||||||
|
SkinID uint32 `fieldDesc:"精灵皮肤ID" `
|
||||||
|
Shiny uint32 `fieldDesc:"精灵是否闪" `
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package info
|
|
||||||
|
|
||||||
import "github.com/tnnmigga/enum"
|
|
||||||
|
|
||||||
// 战斗模式
|
|
||||||
|
|
||||||
var BattleMode_PVP = enum.New[struct {
|
|
||||||
PVP_1V1 EnumBattleMode `enum:"1"`
|
|
||||||
PVP_6V6 EnumBattleMode `enum:"2"`
|
|
||||||
}]()
|
|
||||||
var Playerinvitemap map[uint32][]Playerinvite = make(map[uint32][]Playerinvite) //玩家邀请信息 ,比如一个玩家被多人邀请对战
|
|
||||||
|
|
||||||
type Playerinvite struct { //挂载到[]Playerinvite上? 被邀请者->邀请者
|
|
||||||
InviteID uint32 // 邀请者
|
|
||||||
InviteTime EnumBattleMode //游戏模式
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package fight
|
|
||||||
|
|
||||||
import "blazing/common/socket/handler"
|
|
||||||
|
|
||||||
// HandleFightInviteInboundInfo 处理战斗邀请的入站消息
|
|
||||||
// 回空包就行
|
|
||||||
type HandleFightInviteInboundInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2403" struc:"[0]pad"`
|
|
||||||
UserID uint32 `json:"userId" codec:"userId,uint"` // 邀请我对战人的userid
|
|
||||||
Flag uint32 `json:"flag" codec:"flag,uint"` // 1为同意对战 0为取消对战
|
|
||||||
Mode uint32 `json:"mode" codec:"mode,uint"` // 战斗类型 1 = 1v1 2 = 6v6
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2502的回复包 PVP邀请消息
|
|
||||||
type NoteHandleFightInviteOutboundInfo struct {
|
|
||||||
UserID uint32
|
|
||||||
Nickname string `struc:"[16]byte"` // 固定长度16字节
|
|
||||||
Result uint32 // 0=拒绝 1=同意 2=在线超6小时 3=无出战精灵 4=不在线
|
|
||||||
}
|
|
||||||
|
|
||||||
// 实现入站消息接口(Go中通过方法集隐式实现)
|
|
||||||
type UseSkillInboundInfo struct {
|
|
||||||
Head handler.TomeeHeader `cmd:"2405" struc:"[0]pad"`
|
|
||||||
// 技能id,
|
|
||||||
SkillId uint32
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package maps
|
|
||||||
|
|
||||||
type OgreInfo struct {
|
|
||||||
Data [9]OgrePetInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type OgrePetInfo struct {
|
|
||||||
Id uint32
|
|
||||||
Shiny uint32
|
|
||||||
Lv uint32 `struc:"skip"` //等级
|
|
||||||
}
|
|
||||||
@@ -65,6 +65,7 @@ func (t *InInfo) SpawnMonsters(c *socket.Player, isfrist bool) {
|
|||||||
}
|
}
|
||||||
t1 := t.genMonster(c.Info.MapID)
|
t1 := t.genMonster(c.Info.MapID)
|
||||||
if t1 != nil {
|
if t1 != nil {
|
||||||
|
c.OgreInfo = t1
|
||||||
t1 := tt.Pack(t1)
|
t1 := tt.Pack(t1)
|
||||||
c.SendPack(t1)
|
c.SendPack(t1)
|
||||||
}
|
}
|
||||||
@@ -80,16 +81,16 @@ func RandomStringFromSlice(s []string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 应该根据怪物信息决定后端生成
|
// 应该根据怪物信息决定后端生成
|
||||||
func (t *InInfo) genMonster(mapid uint32) *OgreInfo {
|
func (t *InInfo) genMonster(mapid uint32) *socket.OgreInfo {
|
||||||
// 设置怪物信息
|
// 设置怪物信息
|
||||||
t1 := OgreInfo{}
|
t1 := socket.OgreInfo{}
|
||||||
mapss, ok := xmlres.MonsterMap[gconv.Int(mapid)]
|
mapss, ok := xmlres.MonsterMap[gconv.Int(mapid)]
|
||||||
|
|
||||||
if ok && mapss.Monsters != nil {
|
if ok && mapss.Monsters != nil {
|
||||||
for i, m := range mapss.Monsters.Monsters { //这里是9个
|
for i, m := range mapss.Monsters.Monsters { //这里是9个
|
||||||
id := strings.Split(m.ID, " ")
|
id := strings.Split(m.ID, " ")
|
||||||
lv := strings.Split(m.Lv, " ")
|
lv := strings.Split(m.Lv, " ")
|
||||||
ttt := OgrePetInfo{
|
ttt := socket.OgrePetInfo{
|
||||||
Id: gconv.Uint32(RandomStringFromSlice(id)),
|
Id: gconv.Uint32(RandomStringFromSlice(id)),
|
||||||
}
|
}
|
||||||
if ttt.Id != 0 {
|
if ttt.Id != 0 {
|
||||||
@@ -102,7 +103,7 @@ func (t *InInfo) genMonster(mapid uint32) *OgreInfo {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t2 := OgreInfo{}
|
t2 := socket.OgreInfo{}
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
|
|
||||||
t2.Data[t.monsters[i]] = t1.Data[t.monsters[i]]
|
t2.Data[t.monsters[i]] = t1.Data[t.monsters[i]]
|
||||||
|
|||||||
@@ -55,5 +55,17 @@ type FitmentAllInboundEmpty struct {
|
|||||||
type FitmentAllOutboundInfo struct {
|
type FitmentAllOutboundInfo struct {
|
||||||
FitmentsLen uint32 `json:"fitmentsLen" struc:"sizeof=Fitments"`
|
FitmentsLen uint32 `json:"fitmentsLen" struc:"sizeof=Fitments"`
|
||||||
// 基地摆放物品的数组, 就算没有摆放物品, 也必带一个小屋的参数
|
// 基地摆放物品的数组, 就算没有摆放物品, 也必带一个小屋的参数
|
||||||
Fitments []FitmentShowInfo `codec:"auto" json:"fitments"`
|
Fitments []FitmentItemInfo `codec:"auto" json:"fitments"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FitmentItemInfo 对应Java的FitmentItemInfo类
|
||||||
|
type FitmentItemInfo struct {
|
||||||
|
// Id 家具id 或 默认房型id: 500001(对应Java的@UInt long id)
|
||||||
|
Id uint32 `json:"id"`
|
||||||
|
|
||||||
|
// UsedCount 使用数量(默认房型id项目的使用数据固定为1)(对应Java的@UInt long usedCount)
|
||||||
|
UsedCount uint32 `json:"usedCount"`
|
||||||
|
|
||||||
|
// AllCount 拥有数量(默认房型id项目的拥有数量固定为1)(对应Java的@UInt long allCount)
|
||||||
|
AllCount uint32 `json:"allCount"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,16 @@ type Pet struct {
|
|||||||
Data string `gorm:"type:text;not null;comment:'精灵全部数据'" json:"data"`
|
Data string `gorm:"type:text;not null;comment:'精灵全部数据'" json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LastFourElements[T any](s []T) []T {
|
||||||
|
n := len(s)
|
||||||
|
if n <= 4 {
|
||||||
|
// 切片长度小于等于4时,返回整个切片
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
// 切片长度大于4时,返回最后4个元素(从n-4索引到末尾)
|
||||||
|
return s[n-4:]
|
||||||
|
}
|
||||||
|
|
||||||
// * @param petTypeId 精灵类型ID
|
// * @param petTypeId 精灵类型ID
|
||||||
// * @param individualValue 个体值
|
// * @param individualValue 个体值
|
||||||
// * @param natureId 性格ID
|
// * @param natureId 性格ID
|
||||||
@@ -29,19 +39,19 @@ type Pet struct {
|
|||||||
// * @param isShiny 是否为闪光
|
// * @param isShiny 是否为闪光
|
||||||
// * @param level 等级
|
// * @param level 等级
|
||||||
// * @return 生成的精灵实体
|
// * @return 生成的精灵实体
|
||||||
func GenPetInfo(id, individual, natureId, abilityTypeEnum, shinyid, level uint32) *PetInfo {
|
func GenPetInfo(id, dv, natureId, abilityTypeEnum, shinyid, level uint32) *PetInfo {
|
||||||
|
|
||||||
p := &PetInfo{ID: id,
|
p := &PetInfo{ID: id,
|
||||||
Shiny: shinyid, //闪光
|
Shiny: shinyid, //闪光
|
||||||
Nature: natureId, //性格
|
Nature: natureId, //性格
|
||||||
Dv: individual,
|
Dv: dv,
|
||||||
EffectInfo: make([]PetEffectInfo, 0),
|
EffectInfo: make([]PetEffectInfo, 0),
|
||||||
CatchTime: uint32(time.Now().Unix()),
|
CatchTime: uint32(time.Now().Unix()),
|
||||||
Level: level} //等级
|
Level: level} //等级
|
||||||
|
|
||||||
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{ItemID: abilityTypeEnum})
|
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{ItemID: abilityTypeEnum})
|
||||||
petxml := xmlres.PetMAP[int(id)]
|
|
||||||
naxml := xmlres.NatureRootMap[int(natureId)]
|
naxml := xmlres.NatureRootMap[int(natureId)]
|
||||||
|
petxml := xmlres.PetMAP[int(id)]
|
||||||
tttt := make([]uint32, 0)
|
tttt := make([]uint32, 0)
|
||||||
for _, v := range petxml.LearnableMoves.Moves {
|
for _, v := range petxml.LearnableMoves.Moves {
|
||||||
if p.Level >= uint32(v.LearningLv) {
|
if p.Level >= uint32(v.LearningLv) {
|
||||||
@@ -50,6 +60,7 @@ func GenPetInfo(id, individual, natureId, abilityTypeEnum, shinyid, level uint32
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
tttt = LastFourElements(tttt) //获取最后四个技能,如果不足,那就取全部技能
|
||||||
for i := 0; i < len(tttt); i++ {
|
for i := 0; i < len(tttt); i++ {
|
||||||
p.SkillList[i].ID = tttt[i]
|
p.SkillList[i].ID = tttt[i]
|
||||||
p.SkillList[i].Pp = uint32(xmlres.SkillMap[int(tttt[i])].MaxPP)
|
p.SkillList[i].Pp = uint32(xmlres.SkillMap[int(tttt[i])].MaxPP)
|
||||||
|
|||||||
BIN
public/oldswf/GroupFightDLL.swf
Normal file
BIN
public/oldswf/GroupFightDLL.swf
Normal file
Binary file not shown.
Reference in New Issue
Block a user