Files
bl/logic/service/fight/input/input.go
昔念 aad1e2f44c feat(fight): 添加战斗前状态检查与经验获取限制判断
- 在挑战BOSS和野外怪物战斗前,增加 CanFight 状态检查,防止非法战斗
- 修复战斗胜利后经验与物品发放逻辑,增加 CanGetExp 判断避免重复获取
- 优化战斗中精灵切换逻辑与相关伤害效果处理,确保死亡标记正确设置
- 修正战斗轮次中被动切换行为及技能执行顺序问题
- 移除无用的管理员会话控制器和宠物融合模型代码
- 调整战斗输入结构体中的 Switch 类型为 Map 以提高查找效率
- 修复战斗中精灵存活判定条件,
2025-12-01 23:31:48 +08:00

235 lines
6.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 input
import (
"blazing/common/data/xmlres"
"fmt"
"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
// 删掉伤害记录,可以在回调中记录,而不是每次调用记录
SumDamage decimal.Decimal //伤害
// 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
}
// 非原地交换收集非0血量精灵 + 0血量精灵拼接后返回
func (our *Input) SortPet() {
var nonZeroHP []*info.BattlePetEntity // 收集血量>0的精灵保持原顺序
var zeroHP []*info.BattlePetEntity // 收集血量=0的精灵保持原顺序
// 线性遍历一次,分类收集
for _, s := range our.AllPet {
if s.Info.Hp > 0 {
for _, e1 := range s.Info.EffectInfo {
t := Geteffect(EffectType.NewSel, e1.EID)
if t != nil {
ef := t.ID()
fmt.Println("初始化特性", ef.Suffix())
ef.SetCatchTime(s.Info.CatchTime)
t.ID(ef)
t.Duration(-1)
t.SetArgs(our, e1.Args...) //设置入参,施加方永远是我方
our.AddEffect(our, t)
}
}
nonZeroHP = append(nonZeroHP, s)
} else {
s.NotAlive = true
zeroHP = append(zeroHP, s)
}
}
// 拼接非0血量精灵在前0血量精灵在后
our.AllPet = append(nonZeroHP, zeroHP...)
}
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.SumDamage = 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 ii, Reason
}
}
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
}
if skill.SkillEntity == 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:]
}
}