Files
bl/logic/service/fight/effect/2270_2294.go
昔念 07758266d5 ```
feat(effect): 实现多个战斗效果功能

- 实现了effects 2195-2199的功能,包括消除对手回合类效果、概率附加效果、
  护盾/护罩状态下触发的效果等

- 实现了effects 2220-2239的功能,包括攻击特攻最高值转换、闪避与PP归零、
  伤害提升、恢复体力、回合效果管理等功能

- 实现了effects 2270-2294的部分功能修复,调整了精灵
2026-03-31 06:51:54 +08:00

1342 lines
35 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 (
element "blazing/common/data/Element"
"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"
)
func clearOppEffects(owner, target *input.Input) bool {
if owner == nil || target == nil {
return false
}
cleared := false
for _, eff := range target.Effects {
if eff != nil && eff.Alive() {
eff.Alive(false)
cleared = true
}
}
return cleared
}
func addStatus2270(owner, target *input.Input, statusID int) bool {
if owner == nil || target == nil {
return false
}
eff := owner.InitEffect(input.EffectType.Status, statusID)
if eff == nil {
return false
}
target.AddEffect(owner, eff)
return true
}
func markCatchTime227x(eff input.Effect) uint32 {
if eff == nil || !eff.Alive() || len(eff.Args()) == 0 {
return 0
}
v := eff.Args()[0].IntPart()
if v <= 0 {
return 0
}
return uint32(v)
}
func clearHuntMarks227x(target *input.Input) {
if target == nil {
return
}
for _, eff := range target.Effects {
if eff == nil || !eff.Alive() || eff.ID().GetEffectType() != input.EffectType.Sub {
continue
}
switch int(eff.ID().Suffix()) {
case 2275, 2276, 2277:
eff.Alive(false)
}
}
}
func applyHuntMark227x(owner, target *input.Input, markID int, catchTime uint32) bool {
if owner == nil || target == nil || catchTime == 0 {
return false
}
clearHuntMarks227x(target)
eff := owner.InitEffect(input.EffectType.Sub, markID, int(catchTime))
if eff == nil {
return false
}
target.AddEffect(owner, eff)
return true
}
func isCatchTimeMarked227x(target *input.Input, catchTime uint32) bool {
if target == nil || catchTime == 0 {
return false
}
for _, id := range []int{2275, 2276, 2277} {
if markCatchTime227x(target.GetEffect(input.EffectType.Sub, id)) == catchTime {
return true
}
}
return false
}
func currentIsMarked227x(target *input.Input) bool {
if target == nil || target.CurrentPet == nil {
return false
}
return isCatchTimeMarked227x(target, target.CurrentPet.Info.CatchTime)
}
func markedPet227x(target *input.Input) *info.BattlePetEntity {
if target == nil {
return nil
}
for _, id := range []int{2275, 2276, 2277} {
markedCatch := markCatchTime227x(target.GetEffect(input.EffectType.Sub, id))
if markedCatch == 0 {
continue
}
if target.CurrentPet != nil && target.CurrentPet.Info.CatchTime == markedCatch && target.CurrentPet.Alive() {
return target.CurrentPet
}
for _, pet := range target.AllPet {
if pet != nil && pet.Info.CatchTime == markedCatch && pet.Alive() {
return pet
}
}
}
return nil
}
func pickBenchByCounter227x(our, opp *input.Input, pickHighest bool) *info.BattlePetEntity {
if our == nil || opp == nil || our.CurrentPet == nil {
return nil
}
var chosen *info.BattlePetEntity
var chosenMul float64
for _, pet := range opp.AllPet {
if pet == nil || !pet.Alive() || pet == opp.CurrentPet {
continue
}
if isCatchTimeMarked227x(opp, pet.Info.CatchTime) {
continue
}
mul, err := element.Calculator.GetOffensiveMultiplier(pet.GetType().ID, our.CurrentPet.GetType().ID)
if err != nil {
continue
}
if chosen == nil {
chosen = pet
chosenMul = mul
continue
}
if pickHighest && mul > chosenMul {
chosen = pet
chosenMul = mul
}
if !pickHighest && mul < chosenMul {
chosen = pet
chosenMul = mul
}
}
return chosen
}
func huntSoulStack227x(owner *input.Input) int {
if owner == nil {
return 0
}
eff := owner.GetEffect(input.EffectType.Sub, 2279)
sub, ok := eff.(*Effect2279Sub)
if !ok || sub == nil || !sub.Alive() {
return 0
}
return sub.Stack()
}
// Effect 2270: 免疫n次受到的攻击触发成功则m%令对手{2}
type Effect2270 struct{ node.EffectNode }
func (e *Effect2270) Skill_Use() bool {
if len(e.Args()) < 3 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2270, e.SideEffectArgs...)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2270Sub struct {
node.EffectNode
remaining int
}
func (e *Effect2270Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if len(a) > 0 {
e.remaining = a[0]
}
}
func (e *Effect2270Sub) DamageLockEx(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || e.remaining <= 0 {
return true
}
e.remaining--
if len(e.Args()) >= 3 && grand.N(1, 101) <= int(e.Args()[1].IntPart()) {
addStatus2270(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[2].IntPart()))
}
if e.remaining <= 0 {
e.Alive(false)
}
zone.Damage = alpacadecimal.Zero
return true
}
// Effect 2271: 自身能力提升被消除或吸取时概率令对手{2},未触发则下{3}次攻击必定致命
type Effect2271 struct{ node.EffectNode }
func (e *Effect2271) Skill_Use() bool {
if len(e.Args()) < 4 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2271, e.SideEffectArgs...)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2271Sub struct {
node.EffectNode
remainingCrit int
triggered bool
}
func (e *Effect2271Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
if len(a) == 0 {
return
}
if a[0] > 0 {
e.Duration(a[0])
return
}
e.Duration(-1)
if len(a) > 3 && a[3] > 0 {
e.remainingCrit = a[3]
}
}
func (e *Effect2271Sub) PropBefer(source *input.Input, prop int8, level int8) bool {
if len(e.Args()) < 4 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 {
return true
}
if source != e.Ctx().Opp {
return true
}
if prop < 0 || int(prop) >= len(e.Ctx().Our.Prop) {
return true
}
if level != 0 || e.Ctx().Our.Prop[prop] <= 0 {
return true
}
e.triggered = true
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100); !ok {
return true
}
addStatus2270(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[2].IntPart()))
return true
}
func (e *Effect2271Sub) TurnEnd() {
if e.Duration() == 1 && len(e.Args()) >= 4 && e.Args()[0].Cmp(alpacadecimal.Zero) > 0 && !e.triggered && e.Args()[3].Cmp(alpacadecimal.Zero) > 0 {
crit := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2271, -1, 0, 0, int(e.Args()[3].IntPart()))
if crit != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, crit)
}
}
e.EffectNode.TurnEnd()
}
func (e *Effect2271Sub) SkillHit() bool {
if e.remainingCrit <= 0 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.XML.CritRate = 16
e.remainingCrit--
if e.remainingCrit <= 0 {
e.Alive(false)
}
return true
}
// Effect 2272: 自方有其他精灵存活时造成的攻击伤害提升
type Effect2272 struct{ node.EffectNode }
func (e *Effect2272) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 {
return true
}
for _, pet := range e.Ctx().Our.AllPet {
if pet != nil && pet.Alive() && pet != e.Ctx().Our.CurrentPet {
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + int64(e.Args()[0].IntPart()))).Div(alpacadecimal.NewFromInt(100))
break
}
}
return true
}
// Effect 2273: 对手选择攻击技能时先制+3并概率令对手{1}
type Effect2273 struct{ node.EffectNode }
func (e *Effect2273) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
if len(e.Args()) < 2 {
return true
}
oppAction := actionByPlayer(fattack, sattack, e.Ctx().Opp.UserID)
if oppAction == nil || oppAction.SkillEntity == nil || oppAction.SkillEntity.Category() == info.Category.STATUS {
return true
}
ourAction := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID)
if ourAction == nil || ourAction.SkillEntity == nil {
return true
}
ourAction.SkillEntity.XML.Priority += 3
if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok {
addStatus2270(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
}
return true
}
// Effect 2274: 恢复自身全部PP值每恢复1点吸取对手{0}点体力
type Effect2274 struct{ node.EffectNode }
func (e *Effect2274) Skill_Use() bool {
if len(e.Args()) == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil {
return true
}
restored := totalLostPP(e.Ctx().Our)
e.Ctx().Our.HealPP(-1)
if restored <= 0 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 {
return true
}
drain := alpacadecimal.NewFromInt(restored).Mul(e.Args()[0])
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: drain})
e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain)
return true
}
// Effect 2275: 未击败对手则将对手标记为狩猎之的
type Effect2275 struct{ node.EffectNode }
func (e *Effect2275) Skill_Use() bool {
if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || !e.Ctx().Opp.CurrentPet.Alive() {
return true
}
applyHuntMark227x(e.Ctx().Our, e.Ctx().Opp, 2275, e.Ctx().Opp.CurrentPet.Info.CatchTime)
return true
}
type Effect2275Sub struct{ node.EffectNode }
func (e *Effect2275Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.CanStack(false)
e.Duration(-1)
}
// Effect 2276: 将对方场下对自身克制系数最高的一只非狩猎之精灵标记为狩猎之的
type Effect2276 struct{ node.EffectNode }
func (e *Effect2276) Skill_Use() bool {
target := pickBenchByCounter227x(e.Ctx().Our, e.Ctx().Opp, true)
if target == nil {
return true
}
applyHuntMark227x(e.Ctx().Our, e.Ctx().Opp, 2276, target.Info.CatchTime)
return true
}
type Effect2276Sub struct{ node.EffectNode }
func (e *Effect2276Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.CanStack(false)
e.Duration(-1)
}
// Effect 2277: 将对方场下对自身克制系数最低的一只非狩猎之精灵标记为狩猎之的
type Effect2277 struct{ node.EffectNode }
func (e *Effect2277) Skill_Use() bool {
target := pickBenchByCounter227x(e.Ctx().Our, e.Ctx().Opp, false)
if target == nil {
return true
}
applyHuntMark227x(e.Ctx().Our, e.Ctx().Opp, 2277, target.Info.CatchTime)
return true
}
type Effect2277Sub struct{ node.EffectNode }
func (e *Effect2277Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.CanStack(false)
e.Duration(-1)
}
// Effect 2278: 若对手为狩猎之的则增伤否则回合内无法主动攻击并附加等量于狩猎之的体力n%的真实伤害
type Effect2278 struct{ node.EffectNode }
func (e *Effect2278) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 3 {
return true
}
extra := int64(0)
if huntSoulStack227x(e.Ctx().Our) > 0 {
extra = e.Args()[2].IntPart()
}
if currentIsMarked227x(e.Ctx().Opp) {
bonus := e.Args()[0].IntPart() + extra
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + bonus)).Div(hundred)
return true
}
zone.Damage = alpacadecimal.Zero
return true
}
func (e *Effect2278) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
if currentIsMarked227x(e.Ctx().Opp) {
return true
}
extra := int64(0)
if huntSoulStack227x(e.Ctx().Our) > 0 {
extra = e.Args()[2].IntPart()
}
percent := e.Args()[1].IntPart() + extra
if percent <= 0 {
return true
}
marked := markedPet227x(e.Ctx().Opp)
if marked == nil {
marked = e.Ctx().Opp.CurrentPet
}
if marked == nil {
return true
}
damage := marked.GetHP().Mul(alpacadecimal.NewFromInt(percent)).Div(hundred)
if damage.Cmp(alpacadecimal.Zero) > 0 {
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.Percent,
Damage: damage,
})
}
return true
}
type Effect2278Sub struct {
node.EffectNode
remaining int
}
func (e *Effect2278Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if len(a) > 0 {
e.remaining = a[0]
}
}
func (e *Effect2278Sub) ActionStart(a, b *action.SelectSkillAction) bool {
if e.remaining <= 0 {
e.Alive(false)
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
e.Ctx().SkillEntity.SetMiss()
e.remaining--
if e.remaining <= 0 {
e.Alive(false)
}
return true
}
// Effect 2279: 击败狩猎之的时附加狩猎之魂
type Effect2279 struct{ node.EffectNode }
func (e *Effect2279) OnSkill() bool {
if e.Ctx().Our.GetEffect(input.EffectType.Sub, 2279) != nil {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2279, e.SideEffectArgs...)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2279Sub struct {
node.EffectNode
pendingMark bool
}
func (e *Effect2279Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.CanStack(false)
e.Duration(-1)
}
func (e *Effect2279Sub) SwitchOut(in *input.Input) bool {
if in != e.Ctx().Opp || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Alive() {
return true
}
if !isCatchTimeMarked227x(e.Ctx().Opp, e.Ctx().Opp.CurrentPet.Info.CatchTime) {
return true
}
e.pendingMark = true
e.Stack(e.Stack() + 1)
return true
}
func (e *Effect2279Sub) SwitchIn(in *input.Input) bool {
if !e.pendingMark || in != e.Ctx().Opp || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || !e.Ctx().Opp.CurrentPet.Alive() {
return true
}
applyHuntMark227x(e.Ctx().Our, e.Ctx().Opp, 2275, e.Ctx().Opp.CurrentPet.Info.CatchTime)
e.pendingMark = false
return true
}
func (e *Effect2279Sub) Damage_Mul(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || e.Stack() <= 0 || len(e.Args()) == 0 {
return true
}
bonus := int64(e.Stack()) * e.Args()[0].IntPart()
if bonus > 0 {
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + bonus)).Div(hundred)
}
e.Stack(0)
return true
}
// Effect 2280: 技能无效时,对手下回合无法主动切换精灵
type Effect2280 struct{ node.EffectNode }
func (e *Effect2280) Skill_Use_ex() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime != 0 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2280, 1)
if eff != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2280Sub struct{ RoundEffectArg0Base }
func (e *Effect2280Sub) SwitchOut(in *input.Input) bool {
if in != e.Ctx().Opp {
return true
}
e.Alive(false)
return false
}
// Effect 2281: 若先出手则自身下次受到致死伤害时保留1点体力
type Effect2281 struct{ node.EffectNode }
func (e *Effect2281) Skill_Use() bool {
if !e.IsFirst() {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2281)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2281Sub struct{ FixedDurationNeg1Base }
func (e *Effect2281Sub) DamageLockEx(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
return true
}
currentHP := e.Ctx().Our.CurrentPet.GetHP()
if zone.Damage.Cmp(currentHP) < 0 {
return true
}
zone.Damage = currentHP.Sub(alpacadecimal.NewFromInt(1))
e.Alive(false)
return true
}
// Effect 2282: {0}回合内使用技能恢复自身最大体力1/{1}并造成等量百分比伤害
type Effect2282 struct{ node.EffectNode }
func applyEffect2282(owner, target *input.Input, divisor, truePercent int) {
if owner == nil || target == nil || owner.CurrentPet == nil || target.CurrentPet == nil || divisor <= 0 {
return
}
heal := owner.CurrentPet.GetMaxHP().Div(alpacadecimal.NewFromInt(int64(divisor)))
if heal.Cmp(alpacadecimal.Zero) <= 0 {
return
}
owner.Heal(owner, &action.SelectSkillAction{}, heal)
beforeHP := target.CurrentPet.GetHP()
target.Damage(owner, &info.DamageZone{Type: info.DamageType.Percent, Damage: heal})
if truePercent <= 0 || beforeHP.Cmp(target.CurrentPet.GetHP()) != 0 {
return
}
trueDamage := owner.CurrentPet.GetMaxHP().Mul(alpacadecimal.NewFromInt(int64(truePercent))).Div(hundred)
if trueDamage.Cmp(alpacadecimal.Zero) > 0 {
target.Damage(owner, &info.DamageZone{Type: info.DamageType.True, Damage: trueDamage})
}
}
func (e *Effect2282) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
return true
}
rounds := int(e.Args()[0].IntPart())
divisor := int(e.Args()[1].IntPart())
truePercent := int(e.Args()[2].IntPart())
applyEffect2282(e.Ctx().Our, e.Ctx().Opp, divisor, truePercent)
if rounds <= 1 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2282, rounds-1, divisor, truePercent)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2282Sub struct{ RoundEffectArg0Base }
func (e *Effect2282Sub) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil {
return true
}
applyEffect2282(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart()))
return true
}
// Effect 2283: 消耗自身等同于护盾、护罩之和的体力平均恢复自身不在场精灵
type Effect2283 struct{ node.EffectNode }
func (e *Effect2283) Skill_Use() bool {
if len(e.Args()) < 3 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
return true
}
consumed := e.Ctx().Our.ConsumeAllShield()
if consumed.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{
Type: info.DamageType.True,
Damage: consumed,
})
benchCount := 0
for _, pet := range e.Ctx().Our.AllPet {
if pet == nil || pet == e.Ctx().Our.CurrentPet || pet.Info.Hp == 0 {
continue
}
benchCount++
}
if benchCount > 0 {
healEach := consumed.Div(alpacadecimal.NewFromInt(int64(benchCount)))
if healEach.Cmp(alpacadecimal.Zero) > 0 {
for _, pet := range e.Ctx().Our.AllPet {
if pet == nil || pet == e.Ctx().Our.CurrentPet || pet.Info.Hp == 0 {
continue
}
pet.Info.ModelHP(healEach.IntPart())
}
}
}
if consumed.Cmp(e.Args()[0]) <= 0 {
return true
}
clearedTotal := consumed
if e.Ctx().Opp != nil {
clearedTotal = clearedTotal.Add(e.Ctx().Opp.ConsumeAllShield())
}
bonusShield := clearedTotal.Mul(e.Args()[1]).Div(hundred)
if bonusShield.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 {
maxBonus := e.Ctx().Our.CurrentPet.GetMaxHP().Mul(e.Args()[2]).Div(hundred)
if maxBonus.Cmp(alpacadecimal.Zero) > 0 && bonusShield.Cmp(maxBonus) > 0 {
bonusShield = maxBonus
}
}
if bonusShield.Cmp(alpacadecimal.Zero) > 0 {
e.Ctx().Our.AddShield(bonusShield)
}
return true
}
// Effect 2284: 剥夺对手系别并附加控制类异常与系别伤害
type Effect2284 struct{ node.EffectNode }
func addRandomControlStatus2284(owner, target *input.Input, count int) {
if owner == nil || target == nil || count <= 0 {
return
}
statuses := []int{
int(info.PetStatus.Paralysis),
int(info.PetStatus.Fear),
int(info.PetStatus.Tired),
int(info.PetStatus.Petrified),
int(info.PetStatus.Sleep),
}
if count > len(statuses) {
count = len(statuses)
}
for _, idx := range grand.Perm(len(statuses))[:count] {
addStatus2270(owner, target, statuses[idx])
}
}
func (e *Effect2284) Skill_Use() bool {
if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil {
return true
}
if e.Ctx().Opp.CurrentPet.PetInfo.Type == int(element.ElementTypeNormal) {
return true
}
e.Ctx().Opp.CurrentPet.PetInfo.Type = int(element.ElementTypeNormal)
addRandomControlStatus2284(e.Ctx().Our, e.Ctx().Opp, 1)
rounds := int(e.Args()[0].IntPart())
damagePerType := int(e.Args()[1].IntPart())
if rounds <= 0 || damagePerType <= 0 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2284, rounds, damagePerType)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2284Sub struct{ RoundEffectArg0Base }
func (e *Effect2284Sub) Action_end() bool {
if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil {
return true
}
activeStatus := countAliveStatusKinds(e.Ctx().Opp)
if activeStatus <= 0 {
return true
}
damage := e.Args()[1].Mul(alpacadecimal.NewFromInt(int64(activeStatus)))
if damage.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage})
return true
}
// Effect 2285: {0}回合内对手无法通过技能恢复体力;若对手当回合未选择技能则改为{1}回合内对手体力恢复效果减少{2}%
type Effect2285 struct {
node.EffectNode
oppSelectedSkill bool
}
func (e *Effect2285) ComparePre(fattack, sattack *action.SelectSkillAction) bool {
current := actionByPlayer(fattack, sattack, e.Ctx().Opp.UserID)
e.oppSelectedSkill = current != nil && current.SkillEntity != nil
return true
}
func (e *Effect2285) Skill_Use() bool {
if len(e.Args()) < 3 {
return true
}
rounds := int(e.Args()[0].IntPart())
reduce := 0
mode := 0 // 0: block skill-heal; 1: reduce all healing
if !e.oppSelectedSkill {
rounds = int(e.Args()[1].IntPart())
reduce = int(e.Args()[2].IntPart())
mode = 1
}
if rounds <= 0 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2285, rounds, reduce, mode)
if eff != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2285Sub struct{ RoundEffectArg0Base }
func (e *Effect2285Sub) Heal_Pre(ac action.BattleActionI, amount *int) bool {
if amount == nil || *amount <= 0 {
return true
}
// Fallback mode: reduce healing directly.
if len(e.Args()) >= 3 && e.Args()[2].IntPart() == 1 {
reduce := int(e.Args()[1].IntPart())
if reduce < 0 {
reduce = 0
}
if reduce > 100 {
reduce = 100
}
*amount = *amount * (100 - reduce) / 100
return true
}
// Default mode: only block healing caused by skill actions.
if _, ok := ac.(*action.SelectSkillAction); ok {
*amount = 0
}
return true
}
// Effect 2286: 对手n次回合类效果、能力提升效果被消除时体力上限减少
type Effect2286 struct{ node.EffectNode }
func (e *Effect2286) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2286, e.SideEffectArgs...)
if eff != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2286Sub struct {
node.EffectNode
remaining int
reduceMax int
}
func (e *Effect2286Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if len(a) > 0 {
e.remaining = a[0]
}
if len(a) > 1 {
e.reduceMax = a[1]
}
}
func (e *Effect2286Sub) PropBefer(_ *input.Input, prop, level int8) bool {
if e.remaining <= 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
e.Alive(false)
return true
}
if level != 0 || prop < 0 || int(prop) >= len(e.Ctx().Our.Prop) || e.Ctx().Our.Prop[prop] <= 0 {
return true
}
if e.reduceMax > 0 {
oldMax := int(e.Ctx().Our.CurrentPet.Info.MaxHp)
if oldMax > 1 {
newMax := oldMax - e.reduceMax
if newMax < 1 {
newMax = 1
}
e.Ctx().Our.CurrentPet.Info.MaxHp = uint32(newMax)
if e.Ctx().Our.CurrentPet.Info.Hp > e.Ctx().Our.CurrentPet.Info.MaxHp {
e.Ctx().Our.CurrentPet.Info.Hp = e.Ctx().Our.CurrentPet.Info.MaxHp
}
}
}
e.remaining--
if e.remaining <= 0 {
e.Alive(false)
}
return true
}
// Effect 2287: {0}回合内使用技能恢复自身最大体力1/{1}并造成等量百分比伤害,溢出转化为护罩
type Effect2287 struct{ node.EffectNode }
func applyEffect2287(owner, target *input.Input, divisor int) {
if owner == nil || owner.CurrentPet == nil || target == nil || target.CurrentPet == nil || divisor <= 0 {
return
}
heal := owner.CurrentPet.GetMaxHP().Div(alpacadecimal.NewFromInt(int64(divisor)))
if heal.Cmp(alpacadecimal.Zero) <= 0 {
return
}
before := owner.CurrentPet.GetHP()
owner.Heal(owner, &action.SelectSkillAction{}, heal)
after := owner.CurrentPet.GetHP()
actual := after.Sub(before)
if actual.Cmp(alpacadecimal.Zero) < 0 {
actual = alpacadecimal.Zero
}
overflow := heal.Sub(actual)
if overflow.Cmp(alpacadecimal.Zero) > 0 {
owner.AddShield(overflow)
}
target.Damage(owner, &info.DamageZone{Type: info.DamageType.Percent, Damage: heal})
}
func (e *Effect2287) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
rounds := int(e.Args()[0].IntPart())
divisor := int(e.Args()[1].IntPart())
applyEffect2287(e.Ctx().Our, e.Ctx().Opp, divisor)
if rounds <= 1 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2287, rounds-1, divisor)
if eff != nil {
e.Ctx().Our.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2287Sub struct{ RoundEffectArg0Base }
func (e *Effect2287Sub) Skill_Use() bool {
if len(e.Args()) < 2 {
return true
}
applyEffect2287(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart()))
return true
}
// Effect 2288: 技能无效时为对手附加3回合的琼花仙荼
type Effect2288 struct{ node.EffectNode }
func (e *Effect2288) Skill_Use_ex() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime != 0 {
return true
}
eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2288, 3)
if eff != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, eff)
}
return true
}
type Effect2288Sub struct{ RoundEffectArg0Base }
func (e *Effect2288Sub) ActionStartEx(fattack, sattack *action.SelectSkillAction) bool {
if e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil {
return true
}
damage := e.Ctx().Our.CurrentPet.GetMaxHP().Div(alpacadecimal.NewFromInt(6))
if damage.Cmp(alpacadecimal.Zero) > 0 {
source := e.Ctx().Opp
if source == nil {
source = e.Ctx().Our
}
e.Ctx().Our.Damage(source, &info.DamageZone{Type: info.DamageType.True, Damage: damage})
}
return true
}
func (e *Effect2288Sub) Heal_Pre(ac action.BattleActionI, amount *int) bool {
if amount == nil || *amount == 0 {
return true
}
if _, ok := ac.(*action.UseItemAction); ok && *amount > 0 {
*amount = -*amount
}
if *amount <= 0 {
return true
}
source := e.Ctx().Opp
if source == nil {
source = e.Ctx().Our
}
poison := source.InitEffect(input.EffectType.Status, int(info.PetStatus.Poisoned))
if poison != nil {
poison.Duration(2)
e.Ctx().Our.AddEffect(source, poison)
}
return true
}
// Effect 2289: 自身每点亮1颗雷辰威力提升{0}点若未点亮雷辰则每存活1只己方精灵伤害不低于{1}
type Effect2289 struct{ node.EffectNode }
func (e *Effect2289) SkillHit() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || len(e.Args()) == 0 {
return true
}
energy := e.Ctx().Our.CurrentDivineEnergy()
if energy <= 0 {
return true
}
e.Ctx().SkillEntity.XML.Power += energy * int(e.Args()[0].IntPart())
return true
}
func (e *Effect2289) DamageFloor(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 {
return true
}
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 {
return true
}
if e.Ctx().Our.CurrentDivineEnergy() > 0 {
return true
}
aliveCount := 0
for _, pet := range e.Ctx().Our.AllPet {
if pet != nil && pet.Alive() {
aliveCount++
}
}
if aliveCount <= 0 {
return true
}
floor := e.Args()[1].Mul(alpacadecimal.NewFromInt(int64(aliveCount)))
if zone.Damage.Cmp(floor) < 0 {
zone.Damage = floor
}
return true
}
// Effect 2290: 自身每点雷霆全属性+1
type Effect2290 struct{ node.EffectNode }
func boostAllProps2294(owner *input.Input, level int) {
if owner == nil || level == 0 {
return
}
if level > 0 {
for step := 0; step < level; step++ {
for i := range owner.Prop[:] {
owner.SetProp(owner, int8(i), 1)
}
}
return
}
for step := 0; step < -level; step++ {
for i := range owner.Prop[:] {
owner.SetProp(owner, int8(i), -1)
}
}
}
func getMartialState2294(owner *input.Input, create bool) *Effect2294Sub {
if owner == nil {
return nil
}
if eff := owner.GetEffect(input.EffectType.Sub, 2294); eff != nil {
if state, ok := eff.(*Effect2294Sub); ok {
if state.track == 0 {
state.track = 1
}
return state
}
}
if !create {
return nil
}
eff := owner.InitEffect(input.EffectType.Sub, 2294)
if eff == nil {
return nil
}
owner.AddEffect(owner, eff)
state, ok := eff.(*Effect2294Sub)
if !ok {
return nil
}
if state.track == 0 {
state.track = 1
}
return state
}
func (e *Effect2290) SkillHit() bool {
if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS {
return true
}
state := getMartialState2294(e.Ctx().Our, false)
if state == nil {
return true
}
energy := e.Ctx().Our.CurrentDivineEnergy()
if energy <= state.appliedLightning {
return true
}
delta := energy - state.appliedLightning
boostAllProps2294(e.Ctx().Our, delta)
state.appliedLightning = energy
return true
}
// Effect 2291: 自身武道衔化轨迹为正转时...
type Effect2291 struct{ node.EffectNode }
type Effect2291Sub struct {
node.EffectNode
mode int
reduce int
}
func (e *Effect2291Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
e.mode = 1
e.reduce = 0
if len(a) > 0 {
e.Duration(a[0])
}
if len(a) > 1 {
e.reduce = a[1]
}
if len(a) > 2 {
e.mode = a[2]
}
if e.mode == 0 {
e.mode = 1
}
if e.reduce < 0 {
e.reduce = 0
}
if e.reduce > 100 {
e.reduce = 100
}
}
func (e *Effect2291Sub) Heal_Pre(ac action.BattleActionI, value *int) bool {
if e.mode != 1 || value == nil || *value <= 0 {
return true
}
if _, ok := ac.(*action.SelectSkillAction); !ok || ac.GetPlayerID() != e.Ctx().Our.UserID {
return true
}
*value = 0
return true
}
func (e *Effect2291Sub) Damage_Mul(zone *info.DamageZone) bool {
if e.mode != -1 || e.reduce <= 0 || zone == nil || zone.Type != info.DamageType.Red {
return true
}
zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(int64(100 - e.reduce))).Div(alpacadecimal.NewFromInt(100))
return true
}
func (e *Effect2291) OnSkill() bool {
if len(e.Args()) < 3 {
return true
}
state := getMartialState2294(e.Ctx().Our, true)
if state == nil {
return true
}
if state.track < 0 {
duration := int(e.Args()[1].IntPart())
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2291, duration, int(e.Args()[2].IntPart()), -1)
if sub != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, sub)
}
return true
}
duration := int(e.Args()[0].IntPart())
sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2291, duration, 0, 1)
if sub != nil {
e.Ctx().Opp.AddEffect(e.Ctx().Our, sub)
}
return true
}
// Effect 2292: 将自身武道衔化轨迹改为逆转并反弹武道正转期间吸收的伤害
type Effect2292 struct{ node.EffectNode }
func (e *Effect2292) OnSkill() bool {
if len(e.Args()) == 0 {
return true
}
state := getMartialState2294(e.Ctx().Our, true)
if state == nil {
return true
}
state.track = -1
capDamage := e.Ctx().Our.CurrentPet.GetMaxHP().Mul(e.Args()[0]).Div(alpacadecimal.NewFromInt(100))
if capDamage.Cmp(alpacadecimal.Zero) > 0 {
damage := state.blockedDamage
if damage.Cmp(capDamage) > 0 {
damage = capDamage
}
if damage.Cmp(alpacadecimal.Zero) > 0 {
e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage})
}
}
state.blockedDamage = alpacadecimal.Zero
return true
}
// Effect 2293: 复原自身的武道衔化轨迹每n次衔化时全属性+1
type Effect2293 struct{ node.EffectNode }
func (e *Effect2293) Skill_Use() bool {
if len(e.Args()) == 0 {
return true
}
state := getMartialState2294(e.Ctx().Our, true)
if state == nil {
return true
}
state.track = 1
state.pendingBoost += int(e.Args()[0].IntPart())
if state.pendingBoost < 0 {
state.pendingBoost = 0
}
state.blockedDamage = alpacadecimal.Zero
return true
}
// Effect 2294: 衔化自身的武道
type Effect2294 struct{ node.EffectNode }
type Effect2294Sub struct {
node.EffectNode
track int
lightning int
appliedLightning int
pendingBoost int
blockedDamage alpacadecimal.Decimal
}
func (e *Effect2294Sub) SetArgs(t *input.Input, a ...int) {
e.EffectNode.SetArgs(t, a...)
e.Duration(-1)
if e.track == 0 {
e.track = 1
}
}
func (e *Effect2294Sub) Damage_Shield(zone *info.DamageZone) bool {
if zone == nil || zone.Type != info.DamageType.Red || zone.Damage.Cmp(alpacadecimal.Zero) <= 0 || e.track <= 0 {
return true
}
shield := e.Ctx().Our.CurrentShield()
if shield.Cmp(alpacadecimal.Zero) <= 0 {
return true
}
blocked := alpacadecimal.Min(shield, zone.Damage)
if blocked.Cmp(alpacadecimal.Zero) > 0 {
e.blockedDamage = e.blockedDamage.Add(blocked)
}
return true
}
func (e *Effect2294) Skill_Use() bool {
state := getMartialState2294(e.Ctx().Our, true)
if state == nil {
return true
}
state.lightning++
if state.pendingBoost > 0 {
boostAllProps2294(e.Ctx().Our, 1)
state.pendingBoost--
}
return true
}
func init() {
input.InitEffect(input.EffectType.Skill, 2270, &Effect2270{})
input.InitEffect(input.EffectType.Sub, 2270, &Effect2270Sub{})
input.InitEffect(input.EffectType.Skill, 2271, &Effect2271{})
input.InitEffect(input.EffectType.Sub, 2271, &Effect2271Sub{})
input.InitEffect(input.EffectType.Skill, 2272, &Effect2272{})
input.InitEffect(input.EffectType.Skill, 2273, &Effect2273{})
input.InitEffect(input.EffectType.Skill, 2274, &Effect2274{})
input.InitEffect(input.EffectType.Skill, 2275, &Effect2275{})
input.InitEffect(input.EffectType.Sub, 2275, &Effect2275Sub{})
input.InitEffect(input.EffectType.Skill, 2276, &Effect2276{})
input.InitEffect(input.EffectType.Sub, 2276, &Effect2276Sub{})
input.InitEffect(input.EffectType.Skill, 2277, &Effect2277{})
input.InitEffect(input.EffectType.Sub, 2277, &Effect2277Sub{})
input.InitEffect(input.EffectType.Skill, 2278, &Effect2278{})
input.InitEffect(input.EffectType.Sub, 2278, &Effect2278Sub{})
input.InitEffect(input.EffectType.Skill, 2279, &Effect2279{})
input.InitEffect(input.EffectType.Sub, 2279, &Effect2279Sub{})
input.InitEffect(input.EffectType.Skill, 2280, &Effect2280{})
input.InitEffect(input.EffectType.Sub, 2280, &Effect2280Sub{})
input.InitEffect(input.EffectType.Skill, 2281, &Effect2281{})
input.InitEffect(input.EffectType.Sub, 2281, &Effect2281Sub{})
input.InitEffect(input.EffectType.Skill, 2282, &Effect2282{})
input.InitEffect(input.EffectType.Sub, 2282, &Effect2282Sub{})
input.InitEffect(input.EffectType.Skill, 2283, &Effect2283{})
input.InitEffect(input.EffectType.Skill, 2284, &Effect2284{})
input.InitEffect(input.EffectType.Sub, 2284, &Effect2284Sub{})
input.InitEffect(input.EffectType.Skill, 2285, &Effect2285{})
input.InitEffect(input.EffectType.Sub, 2285, &Effect2285Sub{})
input.InitEffect(input.EffectType.Skill, 2286, &Effect2286{})
input.InitEffect(input.EffectType.Sub, 2286, &Effect2286Sub{})
input.InitEffect(input.EffectType.Skill, 2287, &Effect2287{})
input.InitEffect(input.EffectType.Sub, 2287, &Effect2287Sub{})
input.InitEffect(input.EffectType.Skill, 2288, &Effect2288{})
input.InitEffect(input.EffectType.Sub, 2288, &Effect2288Sub{})
input.InitEffect(input.EffectType.Skill, 2289, &Effect2289{})
input.InitEffect(input.EffectType.Skill, 2290, &Effect2290{})
input.InitEffect(input.EffectType.Skill, 2291, &Effect2291{})
input.InitEffect(input.EffectType.Sub, 2291, &Effect2291Sub{})
input.InitEffect(input.EffectType.Skill, 2292, &Effect2292{})
input.InitEffect(input.EffectType.Skill, 2293, &Effect2293{})
input.InitEffect(input.EffectType.Skill, 2294, &Effect2294{})
input.InitEffect(input.EffectType.Sub, 2294, &Effect2294Sub{})
}