Files
bl/logic/service/fight/effect/selfkill.go
xinian 1a0e0b405a
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
feat: 添加自然祝福相关技能效果实现
实现1383-1387技能效果,包括自然祝福状态下的属性强化、自然祝福层数管理、护盾效果等
2026-04-03 11:19:20 +08:00

537 lines
14 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.CurrentPet.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.CurrentPet.Info.Hp)),
})
return true
},
}
for effectID, handler := range handlers {
initskill(effectID, newSkillHitRegistrarEffect(handler))
}
}
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.CurrentPet.GetHP().Div(alpacadecimal.NewFromInt(2)),
})
return true
},
137: func(e *onSkillRegistrarEffect) bool {
currentHP := e.Ctx().Our.CurrentPet.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.CurrentPet.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,
})
}
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: opponentDamage,
})
return true
},
556: func(e *onSkillRegistrarEffect) bool {
currentHP := e.Ctx().Our.CurrentPet.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 {
initskill(effectID, newOnSkillRegistrarEffect(handler))
}
}
func registerSelfDamageSkillUseEffects() {
handlers := map[int]func(*skillUseRegistrarEffect) bool{
80: func(e *skillUseRegistrarEffect) bool {
damage := e.Ctx().Our.CurrentPet.GetMaxHP().Div(alpacadecimal.NewFromInt(2))
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
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.CurrentPet.Info.MaxHp)),
})
damage := int64(grand.N(250, 300))
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: alpacadecimal.Min(alpacadecimal.NewFromInt(damage), e.Ctx().Opp.CurrentPet.GetHP().Sub(alpacadecimal.NewFromInt(1))),
})
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.CurrentPet.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)
}
remainHP := e.Ctx().Opp.CurrentPet.GetHP().Sub(alpacadecimal.NewFromInt(1))
if remainHP.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
damage := alpacadecimal.Min(alpacadecimal.NewFromInt(int64(randomDamage)), remainHP)
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: damage,
})
return true
},
1380: func(e *skillUseRegistrarEffect) bool {
if len(e.Args()) < 3 {
return true
}
applyAllPropDown(e.Ctx().Our, e.Ctx().Opp, 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 {
e.Ctx().Opp.AddEffect(e.Ctx().Our, sub)
}
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: e.Ctx().Our.CurrentPet.GetHP(),
})
return true
},
}
for effectID, handler := range handlers {
initskill(effectID, newSkillUseRegistrarEffect(handler))
}
}
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.CurrentPet.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 {
initskill(effectID, effect)
}
}
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.CurrentPet.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
}