diff --git a/.codex b/.codex new file mode 100644 index 000000000..e69de29bb diff --git a/docs/effect-unimplemented-tasks/task-155-effects-1388-1392.md b/docs/effect-unimplemented-tasks/task-155-effects-1388-1392.md deleted file mode 100644 index a38aad460..000000000 --- a/docs/effect-unimplemented-tasks/task-155-effects-1388-1392.md +++ /dev/null @@ -1,38 +0,0 @@ -# Task 155: Effects 1388-1392 - -## 目标 - -- 补齐以下 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 1388 -- `argsNum`: `2` -- `info`: `获得{0}点护罩,护罩消失时使对手{1}回合攻击技能无效` - -### Effect 1389 -- `argsNum`: `3` -- `info`: `{0}回合内自身能力提升状态被消除或吸取则{1}%使对手{2},未触发则消除对手回合类效果` -- `param`: `1,2,2` - -### Effect 1390 -- `argsNum`: `4` -- `info`: `{0}%令对手{1},未触发则{2}回合内每回合{3}%闪避对手攻击` -- `param`: `1,1,1` - -### Effect 1391 -- `argsNum`: `2` -- `info`: `{0}回合内若对手使用属性技能则造成伤害前令对手{1},未触发则消除对手回合类效果` -- `param`: `1,1,1` - -### Effect 1392 -- `argsNum`: `0` -- `info`: `解除自身能力下降状态,解除成功则消除对手回合类效果` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-160-effects-1413-1417.md b/docs/effect-unimplemented-tasks/task-160-effects-1413-1417.md deleted file mode 100644 index 2439e4c5e..000000000 --- a/docs/effect-unimplemented-tasks/task-160-effects-1413-1417.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 160: Effects 1413-1417 - -## 目标 - -- 补齐以下 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 1413 -- `argsNum`: `3` -- `info`: `{0}%的概率打出致命一击,未触发则下{1}回合自身先制+{2}` - -### Effect 1414 -- `argsNum`: `1` -- `info`: `消除敌我双方回合类效果,消除任意一项成功则敌我双方同时进入{0}状态` -- `param`: `1,0,0` - -### Effect 1415 -- `argsNum`: `2` -- `info`: `造成伤害的{0}%恢复自身体力,若自身体力低于对手则效果提升至{1}%` - -### Effect 1416 -- `argsNum`: `3` -- `info`: `消耗自身全部体力,使对手受到自身最大体力1/{0}的百分比伤害,同时使自身下只出场精灵前{1}回合{2}%闪避对手的攻击技能` - -### Effect 1417 -- `argsNum`: `2` -- `info`: `对手不处于能力下降状态则使对手随机{0}项能力值-{1}` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-161-effects-1418-1422.md b/docs/effect-unimplemented-tasks/task-161-effects-1418-1422.md deleted file mode 100644 index 3bc8da628..000000000 --- a/docs/effect-unimplemented-tasks/task-161-effects-1418-1422.md +++ /dev/null @@ -1,36 +0,0 @@ -# Task 161: Effects 1418-1422 - -## 目标 - -- 补齐以下 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 1418 -- `argsNum`: `1` -- `info`: `损失自身{0}点体力` - -### Effect 1419 -- `argsNum`: `2` -- `info`: `消除双方能力提升状态,消除任意一方成功则自身免疫下{0}次异常状态且令对手随机{1}个技能PP值归零` - -### Effect 1420 -- `argsNum`: `0` -- `info`: `自身处于能力提升状态时50%打出致命一击` - -### Effect 1421 -- `argsNum`: `4` -- `info`: `当回合打出的攻击伤害在{0}—{1}之间则{2}%令对手{3}` -- `param`: `1,3,3` - -### Effect 1422 -- `argsNum`: `2` -- `info`: `获得{0}点护罩,护罩消失时恢复自身{1}点体力` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-162-effects-1423-1427.md b/docs/effect-unimplemented-tasks/task-162-effects-1423-1427.md deleted file mode 100644 index 8f1c56114..000000000 --- a/docs/effect-unimplemented-tasks/task-162-effects-1423-1427.md +++ /dev/null @@ -1,39 +0,0 @@ -# Task 162: Effects 1423-1427 - -## 目标 - -- 补齐以下 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 1423 -- `argsNum`: `3` -- `info`: `消除对手回合类效果,消除成功则{0}%令对手{1},未触发则恢复自身最大体力的1/{2}` -- `param`: `1,1,1` - -### Effect 1424 -- `argsNum`: `2` -- `info`: `{0}%令对手{1},自身处于能力提升状态时概率翻倍` -- `param`: `1,1,1` - -### Effect 1425 -- `argsNum`: `7` -- `info`: `造成的伤害低于{0}则自身{1}` -- `param`: `0,1,1` - -### Effect 1426 -- `argsNum`: `2` -- `info`: `若对手不处于异常状态则{0}%令对手{1}` -- `param`: `1,1,1` - -### Effect 1427 -- `argsNum`: `3` -- `info`: `{0}回合内每回合{1}%闪避对手攻击,未触发则受到的伤害减少{2}%` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-164-effects-1433-1437.md b/docs/effect-unimplemented-tasks/task-164-effects-1433-1437.md deleted file mode 100644 index 7a4f1d619..000000000 --- a/docs/effect-unimplemented-tasks/task-164-effects-1433-1437.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 164: Effects 1433-1437 - -## 目标 - -- 补齐以下 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 1433 -- `argsNum`: `0` -- `info`: `损失“辛”所有体力,同时使对手受到损失体力值1/2的固定伤害` - -### Effect 1434 -- `argsNum`: `0` -- `info`: `“辛”死亡后令自身下1次受到的攻击伤害减少50%` - -### Effect 1435 -- `argsNum`: `0` -- `info`: `“辛”存活时反转自身能力下降状态,反转成功则2回合内令对手使用的属性技能无效` - -### Effect 1436 -- `argsNum`: `2` -- `info`: `当回合击败对手则{0}%恢复自身全部体力,未触发则全属性+{1}` - -### Effect 1437 -- `argsNum`: `0` -- `info`: `“辛”存活时造成攻击伤害的50%恢复自身体力,“辛”死亡后造成的攻击伤害额外提升50%` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-181-effects-1518-1522.md b/docs/effect-unimplemented-tasks/task-181-effects-1518-1522.md deleted file mode 100644 index 41ff8cceb..000000000 --- a/docs/effect-unimplemented-tasks/task-181-effects-1518-1522.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 181: Effects 1518-1522 - -## 目标 - -- 补齐以下 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 1518 -- `argsNum`: `1` -- `info`: `消耗自身所有体力,削减对手本场战斗中{0}点体力上限` - -### Effect 1519 -- `argsNum`: `4` -- `info`: `{0}%令对手随机{1}项技能PP值归零,若对手处于能力下降状态则{2}%使对手随机{3}项技能PP值归零` - -### Effect 1520 -- `argsNum`: `2` -- `info`: `若对手为雄性精灵则附加自身最大体力1/{0}的百分比伤害且下回合攻击技能先制+{1}` - -### Effect 1521 -- `argsNum`: `2` -- `info`: `若对手雌性精灵则恢复自身最大体力的1/{0}且下回合属性技能先制+{1}` - -### Effect 1522 -- `argsNum`: `2` -- `info`: `附加{0}点固定伤害,若当回合造成的伤害高于{1}则固伤效果翻倍` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-182-effects-1523-1527.md b/docs/effect-unimplemented-tasks/task-182-effects-1523-1527.md deleted file mode 100644 index 28a7e6ad0..000000000 --- a/docs/effect-unimplemented-tasks/task-182-effects-1523-1527.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 182: Effects 1523-1527 - -## 目标 - -- 补齐以下 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 1523 -- `argsNum`: `1` -- `info`: `消除对手回合类效果,消除成功则吸取对手{0}点体力` - -### Effect 1524 -- `argsNum`: `0` -- `info`: `将自身能力下降状态反馈给对手,反馈成功则恢复自身所有体力,反馈失败则解除自身能力下降状态` - -### Effect 1525 -- `argsNum`: `2` -- `info`: `{0}%的概率造成的攻击伤害提升{1}%,若出手时自身为满体力则概率翻倍` - -### Effect 1526 -- `argsNum`: `2` -- `info`: `随机附加{0}-{1}点固定伤害,技能无效时减少对手所有技能PP1点` - -### Effect 1527 -- `argsNum`: `0` -- `info`: `后出手则必定打出致命一击` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-183-effects-1528-1532.md b/docs/effect-unimplemented-tasks/task-183-effects-1528-1532.md deleted file mode 100644 index eef6f2120..000000000 --- a/docs/effect-unimplemented-tasks/task-183-effects-1528-1532.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 183: Effects 1528-1532 - -## 目标 - -- 补齐以下 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 1528 -- `argsNum`: `1` -- `info`: `附加{0}点真实伤害` - -### Effect 1529 -- `argsNum`: `1` -- `info`: `消除对手能力提升状态,消除成功则附加{0}点真实伤害` - -### Effect 1530 -- `argsNum`: `1` -- `info`: `遇到天敌时附加{0}点真实伤害` - -### Effect 1531 -- `argsNum`: `2` -- `info`: `{0}回合内每回合使用技能附加{1}点固定伤害,若对手未受到固定伤害则额外附加等量的真实伤害` - -### Effect 1532 -- `argsNum`: `0` -- `info`: `对手不存在神印则攻击必定打出致命一击,对手每存在1层神印则100%使对手随机1项技能PP值归零` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-184-effects-1533-1537.md b/docs/effect-unimplemented-tasks/task-184-effects-1533-1537.md deleted file mode 100644 index 3f8c6736f..000000000 --- a/docs/effect-unimplemented-tasks/task-184-effects-1533-1537.md +++ /dev/null @@ -1,35 +0,0 @@ -# Task 184: Effects 1533-1537 - -## 目标 - -- 补齐以下 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 1533 -- `argsNum`: `1` -- `info`: `造成的攻击伤害低于{0}时附加大量真实伤害` - -### Effect 1534 -- `argsNum`: `0` -- `info`: `100%令对手随机1个被放逐的精灵所有技能PP值-1,若对手不存在被放逐的精灵则令对手当前精灵所有技能PP值-1` - -### Effect 1535 -- `argsNum`: `0` -- `info`: `对手存在神印则当回合自身先制+1` - -### Effect 1536 -- `argsNum`: `1` -- `info`: `全属性+{0},对手存在神印时强化效果翻倍` - -### Effect 1537 -- `argsNum`: `1` -- `info`: `消耗自身所有护罩并造成等量固定伤害,若当前护罩值低于{0}则造成的固定伤害翻倍` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/docs/effect-unimplemented-tasks/task-185-effects-1538-1542.md b/docs/effect-unimplemented-tasks/task-185-effects-1538-1542.md deleted file mode 100644 index d93b56cef..000000000 --- a/docs/effect-unimplemented-tasks/task-185-effects-1538-1542.md +++ /dev/null @@ -1,37 +0,0 @@ -# Task 185: Effects 1538-1542 - -## 目标 - -- 补齐以下 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 1538 -- `argsNum`: `0` -- `info`: `将对手攻击和特攻中最高的能力值作为自己的能力值进行攻击` - -### Effect 1539 -- `argsNum`: `3` -- `info`: `造成的伤害高于{0}则{1}%令对手{2},未触发则消除对手回合类效果` -- `param`: `1,2,2` - -### Effect 1540 -- `argsNum`: `2` -- `info`: `自身体力高于最大体力的1/{0}时吸取对手{1}点体力` - -### Effect 1541 -- `argsNum`: `1` -- `info`: `使自身下{0}回合获得孤雷风暴效果` - -### Effect 1542 -- `argsNum`: `2` -- `info`: `吸取对手能力提升状态,吸取成功则令对手{0},若对手不处于能力提升状态则令对手全属性-{1}` -- `param`: `1,0,0` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/effect/1391.go b/logic/service/fight/effect/1391.go index 75d761910..e59e17e31 100644 --- a/logic/service/fight/effect/1391.go +++ b/logic/service/fight/effect/1391.go @@ -8,7 +8,6 @@ import ( // Effect 1391: {0}回合内若对手使用属性技能则造成伤害前令对手{1},未触发则消除对手回合类效果 type Effect1391 struct { RoundEffectArg0Base - pending bool triggered bool } @@ -17,21 +16,8 @@ func (e *Effect1391) Skill_Use_ex() bool { return true } - e.pending = true - return true -} - -func (e *Effect1391) SkillHit() bool { - if !e.pending || e.triggered || len(e.Args()) < 2 { - return true - } - if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { - return true - } - if addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) { e.triggered = true - e.pending = false } return true } diff --git a/logic/service/fight/effect/1418_1422.go b/logic/service/fight/effect/1418_1422.go index a159e053b..9ec8e421d 100644 --- a/logic/service/fight/effect/1418_1422.go +++ b/logic/service/fight/effect/1418_1422.go @@ -65,7 +65,7 @@ func (e *Effect1419Sub) EFFect_Befer(in *input.Input, effEffect input.Effect) bo e.Alive(false) return true } - if in != e.Ctx().Our || !input.IS_Stat(effEffect) { + if in != e.Ctx().Opp || !input.IS_Stat(effEffect) { return true } @@ -137,14 +137,15 @@ type Effect1422Sub struct{ node.EffectNode } func (e *Effect1422Sub) SetArgs(t *input.Input, a ...int) { e.EffectNode.SetArgs(t, a...) + e.CanStack(false) e.Duration(-1) } func (e *Effect1422Sub) ShieldChange(before, after alpacadecimal.Decimal) bool { - if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 || len(e.Args()) < 2 { + if before.Cmp(alpacadecimal.Zero) <= 0 || after.Cmp(alpacadecimal.Zero) > 0 || len(e.Args()) == 0 { return true } - heal := e.Args()[1] + heal := e.Args()[0] if heal.Cmp(alpacadecimal.Zero) <= 0 { e.Alive(false) return true diff --git a/logic/service/fight/effect/1518_1522.go b/logic/service/fight/effect/1518_1522.go new file mode 100644 index 000000000..18396f512 --- /dev/null +++ b/logic/service/fight/effect/1518_1522.go @@ -0,0 +1,211 @@ +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 1518: 消耗自身所有体力,削减对手本场战斗中{0}点体力上限 +type Effect1518 struct{ node.EffectNode } + +func (e *Effect1518) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil { + return true + } + + if e.Ctx().Our.CurrentPet.GetHP().Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: e.Ctx().Our.CurrentPet.GetHP(), + }) + } + + loss := e.Args()[0] + if loss.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + reduceCurrentPetMaxHPFlat(e.Ctx().Opp, loss) + sub := e.Ctx().Opp.InitEffect(input.EffectType.Sub, 1518, int(loss.IntPart())) + if sub != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1518Sub struct{ node.EffectNode } + +func (e *Effect1518Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(-1) + e.CanStack(false) +} + +func (e *Effect1518Sub) SwitchIn(in *input.Input) bool { + if in != e.Ctx().Opp || len(e.Args()) == 0 { + return true + } + reduceCurrentPetMaxHPFlat(in, e.Args()[0]) + return true +} + +// Effect 1519: {0}%令对手随机{1}项技能PP值归零,若对手处于能力下降状态则{2}%使对手随机{3}项技能PP值归零 +type Effect1519 struct{ node.EffectNode } + +func (e *Effect1519) Skill_Use() bool { + if len(e.Args()) < 4 || e.Ctx().Opp == nil { + return true + } + + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok { + zeroRandomSkillPP(e.Ctx().Opp, int(e.Args()[1].IntPart())) + return true + } + + if !e.Ctx().Opp.HasPropSub() { + return true + } + + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[2].IntPart()), 100); ok { + zeroRandomSkillPP(e.Ctx().Opp, int(e.Args()[3].IntPart())) + } + return true +} + +// Effect 1520: 若对手为雄性精灵则附加自身最大体力1/{0}的百分比伤害且下回合攻击技能先制+{1} +type Effect1520 struct{ node.EffectNode } + +func (e *Effect1520) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { + return true + } + if e.Ctx().Opp.CurrentPet.Info.Gender != 1 { + return true + } + + denom := e.Args()[0] + if denom.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + damage := e.Ctx().Our.CurrentPet.GetMaxHP().Div(denom) + if damage.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Percent, + Damage: damage, + }) + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1520, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1520Sub struct{ node.EffectNode } + +func (e *Effect1520Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(1) + e.CanStack(false) +} + +func (e *Effect1520Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if len(e.Args()) == 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil || current.SkillEntity.Category() == info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority += int(e.Args()[0].IntPart()) + return true +} + +// Effect 1521: 若对手雌性精灵则恢复自身最大体力的1/{0}且下回合属性技能先制+{1} +type Effect1521 struct{ node.EffectNode } + +func (e *Effect1521) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().Our == nil || e.Ctx().Our.CurrentPet == nil { + return true + } + if e.Ctx().Opp.CurrentPet.Info.Gender != 2 { + return true + } + + denom := e.Args()[0] + if denom.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + heal := e.Ctx().Our.CurrentPet.GetMaxHP().Div(denom) + if heal.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1521, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1521Sub struct{ node.EffectNode } + +func (e *Effect1521Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + e.Duration(1) + e.CanStack(false) +} + +func (e *Effect1521Sub) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if len(e.Args()) == 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil || current.SkillEntity.Category() != info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority += int(e.Args()[0].IntPart()) + return true +} + +// Effect 1522: 附加{0}点固定伤害,若当回合造成的伤害高于{1}则固伤效果翻倍 +type Effect1522 struct{ node.EffectNode } + +func (e *Effect1522) OnSkill() bool { + if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + + damage := e.Args()[0] + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + if e.Ctx().Our.SumDamage.Cmp(e.Args()[1]) > 0 { + damage = damage.Mul(alpacadecimal.NewFromInt(2)) + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: damage, + }) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1518, &Effect1518{}) + input.InitEffect(input.EffectType.Sub, 1518, &Effect1518Sub{}) + input.InitEffect(input.EffectType.Skill, 1519, &Effect1519{}) + input.InitEffect(input.EffectType.Skill, 1520, &Effect1520{}) + input.InitEffect(input.EffectType.Sub, 1520, &Effect1520Sub{}) + input.InitEffect(input.EffectType.Skill, 1521, &Effect1521{}) + input.InitEffect(input.EffectType.Sub, 1521, &Effect1521Sub{}) + input.InitEffect(input.EffectType.Skill, 1522, &Effect1522{}) +} diff --git a/logic/service/fight/effect/1523_1527.go b/logic/service/fight/effect/1523_1527.go new file mode 100644 index 000000000..5d2cf53b2 --- /dev/null +++ b/logic/service/fight/effect/1523_1527.go @@ -0,0 +1,202 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" + "github.com/gogf/gf/v2/util/grand" +) + +// Effect 1523: 清除对手回合类效果后吸取固定体力 +type Effect1523 struct{ node.EffectNode } + +func (e *Effect1523) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil { + return true + } + before := activeTurnEffectCount(e.Ctx().Opp) + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + if before <= 0 { + return true + } + + drain := e.Args()[0] + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: drain, + }) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain) + return true +} + +// Effect 1524: 反馈自身能力下降并恢复体力,否则清除自身能力下降 +type Effect1524 struct{ node.EffectNode } + +func transferSelfStatDowns(owner, target *input.Input) bool { + if owner == nil || target == nil { + return false + } + transferred := false + for idx, level := range owner.Prop[:] { + if level >= 0 { + continue + } + if target.SetProp(owner, int8(idx), level) { + transferred = true + } + } + return transferred +} + +func clearOwnStatDowns(owner *input.Input) { + if owner == nil { + return + } + for idx, level := range owner.Prop[:] { + if level >= 0 { + continue + } + owner.SetProp(owner, int8(idx), 0) + } +} + +func (e *Effect1524) Skill_Use() bool { + if e.Ctx().Our == nil { + return true + } + + if transferSelfStatDowns(e.Ctx().Our, e.Ctx().Opp) { + if e.Ctx().Our.CurrentPet != nil { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, e.Ctx().Our.CurrentPet.GetMaxHP()) + } + return true + } + + clearOwnStatDowns(e.Ctx().Our) + return true +} + +// Effect 1525: 概率提升伤害,满血时概率翻倍 +type Effect1525 struct { + node.EffectNode + boosted bool +} + +func (e *Effect1525) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || len(e.Args()) < 2 { + return true + } + + chance := int(e.Args()[0].IntPart()) + if e.Ctx().Our.CurrentPet != nil && e.Ctx().Our.CurrentPet.GetHP().Cmp(e.Ctx().Our.CurrentPet.GetMaxHP()) >= 0 { + chance *= 2 + if chance > 100 { + chance = 100 + } + } + + if chance <= 0 { + return true + } + + ok, _, _ := e.Input.Player.Roll(chance, 100) + if ok { + e.boosted = true + } + return true +} + +func (e *Effect1525) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || !e.boosted || len(e.Args()) < 2 { + return true + } + + percent := e.Args()[1] + if percent.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + zone.Damage = zone.Damage.Mul(hundred.Add(percent)).Div(hundred) + e.boosted = false + return true +} + +// Effect 1526: 附加固定伤害,技能无效时降低对手所有 PP +type Effect1526 struct{ node.EffectNode } + +func (e *Effect1526) OnSkill() bool { + if len(e.Args()) < 2 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + + min := int64(e.Args()[0].IntPart()) + max := int64(e.Args()[1].IntPart()) + if max < min { + min, max = max, min + } + if max < min { + return true + } + + rangeSize := int(max - min + 1) + if rangeSize <= 0 { + return true + } + + damage := alpacadecimal.NewFromInt(min + int64(grand.Intn(rangeSize))) + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: damage, + }) + return true +} + +func (e *Effect1526) Skill_Use_ex() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.AttackTime != 0 { + return true + } + if e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + + for idx := range e.Ctx().Opp.CurrentPet.Info.SkillList { + skill := &e.Ctx().Opp.CurrentPet.Info.SkillList[idx] + if skill.PP > 0 { + skill.PP-- + } + } + return true +} + +// Effect 1527: 后出手必定致命一击 +type Effect1527 struct{ node.EffectNode } + +func (e *Effect1527) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + if e.Ctx().Our == nil || e.Ctx().Our.FightC == nil { + return true + } + if e.Ctx().Our.FightC.IsFirst(e.Ctx().Our.Player) { + return true + } + + e.Ctx().SkillEntity.XML.CritRate = 16 + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1523, &Effect1523{}) + input.InitEffect(input.EffectType.Skill, 1524, &Effect1524{}) + input.InitEffect(input.EffectType.Skill, 1525, &Effect1525{}) + input.InitEffect(input.EffectType.Skill, 1526, &Effect1526{}) + input.InitEffect(input.EffectType.Skill, 1527, &Effect1527{}) +} diff --git a/logic/service/fight/effect/1528_1532.go b/logic/service/fight/effect/1528_1532.go new file mode 100644 index 000000000..e2e1c9f69 --- /dev/null +++ b/logic/service/fight/effect/1528_1532.go @@ -0,0 +1,131 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +func dealFixedDamage(target *input.Input, owner *input.Input, value alpacadecimal.Decimal) alpacadecimal.Decimal { + if owner == nil || target == nil || value.Cmp(alpacadecimal.Zero) <= 0 { + return alpacadecimal.Zero + } + + before := target.CurrentPet.GetHP() + target.Damage(owner, &info.DamageZone{Type: info.DamageType.Fixed, Damage: value}) + after := target.CurrentPet.GetHP() + return before.Sub(after) +} + +func dealTrueDamage(owner, target *input.Input, value alpacadecimal.Decimal) { + if owner == nil || target == nil || value.Cmp(alpacadecimal.Zero) <= 0 { + return + } + target.Damage(owner, &info.DamageZone{Type: info.DamageType.True, Damage: value}) +} + +// Effect 1528: 附加{0}点真实伤害 +type Effect1528 struct{ node.EffectNode } + +func (e *Effect1528) OnSkill() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil { + return true + } + dealTrueDamage(e.Ctx().Our, e.Ctx().Opp, e.Args()[0]) + return true +} + +// Effect 1529: 消除对手能力提升状态,消除成功则附加{0}点真实伤害 +type Effect1529 struct{ node.EffectNode } + +func (e *Effect1529) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil { + return true + } + if !clearPositiveProps(e.Ctx().Opp, e.Ctx().Our) { + return true + } + dealTrueDamage(e.Ctx().Our, e.Ctx().Opp, e.Args()[0]) + return true +} + +// Effect 1530: 遇到天敌时附加{0}点真实伤害 +type Effect1530 struct{ node.EffectNode } + +func (e *Effect1530) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().Opp == nil || e.Ctx().SkillEntity == nil { + return true + } + if !e.ISNaturalEnemy() { + return true + } + dealTrueDamage(e.Ctx().Our, e.Ctx().Opp, e.Args()[0]) + return true +} + +// Effect 1531: {0}回合内每回合使用技能附加{1}点固定伤害,若对手未受到固定伤害则额外附加等量的真实伤害 +type Effect1531 struct{ node.EffectNode } + +func (e *Effect1531) Skill_Use() bool { + if len(e.Args()) < 2 { + return true + } + duration := int(e.Args()[0].IntPart()) + if duration <= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1531, duration, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1531Sub struct{ RoundEffectArg0Base } + +func (e *Effect1531Sub) OnSkill() bool { + if len(e.Args()) < 2 { + return true + } + fixed := e.Args()[1] + if fixed.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if e.Ctx().Opp == nil { + return true + } + received := dealFixedDamage(e.Ctx().Opp, e.Ctx().Our, fixed) + if received.Cmp(alpacadecimal.Zero) == 0 { + dealTrueDamage(e.Ctx().Our, e.Ctx().Opp, fixed) + } + return true +} + +// Effect 1532: 对手不存在神印则攻击必定打出致命一击,对手每存在1层神印则100%使对手随机1项技能PP值归零 +type Effect1532 struct{ node.EffectNode } + +func (e *Effect1532) SkillHit() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + energy := e.Ctx().Opp.CurrentDivineEnergy() + if energy <= 0 { + e.Ctx().SkillEntity.XML.CritRate = 16 + return true + } + for i := 0; i < energy; i++ { + zeroRandomSkillPP(e.Ctx().Opp, 1) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1528, &Effect1528{}) + input.InitEffect(input.EffectType.Skill, 1529, &Effect1529{}) + input.InitEffect(input.EffectType.Skill, 1530, &Effect1530{}) + input.InitEffect(input.EffectType.Skill, 1531, &Effect1531{}) + input.InitEffect(input.EffectType.Sub, 1531, &Effect1531Sub{}) + input.InitEffect(input.EffectType.Skill, 1532, &Effect1532{}) +} diff --git a/logic/service/fight/effect/1533_1537.go b/logic/service/fight/effect/1533_1537.go new file mode 100644 index 000000000..ce1713412 --- /dev/null +++ b/logic/service/fight/effect/1533_1537.go @@ -0,0 +1,161 @@ +package effect + +import ( + "blazing/logic/service/fight/action" + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +func transferPositiveProps(owner, source, target *input.Input) bool { + if owner == nil || source == nil || target == nil { + return false + } + + transferred := false + for idx, level := range source.Prop[:] { + if level <= 0 { + continue + } + if source.SetProp(owner, int8(idx), 0) { + target.SetProp(owner, int8(idx), level) + transferred = true + } + } + return transferred +} + +func reducePetSkillPP(pet *info.BattlePetEntity, value int) bool { + if pet == nil || value <= 0 { + return false + } + + changed := false + for idx := range pet.Info.SkillList { + if pet.Info.SkillList[idx].PP <= 0 { + continue + } + if pet.Info.SkillList[idx].PP <= uint32(value) { + pet.Info.SkillList[idx].PP = 0 + } else { + pet.Info.SkillList[idx].PP -= uint32(value) + } + changed = true + } + return changed +} + +func divineMarkLayers(target *input.Input) int { + if target == nil { + return 0 + } + return target.CurrentDivineEnergy() +} + +func pickBanishedPet(target *input.Input) *info.BattlePetEntity { + if target == nil { + return nil + } + // The current codebase has no explicit "banished" pet state yet. + // Keep the fallback path intact until a dedicated representation exists. + return nil +} + +// Effect 1533: 造成的攻击伤害低于{0}时附加大量真实伤害 +type Effect1533 struct{ node.EffectNode } + +func (e *Effect1533) Skill_Use() bool { + if len(e.Args()) == 0 || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + if e.Ctx().Our.SumDamage.Cmp(e.Args()[0]) >= 0 { + return true + } + dealTrueDamage(e.Ctx().Our, e.Ctx().Opp, e.Args()[0]) + return true +} + +// Effect 1534: 100%令对手随机1个被放逐的精灵所有技能PP值-1,若对手不存在被放逐的精灵则令对手当前精灵所有技能PP值-1 +type Effect1534 struct{ node.EffectNode } + +func (e *Effect1534) Skill_Use() bool { + if e.Ctx().Opp == nil { + return true + } + + if pet := pickBanishedPet(e.Ctx().Opp); pet != nil && reducePetSkillPP(pet, 1) { + return true + } + + reducePetSkillPP(e.Ctx().Opp.CurrentPet, 1) + return true +} + +// Effect 1535: 对手存在神印则当回合自身先制+1 +type Effect1535 struct{ node.EffectNode } + +func (e *Effect1535) ComparePre(fattack, sattack *action.SelectSkillAction) bool { + if divineMarkLayers(e.Ctx().Opp) <= 0 { + return true + } + current := actionByPlayer(fattack, sattack, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil { + return true + } + current.SkillEntity.XML.Priority++ + return true +} + +// Effect 1536: 全属性+{0},对手存在神印时强化效果翻倍 +type Effect1536 struct{ node.EffectNode } + +func (e *Effect1536) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + + boost := int8(e.Args()[0].IntPart()) + if divineMarkLayers(e.Ctx().Opp) > 0 { + boost *= 2 + } + applyAllPropUp(e.Ctx().Our, boost) + return true +} + +// Effect 1537: 消耗自身所有护罩并造成等量固定伤害,若当前护罩值低于{0}则造成的固定伤害翻倍 +type Effect1537 struct{ node.EffectNode } + +func (e *Effect1537) Skill_Use() bool { + if e.Ctx().Our == nil || e.Ctx().Opp == nil { + return true + } + + shield := e.Ctx().Our.CurrentShield() + if shield.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + damage := e.Ctx().Our.ConsumeAllShield() + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if len(e.Args()) > 0 && shield.Cmp(e.Args()[0]) < 0 { + damage = damage.Mul(alpacadecimal.NewFromInt(2)) + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: damage, + }) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1533, &Effect1533{}) + input.InitEffect(input.EffectType.Skill, 1534, &Effect1534{}) + input.InitEffect(input.EffectType.Skill, 1535, &Effect1535{}) + input.InitEffect(input.EffectType.Skill, 1536, &Effect1536{}) + input.InitEffect(input.EffectType.Skill, 1537, &Effect1537{}) +} diff --git a/logic/service/fight/effect/1538_1542.go b/logic/service/fight/effect/1538_1542.go new file mode 100644 index 000000000..ba5961202 --- /dev/null +++ b/logic/service/fight/effect/1538_1542.go @@ -0,0 +1,165 @@ +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" +) + +type Effect1538 struct{ node.EffectNode } + +func (e *Effect1538) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || e.Ctx().Opp == nil || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + + ourValue := e.Ctx().Our.GetProp(0) + if e.Ctx().SkillEntity.Category() == info.Category.SPECIAL { + ourValue = e.Ctx().Our.GetProp(2) + } + if ourValue.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + bestValue := e.Ctx().Opp.GetProp(0) + if e.Ctx().Opp.GetProp(2).Cmp(bestValue) > 0 { + bestValue = e.Ctx().Opp.GetProp(2) + } + if bestValue.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + zone.Damage = zone.Damage.Mul(bestValue).Div(ourValue) + return true +} + +type Effect1539 struct{ node.EffectNode } + +func (e *Effect1539) OnSkill() bool { + if len(e.Args()) < 3 || e.Ctx().Opp == nil { + return true + } + threshold := e.Args()[0] + if e.Ctx().Our.SumDamage.Cmp(threshold) <= 0 { + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + return true + } + + ok, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100) + if ok { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[2].IntPart())) + return true + } + e.Ctx().Opp.CancelTurn(e.Ctx().Our) + return true +} + +type Effect1540 struct{ node.EffectNode } + +func (e *Effect1540) Skill_Use() bool { + if len(e.Args()) < 2 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + if e.Ctx().Our.CurrentPet == nil || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + + threshold := e.Ctx().Our.CurrentPet.GetMaxHP().Div(e.Args()[0]) + if e.Ctx().Our.CurrentPet.GetHP().Cmp(threshold) <= 0 { + return true + } + + drain := e.Args()[1] + if drain.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: drain, + }) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, drain) + return true +} + +type Effect1541 struct{ node.EffectNode } + +func (e *Effect1541) Skill_Use() bool { + if len(e.Args()) == 0 { + return true + } + + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1541, int(e.Args()[0].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1541Sub struct{ RoundEffectArg0Base } + +func (e *Effect1541Sub) ComparePre(first, second *action.SelectSkillAction) bool { + current := actionByPlayer(first, second, e.Ctx().Our.UserID) + if current == nil || current.SkillEntity == nil || current.SkillEntity.Category() == info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority++ + return true +} + +func (e *Effect1541Sub) ActionStart(first, second *action.SelectSkillAction) bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.XML.MustHit = 1 + return true +} + +func (e *Effect1541Sub) OnSkill() bool { + if e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() != info.Category.STATUS { + return true + } + extra := alpacadecimal.NewFromInt(int64(e.Ctx().Opp.AttackValue.LostHp)).Div(alpacadecimal.NewFromInt(2)) + if extra.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: extra, + }) + return true +} + +type Effect1542 struct{ node.EffectNode } + +func (e *Effect1542) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil { + return true + } + + if transferPositiveProps(e.Ctx().Our, e.Ctx().Opp, e.Ctx().Our) { + addStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[0].IntPart())) + return true + } + + level := int8(e.Args()[1].IntPart()) + if level == 0 { + return true + } + for idx := range e.Ctx().Opp.Prop { + e.Ctx().Opp.SetProp(e.Ctx().Our, int8(idx), -level) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1538, &Effect1538{}) + input.InitEffect(input.EffectType.Skill, 1539, &Effect1539{}) + input.InitEffect(input.EffectType.Skill, 1540, &Effect1540{}) + input.InitEffect(input.EffectType.Skill, 1541, &Effect1541{}) + input.InitEffect(input.EffectType.Sub, 1541, &Effect1541Sub{}) + input.InitEffect(input.EffectType.Skill, 1542, &Effect1542{}) +} diff --git a/logic/service/fight/effect/1578_1582.go b/logic/service/fight/effect/1578_1582.go new file mode 100644 index 000000000..3be08ed07 --- /dev/null +++ b/logic/service/fight/effect/1578_1582.go @@ -0,0 +1,205 @@ +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" +) + +var hundred = alpacadecimal.NewFromInt(100) + +func applyStatusByID(owner, target *input.Input, statusID int) bool { + if owner == nil || target == nil || statusID <= 0 { + return false + } + eff := owner.InitEffect(input.EffectType.Status, statusID) + if eff == nil { + return false + } + target.AddEffect(owner, eff) + return true +} + +// Effect 1578: 出手时自身护盾值高于{0}则自身下回合攻击技能先制+{1} +type Effect1578 struct{ node.EffectNode } + +func (e *Effect1578) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Our == nil { + return true + } + shield := e.Ctx().Our.CurrentShield() + if shield.Cmp(e.Args()[0]) <= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1578, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1578Sub struct { + RoundEffectArg0Base + remaining int + priority int +} + +func (e *Effect1578Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + if len(a) > 0 { + e.remaining = 1 + } + if len(a) > 1 { + e.priority = a[0] + } +} + +func (e *Effect1578Sub) 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 || current.SkillEntity.Category() == info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority += e.priority + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +// Effect 1579: 出手时自身护盾值低于{0}则下回合属性技能先制+{1} +type Effect1579 struct{ node.EffectNode } + +func (e *Effect1579) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Our == nil { + return true + } + if e.Ctx().Our.CurrentShield().Cmp(e.Args()[0]) >= 0 { + return true + } + sub := e.Ctx().Our.InitEffect(input.EffectType.Sub, 1579, int(e.Args()[1].IntPart())) + if sub != nil { + e.Ctx().Our.AddEffect(e.Ctx().Our, sub) + } + return true +} + +type Effect1579Sub struct { + RoundEffectArg0Base + remaining int + priority int +} + +func (e *Effect1579Sub) SetArgs(t *input.Input, a ...int) { + e.EffectNode.SetArgs(t, a...) + if len(a) > 0 { + e.remaining = 1 + } + if len(a) > 1 { + e.priority = a[0] + } +} + +func (e *Effect1579Sub) 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 || current.SkillEntity.Category() != info.Category.STATUS { + return true + } + current.SkillEntity.XML.Priority += e.priority + e.remaining-- + if e.remaining <= 0 { + e.Alive(false) + } + return true +} + +// Effect 1580: 出手时对手体力高于最大体力的1/{0}则造成伤害的{1}%恢复自身体力 +type Effect1580 struct { + node.EffectNode + shouldHeal bool +} + +func (e *Effect1580) Skill_Use() bool { + if len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil { + return true + } + maxThreshold := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[0]) + if e.Ctx().Opp.CurrentPet.GetHP().Cmp(maxThreshold) <= 0 { + return true + } + e.shouldHeal = true + return true +} + +func (e *Effect1580) DamageAdd(zone *info.DamageZone) bool { + if !e.shouldHeal || zone == nil || zone.Type != info.DamageType.Red || e.Ctx().Our == nil { + return true + } + if len(e.Args()) < 2 { + return true + } + heal := zone.Damage.Mul(e.Args()[1]).Div(hundred) + if heal.Cmp(alpacadecimal.Zero) > 0 { + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, heal) + } + e.shouldHeal = false + return true +} + +// Effect 1581: 出手时对手体力低于最大体力的1/{0}则造成的伤害提升{1}% +type Effect1581 struct{ node.EffectNode } + +func (e *Effect1581) Damage_Mul(zone *info.DamageZone) bool { + if zone == nil || zone.Type != info.DamageType.Red || len(e.Args()) < 2 || e.Ctx().Opp == nil || e.Ctx().Opp.CurrentPet == nil || e.Ctx().SkillEntity == nil || e.Ctx().SkillEntity.Category() == info.Category.STATUS || e.Ctx().SkillEntity.AttackTime == 0 { + return true + } + threshold := e.Ctx().Opp.CurrentPet.GetMaxHP().Div(e.Args()[0]) + if e.Ctx().Opp.CurrentPet.GetHP().Cmp(threshold) >= 0 { + return true + } + zone.Damage = zone.Damage.Mul(hundred.Add(e.Args()[1])).Div(hundred) + return true +} + +// Effect 1582: {0}%令对手{1},{2}%令自身{3},均未触发则为自身附加{4}点护盾 +type Effect1582 struct{ node.EffectNode } + +func (e *Effect1582) Skill_Use() bool { + if len(e.Args()) < 5 || e.Ctx().Our == nil { + return true + } + opponentTriggered := false + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100); ok { + opponentTriggered = applyStatusByID(e.Ctx().Our, e.Ctx().Opp, int(e.Args()[1].IntPart())) + } + selfTriggered := false + if ok, _, _ := e.Input.Player.Roll(int(e.Args()[2].IntPart()), 100); ok { + selfTriggered = applyStatusByID(e.Ctx().Our, e.Ctx().Our, int(e.Args()[3].IntPart())) + } + if opponentTriggered || selfTriggered { + return true + } + e.Ctx().Our.AddShield(e.Args()[4]) + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 1578, &Effect1578{}) + input.InitEffect(input.EffectType.Sub, 1578, &Effect1578Sub{}) + input.InitEffect(input.EffectType.Skill, 1579, &Effect1579{}) + input.InitEffect(input.EffectType.Sub, 1579, &Effect1579Sub{}) + input.InitEffect(input.EffectType.Skill, 1580, &Effect1580{}) + input.InitEffect(input.EffectType.Skill, 1581, &Effect1581{}) + input.InitEffect(input.EffectType.Skill, 1582, &Effect1582{}) +} diff --git a/logic/service/fight/effect/effect_info_map.go b/logic/service/fight/effect/effect_info_map.go index 5c036cb11..c66bb5317 100644 --- a/logic/service/fight/effect/effect_info_map.go +++ b/logic/service/fight/effect/effect_info_map.go @@ -972,6 +972,31 @@ var effectInfoByID = map[int]string{ 1510: "{0}回合内对手主动切换精灵则登场精灵{1}%随机进入{2}种异常状态", 1511: "先出手时免疫当回合受到的攻击伤害,若对手为自身天敌则免疫并反弹给对手造成伤害值{0}%的百分比伤害", 1512: "集结天幕四龙之神力,使自身下2回合先制+3且攻击必定命中、必定致命", + 1518: "消耗自身所有体力,削减对手本场战斗中{0}点体力上限", + 1519: "{0}%令对手随机{1}项技能PP值归零,若对手处于能力下降状态则{2}%使对手随机{3}项技能PP值归零", + 1520: "若对手为雄性精灵则附加自身最大体力1/{0}的百分比伤害且下回合攻击技能先制+{1}", + 1521: "若对手雌性精灵则恢复自身最大体力的1/{0}且下回合属性技能先制+{1}", + 1522: "附加{0}点固定伤害,若当回合造成的伤害高于{1}则固伤效果翻倍", + 1523: "消除对手回合类效果,消除成功则吸取对手{0}点体力", + 1524: "将自身能力下降状态反馈给对手,反馈成功则恢复自身所有体力,反馈失败则解除自身能力下降状态", + 1525: "{0}%的概率造成的攻击伤害提升{1}%,若出手时自身为满体力则概率翻倍", + 1526: "随机附加{0}-{1}点固定伤害,技能无效时减少对手所有技能PP1点", + 1527: "后出手则必定打出致命一击", + 1528: "附加{0}点真实伤害", + 1529: "消除对手能力提升状态,消除成功则附加{0}点真实伤害", + 1530: "遇到天敌时附加{0}点真实伤害", + 1531: "{0}回合内每回合使用技能附加{1}点固定伤害,若对手未受到固定伤害则额外附加等量的真实伤害", + 1532: "对手不存在神印则攻击必定打出致命一击,对手每存在1层神印则100%使对手随机1项技能PP值归零", + 1533: "造成的攻击伤害低于{0}时附加大量真实伤害", + 1534: "100%令对手随机1个被放逐的精灵所有技能PP值-1,若对手不存在被放逐的精灵则令对手当前精灵所有技能PP值-1", + 1535: "对手存在神印则当回合自身先制+1", + 1536: "全属性+{0},对手存在神印时强化效果翻倍", + 1537: "消耗自身所有护罩并造成等量固定伤害,若当前护罩值低于{0}则造成的固定伤害翻倍", + 1538: "将对手攻击和特攻中最高的能力值作为自己的能力值进行攻击", + 1539: "造成的伤害高于{0}则{1}%令对手{2},未触发则消除对手回合类效果", + 1540: "自身体力高于最大体力的1/{0}时吸取对手{1}点体力", + 1541: "使自身下{0}回合获得孤雷风暴效果", + 1542: "吸取对手能力提升状态,吸取成功则令对手{0},若对手不处于能力提升状态则令对手全属性-{1}", 1553: "自身体力高于最大体力的1/{0}时攻击后附加造成伤害值{1}%的百分比伤害", 1554: "若自身当前体力低于最大体力的1/{0}则令自身{1}且免疫下{2}次受到的攻击", 1555: "对手不处于能力提升时令对手所有技能PP值-{0}",