Files
bl/logic/controller/fight_boss.go
昔念 36ca75aa03 ```
refactor(item): 优化物品添加逻辑并移除冗余代码

- 修改 ItemAdd 方法签名,从可变参数改为两个独立参数 itemId 和 itemCnt
- 移除了对 model.ItemInfo 的依赖,简化调用方式
- 更新所有调用 ItemAdd 的地方以适配新接口
- 删除未使用的 imports 和注释掉的旧配置加载逻辑
- 修复购买物品时金币扣除与物品发放的一致性问题
- 增加玩家操作消耗塞尔豆的扣费逻辑(如宠物治疗、技能设置等)

此变更提升了代码简洁性和一致性,并增强了业务逻辑的准确性。
```
2025-12-08 21:11:12 +08:00

223 lines
5.6 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"
"blazing/modules/blazing/service"
"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) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrSystemError
}
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
}
for i, bm := range bc.BossMon {
mo = model.GenPetInfo(
gconv.Int(processMonID(bm.MonID)), 24, //24个体
-1,
0, //野怪没特性
0,
bm.Lv)
mo.CatchTime = uint32(i)
mo.Hp = uint32(bm.Hp)
mo.MaxHp = uint32(bm.Hp)
for _, v := range strings.Split(bm.NewSeIdxs, " ") {
idx := gconv.Uint16(v)
// eff := xmlres.EffectMAP[int(idx)]
// args := strings.Split(eff.Args, " ")
EID, args := service.Effects.Args(uint32(idx))
mo.EffectInfo = append(mo.EffectInfo, model.PetEffectInfo{
Idx: idx,
EID: gconv.Uint16(EID),
Args: gconv.Ints(args),
})
}
moinfo.PetList = append(moinfo.PetList, *mo)
}
if bc.BossCatchable == 1 {
cancpet = xmlres.PetMAP[int(mo.ID)].CatchRate
}
moinfo.Nick = bc.Name //xmlres.PetMAP[int(mo.ID)].DefName
break
}
}
if len(moinfo.PetList) == 0 {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC
c.Fightinfo.Mode = info.BattleMode.MULTI_MODE
ai := player.NewAI_player(moinfo)
ai.CanCapture = cancpet
ai.Prop[0] = 2
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
if taskid != 0 {
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
if c.Info.GetTask(taskid) == model.Unaccepted {
c.Info.SetTask(taskid, model.Completed) //设置完成任务
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,
})
}
}
}
c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId, uint32(foi.Reason)}, nil)
})
return nil, -1
}
// 战斗野怪
func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrSystemError
}
refpet := c.OgreInfo.Data[data.Number]
if refpet.Id == 0 {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
mo := model.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)}, nil)
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
if !c.CanGetExp() {
return
}
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 {
c.ItemAdd(refpet.Item, uint32(grand.Intn(2)+1))
items.ItemList = append(items.ItemList, 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) - 1
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 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
}