| name | bag-generator |
| description | 生成Go语言的背包/容器初始代码。当用户想要创建具有特定容器类型的新背包类型时调用。 |
背包生成器
此技能用于生成遵循项目规范的背包/容器初始代码。
调用时机
- 用户想要创建新的背包/容器
- 用户要求生成新的物品栏类型
- 用户需要背包功能的样板代码
所需信息
向用户询问以下信息:
- 背包名称:背包的名称(例如:"Equip"、"UniqueItem")
- 容器类型:继承哪个ElemContainer:
- CountContainer:用于可堆叠物品(键:int32,值:数量)
- UniqueContainer:用于带有uniqueId的唯一物品(键:int64)
- CfgContainer:用于基于配置的物品(键:int32,配置id)
- Proto数据类型:如果使用UniqueContainer或CfgContainer,指定proto消息类型(例如:
*pb.Equip、*pb.HeroData)
命名规范
根据背包名称生成:
- 结构体名称:
<BagName>Bag(例如:"Equip" → "EquipBag")
- 容器枚举:
ContainerType_ContainerType_<BagName>(例如:"Equip" → ContainerType_ContainerType_Equip)
- 物品类型枚举:
ItemType_ItemType_<BagName>(例如:"Equip" → ItemType_ItemType_Equip)
- 成员变量:
Bag<BagName>(例如:"Equip" → BagEquip)
实现步骤
步骤1:检查并更新Proto文件
检查以下proto文件(位于proto/文件夹):
-
proto/bags.proto - 检查enum ContainerType:
- 如果容器枚举不存在,添加:
ContainerType_<BagName> = <next_value>
-
proto/cfg.proto - 检查enum ItemType:
- 如果物品类型枚举不存在,添加:
ItemType_<BagName> = <next_value>
-
proto/bags.proto - 检查message BagsSync:
步骤2:创建背包文件
使用适当的模板创建game/bag_<bagname>.go。
步骤3:更新game/bags.go
-
向Bags结构体添加背包字段:
Bag<BagName> *<BagName>Bag `child:"<BagName>"`
-
在init()函数中初始化背包:
bags.Bag<BagName> = New<BagName>Bag(bags)
-
在GetBagByArg()中添加case:
case int32(pb.ItemType_ItemType_<BagName>):
return b.Bag<BagName>
-
将背包添加到SyncDataToClient():
<BagName>: b.Bag<BagName>.Data,
代码模板
CountContainer模板
package game
import "github.com/fish-tennis/gserver/pb"
type <BagName>Bag struct {
*CountContainer `db:""`
}
func New<BagName>Bag(bags *Bags) *<BagName>Bag {
bag := &<BagName>Bag{
CountContainer: NewBagCountItem(bags),
}
return bag
}
UniqueContainer模板
package game
import (
"github.com/fish-tennis/gentity/util"
"github.com/fish-tennis/gserver/pb"
)
type <BagName>Bag struct {
*UniqueContainer[*pb.<DataType>] `db:""`
}
func New<BagName>Bag(bags *Bags) *<BagName>Bag {
bag := &<BagName>Bag{
UniqueContainer: NewBagUnique[*pb.<DataType>](bags, pb.ContainerType_ContainerType_<BagName>, func(arg *pb.AddElemArg) *pb.<DataType> {
return &pb.<DataType>{
Id: arg.GetId(),
UniqueId: util.GenUniqueId(),
}
}),
}
return bag
}
CfgContainer模板
package game
import "github.com/fish-tennis/gserver/pb"
type <BagName>Bag struct {
*CfgContainer[*pb.<DataType>] `db:""`
}
func New<BagName>Bag(bags *Bags) *<BagName>Bag {
bag := &<BagName>Bag{
CfgContainer: NewBagCfg[*pb.<DataType>](bags, pb.ContainerType_ContainerType_<BagName>, func(arg *pb.AddElemArg) *pb.<DataType> {
return &pb.<DataType>{
Id: arg.GetId(),
}
}),
}
return bag
}
示例
对于使用CfgContainer和*pb.PetData的"Pet"背包:
- 检查
proto/bags.proto - 添加ContainerType_Pet = 6
- 检查
proto/cfg.proto - 添加ItemType_Pet = 4
- 检查
proto/bags.proto - 向BagsSync添加Pet map[int32]*PetData
- 创建
game/bag_pet.go
- 更新
game/bags.go:
- 添加
BagPet *PetBag \child:"Pet"``
- 添加
bags.BagPet = NewPetBag(bags)
- 为
ItemType_ItemType_Pet添加case
- 向SyncDataToClient添加
Pet: b.BagPet.Data
注意事项
- Proto文件位于
proto/目录
- 修改proto文件后,运行
protoc重新生成Go代码
- 遵循
game/bag_equip.go中的现有模式
- ContainerType值必须唯一且连续
- ItemType值必须唯一且连续