2025-09-14 01:35:16 +08:00
|
|
|
|
package input
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2025-09-30 18:32:15 +08:00
|
|
|
|
"blazing/common/data/xmlres"
|
2026-01-20 02:25:02 +08:00
|
|
|
|
"blazing/cool"
|
2026-03-04 22:47:21 +08:00
|
|
|
|
"blazing/modules/player/model"
|
2025-11-29 19:26:56 +08:00
|
|
|
|
"fmt"
|
2025-11-11 05:54:24 +00:00
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"blazing/logic/service/common"
|
2025-09-30 18:32:15 +08:00
|
|
|
|
"blazing/logic/service/fight/action"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"blazing/logic/service/fight/info"
|
|
|
|
|
|
|
2025-12-05 00:24:02 +08:00
|
|
|
|
"github.com/alpacahq/alpacadecimal"
|
|
|
|
|
|
|
2025-09-14 01:35:16 +08:00
|
|
|
|
"github.com/jinzhu/copier"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type Input struct {
|
2025-12-10 16:42:23 +00:00
|
|
|
|
CanChange uint32 //是否可以死亡切换CanChange
|
|
|
|
|
|
// CanAction bool //是否可以行动
|
2026-04-04 04:34:43 +08:00
|
|
|
|
CurPet []*info.BattlePetEntity //当前上场精灵
|
2025-11-11 01:10:26 +08:00
|
|
|
|
AllPet []*info.BattlePetEntity
|
|
|
|
|
|
Player common.PlayerI
|
2025-11-11 05:54:24 +00:00
|
|
|
|
Opp *Input
|
2025-11-21 02:40:27 +08:00
|
|
|
|
CanCapture int
|
2025-11-11 05:54:24 +00:00
|
|
|
|
Finished bool //是否加载完成
|
2026-03-04 22:47:21 +08:00
|
|
|
|
*model.AttackValue
|
2025-09-14 01:35:16 +08:00
|
|
|
|
FightC common.FightI
|
|
|
|
|
|
// info.BattleActionI
|
2025-11-11 01:10:26 +08:00
|
|
|
|
Effects []Effect //effects 实际上全局就是effect无限回合 //effects容器 技能的
|
|
|
|
|
|
EffectCache []Effect //这里是命中前执行的容器,也就是命中前执行的所有逻辑相关,理论上一个effect被激活,就应该同时将其他的effect取消激活
|
2026-01-04 21:41:10 +08:00
|
|
|
|
EffectLost []Effect
|
2025-11-21 05:47:51 +00:00
|
|
|
|
// 删掉伤害记录,可以在回调中记录,而不是每次调用记录
|
2025-12-05 00:24:02 +08:00
|
|
|
|
SumDamage alpacadecimal.Decimal //伤害
|
2026-03-29 16:38:34 +08:00
|
|
|
|
// 记录上一回合结束时的能力等级,供效果727等回溯使用。
|
|
|
|
|
|
LastTurnEndProp [6]int8
|
2025-11-21 05:47:51 +00:00
|
|
|
|
// 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 //攻击伤害被挡前伤害记录
|
|
|
|
|
|
// } //伤害容器
|
2025-09-30 18:32:15 +08:00
|
|
|
|
//First bool //是否先手
|
2025-09-14 01:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 04:48:38 +08:00
|
|
|
|
func NewInput(c common.FightI, p common.PlayerI) *Input {
|
|
|
|
|
|
ret := &Input{FightC: c, Player: p}
|
2025-10-31 11:21:24 +00:00
|
|
|
|
ret.Effects = make([]Effect, 0)
|
2026-04-04 04:34:43 +08:00
|
|
|
|
ret.CurPet = make([]*info.BattlePetEntity, 0)
|
2025-09-26 21:15:58 +00:00
|
|
|
|
|
2025-09-26 02:09:33 +00:00
|
|
|
|
// t := Geteffect(EffectType.Damage, 0)
|
|
|
|
|
|
// t.Effect.SetArgs(ret)
|
|
|
|
|
|
// ret.AddEffect(t) //添加默认基类,实现继承
|
|
|
|
|
|
p.SetFightC(c) //给玩家设置战斗容器
|
2025-09-24 19:46:42 +08:00
|
|
|
|
|
2025-09-14 04:48:38 +08:00
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-11-15 01:53:51 +08:00
|
|
|
|
|
2026-04-04 04:34:43 +08:00
|
|
|
|
func (our *Input) CurPetAt(index int) *info.BattlePetEntity {
|
|
|
|
|
|
if our == nil || index < 0 || index >= len(our.CurPet) {
|
2026-04-04 04:28:04 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2026-04-04 04:34:43 +08:00
|
|
|
|
return our.CurPet[index]
|
2026-04-04 04:28:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-04 04:34:43 +08:00
|
|
|
|
func (our *Input) PrimaryCurPet() *info.BattlePetEntity {
|
|
|
|
|
|
return our.CurPetAt(0)
|
2026-04-04 04:28:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-04 04:34:43 +08:00
|
|
|
|
func (our *Input) SetCurPetAt(index int, pet *info.BattlePetEntity) {
|
2026-04-04 04:28:04 +08:00
|
|
|
|
if our == nil || index < 0 {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-04-04 04:34:43 +08:00
|
|
|
|
for len(our.CurPet) <= index {
|
|
|
|
|
|
our.CurPet = append(our.CurPet, nil)
|
2026-04-04 04:28:04 +08:00
|
|
|
|
}
|
2026-04-04 04:34:43 +08:00
|
|
|
|
our.CurPet[index] = pet
|
2026-04-04 04:28:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-30 04:57:48 +00:00
|
|
|
|
// 非原地交换:收集非0血量精灵 + 0血量精灵,拼接后返回
|
2025-11-15 01:53:51 +08:00
|
|
|
|
func (our *Input) SortPet() {
|
2025-11-30 04:57:48 +00:00
|
|
|
|
var nonZeroHP []*info.BattlePetEntity // 收集血量>0的精灵(保持原顺序)
|
|
|
|
|
|
var zeroHP []*info.BattlePetEntity // 收集血量=0的精灵(保持原顺序)
|
2025-11-26 15:25:10 +08:00
|
|
|
|
|
2025-11-30 04:57:48 +00:00
|
|
|
|
// 线性遍历一次,分类收集
|
|
|
|
|
|
for _, s := range our.AllPet {
|
2025-12-01 23:31:48 +08:00
|
|
|
|
if s.Info.Hp > 0 {
|
2025-11-30 04:57:48 +00:00
|
|
|
|
for _, e1 := range s.Info.EffectInfo {
|
2026-03-08 17:48:34 +08:00
|
|
|
|
t := our.InitEffect(EffectType.NewSel, int(e1.EID), e1.Args...)
|
2025-11-26 15:25:10 +08:00
|
|
|
|
if t != nil {
|
|
|
|
|
|
ef := t.ID()
|
2026-01-20 02:25:02 +08:00
|
|
|
|
if cool.Config.ServerInfo.IsDebug != 0 {
|
|
|
|
|
|
fmt.Println("初始化特性", ef.Suffix())
|
|
|
|
|
|
}
|
2025-11-26 18:39:23 +08:00
|
|
|
|
|
2025-11-30 04:57:48 +00:00
|
|
|
|
ef.SetCatchTime(s.Info.CatchTime)
|
2025-11-26 18:39:23 +08:00
|
|
|
|
|
2025-11-26 15:25:10 +08:00
|
|
|
|
t.ID(ef)
|
2025-11-26 18:39:23 +08:00
|
|
|
|
|
2025-11-26 15:25:10 +08:00
|
|
|
|
t.Duration(-1)
|
2026-03-08 17:48:34 +08:00
|
|
|
|
|
2025-11-26 15:25:10 +08:00
|
|
|
|
our.AddEffect(our, t)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-11-30 04:57:48 +00:00
|
|
|
|
nonZeroHP = append(nonZeroHP, s)
|
|
|
|
|
|
} else {
|
2026-03-17 13:34:50 +08:00
|
|
|
|
|
2025-11-30 04:57:48 +00:00
|
|
|
|
zeroHP = append(zeroHP, s)
|
2025-11-15 01:53:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-30 04:57:48 +00:00
|
|
|
|
|
|
|
|
|
|
// 拼接:非0血量精灵在前,0血量精灵在后
|
|
|
|
|
|
our.AllPet = append(nonZeroHP, zeroHP...)
|
2025-11-15 01:53:51 +08:00
|
|
|
|
}
|
2025-11-30 04:57:48 +00:00
|
|
|
|
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) GetPetInfo() *info.BattlePetEntity {
|
|
|
|
|
|
|
2026-04-04 04:34:43 +08:00
|
|
|
|
return our.PrimaryCurPet()
|
2025-11-11 05:54:24 +00:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
func (our *Input) SetOPP(t *Input) {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
2025-11-11 05:54:24 +00:00
|
|
|
|
our.Opp = t
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
2025-11-10 08:25:40 +00:00
|
|
|
|
}
|
2025-12-18 03:54:45 +00:00
|
|
|
|
func (our *Input) RecoverEffect() {
|
2026-01-04 21:41:10 +08:00
|
|
|
|
//println("恢复效果",our.UserID)
|
2025-11-15 01:53:51 +08:00
|
|
|
|
|
2025-12-18 03:54:45 +00:00
|
|
|
|
//根本没释放技能,这些效果全部失效
|
|
|
|
|
|
for _, e := range our.EffectCache {
|
2025-12-18 07:19:38 +00:00
|
|
|
|
|
2025-12-18 03:54:45 +00:00
|
|
|
|
e.Alive(false)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//这时候将被覆盖的效果全部装回来enterturn
|
2026-01-04 21:41:10 +08:00
|
|
|
|
for _, e := range our.EffectLost {
|
2025-12-18 07:19:38 +00:00
|
|
|
|
if e.Duration() > 0 || e.Duration() == -1 {
|
2026-01-04 21:41:10 +08:00
|
|
|
|
// e.Alive(true)
|
|
|
|
|
|
our.AddEffect(e.GetInput(), e)
|
2025-12-18 07:19:38 +00:00
|
|
|
|
}
|
2025-12-18 03:54:45 +00:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
func (our *Input) ReactvieEffect() {
|
|
|
|
|
|
|
|
|
|
|
|
//根本没释放技能,这些效果全部失效
|
2026-01-04 21:41:10 +08:00
|
|
|
|
for _, e := range our.EffectLost {
|
2025-12-18 03:54:45 +00:00
|
|
|
|
e.Alive(false)
|
|
|
|
|
|
|
2026-01-04 21:41:10 +08:00
|
|
|
|
// our.AddEffect(e.GetInput(), e)
|
|
|
|
|
|
|
2025-12-18 03:54:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//这时候将被覆盖的效果全部装回来enterturn
|
2025-12-18 04:40:58 +00:00
|
|
|
|
for _, e := range our.EffectCache {
|
2026-01-04 21:41:10 +08:00
|
|
|
|
// e.Alive(true)
|
|
|
|
|
|
//因为后手方实际上是到了他出手阶段重新添加的结果,而非后手方重新激活效果
|
|
|
|
|
|
our.AddEffect(e.GetInput(), e)
|
2025-12-18 03:54:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) GenSataus() {
|
2025-11-13 05:05:05 +08:00
|
|
|
|
our.Status = [20]int8{}
|
2025-11-10 08:25:40 +00:00
|
|
|
|
for i := 0; i < 20; i++ { //堆叠状态剩余回合
|
|
|
|
|
|
|
2025-11-11 05:54:24 +00:00
|
|
|
|
t := our.GetEffect(EffectType.Status, i)
|
2025-11-10 08:25:40 +00:00
|
|
|
|
|
2025-11-11 01:10:26 +08:00
|
|
|
|
if t != nil && t.Alive() { //状态都是叠层类的
|
2025-11-10 08:25:40 +00:00
|
|
|
|
|
2025-11-11 05:54:24 +00:00
|
|
|
|
our.Status[i] = int8(t.Duration())
|
2025-11-10 08:25:40 +00:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) GenInfo() {
|
2026-04-04 04:34:43 +08:00
|
|
|
|
currentPet := our.PrimaryCurPet()
|
2026-04-04 04:28:04 +08:00
|
|
|
|
if currentPet == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-11-10 08:25:40 +00:00
|
|
|
|
|
2026-04-04 04:28:04 +08:00
|
|
|
|
our.RemainHp = int32(currentPet.Info.Hp)
|
|
|
|
|
|
our.SkillList = currentPet.Info.SkillList
|
2026-03-10 09:17:26 +08:00
|
|
|
|
|
2026-04-04 04:34:43 +08:00
|
|
|
|
// f.Second.SkillList = f.Second.CurPet.Info.SkillList
|
|
|
|
|
|
// f.Second.RemainHp = int32(f.Second.CurPet.Info.Hp)
|
2025-11-10 08:25:40 +00:00
|
|
|
|
// ret.FAttack = *f.First.AttackValue
|
|
|
|
|
|
// ret.SAttack = *f.Second.AttackValue
|
|
|
|
|
|
|
2025-10-31 02:24:49 +00:00
|
|
|
|
}
|
2026-03-29 16:38:34 +08:00
|
|
|
|
func (our *Input) SnapshotTurnProp() {
|
|
|
|
|
|
our.LastTurnEndProp = our.AttackValue.Prop
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) ResetAttackValue() {
|
|
|
|
|
|
our.AttackValue.SkillID = 0
|
|
|
|
|
|
our.AttackValue.IsCritical = 0
|
|
|
|
|
|
our.AttackValue.GainHp = 0
|
|
|
|
|
|
our.AttackValue.LostHp = 0
|
2026-01-21 20:46:05 +00:00
|
|
|
|
our.SumDamage = alpacadecimal.Zero
|
2025-11-13 21:36:18 +08:00
|
|
|
|
//our.CanUseSkill = true
|
2025-09-14 01:35:16 +08:00
|
|
|
|
}
|
2025-09-14 04:48:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 这个每回合都会调用
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) InitAttackValue() {
|
|
|
|
|
|
our.AttackValue = info.NewAttackValue(our.Player.GetInfo().UserID)
|
2026-03-29 16:38:34 +08:00
|
|
|
|
our.LastTurnEndProp = [6]int8{}
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) GetPet(id uint32) (ii *info.BattlePetEntity, Reason info.ChangePetInfo) {
|
|
|
|
|
|
for _, v := range our.AllPet {
|
2026-02-05 23:44:07 +08:00
|
|
|
|
if v.Info.CatchTime == uint32(id) && v.Info.Hp > 0 {
|
2025-09-14 01:35:16 +08:00
|
|
|
|
copier.Copy(&Reason, &v.Info)
|
2025-11-11 05:54:24 +00:00
|
|
|
|
Reason.UserId = our.Player.GetInfo().UserID
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
|
|
ii = v
|
2025-11-29 19:26:56 +08:00
|
|
|
|
|
|
|
|
|
|
return ii, Reason
|
2025-09-14 01:35:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-21 14:56:37 +00:00
|
|
|
|
|
|
|
|
|
|
// GetStatusBonus 获取最高的状态倍率
|
|
|
|
|
|
// 遍历状态数组,返回存在的状态中最高的倍率(无状态则返回1.0)
|
2025-11-11 05:54:24 +00:00
|
|
|
|
func (our *Input) GetStatusBonus() float64 {
|
2025-09-21 14:56:37 +00:00
|
|
|
|
// 异常状态倍率映射表(状态索引 -> 倍率)
|
2025-11-14 00:26:34 +08:00
|
|
|
|
var statusBonuses = map[info.EnumPetStatus]float64{
|
2025-09-25 14:51:11 +00:00
|
|
|
|
info.PetStatus.Paralysis: 1.5,
|
|
|
|
|
|
info.PetStatus.Poisoned: 1.5,
|
|
|
|
|
|
info.PetStatus.Sleep: 2.0,
|
2025-09-21 14:56:37 +00:00
|
|
|
|
// /info.BattleStatus.Frozen: 2.0,
|
|
|
|
|
|
}
|
|
|
|
|
|
maxBonus := 1.0 // 默认无状态倍率
|
|
|
|
|
|
|
|
|
|
|
|
for statusIdx := 0; statusIdx < 20; statusIdx++ {
|
2026-03-08 10:34:23 +08:00
|
|
|
|
t := our.InitEffect(EffectType.Status, statusIdx)
|
2025-09-21 14:56:37 +00:00
|
|
|
|
|
|
|
|
|
|
// 检查状态是否存在(数组中值为1表示存在该状态)
|
2025-10-31 11:21:24 +00:00
|
|
|
|
if t != nil && t.Stack() > 0 {
|
2025-11-14 00:26:34 +08:00
|
|
|
|
if bonus, exists := statusBonuses[info.EnumPetStatus(statusIdx)]; exists && bonus > maxBonus {
|
2025-09-21 14:56:37 +00:00
|
|
|
|
maxBonus = bonus
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return maxBonus
|
|
|
|
|
|
}
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
|
|
|
|
|
// 解析并 施加effect
|
2025-11-14 06:14:49 +08:00
|
|
|
|
func (our *Input) Parseskill(skill *action.SelectSkillAction) {
|
|
|
|
|
|
if skill == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-11-25 18:25:52 +08:00
|
|
|
|
if skill.SkillEntity == nil {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-11-13 21:36:18 +08:00
|
|
|
|
|
2025-11-13 05:05:05 +08:00
|
|
|
|
// our.Initeffectcache() //这里说明是延续的效果,每次复制出来一个新的就好了
|
2025-11-11 01:10:26 +08:00
|
|
|
|
//i.NewEffects = make([]Effect, 0) //这里说明是新增的效果
|
2026-03-09 18:49:51 +08:00
|
|
|
|
temparg := skill.XML.SideEffectArgS
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2026-03-09 18:49:51 +08:00
|
|
|
|
for _, v := range skill.XML.SideEffectS {
|
2025-09-30 18:32:15 +08:00
|
|
|
|
args := xmlres.EffectArgs[v]
|
2026-03-08 18:01:41 +08:00
|
|
|
|
t := our.InitEffect(EffectType.Skill, v, temparg[:args]...)
|
|
|
|
|
|
|
2025-10-05 00:29:22 +08:00
|
|
|
|
//这里是给双方添加buff
|
2025-10-31 11:21:24 +00:00
|
|
|
|
if t != nil {
|
2026-03-08 18:01:41 +08:00
|
|
|
|
// t.SetArgs(our, temparg[:args]...) //设置入参,施加方永远是我方
|
2025-09-30 18:32:15 +08:00
|
|
|
|
|
2025-11-08 16:38:41 +08:00
|
|
|
|
// if t.Owner() { //如果取反,说明是给对方添加的回合效果
|
|
|
|
|
|
// //实际上,owner永远为反,说明是对方给我添加的
|
|
|
|
|
|
// t.SetArgs(i, temparg[:args]...) //设置入参,施加方永远是我方
|
|
|
|
|
|
// //给双方添加
|
|
|
|
|
|
// defender.AddEffect(t)
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
//t.SetArgs(i, temparg[:args]...) //设置入参
|
2025-11-14 03:21:00 +08:00
|
|
|
|
loste := our.AddEffect(our, t)
|
2025-11-13 02:43:00 +08:00
|
|
|
|
if loste != nil {
|
2026-01-04 21:41:10 +08:00
|
|
|
|
our.EffectLost = append(our.EffectLost, loste)
|
2025-11-13 02:43:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-08 16:38:41 +08:00
|
|
|
|
// }
|
2025-10-05 00:29:22 +08:00
|
|
|
|
//这里是临时缓存buff,后面确认命中后修改HIT状态
|
2025-11-12 21:44:56 +08:00
|
|
|
|
// t.Alive() //先让效果保持存活
|
2025-11-11 05:54:24 +00:00
|
|
|
|
our.EffectCache = append(our.EffectCache, t)
|
2025-11-11 01:10:26 +08:00
|
|
|
|
// i.NewEffects = append(i.NewEffects, t)
|
2026-03-08 22:43:51 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
fmt.Println("技能效果不存在", v)
|
2025-09-30 18:32:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
temparg = temparg[args:]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|