diff --git a/logic/controller/inbound_pet.go b/logic/controller/inbound_pet.go index 70e29e369..d1e48f593 100644 --- a/logic/controller/inbound_pet.go +++ b/logic/controller/inbound_pet.go @@ -80,6 +80,12 @@ type C2S_Skill_Sort struct { 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 { Head common.TomeeHeader `cmd:"2351" struc:"skip"` Mcatchtime uint32 `json:"mcatchtime" msgpack:"mcatchtime"` diff --git a/logic/controller/pet_skill.go b/logic/controller/pet_skill.go index 17d77526a..9c815644d 100644 --- a/logic/controller/pet_skill.go +++ b/logic/controller/pet_skill.go @@ -8,10 +8,63 @@ import ( "blazing/logic/service/pet" "blazing/logic/service/player" "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赛尔豆 func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) { const setSkillCost = 50 @@ -26,15 +79,20 @@ func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result if !ok { return nil, errorcode.ErrorCodes.ErrSystemBusy } - canleaernskill := currentPet.GetLevelRangeCanLearningSkills(1, currentPet.Level) - _, ok = lo.Find(canleaernskill, func(item uint32) bool { - return item == data.ReplaceSkill - }) - - if !ok { - return result, errorcode.ErrorCodes.ErrSystemBusy + canLearnSkillSet := make(map[uint32]struct{}) + for _, skillID := range collectPetLearnableSkillList(currentPet) { + canLearnSkillSet[skillID] = struct{}{} } + 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 { //已经存在技能 return item.ID == data.ReplaceSkill }) @@ -42,13 +100,25 @@ func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result return nil, errorcode.ErrorCodes.ErrSystemBusy } - // 查找要学习的技能并替换 - _, targetSkill, ok := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool { - return item.ID == data.HasSkill - }) - if ok { + maxPP := uint32(skillInfo.MaxPP) + if data.HasSkill != 0 { + // 查找要学习的技能并替换 + _, targetSkill, found := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool { + return item.ID == data.HasSkill + }) + if !found { + return nil, errorcode.ErrorCodes.ErrSystemBusy + } 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{ @@ -67,18 +137,45 @@ func (h Controller) SortPetSkills(data *C2S_Skill_Sort, c *player.Player) (resul c.Info.Coins -= skillSortCost _, currentPet, ok := c.FindPet(data.CapTm) - if ok { - var newSkillList []model.SkillInfo - 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 + if !ok { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists } + 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 } diff --git a/modules/player/controller/admin/pet.go b/modules/player/controller/admin/pet.go index 63c2959de..4448469db 100644 --- a/modules/player/controller/admin/pet.go +++ b/modules/player/controller/admin/pet.go @@ -95,13 +95,17 @@ func (c *PetBagController) Level(ctx context.Context, req *PetLevelReq) (res *co type PetStorageReq struct { g.Meta `path:"/storage" method:"POST"` IsVIP int `json:"is_vip"` + Free int `json:"free"` } func (c *PetBagController) Storage(ctx context.Context, req *PetStorageReq) (res *cool.BaseRes, err error) { admin := cool.GetAdmin(ctx) 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 } diff --git a/modules/player/service/pet.go b/modules/player/service/pet.go index a8be2974e..36799a608 100644 --- a/modules/player/service/pet.go +++ b/modules/player/service/pet.go @@ -58,9 +58,9 @@ func (s *PetService) PetInfo(flag int) []model.Pet { return tt } -func (s *PetService) StorageInfo(isVip int) []model.Pet { +func (s *PetService) StorageInfo(isVip int, free int) []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 } for i := range tt {