From 4b604669e4334f687e9d5f5c532c217f1c7c58ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Sun, 14 Dec 2025 05:34:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(pet):=20=E6=9B=B4=E6=96=B0=E7=B2=BE?= =?UTF-8?q?=E7=81=B5=E9=97=AA=E5=85=89=E4=BF=A1=E6=81=AF=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9B=B4=E4=B8=B0=E5=AF=8C=E7=9A=84?= =?UTF-8?q?=E5=85=89=E6=99=95=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 Shiny 字段从单一 uint32 值扩展为 GlowFilter 结构体数组及相关长度字段, 用于表示更复杂的闪光视觉效果。同时调整相关序列化标签及保留字段布局。 - 修改 PetInfo、PetShortInfo、ReadyFightPetInfo 等结构体中的 Shiny 表示方式 - 添加 ShinyLen 和 ShinyInfo 字段,并配置 json 与 struc 序列化选项 - 调整部分结构体中 Reserved 字段为数组形式以优化空间布局 - 更新 copier.Copy 为 copier.CopyWithOption 并启用深拷贝逻辑 - 微调经验升级顺序以确保数据一致性 - 修正地图BOSS信息判断条件并清理无用导入和注释代码 --- logic/controller/activce_leiyi.go | 19 +++++++++++ logic/controller/map.go | 2 +- .../service/fight/effect/EffectAttackMiss.go | 2 ++ logic/service/fight/info/info.go | 4 ++- logic/service/leiyi/leiyi.go | 21 ++++++++++++ logic/service/pet/list.go | 4 ++- logic/service/pet/pet.go | 6 ++-- logic/service/player/pet.go | 4 +-- logic/service/space/in_out.go | 4 +-- logic/service/space/info/info.go | 11 +++--- login/main.go | 34 +++++++++++++++++-- modules/blazing/model/pet.go | 16 ++++----- 12 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 logic/controller/activce_leiyi.go create mode 100644 logic/service/leiyi/leiyi.go diff --git a/logic/controller/activce_leiyi.go b/logic/controller/activce_leiyi.go new file mode 100644 index 000000000..c4b01d9f2 --- /dev/null +++ b/logic/controller/activce_leiyi.go @@ -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 + +} diff --git a/logic/controller/map.go b/logic/controller/map.go index 1f0103096..96b8e140b 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -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) diff --git a/logic/service/fight/effect/EffectAttackMiss.go b/logic/service/fight/effect/EffectAttackMiss.go index a9f2e77ba..2e487ea9b 100644 --- a/logic/service/fight/effect/EffectAttackMiss.go +++ b/logic/service/fight/effect/EffectAttackMiss.go @@ -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]指定 } diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index 1f31ad78e..487809946 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -287,7 +287,9 @@ type ReadyFightPetInfo struct { // 固定给0,@UInt long CatchLevel uint32 `fieldDesc:"给0" ` SkinID uint32 `fieldDesc:"精灵皮肤ID" ` - Shiny uint32 `fieldDesc:"精灵是否闪" ` + // 是否闪光(@UInt long → uint32,0=否,1=是) + ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"` + ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"` } // FightOverInfo 战斗结束信息结构体 2506 diff --git a/logic/service/leiyi/leiyi.go b/logic/service/leiyi/leiyi.go new file mode 100644 index 000000000..d01db0251 --- /dev/null +++ b/logic/service/leiyi/leiyi.go @@ -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次数 + +} diff --git a/logic/service/pet/list.go b/logic/service/pet/list.go index d860bc11e..2c687ea14 100644 --- a/logic/service/pet/list.go +++ b/logic/service/pet/list.go @@ -22,7 +22,9 @@ type PetShortInfo struct { CatchTime uint32 // 精灵生成时间 Level uint32 // 精灵等级 SkinID uint32 // 精灵皮肤ID - Shiny uint32 // 精灵是否闪光(0=否,1=是) + // 是否闪光(@UInt long → uint32,0=否,1=是) + ShinyLen uint32 `json:"-" struc:"sizeof=ShinyInfo"` + ShinyInfo []model.GlowFilter `json:"ShinyInfo,omitempty"` } // C2S_PetFusion 前端(Client)到后端(Server)的精灵融合请求包 diff --git a/logic/service/pet/pet.go b/logic/service/pet/pet.go index 2d54765c2..636d2d997 100644 --- a/logic/service/pet/pet.go +++ b/logic/service/pet/pet.go @@ -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 → uint32,0=否,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 { diff --git a/logic/service/player/pet.go b/logic/service/player/pet.go index 1b14d2ee7..ec6c5d78e 100644 --- a/logic/service/player/pet.go +++ b/logic/service/player/pet.go @@ -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 diff --git a/logic/service/space/in_out.go b/logic/service/space/in_out.go index db5741134..71107bb6b 100644 --- a/logic/service/space/in_out.go +++ b/logic/service/space/in_out.go @@ -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) diff --git a/logic/service/space/info/info.go b/logic/service/space/info/info.go index 1356eed99..80dd73f21 100644 --- a/logic/service/space/info/info.go +++ b/logic/service/space/info/info.go @@ -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 → uint32,0=否,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"` diff --git a/login/main.go b/login/main.go index 499046021..59b4d68d5 100644 --- a/login/main.go +++ b/login/main.go @@ -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.8(0.0~1.0 范围内的合理值,float64 类型) + // Alpha: 0.8, + // // 水平模糊量:10(0~255 范围内,uint8 类型,略高于默认值6) + // BlurX: 10, + // // 垂直模糊量:10(与 BlurX 对称,uint8 类型) + // BlurY: 10, + // // 发光强度:8(0~255 范围内,uint8 类型,略高于默认值2) + // Strength: 8, + // // 滤镜应用次数:2(1~3 范围内,int 类型,非默认值1) + // Quality: 2, + // // 内侧发光:true(bool 类型,模拟开启内侧发光) + // Inner: true, + // // 挖空:false(bool 类型,保持默认逻辑) + // 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) // } diff --git a/modules/blazing/model/pet.go b/modules/blazing/model/pet.go index dd56dfb75..a98219f00 100644 --- a/modules/blazing/model/pet.go +++ b/modules/blazing/model/pet.go @@ -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 → uint32,0=否,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"` //自定义参数装载