Files
bl/logic/service/fight/input/input.go
昔念 e54d4bacaa ```
feat(fight): 增加战斗模式枚举并重构战斗逻辑判断

- 引入完整的 BattleMode 枚举定义,替代原有的 BattleStatus,明确区分各类战斗场景
- 在多个控制器中替换对旧 Status 字段的依赖,统一使用 Mode 判断战斗状态
- 修复部分函数调用前未检查 FightC 是否为空的问题,增加 ErrBattleEnded 错误返回
- 调整
2025-11-21 02:40:27 +08:00

219 lines
5.8 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 input
import (
"blazing/common/data/xmlres"
"sort"
"blazing/logic/service/common"
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"github.com/jinzhu/copier"
"github.com/shopspring/decimal"
)
type Input struct {
CanChange bool //是否可以死亡切换CanChange
CurrentPet *info.BattlePetEntity //当前精灵
AllPet []*info.BattlePetEntity
Player common.PlayerI
Opp *Input
CanCapture int
Finished bool //是否加载完成
*info.AttackValue
FightC common.FightI
// info.BattleActionI
Effects []Effect //effects 实际上全局就是effect无限回合 //effects容器 技能的
EffectCache []Effect //这里是命中前执行的容器,也就是命中前执行的所有逻辑相关,理论上一个effect被激活,就应该同时将其他的effect取消激活
Effect_Lost []Effect
//CanUseSkill bool
//Effect_Lost []Effect
//NewEffects []Effect
DamageZone struct {
Damage decimal.Decimal //伤害
BeforeADD decimal.Decimal //攻击伤害
BeforeMul decimal.Decimal
BeforeFloor decimal.Decimal
BeforeDiv decimal.Decimal
BeforeSUB decimal.Decimal
BeforeLock decimal.Decimal //锁伤 先锁受击方,再锁攻击方 受击方免疫也是这么锁 免疫等于锁0
BeforeLocked decimal.Decimal
//BeforePost decimal.Decimal
//OldAttack int //攻击伤害被挡前伤害记录
} //伤害容器
//First bool //是否先手
}
func NewInput(c common.FightI, p common.PlayerI) *Input {
ret := &Input{FightC: c, Player: p}
ret.Effects = make([]Effect, 0)
// t := Geteffect(EffectType.Damage, 0)
// t.Effect.SetArgs(ret)
// ret.AddEffect(t) //添加默认基类,实现继承
p.SetFightC(c) //给玩家设置战斗容器
return ret
}
func (our *Input) SortPet() {
sort.Slice(our.AllPet, func(i, j int) bool {
x, y := our.AllPet[i], our.AllPet[j]
// 若x血量>0且y血量=0则x排在前
if x.Info.Hp > 0 && y.Info.Hp <= 0 {
return true
}
// 若x血量=0且y血量>0则x排在后
if x.Info.Hp <= 0 && y.Info.Hp > 0 {
return false
}
// 同类型(都>0或都=0保持原有顺序
return i < j
})
for _, v := range our.AllPet {
if v.Info.Hp == 0 {
v.NotAlive = true
}
}
}
func (our *Input) GetPetInfo() *info.BattlePetEntity {
return our.CurrentPet
}
func (our *Input) SetOPP(t *Input) {
our.Opp = t
}
func (our *Input) GenSataus() {
our.Status = [20]int8{}
for i := 0; i < 20; i++ { //堆叠状态剩余回合
t := our.GetEffect(EffectType.Status, i)
if t != nil && t.Alive() { //状态都是叠层类的
our.Status[i] = int8(t.Duration())
}
}
}
func (our *Input) GenInfo() {
our.RemainHp = int32(our.CurrentPet.Info.Hp)
our.SkillList = our.CurrentPet.Info.SkillList
// f.Second.SkillList = f.Second.CurrentPet.Info.SkillList
// f.Second.RemainHp = int32(f.Second.CurrentPet.Info.Hp)
// ret.FAttack = *f.First.AttackValue
// ret.SAttack = *f.Second.AttackValue
}
func (our *Input) ResetAttackValue() {
our.AttackValue.SkillID = 0
our.AttackValue.IsCritical = 0
our.AttackValue.GainHp = 0
our.AttackValue.LostHp = 0
our.DamageZone.Damage = decimal.NewFromInt(0)
//our.CanUseSkill = true
}
// 这个每回合都会调用
func (our *Input) InitAttackValue() {
our.AttackValue = info.NewAttackValue(our.Player.GetInfo().UserID)
}
func (our *Input) GetPet(id uint32) (ii *info.BattlePetEntity, Reason info.ChangePetInfo) {
for _, v := range our.AllPet {
if v.Info.CatchTime == uint32(id) {
copier.Copy(&Reason, &v.Info)
Reason.UserId = our.Player.GetInfo().UserID
ii = v
}
}
return
}
// GetStatusBonus 获取最高的状态倍率
// 遍历状态数组返回存在的状态中最高的倍率无状态则返回1.0
func (our *Input) GetStatusBonus() float64 {
// 异常状态倍率映射表(状态索引 -> 倍率)
var statusBonuses = map[info.EnumPetStatus]float64{
info.PetStatus.Paralysis: 1.5,
info.PetStatus.Poisoned: 1.5,
info.PetStatus.Sleep: 2.0,
// /info.BattleStatus.Frozen: 2.0,
}
maxBonus := 1.0 // 默认无状态倍率
for statusIdx := 0; statusIdx < 20; statusIdx++ {
t := Geteffect(EffectType.Status, statusIdx)
// 检查状态是否存在数组中值为1表示存在该状态
if t != nil && t.Stack() > 0 {
if bonus, exists := statusBonuses[info.EnumPetStatus(statusIdx)]; exists && bonus > maxBonus {
maxBonus = bonus
}
}
}
return maxBonus
}
// 解析并 施加effect
func (our *Input) Parseskill(skill *action.SelectSkillAction) {
if skill == nil {
return
}
our.EffectCache = make([]Effect, 0) //先把上一回合数据清空,但是应该把本身延续类效果集成过来
our.Effect_Lost = make([]Effect, 0)
// our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了
//i.NewEffects = make([]Effect, 0) //这里说明是新增的效果
temparg := skill.SideEffectArgS
for _, v := range skill.SideEffectS {
t := Geteffect(EffectType.Skill, v)
args := xmlres.EffectArgs[v]
//这里是给双方添加buff
if t != nil {
t.SetArgs(our, temparg[:args]...) //设置入参,施加方永远是我方
// if t.Owner() { //如果取反,说明是给对方添加的回合效果
// //实际上,owner永远为反,说明是对方给我添加的
// t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
// //给双方添加
// defender.AddEffect(t)
// } else {
//t.SetArgs(i, temparg[:args]...) //设置入参
loste := our.AddEffect(our, t)
if loste != nil {
our.Effect_Lost = append(our.Effect_Lost, loste)
}
// }
//这里是临时缓存buff,后面确认命中后修改HIT状态
// t.Alive() //先让效果保持存活
our.EffectCache = append(our.EffectCache, t)
// i.NewEffects = append(i.NewEffects, t)
}
temparg = temparg[args:]
}
}