Files
bl/logic/service/fight/effect/selfkill.go
昔念 0c79fee8af
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
1
2026-04-17 00:35:17 +08:00

591 lines
15 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 effect
import (
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"github.com/alpacahq/alpacadecimal"
"github.com/gogf/gf/v2/util/grand"
)
type SelfKill struct {
node.EffectNode
can bool
}
func (e *SelfKill) SetArgs(t *input.Input, a ...int) {
// e.CanStack(-1)//后续的不会顶掉这个效果
e.EffectNode.SetArgs(t, a...)
e.Duration(-1) // 次数类,无限回合
}
func (e *SelfKill) OnSkill() bool {
if e.can {
return true
}
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurPet[0].Info.MaxHp)),
})
e.can = true
return true
}
// 自杀,所以效果不消除
func (e *SelfKill) SwitchOut(in *input.Input) bool {
return true
}
type skillHitRegistrarEffect struct {
node.EffectNode
handler func(*skillHitRegistrarEffect) bool
}
func newSkillHitRegistrarEffect(handler func(*skillHitRegistrarEffect) bool) *skillHitRegistrarEffect {
return &skillHitRegistrarEffect{handler: handler}
}
func (e *skillHitRegistrarEffect) SkillHit() bool {
if e.handler == nil {
return true
}
return e.handler(e)
}
type onSkillRegistrarEffect struct {
node.EffectNode
handler func(*onSkillRegistrarEffect) bool
}
func newOnSkillRegistrarEffect(handler func(*onSkillRegistrarEffect) bool) *onSkillRegistrarEffect {
return &onSkillRegistrarEffect{handler: handler}
}
func (e *onSkillRegistrarEffect) OnSkill() bool {
if e.handler == nil {
return true
}
return e.handler(e)
}
type skillUseRegistrarEffect struct {
node.EffectNode
handler func(*skillUseRegistrarEffect) bool
}
func newSkillUseRegistrarEffect(handler func(*skillUseRegistrarEffect) bool) *skillUseRegistrarEffect {
return &skillUseRegistrarEffect{handler: handler}
}
func (e *skillUseRegistrarEffect) Skill_Use() bool {
if e.handler == nil {
return true
}
return e.handler(e)
}
type comparePreOnSkillRegistrarEffect struct {
node.EffectNode
comparePreHandler func(*comparePreOnSkillRegistrarEffect, *action.SelectSkillAction, *action.SelectSkillAction) bool
onSkillHandler func(*comparePreOnSkillRegistrarEffect) bool
}
func newComparePreOnSkillRegistrarEffect(comparePre func(*comparePreOnSkillRegistrarEffect, *action.SelectSkillAction, *action.SelectSkillAction) bool, onSkill func(*comparePreOnSkillRegistrarEffect) bool) *comparePreOnSkillRegistrarEffect {
return &comparePreOnSkillRegistrarEffect{
comparePreHandler: comparePre,
onSkillHandler: onSkill,
}
}
func (e *comparePreOnSkillRegistrarEffect) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if e.comparePreHandler == nil {
return true
}
return e.comparePreHandler(e, fattack, sattack)
}
func (e *comparePreOnSkillRegistrarEffect) OnSkill() bool {
if e.onSkillHandler == nil {
return true
}
return e.onSkillHandler(e)
}
func init() {
registerSelfKillEffects()
registerSelfDamageSkillHitEffects()
registerSelfDamageOnSkillEffects()
registerSelfDamageSkillUseEffects()
registerSelfDamageComparePreOnSkillEffects()
registerSelfDamageSubEffects()
}
func registerSelfKillEffects() {
builders := map[int]func() input.Effect{
59: func() input.Effect { return &Effect59{} },
71: func() input.Effect { return &Effect71{count: 2} },
144: func() input.Effect { return &Effect144{} },
435: func() input.Effect { return &Effect435{} },
574: func() input.Effect { return &Effect574{} },
618: func() input.Effect { return &Effect618{} },
}
for effectID, builder := range builders {
initskill(effectID, builder())
}
}
func registerSelfDamageSkillHitEffects() {
handlers := map[int]func(*skillHitRegistrarEffect) bool{
72: func(e *skillHitRegistrarEffect) bool {
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().AttackTime != 0 {
return true
}
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.True,
Damage: alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurPet[0].Info.Hp)),
})
return true
},
}
for effectID, handler := range handlers {
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newSkillHitRegistrarEffect(currentHandler)
})
}
}
func registerSelfDamageOnSkillEffects() {
handlers := map[int]func(*onSkillRegistrarEffect) bool{
79: func(e *onSkillRegistrarEffect) bool {
e.Ctx().Our.SetProp(e.Ctx().Our, 2, 2)
e.Ctx().Our.SetProp(e.Ctx().Our, 4, 1)
e.Ctx().Our.SetProp(e.Ctx().Our, 5, 1)
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: e.Ctx().Our.CurPet[0].GetHP().Div(alpacadecimal.NewFromInt(2)),
})
return true
},
137: func(e *onSkillRegistrarEffect) bool {
currentHP := e.Ctx().Our.CurPet[0].GetHP()
halfHP := currentHP.Div(alpacadecimal.NewFromInt(2))
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: halfHP,
})
e.Ctx().Our.SetProp(e.Ctx().Our, 4, 2)
e.Ctx().Our.SetProp(e.Ctx().Our, 0, 2)
return true
},
479: func(e *onSkillRegistrarEffect) bool {
selfDamage := alpacadecimal.NewFromInt(int64(e.Args()[0].IntPart()))
opponentDamage := alpacadecimal.NewFromInt(int64(e.Args()[1].IntPart()))
currentHP := e.Ctx().Our.CurPet[0].GetHP()
minHP := alpacadecimal.NewFromInt(200)
if currentHP.Cmp(minHP) < 0 {
damageToTake := currentHP.Sub(alpacadecimal.NewFromInt(1))
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damageToTake,
})
} else {
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: selfDamage,
})
}
forEachEnemyTargetBySkill(e.Ctx().Our, e.Ctx().Opp, e.Ctx().SkillEntity, func(target *input.Input) bool {
if target == nil || target.CurrentPet() == nil {
return true
}
target.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: opponentDamage,
})
return true
})
return true
},
556: func(e *onSkillRegistrarEffect) bool {
currentHP := e.Ctx().Our.CurPet[0].Info.Hp
if currentHP > 1 {
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: alpacadecimal.NewFromInt(int64(currentHP - 1)),
})
}
return true
},
}
for effectID, handler := range handlers {
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newOnSkillRegistrarEffect(currentHandler)
})
}
}
func registerSelfDamageSkillUseEffects() {
handlers := map[int]func(*skillUseRegistrarEffect) bool{
80: func(e *skillUseRegistrarEffect) bool {
damage := e.Ctx().Our.CurPet[0].GetMaxHP().Div(alpacadecimal.NewFromInt(2))
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
forEachEnemyTargetBySkill(e.Ctx().Our, e.Ctx().Opp, e.Ctx().SkillEntity, func(target *input.Input) bool {
if target == nil || target.CurrentPet() == nil {
return true
}
target.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
return true
})
return true
},
112: func(e *skillUseRegistrarEffect) bool {
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurPet[0].Info.MaxHp)),
})
damage := int64(grand.N(250, 300))
forEachEnemyTargetBySkill(e.Ctx().Our, e.Ctx().Opp, e.Ctx().SkillEntity, func(target *input.Input) bool {
if target == nil {
return true
}
targetPet := target.CurrentPet()
if targetPet == nil {
return true
}
remainHP := targetPet.GetHP().Sub(alpacadecimal.NewFromInt(1))
if remainHP.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
target.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: alpacadecimal.Min(alpacadecimal.NewFromInt(damage), remainHP),
})
return true
})
return true
},
617: func(e *skillUseRegistrarEffect) bool {
if len(e.Args()) < 2 {
return true
}
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: e.Ctx().Our.CurPet[0].GetMaxHP(),
})
minDamage := int(e.Args()[0].IntPart())
maxDamage := int(e.Args()[1].IntPart())
if maxDamage < minDamage {
minDamage, maxDamage = maxDamage, minDamage
}
randomDamage := minDamage
if maxDamage > minDamage {
randomDamage = grand.N(minDamage, maxDamage)
}
forEachEnemyTargetBySkill(e.Ctx().Our, e.Ctx().Opp, e.Ctx().SkillEntity, func(target *input.Input) bool {
if target == nil {
return true
}
targetPet := target.CurrentPet()
if targetPet == nil {
return true
}
remainHP := targetPet.GetHP().Sub(alpacadecimal.NewFromInt(1))
if remainHP.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
damage := alpacadecimal.Min(alpacadecimal.NewFromInt(int64(randomDamage)), remainHP)
target.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
return true
})
return true
},
1380: func(e *skillUseRegistrarEffect) bool {
if len(e.Args()) < 3 {
return true
}
forEachEnemyTargetBySkill(e.Ctx().Our, e.Ctx().Opp, e.Ctx().SkillEntity, func(target *input.Input) bool {
if target == nil || target.CurrentPet() == nil {
return true
}
applyAllPropDown(e.Ctx().Our, target, int8(e.Args()[0].IntPart()))
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1380, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart()))
if sub != nil {
target.AddEffect(e.Ctx().Our, sub)
}
return true
})
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: e.Ctx().Our.CurPet[0].GetHP(),
})
return true
},
}
for effectID, handler := range handlers {
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newSkillUseRegistrarEffect(currentHandler)
})
}
}
func registerSelfDamageComparePreOnSkillEffects() {
effects := map[int]*comparePreOnSkillRegistrarEffect{
142: newComparePreOnSkillRegistrarEffect(
func(e *comparePreOnSkillRegistrarEffect, fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if fattack == nil {
return true
}
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil || sattack.SkillEntity == nil {
return true
}
sattack.SkillEntity.XML.Priority += 1
return true
},
func(e *comparePreOnSkillRegistrarEffect) bool {
maxHP := e.Ctx().Our.CurPet[0].GetMaxHP()
damageAmount := maxHP.Div(e.Args()[0])
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damageAmount,
})
return true
},
),
}
for effectID, effect := range effects {
currentEffect := effect
initskillFactory(effectID, func() input.Effect {
return newComparePreOnSkillRegistrarEffect(currentEffect.comparePreHandler, currentEffect.onSkillHandler)
})
}
}
func registerSelfDamageSubEffects() {
input.InitEffect(input.EffectType.Sub, 618, &Effect618Sub{})
input.InitEffect(input.EffectType.Sub, 1380, &Effect1380Sub{})
}
// Effect 59: 消耗自身全部体力(体力降到0),使下一只出战精灵的{0}和{1}能力提升1个等级
type Effect59 struct {
SelfKill
}
func (e *Effect59) TurnStart(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) {
if !e.can {
return
}
e.Ctx().Our.SetProp(e.Ctx().Our, int8(e.Args()[0].IntPart()), 1)
e.Ctx().Our.SetProp(e.Ctx().Our, int8(e.Args()[1].IntPart()), 1)
e.Alive(false)
}
// Effect 71: 消耗自身全部体力己方下2次攻击技能必定打出致命一击
type Effect71 struct {
SelfKill
count int
}
func (e *Effect71) ActionStart(a, b *action.SelectSkillAction) bool {
if !e.can {
return true
}
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.CritRate = 16
e.count--
if e.count <= 0 {
e.Alive(false)
}
return true
}
// Effect 144: 消耗自己所有体力,使下一个出战的精灵{0}回合免疫异常状态
type Effect144 struct {
SelfKill
count int
}
func (e *Effect144) EFFect_Befer(in *input.Input, effEffect input.Effect) bool {
if !e.can {
return true
}
if int(e.Input.FightC.GetOverInfo().Round) >= e.count+e.SideEffectArgs[0] {
e.Alive(false)
}
if e.count == 0 {
e.count = int(e.Input.FightC.GetOverInfo().Round)
}
if in != e.Ctx().Opp {
return true
}
if input.IS_Stat(effEffect) {
return false
}
return true
}
// Effect 435: 牺牲自己,使下回合出场的精灵首次攻击必定命中,必定先手
type Effect435 struct {
SelfKill
}
func (e *Effect435) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if !e.can {
return true
}
if fattack == nil {
return true
}
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil || sattack.SkillEntity == nil {
return true
}
sattack.SkillEntity.XML.Priority += 7
e.Alive(false)
return true
}
func (e *Effect435) ActionStart(a, b *action.SelectSkillAction) bool {
if !e.can {
return true
}
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.MustHit = 1
return true
}
// Effect 574: 消耗自身全部体力,令己方下次使用的技能必定先手、必定命中,下次命中的攻击技能必定打出致命一击
type Effect574 struct {
SelfKill
}
func (e *Effect574) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool {
if !e.can {
return true
}
if fattack == nil {
return true
}
if fattack.PlayerID == e.Ctx().Our.UserID {
return true
}
if sattack == nil || sattack.SkillEntity == nil {
return true
}
sattack.SkillEntity.XML.Priority += 7
e.Alive(false)
return true
}
func (e *Effect574) ActionStart(a, b *action.SelectSkillAction) bool {
if !e.can {
return true
}
if e.Ctx().SkillEntity == nil {
return true
}
if e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.MustHit = 1
e.Ctx().SkillEntity.XML.CritRate = 16
return true
}
// Effect 618: 消耗自身所有体力,使下一只出战精灵{0}回合内每回合恢复{1}点体力
type Effect618 struct {
SelfKill
}
func (e *Effect618) SwitchIn(in *input.Input) bool {
if !e.can || in != e.Ctx().Our {
return true
}
effect := e.Ctx().Our.InitEffect(input.EffectType.Sub, 618, e.SideEffectArgs...)
if effect != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, effect)
}
e.Alive(false)
return true
}
type Effect618Sub struct {
RoundEffectArg0Base
}
func (e *Effect618Sub) TurnEnd() {
if len(e.Args()) > 1 && e.Ctx().Our.CurPet[0].Info.Hp > 0 {
e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Args()[1])
}
e.EffectNode.TurnEnd()
}
type Effect1380Sub struct {
RoundEffectArg0Base
}
func (e *Effect1380Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
if current == nil || current.SkillEntity == nil || len(e.Args()) < 2 {
return true
}
current.SkillEntity.XML.Priority -= int(e.Args()[1].IntPart())
return true
}