feat(fight_boss): 更新BOSS战斗效果逻辑以使用新的服务接口

将原来直接访问xmlres.EffectMAP获取效果信息的方式,
替换为通过service.NewEffectService().Args方法获取EID与参数,
提高代码解耦性与可维护性。

refactor(item_buy): 调整金币商品购买时的价格计算逻辑

修复购买金币商品时价格未正确乘以100的问题,
确保消耗金币数量准确无
This commit is contained in:
2025-12-08 00:17:04 +08:00
parent 294cb2e3fd
commit 7005c1047f
12 changed files with 190 additions and 12 deletions

View File

@@ -0,0 +1,17 @@
package controller
import (
"blazing/common/socket/errorcode"
"blazing/logic/service/egg"
"blazing/logic/service/player"
"blazing/modules/blazing/model"
)
func (h Controller) EGG(data *egg.C2S_EGG_GAME_PLAY, c *player.Player) (result *egg.S2C_EGG_GAME_PLAY, err errorcode.ErrorCode) {
r := model.GenPetInfo(1, -1, -1, -1, 0, 1)
c.Service.Pet.PetAdd(r)
result = &egg.S2C_EGG_GAME_PLAY{HadTime: r.CatchTime, ListInfo: []model.ItemInfo{}, PetID: r.ID}
return
}

View File

