feat(effect): 实现effects 1770-1794战斗效果

- 实现Effect 1770: 开启战魂附体效果,免疫对手下1次攻击技能伤害,
  若对手攻击技能PP值为满则额外免疫下1次固定伤害和百分比伤害

- 实现Effect 1771-1779相关战斗效果,包括能力状态反转、固定伤害计算等功能

- 实现Effect 1780-1794系列效果,包含伤害计算、护盾机制、切换限制等功能
This commit is contained in:
昔念
2026-03-31 08:28:37 +08:00
parent 1a804f5e19
commit 4cf1bcc07f
19 changed files with 2148 additions and 566 deletions

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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优先补核心逻辑或补充明确的不可实现说明

View File

@@ -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{})
}

View File

@@ -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{})

View File

@@ -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{})
}

View File

@@ -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{})

View File

@@ -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{})

View File

@@ -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,