diff --git a/docs/effect-unimplemented-tasks/task-209-effects-1660-1664.md b/docs/effect-unimplemented-tasks/task-209-effects-1660-1664.md deleted file mode 100644 index 8be8542f1..000000000 --- a/docs/effect-unimplemented-tasks/task-209-effects-1660-1664.md +++ /dev/null @@ -1,37 +0,0 @@ -# Task 209: Effects 1660-1664 - -## 目标 - -- 补齐以下 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 1660 -- `argsNum`: `3` -- `info`: `{0}%令对手{1},未触发则降低对手所有技能{2}点PP值` -- `param`: `1,1,1` - -### Effect 1661 -- `argsNum`: `3` -- `info`: `获得{0}点护盾,护盾消失时{1}%的概率使对手{2}` -- `param`: `1,2,2` - -### Effect 1662 -- `argsNum`: `0` -- `info`: `消耗自身所有护盾值并附加等量固定伤害,若对手体力未变化则恢复自身等量体力值` - -### Effect 1663 -- `argsNum`: `1` -- `info`: `当回合击败对手则令对手下只登场精灵随机{0}个技能PP值归零` - -### Effect 1664 -- `argsNum`: `1` -- `info`: `当回合若自身先出手则令对手使用的威力低于{0}的攻击技能无效,若击败对手则攻击无效效果延续至下回合` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-231-effects-1770-1774.md b/docs/effect-unimplemented-tasks/task-231-effects-1770-1774.md deleted file mode 100644 index 46aa06759..000000000 --- a/docs/effect-unimplemented-tasks/task-231-effects-1770-1774.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 231: Effects 1770-1774 - -## 目标 - -- 补齐以下 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 1770 -- `argsNum`: `0` -- `info`: `开启战魂附体:免疫对手下1次攻击技能造成的伤害,若对手使用的攻击技能PP值为满则自身额外免疫下1次受到的固定伤害和百分比伤害` - -### Effect 1771 -- `argsNum`: `1` -- `info`: `反转对手能力提升状态,反转成功则{0}回合内对手的能力下降状态无法被解除或反转` - -### Effect 1772 -- `argsNum`: `1` -- `info`: `附加对手能力下降等级总和X{0}的固定伤害` - -### Effect 1773 -- `argsNum`: `1` -- `info`: `附加双方能力下降等级总和X{0}的固定伤害` - -### Effect 1774 -- `argsNum`: `0` -- `info`: `若对手当回合使用的技能为攻击技能则自身额外先制+1` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-232-effects-1775-1779.md b/docs/effect-unimplemented-tasks/task-232-effects-1775-1779.md deleted file mode 100644 index c976310a0..000000000 --- a/docs/effect-unimplemented-tasks/task-232-effects-1775-1779.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 232: Effects 1775-1779 - -## 目标 - -- 补齐以下 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 1775 -- `argsNum`: `1` -- `info`: `令对手下{0}次使用的技能PP值归零` - -### Effect 1776 -- `argsNum`: `1` -- `info`: `吸取对手能力提升状态,吸取成功则{0}回合内对手攻击技能无法造成伤害且命中效果失效` - -### Effect 1777 -- `argsNum`: `2` -- `info`: `消除对手回合类效果,若对手不处于回合类效果则{0}%令对手{1}` -- `param`: `1,1,1` - -### Effect 1778 -- `argsNum`: `2` -- `info`: `当回合结束后,若本回合自身未受到攻击则使对手下{0}回合属性技能先制-{1}` - -### Effect 1779 -- `argsNum`: `2` -- `info`: `对手下{0}次主动切换或死亡切换精灵时,在场精灵吸取对手下只出场精灵最大体力的1/{1}` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-235-effects-1790-1794.md b/docs/effect-unimplemented-tasks/task-235-effects-1790-1794.md deleted file mode 100644 index 23591dfa3..000000000 --- a/docs/effect-unimplemented-tasks/task-235-effects-1790-1794.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 235: Effects 1790-1794 - -## 目标 - -- 补齐以下 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 1790 -- `argsNum`: `1` -- `info`: `预留,{0}` - -### Effect 1791 -- `argsNum`: `3` -- `info`: `消除双方护盾并附加护盾值{0}%的百分比伤害,若护盾值总和超过{1}点则转变为附加护盾值{2}%的百分比伤害` - -### Effect 1792 -- `argsNum`: `1` -- `info`: `使对手直接受到{0}点光·暗影系伤害并获得等量护盾(不可叠加),若自身没有护盾则效果翻倍` - -### Effect 1793 -- `argsNum`: `2` -- `info`: `下{0}次受到攻击伤害时,若伤害高于{1},则自身恢复全部体力` - -### Effect 1794 -- `argsNum`: `3` -- `info`: `技能无效时,恢复自身最大体力的1/2且下1次受到的攻击伤害额外减少50%` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-291-effects-2070-2074.md b/docs/effect-unimplemented-tasks/task-291-effects-2070-2074.md deleted file mode 100644 index ac8231573..000000000 --- a/docs/effect-unimplemented-tasks/task-291-effects-2070-2074.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 291: Effects 2070-2074 - -## 目标 - -- 补齐以下 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 2070 -- `argsNum`: `1` -- `info`: `下{0}次自身能力提升状态被反转时令该效果无效` - -### Effect 2071 -- `argsNum`: `2` -- `info`: `自身被击败后,对手下{0}次体力恢复效果减少{1}%` - -### Effect 2072 -- `argsNum`: `0` -- `info`: `自身处于异常状态时先制+1且必定命中` - -### Effect 2073 -- `argsNum`: `1` -- `info`: `对手每处于一种异常状态造成的伤害提升{0}%` - -### Effect 2074 -- `argsNum`: `1` -- `info`: `随机附加{0}种非限制类异常状态` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-292-effects-2075-2079.md b/docs/effect-unimplemented-tasks/task-292-effects-2075-2079.md deleted file mode 100644 index b34cabd94..000000000 --- a/docs/effect-unimplemented-tasks/task-292-effects-2075-2079.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 292: Effects 2075-2079 - -## 目标 - -- 补齐以下 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 2075 -- `argsNum`: `1` -- `info`: `未击败对手则对手下{0}回合无法解除、反转自身能力下降状态` - -### Effect 2076 -- `argsNum`: `4` -- `info`: `{0}回合内使用技能吸取对手最大体力的1/{1},自身体力低于1/{2}时效果翻倍,吸取后若对手体力未减少则为己方所有场下存活精灵恢复{3}点体力` - -### Effect 2077 -- `argsNum`: `4` -- `info`: `{0}回合内使用技能吸取对手{1}点体力,自身体力低于1/{2}时效果翻倍,吸取后若对手体力减少值低于180则附加{3}点真实伤害与1层自身所处形态相应的圣告/邪诲` - -### Effect 2078 -- `argsNum`: `1` -- `info`: `吸取对手{0}点体力,吸取后若对手体力减少值低于180则为对手附加1层自身所处形态相反的圣告/邪诲` - -### Effect 2079 -- `argsNum`: `0` -- `info`: `对手处于护盾状态时先制+1并无视对手护盾效果` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-293-effects-2080-2084.md b/docs/effect-unimplemented-tasks/task-293-effects-2080-2084.md deleted file mode 100644 index ecd354151..000000000 --- a/docs/effect-unimplemented-tasks/task-293-effects-2080-2084.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 293: Effects 2080-2084 - -## 目标 - -- 补齐以下 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 2080 -- `argsNum`: `1` -- `info`: `自身处于护盾状态时威力提升{0}%` - -### Effect 2081 -- `argsNum`: `1` -- `info`: `对手不处于异常状态时令对手随机{0}个技能PP值归零` - -### Effect 2082 -- `argsNum`: `0` -- `info`: `为对手附加1道天霆之律` - -### Effect 2083 -- `argsNum`: `0` -- `info`: `对手选择必中技能时先制+3` - -### Effect 2084 -- `argsNum`: `1` -- `info`: `对手选择非必中技能时吸取对手所选技能{0}点PP值` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-294-effects-2085-2089.md b/docs/effect-unimplemented-tasks/task-294-effects-2085-2089.md deleted file mode 100644 index 882e25efa..000000000 --- a/docs/effect-unimplemented-tasks/task-294-effects-2085-2089.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 294: Effects 2085-2089 - -## 目标 - -- 补齐以下 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 2085 -- `argsNum`: `7` -- `info`: `命中后自身{0},若造成的伤害高于{6}则效果翻倍` -- `param`: `0,0,0` - -### Effect 2086 -- `argsNum`: `0` -- `info`: `空元之诗·渍:若技能无效,则消除对手回合类效果、能力提升效果,消除成功任意一项则令对手诅咒` - -### Effect 2087 -- `argsNum`: `0` -- `info`: `空元之诗·镀:若对手处于控制类异常状态,则己方免疫下2次受到的异常状态` - -### Effect 2088 -- `argsNum`: `0` -- `info`: `空元之诗·柱:若对手处于回合类效果,则对手每有1个技能PP值不为满附加50点次元·龙系伤害且对手下回合无法主动切换精灵` - -### Effect 2089 -- `argsNum`: `0` -- `info`: `空元之诗·烙:若自身为先出手,则此技能每剩余1点PP值附加50点次元·龙系伤害,下次击败对手后恢复自身全部体力与PP值` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-302-effects-2125-2129.md b/docs/effect-unimplemented-tasks/task-302-effects-2125-2129.md deleted file mode 100644 index d399ccc54..000000000 --- a/docs/effect-unimplemented-tasks/task-302-effects-2125-2129.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 302: Effects 2125-2129 - -## 目标 - -- 补齐以下 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 2125 -- `argsNum`: `0` -- `info`: `携带此技能时,专属特性中对手属性技能无效的概率提升至100%` - -### Effect 2126 -- `argsNum`: `0` -- `info`: `技能无效时,消除对手回合类效果、能力提升效果,令对手焚烬` - -### Effect 2127 -- `argsNum`: `0` -- `info`: `技能无效时,消除对手回合类效果、能力提升效果,令对手烧伤` - -### Effect 2128 -- `argsNum`: `2` -- `info`: `对手不处于异常状态时对手{0}回合内体力恢复效果减少{1}%` - -### Effect 2129 -- `argsNum`: `2` -- `info`: `攻击后附加造成伤害{0}%的百分比伤害,先出手时效果提升{1}%,附加后若对手体力未减少则额外附加等量的真实伤害` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-303-effects-2130-2134.md b/docs/effect-unimplemented-tasks/task-303-effects-2130-2134.md deleted file mode 100644 index 96ea1280a..000000000 --- a/docs/effect-unimplemented-tasks/task-303-effects-2130-2134.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 303: Effects 2130-2134 - -## 目标 - -- 补齐以下 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 2130 -- `argsNum`: `0` -- `info`: `对手持有失能时必定命中且无视攻击免疫效果` - -### Effect 2131 -- `argsNum`: `1` -- `info`: `自身持有回能时先制+1且附加对手最大体力1/{0}的百分比伤害` - -### Effect 2132 -- `argsNum`: `0` -- `info`: `对手持有失体时造成伤害提升100%,否则为对手附加3回合的失体并令对手害怕` - -### Effect 2133 -- `argsNum`: `0` -- `info`: `自身持有回体时先制+1,否则为自身附加3回合的回体并令对手疲惫` - -### Effect 2134 -- `argsNum`: `0` -- `info`: `反转对手能力提升状态,反转成功则恢复自身所有体力和PP值` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-304-effects-2135-2139.md b/docs/effect-unimplemented-tasks/task-304-effects-2135-2139.md deleted file mode 100644 index 40245e0db..000000000 --- a/docs/effect-unimplemented-tasks/task-304-effects-2135-2139.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 304: Effects 2135-2139 - -## 目标 - -- 补齐以下 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 2135 -- `argsNum`: `0` -- `info`: `自身未持有失命时为自身附加3回合的失命,若自身持有失命则将失命转移给对手` - -### Effect 2136 -- `argsNum`: `0` -- `info`: `对手未持有回命时为对手附加3回合的回命,若对手持有回命且剩余回合数大于1则回合数-1` - -### Effect 2137 -- `argsNum`: `2` -- `info`: `自身每有1回合异常状态造成伤害提升{0}%,最高{1}%` - -### Effect 2138 -- `argsNum`: `0` -- `info`: `为对手种下晦暗之因,若对手的晦暗之因已成熟则收割晦暗之因转化为自身的1层晦暗之根` - -### Effect 2139 -- `argsNum`: `1` -- `info`: `100%令对手害怕,对手拥有晦暗之因时改为诅咒,自身拥有晦暗之根时每有1层伤害提升{0}%` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-305-effects-2140-2144.md b/docs/effect-unimplemented-tasks/task-305-effects-2140-2144.md deleted file mode 100644 index 539cbaa00..000000000 --- a/docs/effect-unimplemented-tasks/task-305-effects-2140-2144.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 305: Effects 2140-2144 - -## 目标 - -- 补齐以下 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 2140 -- `argsNum`: `3` -- `info`: `吸取对手最大体力的{0}%,对手每有1级晦暗之因提升{1}%,吸取后若对手体力未减少则对手下{2}回合无法主动切换精灵` - -### Effect 2141 -- `argsNum`: `0` -- `info`: `击败拥有晦暗之因的对手时自身获得1层晦暗之根` - -### Effect 2142 -- `argsNum`: `0` -- `info`: `无视对手正先制等级` - -### Effect 2143 -- `argsNum`: `0` -- `info`: `无视自身负先制等级` - -### Effect 2144 -- `argsNum`: `1` -- `info`: `双方下{0}回合无法主动切换精灵` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-319-effects-2210-2214.md b/docs/effect-unimplemented-tasks/task-319-effects-2210-2214.md deleted file mode 100644 index df51d48f1..000000000 --- a/docs/effect-unimplemented-tasks/task-319-effects-2210-2214.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 319: Effects 2210-2214 - -## 目标 - -- 补齐以下 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 2210 -- `argsNum`: `0` -- `info`: `若自身处于星赐且不处于星哲则将此技能转化为物理攻击,若自身处于星哲且不处于星赐则将此技能转化为特殊攻击,转化后此技能系别与自身相同且自身天赋值越高技能威力越大` - -### Effect 2211 -- `argsNum`: `3` -- `info`: `为对手附加{0}层蚩庸之锁,若附加的蚩庸之锁超出了上限则对手下{1}回合先制-{2}` - -### Effect 2212 -- `argsNum`: `3` -- `info`: `{0}回合内对手使用威力不高于{1}的攻击技能时令对手{2},未触发则抵挡对手当次攻击` -- `param`: `1,2,2` - -### Effect 2213 -- `argsNum`: `1` -- `info`: `消耗自身全部体力,己方下只精灵获得点数等同于消耗值{0}%的护盾与护罩` - -### Effect 2214 -- `argsNum`: `1` -- `info`: `对手每有1层蚩庸之锁令对手随机1个攻击技能PP值归0,对手存有PP值的攻击技能个数不足时造成的伤害提升{0}%` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/effect/1660_1664.go b/logic/service/fight/effect/1660_1664.go new file mode 100644 index 000000000..2f2e0766d --- /dev/null +++ b/logic/service/fight/effect/1660_1664.go @@ -0,0 +1,208 @@ +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 1660: {0}%令对手{1},未触发则降低对手所有技能{2}点PP值 +type Effect1660 struct { + node.EffectNode +} + +func (e *Effect1660) Skill_Use() bool { + if len(e.Args()) < 3 { + return true + } + + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok { + if !addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) { + e.Ctx().Opp.DelPP(int(e.Args()[2].IntPart())) + } + return true + } + + e.Ctx().Opp.DelPP(int(e.Args()[2].IntPart())) + return true +} + +// Effect 1661: 获得{0}点护盾,护盾消失时{1}%的概率使对手{2} +type Effect1661 struct { + node.EffectNode +} + +func (e *Effect1661) Skill_Use() bool { + if len(e.Args()) < 3 { + 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, 1661, int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1661Sub struct { + node.EffectNode +} + +func (e *Effect1661Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(-1) +} + +func (e *Effect1661Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { + if len(e.Args()) < 2 { + return true + } + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 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 +} + +// Effect 1662: 消耗自身所有护盾值并附加等量固定伤害,若对手体力未变化则恢复自身等量体力 +type Effect1662 struct { + node.EffectNode +} + +func (e *Effect1662) Skill_Use() bool { + shield := e.Ctx().Our.ConsumeAllShield() + if shield.Cmp(alpacadecimal.Zero) <= 0 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + + before := e.Ctx().Opp.CurrentPet.GetHP() + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: shield, + }) + if e.Ctx().Opp.CurrentPet.GetHP().Cmp(before) == 0 { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, shield) + } + return true +} + +// Effect 1663: 当回合击败对手则令对手下只登场精灵随机{0}个技能PP值归零 +type Effect1663 struct { + node.EffectNode +} + +func (e *Effect1663) Skill_Use() bool { + if len(e.Args()) < 1 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp > 0 { + return true + } + + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1663, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1663Sub struct { + node.EffectNode +} + +func (e *Effect1663Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(1) +} + +func (e *Effect1663Sub) SwitchIn(in *input.Input) bool { + if in != e.Ctx().Opp || len(e.Args()) < 1 { + return true + } + + randomSkillPPZero(e.Ctx().Opp, int(e.Args()[0].IntPart())) + e.Alive(false) + return true +} + +// Effect 1664: 当回合若自身先出手则令对手使用的威力低于{0}的攻击技能无效,若击败对手则攻击无效效果延续至下回合 +type Effect1664 struct { + node.EffectNode +} + +func (e *Effect1664) ActionStart(a, b *action.SelectSkillAction) bool { + if !e.IsFirst() || len(e.Args()) < 1 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1664, int(e.Args()[0].IntPart())) + if sub != nil { + if s, ok := sub.(*Effect1664Sub); ok { + s.Duration(1) + } + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +func (e *Effect1664) Skill_Use() bool { + if !e.IsFirst() || len(e.Args()) < 1 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp > 0 { + return true + } + + if sub := e.Ctx().Opp.GetEffect(input.EffectType.Sub, 1664); sub != nil { + if s, ok := sub.(*Effect1664Sub); ok && s.Duration() < 2 { + s.Duration(2) + } + } + return true +} + +type Effect1664Sub struct { + node.EffectNode +} + +func (e *Effect1664Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(false) + e.Duration(1) +} + +func (e *Effect1664Sub) ActionStart(a, b *action.SelectSkillAction) bool { + if len(e.Args()) < 1 { + return true + } + skill := e.Ctx().SkillEntity + if skill == nil || skill.Category() == info.Category.STATUS { + return true + } + if skill.XML.Power < int(e.Args()[0].IntPart()) { + skill.SetMiss() + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1660, &Effect1660{}) + input.InitEffect(input.EffectType.Skill, 1661, &Effect1661{}) + input.InitEffect(input.EffectType.Sub, 1661, &Effect1661Sub{}) + input.InitEffect(input.EffectType.Skill, 1662, &Effect1662{}) + input.InitEffect(input.EffectType.Skill, 1663, &Effect1663{}) + input.InitEffect(input.EffectType.Sub, 1663, &Effect1663Sub{}) + input.InitEffect(input.EffectType.Skill, 1664, &Effect1664{}) + input.InitEffect(input.EffectType.Sub, 1664, &Effect1664Sub{}) +} diff --git a/logic/service/fight/effect/1770_1794.go b/logic/service/fight/effect/1770_1794.go index d23a76b9e..9600ac5cf 100644 --- a/logic/service/fight/effect/1770_1794.go +++ b/logic/service/fight/effect/1770_1794.go @@ -1,6 +1,7 @@ package effect import ( + "blazing/common/data/xmlres" "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" @@ -9,6 +10,73 @@ import ( "github.com/alpacahq/alpacadecimal" ) +// Effect 1770: 开启战魂附体:免疫对手下1次攻击技能造成的伤害,若对手使用的攻击技能PP值为满则自身额外免疫下1次受到的固定伤害和百分比伤害 +type Effect1770 struct { + node.EffectNode +} + +func (e *Effect1770) Skill_Use() bool { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1770) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1770Sub struct { + node.EffectNode + blockedSkill *info.SkillEntity + attackUsed bool + extraPending bool +} + +func (e *Effect1770Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) +} + +func (e *Effect1770Sub) TurnEnd() { + e.blockedSkill = nil + if e.attackUsed && !e.extraPending { + e.Alive(false) + return + } + e.EffectNode.TurnEnd() +} + +func (e *Effect1770Sub) DamageLockEx(zone *info.DamageZone) bool { + if zone == nil || zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + current := e.Ctx().SkillEntity + if current != nil && current.Category() != info.Category.STATUS && current.AttackTime != 0 { + if e.blockedSkill != nil && e.blockedSkill != current { + e.blockedSkill = nil + } + if !e.attackUsed { + e.attackUsed = true + e.blockedSkill = current + zone.Damage = alpacadecimal.Zero + if skill, ok := xmlres.SkillMap[int(current.Info.ID)]; ok && current.Info.PP >= uint32(skill.MaxPP) { + e.extraPending = true + } + return true + } + if e.blockedSkill == current { + zone.Damage = alpacadecimal.Zero + return true + } + } + + if e.extraPending && (zone.Type == info.DamageType.Fixed || zone.Type == info.DamageType.Percent) { + zone.Damage = alpacadecimal.Zero + e.extraPending = false + e.Alive(false) + } + return true +} + func totalNegativePropLevels(in *input.Input) int64 { if in == nil { return 0 @@ -39,6 +107,23 @@ func clearSubEffects(target *input.Input) bool { return cleared } +func countTurnEffects(target *input.Input) int { + if target == nil { + return 0 + } + + count := 0 + for _, effect := range target.Effects { + if effect == nil || !effect.Alive() { + continue + } + if effect.Duration() > 0 { + count++ + } + } + return count +} + // Effect 1771: 反转对手能力提升状态,反转成功则{0}回合内对手的能力下降状态无法被解除或反转 type Effect1771 struct { node.EffectNode @@ -313,15 +398,79 @@ func (e *Effect1779) SwitchIn(in *input.Input) bool { type Effect1780 struct{ node.EffectNode } func (e *Effect1780) OnSkill() bool { - if len(e.Args()) < 5 { + if len(e.Args()) < 5 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { return true } - e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.True, Damage: e.Ctx().Our.CurrentPet.GetHP()}) - shield := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[1]) - if shield.Cmp(alpacadecimal.Zero) > 0 { - e.Ctx().Our.AddShield(shield) + + selfHP := e.Ctx().Our.CurrentPet.GetHP() + if selfHP.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.True, Damage: selfHP}) + } + + if e.Args()[0].Cmp(alpacadecimal.Zero) > 0 { + damage := e.Ctx().Opp.CurrentPet.GetHP().Div(e.Args()[0]) + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Fixed, Damage: damage}) + } + } + + shield := alpacadecimal.Zero + if e.Args()[1].Cmp(alpacadecimal.Zero) > 0 { + shield = e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[1]) + } + if shield.Cmp(alpacadecimal.Zero) > 0 { + if capShield := e.Args()[4]; capShield.Cmp(alpacadecimal.Zero) > 0 { + current := e.Ctx().Our.CurrentShield() + if current.Cmp(capShield) < 0 { + remain := capShield.Sub(current) + if shield.Cmp(remain) > 0 { + shield = remain + } + } else { + shield = alpacadecimal.Zero + } + } + if shield.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.AddShield(shield) + } + } + + if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1780, int(e.Args()[2].IntPart()), int(e.Args()[3].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + } + return true +} + +type Effect1780Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect1780Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1780Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.remaining <= 0 { + e.Alive(false) + 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()) + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) } - e.Ctx().Our.SetProp(e.Ctx().Our, 5, int8(e.Args()[3].IntPart())) return true } @@ -414,22 +563,50 @@ func (e *Effect1783) Skill_Use() bool { return true } - sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1783, int(e.Args()[1].IntPart())) - if sub != nil { - e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + if e.Args()[1].Cmp(alpacadecimal.Zero) > 0 { + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1783, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + e.Ctx().Opp.CanChange = 1 + } } return true } type Effect1783Sub struct { - RoundEffectArg0Base + node.EffectNode + remaining int } -func (e *Effect1783Sub) SwitchIn(in *input.Input) bool { - if in != e.Ctx().Opp { - return true +func (e *Effect1783Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1783Sub) TurnEnd() { + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + e.remaining-- + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + if e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Our.CurrentPet.Info.Hp > 0 { + e.Ctx().Our.CanChange = 1 + } +} + +func (e *Effect1783Sub) SwitchOut(in *input.Input) bool { + if in == e.Ctx().Our { + e.Ctx().Our.CanChange = 0 } - e.Alive(false) return true } @@ -454,10 +631,11 @@ type Effect1784Sub struct { } func (e *Effect1784Sub) DamageLockEx(zone *info.DamageZone) bool { - if zone == nil || zone.Type != info.DamageType.Red { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { return true } - if zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + currentHP := e.Ctx().Our.CurrentPet.GetHP() + if zone.Damage.Cmp(currentHP) >= 0 { return true } zone.Damage = alpacadecimal.Zero @@ -512,6 +690,146 @@ func (e *Effect1785Sub) OnSkill() bool { return true } +// Effect 1790: 预留 +type Effect1790 struct{ node.EffectNode } + +func (e *Effect1790) Skill_Use() bool { return true } + +// Effect 1786: {0}回合内若自身回合类效果被消除则对手下{1}次使用的攻击技能附加效果失效 +type Effect1786 struct { + node.EffectNode +} + +func (e *Effect1786) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1786, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub == nil { + return true + } + if s, ok := sub.(*Effect1786Sub); ok { + s.previous = countTurnEffects(e.Ctx().Our) + } + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + return true +} + +type Effect1786Sub struct { + RoundEffectArg0Base + previous int + remainingTurn int + triggered bool +} + +func (e *Effect1786Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remainingTurn = a[0] + } +} + +func (e *Effect1786Sub) TurnEnd() { + e.EffectNode.TurnEnd() + if e.triggered || e.remainingTurn <= 0 { + return + } + + current := countTurnEffects(e.Ctx().Our) + if e.previous <= 0 || current > 0 { + e.previous = current + e.remainingTurn-- + if e.remainingTurn <= 0 { + e.Alive(false) + } + return + } + + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1786, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + e.triggered = true + e.Alive(false) +} + +type Effect1786Debuff struct { + node.EffectNode + remaining int +} + +func (e *Effect1786Debuff) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect1786Debuff) SkillHit_ex() 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.SetNoSide() + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +// Effect 1787: 沙之力量觉醒,使自身下{0}次攻击获得鳞天之尘效果 +type Effect1787 struct { + node.EffectNode +} + +func (e *Effect1787) Skill_Use() bool { return true } + +// Effect 1788: {0}%令对手{1},未触发则附加自身最大体力的{2}%的百分比伤害,若对手免疫百分比伤害则转变为真实伤害 +type Effect1788 struct { + node.EffectNode +} + +func (e *Effect1788) Skill_Use() bool { + if len(e.Args()) < 3 { + return true + } + + success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100) + if success { + status := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[1].IntPart())) + if status != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, status) + } + return true + } + + damage := e.Ctx().Our.CurrentPet.GetMaxHP().Mul(e.Args()[2]).Div(hundred) + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Percent, + Damage: damage, + }) + return true +} + +// Effect 1789: 预留效果 +type Effect1789 struct { + node.EffectNode +} + +func (e *Effect1789) Skill_Use() bool { return true } + type Effect1791 struct { node.EffectNode } @@ -645,6 +963,8 @@ func (e *Effect1794Sub) DamageLockEx(zone *info.DamageZone) bool { } func init() { + input.InitEffect(input.EffectType.Skill, 1770, &Effect1770{}) + input.InitEffect(input.EffectType.Sub, 1770, &Effect1770Sub{}) input.InitEffect(input.EffectType.Skill, 1771, &Effect1771{}) input.InitEffect(input.EffectType.Sub, 1771, &Effect1771Sub{}) input.InitEffect(input.EffectType.Skill, 1772, &Effect1772{}) @@ -656,11 +976,22 @@ func init() { input.InitEffect(input.EffectType.Sub, 1776, &Effect1776Sub{}) input.InitEffect(input.EffectType.Skill, 1785, &Effect1785{}) input.InitEffect(input.EffectType.Sub, 1785, &Effect1785Sub{}) + input.InitEffect(input.EffectType.Skill, 1786, &Effect1786{}) + input.InitEffect(input.EffectType.Sub, 1786, &Effect1786Sub{}) + input.InitEffect(input.EffectType.Sub, 1786, &Effect1786Debuff{}) + input.InitEffect(input.EffectType.Skill, 1787, &Effect1787{}) + input.InitEffect(input.EffectType.Skill, 1788, &Effect1788{}) + input.InitEffect(input.EffectType.Skill, 1789, &Effect1789{}) + input.InitEffect(input.EffectType.Skill, 1780, &Effect1780{}) + input.InitEffect(input.EffectType.Sub, 1780, &Effect1780Sub{}) input.InitEffect(input.EffectType.Skill, 1781, &Effect1781{}) input.InitEffect(input.EffectType.Sub, 1781, &Effect1781Sub{}) input.InitEffect(input.EffectType.Skill, 1782, &Effect1782{}) input.InitEffect(input.EffectType.Skill, 1783, &Effect1783{}) input.InitEffect(input.EffectType.Sub, 1783, &Effect1783Sub{}) + input.InitEffect(input.EffectType.Skill, 1784, &Effect1784{}) + input.InitEffect(input.EffectType.Sub, 1784, &Effect1784Sub{}) + input.InitEffect(input.EffectType.Skill, 1790, &Effect1790{}) input.InitEffect(input.EffectType.Skill, 1791, &Effect1791{}) input.InitEffect(input.EffectType.Skill, 1792, &Effect1792{}) input.InitEffect(input.EffectType.Skill, 1793, &Effect1793{}) diff --git a/logic/service/fight/effect/2070_2094.go b/logic/service/fight/effect/2070_2094.go index 437f31479..2430c4b98 100644 --- a/logic/service/fight/effect/2070_2094.go +++ b/logic/service/fight/effect/2070_2094.go @@ -1,6 +1,7 @@ package effect import ( + "blazing/common/data/xmlres" "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" @@ -10,11 +11,170 @@ import ( "github.com/gogf/gf/v2/util/grand" ) +const ( + petStatus2077Holy info.EnumPetStatus = 32 + petStatus2077Evil info.EnumPetStatus = 33 +) + +func effect2077StatusID(formType int, opposite bool) int { + statusID := int(petStatus2077Holy) + if formType != 0 { + statusID = int(petStatus2077Evil) + } + if opposite { + if statusID == int(petStatus2077Holy) { + return int(petStatus2077Evil) + } + return int(petStatus2077Holy) + } + return statusID +} + +func isControlStatus2087(statusID int) bool { + switch info.EnumPetStatus(statusID) { + case info.PetStatus.Paralysis, + info.PetStatus.Tired, + info.PetStatus.Fear, + info.PetStatus.Petrified, + info.PetStatus.Sleep: + return true + default: + return false + } +} + +func countNotFullSkillPP2088(target *input.Input) int { + if target == nil || target.CurrentPet == nil { + return 0 + } + + count := 0 + for _, skillInfo := range target.CurrentPet.Info.SkillList { + skill, ok := xmlres.SkillMap[int(skillInfo.ID)] + if !ok || skill.MaxPP <= 0 { + continue + } + if skillInfo.PP < uint32(skill.MaxPP) { + count++ + } + } + return count +} + +func restoreAllSkillPP2089(target *input.Input) { + if target == nil || target.CurrentPet == nil { + return + } + target.HealPP(-1) +} + // Effect 2072: 自身处于异常状态时先制+1且必定命中 type Effect2072 struct { node.EffectNode } +// Effect 2070: 下{0}次自身能力提升状态被反转时令该效果无效 +type Effect2070 struct { + node.EffectNode +} + +func (e *Effect2070) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2070, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2070Sub struct { + RoundEffectArg0Base +} + +func (e *Effect2070Sub) SetArgs(t *input.Input, a ...int) { + e.RoundEffectArg0Base.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.Stack(a[0]) + } +} + +func (e *Effect2070Sub) PropBefer(source *input.Input, prop int8, level int8) bool { + 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 + } + if e.Stack() <= 0 { + e.Alive(false) + return true + } + e.Stack(e.Stack() - 1) + if e.Stack() <= 0 { + e.Alive(false) + } + return false +} + +// Effect 2071: 自身被击败后,对手下{0}次体力恢复效果减少{1}% +type Effect2071 struct { + node.EffectNode +} + +func (e *Effect2071) SwitchOut(in *input.Input) bool { + if in != e.Ctx().Our || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Our.CurrentPet.Alive() { + return true + } + if len(e.Args()) < 2 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2071, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2071Sub struct { + RoundEffectArg0Base +} + +func (e *Effect2071Sub) SetArgs(t *input.Input, a ...int) { + e.RoundEffectArg0Base.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.Stack(a[0]) + } +} + +func (e *Effect2071Sub) Heal_Pre(_ action.BattleActionI, value *int) bool { + if len(e.Args()) < 2 || value == nil || *value <= 0 { + return true + } + if e.Stack() <= 0 { + e.Alive(false) + return true + } + + reduce := *value * int(e.Args()[1].IntPart()) / 100 + if reduce > *value { + reduce = *value + } + *value -= reduce + e.Stack(e.Stack() - 1) + if e.Stack() <= 0 { + e.Alive(false) + } + return true +} + func (e *Effect2072) ComparePre(fattack, sattack *action.SelectSkillAction) bool { if !e.Ctx().Our.StatEffect_Exist_all() { return true @@ -102,6 +262,294 @@ func (e *Effect2074) Skill_Use() bool { return true } +// Effect 2080: 自身处于护盾状态时威力提升{0}% +// Effect 2075: 未击败对手则对手{0}回合无法解除、反转自身能力下降状态 +type Effect2075 struct { + node.EffectNode +} + +func (e *Effect2075) Action_end() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2075, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2075Sub struct { + RoundEffectArg0Base +} + +func (e *Effect2075Sub) SwitchOut(in *input.Input) bool { + if in == e.Ctx().Our { + e.Alive(false) + } + return true +} + +func (e *Effect2075Sub) PropBefer(source *input.Input, prop int8, level int8) bool { + if source != e.Ctx().Our { + return true + } + if prop < 0 || int(prop) >= len(e.Ctx().Our.Prop) { + return true + } + if e.Ctx().Our.Prop[prop] >= 0 { + return true + } + if level >= 0 { + return false + } + return true +} + +// Effect 2076: {0}回合内使用技能吸取对手最大体力的1/{1},自身低于1/{2}时效果翻倍,吸取后若对手体力未减少则为己方所有不在场精灵恢复{3}点体力 +type Effect2076 struct { + RoundEffectArg0Base +} + +func (e *Effect2076) Skill_Use() bool { + if len(e.Args()) < 4 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + return true + } + if e.Args()[1].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + drain := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[1]) + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 { + threshold := e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[2]) + if e.Ctx().Our.CurrentPet.GetHP().Cmp(threshold) < 0 { + drain = drain.Mul(alpacadecimal.NewFromInt(2)) + } + } + + beforeHP := e.Ctx().Opp.CurrentPet.Info.Hp + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Percent, + Damage: drain, + }) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain) + + if beforeHP == e.Ctx().Opp.CurrentPet.Info.Hp && e.Args()[3].Cmp(alpacadecimal.Zero) > 0 { + healBench(e.Ctx().Our, e.Args()[3]) + } + return true +} + +// Effect 2077: {0}回合内使用技能吸取对手{1}点体力,自身体力低于1/{2}时效果翻倍,吸取后若对手体力减少值低于180则附加{3}点真实伤害与1层自身所处形态相应的圣告/邪诲 +type Effect2077 struct { + RoundEffectArg0Base +} + +func (e *Effect2077) Skill_Use() bool { + if len(e.Args()) < 4 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + return true + } + if e.Args()[1].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + drain := e.Args()[1] + if e.Args()[2].Cmp(alpacadecimal.Zero) > 0 { + threshold := e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[2]) + if e.Ctx().Our.CurrentPet.GetHP().Cmp(threshold) < 0 { + drain = drain.Mul(alpacadecimal.NewFromInt(2)) + } + } + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + beforeHP := e.Ctx().Opp.CurrentPet.Info.Hp + 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) + + if int64(beforeHP)-int64(e.Ctx().Opp.CurrentPet.Info.Hp) < 180 { + if e.Args()[3].Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.True, + Damage: e.Args()[3], + }) + } + if e.Ctx().Our.CurrentPet != nil { + addStatusEffect(e.Ctx().Our, e.Ctx().Opp, effect2077StatusID(e.Ctx().Our.CurrentPet.PetInfo.Type, false)) + } + } + return true +} + +// Effect 2078: 吸取对手{0}点体力,吸取后若对手体力减少值低于180则为对手附加1层自身所处形态相反的圣告/邪诲 +type Effect2078 struct { + RoundEffectArg0Base +} + +func (e *Effect2078) 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 || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + return true + } + if e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + drain := e.Args()[0] + beforeHP := e.Ctx().Opp.CurrentPet.Info.Hp + 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) + + if int64(beforeHP)-int64(e.Ctx().Opp.CurrentPet.Info.Hp) < 180 && e.Ctx().Our.CurrentPet != nil { + addStatusEffect(e.Ctx().Our, e.Ctx().Opp, effect2077StatusID(e.Ctx().Our.CurrentPet.PetInfo.Type, true)) + } + return true +} + +// Effect 2079: 对手处于护盾状态时先制+1并无视对手护盾 +type Effect2079 struct { + node.EffectNode +} + +func (e *Effect2079) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if !e.Ctx().Opp.HasShield() { + return true + } + + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current != nil && current.SkillEntity != nil { + current.SkillEntity.XML.Priority += 1 + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2079) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2079Sub struct { + node.EffectNode +} + +func (e *Effect2079Sub) Damage_Shield(zone *info.DamageZone) bool { + if zone == nil || zone.Damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Our.CurrentShield().Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Our.ConsumeAllShield() + e.Alive(false) + return true +} + +func (e *Effect2079Sub) SwitchOut(in *input.Input) bool { + if in == e.Ctx().Our { + e.Alive(false) + } + return true +} + +type Effect2080 struct { + node.EffectNode +} + +func (e *Effect2080) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 { + return true + } + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if !e.Ctx().Our.HasShield() { + return true + } + + zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred) + return true +} + +// Effect 2081: 对手不处于异常状态时令对手随机{0}个技能PP值归零 +type Effect2081 struct { + node.EffectNode +} + +func (e *Effect2081) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + if e.Ctx().Opp.StatEffect_Exist_all() { + return true + } + + zeroRandomSkillPP(e.Ctx().Opp, int(e.Args()[0].IntPart())) + return true +} + +// Effect 2082: 为对手附加1道天霆之律 +type Effect2082 struct { + node.EffectNode +} + +func (e *Effect2082) Skill_Use() bool { + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + if eff := e.Ctx().Opp.GetEffect(input.EffectType.Sub, 2082); eff != nil { + if sub, ok := eff.(*Effect2082Sub); ok && sub != nil && sub.Stack() >= 3 { + return true + } + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2082) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2082Sub struct { + node.EffectNode +} + +func (e *Effect2082Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.CanStack(true) + e.Duration(-1) + e.Stack(1) +} + +func (e *Effect2082Sub) HookPP(count *int) bool { + if count == nil || e.Stack() <= 0 { + return true + } + + *count += e.Stack() + return true +} + +func (e *Effect2082Sub) SwitchOut(in *input.Input) bool { + if in != e.Ctx().Our { + return true + } + + zeroRandomSkillPP(e.Ctx().Our, e.Stack()) + e.Alive(false) + return true +} + // Effect 2083: 对手选择必中技能时先制+3 type Effect2083 struct { node.EffectNode @@ -162,9 +610,429 @@ func (e *Effect2084Sub) Skill_Use_ex() bool { return true } +// Effect 2085: 命中后自身{0},若造成的伤害高于{6}则效果翻倍 +type Effect2085 struct { + node.EffectNode +} + +func (e *Effect2085) 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 || e.Ctx().SkillEntity.AttackTime == 0 || len(e.Args()) < 7 { + return true + } + + multiplier := int8(1) + if zone.Damage.Cmp(e.Args()[6]) > 0 { + multiplier = 2 + } + for i := 0; i < 6; i++ { + boost := int8(e.Args()[i].IntPart()) * multiplier + if boost != 0 { + e.Ctx().Our.SetProp(e.Ctx().Our, int8(i), boost) + } + } + return true +} + +// Effect 2086: 空元之诗·渍:若技能无效,则消除对手回合类效果、能力提升效果,消除成功任意一项则令对手诅咒 +type Effect2086 struct { + node.EffectNode +} + +func (e *Effect2086) Skill_Use_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime != 0 { + return true + } + + cleared := false + if activeTurnEffectCount(e.Ctx().Opp) > 0 { + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + cleared = true + } + if clearPositiveProps(e.Ctx().Opp, e.Ctx().Our) { + cleared = true + } + if cleared { + addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(petStatusCurse)) + } + return true +} + +// Effect 2087: 空元之诗·镀:若对手处于控制类异常状态,则己方免疫下2次受到的异常状态 +type Effect2087 struct { + node.EffectNode +} + +func (e *Effect2087) Skill_Use() bool { + if e.Ctx().Opp == nil { + return true + } + + hasControl := false + for _, statusID := range []info.EnumPetStatus{ + info.PetStatus.Paralysis, + info.PetStatus.Tired, + info.PetStatus.Fear, + info.PetStatus.Petrified, + info.PetStatus.Sleep, + } { + if e.Ctx().Opp.StatEffect_Exist(statusID) { + hasControl = true + break + } + } + if !hasControl { + return true + } + + if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2087, 2); eff != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + } + return true +} + +type Effect2087Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect2087Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect2087Sub) 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 + } + + if !isControlStatus2087(int(effEffect.ID().Suffix())) { + return true + } + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return false +} + +// Effect 2088: 空元之诗·柱:若对手处于回合类效果,则对手每有1个技能PP值不为满附加50点次元·龙系伤害且对手下回合无法主动切换精灵 +type Effect2088 struct { + node.EffectNode +} + +func (e *Effect2088) Skill_Use() bool { + if e.Ctx().Opp == nil || activeTurnEffectCount(e.Ctx().Opp) <= 0 { + return true + } + + count := countNotFullSkillPP2088(e.Ctx().Opp) + if count > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: alpacadecimal.NewFromInt(int64(50 * count)), + }) + } + + if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2088, 2); eff != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) + e.Ctx().Opp.CanChange = 1 + } + return true +} + +type Effect2088Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect2088Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + if len(a) > 0 { + e.remaining = a[0] + } +} + +func (e *Effect2088Sub) TurnEnd() { + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + + e.remaining-- + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + e.Ctx().Our.CanChange = 1 +} + +// Effect 2089: 空元之诗·烙:若自身为先出手,则此技能每剩余1点PP值附加50点次元·龙系伤害,下次击败对手后恢复自身全部体力与PP值 +type Effect2089 struct { + node.EffectNode +} + +func (e *Effect2089) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || !e.IsFirst() || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + + if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2089); eff != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + } + return true +} + +func (e *Effect2089) 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 || e.Ctx().SkillEntity.AttackTime == 0 || !e.IsFirst() { + return true + } + + bonus := alpacadecimal.NewFromInt(int64(e.Ctx().SkillEntity.Info.PP * 50)) + if bonus.Cmp(alpacadecimal.Zero) > 0 { + zone.Damage = zone.Damage.Add(bonus) + } + return true +} + +type Effect2089Sub struct { + node.EffectNode +} + +func (e *Effect2089Sub) Action_end() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp > 0 { + return true + } + + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Ctx().Our.CurrentPet.GetMaxHP()) + restoreAllSkillPP2089(e.Ctx().Our) + e.Alive(false) + return true +} + +func getPoemState2091(owner *input.Input, create bool) *Effect2091 { + if owner == nil { + return nil + } + if eff := owner.GetEffect(input.EffectType.Sub, 2091); eff != nil { + if state, ok := eff.(*Effect2091); ok && state.Alive() { + return state + } + } + if !create { + return nil + } + eff := owner.InitEffect(input.EffectType.Sub, 2091) + if eff == nil { + return nil + } + owner.AddEffect(owner, eff) + state, ok := eff.(*Effect2091) + if !ok { + return nil + } + return state +} + +// Effect 2090: 空元之诗·均:附加双方体力上限差值50%的次元·龙系伤害,自身体力上限高于对手时额外吸取对手第五技能剩余的PP值,自身体力上限低于对手时附加伤害翻倍 +type Effect2090 struct{ node.EffectNode } + +func (e *Effect2090) Skill_Use() bool { + if e.Ctx().Our == nil || e.Ctx().Opp == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + if e.Ctx().Our.CurrentPet.GetMaxHP().Cmp(e.Ctx().Opp.CurrentPet.GetMaxHP()) <= 0 { + return true + } + if len(e.Ctx().Opp.CurrentPet.Info.SkillList) < 5 { + return true + } + pp := e.Ctx().Opp.CurrentPet.Info.SkillList[4].PP + if pp <= 0 { + return true + } + e.Ctx().Opp.CurrentPet.Info.SkillList[4].PP = 0 + return true +} + +func (e *Effect2090) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().Our == nil || e.Ctx().Opp == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + ourMax := e.Ctx().Our.CurrentPet.GetMaxHP() + oppMax := e.Ctx().Opp.CurrentPet.GetMaxHP() + diff := ourMax.Sub(oppMax).Abs() + if diff.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + bonus := diff.Mul(alpacadecimal.NewFromInt(50)).Div(hundred) + if ourMax.Cmp(oppMax) < 0 { + bonus = bonus.Mul(alpacadecimal.NewFromInt(2)) + } + if bonus.Cmp(alpacadecimal.Zero) > 0 { + zone.Damage = zone.Damage.Add(bonus) + } + return true +} + +// Effect 2091: 空妄诗章计数状态 +type Effect2091 struct{ node.EffectNode } + +func (e *Effect2091) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.CanStack(true) +} + +// Effect 2092: 全属性+{0}并将空妄诗章补充至与自身先制等级相等,自身没有空妄诗章时额外书写{1}篇,拥有时强化效果翻倍 +type Effect2092 struct{ node.EffectNode } + +func (e *Effect2092) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Our == nil { + return true + } + poem := getPoemState2091(e.Ctx().Our, true) + if poem == nil { + return true + } + boost := int(e.Args()[0].IntPart()) + if poem.Stack() > 0 { + boost *= 2 + } + boostAllProps2294(e.Ctx().Our, boost) + + priority := 0 + if e.Ctx().SkillEntity != nil { + priority = e.Ctx().SkillEntity.XML.Priority + if priority < 0 { + priority = 0 + } + } + poems := poem.Stack() + if poems < priority { + poems = priority + } + if poem.Stack() <= 0 { + poems += int(e.Args()[1].IntPart()) + } + poem.Stack(poems) + return true +} + +// Effect 2093: {0}回合内使用技能吸取对手最大体力的1/{1},自身体力低于1/{2}时效果翻倍,吸取后若对手体力未减少则{3}回合内对手{4} +type Effect2093 struct{ node.EffectNode } + +func (e *Effect2093) Skill_Use() bool { + if len(e.Args()) < 5 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2093, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart()), int(e.Args()[3].IntPart()), int(e.Args()[4].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2093Sub struct { + RoundEffectArg0Base +} + +func (e *Effect2093Sub) Skill_Use() bool { + if len(e.Args()) < 5 || e.Ctx().Our == nil || e.Ctx().Opp == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + drain := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[1]) + if e.Ctx().Our.CurrentPet.GetHP().Cmp(e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[2])) < 0 { + drain = drain.Mul(alpacadecimal.NewFromInt(2)) + } + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + before := e.Ctx().Opp.CurrentPet.Info.Hp + 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) + if e.Ctx().Opp.CurrentPet.Info.Hp >= before { + return true + } + return true +} + +// Effect 2094: 自身每有1篇空妄诗章造成的攻击伤害提升{0}%,若空妄诗章的篇数高于{1}则每有1篇额外附加{2}点真实伤害 +type Effect2094 struct{ node.EffectNode } + +func (e *Effect2094) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 3 || e.Ctx().Our == nil { + return true + } + poem := getPoemState2091(e.Ctx().Our, false) + if poem == nil || poem.Stack() <= 0 { + return true + } + count := poem.Stack() + bonus := alpacadecimal.NewFromInt(int64(count) * e.Args()[0].IntPart()) + if bonus.Cmp(alpacadecimal.Zero) > 0 { + zone.Damage = zone.Damage.Mul(hundred.Add(bonus)).Div(hundred) + } + if count > int(e.Args()[1].IntPart()) { + extra := alpacadecimal.NewFromInt(int64(count) * e.Args()[2].IntPart()) + if extra.Cmp(alpacadecimal.Zero) > 0 { + zone.Damage = zone.Damage.Add(extra) + } + } + return true +} + func init() { + holy := &BaseStatus{} + holy.Status = petStatus2077Holy + input.InitEffect(input.EffectType.Status, int(petStatus2077Holy), holy) + evil := &BaseStatus{} + evil.Status = petStatus2077Evil + input.InitEffect(input.EffectType.Status, int(petStatus2077Evil), evil) + + input.InitEffect(input.EffectType.Skill, 2070, &Effect2070{}) + input.InitEffect(input.EffectType.Sub, 2070, &Effect2070Sub{}) + input.InitEffect(input.EffectType.Skill, 2071, &Effect2071{}) + input.InitEffect(input.EffectType.Sub, 2071, &Effect2071Sub{}) input.InitEffect(input.EffectType.Skill, 2074, &Effect2074{}) + input.InitEffect(input.EffectType.Skill, 2075, &Effect2075{}) + input.InitEffect(input.EffectType.Sub, 2075, &Effect2075Sub{}) + input.InitEffect(input.EffectType.Skill, 2076, &Effect2076{}) + input.InitEffect(input.EffectType.Skill, 2077, &Effect2077{}) + input.InitEffect(input.EffectType.Skill, 2078, &Effect2078{}) + input.InitEffect(input.EffectType.Skill, 2079, &Effect2079{}) + input.InitEffect(input.EffectType.Sub, 2079, &Effect2079Sub{}) + input.InitEffect(input.EffectType.Skill, 2080, &Effect2080{}) + input.InitEffect(input.EffectType.Skill, 2081, &Effect2081{}) + input.InitEffect(input.EffectType.Skill, 2082, &Effect2082{}) + input.InitEffect(input.EffectType.Sub, 2082, &Effect2082Sub{}) input.InitEffect(input.EffectType.Skill, 2083, &Effect2083{}) input.InitEffect(input.EffectType.Skill, 2084, &Effect2084{}) input.InitEffect(input.EffectType.Sub, 2084, &Effect2084Sub{}) + input.InitEffect(input.EffectType.Skill, 2085, &Effect2085{}) + input.InitEffect(input.EffectType.Skill, 2086, &Effect2086{}) + input.InitEffect(input.EffectType.Skill, 2087, &Effect2087{}) + input.InitEffect(input.EffectType.Sub, 2087, &Effect2087Sub{}) + input.InitEffect(input.EffectType.Skill, 2088, &Effect2088{}) + input.InitEffect(input.EffectType.Sub, 2088, &Effect2088Sub{}) + input.InitEffect(input.EffectType.Skill, 2089, &Effect2089{}) + input.InitEffect(input.EffectType.Sub, 2089, &Effect2089Sub{}) + input.InitEffect(input.EffectType.Skill, 2090, &Effect2090{}) + input.InitEffect(input.EffectType.Sub, 2091, &Effect2091{}) + input.InitEffect(input.EffectType.Skill, 2092, &Effect2092{}) + input.InitEffect(input.EffectType.Skill, 2093, &Effect2093{}) + input.InitEffect(input.EffectType.Sub, 2093, &Effect2093Sub{}) + input.InitEffect(input.EffectType.Skill, 2094, &Effect2094{}) } diff --git a/logic/service/fight/effect/2120_2144.go b/logic/service/fight/effect/2120_2144.go index 0b48181dd..08da73474 100644 --- a/logic/service/fight/effect/2120_2144.go +++ b/logic/service/fight/effect/2120_2144.go @@ -10,6 +10,18 @@ import ( "github.com/alpacahq/alpacadecimal" ) +func healBench2121(owner *input.Input, amount alpacadecimal.Decimal) { + if owner == nil || amount.Cmp(alpacadecimal.Zero) <= 0 { + return + } + for _, pet := range owner.AllPet { + if pet == nil || !pet.Alive() || pet == owner.CurrentPet { + continue + } + pet.Info.ModelHP(amount.IntPart()) + } +} + func clearTargetEffects(owner, target *input.Input) bool { if owner == nil || target == nil { return false @@ -36,9 +48,134 @@ func addStatusEffect(owner, target *input.Input, statusID int) bool { return true } +const ( + status2135LossLife = 2135 + status2136ReturnLife = 2136 + status2138ShadowSeed = 2138 + status2139ShadowRoot = 2139 +) + +var effect2137StatusRounds = []info.EnumPetStatus{ + info.PetStatus.Paralysis, + info.PetStatus.Poisoned, + info.PetStatus.Burned, + info.PetStatus.DrainHP, + info.PetStatus.Frozen, + info.PetStatus.Fear, + info.PetStatus.Tired, + info.PetStatus.Sleep, + info.PetStatus.Petrified, + info.PetStatus.Confused, + info.PetStatus.Weakened, + info.PetStatus.Flammable, + info.PetStatus.Berserk, + info.PetStatus.IceBound, + info.PetStatus.Bleeding, + info.PetStatus.Paralyzed, + info.PetStatus.Blind, +} + +type timedStatus struct { + BaseStatus + defaultDuration int + stackable bool +} + +func (e *timedStatus) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t) + e.Duration(e.defaultDuration) + e.CanStack(e.stackable) +} + +func getAliveStatusEffect(target *input.Input, statusID int) input.Effect { + if target == nil { + return nil + } + eff := target.GetEffect(input.EffectType.Status, statusID) + if eff == nil || !eff.Alive() { + return nil + } + return eff +} + +func addTimedStatus(owner, target *input.Input, statusID, duration int) bool { + if owner == nil || target == nil { + return false + } + eff := owner.InitEffect(input.EffectType.Status, statusID, duration) + if eff == nil { + return false + } + if duration <= 0 { + duration = 1 + } + eff.Duration(duration) + target.AddEffect(owner, eff) + return true +} + +func transferTimedStatus(owner, source, target *input.Input, statusID int) bool { + eff := getAliveStatusEffect(source, statusID) + if eff == nil { + return false + } + + duration := eff.Duration() + if duration <= 0 { + duration = 1 + } + eff.Alive(false) + return addTimedStatus(owner, target, statusID, duration) +} + +func countEffectRounds(target *input.Input, statusIDs []info.EnumPetStatus) int { + if target == nil { + return 0 + } + total := 0 + for _, statusID := range statusIDs { + eff := getAliveStatusEffect(target, int(statusID)) + if eff == nil { + continue + } + if duration := eff.Duration(); duration > 0 { + total += duration + } + } + return total +} + +func addShadowRoot(owner, target *input.Input) bool { + if owner == nil || target == nil { + return false + } + eff := owner.InitEffect(input.EffectType.Status, status2139ShadowRoot) + if eff == nil { + return false + } + eff.Stack(1) + target.AddEffect(owner, eff) + return true +} + +func hasShadowSeed(target *input.Input) bool { + return getAliveStatusEffect(target, status2138ShadowSeed) != nil +} + // Effect 2120: 自身为对手天敌时n回合内受到攻击的伤害减少m% type Effect2120 struct{ node.EffectNode } +func (e *Effect2120) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2120, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart())) + if eff != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + } + return true +} + func (e *Effect2120) DamageDivEx(zone *info.DamageZone) bool { if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 || !e.ISNaturalEnemy() { return true @@ -47,19 +184,45 @@ func (e *Effect2120) DamageDivEx(zone *info.DamageZone) bool { return true } +type Effect2120Sub struct{ RoundEffectArg0Base } + // Effect 2121: 未击败对手则己方场下精灵吸取对手最大体力的n% type Effect2121 struct{ node.EffectNode } func (e *Effect2121) Skill_Use() bool { - if len(e.Args()) == 0 || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { + if len(e.Args()) == 0 || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { return true } + eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2121, int(e.Args()[0].IntPart())) + if eff != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + } + return true +} + +type Effect2121Sub struct { + node.EffectNode +} + +func (e *Effect2121Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) +} + +func (e *Effect2121Sub) TurnEnd() { + if len(e.Args()) == 0 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { + return + } heal := e.Ctx().Opp.CurrentPet.GetMaxHP().Mul(e.Args()[0]).Div(alpacadecimal.NewFromInt(100)) if heal.Cmp(alpacadecimal.Zero) <= 0 { - return true + return + } + before := e.Ctx().Opp.CurrentPet.Info.Hp + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Percent, Damage: heal}) + healBench2121(e.Ctx().Our, heal) + if e.Ctx().Opp.CurrentPet.Info.Hp < before { + e.Alive(false) } - e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) - return true } // Effect 2122: 获得护罩,护罩消失时自身所有技能PP值+{1} @@ -70,6 +233,43 @@ func (e *Effect2122) Skill_Use() bool { return true } e.Ctx().Our.AddShield(e.Args()[0]) + eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2122, int(e.Args()[1].IntPart())) + if eff != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + } + return true +} + +type Effect2122Sub struct { + node.EffectNode +} + +func (e *Effect2122Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) +} + +func (e *Effect2122Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 || len(e.Args()) == 0 { + return true + } + restore := uint32(e.Args()[0].IntPart()) + if restore == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { + return true + } + for i := range e.Ctx().Our.CurrentPet.Info.SkillList { + skillInfo := &e.Ctx().Our.CurrentPet.Info.SkillList[i] + skill, ok := xmlres.SkillMap[int(skillInfo.ID)] + if !ok || skill.MaxPP <= 0 { + continue + } + next := skillInfo.PP + restore + if next > uint32(skill.MaxPP) { + next = uint32(skill.MaxPP) + } + skillInfo.PP = next + } + e.Alive(false) return true } @@ -113,7 +313,13 @@ func (e *Effect2124) Damage_Mul(zone *info.DamageZone) bool { // Effect 2125: 携带此技能时,专属特性中对手属性技能无效的概率提升至100% type Effect2125 struct{ node.EffectNode } -func (e *Effect2125) SkillHit_ex() bool { return true } +func (e *Effect2125) SkillHit_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.SetNoSide() + return true +} // Effect 2126: 技能无效时,消除对手回合类效果、能力提升效果,并令对手烧伤 type Effect2126 struct{ node.EffectNode } @@ -195,15 +401,56 @@ func (e *Effect2129Sub) Damage_Mul(zone *info.DamageZone) bool { } // Effect 2130: 对手持有失能时必定命中且无视攻击免疫效果 -type Effect2130 struct{ node.EffectNode } +type Effect2130 struct { + node.EffectNode + disabled []input.Effect +} -func (e *Effect2130) SkillHit_ex() bool { return true } +func (e *Effect2130) SkillHit_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || !e.Ctx().Opp.HasPropSub() { + return true + } + + e.disabled = e.disabled[:0] + for _, eff := range e.Ctx().Opp.Effects { + if eff == nil || !eff.Alive() { + continue + } + if _, ok := effect1508IgnoredImmunityIDs[int(eff.ID().Suffix())]; !ok { + continue + } + eff.Alive(false) + e.disabled = append(e.disabled, eff) + } + e.Ctx().SkillEntity.AttackTime = 2 + e.Ctx().SkillEntity.Hit = true + return true +} + +func (e *Effect2130) Skill_Use() bool { + for _, eff := range e.disabled { + if eff != nil { + eff.Alive(true) + } + } + e.disabled = e.disabled[:0] + return true +} // Effect 2131: 自身持有回体时先制+1且附加对手最大体力1/{0}的百分比伤害 type Effect2131 struct{ node.EffectNode } +func (e *Effect2131) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil || !e.Ctx().Our.StatEffect_Exist(info.PetStatus.DrainedHP) { + return true + } + current.SkillEntity.XML.Priority++ + return true +} + func (e *Effect2131) Damage_Mul(zone *info.DamageZone) bool { - if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 || !e.Ctx().Our.StatEffect_Exist_all() { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) == 0 || !e.Ctx().Our.StatEffect_Exist(info.PetStatus.DrainedHP) { return true } zone.Damage = zone.Damage.Add(e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[0])) @@ -213,25 +460,20 @@ func (e *Effect2131) Damage_Mul(zone *info.DamageZone) bool { // Effect 2132: 对手持有失体时造成伤害提升100%,否则为对手附加3回合的失体并令对手害怕 type Effect2132 struct{ node.EffectNode } -func (e *Effect2132) OnSkill() bool { - if e.Ctx().Opp.StatEffect_Exist_all() { +func (e *Effect2132) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || !e.Ctx().Opp.StatEffect_Exist(info.PetStatus.DrainedHP) { return true } - addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.DrainHP)) - eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2132, 3) - if eff != nil { - e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) - } - addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.Fear)) + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(2)) return true } -type Effect2132Sub struct{ node.EffectNode } - -func (e *Effect2132Sub) Damage_Mul(zone *info.DamageZone) bool { - if zone != nil && zone.Type == info.DamageType.Red { - zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(2)) +func (e *Effect2132) OnSkill() bool { + if e.Ctx().Opp.StatEffect_Exist(info.PetStatus.DrainedHP) { + return true } + addTimedStatus(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.DrainedHP), 3) + addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.Fear)) return true } @@ -239,96 +481,149 @@ func (e *Effect2132Sub) Damage_Mul(zone *info.DamageZone) bool { type Effect2133 struct{ node.EffectNode } func (e *Effect2133) Skill_Use() bool { - if e.Ctx().Our.StatEffect_Exist_all() { + if e.Ctx().Our.StatEffect_Exist(info.PetStatus.DrainedHP) { return true } - addStatusEffect(e.Ctx().Our, e.Ctx().Our, int(info.PetStatus.DrainedHP)) - eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2133, 3) - if eff != nil { - e.Ctx().Our.AddEffect(e.Ctx().Our, eff) - } + addTimedStatus(e.Ctx().Our, e.Ctx().Our, int(info.PetStatus.DrainedHP), 3) addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.Tired)) return true } -type Effect2133Sub struct{ node.EffectNode } - -func (e *Effect2133Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { - current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) - if current != nil && current.SkillEntity != nil { - current.SkillEntity.XML.Priority++ - } - return true -} - // Effect 2134: 反转对手能力提升状态,反转成功则恢复自身所有体力和PP值 type Effect2134 struct{ node.EffectNode } func (e *Effect2134) OnSkill() bool { - if !clearTargetEffects(e.Ctx().Our, e.Ctx().Opp) { + reversed := false + for i, v := range e.Ctx().Opp.Prop[:] { + if v <= 0 { + continue + } + if e.Ctx().Opp.SetProp(e.Ctx().Our, int8(i), -2*v) { + reversed = true + } + } + if !reversed { return true } e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Ctx().Our.CurrentPet.GetMaxHP()) - for i := range e.Ctx().Our.CurrentPet.Info.SkillList { - if skill, ok := xmlres.SkillMap[int(e.Ctx().Our.CurrentPet.Info.SkillList[i].ID)]; ok { - e.Ctx().Our.CurrentPet.Info.SkillList[i].PP = uint32(skill.MaxPP) - } - } + e.Ctx().Our.HealPP(-1) return true } // Effect 2135: 自身未持有失命时为自身附加回合的失命,若自身持有失命则将失命转移给对手 type Effect2135 struct{ node.EffectNode } -func (e *Effect2135) Skill_Use() bool { return true } +func (e *Effect2135) Skill_Use() bool { + if transferTimedStatus(e.Ctx().Our, e.Ctx().Our, e.Ctx().Opp, status2135LossLife) { + return true + } + addTimedStatus(e.Ctx().Our, e.Ctx().Our, status2135LossLife, 3) + return true +} // Effect 2136: 对手未持有回命时为对手附加回合的回命,若对手持有回命且剩余回合数大于0则回合数-1 type Effect2136 struct{ node.EffectNode } -func (e *Effect2136) Skill_Use() bool { return true } +func (e *Effect2136) Skill_Use() bool { + if eff := getAliveStatusEffect(e.Ctx().Opp, status2136ReturnLife); eff != nil { + if eff.Duration() > 1 { + eff.Duration(eff.Duration() - 1) + } + return true + } + addTimedStatus(e.Ctx().Our, e.Ctx().Opp, status2136ReturnLife, 3) + return true +} // Effect 2137: 自身每有1回合异常状态造成伤害提升{0}%,最高{1}% type Effect2137 struct{ node.EffectNode } func (e *Effect2137) Damage_Mul(zone *info.DamageZone) bool { - if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || len(e.Args()) < 2 { return true } - if !e.Ctx().Our.StatEffect_Exist_all() { + rounds := countEffectRounds(e.Ctx().Our, effect2137StatusRounds) + if rounds <= 0 { return true } - zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + int64(e.Args()[0].IntPart()))).Div(alpacadecimal.NewFromInt(100)) + percent := int(e.Args()[0].IntPart()) + limit := int(e.Args()[1].IntPart()) + bonus := rounds * percent + if bonus > limit { + bonus = limit + } + if bonus <= 0 { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + int64(bonus))).Div(alpacadecimal.NewFromInt(100)) return true } // Effect 2138: 为对手种下悬暗之因,若对手悬暗之因已成熟则转化为自身1层悬暗之根 type Effect2138 struct{ node.EffectNode } -func (e *Effect2138) Skill_Use() bool { return true } +func (e *Effect2138) Skill_Use() bool { + if seed := getAliveStatusEffect(e.Ctx().Opp, status2138ShadowSeed); seed != nil && seed.Duration() <= 1 { + seed.Alive(false) + addShadowRoot(e.Ctx().Our, e.Ctx().Our) + return true + } + addTimedStatus(e.Ctx().Our, e.Ctx().Opp, status2138ShadowSeed, 3) + return true +} // Effect 2139: 100%令对手害怕,对手拥有悬暗之因时改为诅咒,自身拥有悬暗之根时每层伤害提升{0}% type Effect2139 struct{ node.EffectNode } func (e *Effect2139) Skill_Use() bool { - if len(e.Args()) == 0 { + if hasShadowSeed(e.Ctx().Opp) { + addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(petStatusCurse)) return true } addStatusEffect(e.Ctx().Our, e.Ctx().Opp, int(info.PetStatus.Fear)) return true } +func (e *Effect2139) 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 || len(e.Args()) == 0 { + return true + } + eff := getAliveStatusEffect(e.Ctx().Our, status2139ShadowRoot) + if eff == nil || eff.Stack() <= 0 { + return true + } + bonus := eff.Stack() * int(e.Args()[0].IntPart()) + if bonus <= 0 { + return true + } + zone.Damage = zone.Damage.Mul(alpacadecimal.NewFromInt(100 + int64(bonus))).Div(alpacadecimal.NewFromInt(100)) + return true +} + // Effect 2140: 吸取对手最大体力的{0}%,对手每有1层悬暗之因提升{1}%,吸取后若对手体力未减少则对手下{2}回合无法主动切换精灵 type Effect2140 struct{ node.EffectNode } func (e *Effect2140) Skill_Use() bool { - if len(e.Args()) < 3 { + if len(e.Args()) < 3 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp <= 0 { return true } - damage := e.Ctx().Opp.CurrentPet.GetMaxHP().Mul(e.Args()[0]).Div(alpacadecimal.NewFromInt(100)) + + beforeHP := e.Ctx().Opp.CurrentPet.GetHP() + percent := e.Args()[0] + if seed := getAliveStatusEffect(e.Ctx().Opp, status2138ShadowSeed); seed != nil && seed.Stack() > 0 { + percent = percent.Add(e.Args()[1].Mul(alpacadecimal.NewFromInt(int64(seed.Stack())))) + } + damage := e.Ctx().Opp.CurrentPet.GetMaxHP().Mul(percent).Div(alpacadecimal.NewFromInt(100)) if damage.Cmp(alpacadecimal.Zero) > 0 { e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{Type: info.DamageType.Percent, Damage: damage}) e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, damage) } + if e.Ctx().Opp.CurrentPet.GetHP().Cmp(beforeHP) >= 0 { + if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2144, int(e.Args()[2].IntPart())); eff != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) + e.Ctx().Opp.CanChange = 1 + } + } return true } @@ -336,19 +631,35 @@ func (e *Effect2140) Skill_Use() bool { type Effect2141 struct{ node.EffectNode } func (e *Effect2141) Skill_Use() bool { - addStatusEffect(e.Ctx().Our, e.Ctx().Our, int(info.PetStatus.Confused)) + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Opp.CurrentPet.Info.Hp > 0 { + return true + } + if !hasShadowSeed(e.Ctx().Opp) { + return true + } + addShadowRoot(e.Ctx().Our, e.Ctx().Our) return true } // Effect 2142: 无视对手正先制等级 type Effect2142 struct{ node.EffectNode } -func (e *Effect2142) ComparePre(fattack, sattack *action.SelectSkillAction) bool { return true } +func (e *Effect2142) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if current := actionByPlayer(fattack, sattack, e.Ctx().Opp.UserID); current != nil && current.SkillEntity != nil && current.SkillEntity.XML.Priority > 0 { + current.SkillEntity.XML.Priority = 0 + } + return true +} // Effect 2143: 无视自身负先制等级 type Effect2143 struct{ node.EffectNode } -func (e *Effect2143) ComparePre(fattack, sattack *action.SelectSkillAction) bool { return true } +func (e *Effect2143) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID); current != nil && current.SkillEntity != nil && current.SkillEntity.XML.Priority < 0 { + current.SkillEntity.XML.Priority = 0 + } + return true +} // Effect 2144: 双方n回合无法主动切换精灵 type Effect2144 struct{ node.EffectNode } @@ -359,9 +670,11 @@ func (e *Effect2144) Skill_Use() bool { } if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2144, int(e.Args()[0].IntPart())); eff != nil { e.Ctx().Our.AddEffect(e.Ctx().Our, eff) + e.Ctx().Our.CanChange = 1 } if eff := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2144, int(e.Args()[0].IntPart())); eff != nil { e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) + e.Ctx().Opp.CanChange = 1 } return true } @@ -380,16 +693,40 @@ func (e *Effect2144Sub) SetArgs(t *input.Input, a ...int) { } func (e *Effect2144Sub) SwitchOut(in *input.Input) bool { + if in != e.Ctx().Our { + return true + } + e.Ctx().Our.CanChange = 0 if e.remaining <= 0 { e.Alive(false) } - return false + return true +} + +func (e *Effect2144Sub) TurnEnd() { + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + e.remaining-- + if e.remaining <= 0 { + e.Ctx().Our.CanChange = 0 + e.Alive(false) + return + } + if e.Ctx().Our != nil && e.Ctx().Our.CurrentPet != nil && e.Ctx().Our.CurrentPet.Info.Hp > 0 { + e.Ctx().Our.CanChange = 1 + } } func init() { input.InitEffect(input.EffectType.Skill, 2120, &Effect2120{}) + input.InitEffect(input.EffectType.Sub, 2120, &Effect2120Sub{}) input.InitEffect(input.EffectType.Skill, 2121, &Effect2121{}) + input.InitEffect(input.EffectType.Sub, 2121, &Effect2121Sub{}) input.InitEffect(input.EffectType.Skill, 2122, &Effect2122{}) + input.InitEffect(input.EffectType.Sub, 2122, &Effect2122Sub{}) input.InitEffect(input.EffectType.Skill, 2123, &Effect2123{}) input.InitEffect(input.EffectType.Skill, 2124, &Effect2124{}) input.InitEffect(input.EffectType.Skill, 2125, &Effect2125{}) @@ -402,14 +739,16 @@ func init() { input.InitEffect(input.EffectType.Skill, 2130, &Effect2130{}) input.InitEffect(input.EffectType.Skill, 2131, &Effect2131{}) input.InitEffect(input.EffectType.Skill, 2132, &Effect2132{}) - input.InitEffect(input.EffectType.Sub, 2132, &Effect2132Sub{}) input.InitEffect(input.EffectType.Skill, 2133, &Effect2133{}) - input.InitEffect(input.EffectType.Sub, 2133, &Effect2133Sub{}) input.InitEffect(input.EffectType.Skill, 2134, &Effect2134{}) + input.InitEffect(input.EffectType.Status, status2135LossLife, &timedStatus{defaultDuration: 3}) input.InitEffect(input.EffectType.Skill, 2135, &Effect2135{}) + input.InitEffect(input.EffectType.Status, status2136ReturnLife, &timedStatus{defaultDuration: 3}) input.InitEffect(input.EffectType.Skill, 2136, &Effect2136{}) input.InitEffect(input.EffectType.Skill, 2137, &Effect2137{}) + input.InitEffect(input.EffectType.Status, status2138ShadowSeed, &timedStatus{defaultDuration: 3}) input.InitEffect(input.EffectType.Skill, 2138, &Effect2138{}) + input.InitEffect(input.EffectType.Status, status2139ShadowRoot, &timedStatus{defaultDuration: -1, stackable: true}) input.InitEffect(input.EffectType.Skill, 2139, &Effect2139{}) input.InitEffect(input.EffectType.Skill, 2140, &Effect2140{}) input.InitEffect(input.EffectType.Skill, 2141, &Effect2141{}) diff --git a/logic/service/fight/effect/2195_2219.go b/logic/service/fight/effect/2195_2219.go index fd0ba8e38..fc78808d1 100644 --- a/logic/service/fight/effect/2195_2219.go +++ b/logic/service/fight/effect/2195_2219.go @@ -27,6 +27,78 @@ func clearOwnStatusEffects(target *input.Input) bool { return cleared } +func countLightDarkSkills(target *input.Input) (light, dark int) { + if target == nil || target.CurrentPet == nil { + return 0, 0 + } + for _, skillInfo := range target.CurrentPet.Info.SkillList { + skill, ok := xmlres.SkillMap[int(skillInfo.ID)] + if !ok { + continue + } + switch skill.Type { + case int(element.ElementTypeLight): + light++ + case int(element.ElementTypeDark): + dark++ + } + } + return light, dark +} + +func currentNewSelEffect(our *input.Input, id int) bool { + if our == nil || our.CurrentPet == nil { + return false + } + eff := our.GetEffect(input.EffectType.NewSel, id) + if eff == nil || !eff.Alive() { + return false + } + return eff.ID().GetCatchTime() == our.CurrentPet.Info.CatchTime +} + +func attackSkillPPCount(target *input.Input) int { + if target == nil || target.CurrentPet == nil { + return 0 + } + count := 0 + for _, skillInfo := range target.CurrentPet.Info.SkillList { + skill, ok := xmlres.SkillMap[int(skillInfo.ID)] + if !ok || skill.Category == int(info.Category.STATUS) || skillInfo.PP == 0 { + continue + } + count++ + } + return count +} + +func zeroRandomAttackSkillPP(target *input.Input, count int) int { + if target == nil || target.CurrentPet == nil || count <= 0 { + return 0 + } + + zeroed := 0 + for zeroed < count { + candidates := make([]int, 0, len(target.CurrentPet.Info.SkillList)) + for i, skillInfo := range target.CurrentPet.Info.SkillList { + skill, ok := xmlres.SkillMap[int(skillInfo.ID)] + if !ok || skill.Category == int(info.Category.STATUS) || skillInfo.PP == 0 { + continue + } + candidates = append(candidates, i) + } + if len(candidates) == 0 { + break + } + + idx := candidates[grand.Intn(len(candidates))] + target.CurrentPet.Info.SkillList[idx].PP = 0 + zeroed++ + } + + return zeroed +} + // Effect 2195: 消除对手回合类效果并降低先制 type Effect2195 struct { node.EffectNode @@ -149,20 +221,22 @@ type Effect2201 struct { node.EffectNode } -func (e *Effect2201) Damage_Mul(zone *info.DamageZone) bool { - if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 1 { +func (e *Effect2201) Skill_Use() bool { + if len(e.Args()) < 1 || e.Ctx().Our == nil || e.Ctx().Opp == nil { return true } - if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + light, dark := countLightDarkSkills(e.Ctx().Our) + if light == dark { return true } - if e.Ctx().SkillEntity.Pet == nil || e.Ctx().Opp.CurrentPet == nil { + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); !ok { return true } - if e.Ctx().SkillEntity.Pet.GetType().Primary == e.Ctx().Opp.CurrentPet.GetType().Primary { - return true + statusID := int(info.PetStatus.Fear) + if light > dark { + statusID = int(info.PetStatus.Tired) } - zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred) + addStatusByID(e.Ctx().Our, e.Ctx().Opp, statusID) return true } @@ -171,10 +245,41 @@ type Effect2202 struct { node.EffectNode } +func (e *Effect2202) Skill_Use() bool { + if len(e.Args()) < 1 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + light, dark := countLightDarkSkills(e.Ctx().Our) + if dark < light { + return true + } + if e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + divisor := e.Args()[0] + if divisor.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + damage := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(divisor) + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Percent, + Damage: damage, + }) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, damage) + return true +} + func (e *Effect2202) SkillHit() bool { if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { return true } + light, dark := countLightDarkSkills(e.Ctx().Our) + if light < dark { + return true + } e.Ctx().SkillEntity.XML.CritRate = 16 return true } @@ -185,6 +290,36 @@ type Effect2203 struct { } func (e *Effect2203) Skill_Use_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime != 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2203) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2203Sub struct { + node.EffectNode + remaining int +} + +func (e *Effect2203Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.remaining = 1 +} + +func (e *Effect2203Sub) DamageLockEx(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.remaining <= 0 { + return true + } + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + zone.Damage = alpacadecimal.Zero return true } @@ -194,12 +329,19 @@ type Effect2204 struct { } func (e *Effect2204) SkillHit() bool { - if e.Ctx().SkillEntity == nil || len(e.Args()) < 2 { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || len(e.Args()) < 2 { return true } + power := e.Ctx().SkillEntity.XML.Power if e.Ctx().Opp.StatEffect_Exist_all() { - e.Ctx().SkillEntity.XML.Power += int(e.Args()[1].IntPart()) + power += power * int(e.Args()[1].IntPart()) / 100 + } else { + power -= power * int(e.Args()[0].IntPart()) / 100 + if power < 0 { + power = 0 + } } + e.Ctx().SkillEntity.XML.Power = power return true } @@ -329,16 +471,27 @@ type Effect2210 struct { } func (e *Effect2210) Skill_Use() bool { - if e.Ctx().SkillEntity == nil { + skill := e.Ctx().SkillEntity + if skill == nil || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { return true } - if e.Ctx().Our.CurrentPet.PetInfo.Type == e.Ctx().Opp.CurrentPet.PetInfo.Type { + if skill.Category() == info.Category.STATUS { return true } - e.Ctx().SkillEntity.XML.Category = int(info.Category.PHYSICAL) - if e.Ctx().Our.CurrentPet.Info.Dv > 0 { - e.Ctx().SkillEntity.XML.Power += int(e.Ctx().Our.CurrentPet.Info.Dv) + + hasStarCui := currentNewSelEffect(e.Ctx().Our, 33) + hasStarZhe := currentNewSelEffect(e.Ctx().Our, 34) + if hasStarCui == hasStarZhe { + return true } + + if hasStarCui { + skill.XML.Category = int(info.Category.PHYSICAL) + } else { + skill.XML.Category = int(info.Category.SPECIAL) + } + skill.XML.Type = e.Ctx().Our.CurrentPet.PetInfo.Type + skill.XML.Power += int(e.Ctx().Our.CurrentPet.Info.Dv) return true } @@ -351,24 +504,102 @@ func (e *Effect2211) Skill_Use() bool { if len(e.Args()) < 3 { return true } - statusEffect := e.Ctx().Our.InitEffect(input.EffectType.Status, int(e.Args()[0].IntPart())) - if statusEffect != nil { - e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect) + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + + addLayers := int(e.Args()[0].IntPart()) + if addLayers <= 0 { + return true + } + + lockEffect := e.Ctx().Opp.GetEffect(input.EffectType.Sub, 2211) + if lockSub, ok := lockEffect.(*Effect2211Sub); ok && lockSub != nil { + nextStack := lockSub.Stack() + addLayers + if nextStack > effect2211LockCap { + nextStack = effect2211LockCap + if lockSub.overflowTurns < int(e.Args()[1].IntPart()) { + lockSub.overflowTurns = int(e.Args()[1].IntPart()) + } + lockSub.priorityDown = int(e.Args()[2].IntPart()) + } + lockSub.Stack(nextStack) + return true + } + + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 2211, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart())) + lockSub, ok := sub.(*Effect2211Sub) + if !ok || lockSub == nil { + return true + } + lockSub.CanStack(true) + lockSub.Duration(-1) + lockSub.Stack(addLayers) + if lockSub.Stack() > effect2211LockCap { + lockSub.Stack(effect2211LockCap) + lockSub.overflowTurns = int(e.Args()[1].IntPart()) + lockSub.priorityDown = int(e.Args()[2].IntPart()) + } + e.Ctx().Opp.AddEffect(e.Ctx().Our, lockSub) + return true +} + +type Effect2211Sub struct { + node.EffectNode + overflowTurns int + priorityDown int +} + +func (e *Effect2211Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if e.overflowTurns <= 0 || e.priorityDown <= 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Opp.UserID) + if current != nil && current.SkillEntity != nil && current.SkillEntity.Category() != info.Category.STATUS { + current.SkillEntity.XML.Priority -= e.priorityDown } return true } +func (e *Effect2211Sub) TurnEnd() { + if e.overflowTurns > 0 { + e.overflowTurns-- + } +} + // Effect 2212: 威力不高于阈值时使对手行动失效 type Effect2212 struct { node.EffectNode } -func (e *Effect2212) OnSkill() bool { - if len(e.Args()) < 3 || e.Ctx().SkillEntity == nil { +func (e *Effect2212) Skill_Use() bool { + if len(e.Args()) < 3 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { return true } - if e.Ctx().SkillEntity.XML.Power <= int(e.Args()[1].IntPart()) { - e.Ctx().Opp.CancelTurn(e.Ctx().Our) + + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 2212, int(e.Args()[0].IntPart()), int(e.Args()[1].IntPart()), int(e.Args()[2].IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect2212Sub struct { + RoundEffectArg0Base +} + +func (e *Effect2212Sub) ActionStart(a, b *action.SelectSkillAction) bool { + skill := e.Ctx().SkillEntity + if skill == nil || len(e.Args()) < 3 || skill.Category() == info.Category.STATUS { + return true + } + if skill.XML.Power > int(e.Args()[1].IntPart()) { + return false + } + + statusEffect := e.Ctx().Opp.InitEffect(input.EffectType.Status, int(e.Args()[2].IntPart())) + if statusEffect != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, statusEffect) } return true } @@ -378,27 +609,89 @@ type Effect2213 struct { node.EffectNode } -func (e *Effect2213) OnSkill() bool { - if len(e.Args()) == 0 { +func (e *Effect2213) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { return true } - if e.Ctx().Our.CurrentPet.GetHP().Cmp(alpacadecimal.Zero) <= 0 { + + currentHP := e.Ctx().Our.CurrentPet.GetHP() + if currentHP.Cmp(alpacadecimal.Zero) <= 0 { return true } - e.Ctx().Our.AddShield(e.Args()[0]) + + shield := currentHP.Mul(e.Args()[0]).Div(hundred) + if shield.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: currentHP, + }) + + if carry, ok := e.Ctx().Our.GetEffect(input.EffectType.Sub, 2213).(*Effect2213Sub); ok && carry != nil { + carry.shield = carry.shield.Add(shield) + carry.granted = false + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 2213) + carry, ok := sub.(*Effect2213Sub) + if !ok || carry == nil { + return true + } + carry.Duration(-1) + carry.shield = shield + e.Ctx().Our.AddEffect(e.Ctx().Our, carry) + return true +} + +type Effect2213Sub struct { + node.EffectNode + shield alpacadecimal.Decimal + granted bool +} + +func (e *Effect2213Sub) SwitchIn(in *input.Input) bool { + if in != e.Ctx().Our || e.granted || e.shield.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.granted = true + e.Ctx().Our.AddShield(e.shield) return true } // Effect 2214: 螺旋之锁下PP归零 type Effect2214 struct { node.EffectNode + boost bool } -func (e *Effect2214) OnSkill() bool { - if len(e.Args()) < 1 { +func (e *Effect2214) Skill_Use() bool { + e.boost = false + if len(e.Args()) < 1 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { return true } - zeroRandomSkillPP(e.Ctx().Opp, 1) + + lockEffect := e.Ctx().Opp.GetEffect(input.EffectType.Sub, 2211) + lockSub, ok := lockEffect.(*Effect2211Sub) + if !ok || lockSub == nil || lockSub.Stack() <= 0 { + return true + } + + if attackSkillPPCount(e.Ctx().Opp) < lockSub.Stack() { + e.boost = true + } + zeroRandomAttackSkillPP(e.Ctx().Opp, lockSub.Stack()) + return true +} + +func (e *Effect2214) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || !e.boost || len(e.Args()) == 0 { + return true + } + zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[0])).Div(hundred) + e.boost = false return true } @@ -538,6 +831,7 @@ func init() { input.InitEffect(input.EffectType.Skill, 2201, &Effect2201{}) input.InitEffect(input.EffectType.Skill, 2202, &Effect2202{}) input.InitEffect(input.EffectType.Skill, 2203, &Effect2203{}) + input.InitEffect(input.EffectType.Sub, 2203, &Effect2203Sub{}) input.InitEffect(input.EffectType.Skill, 2204, &Effect2204{}) input.InitEffect(input.EffectType.Skill, 2205, &Effect2205{}) input.InitEffect(input.EffectType.Skill, 2206, &Effect2206{}) @@ -547,8 +841,11 @@ func init() { input.InitEffect(input.EffectType.Skill, 2209, &Effect2209{}) input.InitEffect(input.EffectType.Skill, 2210, &Effect2210{}) input.InitEffect(input.EffectType.Skill, 2211, &Effect2211{}) + input.InitEffect(input.EffectType.Sub, 2211, &Effect2211Sub{}) input.InitEffect(input.EffectType.Skill, 2212, &Effect2212{}) + input.InitEffect(input.EffectType.Sub, 2212, &Effect2212Sub{}) input.InitEffect(input.EffectType.Skill, 2213, &Effect2213{}) + input.InitEffect(input.EffectType.Sub, 2213, &Effect2213Sub{}) input.InitEffect(input.EffectType.Skill, 2214, &Effect2214{}) input.InitEffect(input.EffectType.Skill, 2215, &Effect2215{}) input.InitEffect(input.EffectType.Skill, 2216, &Effect2216{}) diff --git a/logic/service/fight/effect/810_814.go b/logic/service/fight/effect/810_814.go index 8d23d4faf..e957c0815 100644 --- a/logic/service/fight/effect/810_814.go +++ b/logic/service/fight/effect/810_814.go @@ -1,7 +1,6 @@ package effect import ( - "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/fight/node" @@ -97,13 +96,13 @@ func (e *Effect812) TurnEnd() { if e.Ctx().Our.Prop[4] <= 0 { return } - + base := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[0]) damage := base.Mul(alpacadecimal.NewFromInt(int64(e.Ctx().Our.Prop[4]))) if damage.Cmp(alpacadecimal.Zero) <= 0 { return } - + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ Type: info.DamageType.Percent, Damage: damage, @@ -143,7 +142,7 @@ func (e *Effect814) OnSkill() bool { if damage.Cmp(alpacadecimal.Zero) <= 0 { return true } - + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ Type: info.DamageType.Fixed, Damage: damage,