feat(pet): 更新精灵闪光信息结构以支持更丰富的光晕效果

将 Shiny 字段从单一 uint32 值扩展为 GlowFilter 结构体数组及相关长度字段,
用于表示更复杂的闪光视觉效果。同时调整相关序列化标签及保留字段布局。

- 修改 PetInfo、PetShortInfo、ReadyFightPetInfo 等结构体中的 Shiny 表示方式
- 添加 ShinyLen 和 ShinyInfo 字段,并配置 json 与 struc 序列化选项
- 调整部分结构体中 Reserved 字段为数组形式以优化空间布局
- 更新 copier.Copy 为 copier.CopyWithOption 并启用深拷贝逻辑
- 微调经验升级顺序以确保数据一致性
- 修正地图BOSS信息判断条件并清理无用导入和注释代码
This commit is contained in:
2025-12-14 05:34:39 +08:00
parent 6368e2f2e9
commit 4b604669e4
12 changed files with 101 additions and 26 deletions

View File

@@ -0,0 +1,19 @@
package controller
import (
"blazing/common/socket/errorcode"
"blazing/logic/service/leiyi"
"blazing/logic/service/player"
)
func (h Controller) Leiyi(data *leiyi.C2s_LEIYI_TRAIN_GET_STATUS, c *player.Player) (result *leiyi.S2C_LEIYI_TRAIN_GET_STATUS, err errorcode.ErrorCode) {
result = &leiyi.S2C_LEIYI_TRAIN_GET_STATUS{}
for i := 0; i < 6; i++ {
result.Status[i].Total = 10
}
return
}

View File

@@ -21,7 +21,7 @@ func (h *Controller) MapEnter(data *space.InInfo, c *player.Player) (result *inf
println("进入地图", c.Info.UserID, c.Info.MapID)
result = info.NewOutInfo()
c.Info.Pos = data.Point
copier.Copy(result, c.Info)
copier.CopyWithOption(result, c.Info, copier.Option{DeepCopy: true})
defer c.GetSpace().EnterMap(c)

View File

@@ -12,6 +12,7 @@ import (
type EffectAttackMiss struct {
node.EffectNode
targetCategory info.EnumCategory // 差异化:目标攻击类型(物理/特殊等)
can bool
}
// 工厂函数:创建"指定攻击类型必定miss"效果实例
@@ -68,5 +69,6 @@ func (e *EffectAttackMiss) Skill_Hit_ex() bool {
// 设置参数:复用父类逻辑,设置持续回合
func (e *EffectAttackMiss) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.CanStack(true)
e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0] - 1) // 持续回合由SideEffectArgs[0]指定
}

View File

@@ -287,7 +287,9 @@ type ReadyFightPetInfo struct {
// 固定给0@UInt long
CatchLevel uint32 `fieldDesc:"给0" `
SkinID uint32 `fieldDesc:"精灵皮肤ID" `
Shiny uint32 `fieldDesc:"精灵是否闪" `
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
}
// FightOverInfo 战斗结束信息结构体 2506

View File

@@ -0,0 +1,21 @@
package leiyi
import (
"blazing/logic/service/common"
)
type C2s_LEIYI_TRAIN_GET_STATUS struct {
Head common.TomeeHeader `cmd:"2393" struc:"skip"` //玩家登录
}
// OutInfo 表示地图热度的出站消息
type S2C_LEIYI_TRAIN_GET_STATUS struct {
Status [10]S2C_LEIYI_TRAIN_GET_STATUS_info `json:"status"`
}
type S2C_LEIYI_TRAIN_GET_STATUS_info struct {
// Today uint32 // 今日训练HP次数
Current uint32 // 当前训练HP次数
Total uint32 // 目标训练HP次数
}

View File

@@ -22,7 +22,9 @@ type PetShortInfo struct {
CatchTime uint32 // 精灵生成时间
Level uint32 // 精灵等级
SkinID uint32 // 精灵皮肤ID
Shiny uint32 // 精灵是否闪光(0=否1=是)
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
}
// C2S_PetFusion 前端(Client)到后端(Server)的精灵融合请求包

View File

