```
feat(pet): 新增精灵可学习技能查询功能 新增 GetPetLearnableSkills 接口用于查询当前精灵可学习技能(包含等级技能和额外技能ExtSKill), 优化 SetPetSkill 和 SortPetSkills 方法中的技能处理逻辑,提升技能管理和排序的准确性。 同时修复了宠物存储信息查询时缺少参数验证的问题,在管理后台接口中增加 free 参数支持。 BREAKING CHANGE: 管理后台
This commit is contained in:
@@ -80,6 +80,12 @@ type C2S_Skill_Sort struct {
|
|||||||
Skill [4]uint32 `json:"skill_1"`
|
Skill [4]uint32 `json:"skill_1"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPetLearnableSkillsInboundInfo 查询当前精灵可学习技能(含额外技能ExtSKill)
|
||||||
|
type GetPetLearnableSkillsInboundInfo struct {
|
||||||
|
Head common.TomeeHeader `cmd:"52312" struc:"skip"`
|
||||||
|
CatchTime uint32 `json:"catchTime"`
|
||||||
|
}
|
||||||
|
|
||||||
type C2S_PetFusion struct {
|
type C2S_PetFusion struct {
|
||||||
Head common.TomeeHeader `cmd:"2351" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2351" struc:"skip"`
|
||||||
Mcatchtime uint32 `json:"mcatchtime" msgpack:"mcatchtime"`
|
Mcatchtime uint32 `json:"mcatchtime" msgpack:"mcatchtime"`
|
||||||
|
|||||||
@@ -8,10 +8,63 @@ import (
|
|||||||
"blazing/logic/service/pet"
|
"blazing/logic/service/pet"
|
||||||
"blazing/logic/service/player"
|
"blazing/logic/service/player"
|
||||||
"blazing/modules/player/model"
|
"blazing/modules/player/model"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GetPetLearnableSkillsOutboundInfo struct {
|
||||||
|
SkillListLen uint32 `struc:"sizeof=SkillList"`
|
||||||
|
SkillList []uint32 `json:"skillList"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectPetLearnableSkillList(currentPet *model.PetInfo) []uint32 {
|
||||||
|
skillSet := make(map[uint32]struct{})
|
||||||
|
skills := make([]uint32, 0)
|
||||||
|
|
||||||
|
appendSkill := func(skillID uint32) {
|
||||||
|
if skillID == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, exists := skillSet[skillID]; exists {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
skillSet[skillID] = struct{}{}
|
||||||
|
skills = append(skills, skillID)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, skillID := range currentPet.GetLevelRangeCanLearningSkills(1, currentPet.Level) {
|
||||||
|
appendSkill(skillID)
|
||||||
|
}
|
||||||
|
for _, skillID := range currentPet.ExtSKill {
|
||||||
|
appendSkill(skillID)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, skill := range currentPet.SkillList {
|
||||||
|
delete(skillSet, skill.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]uint32, 0, len(skillSet))
|
||||||
|
for _, skillID := range skills {
|
||||||
|
if _, exists := skillSet[skillID]; exists {
|
||||||
|
result = append(result, skillID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPetLearnableSkills 查询当前精灵可学习技能(等级技能 + 额外技能ExtSKill)
|
||||||
|
func (h Controller) GetPetLearnableSkills(
|
||||||
|
data *GetPetLearnableSkillsInboundInfo,
|
||||||
|
c *player.Player,
|
||||||
|
) (result *GetPetLearnableSkillsOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
_, currentPet, ok := c.FindPet(data.CatchTime)
|
||||||
|
if !ok {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetPetLearnableSkillsOutboundInfo{
|
||||||
|
SkillList: collectPetLearnableSkillList(currentPet),
|
||||||
|
}, 0
|
||||||
|
}
|
||||||
|
|
||||||
// SetPetSkill 设置宠物技能,消耗50赛尔豆
|
// SetPetSkill 设置宠物技能,消耗50赛尔豆
|
||||||
func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) {
|
func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) {
|
||||||
const setSkillCost = 50
|
const setSkillCost = 50
|
||||||
@@ -26,15 +79,20 @@ func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
}
|
}
|
||||||
canleaernskill := currentPet.GetLevelRangeCanLearningSkills(1, currentPet.Level)
|
|
||||||
|
|
||||||
_, ok = lo.Find(canleaernskill, func(item uint32) bool {
|
canLearnSkillSet := make(map[uint32]struct{})
|
||||||
return item == data.ReplaceSkill
|
for _, skillID := range collectPetLearnableSkillList(currentPet) {
|
||||||
})
|
canLearnSkillSet[skillID] = struct{}{}
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return result, errorcode.ErrorCodes.ErrSystemBusy
|
|
||||||
}
|
}
|
||||||
|
if _, exists := canLearnSkillSet[data.ReplaceSkill]; !exists {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
|
}
|
||||||
|
|
||||||
|
skillInfo, exists := xmlres.SkillMap[int(data.ReplaceSkill)]
|
||||||
|
if !exists {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
|
}
|
||||||
|
|
||||||
_, _, ok = utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool { //已经存在技能
|
_, _, ok = utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool { //已经存在技能
|
||||||
return item.ID == data.ReplaceSkill
|
return item.ID == data.ReplaceSkill
|
||||||
})
|
})
|
||||||
@@ -42,13 +100,25 @@ func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result
|
|||||||
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找要学习的技能并替换
|
maxPP := uint32(skillInfo.MaxPP)
|
||||||
_, targetSkill, ok := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
if data.HasSkill != 0 {
|
||||||
return item.ID == data.HasSkill
|
// 查找要学习的技能并替换
|
||||||
})
|
_, targetSkill, found := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
||||||
if ok {
|
return item.ID == data.HasSkill
|
||||||
|
})
|
||||||
|
if !found {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
|
}
|
||||||
targetSkill.ID = data.ReplaceSkill
|
targetSkill.ID = data.ReplaceSkill
|
||||||
targetSkill.PP = uint32(xmlres.SkillMap[int(targetSkill.ID)].MaxPP)
|
targetSkill.PP = maxPP
|
||||||
|
} else {
|
||||||
|
if len(currentPet.SkillList) >= 4 {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
||||||
|
}
|
||||||
|
currentPet.SkillList = append(currentPet.SkillList, model.SkillInfo{
|
||||||
|
ID: data.ReplaceSkill,
|
||||||
|
PP: maxPP,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pet.ChangeSkillOutInfo{
|
return &pet.ChangeSkillOutInfo{
|
||||||
@@ -67,18 +137,45 @@ func (h Controller) SortPetSkills(data *C2S_Skill_Sort, c *player.Player) (resul
|
|||||||
c.Info.Coins -= skillSortCost
|
c.Info.Coins -= skillSortCost
|
||||||
|
|
||||||
_, currentPet, ok := c.FindPet(data.CapTm)
|
_, currentPet, ok := c.FindPet(data.CapTm)
|
||||||
if ok {
|
if !ok {
|
||||||
var newSkillList []model.SkillInfo
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
||||||
for _, skillID := range data.Skill {
|
|
||||||
_, skill, found := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
|
||||||
return item.ID == skillID
|
|
||||||
})
|
|
||||||
if found {
|
|
||||||
newSkillList = append(newSkillList, *skill)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentPet.SkillList = newSkillList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usedSkillSet := make(map[uint32]struct{})
|
||||||
|
newSkillList := make([]model.SkillInfo, 0, 4)
|
||||||
|
|
||||||
|
for _, skillID := range data.Skill {
|
||||||
|
if skillID == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, used := usedSkillSet[skillID]; used {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, skill, found := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
||||||
|
return item.ID == skillID
|
||||||
|
})
|
||||||
|
if !found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newSkillList = append(newSkillList, *skill)
|
||||||
|
usedSkillSet[skillID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, skill := range currentPet.SkillList {
|
||||||
|
if skill.ID == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, used := usedSkillSet[skill.ID]; used {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newSkillList = append(newSkillList, skill)
|
||||||
|
usedSkillSet[skill.ID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newSkillList) > 4 {
|
||||||
|
newSkillList = newSkillList[:4]
|
||||||
|
}
|
||||||
|
currentPet.SkillList = newSkillList
|
||||||
|
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,13 +95,17 @@ func (c *PetBagController) Level(ctx context.Context, req *PetLevelReq) (res *co
|
|||||||
type PetStorageReq struct {
|
type PetStorageReq struct {
|
||||||
g.Meta `path:"/storage" method:"POST"`
|
g.Meta `path:"/storage" method:"POST"`
|
||||||
IsVIP int `json:"is_vip"`
|
IsVIP int `json:"is_vip"`
|
||||||
|
Free int `json:"free"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PetBagController) Storage(ctx context.Context, req *PetStorageReq) (res *cool.BaseRes, err error) {
|
func (c *PetBagController) Storage(ctx context.Context, req *PetStorageReq) (res *cool.BaseRes, err error) {
|
||||||
admin := cool.GetAdmin(ctx)
|
admin := cool.GetAdmin(ctx)
|
||||||
|
|
||||||
res = &cool.BaseRes{}
|
res = &cool.BaseRes{}
|
||||||
res.Data = service.NewPetService(uint32(admin.UserId)).StorageInfo(req.IsVIP)
|
if req.Free < 0 || req.Free > 2 {
|
||||||
|
req.Free = 0
|
||||||
|
}
|
||||||
|
res.Data = service.NewPetService(uint32(admin.UserId)).StorageInfo(req.IsVIP, req.Free)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ func (s *PetService) PetInfo(flag int) []model.Pet {
|
|||||||
return tt
|
return tt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PetService) StorageInfo(isVip int) []model.Pet {
|
func (s *PetService) StorageInfo(isVip int, free int) []model.Pet {
|
||||||
var tt []model.Pet
|
var tt []model.Pet
|
||||||
if err := s.dbm_fix(s.Model).Where("free", 0).Where("is_vip", isVip).Scan(&tt); err != nil {
|
if err := s.dbm_fix(s.Model).Where("free", free).Where("is_vip", isVip).Scan(&tt); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for i := range tt {
|
for i := range tt {
|
||||||
|
|||||||
Reference in New Issue
Block a user