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

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

201 lines
4.9 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"
"strings"
"blazing/logic/service/fight"
"blazing/logic/service/fight/info"
"blazing/logic/service/player"
"blazing/modules/blazing/model"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"github.com/samber/lo"
)
func processMonID(bm string) string {
// 按空格分割字符串
monid := strings.Split(bm, " ")
// 过滤分割后可能的空字符串(如连续空格导致的空元素)
filtered := make([]string, 0, len(monid))
for _, m := range monid {
if m != "" {
filtered = append(filtered, m)
}
}
monid = filtered
var selected string
switch len(monid) {
case 0:
// 无元素时,可返回空或默认值(根据业务需求调整)
selected = ""
case 1:
// 长度为1时取第一个唯一的元素
selected = monid[0]
default:
// 长度大于1时随机选取一个
randomIdx := grand.Intn(len(monid))
selected = monid[randomIdx]
}
return selected
}
// 挑战地图boss
func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
var mo *model.PetInfo
moinfo := &model.PlayerInfo{}
var taskid int
var cancpet int
mdata, ok := xmlres.MonsterMap[int(c.Info.MapID)]
if !ok {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
if len(mdata.Bosses) == 0 {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
for _, bc := range mdata.Bosses {
if bc.Id == nil {
bc.Id = gconv.PtrInt(0)
}
if (bc.Id == nil && data.BossId == 0) || uint32(*bc.Id) == data.BossId { //打默认第一个boss
if bc.TaskID != nil {
taskid = *bc.TaskID
}
if bc.BossCatchable == 1 {
cancpet = xmlres.PetMAP[int(mo.ID)].CatchRate
}
for _, bm := range bc.BossMon {
mo = c.GenPetInfo(
gconv.Int(processMonID(bm.MonID)), 24, //24个体
-1,
0, //野怪没特性
0,
bm.Lv)
mo.Hp = uint32(bm.Hp)
mo.MaxHp = uint32(bm.Hp)
moinfo.PetList = append(moinfo.PetList, *mo)
}
moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName
break
}
}
c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
ai := player.NewAI_player(moinfo)
ai.CanCapture = cancpet
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId, uint32(foi.Reason)}, func(results *model.MilestoneEX) uint32 {
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
if results.CheakNoNumber(1) && taskid != 0 { //触发3次奖励
c.Info.TaskList[taskid-1] = 3
moinfo.PetList[0].Downgrade(1)
PetID := moinfo.PetList[0].ID
newm1 := model.GenPetInfo(int(PetID), -1, -1, 0, 0, 1)
c.Service.Pet.PetAdd(*newm1)
c.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{
BonusID: uint32(taskid),
PetID: PetID,
CaptureTm: newm1.CatchTime,
})
return 1
}
}
return 0
})
})
return nil, -1
}
// 战斗野怪
func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
refpet := c.OgreInfo.Data[data.Number]
if refpet.Id == 0 {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
mo := c.GenPetInfo(
int(refpet.Id), -1,
-1,
0, //野怪没特性
int(refpet.Shiny),
int(refpet.Lv))
moinfo := &model.PlayerInfo{}
moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName
moinfo.PetList = append(moinfo.PetList, *mo)
ai := player.NewAI_player(moinfo)
ai.CanCapture = handleNPCFightSpecial(mo.ID)
c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC //打野怪
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE //多人模式
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
c.Done.Exec(model.MilestoneMode.Moster, []uint32{c.Info.MapID, moinfo.PetList[0].ID, uint32(foi.Reason)}, func(results *model.MilestoneEX) uint32 {
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
exp := uint32(xmlres.PetMAP[int(mo.ID)].YieldingExp) * mo.Level / 7
items := &info.S2C_GET_BOSS_MONSTER{
//EV: 45,
EXP: exp * 2,
}
if refpet.Item != 0 {
items.ItemList = c.ItemAdd(model.ItemInfo{
ItemId: refpet.Item,
ItemCnt: uint32(grand.Intn(2) + 1),
})
}
evs := gconv.Uint32s(strings.Split(xmlres.PetMAP[int(mo.ID)].YieldingEV, " "))
items.EV = lo.Sum(evs)
c.Info.EVPool += lo.Sum(evs) //给予累计学习力
foi.Winpet.AddEV(evs)
c.Info.ExpPool += exp * 4
c.AddPetExp(foi.Winpet, uint32(exp)*2)
c.SendPackCmd(8004, items)
}
return 0
})
})
return nil, -1
}
func handleNPCFightSpecial(petid uint32) int {
npcPetID := int(petid)
petCfg, ok := xmlres.PetMAP[npcPetID]
if !ok {
// log.Error(context.Background(), "NPC宠物配置不存在", "petID", npcPetID)
return 0
}
catchRate := gconv.Int(petCfg.CatchRate)
return catchRate
}