@@ -43,8 +43,10 @@ type PetShowOutboundInfo struct {
ID uint32 `codec:"PetID" description:"精灵编号"`
Flag uint32 `codec:"flag" description:"1为显示 0为收回"`
Dv uint32 `codec:"dv" description:"个体"`
Shiny uint32 `codec:"shiny" description:"闪光状态标识"`
SkinID uint32 `codec:"skinID" description:"皮肤ID"`
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
SkinID uint32 `codec:"skinID" description:"皮肤ID"`
Reserved1 [3]uint32
}
type PetOneCureInboundInfo struct {

View File

@@ -23,9 +23,9 @@ func (p *Player) AddPetExp(petinfo *model.PetInfo, addExp uint32) {
for Exp >= petinfo.NextLvExp {
petinfo.Level++
petinfo.Update(true)
Exp -= petinfo.LvExp
Exp -= petinfo.LvExp
petinfo.Update(true)
if originalLevel < 100 && petinfo.Level == 100 { //升到100了
p.Info.ExpPool += Exp //减去已使用的经验
gainexp -= Exp

View File

@@ -2,7 +2,7 @@ package space
import (
"blazing/logic/service/common"
"blazing/logic/service/space/info"
"sync/atomic"
@@ -74,7 +74,7 @@ func (s *Space) GetInfo(c common.PlayerI) []info.OutInfo {
if atomic.LoadUint32(&s.TimeBoss.Flag) == 1 {
defer c.SendPackCmd(2022, &s.TimeBoss)
}
if s.MapBossInfo.Id != 0 {
if s.MapBossInfo.Pos != 200 {
var t info.MapBossSInfo
t.INFO = append(t.INFO, s.MapBossInfo)
s.Broadcast(nil, 2021, &t)

View File

@@ -88,16 +88,13 @@ type OutInfo struct {
// 宠物 ID 暂时无法测试,给 0
PetDV uint32 `struc:"uint32" fieldDesc:"宠物ID暂时无法测试, 给0" json:"pet_dv"`
// 宠物闪光暂时无法测试,给 0
PetShiny uint32 `struc:"uint32" fieldDesc:"宠物闪光暂时无法测试, 给0" json:"pet_shiny"`
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"`
// 宠物皮肤暂时无法测试,给 0
PetSkin uint32 `struc:"uint32" fieldDesc:"宠物皮肤暂时无法测试, 给0" json:"pet_skin"`
// 填充字符
Reserved uint32 `struc:"uint32" fieldDesc:"填充字符" json:"reserved"`
// 填充字符
Reserved1 uint32 `struc:"uint32" fieldDesc:"填充字符" json:"reserved1"`
// 填充字符
Reserved2 uint32 `struc:"uint32" fieldDesc:"填充字符" json:"reserved2"`
Reserved [3]uint32 `struc:"uint32" fieldDesc:"填充字符" json:"reserved"`
// 暂时不明给0
FightFlag uint32 `struc:"uint32" fieldDesc:"暂时不明给0" json:"fight_flag"`

View File

@@ -57,8 +57,38 @@ func main() {
// }
//service.TestSendVerificationCode()
// t := model.GenPetInfo(1, 31, 1, 1, 1, 1)
// for i := 0; i < 10; i++ {
// t := model.GenPetInfo(1, 31, 1, 1, 1, 1)
// t.ShinyInfo = make([]model.GlowFilter, 1)
// // 假设 t 是包含 ShinyInfo 字段的结构体ShinyInfo 是 GlowFilter 类型的切片
// t.ShinyInfo[0] = model.GlowFilter{
// // 光晕颜色:白色(十六进制 0xFFFFFF符合 uint32 类型
// Color: 0xFFFFFF,
// // 透明度0.80.0~1.0 范围内的合理值float64 类型)
// Alpha: 0.8,
// // 水平模糊量100~255 范围内uint8 类型略高于默认值6
// BlurX: 10,
// // 垂直模糊量10与 BlurX 对称uint8 类型)
// BlurY: 10,
// // 发光强度80~255 范围内uint8 类型略高于默认值2
// Strength: 8,
// // 滤镜应用次数21~3 范围内int 类型非默认值1
// Quality: 2,
// // 内侧发光truebool 类型,模拟开启内侧发光)
// Inner: true,
// // 挖空falsebool 类型,保持默认逻辑)
// Knockout: false,
// // 颜色矩阵:标准 RGBA 矩阵20个uint8符合 [20]uint8 数组类型)
// // 矩阵含义R=100%、G=100%、B=100%、A=100%,无颜色偏移
// ColorMatrixFilter: [20]uint8{
// 1, 0, 0, 0, 0, // R 通道
// 0, 1, 0, 0, 0, // G 通道
// 0, 0, 1, 0, 0, // B 通道
// 0, 0, 0, 1, 0, // A 通道
// },
// }
// service.NewUserService(10001).Pet.PetAdd(t)
// }
// for i := 0; i < 1000; i++ {
// service.NewUserService(10001).Pet.PetAdd(t)
// }

View File

@@ -52,7 +52,7 @@ type PetInfo struct {
ID uint32 `fieldDesc:"精灵编号" `
// 名字默认为全0补齐到16字节固定长度 → [16]byte
Name string `struc:"[16]byte" `
Name string `struc:"[16]byte" json:"Name,omitempty"`
// 个体值(@UInt long → uint32
Dv uint32 `struc:"uint32" `
@@ -83,24 +83,24 @@ type PetInfo struct {
// * ev:生命学习力,攻击学习力,防御学习力,特攻学习力,特防学习力,速度学习力
Ev [6]uint32 `fieldDesc:"属性" `
SkillListLen uint32 `struc:"sizeof=SkillList"`
SkillListLen uint32 `struc:"sizeof=SkillList" json:"-"`
// 技能信息固定4条空则赋值0固定长度List → [4]SkillInfo零值即符合“赋值0”
SkillList []SkillInfo
// 捕捉时间(@UInt long → 若为时间戳用uint32若需时间类型可改为time.Time需配合序列化处理
CatchTime uint32 //`json:"-"` // 显式忽略,不参与序列化
CatchTime uint32 //显式忽略,不参与序列化
OldCatchTime uint32 `struc:"skip" fieldDesc:"旧捕捉时间" `
// 捕捉地图(@UInt long → uint32
CatchMap uint32 `fieldDesc:"捕捉地图" `
CatchMap uint32 `json:"CatchMap,omitempty"`
// 未知默认0@UInt long → uint32
CatchRect uint32 `fieldDesc:"未知默认为0" `
CatchRect uint32 `json:"CatchRect,omitempty"`
// 捕获等级默认0@UInt long → uint32
CatchLevel uint32 `fieldDesc:"捕获等级 默认为0" `
EffectInfoLen uint16 `struc:"sizeof=EffectInfo"`
EffectInfoLen uint16 `struc:"sizeof=EffectInfo" json:"-"`
// 特性列表长度用UShort存储变长List → []PetEffectInfo + 长度前缀规则) 第一个一定是特性
EffectInfo []PetEffectInfo `fieldDesc:"特性列表, 长度在头部以UShort存储" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
@@ -108,7 +108,7 @@ type PetInfo struct {
SkinID uint32 `fieldDesc:"皮肤id默认为0" `
// 是否闪光(@UInt long → uint320=否1=是)
ShinyLen uint32 `json:"ShinyLen,omitempty" struc:"sizeof=ShinyInfo"`
ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"`
ShinyInfo []GlowFilter `json:"ShinyInfo,omitempty"`
//时间轮转然后effect根据type同时只共存一个特性是1 特质是1柱子是两种魂印是一个然后异色字段然后特训技能字段
@@ -345,7 +345,7 @@ type PetEffectInfo struct {
Status byte `struc:"byte" json:"status"` //特性为1,能量珠为2
LeftCount byte `struc:"byte" json:"left_count"` //剩余次数
EID uint16 `struc:"uint16" json:"effect_id"` //特效ID
ArgsLen uint32 `struc:"sizeof=Args"`
ArgsLen uint32 `struc:"sizeof=Args" json:"-"`
Args []int ` json:"Args"` //自定义参数装载