fix: 修正 effect 642-646 实现逻辑
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed

This commit is contained in:
xinian
2026-03-29 21:44:27 +08:00
committed by cnb
parent 0580cb0fef
commit a7171e9ef4
4 changed files with 193 additions and 38 deletions

View File

@@ -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` 已完成可从任务目录移除

View File

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

View File

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

View File

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