Files
bl/modules/player/model/pvp.go
昔念 4751594ee8 ```
feat: 更新战斗系统模型结构和Redis消息处理

- 引入gredis依赖用于Redis消息处理
- 将战斗相关的枚举和结构体从info包迁移到model包
- 更新战斗结束原因、攻击值等类型的引用路径
- 添加新的zset工具包到工作区
- 修改Redis消息处理逻辑以正确解析gredis.Message类型
- 在战斗控制器中统一使用model包下的类型定义
2026-03-04 22:47:21 +08:00

188 lines
8.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 → uint320=否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{})
}