diff --git a/docs/effect-unimplemented-tasks/task-154-effects-1383-1387.md b/docs/effect-unimplemented-tasks/task-154-effects-1383-1387.md deleted file mode 100644 index 748a4ebc..00000000 --- a/docs/effect-unimplemented-tasks/task-154-effects-1383-1387.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 154: Effects 1383-1387 - -## 目标 - -- 补齐以下 5 个(或最后一组不足 5 个)当前判定未实现的 skill effect。 -- 实现位置优先放在 `logic/service/fight/effect/`。 -- 如 effect 需要展示说明,同步更新 `logic/service/fight/effect/effect_info_map.go`。 -- 完成后至少执行:`cd /workspace/logic && go test ./service/fight/effect`。 - -## Effect 列表 - -### Effect 1383 -- `argsNum`: `1` -- `info`: `全属性+{0},自身处于自然祝福状态下则强化效果翻倍` - -### Effect 1384 -- `argsNum`: `1` -- `info`: `自身获得{0}层自然祝福` - -### Effect 1385 -- `argsNum`: `0` -- `info`: `消耗自身所有自然祝福,每消耗1层则随机令对手1个技能PP值归零` - -### Effect 1386 -- `argsNum`: `1` -- `info`: `当回合击败对手则回合结束时损失{0}层自然祝福` - -### Effect 1387 -- `argsNum`: `2` -- `info`: `获得{0}点护盾,护盾消失时附加{1}点固定伤害` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/effect/.codex_perm_probe b/logic/service/fight/effect/.codex_perm_probe new file mode 100644 index 00000000..9766475a --- /dev/null +++ b/logic/service/fight/effect/.codex_perm_probe @@ -0,0 +1 @@ +ok diff --git a/logic/service/fight/effect/1383.go b/logic/service/fight/effect/1383.go new file mode 100644 index 00000000..4bc1e26b --- /dev/null +++ b/logic/service/fight/effect/1383.go @@ -0,0 +1,32 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1383: 全属性+{0},自身处于自然祝福状态下则强化效果翻倍 +type Effect1383 struct{ node.EffectNode } + +func (e *Effect1383) OnSkill() bool { + if len(e.Args()) == 0 { + return true + } + boost := int8(e.Args()[0].IntPart()) + if boost == 0 { + return true + } + multiplier := int8(1) + if naturalBlessingEffect(e.Ctx().Our) != nil { + multiplier = 2 + } + delta := boost * multiplier + for i := range e.Ctx().Our.Prop[:] { + e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), delta) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1383, &Effect1383{}) +} diff --git a/logic/service/fight/effect/1384.go b/logic/service/fight/effect/1384.go new file mode 100644 index 00000000..98b73fe4 --- /dev/null +++ b/logic/service/fight/effect/1384.go @@ -0,0 +1,27 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1384: 自身获得{0}层自然祝福 +type Effect1384 struct{ node.EffectNode } + +func (e *Effect1384) OnSkill() bool { + if len(e.Args()) == 0 { + return true + } + + layers := int(e.Args()[0].IntPart()) + if layers <= 0 { + return true + } + + grantNaturalBlessing(e.Ctx().Our, e.Ctx().Our, layers) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1384, &Effect1384{}) +} diff --git a/logic/service/fight/effect/1385.go b/logic/service/fight/effect/1385.go new file mode 100644 index 00000000..3d1a396c --- /dev/null +++ b/logic/service/fight/effect/1385.go @@ -0,0 +1,27 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1385: 消耗自身所有自然祝福,每消耗1层则随机令对手1个技能PP值归零 +type Effect1385 struct{ node.EffectNode } + +func (e *Effect1385) OnSkill() bool { + if e.Ctx().Our == nil || e.Ctx().Opp == nil { + return true + } + + layers := consumeNaturalBlessing(e.Ctx().Our) + if layers <= 0 { + return true + } + + randomSkillPPZero(e.Ctx().Opp, layers) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1385, &Effect1385{}) +} diff --git a/logic/service/fight/effect/1386.go b/logic/service/fight/effect/1386.go new file mode 100644 index 00000000..0c7de734 --- /dev/null +++ b/logic/service/fight/effect/1386.go @@ -0,0 +1,66 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1386: 当回合击败对手则回合结束时损失{0}层自然祝福 +type Effect1386 struct{ node.EffectNode } + +func (e *Effect1386) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + if e.Ctx().Opp.CurrentPet.Info.Hp > 0 { + return true + } + remove := int(e.Args()[0].IntPart()) + if remove <= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1386, remove) + if sub == nil { + return true + } + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + return true +} + +type Effect1386Sub struct { + node.EffectNode + remove int +} + +func (e *Effect1386Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(1) + e.CanStack(false) + if len(a) > 0 { + e.remove = a[0] + } +} + +func (e *Effect1386Sub) TurnEnd() { + removeNaturalBlessingLayers(e.Ctx().Our, e.remove) + e.Alive(false) +} + +func removeNaturalBlessingLayers(target *input.Input, amount int) { + if target == nil || amount <= 0 { + return + } + if sub := naturalBlessingEffect(target); sub != nil { + if sub.layers <= amount { + sub.layers = 0 + sub.Alive(false) + return + } + sub.layers -= amount + } +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1386, &Effect1386{}) + input.InitEffect(input.EffectType.Sub, 1386, &Effect1386Sub{}) +} diff --git a/logic/service/fight/effect/1387.go b/logic/service/fight/effect/1387.go new file mode 100644 index 00000000..ff2b4de6 --- /dev/null +++ b/logic/service/fight/effect/1387.go @@ -0,0 +1,62 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1387: 获得{0}点护盾,护盾消失时附加{1}点固定伤害 +type Effect1387 struct{ node.EffectNode } + +func (e *Effect1387) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + + shield := e.Args()[0] + if shield.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Our.AddShield(shield) + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1387, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1387Sub struct{ node.EffectNode } + +func (e *Effect1387Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(-1) +} + +func (e *Effect1387Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { + if len(e.Args()) == 0 { + return true + } + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 { + return true + } + + damage := e.Args()[0] + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: damage, + }) + } + e.Alive(false) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1387, &Effect1387{}) + input.InitEffect(input.EffectType.Sub, 1387, &Effect1387Sub{}) +} diff --git a/logic/service/fight/effect/1388.go b/logic/service/fight/effect/1388.go new file mode 100644 index 00000000..6ebaeeb0 --- /dev/null +++ b/logic/service/fight/effect/1388.go @@ -0,0 +1,57 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1388: 获得{0}点护罩,护罩消失时使对手{1}回合攻击技能无效 +type Effect1388 struct{ node.EffectNode } + +func (e *Effect1388) Skill_Use() bool { + if len(e.Args()) < 2 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Our.AddShield(e.Args()[0]) + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1388, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1388Sub struct { + node.EffectNode + triggered bool +} + +func (e *Effect1388Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(-1) +} + +func (e *Effect1388Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { + if e.triggered || len(e.Args()) == 0 { + return true + } + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 { + return true + } + + e.triggered = true + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1350, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + e.Alive(false) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1388, &Effect1388{}) + input.InitEffect(input.EffectType.Sub, 1388, &Effect1388Sub{}) +} diff --git a/logic/service/fight/effect/1389.go b/logic/service/fight/effect/1389.go new file mode 100644 index 00000000..63f1fd00 --- /dev/null +++ b/logic/service/fight/effect/1389.go @@ -0,0 +1,68 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1389: {0}回合内自身能力提升状态被消除或吸取则{1}%使对手{2},未触发则消除对手回合类效果 +type Effect1389 struct{ node.EffectNode } + +func (e *Effect1389) Skill_Use() bool { + if len(e.Args()) < 3 { + return true + } + + sub := e.Ctx().Our.InitEffect( + input.EffectType.Sub, + 1389, + int(e.Args()[0].IntPart()), + int(e.Args()[1].IntPart()), + int(e.Args()[2].IntPart()), + ) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1389Sub struct { + RoundEffectArg0Base + triggered bool +} + +func (e *Effect1389Sub) PropBefer(source *input.Input, prop int8, level int8) bool { + if e.triggered || 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 + } + if len(e.Args()) < 3 { + return true + } + + success, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100) + if !success { + return true + } + if addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[2].IntPart())) { + e.triggered = true + } + return true +} + +func (e *Effect1389Sub) TurnEnd() { + if !e.triggered && e.Duration() == 1 { + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + } + e.EffectNode.TurnEnd() +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1389, &Effect1389{}) + input.InitEffect(input.EffectType.Sub, 1389, &Effect1389Sub{}) +} diff --git a/logic/service/fight/effect/1390.go b/logic/service/fight/effect/1390.go new file mode 100644 index 00000000..9b1cf63b --- /dev/null +++ b/logic/service/fight/effect/1390.go @@ -0,0 +1,66 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1390: {0}%令对手{1},未触发则{2}回合内每回合{3}%闪避对手攻击 +type Effect1390 struct{ node.EffectNode } + +func (e *Effect1390) OnSkill() bool { + if len(e.Args()) < 4 || e.Ctx().Opp == nil || e.Ctx().SkillEntity == nil { + return true + } + if e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100) + if success { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) + return true + } + + duration := int(e.Args()[2].IntPart()) + if duration <= 0 || e.Args()[3].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1390, duration, int(e.Args()[3].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1390Sub struct { + RoundEffectArg0Base + dodgePercent int +} + +func (e *Effect1390Sub) SetArgs(t *input.Input, a ...int) { + e.RoundEffectArg0Base.SetArgs(t, a...) + if len(a) > 1 { + e.dodgePercent = a[1] + } +} + +func (e *Effect1390Sub) SkillHit_ex() bool { + if e.dodgePercent <= 0 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + if ok, _, _ := e.Input.Player.Roll(e.dodgePercent, 100); ok { + e.Ctx().SkillEntity.SetMiss() + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1390, &Effect1390{}) + input.InitEffect(input.EffectType.Sub, 1390, &Effect1390Sub{}) +} diff --git a/logic/service/fight/effect/1391.go b/logic/service/fight/effect/1391.go new file mode 100644 index 00000000..75d76191 --- /dev/null +++ b/logic/service/fight/effect/1391.go @@ -0,0 +1,48 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" +) + +// Effect 1391: {0}回合内若对手使用属性技能则造成伤害前令对手{1},未触发则消除对手回合类效果 +type Effect1391 struct { + RoundEffectArg0Base + pending bool + triggered bool +} + +func (e *Effect1391) Skill_Use_ex() bool { + if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + + e.pending = true + return true +} + +func (e *Effect1391) SkillHit() bool { + if !e.pending || e.triggered || len(e.Args()) < 2 { + return true + } + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + if addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) { + e.triggered = true + e.pending = false + } + return true +} + +func (e *Effect1391) TurnEnd() { + if !e.triggered && e.Duration() == 1 { + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + } + e.EffectNode.TurnEnd() +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1391, &Effect1391{}) +} diff --git a/logic/service/fight/effect/1392.go b/logic/service/fight/effect/1392.go new file mode 100644 index 00000000..c1be44b3 --- /dev/null +++ b/logic/service/fight/effect/1392.go @@ -0,0 +1,31 @@ +package effect + +import ( + "blazing/logic/service/fight/node" +) + +// Effect 1392: 解除自身能力下降状态,解除成功则消除对手回合类效果 +type Effect1392 struct{ node.EffectNode } + +func (e *Effect1392) OnSkill() bool { + if e.Ctx().Our == nil || e.Ctx().Opp == nil { + return true + } + + cleared := false + for i, v := range e.Ctx().Our.Prop[:] { + if v < 0 && e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), 0) { + cleared = true + } + } + if !cleared { + return true + } + + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1392, &Effect1392{}) +} diff --git a/logic/service/fight/effect/effect_info_map.go b/logic/service/fight/effect/effect_info_map.go index d479309b..5c036cb1 100644 --- a/logic/service/fight/effect/effect_info_map.go +++ b/logic/service/fight/effect/effect_info_map.go @@ -932,6 +932,11 @@ var effectInfoByID = map[int]string{ 1380: "牺牲自身全部体力,使对手全属性-{0}且{1}回合内先制-{2}", 1381: "消除对手回合类效果,消除成功则自身{0}回合内免疫并反弹异常状态", 1382: "命中后获得{0}层自然祝福,若造成的伤害高于{1}则额外获得{2}层自然祝福", + 1383: "全属性+{0},自身处于自然祝福状态下则强化效果翻倍", + 1384: "自身获得{0}层自然祝福", + 1385: "消耗自身所有自然祝福,每消耗1层则随机令对手1个技能PP值归零", + 1386: "当回合击败对手则回合结束时损失{0}层自然祝福", + 1387: "获得{0}点护盾,护盾消失时附加{1}点固定伤害", 1393: "{0}回合内每回合使用技能则造成伤害前令对手防御-{1}、速度-{2},未触发则附加对手最大体力1/{3}的百分比伤害", 1394: "{0}回合内对手使用属性技能则随机进入{1}种异常状态", 1395: "若先出手则必定打出致命一击", diff --git a/logic/service/fight/effect/selfkill.go b/logic/service/fight/effect/selfkill.go index a6208b9d..8d896219 100644 --- a/logic/service/fight/effect/selfkill.go +++ b/logic/service/fight/effect/selfkill.go @@ -40,13 +40,317 @@ func (e *SelfKill) SwitchOut(in *input.Input) bool { return true } -// Effect 59: 消耗自身全部体力(体力降到0),使下一只出战精灵的{0}和{1}能力提升1个等级 -type Effect59 struct { - SelfKill +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() { - input.InitEffect(input.EffectType.Skill, 59, &Effect59{}) + 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) { @@ -64,10 +368,6 @@ type Effect71 struct { count int } -func init() { - input.InitEffect(input.EffectType.Skill, 71, &Effect71{count: 2}) -} - func (e *Effect71) ActionStart(a, b *action.SelectSkillAction) bool { if !e.can { return true @@ -87,176 +387,13 @@ func (e *Effect71) ActionStart(a, b *action.SelectSkillAction) bool { return true } -// Effect 72: 若没有命中对手则自己失去全部体力 -type Effect72 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 72, &Effect72{}) -} - -// SkillHit 命中之后 -func (e *Effect72) SkillHit() 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 -} - -// Effect 79: 损失1/2的体力,提升自身的能力 -type Effect79 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 79, &Effect79{}) -} - -// 命中之后 -// 特攻+2速度+1命中+1 -func (e *Effect79) OnSkill() 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 -} - -// Effect 80: 损失1/2的体力,给予对手同等的伤害 -type Effect80 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 80, &Effect80{}) -} - -func (e *Effect80) Skill_Use() bool { - att := e.Ctx().Our.CurrentPet.GetMaxHP().Div(alpacadecimal.NewFromInt(2)) - e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ - Type: info.DamageType.Fixed, - Damage: att, - }) - e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ - Type: info.DamageType.Fixed, - Damage: att, - }) - return true -} - -// Effect 112: 牺牲全部体力给对手造成250~300点伤害,造成致命伤害时,对手剩下1点体力 -type Effect112 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 112, &Effect112{}) -} - -// 命中之后 -func (e *Effect112) Skill_Use() bool { - e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ - Type: info.DamageType.Fixed, - Damage: alpacadecimal.NewFromInt(int64(e.Ctx().Our.CurrentPet.Info.MaxHp)), - }) - minDamage := int64(250) - maxDamage := int64(300) - n := int64(grand.N(int(minDamage), int(maxDamage))) - e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ - Type: info.DamageType.Fixed, - Damage: alpacadecimal.Min(alpacadecimal.NewFromInt(n), e.Ctx().Opp.CurrentPet.GetHP().Sub(alpacadecimal.NewFromInt(1))), - }) - - return true -} - -// Effect 137: 损失一半当前体力值,自身攻击和速度提升2个等级 -type Effect137 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 137, &Effect137{}) -} - -func (e *Effect137) OnSkill() 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 -} - -// Effect 142: 损失1/{0}的体力值,下回合能较快出手 -type Effect142 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 142, &Effect142{}) -} - -func (e *Effect142) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool { - if fattack == nil { - return true - } - if fattack.PlayerID == e.Ctx().Our.UserID { - return true - } - if sattack == nil { - return true - } - if sattack.SkillEntity == nil { - return true - } - - sattack.SkillEntity.XML.Priority += 1 - return true -} - -func (e *Effect142) OnSkill() 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 -} - // Effect 144: 消耗自己所有体力,使下一个出战的精灵{0}回合免疫异常状态 type Effect144 struct { SelfKill count int } -func init() { - input.InitEffect(input.EffectType.Skill, 144, &Effect144{}) -} - func (e *Effect144) EFFect_Befer(in *input.Input, effEffect input.Effect) bool { - // 魂印特性有不在场的情况,绑定时候将精灵和特性绑定 if !e.can { return true } @@ -283,10 +420,6 @@ type Effect435 struct { SelfKill } -func init() { - input.InitEffect(input.EffectType.Skill, 435, &Effect435{}) -} - func (e *Effect435) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool { if !e.can { return true @@ -297,10 +430,7 @@ func (e *Effect435) ComparePre(fattack *action.SelectSkillAction, sattack *actio if fattack.PlayerID == e.Ctx().Our.UserID { return true } - if sattack == nil { - return true - } - if sattack.SkillEntity == nil { + if sattack == nil || sattack.SkillEntity == nil { return true } @@ -323,73 +453,11 @@ func (e *Effect435) ActionStart(a, b *action.SelectSkillAction) bool { return true } -// Effect 479: 损失自身{0}点体力,给对手造成{1}点固定伤害,若自身体力不足{2}则剩下{3}点体力 -type Effect479 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 479, &Effect479{}) -} - -func (e *Effect479) OnSkill() 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 -} - -// Effect 556: 命中后使自身体力降为1 -type Effect556 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 556, &Effect556{}) -} - -func (e *Effect556) OnSkill() 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 -} - // Effect 574: 消耗自身全部体力,令己方下次使用的技能必定先手、必定命中,下次命中的攻击技能必定打出致命一击 type Effect574 struct { SelfKill } -func init() { - input.InitEffect(input.EffectType.Skill, 574, &Effect574{}) -} - func (e *Effect574) ComparePre(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) bool { if !e.can { return true @@ -400,10 +468,7 @@ func (e *Effect574) ComparePre(fattack *action.SelectSkillAction, sattack *actio if fattack.PlayerID == e.Ctx().Our.UserID { return true } - if sattack == nil { - return true - } - if sattack.SkillEntity == nil { + if sattack == nil || sattack.SkillEntity == nil { return true } @@ -424,50 +489,6 @@ func (e *Effect574) ActionStart(a, b *action.SelectSkillAction) bool { } e.Ctx().SkillEntity.XML.MustHit = 1 e.Ctx().SkillEntity.XML.CritRate = 16 - - return true -} - -// Effect 617: 消耗自身所有体力给对手造成{0}-{1}点伤害,若造成伤害大于对手体力,则对手必定留1点血 -type Effect617 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 617, &Effect617{}) -} - -func (e *Effect617) Skill_Use() 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 } @@ -476,11 +497,6 @@ type Effect618 struct { SelfKill } -func init() { - input.InitEffect(input.EffectType.Skill, 618, &Effect618{}) - input.InitEffect(input.EffectType.Sub, 618, &Effect618Sub{}) -} - func (e *Effect618) SwitchIn(in *input.Input) bool { if !e.can || in != e.Ctx().Our { return true @@ -505,33 +521,6 @@ func (e *Effect618Sub) TurnEnd() { e.EffectNode.TurnEnd() } -// Effect 1380: 牺牲自身全部体力,使对手全属性-{0}且{1}回合内先制-{2} -type Effect1380 struct { - node.EffectNode -} - -func init() { - input.InitEffect(input.EffectType.Skill, 1380, &Effect1380{}) - input.InitEffect(input.EffectType.Sub, 1380, &Effect1380Sub{}) -} - -func (e *Effect1380) Skill_Use() 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 -} - type Effect1380Sub struct { RoundEffectArg0Base }