Files
bl/logic/controller/pet.go
昔念 28e0addda0 ```
feat(pet): 添加学习力分配功能并优化相关逻辑

- 新增 PetEVdiy 接口用于自定义宠物学习力分配
- 限制单次学习力分配不超过510,单项不超过255
- 学习力池 EVPool 字段添加到 PlayerInfo 结构体
- 使用 github.com/samber/lo 简化数组求和操作
- 更新 fight_boss 逻辑以正确处理 BOSS 战斗后经验与学习力奖励发放
- 调整任务列表中部分
2025-11-25 00:55:10 +08:00

290 lines
7.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
"blazing/modules/blazing/model"
"github.com/jinzhu/copier"
"github.com/samber/lo"
)
// 获取精灵信息
func (h *Controller) GetPetInfo(
data *pet.InInfo,
c *player.Player) (result *pet.OutInfo,
err errorcode.ErrorCode) { //这个时候player应该是空的
_, tet, ok := c.FindPet(data.CatchTime)
if ok {
result = &pet.OutInfo{
PetInfo: *tet,
}
return result, 0
} else {
result = &pet.OutInfo{
PetInfo: c.Service.Pet.PetInfo_One(data.CatchTime).Data,
}
}
return result, 0
}
// 获取仓库列表
func (h *Controller) GetPetList(
data *pet.GetPetListInboundEmpty,
c *player.Player) (result *pet.GetPetListOutboundInfo,
err errorcode.ErrorCode) { //这个时候player应该是空的
result = &pet.GetPetListOutboundInfo{}
tt := c.Service.Pet.PetInfo(0) //获得未放生的精灵
result.ShortInfoList = make([]pet.PetShortInfo, len(tt))
for i, v := range tt {
copier.Copy(&result.ShortInfoList[i], &v.Data)
}
return result, 0
}
// 获取放生列表
func (h *Controller) PET_ROWEI_LIST(
data *pet.GetPetListFreeInboundEmpty,
c *player.Player) (result *pet.GetPetListOutboundInfo,
err errorcode.ErrorCode) { //这个时候player应该是空的
result = &pet.GetPetListOutboundInfo{}
tt := c.Service.Pet.PetInfo(1) //获得未放生的精灵
result.ShortInfoList = make([]pet.PetShortInfo, len(tt))
for i, v := range tt {
copier.Copy(&result.ShortInfoList[i], &v.Data)
}
return result, 0
}
// 放生包
func (h *Controller) PET_ROWEI(
data *pet.PET_ROWEI, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
c.Service.Pet.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) {
_, _, ok := c.FindPet(data.CatchTime)
//如果背包没找到,再放入背包
if !ok && t.CatchTime != 0 && xmlres.PetMAP[int(data.ID)].FreeForbidden == 0 {
t.Free = 1
}
})
return nil, 0
}
// 领回包
func (h *Controller) PET_RETRIEVE(
data *pet.PET_RETRIEVE, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
c.Service.Pet.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) {
_, _, ok := c.FindPet(data.CatchTime)
//如果背包没找到,再放入背包
if !ok && t.CatchTime != 0 {
t.Free = 0
}
})
return nil, 0
}
// 精灵背包仓库切换
func (h *Controller) PetRelease(
data *pet.PetReleaseInboundInfo,
c *player.Player) (
result *pet.PetReleaseOutboundInfo,
err errorcode.ErrorCode) { //这个时候player应该是空的
//放入背包=数据库置1+添加到背包+pet release发包 仓库=数据库置0+移除背包 设置首发等于取到首发精灵后重新排序
//这里只修改,因为添加和移除背包在宠物获取时已经做了
result = &pet.PetReleaseOutboundInfo{}
result.Flag = uint32(data.Flag)
//擂台住不能换精灵
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotSwitch
}
switch data.Flag {
case 0:
index, _, ok := c.FindPet(data.CatchTime)
if ok {
c.Info.PetList = append(c.Info.PetList[:index], c.Info.PetList[index+1:]...)
}
// break // 只移除第一个匹配值,若需移除所有,可省略 break 继续循环
case 1:
if len(c.Info.PetList) < 6 {
//todo 背包
c.Service.Pet.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) {
_, _, ok := c.FindPet(data.CatchTime)
//如果背包没找到,再放入背包
if !ok && t.CatchTime != 0 {
//t.InBag = 1
c.Info.PetList = append(c.Info.PetList, t.Data)
result.PetInfo = t.Data
}
})
}
}
if len(c.Info.PetList) > 0 {
result.FirstPetTime = c.Info.PetList[0].CatchTime //设置首发
}
return result, 0
}
// 精灵展示
func (h *Controller) PlayerShowPet(
data *pet.PetShowInboundInfo, c *player.Player) (result *pet.PetShowOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
result = &pet.PetShowOutboundInfo{}
_, onpet, ok := c.FindPet(data.CatchTime)
if ok {
copier.Copy(&result, onpet)
result.Flag = data.Flag
result.UserID = data.Head.UserID
c.GetSpace().Broadcast(c, data.Head.CMD, result)
}
return
}
// 单体治疗
func (h *Controller) PetOneCure(
data *pet.PetOneCureInboundInfo, c *player.Player) (result *pet.PetOneCureOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotHeal
}
_, onpet, ok := c.FindPet(data.CatchTime)
if ok {
onpet.Cure()
}
return &pet.PetOneCureOutboundInfo{
CatchTime: data.CatchTime,
}, 0
}
// 精灵首发
func (h *Controller) PetFirst(
data *pet.PetDefaultInboundInfo, c *player.Player) (result *pet.PetDefaultOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
//擂台住不能换精灵
if c.GetSpace().Owner.UserID == c.Info.UserID {
return result, errorcode.ErrorCodes.ErrChampionCannotSwitch
}
result = &pet.PetDefaultOutboundInfo{}
index, _, ok := c.FindPet(data.CatchTime)
if ok && index != 0 {
c.Info.PetList[index], c.Info.PetList[0] = c.Info.PetList[0], c.Info.PetList[index]
result.IsDefault = 1
}
return result, 0
}
// FindWithIndex 遍历slice找到第一个满足条件的元素
// 返回:索引、元素指针、是否找到
func (h Controller) SetPetExp(data *pet.PetSetExpInboundInfo, c *player.Player) (result *pet.PetSetExpOutboundInfo, err errorcode.ErrorCode) {
_, onpet, ok := c.FindPet(data.CatchTime)
if ok {
c.AddPetExp(onpet, data.Exp)
}
return &pet.PetSetExpOutboundInfo{
Exp: c.Info.ExpPool,
}, 0
}
func (h Controller) SetPetSkill(data *pet.ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) {
_, onpet, ok := c.FindPet(data.CatchTime)
if ok {
_, HasSkill, ok := utils.FindWithIndex(onpet.SkillList, func(item model.SkillInfo) bool { //已经存在技能
return item.ID == data.ReplaceSkill
})
if !ok {
HasSkill.ID = data.ReplaceSkill
HasSkill.PP = uint32(xmlres.SkillMap[int(HasSkill.ID)].MaxPP)
}
}
return &pet.ChangeSkillOutInfo{
CatchTime: data.CatchTime,
}, 0
}
func (h Controller) PetBargeList(data *pet.PetBargeListInboundInfo, c *player.Player) (result *pet.PetBargeListOutboundInfo, err errorcode.ErrorCode) {
return &pet.PetBargeListOutboundInfo{
PetBargeList: make([]pet.PetBargeListInfo, 0),
}, 0
}
func (h Controller) PetEVdiy(data *pet.PetEV, c *player.Player) (result *pet.S2C_50001, err errorcode.ErrorCode) {
_, onpet, ok := c.FindPet(data.CacthTime)
if !ok {
return nil, errorcode.ErrorCodes.Err10401
}
//分配超过510的数据
if lo.Sum(data.EVs[:]) > 510 {
return nil, errorcode.ErrorCodes.Err10401
}
for _, v := range data.EVs {
//分配超过255的数据
if v > 255 {
return nil, errorcode.ErrorCodes.Err10401
}
}
if lo.Sum(data.EVs[:]) < lo.Sum(onpet.Ev[:]) {
return nil, errorcode.ErrorCodes.Err10401
}
USEEV1 := lo.Sum(data.EVs[:]) - lo.Sum(onpet.Ev[:])
//加的比池子还多
if USEEV1 > c.Info.EVPool {
return nil, errorcode.ErrorCodes.Err10401
}
onpet.Ev = data.EVs
c.Info.EVPool -= USEEV1
result = &pet.S2C_50001{}
result.UseEV = USEEV1
return result, 0
}