feat: 更新战斗系统模型结构和Redis消息处理 - 引入gredis依赖用于Redis消息处理 - 将战斗相关的枚举和结构体从info包迁移到model包 - 更新战斗结束原因、攻击值等类型的引用路径 - 添加新的zset工具包到工作区 - 修改Redis消息处理逻辑以正确解析gredis.Message类型 - 在战斗控制器中统一使用model包下的类型定义
188 lines
8.3 KiB
Go
188 lines
8.3 KiB
Go
package model
|
||
|
||
import (
|
||
"blazing/common/data"
|
||
"blazing/cool"
|
||
|
||
"github.com/tnnmigga/enum"
|
||
)
|
||
|
||
// 表名常量
|
||
const TableNamePlayerPVP = "player_pvp"
|
||
|
||
// PVP 对应数据库表 player_pvp,用于记录用户PVP赛季数据及场次统计
|
||
type PVP struct {
|
||
Base
|
||
PlayerID uint64 `gorm:"not null;index:idx_pvp_player_id;comment:'所属玩家ID'" json:"player_id"`
|
||
//SeasonID uint32 `gorm:"not null;index:idx_pvp_season_id;comment:'赛季ID(如2026S1=101)'" json:"season_id"`
|
||
SeasonData []PVPRankInfo `gorm:"type:jsonb;not null;comment:'赛季核心数据'" json:"season_data"`
|
||
MatchRecords []PVPMatchRecord `gorm:"type:jsonb;not null;comment:'本赛季场次记录(仅存最近100场)'" json:"match_records"`
|
||
RankInfo PVPRankInfo `gorm:"type:jsonb;not null;comment:'本赛季排名信息'" json:"rank_info"`
|
||
}
|
||
|
||
// PVPSeasonData PVP赛季核心统计数据
|
||
// 聚合维度:总场次、胜负、积分、胜率等
|
||
type PVPRankInfo struct {
|
||
Rank uint32 `json:"rank"` // 本赛季全服排名(0=未上榜)
|
||
Segment uint32 `json:"segment"` // 段位ID(如1=青铜 2=白银...)
|
||
SegmentStar uint32 `json:"segment_star"` // 段位星级(如青铜3星)
|
||
NextSegmentScore int32 `json:"next_segment_score"` // 升段所需积分
|
||
TotalMatch uint32 `json:"total_match"` // 本赛季总场次
|
||
WinMatch uint32 `json:"win_match"` // 本赛季胜利场次
|
||
LoseMatch uint32 `json:"lose_match"` // 本赛季失败场次
|
||
DrawMatch uint32 `json:"draw_match"` // 本赛季平局场次
|
||
TotalScore int32 `json:"total_score"` // 本赛季总积分(胜加负减)
|
||
HighestScore int32 `json:"highest_score"` // 本赛季最高积分
|
||
ContinuousWin uint32 `json:"continuous_win"` // 本赛季最高连胜次数
|
||
LastMatchTime uint64 `json:"last_match_time"` // 最后一场PVP时间(时间戳)
|
||
}
|
||
|
||
// PVPMatchRecord PVP单场记录
|
||
// 记录每一场的详细信息,便于复盘和统计
|
||
type PVPMatchRecord struct {
|
||
MatchID string `json:"match_id"` // 匹配局ID(全局唯一)
|
||
MatchTime uint64 `json:"match_time"` // 对局时间(时间戳)
|
||
NoteReadyToFightInfo
|
||
Result uint32 `json:"result"` // 对局结果:0=负 1=胜 2=平
|
||
ScoreChange int32 `json:"score_change"` // 本场积分变化(+10/-5等)
|
||
UsedPetIDs []uint32 `json:"used_pet_ids"` // 本场使用的精灵ID列表
|
||
WinStreak uint32 `json:"win_streak"` // 本场结束后的连胜数
|
||
Duration uint32 `json:"duration"` // 对局时长(秒)
|
||
}
|
||
|
||
// NoteReadyToFightInfo 战斗准备就绪消息结构体,NoteReadyToFightInfo
|
||
type NoteReadyToFightInfo struct {
|
||
//MAXPET uint32 `struc:"skip"` // 最大精灵数 struc:"skip"`
|
||
// 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用)
|
||
// @UInt long
|
||
Status uint32 `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `
|
||
//Mode uint32 `struc:"skip"`
|
||
// 我方信息
|
||
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"`
|
||
}
|
||
type FightUserInfo struct {
|
||
// 用户ID(野怪为0),@UInt long
|
||
UserID uint32 `fieldDesc:"userID 如果为野怪则为0" `
|
||
|
||
// 玩家名称(野怪为UTF-8的'-',固定16字节)
|
||
// 使用[16]byte存储固定长度的字节数组
|
||
Nick string `struc:"[16]byte"`
|
||
}
|
||
|
||
// 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 `struc:"sizeof=SkillList"`
|
||
// 技能信息列表(固定4个元素,技能ID和剩余PP,无技能则为0)
|
||
// List<SkillInfo>,初始化容量为4
|
||
SkillList []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" `
|
||
// 是否闪光(@UInt long → uint32,0=否,1=是)
|
||
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
|
||
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
|
||
}
|
||
type FightOverInfo struct {
|
||
//0 正常结束
|
||
//1=isPlayerLost 对方玩家退出
|
||
// 2=isOvertime 超时
|
||
// 3=isDraw 双方平手
|
||
// 4=isSysError 系统错误
|
||
// 5=isNpcEscape 精灵主动逃跑
|
||
|
||
Winpet *PetInfo `struc:"skip"`
|
||
Round uint32 `struc:"skip"`
|
||
LastAttavue AttackValue `struc:"skip"`
|
||
//7 切磋结束
|
||
Reason EnumBattleOverReason // 固定值0
|
||
WinnerId uint32 // 胜者的米米号 野怪为0
|
||
TwoTimes uint32 // 双倍经验剩余次数
|
||
ThreeTimes uint32 // 三倍经验剩余次数
|
||
AutoFightTimes uint32 // 自动战斗剩余次数
|
||
EnergyTime uint32 // 能量吸收器剩余次数
|
||
LearnTimes uint32 // 双倍学习器剩余次数
|
||
}
|
||
|
||
// 战斗结束原因枚举
|
||
type EnumBattleOverReason int
|
||
|
||
var BattleOverReason = enum.New[struct {
|
||
PlayerOffline EnumBattleOverReason `enum:"1"` //掉线
|
||
PlayerOVerTime EnumBattleOverReason `enum:"2"` //超时
|
||
NOTwind EnumBattleOverReason `enum:"3"` //打成平手
|
||
DefaultEnd EnumBattleOverReason `enum:"4"` //默认结束
|
||
PlayerEscape EnumBattleOverReason `enum:"5"` //逃跑
|
||
Cacthok EnumBattleOverReason `enum:"6"`
|
||
}]()
|
||
|
||
// 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 则击中,2为必中"`
|
||
LostHp uint32 `json:"lostHp" fieldDescription:"我方造成的伤害"`
|
||
GainHp int32 `json:"gainHp" fieldDescription:"我方获得血量"`
|
||
RemainHp int32 `json:"remainHp" fieldDescription:"我方剩余血量"`
|
||
MaxHp uint32 `json:"maxHp" fieldDescription:"我方最大血量"`
|
||
//颜色
|
||
State uint32 `json:"state" `
|
||
SkillListLen uint32 `struc:"sizeof=SkillList"`
|
||
SkillList []SkillInfo `json:"skillList" fieldDescription:"根据精灵的数据插入技能 最多4条 不定长"`
|
||
IsCritical uint32 `json:"isCritical" fieldDescription:"是否暴击"`
|
||
Status [20]int8 //精灵的状态
|
||
// 攻击,防御,特供,特防,速度,命中
|
||
Prop [6]int8
|
||
Offensive float32
|
||
// OwnerMaxShield uint32 `json:"ownerMaxShield" fieldDescription:"我方最大护盾"`
|
||
// OwnerCurrentShield uint32 `json:"ownerCurrentShield" fieldDescription:"我方当前护盾"`
|
||
}
|
||
|
||
// TableName 返回表名
|
||
func (*PVP) TableName() string {
|
||
return TableNamePlayerPVP
|
||
}
|
||
|
||
// GroupName 返回表组名
|
||
func (*PVP) GroupName() string {
|
||
return "default"
|
||
}
|
||
|
||
// init 程序启动时自动创建表
|
||
func init() {
|
||
cool.CreateTable(&PVP{})
|
||
}
|