Files
bl/logic/controller/fight_boss.go
昔念 3f059c71fa feat(pet): 更新宠物生成逻辑以支持异色属性
- 修改 `GenPetInfo` 函数签名,将 `shinyid` 参数调整为 `[]GlowFilter` 类型,并移动其位置
- 在多个控制器中更新调用 `GenPetInfo` 的地方,适配新的参数顺序和类型
- 引入 `GlowFilter` 结构用于描述异色效果,并在 `OgrePetInfo` 中添加相关字段
- 新增 `GenerateNormalizedColorMatrix` 工具函数用于生成颜色矩阵
- 调整宠物生成时对异色信息的初始化
2025-12-14 19:23:26 +08:00

232 lines
5.7 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, //野怪没特性
bm.Lv, nil)
mo.CatchTime = uint32(i)
if bm.Hp != 0 {
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, " ")
if idx == 0 {
continue
}
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, 1, nil)
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
}
if refpet.Ext != 0 {
refpet.Id = refpet.Ext
}
mo := model.GenPetInfo(
int(refpet.Id), -1,
-1,
0, //野怪没特性
int(refpet.Lv),
refpet.ShinyInfo)
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
}