```
feat(pet): 实现精灵融合功能并优化相关数据结构 - 新增精灵融合主服务和材料服务,支持根据主副精灵ID查询融合结果 - 调整融合接口参数结构,将物品字段统一为数组形式 - 修改融合材料模型字段类型,提升数据一致性 - 重构融合配置相关逻辑,移除旧融合配置模型及服务 - 增加特性随机选择逻辑,确保融合产物具备有效特性 - 添加材料合法性校验,防止非法材料参与融合 ```
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"blazing/logic/service/pet"
|
||||
"blazing/logic/service/player"
|
||||
"blazing/modules/blazing/model"
|
||||
"blazing/modules/blazing/service"
|
||||
)
|
||||
|
||||
func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result *pet.PetFusionInfo, err errorcode.ErrorCode) {
|
||||
@@ -34,10 +35,26 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result
|
||||
if xmlres.PetMAP[int(Auxpetinfo.ID)].FuseSub == 0 {
|
||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
||||
}
|
||||
r := model.GenPetInfo(1, -1, -1, -1, -1, 1)
|
||||
|
||||
///性格生成
|
||||
var natureId int32 = -1
|
||||
if Auxpetinfo.Nature == Mcatchpetinfo.Nature {
|
||||
natureId = int32(Auxpetinfo.Nature)
|
||||
}
|
||||
|
||||
resid := int(service.NewPetFusionService().Data(Mcatchpetinfo.ID, Auxpetinfo.ID))
|
||||
|
||||
if resid == 0 {
|
||||
//todo失败降低等级
|
||||
return &pet.PetFusionInfo{}, 0
|
||||
}
|
||||
|
||||
effect := int(service.NewPetFusionMaterialService().Data(data.Item1))
|
||||
r := model.GenPetInfo(resid, -1, int(natureId), effect, -1, 1)
|
||||
c.Service.Pet.PetAdd(*r)
|
||||
c.Pet_del(Auxpetinfo.CatchTime)
|
||||
c.Pet_del(Mcatchpetinfo.CatchTime)
|
||||
//todo材料扣除
|
||||
return &pet.PetFusionInfo{
|
||||
ObtainTime: r.CatchTime,
|
||||
SoulID: 1000017,
|
||||
|
||||
@@ -27,12 +27,10 @@ type C2S_PetFusion struct {
|
||||
Head common.TomeeHeader `cmd:"2351" struc:"skip"`
|
||||
Mcatchtime uint32 `json:"mcatchtime" msgpack:"mcatchtime"` // 主精灵的时间戳
|
||||
Auxcatchtime uint32 `json:"auxcatchtime" msgpack:"auxcatchtime"` // 副精灵的时间戳
|
||||
Item1 uint32 `json:"item1" msgpack:"item1"` // 物品序号1
|
||||
Item2 uint32 `json:"item2" msgpack:"item2"` // 物品序号2
|
||||
Item3 uint32 `json:"item3" msgpack:"item3"` // 物品序号3
|
||||
Item4 uint32 `json:"item4" msgpack:"item4"` // 物品序号4
|
||||
GoldItem1 uint32 `json:"gold_item1" msgpack:"gold_item1"` // 0代表未放置 金豆物品1(C#:gold_item1)
|
||||
GoldItem2 uint32 `json:"gold_item2" msgpack:"gold_item2"` // 0代表未放置 金豆物品2(C#:gold_item2)
|
||||
Item1 [4]uint32 `json:"item1" msgpack:"item1"` // 物品序号1
|
||||
|
||||
GoldItem1 uint32 `json:"gold_item1" msgpack:"gold_item1"` // 0代表未放置 金豆物品1(C#:gold_item1)
|
||||
GoldItem2 uint32 `json:"gold_item2" msgpack:"gold_item2"` // 0代表未放置 金豆物品2(C#:gold_item2)
|
||||
}
|
||||
|
||||
// PetFusionInfo 精灵融合结果详情(后端回包嵌套结构体)
|
||||
|
||||
@@ -12,13 +12,13 @@ const (
|
||||
type PetFusion struct {
|
||||
*cool.Model // 嵌入通用Model(ID/创建时间/更新时间等)
|
||||
|
||||
MainPetID int32 `gorm:"not null;comment:'主宠物ID(如:尼尔)'" json:"main_pet_id"`
|
||||
SubPetID int32 `gorm:"not null;comment:'副宠物ID(如:闪皮)'" json:"sub_pet_id"`
|
||||
Probability float32 `gorm:"not null;comment:'融合成功率(百分比,如80代表80%)'" json:"probability"`
|
||||
ResultPetID int32 `gorm:"not null;comment:'融合结果宠物ID(如:卡鲁、闪尼)'" json:"result_pet_id"`
|
||||
Remark string `gorm:"type:varchar(255);default:'';comment:'融合配方备注(如:尼尔+闪皮=闪尼)'" json:"remark"`
|
||||
IsEnable int32 `gorm:"not null;default:1;comment:'是否启用(1:启用,0:禁用)'" json:"is_enable"`
|
||||
IsDefault int32 `gorm:"not null;default:0;comment:'是否默认配方(1:默认配方,0:非默认;所有配方不匹配时随机选默认配方)'" json:"is_default"`
|
||||
MainPetID int32 `gorm:"not null;comment:'主宠物ID(如:尼尔)'" json:"main_pet_id"`
|
||||
SubPetID int32 `gorm:"not null;comment:'副宠物ID(如:闪皮)'" json:"sub_pet_id"`
|
||||
Probability int32 `gorm:"not null;comment:'融合成功率(百分比,如80代表80%)'" json:"probability"`
|
||||
ResultPetID int32 `gorm:"not null;comment:'融合结果宠物ID(如:卡鲁、闪尼)'" json:"result_pet_id"`
|
||||
Remark string `gorm:"type:varchar(255);default:'';comment:'融合配方备注(如:尼尔+闪皮=闪尼)'" json:"remark"`
|
||||
IsEnable int32 `gorm:"not null;default:1;comment:'是否启用(1:启用,0:禁用)'" json:"is_enable"`
|
||||
IsDefault int32 `gorm:"not null;default:0;comment:'是否默认配方(1:默认配方,0:非默认;所有配方不匹配时随机选默认配方)'" json:"is_default"`
|
||||
|
||||
// 关联:一个配方对应多个材料(gorm 一对多关联,查询时可预加载)
|
||||
//Materials []*PetFusionMaterial `gorm:"foreignKey:PetFusionID;references:ID" json:"materials,omitempty"`
|
||||
|
||||
@@ -11,16 +11,16 @@ type PetFusionMaterial struct {
|
||||
*cool.Model // 嵌入通用Model(ID/创建时间/更新时间等)
|
||||
|
||||
// 4个材料ID(对应XML ItemGroup的Idx=1-4,无材料填0)
|
||||
Material1 int64 `gorm:"not null;comment:'材料1ID(如400030)'" json:"material1"`
|
||||
Material2 int64 `gorm:"not null;comment:'材料2ID(如400030)'" json:"material2"`
|
||||
Material3 int64 `gorm:"not null;comment:'材料3ID(如400028)'" json:"material3"`
|
||||
Material4 int64 `gorm:"not null;comment:'材料4ID(如400030)'" json:"material4"`
|
||||
Material1 uint32 `gorm:"not null;comment:'材料1ID(如400030)'" json:"material1"`
|
||||
Material2 uint32 `gorm:"not null;comment:'材料2ID(如400030)'" json:"material2"`
|
||||
Material3 uint32 `gorm:"not null;comment:'材料3ID(如400028)'" json:"material3"`
|
||||
Material4 uint32 `gorm:"not null;comment:'材料4ID(如400030)'" json:"material4"`
|
||||
|
||||
// 4个特性ID(对应XML MaterialGroup的特性索引,4-4对应)
|
||||
Trait1Idx int32 `gorm:"not null;comment:'特性1索引(如1008)'" json:"trait1_idx"`
|
||||
Trait2Idx int32 `gorm:"not null;comment:'特性2索引(如1018)'" json:"trait2_idx"`
|
||||
Trait3Idx int32 `gorm:"not null;comment:'特性3索引(如1023)'" json:"trait3_idx"`
|
||||
Trait4Idx int32 `gorm:"not null;comment:'特性4索引(如1031)'" json:"trait4_idx"`
|
||||
Trait1Idx uint32 `gorm:"not null;comment:'特性1索引(如1008)'" json:"trait1_idx"`
|
||||
Trait2Idx uint32 `gorm:"not null;comment:'特性2索引(如1018)'" json:"trait2_idx"`
|
||||
Trait3Idx uint32 `gorm:"not null;comment:'特性3索引(如1023)'" json:"trait3_idx"`
|
||||
Trait4Idx uint32 `gorm:"not null;comment:'特性4索引(如1031)'" json:"trait4_idx"`
|
||||
|
||||
IsEnable int32 `gorm:"not null;default:1;comment:'是否启用该组合(1:启用,0:禁用)'" json:"is_enable"`
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
)
|
||||
|
||||
const (
|
||||
TableNamePetFusionConfig = "pet_fusion_config" // 宠物融合配置表(尼尔/闪皮融合规则)
|
||||
)
|
||||
|
||||
// PetFusionConfig 宠物融合配置模型(对应尼尔/闪皮融合卡鲁/闪尼的规则)
|
||||
type PetFusionConfig struct {
|
||||
*cool.Model
|
||||
|
||||
MainPetID int32 `gorm:"not null;comment:'主精灵ID(尼尔)'" json:"main_pet_id"`
|
||||
AuxPetID int32 `gorm:"not null;comment:'副精灵ID(闪皮)'" json:"aux_pet_id"`
|
||||
FusionMaterial1 int32 `gorm:"not null;default:0;comment:'融合材料1编号'" json:"fusion_material1"`
|
||||
FusionMaterial2 int32 `gorm:"not null;default:0;comment:'融合材料2编号'" json:"fusion_material2"`
|
||||
FusionMaterial3 int32 `gorm:"not null;default:0;comment:'融合材料3编号'" json:"fusion_material3"`
|
||||
FusionMaterial4 int32 `gorm:"not null;default:0;comment:'融合材料4编号'" json:"fusion_material4"`
|
||||
FusionProbability float64 `gorm:"not null;comment:'融合成功概率(百分比,0-100)'" json:"fusion_probability"`
|
||||
ResultPetID int32 `gorm:"not null;comment:'融合结果精灵ID(卡鲁/闪尼)'" json:"result_pet_id"`
|
||||
}
|
||||
|
||||
// TableName PetFusionConfig's table name
|
||||
func (*PetFusionConfig) TableName() string {
|
||||
return TableNamePetFusionConfig
|
||||
}
|
||||
|
||||
// GroupName PetFusionConfig's table group
|
||||
func (*PetFusionConfig) GroupName() string {
|
||||
return "default" // 与原模型保持一致的分组名
|
||||
}
|
||||
|
||||
// NewPetFusionConfig create a new PetFusionConfig
|
||||
func NewPetFusionConfig() *PetFusionConfig {
|
||||
return &PetFusionConfig{
|
||||
Model: cool.NewModel(),
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化表结构(与原模型保持一致的初始化方式)
|
||||
func init() {
|
||||
cool.CreateTable(&PetFusionConfig{})
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/common/utils"
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
dictmodel "blazing/modules/dict/model"
|
||||
"blazing/modules/dict/service"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
// PetFusionMaterialService 宠物融合材料子表Service(对应pet_fusion_material表)
|
||||
@@ -18,3 +25,60 @@ func NewPetFusionMaterialService() *PetFusionMaterialService {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 获取融合材料的特性,返回两个值,一个是指定的特性,另一个是如果配方没找到的情况下,默认的配置
|
||||
func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 {
|
||||
|
||||
fusion, _ := service.NewDictInfoService().DataOne("fusion")
|
||||
|
||||
fusions := utils.ToMap(fusion, func(t dictmodel.DictInfo) uint32 {
|
||||
|
||||
return gconv.Uint32(t.Remark)
|
||||
})
|
||||
for _, v := range Material1 {
|
||||
_, ok := fusions[v]
|
||||
if !ok {
|
||||
//todo使用了非法材料
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
||||
m := cool.DBM(s.Model)
|
||||
|
||||
var effect model.PetFusionMaterial //一个特性应该是唯一的,但是我们要获取默认随机特性
|
||||
condition := g.Map{
|
||||
"material1": fusions[Material1[0]].ID,
|
||||
"material2": fusions[Material1[1]].ID,
|
||||
"material3": fusions[Material1[2]].ID,
|
||||
"material4": fusions[Material1[3]].ID,
|
||||
"is_enable": 1,
|
||||
}
|
||||
m.Where(condition).Scan(&effect)
|
||||
//这时候有可能效果是空的,那么这时候就再次查询默认的特性,保证每次必会生成一个数据库有的特性
|
||||
//也许这个时候的特性配方就是随机从数据库中查找一个特性
|
||||
|
||||
effect2, _ := service.NewDictInfoService().DataOne("effect")
|
||||
effect2s := utils.ToMap(effect2, func(t dictmodel.DictInfo) uint32 {
|
||||
|
||||
return gconv.Uint32(t.ID)
|
||||
})
|
||||
|
||||
if effect.Trait1Idx != 0 {
|
||||
r := grand.Intn(3)
|
||||
switch r {
|
||||
case 0:
|
||||
return gconv.Uint32(effect2s[effect.Trait1Idx].Remark)
|
||||
case 1:
|
||||
return gconv.Uint32(effect2s[effect.Trait2Idx].Remark)
|
||||
case 2:
|
||||
return gconv.Uint32(effect2s[effect.Trait3Idx].Remark)
|
||||
case 3:
|
||||
return gconv.Uint32(effect2s[effect.Trait4Idx].Remark)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
r := grand.Intn(len(effect2) - 1)
|
||||
return gconv.Uint32(effect2[r].Remark)
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package service
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
// PetFusionService 宠物融合配方主表Service(对应pet_fusion表)
|
||||
@@ -15,6 +18,42 @@ func NewPetFusionService() *PetFusionService {
|
||||
return &PetFusionService{
|
||||
&cool.Service{
|
||||
Model: model.NewPetFusion(), // 绑定PetFusion模型
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//获取主副精灵融合的id,如果不存在,那就给一个保底的id
|
||||
|
||||
func (s *PetFusionService) Data(p1, p2 uint32) uint32 {
|
||||
m := cool.DBM(s.Model)
|
||||
|
||||
var pet []model.PetFusion //一个特性应该是唯一的,但是我们要获取默认随机特性
|
||||
condition := g.Map{
|
||||
"main_pet_id": p1,
|
||||
"sub_pet_id": p2,
|
||||
"is_enable": 1,
|
||||
// "hits between ? and ?" : g.Slice{1, 10},
|
||||
// "exp > 0" : nil,
|
||||
// "category" : g.Slice{100, 200},
|
||||
}
|
||||
m.Where(condition).Scan(&pet)
|
||||
|
||||
for _, v := range pet {
|
||||
|
||||
rr := grand.Intn(100)
|
||||
if rr < int(v.Probability) {
|
||||
return uint32(v.ResultPetID)
|
||||
}
|
||||
}
|
||||
|
||||
var pets []model.PetFusion
|
||||
|
||||
m.Where("is_enable", 1).Where("is_default", 1).Scan(&pets)
|
||||
if len(pets) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
return uint32(pets[grand.Intn(len(pets)-1)].ID)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type FusionService struct {
|
||||
*cool.Service
|
||||
}
|
||||
|
||||
func NewFusionService() *FusionService {
|
||||
return &FusionService{
|
||||
&cool.Service{
|
||||
Model: model.NewPetFusionConfig(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,26 @@ func (s *DictInfoService) Data(ctx context.Context, types []string) (data interf
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *DictInfoService) DataOne(types string) (data []model.DictInfo, err error) {
|
||||
var (
|
||||
dictInfoModel = model.NewDictInfo()
|
||||
dictTypeModel = model.NewDictType()
|
||||
)
|
||||
// 如果typeData为空, 则返回空
|
||||
var ty *model.DictType
|
||||
mType := cool.DBM(dictTypeModel)
|
||||
mType.Where("key in (?)", types).Scan(&ty)
|
||||
|
||||
// 如果typeData为空, 则返回空
|
||||
if ty == nil {
|
||||
return []model.DictInfo{}, nil
|
||||
}
|
||||
m := cool.DBM(dictInfoModel)
|
||||
var ress []model.DictInfo
|
||||
m.Where("typeId", ty.ID).Scan(&ress)
|
||||
|
||||
return ress, nil
|
||||
}
|
||||
|
||||
// ModifyAfter 修改后
|
||||
func (s *DictInfoService) ModifyAfter(ctx context.Context, method string, param map[string]interface{}) (err error) {
|
||||
|
||||
Reference in New Issue
Block a user