diff --git a/docs/effect-refactor-summary-2026-03-28.md b/docs/effect-refactor-summary-2026-03-28.md index 09147ebbc..d79c2d2fd 100644 --- a/docs/effect-refactor-summary-2026-03-28.md +++ b/docs/effect-refactor-summary-2026-03-28.md @@ -296,3 +296,28 @@ JSON 中存在但代码未注册(示例前 60 项): ### 9.5 本轮验证 - `cd /workspace/logic && go test ./service/fight/effect` - `cd /workspace/logic && go build ./...` + +--- + +## 10. 2026-03-29 增量记录(三) + +### 10.1 本轮补齐的 effect +- `642` `{0}回合内若对手攻击技能命中则己方在场精灵{1}%做出{2}` +- `643` `{0}%概率使对手{1}回合内{2}能力每回合变化{3}` +- `644` 当回合未击败对手,则减少对手当前体力`1/{0}` +- `645` 体力低于`1/{0}`时威力`{1}`倍 +- `646` 体力高于对手时,此技能命中后 100% 使对手能力下降 + +### 10.2 实现口径 +- `642` 按 `moves.json` 中 `1000642` 的说明实现反击档位映射:`0-5` 分别对应 `50/100/150/200/250/300` 点固定伤害;挂在 defender 侧 `Skill_Use_ex()`,仅对命中的攻击技能生效。 +- `643` 按真实技能实参 `55 2 1 -1` 这类布局处理为“命中后按概率给对手挂回合子效果”,子效果在 `TurnEnd()` 对指定能力执行一次 `SetProp`。 +- `644` 复用 `579` 的“未击败对手”判定时机,落在 `Action_end()`,按对手当前体力结算 `1/n` 的百分比伤害。 +- `645` 复用 `37` 的低血线威力倍率模式,在 `SkillHit()` 中按当前体力是否低于最大体力 `1/n` 改写技能威力。 +- `646` 未按任务文档里的占位 `param` 硬编码;改按实际技能配置的 6 段能力变化参数通用处理,仅在自身体力高于对手且本次技能命中后生效。 + +### 10.3 本轮新增文件 +- `logic/service/fight/effect/642_646.go` + +### 10.4 本轮同步更新 +- `logic/service/fight/effect/effect_info_map.go` +- `docs/effect-unimplemented-tasks/task-009-effects-642-646.md` 已完成,可从任务目录移除 diff --git a/docs/effect-unimplemented-tasks/task-009-effects-642-646.md b/docs/effect-unimplemented-tasks/task-009-effects-642-646.md deleted file mode 100644 index c20e94af3..000000000 --- a/docs/effect-unimplemented-tasks/task-009-effects-642-646.md +++ /dev/null @@ -1,38 +0,0 @@ -# Task 009: Effects 642-646 - -## 目标 - -- 补齐以下 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 642 -- `argsNum`: `3` -- `info`: `{0}回合内若对手攻击技能命中则己方在场精灵{1}%做出{2}` -- `param`: `13,2,2` - -### Effect 643 -- `argsNum`: `4` -- `info`: `{0}%概率使对手{1}回合内{2}能力每回合变化{3}` -- `param`: `2,2,2` - -### Effect 644 -- `argsNum`: `1` -- `info`: `当回合未击败对手,则减少对手当前体力1/{0}` - -### Effect 645 -- `argsNum`: `2` -- `info`: `体力低于1/{0}时威力{1}倍` - -### Effect 646 -- `argsNum`: `6` -- `info`: `体力高于对手时,此技能命中后100%使对手{0}` -- `param`: `0,0,0` - -## 备注 - -- 该清单按当前仓库静态注册结果生成;如果某个 effect 实际通过其他模块或运行时路径实现,需要先复核后再落代码。 -- 对 `201`、`445` 这类占位 effect,优先补核心逻辑或补充明确的不可实现说明。 diff --git a/logic/service/fight/effect/642_646.go b/logic/service/fight/effect/642_646.go new file mode 100644 index 000000000..e059503a2 --- /dev/null +++ b/logic/service/fight/effect/642_646.go @@ -0,0 +1,163 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" + + "github.com/alpacahq/alpacadecimal" +) + +func counterDamageByLevel(level int) alpacadecimal.Decimal { + if level < 0 || level > 5 { + return alpacadecimal.Zero + } + + return alpacadecimal.NewFromInt(int64((level + 1) * 50)) +} + +// Effect 642: {0}回合内若对手攻击技能命中则己方在场精灵{1}%做出{2} +type Effect642 struct { + RoundEffectArg0Base +} + +func (e *Effect642) Skill_Use_ex() bool { + skill := e.Ctx().SkillEntity + if skill == nil || skill.AttackTime == 0 || skill.Category() == info.Category.STATUS { + return true + } + + success, _, _ := e.Input.Player.Roll(int(e.Args()[1].IntPart()), 100) + if !success { + return true + } + + damage := counterDamageByLevel(int(e.Args()[2].IntPart())) + if damage.Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ + Type: info.DamageType.Fixed, + Damage: damage, + }) + return true +} + +// Effect 643: {0}%概率使对手{1}回合内{2}能力每回合变化{3} +type Effect643 struct { + node.EffectNode +} + +func (e *Effect643) Skill_Use() bool { + skill := e.Ctx().SkillEntity + if skill == nil || skill.AttackTime == 0 { + return true + } + + success, _, _ := e.Input.Player.Roll(int(e.Args()[0].IntPart()), 100) + if !success { + return true + } + + effect := e.Ctx().Our.InitEffect( + input.EffectType.Sub, + 643, + int(e.Args()[0].IntPart()), + int(e.Args()[1].IntPart()), + int(e.Args()[2].IntPart()), + int(e.Args()[3].IntPart()), + ) + if effect != nil { + e.Ctx().Opp.AddEffect(e.Ctx().Our, effect) + } + return true +} + +type Effect643Sub struct { + RoundEffectArg1Base +} + +func (e *Effect643Sub) TurnEnd() { + propID := int(e.Args()[2].IntPart()) + if propID >= 0 && propID < 6 { + e.Ctx().Our.SetProp(e.Ctx().Opp, int8(propID), int8(e.Args()[3].IntPart())) + } + + e.EffectNode.TurnEnd() +} + +// Effect 644: 当回合未击败对手,则减少对手当前体力1/{0} +type Effect644 struct { + node.EffectNode +} + +func (e *Effect644) Action_end() bool { + skill := e.Ctx().SkillEntity + if skill == nil || skill.AttackTime == 0 { + return true + } + if e.Ctx().Opp.CurrentPet.Info.Hp <= 0 || e.Args()[0].Cmp(alpacadecimal.Zero) <= 0 { + return true + } + + damage := e.Ctx().Opp.CurrentPet.GetHP().Div(e.Args()[0]) + 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 645: 体力低于1/{0}时威力{1}倍 +type Effect645 struct { + node.EffectNode +} + +func (e *Effect645) SkillHit() bool { + if e.Ctx().SkillEntity == nil { + return true + } + + threshold := e.GetInput().CurrentPet.GetMaxHP().Div(e.Args()[0]) + if e.GetInput().CurrentPet.GetHP().Cmp(threshold) < 0 { + e.Ctx().SkillEntity.XML.Power *= int(e.Args()[1].IntPart()) + } + return true +} + +// Effect 646: 体力高于对手时,此技能命中后100%使对手{0} +type Effect646 struct { + node.EffectNode +} + +func (e *Effect646) Skill_Use() bool { + skill := e.Ctx().SkillEntity + if skill == nil || skill.AttackTime == 0 { + return true + } + if e.Ctx().Our.CurrentPet.GetHP().Cmp(e.Ctx().Opp.CurrentPet.GetHP()) <= 0 { + return true + } + + for i, delta := range e.SideEffectArgs[:min(len(e.SideEffectArgs), 6)] { + if delta == 0 { + continue + } + e.Ctx().Opp.SetProp(e.Ctx().Our, int8(i), int8(delta)) + } + return true +} + +func init() { + input.InitEffect(input.EffectType.Skill, 642, &Effect642{}) + input.InitEffect(input.EffectType.Skill, 643, &Effect643{}) + input.InitEffect(input.EffectType.Sub, 643, &Effect643Sub{}) + input.InitEffect(input.EffectType.Skill, 644, &Effect644{}) + input.InitEffect(input.EffectType.Skill, 645, &Effect645{}) + input.InitEffect(input.EffectType.Skill, 646, &Effect646{}) +} diff --git a/logic/service/fight/effect/effect_info_map.go b/logic/service/fight/effect/effect_info_map.go index f0d946e92..e403d9f7a 100644 --- a/logic/service/fight/effect/effect_info_map.go +++ b/logic/service/fight/effect/effect_info_map.go @@ -381,6 +381,11 @@ var effectInfoByID = map[int]string{ 639: "造成伤害{0}{1},则下{2}回合所有技能附带{3}点固定伤害", 640: "命中后{0}%使对手{1}{2}回合,遇到天敌概率翻倍", 641: "命中后{0}%使对手进入流血状态", + 642: "{0}回合内若对手攻击技能命中则己方在场精灵{1}%做出{2}", + 643: "{0}%概率使对手{1}回合内{2}能力每回合变化{3}", + 644: "当回合未击败对手,则减少对手当前体力1/{0}", + 645: "体力低于1/{0}时威力{1}倍", + 646: "体力高于对手时,此技能命中后100%使对手{0}", 680: "先出手时{0}%使对手{1}{2}回合", 681: "下{0}回合自身攻击技能必定致命、必定命中", 682: "受到的伤害超过{0},自身{1}",