@@ -10,6 +10,7 @@ import (
"blazing/logic/service/player" "blazing/logic/service/player"
"blazing/modules/blazing/model" "blazing/modules/blazing/model"
"blazing/modules/blazing/service"
"github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand" "github.com/gogf/gf/v2/util/grand"
@@ -88,11 +89,13 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
for _, v := range strings.Split(bm.NewSeIdxs, " ") { for _, v := range strings.Split(bm.NewSeIdxs, " ") {
idx := gconv.Uint16(v) idx := gconv.Uint16(v)
eff := xmlres.EffectMAP[int(idx)] // eff := xmlres.EffectMAP[int(idx)]
args := strings.Split(eff.Args, " ") // args := strings.Split(eff.Args, " ")
EID, args := service.NewEffectService().Args(uint32(idx))
mo.EffectInfo = append(mo.EffectInfo, model.PetEffectInfo{ mo.EffectInfo = append(mo.EffectInfo, model.PetEffectInfo{
Idx: idx, Idx: idx,
EID: gconv.Uint16(eff.Eid), EID: gconv.Uint16(EID),
Args: gconv.Ints(args), Args: gconv.Ints(args),
}) })
} }

View File

@@ -58,7 +58,7 @@ func (h Controller) BuyMItem(data *item.BuyMultiInboundInfo, c *player.Player) (
func (h Controller) BuyGoldItem(data *item.C2S_GOLD_BUY_PRODUCT, c *player.Player) (result *item.S2C_GoldBuyProductInfo, err errorcode.ErrorCode) { func (h Controller) BuyGoldItem(data *item.C2S_GOLD_BUY_PRODUCT, c *player.Player) (result *item.S2C_GoldBuyProductInfo, err errorcode.ErrorCode) {
r := xmlres.GoldProductMap[int(data.ProductID)] r := xmlres.GoldProductMap[int(data.ProductID)]
if !c.UseGold(uint32(data.Count) * uint32(gconv.Uint32(r.Price))) { if !c.UseGold(uint32(data.Count) * uint32(gconv.Uint32(r.Price)*100)) {
return nil, errorcode.ErrorCodes.ErrSystemError return nil, errorcode.ErrorCodes.ErrSystemError
} }
r1 := c.ItemAdd(model.ItemInfo{ItemId: uint32(gconv.Uint32(r.ItemID)), ItemCnt: uint32(data.Count)}) r1 := c.ItemAdd(model.ItemInfo{ItemId: uint32(gconv.Uint32(r.ItemID)), ItemCnt: uint32(data.Count)})

View File

@@ -17,11 +17,11 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *player.Player) (result *info
c.Info.MapID = data.MapId //登录地图 c.Info.MapID = data.MapId //登录地图
c.GetSpace().User.Store(c.Info.UserID, c) //添加玩家 c.GetSpace().User.Store(c.Info.UserID, c) //添加玩家
println("进入地图", c.Info.UserID, c.Info.MapID)
result = info.NewOutInfo() result = info.NewOutInfo()
c.Info.Pos = data.Point c.Info.Pos = data.Point
copier.Copy(result, c.Info) copier.Copy(result, c.Info)
atomic.StoreUint32(&c.Canmon, 2)
defer c.GetSpace().EnterMap(c) defer c.GetSpace().EnterMap(c)
// go func() { // go func() {
@@ -72,7 +72,6 @@ func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *player.Play
result = &info.ListMapPlayerOutboundInfo{ result = &info.ListMapPlayerOutboundInfo{
Player: c.GetSpace().GetInfo(), Player: c.GetSpace().GetInfo(),
} }
atomic.StoreUint32(&c.Canmon, 2)
return return
} }

24
logic/service/egg/egg.go Normal file
View File

@@ -0,0 +1,24 @@
package egg
import (
"blazing/logic/service/common"
"blazing/modules/blazing/model"
)
// C2S_EGG_GAME_PLAY 前端向后端发送的抽蛋请求结构体
// 对应原 C# 的 C2S_EGG_GAME_PLAY
type C2S_EGG_GAME_PLAY struct {
Head common.TomeeHeader `cmd:"3201" struc:"skip"`
EggNum uint32 `json:"eggNum"` // 抽蛋次数标识1 = 1次 2 = 5次 3 = 10次
// 注Go 中 uint 是平台相关类型32/64位游戏开发中推荐用 uint32 明确匹配 C# 的 uint
}
// S2C_EGG_GAME_PLAY 后端向前端返回的抽蛋结果结构体
// 对应原 C# 的 S2C_EGG_GAME_PLAY
type S2C_EGG_GAME_PLAY struct {
GiftIN uint32 `json:"giftIN"` // 未知字段 写0 未引用
PetID uint32 `json:"petID"` // 抽中精灵的id
HadTime uint32 `json:"hadTime"` // 抽中精灵的捕捉时间(若为时间戳,建议改为 uint64
ListInfoLen uint32 `struc:"sizeof=ListInfo"`
ListInfo []model.ItemInfo `json:"listinfo"` // 抽中物品的物品数组
}

View File

@@ -35,6 +35,19 @@ func InitEffect(etype EnumEffectType, id int, t Effect) {
NodeM[pr.EffectID()] = t NodeM[pr.EffectID()] = t
} }
func GeteffectIDs(etype EnumEffectType) []uint32 {
var ret []uint32 = make([]uint32, 0)
for _, v := range NodeM {
if v.ID().GetEffectType() == etype {
ret = append(ret, uint32(v.ID().Suffix()))
}
}
return ret
}
// 这里的catchtime为0,取出来之后如果是魂印,要重新赋值 // 这里的catchtime为0,取出来之后如果是魂印,要重新赋值
func Geteffect[T int | byte | uint16](etype EnumEffectType, id T) Effect { func Geteffect[T int | byte | uint16](etype EnumEffectType, id T) Effect {

View File

@@ -66,7 +66,7 @@ func (p *Player) CanGetExp() bool {
// CompleteLogin 标记登录完成并通知等待者 // CompleteLogin 标记登录完成并通知等待者
func (lw *Player) CompleteLogin() { func (lw *Player) CompleteLogin() {
if lw.Info.MapID > 500 || lw.Info.MapID == 0 { //如果位于基地,就重置到传送仓 if lw.Info.MapID > 300 || lw.Info.MapID == 0 { //如果位于基地,就重置到传送仓
lw.Info.MapID = 1 lw.Info.MapID = 1
} }

View File

@@ -0,0 +1,39 @@
package admin
import (
"blazing/cool"
_ "blazing/logic/service/fight/boss"
"blazing/logic/service/fight/input"
"blazing/modules/blazing/service"
"context"
"github.com/gogf/gf/v2/frame/g"
)
type EffectController struct {
*cool.Controller
}
func init() {
var task_info_controller = &EffectController{
&cool.Controller{
Prefix: "/admin/monster/effect",
Api: []string{"Add", "Delete", "Update", "Info", "List", "Page"},
Service: service.NewEffectService(),
},
}
// 注册路由
cool.RegisterController(task_info_controller)
}
type EffIDReq struct {
g.Meta `path:"/effid" method:"GET"`
}
func (c *EffectController) GetSession(ctx context.Context, req *EffIDReq) (res *cool.BaseRes, err error) {
res = &cool.BaseRes{}
res.Data = input.GeteffectIDs(input.EffectType.NewSel)
return
}

View File

@@ -0,0 +1,43 @@
package model
import (
"blazing/cool"
)
// 表名常量(遵循现有命名规范)
const TableNamePlayerPetSpecialEffect = "player_pet_special_effect"
// PlayerPetSpecialEffect 精灵特效表仅包含XML中指定的4个核心字段
// 对应XML中的<NewSeIdx>节点Idx、Stat、Eid、Args
type PlayerPetSpecialEffect struct {
*cool.Model // 嵌入基础Model包含主键、创建/更新时间等通用字段)
// 严格对应XML的4个核心字段
SeIdx uint32 `gorm:"not null;uniqueIndex:idx_se_idx;comment:'精灵特效索引XML中的Idx'" json:"se_idx"`
//Stat uint32 `gorm:"not null;default:0;comment:'精灵特效状态XML中的Stat'" json:"stat"`
Eid uint32 `gorm:"not null;index:idx_eid;comment:'精灵特效EidXML中的Eid'" json:"eid"`
Args []int `gorm:"type:json;comment:'精灵特效参数XML中的Args'" json:"args"`
Desc string `gorm:"type:varchar(255);default:'';comment:'精灵特效描述XML中的Desc'" json:"desc"`
}
// TableName 指定表名(遵循现有规范)
func (*PlayerPetSpecialEffect) TableName() string {
return TableNamePlayerPetSpecialEffect
}
// GroupName 指定表分组默认分组与现有Item表一致
func (*PlayerPetSpecialEffect) GroupName() string {
return "default"
}
// NewPlayerPetSpecialEffect 创建精灵特效表实例初始化基础Model
func NewPlayerPetSpecialEffect() *PlayerPetSpecialEffect {
return &PlayerPetSpecialEffect{
Model: cool.NewModel(),
}
}
// init 程序启动时自动创建表与现有Item表的初始化逻辑一致
func init() {
cool.CreateTable(&PlayerPetSpecialEffect{})
}

View File

@@ -0,0 +1,40 @@
package service
import (
"blazing/cool"
"blazing/modules/blazing/model"
)
type EffectService struct {
*cool.Service
}
func (s *EffectService) Args(id uint32) (int, []int) {
m := cool.DBM(s.Model).Where("se_idx", id)
var tt model.PlayerPetSpecialEffect
err := m.Scan(&tt)
if err != nil {
return 0, nil
}
ret := tt.Args
return int(tt.Eid), ret
}
func NewEffectService() *EffectService {
return &EffectService{
&cool.Service{
// PageQueryOp: &cool.QueryOp{
// ModifyResult: func(ctx g.Ctx, data interface{}) interface{} {
// // t, _ := json.Marshal(data)
// // gjson.GetBytes(t, "list")
// return data
// },
// },
Model: model.NewPlayerPetSpecialEffect(),
},
}
}

View File

@@ -1 +1 @@
E:/newcode/flash/out/resource/xml/30001.xml E:/newcode/flash/out/dll/30001.xml

View File

@@ -3442,11 +3442,11 @@ eg:
<Boss Id="0" TaskID="307" AppearTime="0 23" BossVisible="0" Name="SPT纳多雷" <Boss Id="0" TaskID="307" AppearTime="0 23" BossVisible="0" Name="SPT纳多雷"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="7" BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="7"
SptLevel="1"> SptLevel="1">
<!--BossMon <BossMon
MonID="88" Hp="1400" Lv="70" NewSeIdxs="9 63 71"/--> MonID="88" Hp="1400" Lv="70" NewSeIdxs="9 63 71" />
<!--BossMon <!--BossMon
MonID="88" Hp="900" Lv="70" NewSeIdxs="9"/--> MonID="88" Hp="900" Lv="70" NewSeIdxs="9"/-->
<BossMon MonID="88" Hp="700" Lv="70" NewSeIdxs="9" /> <!-- <BossMon MonID="88" Hp="700" Lv="70" NewSeIdxs="9" /> -->
</Boss> </Boss>
<Boss Id="1" TaskID="2007" AppearTime="0 23" BossVisible="0" Name="SPT纳多雷" <Boss Id="1" TaskID="2007" AppearTime="0 23" BossVisible="0" Name="SPT纳多雷"
BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="7" BonusProbability="20" BonusTotalProbability="1000" BonusID="5016" ItemBonusOutID="7"