2025-11-25 12:29:50 +08:00
|
|
|
|
package controller
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"blazing/common/data/xmlres"
|
|
|
|
|
|
"blazing/common/socket/errorcode"
|
|
|
|
|
|
"blazing/common/utils"
|
|
|
|
|
|
"blazing/logic/service/fight"
|
|
|
|
|
|
"blazing/logic/service/pet"
|
|
|
|
|
|
"blazing/logic/service/player"
|
2026-01-19 18:51:56 +08:00
|
|
|
|
"blazing/modules/player/model"
|
2025-11-25 12:29:50 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2026-04-05 12:45:00 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-23 10:46:17 +08:00
|
|
|
|
// SetPetSkill 设置宠物技能,消耗50赛尔豆
|
2026-04-05 07:24:36 +08:00
|
|
|
|
func (h Controller) SetPetSkill(data *ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) {
|
2025-12-23 10:46:17 +08:00
|
|
|
|
const setSkillCost = 50
|
|
|
|
|
|
|
2025-12-24 19:03:11 +08:00
|
|
|
|
_, currentPet, ok := c.FindPet(data.CatchTime)
|
2025-11-25 16:36:55 +08:00
|
|
|
|
if !ok {
|
2025-12-23 10:46:17 +08:00
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
2025-11-25 16:36:55 +08:00
|
|
|
|
}
|
2025-12-23 13:53:34 +00:00
|
|
|
|
|
2026-04-05 12:45:00 +08:00
|
|
|
|
canLearnSkillSet := make(map[uint32]struct{})
|
|
|
|
|
|
for _, skillID := range collectPetLearnableSkillList(currentPet) {
|
|
|
|
|
|
canLearnSkillSet[skillID] = struct{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
if _, exists := canLearnSkillSet[data.ReplaceSkill]; !exists {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
|
|
|
|
|
}
|
2025-12-23 10:46:17 +08:00
|
|
|
|
|
2026-04-05 12:45:00 +08:00
|
|
|
|
skillInfo, exists := xmlres.SkillMap[int(data.ReplaceSkill)]
|
|
|
|
|
|
if !exists {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
2025-11-25 16:36:55 +08:00
|
|
|
|
}
|
2026-04-05 12:45:00 +08:00
|
|
|
|
|
2026-04-08 01:28:55 +08:00
|
|
|
|
_, _, ok = utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
2025-11-26 15:25:10 +08:00
|
|
|
|
return item.ID == data.ReplaceSkill
|
|
|
|
|
|
})
|
|
|
|
|
|
if ok {
|
2025-12-23 10:46:17 +08:00
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
2025-11-26 15:25:10 +08:00
|
|
|
|
}
|
2025-12-23 10:46:17 +08:00
|
|
|
|
|
2026-04-08 01:28:55 +08:00
|
|
|
|
if data.HasSkill == 0 && len(currentPet.SkillList) >= 4 {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-05 12:45:00 +08:00
|
|
|
|
if data.HasSkill != 0 {
|
2026-04-08 01:28:55 +08:00
|
|
|
|
_, _, found := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
2026-04-05 12:45:00 +08:00
|
|
|
|
return item.ID == data.HasSkill
|
|
|
|
|
|
})
|
|
|
|
|
|
if !found {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSystemBusy
|
|
|
|
|
|
}
|
2026-04-08 01:28:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if !c.GetCoins(setSkillCost) {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSunDouInsufficient10016
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
c.Info.Coins -= setSkillCost
|
|
|
|
|
|
maxPP := uint32(skillInfo.MaxPP)
|
|
|
|
|
|
if data.HasSkill != 0 {
|
|
|
|
|
|
_, targetSkill, _ := utils.FindWithIndex(currentPet.SkillList, func(item model.SkillInfo) bool {
|
|
|
|
|
|
return item.ID == data.HasSkill
|
|
|
|
|
|
})
|
2025-12-24 19:03:11 +08:00
|
|
|
|
targetSkill.ID = data.ReplaceSkill
|
2026-04-05 12:45:00 +08:00
|
|
|
|
targetSkill.PP = maxPP
|
|
|
|
|
|
} else {
|
|
|
|
|
|
currentPet.SkillList = append(currentPet.SkillList, model.SkillInfo{
|
|
|
|
|
|
ID: data.ReplaceSkill,
|
|
|
|
|
|
PP: maxPP,
|
|
|
|
|
|
})
|
2025-11-25 12:29:50 +08:00
|
|
|
|
}
|
2025-12-23 10:46:17 +08:00
|
|
|
|
|
2025-11-25 12:29:50 +08:00
|
|
|
|
return &pet.ChangeSkillOutInfo{
|
|
|
|
|
|
CatchTime: data.CatchTime,
|
|
|
|
|
|
}, 0
|
|
|
|
|
|
}
|
2025-12-23 10:46:17 +08:00
|
|
|
|
|
2025-12-24 19:03:11 +08:00
|
|
|
|
// SortPetSkills 排序宠物技能,消耗50赛尔豆
|
2026-04-05 07:24:36 +08:00
|
|
|
|
func (h Controller) SortPetSkills(data *C2S_Skill_Sort, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
2025-12-23 10:46:17 +08:00
|
|
|
|
const skillSortCost = 50
|
|
|
|
|
|
|
2025-12-24 19:03:11 +08:00
|
|
|
|
_, currentPet, ok := c.FindPet(data.CapTm)
|
2026-04-05 12:45:00 +08:00
|
|
|
|
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
|
2025-11-25 12:29:50 +08:00
|
|
|
|
}
|
2026-04-05 12:45:00 +08:00
|
|
|
|
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]
|
2025-11-25 12:29:50 +08:00
|
|
|
|
}
|
2026-04-08 01:28:55 +08:00
|
|
|
|
|
|
|
|
|
|
if !c.GetCoins(skillSortCost) {
|
|
|
|
|
|
return nil, errorcode.ErrorCodes.ErrSunDouInsufficient10016
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
c.Info.Coins -= skillSortCost
|
2026-04-05 12:45:00 +08:00
|
|
|
|
currentPet.SkillList = newSkillList
|
2025-11-25 12:29:50 +08:00
|
|
|
|
|
|
|
|
|
|
return nil, 0
|
|
|
|
|
|
}
|