diff --git a/docs/effect-unimplemented-tasks/task-163-effects-1428-1432.md b/docs/effect-unimplemented-tasks/task-163-effects-1428-1432.md deleted file mode 100644 index 78087e6a6..000000000 --- a/docs/effect-unimplemented-tasks/task-163-effects-1428-1432.md +++ /dev/null @@ -1,38 +0,0 @@ -# Task 163: Effects 1428-1432 - -## 目标 - -- 补齐以下 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 1428 -- `argsNum`: `8` -- `info`: `{0}%使对手全属性-1,{1}回合内每回合对手{2}` -- `param`: `0,2,2` - -### Effect 1429 -- `argsNum`: `2` -- `info`: `50%的概率打出致命一击,未触发则{0}%令对手{1}` -- `param`: `1,1,1` - -### Effect 1430 -- `argsNum`: `6` -- `info`: `造成的伤害低于{0}则{1}%令对手{2},未触发则下{3}回合攻击技能{4}%令对手{5}` -- `param`: `1,2,2|1,5,5` - -### Effect 1431 -- `argsNum`: `0` -- `info`: `“辛”死亡后额外先制+1且25%打出致命一击` - -### Effect 1432 -- `argsNum`: `0` -- `info`: `“辛”存活时50%的概率令自身2回合内回合类效果无法被消除(后出手则延续至下2回合),“辛”死亡后概率翻倍` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/effect/1413_1417.go b/logic/service/fight/effect/1413_1417.go new file mode 100644 index 000000000..406a46fbe --- /dev/null +++ b/logic/service/fight/effect/1413_1417.go @@ -0,0 +1,184 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" + "github.com/gogf/gf/v2/util/grand" +) + +// Effect 1413: {0}%的概率打出致命一击,未触发则下{1}回合自身先制+{2} +type Effect1413 struct{ node.EffectNode } + +func (e *Effect1413) SkillHit() bool { + if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100) + if ok { + e.Ctx().SkillEntity.XML.CritRate = 16 + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1413, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1413Sub struct{ RoundEffectArg0Base } + +func (e *Effect1413Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if len(e.Args()) < 2 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + current.SkillEntity.XML.Priority += int(e.Args()[1].IntPart()) + return true +} + +// Effect 1414: 消除敌我双方回合类效果,消除任意一项成功则敌我双方同时进入{0}状态 +type Effect1414 struct{ node.EffectNode } + +func (e *Effect1414) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + + ourTurn := activeTurnEffectCount(e.Ctx().Our) + oppTurn := activeTurnEffectCount(e.Ctx().Opp) + e.Ctx().Our.CancelTurn(e.Ctx().Our) + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + if ourTurn+oppTurn <= 0 { + return true + } + + statusID := int(e.Args()[0].IntPart()) + addStatusByID(e.Ctx().Our, e.Ctx().Our, statusID) + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + return true +} + +// Effect 1415: 造成伤害的{0}%恢复自身体力,若自身体力低于对手则效果提升至{1}% +type Effect1415 struct{ node.EffectNode } + +func (e *Effect1415) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Our.SumDamage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + percent := e.Args()[0] + if e.Ctx().Our.CurrentPet.GetHP().Cmp(e.Ctx().Opp.CurrentPet.GetHP()) < 0 { + percent = e.Args()[1] + } + heal := e.Ctx().Our.SumDamage.Mul(percent).Div(hundred) + if heal.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + return true +} + +// Effect 1416: 消耗自身全部体力,使对手受到自身最大体力1/{0}的百分比伤害,同时使自身下只出场精灵前{1}回合{2}%闪避对手的攻击技能 +type Effect1416 struct{ node.EffectNode } + +func (e *Effect1416) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + maxHP := e.Ctx().Our.CurrentPet.GetMaxHP() + selfHP := e.Ctx().Our.CurrentPet.GetHP() + if selfHP.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: selfHP}) + } + damage := maxHP.Div(e.Args()[0]) + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Percent, Damage: damage}) + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1416, e.SideEffectArgs...) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1416Sub struct { + node.EffectNode + pending bool +} + +func (e *Effect1416Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.CanStack(false) + e.pending = true +} + +func (e *Effect1416Sub) SwitchIn(in *input.Input) bool { + if !e.pending || in != e.Ctx().Our || len(e.Args()) < 3 { + return true + } + + e.pending = false + e.Duration(int(e.Args()[1].IntPart())) + if e.Duration() <= 0 { + e.Alive(false) + } + return true +} + +func (e *Effect1416Sub) SkillHit_ex() bool { + if e.pending || len(e.Args()) < 3 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + ok, _, _ := e.Input.Player.Roll(int(e.Args()[2].IntPart()), 100) + if ok { + e.Ctx().SkillEntity.SetMiss() + } + return true +} + +// Effect 1417: 对手不处于能力下降状态则使对手随机{0}项能力值-{1} +type Effect1417 struct{ node.EffectNode } + +func (e *Effect1417) OnSkill() bool { + if len(e.Args()) < 2 || e.Ctx().Opp.HasPropSub() { + return true + } + + count := int(e.Args()[0].IntPart()) + level := int8(e.Args()[1].IntPart()) + if count <= 0 || level <= 0 { + return true + } + + indexes := grand.Perm(len(e.Ctx().Opp.Prop)) + if count > len(indexes) { + count = len(indexes) + } + for _, idx := range indexes[:count] { + e.Ctx().Opp.SetProp(e.Ctx().Our, int8(idx), -level) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1413, &Effect1413{}) + input.InitEffect(input.EffectType.Sub, 1413, &Effect1413Sub{}) + input.InitEffect(input.EffectType.Skill, 1414, &Effect1414{}) + input.InitEffect(input.EffectType.Skill, 1415, &Effect1415{}) + input.InitEffect(input.EffectType.Skill, 1416, &Effect1416{}) + input.InitEffect(input.EffectType.Sub, 1416, &Effect1416Sub{}) + input.InitEffect(input.EffectType.Skill, 1417, &Effect1417{}) +} diff --git a/logic/service/fight/effect/1418_1422.go b/logic/service/fight/effect/1418_1422.go new file mode 100644 index 000000000..a159e053b --- /dev/null +++ b/logic/service/fight/effect/1418_1422.go @@ -0,0 +1,166 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1418: 损失自身{0}点体力 +type Effect1418 struct{ node.EffectNode } + +func (e *Effect1418) Skill_Use() bool { + if len(e.Args()) == 0 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: e.Args()[0], + }) + return true +} + +// Effect 1419: 消除双方能力提升状态,消除任意一方成功则自身免疫下{0}次异常状态且令对手随机{1}个技能PP值归零 +type Effect1419 struct{ node.EffectNode } + +func (e *Effect1419) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + + cleared := clearPositiveProps(e.Ctx().Our, e.Ctx().Our) + if clearPositiveProps(e.Ctx().Opp, e.Ctx().Our) { + cleared = true + } + if !cleared { + return true + } + + immune := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1419, int(e.Args()[0].IntPart())) + if immune != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, immune) + } + zeroRandomSkillPP(e.Ctx().Opp, int(e.Args()[1].IntPart())) + return true +} + +type Effect1419Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect1419Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1419Sub) EFFect_Befer(in *input.Input, effEffect input.Effect) bool { + if e.remaining <= 0 { + e.Alive(false) + return true + } + if in != e.Ctx().Our || !input.IS_Stat(effEffect) { + return true + } + + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return false +} + +// Effect 1420: 自身处于能力提升状态时50%打出致命一击 +type Effect1420 struct{ node.EffectNode } + +func (e *Effect1420) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if !e.Ctx().Our.HasPropADD() { + return true + } + + ok, _, _ := e.Input.Player.Roll(50, 100) + if ok { + e.Ctx().SkillEntity.XML.CritRate = 16 + } + return true +} + +// Effect 1421: 当回合打出的攻击伤害在{0}—{1}之间则{2}%令对手{3} +type Effect1421 struct{ node.EffectNode } + +func (e *Effect1421) Skill_Use() bool { + if len(e.Args()) < 4 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + + low := e.Args()[0] + high := e.Args()[1] + if low.Cmp(high) > 0 { + low, high = high, low + } + if e.Ctx().Our.SumDamage.Cmp(low) < 0 || e.Ctx().Our.SumDamage.Cmp(high) > 0 { + return true + } + + ok, _, _ := e.Input.Player.Roll(int(e.Args()[2].IntPart()), 100) + if ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[3].IntPart())) + } + return true +} + +// Effect 1422: 获得{0}点护罩,护罩消失时恢复自身{1}点体力 +type Effect1422 struct{ node.EffectNode } + +func (e *Effect1422) 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, 1422, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1422Sub struct{ node.EffectNode } + +func (e *Effect1422Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) +} + +func (e *Effect1422Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 || len(e.Args()) < 2 { + return true + } + heal := e.Args()[1] + if heal.Cmp(alpacadecimal.Zero) <= 0 { + e.Alive(false) + return true + } + + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + e.Alive(false) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1418, &Effect1418{}) + input.InitEffect(input.EffectType.Skill, 1419, &Effect1419{}) + input.InitEffect(input.EffectType.Sub, 1419, &Effect1419Sub{}) + input.InitEffect(input.EffectType.Skill, 1420, &Effect1420{}) + input.InitEffect(input.EffectType.Skill, 1421, &Effect1421{}) + input.InitEffect(input.EffectType.Skill, 1422, &Effect1422{}) + input.InitEffect(input.EffectType.Sub, 1422, &Effect1422Sub{}) +} diff --git a/logic/service/fight/effect/1423_1427.go b/logic/service/fight/effect/1423_1427.go new file mode 100644 index 000000000..6e6eaf8f6 --- /dev/null +++ b/logic/service/fight/effect/1423_1427.go @@ -0,0 +1,148 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +// Effect 1423: 消除对手回合类效果,消除成功则{0}%令对手{1},未触发则恢复自身最大体力的1/{2} +type Effect1423 struct{ node.EffectNode } + +func (e *Effect1423) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Our.CurrentPet == nil || e.Args()[2].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + before := activeTurnEffectCount(e.Ctx().Opp) + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + if before <= 0 { + return true + } + + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok && addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) { + return true + } + + heal := e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[2]) + if heal.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + } + return true +} + +// Effect 1424: {0}%令对手{1},自身处于能力提升状态时概率翻倍 +type Effect1424 struct{ node.EffectNode } + +func (e *Effect1424) OnSkill() bool { + if len(e.Args()) < 2 { + return true + } + + chance := int(e.Args()[0].IntPart()) + if e.Ctx().Our.HasPropADD() { + chance *= 2 + if chance > 100 { + chance = 100 + } + } + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) + } + return true +} + +// Effect 1425: 造成的伤害低于{0}则自身{1} +type Effect1425 struct{ node.EffectNode } + +func (e *Effect1425) Skill_Use() bool { + if len(e.Args()) < 7 { + return true + } + if e.Ctx().Our.SumDamage.Cmp(e.Args()[0]) >= 0 { + return true + } + + for idx := range e.Ctx().Our.Prop { + argIndex := idx + 1 + if argIndex >= len(e.Args()) { + break + } + delta := int8(e.Args()[argIndex].IntPart()) + if delta == 0 { + continue + } + e.Ctx().Our.SetProp(e.Ctx().Our, int8(idx), delta) + } + return true +} + +// Effect 1426: 若对手不处于异常状态则{0}%令对手{1} +type Effect1426 struct{ node.EffectNode } + +func (e *Effect1426) OnSkill() bool { + if len(e.Args()) < 2 || e.Ctx().Opp.StatEffect_Exist_all() { + return true + } + + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) + } + return true +} + +// Effect 1427: {0}回合内每回合{1}%闪避对手攻击,未触发则受到的伤害减少{2}% +type Effect1427 struct{ node.EffectNode } + +func (e *Effect1427) Skill_Use() bool { + if len(e.Args()) < 3 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1427, 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 Effect1427Sub struct{ RoundEffectArg0Base } + +func (e *Effect1427Sub) SkillHit_ex() bool { + skill := e.Ctx().SkillEntity + if skill == nil || skill.Category() == info.Category.STATUS || skill.AttackTime == 0 || len(e.Args()) < 3 { + return true + } + + if skill.AttackTime != 2 { + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100); ok && skill.SetMiss() { + return true + } + } + return true +} + +func (e *Effect1427Sub) DamageDivEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 3 { + return true + } + + reduce := hundred.Sub(e.Args()[2]) + if reduce.Cmp(alpacadecimal.Zero) < 0 { + reduce = alpacadecimal.Zero + } + zone.Damage = zone.Damage.Mul(reduce).Div(hundred) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1423, &Effect1423{}) + input.InitEffect(input.EffectType.Skill, 1424, &Effect1424{}) + input.InitEffect(input.EffectType.Skill, 1425, &Effect1425{}) + input.InitEffect(input.EffectType.Skill, 1426, &Effect1426{}) + input.InitEffect(input.EffectType.Skill, 1427, &Effect1427{}) + input.InitEffect(input.EffectType.Sub, 1427, &Effect1427Sub{}) +} diff --git a/logic/service/fight/effect/1428_1432.go b/logic/service/fight/effect/1428_1432.go new file mode 100644 index 000000000..b033e22b5 --- /dev/null +++ b/logic/service/fight/effect/1428_1432.go @@ -0,0 +1,256 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// Effect 1428: {0}%使对手全属性-1,{1}回合内每回合对手{2} +type Effect1428 struct{ node.EffectNode } + +func (e *Effect1428) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Opp == nil { + return true + } + + chance := int(e.Args()[0].IntPart()) + duration := int(e.Args()[1].IntPart()) + statusID := int(e.Args()[2].IntPart()) + + trigger := chance <= 0 + if chance > 0 { + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + trigger = true + } + } + + if trigger { + for idx := range e.Ctx().Opp.Prop { + e.Ctx().Opp.SetProp(e.Ctx().Our, int8(idx), -1) + } + } + + if duration > 0 && statusID > 0 { + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1428, duration, statusID) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + } + return true +} + +type Effect1428Sub struct{ RoundEffectArg0Base } + +func (e *Effect1428Sub) TurnEnd() bool { + if len(e.Args()) < 2 { + return true + } + statusID := int(e.Args()[1].IntPart()) + if statusID <= 0 { + return true + } + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + return true +} + +// Effect 1429: 50%的概率打出致命一击,未触发则{0}%令对手{1} +type Effect1429 struct{ node.EffectNode } + +func (e *Effect1429) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + if ok, _, _ := e.Input.Player.Roll(50, 100); ok { + e.Ctx().SkillEntity.XML.CritRate = 16 + return true + } + + if len(e.Args()) < 2 { + return true + } + + chance := int(e.Args()[0].IntPart()) + statusID := int(e.Args()[1].IntPart()) + if chance <= 0 || statusID <= 0 { + return true + } + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + } + return true +} + +// Effect 1430: 造成的伤害低于{0}则{1}%令对手{2},未触发则下{3}回合攻击技能{4}%令对手{5} +type Effect1430 struct{ node.EffectNode } + +func (e *Effect1430) Skill_Use() bool { + if len(e.Args()) < 6 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + threshold := e.Args()[0] + chance := int(e.Args()[1].IntPart()) + statusID := int(e.Args()[2].IntPart()) + rollRounds := int(e.Args()[3].IntPart()) + brChance := int(e.Args()[4].IntPart()) + brStatus := int(e.Args()[5].IntPart()) + + if e.Ctx().Our.SumDamage.Cmp(threshold) < 0 && chance > 0 && statusID > 0 { + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + return true + } + } + + if rollRounds <= 0 || brChance <= 0 || brStatus <= 0 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1430, rollRounds, brChance, brStatus) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1430Sub struct{ RoundEffectArg0Base } + +func (e *Effect1430Sub) SkillHit() bool { + if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + chance := int(e.Args()[1].IntPart()) + statusID := int(e.Args()[2].IntPart()) + if chance <= 0 || statusID <= 0 { + return true + } + if ok, _, _ := e.Input.Player.Roll(chance, 100); ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) + } + return true +} + +// Effect 1431: “辛”死亡后额外先制+1且25%打出致命一击 +type Effect1431 struct{ node.EffectNode } + +func (e *Effect1431) SwitchOut(in *input.Input) bool { + if in != e.Ctx().Our { + return true + } + ownerPet := effectOwnerPetByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) + if ownerPet == nil || ownerPet.Alive() { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1431) + if sub != nil { + sub.Duration(1) + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + e.Alive(false) + return true +} + +type Effect1431Sub struct { + node.EffectNode + applied bool +} + +func (e *Effect1431Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.applied || e.Ctx().SkillEntity == nil { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + current.SkillEntity.XML.Priority += 1 + e.applied = true + return true +} + +func (e *Effect1431Sub) SkillHit() bool { + if !e.applied || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if ok, _, _ := e.Input.Player.Roll(25, 100); ok { + e.Ctx().SkillEntity.XML.CritRate = 16 + } + e.Alive(false) + return true +} + +// Effect 1432: “辛”存活时50%的概率令自身2回合内回合类效果无法被消除(后出手则延续至下2回合),“辛”死亡后概率翻倍 +type Effect1432 struct{ node.EffectNode } + +func (e *Effect1432) Skill_Use() bool { + if e.Ctx().Our == nil { + return true + } + chance := 50 + if !effectOwnerAliveByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) { + chance = 100 + } + if ok, _, _ := e.Input.Player.Roll(chance, 100); !ok { + return true + } + + rounds := 2 + if !e.IsFirst() { + rounds += 2 + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1432, rounds) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1432Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect1432Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1432Sub) Skill_Use_ex() bool { + for _, eff := range e.Ctx().Our.Effects { + if eff == nil || eff == e { + continue + } + if eff.ID().GetEffectType() == input.EffectType.Status || eff.Duration() <= 0 { + continue + } + eff.Alive(true) + } + return true +} + +func (e *Effect1432Sub) TurnEnd() { + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1428, &Effect1428{}) + input.InitEffect(input.EffectType.Sub, 1428, &Effect1428Sub{}) + input.InitEffect(input.EffectType.Skill, 1429, &Effect1429{}) + input.InitEffect(input.EffectType.Skill, 1430, &Effect1430{}) + input.InitEffect(input.EffectType.Sub, 1430, &Effect1430Sub{}) + input.InitEffect(input.EffectType.Skill, 1431, &Effect1431{}) + input.InitEffect(input.EffectType.Sub, 1431, &Effect1431Sub{}) + input.InitEffect(input.EffectType.Skill, 1432, &Effect1432{}) + input.InitEffect(input.EffectType.Sub, 1432, &Effect1432Sub{}) +} diff --git a/logic/service/fight/effect/1433_1437.go b/logic/service/fight/effect/1433_1437.go new file mode 100644 index 000000000..5a78cac73 --- /dev/null +++ b/logic/service/fight/effect/1433_1437.go @@ -0,0 +1,194 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +func effectOwnerPetByCatchTime(our *input.Input, catchTime uint32) *info.BattlePetEntity { + if our == nil { + return nil + } + if catchTime == 0 { + return our.CurrentPet + } + for _, pet := range our.AllPet { + if pet != nil && pet.Info.CatchTime == catchTime { + return pet + } + } + return our.CurrentPet +} + +func effectOwnerAliveByCatchTime(our *input.Input, catchTime uint32) bool { + pet := effectOwnerPetByCatchTime(our, catchTime) + return pet != nil && pet.Alive() +} + +// Effect 1433: 损失“辛”所有体力,同时使对手受到损失体力值1/2的固定伤害 +type Effect1433 struct{ node.EffectNode } + +func (e *Effect1433) Skill_Use() bool { + ownerPet := effectOwnerPetByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) + if ownerPet == nil { + return true + } + + lost := alpacadecimal.NewFromInt(int64(ownerPet.Info.Hp)) + if lost.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + if ownerPet == e.Ctx().Our.CurrentPet { + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: lost, + }) + } else { + ownerPet.Info.Hp = 0 + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: lost.Div(alpacadecimal.NewFromInt(2)), + }) + return true +} + +// Effect 1434: “辛”死亡后令自身下1次受到的攻击伤害减少50% +type Effect1434 struct{ node.EffectNode } + +func (e *Effect1434) SwitchOut(in *input.Input) bool { + if in != e.Ctx().Our { + return true + } + ownerPet := effectOwnerPetByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) + if ownerPet == nil || ownerPet.Alive() { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1434) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + e.Alive(false) + return true +} + +type Effect1434Sub struct { + FixedDurationNeg1Base + used bool +} + +func (e *Effect1434Sub) DamageDivEx(zone *info.DamageZone) bool { + if e.used || zone == nil || zone.Type != info.DamageType.Red { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(50)).Div(hundred) + e.used = true + e.Alive(false) + return true +} + +// Effect 1435: “辛”存活时反转自身能力下降状态,反转成功则2回合内令对手使用的属性技能无效 +type Effect1435 struct{ node.EffectNode } + +func (e *Effect1435) OnSkill() bool { + if !effectOwnerAliveByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) { + return true + } + + reversed := false + for i, v := range e.Ctx().Our.Prop[:] { + if v >= 0 { + continue + } + if e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), -2*v) { + reversed = true + } + } + if !reversed { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1435) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1435Sub struct{ FixedDuration2Base } + +func (e *Effect1435Sub) SkillHit_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.SetNoSide() + return true +} + +// Effect 1436: 当回合击败对手则{0}%恢复自身全部体力,未触发则全属性+{1} +type Effect1436 struct{ node.EffectNode } + +func (e *Effect1436) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + if e.Ctx().Opp.CurrentPet.Info.Hp == 0 { + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Ctx().Our.CurrentPet.GetMaxHP()) + return true + } + } + + boost := int8(e.Args()[1].IntPart()) + for i := range e.Ctx().Our.Prop[:] { + e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), boost) + } + return true +} + +// Effect 1437: “辛”存活时造成攻击伤害的50%恢复自身体力,“辛”死亡后造成的攻击伤害额外提升50% +type Effect1437 struct{ node.EffectNode } + +func (e *Effect1437) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if effectOwnerAliveByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(150)).Div(hundred) + return true +} + +func (e *Effect1437) Skill_Use() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if !effectOwnerAliveByCatchTime(e.Ctx().Our, e.ID().GetCatchTime()) { + return true + } + if e.Ctx().Our.SumDamage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + heal := e.Ctx().Our.SumDamage.Div(alpacadecimal.NewFromInt(2)) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1433, &Effect1433{}) + input.InitEffect(input.EffectType.Skill, 1434, &Effect1434{}) + input.InitEffect(input.EffectType.Sub, 1434, &Effect1434Sub{}) + input.InitEffect(input.EffectType.Skill, 1435, &Effect1435{}) + input.InitEffect(input.EffectType.Sub, 1435, &Effect1435Sub{}) + input.InitEffect(input.EffectType.Skill, 1436, &Effect1436{}) + input.InitEffect(input.EffectType.Skill, 1437, &Effect1437{}) +}