feat(effect): 实现多个战斗效果功能 - 实现了effects 2195-2199的功能,包括消除对手回合类效果、概率附加效果、 护盾/护罩状态下触发的效果等 - 实现了effects 2220-2239的功能,包括攻击特攻最高值转换、闪避与PP归零、 伤害提升、恢复体力、回合效果管理等功能 - 实现了effects 2270-2294的部分功能修复,调整了精灵
1342 lines
35 KiB
Go
1342 lines
35 KiB
Go
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{})
|
||
}
|