package model import ( "blazing/common/data" "blazing/cool" "github.com/gogf/gf/v2/os/gtime" "github.com/tnnmigga/enum" ) // 表名常量 const TableNamePlayerPVP = "player_pvp" const Curpvp = 0 // PVP 对应数据库表 player_pvp,用于记录用户PVP赛季数据及场次统计 type PVP struct { *cool.Model PlayerID uint32 `gorm:"not null;index:idx_pvp_player_id;comment:'所属玩家ID'" json:"player_id"` //第几赛季 Season uint32 `gorm:"not null;default:0;comment:'赛季R'" json:"season"` //本赛季排名信息'通过下标来确认当前赛季 RankInfo PVPRankInfo `gorm:"type:jsonb;not null;comment:'赛季核心数据'" json:"rank_info"` } func (u *PVP) Less(than *PVP) bool { if u.RankInfo.Score == than.RankInfo.Score { return u.RankInfo.LastMatchTime.Unix() < than.RankInfo.LastMatchTime.Unix() } return u.RankInfo.Score < than.RankInfo.Score } func NewPVP() *PVP { return &PVP{ Model: cool.NewModel(), } } // PVPSeasonData PVP赛季核心统计数据 // 聚合维度:总场次、胜负、积分、胜率等 type PVPRankInfo struct { Rank uint32 `json:"rank"` // 本赛季全服排名(0=未上榜) Score int `json:"score"` // 当前积分 WinStreak uint32 `json:"win_streak"` // 当前连胜场次 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 *gtime.Time `json:"last_match_time"` // 最后一场PVP时间(时间戳) } // func (u *PVPRankInfo) Key() uint32 { // return uint32(u.ID) // } // 如果分数不对的话,就按时间排序 // NoteReadyToFightInfo 战斗准备就绪消息结构体,NoteReadyToFightInfo type NoteReadyToFightInfo struct { //MAXPET uint32 `struc:"skip"` // 最大精灵数 struc:"skip"` // 战斗类型ID(与野怪战斗为3,与人战斗为1,前端似乎未使用) 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,使用切片模拟动态列表 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) UserID uint32 `fieldDesc:"userID 如果为野怪则为0" ` // 玩家名称(野怪为UTF-8的'-',固定16字节) // 使用[16]byte存储固定长度的字节数组 Nick string `struc:"[16]byte"` } // ReadyFightPetInfo 准备战斗的精灵信息结构体,ReadyFightPetInfo类 type ReadyFightPetInfo struct { // 精灵ID ID uint32 `fieldDesc:"精灵ID" ` // 精灵等级 Level uint32 `fieldDesc:"精灵等级" ` // 精灵当前HP Hp uint32 `fieldDesc:"精灵HP" ` // 精灵最大HP MaxHp uint32 `fieldDesc:"最大HP" ` SkillListLen uint32 `struc:"sizeof=SkillList"` // 技能信息列表(固定4个元素,技能ID和剩余PP,无技能则为0) // List,初始化容量为4 SkillList []SkillInfo `fieldDesc:"技能信息 技能ID跟剩余PP 固定32字节 没有给0" serialize:"fixedLength=4,type=structArray"` // 精灵捕获时间 CatchTime uint32 `fieldDesc:"精灵捕获时间" ` // 捕捉地图(固定给0) CatchMap uint32 `fieldDesc:"捕捉地图 给0" ` // 固定给0 CatchRect uint32 `fieldDesc:"给0" ` // 固定给0 CatchLevel uint32 `fieldDesc:"给0" ` SkinID uint32 `fieldDesc:"精灵皮肤ID" ` ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"` ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"` IsCapture uint8 `struc:"uint8" json:"isCapture"` } type FightOverInfo struct { //0 正常结束 //1=isPlayerLost 对方玩家退出 // 2=isOvertime 超时 // 3=isDraw 双方平手 // 4=isSysError 系统错误 // 5=isNpcEscape 精灵主动逃跑 Winpet *PetInfo `struc:"skip"` Round uint32 `struc:"skip"` // Duration uint32 `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"` ActorIndex uint32 `json:"actorIndex" fieldDescription:"当前动作所属战斗位"` TargetIndex uint32 `json:"targetIndex" fieldDescription:"当前动作目标战斗位"` 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{}) }