Files
bl/docs/fight-effect-impl-skill.md
xinian c40430aaa4
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
feat: 实现战斗技能效果
2026-03-29 16:38:34 +08:00

6.8 KiB

name, description
name description
fight-effect-impl Implement or repair Go fight effects in the Blazing battle system. Use when working in logic/service/fight/effect or nearby boss hooks, especially for missing effect tasks, effect registration, hook selection, delayed/round effects, status application, effect_info_map updates, and package-level validation.

Fight Effect Impl

Implement effect work in the existing battle framework instead of inventing a parallel pattern.

Workflow

  1. Read the task source first. If the request comes from docs/effect-unimplemented-tasks/, open the task file and extract effect IDs, arg counts, and description text.

  2. Confirm whether each effect is actually missing. Search for both type names and registrations. Do not rely only on direct InitEffect(...) grep results. Also inspect shared registration files such as:

  • logic/service/fight/effect/sterStatusEffects.go
  • logic/service/fight/effect/effect_power_doblue.go
  • logic/service/fight/effect/EffectAttackMiss.go
  • logic/service/fight/effect/EffectPhysicalAttackAddStatus.go
  • logic/service/fight/effect/EffectDefeatTrigger.go
  • logic/service/fight/effect/effect_attr.go
  1. Reuse the nearest local pattern. Open effects with similar timing or semantics before writing code. Prefer matching existing hooks, helper bases, registration style, and comments over building a generic abstraction.

  2. Choose the hook from battle flow, not from description text alone. Read logic/service/fight/input/interface.go, logic/service/fight/fightc.go, and logic/service/fight/loop.go when timing is unclear.

Effect Hooks

Use this section when effect timing is unclear.

Core call order

The main references are:

  • logic/service/fight/input/interface.go
  • logic/service/fight/fightc.go
  • logic/service/fight/loop.go

Typical attack flow inside processSkillAttack and enterturn is:

  1. defender SkillHit_ex()
  2. attacker SkillHit()
  3. attacker CalculatePre()
  4. attacker OnSkill()
  5. defender Damage(...) settles red/fixed/true damage
  6. defender Skill_Use_ex()
  7. attacker Skill_Use()
  8. defender Action_end_ex()
  9. attacker Action_end()
  10. both sides TurnEnd() at round end
  11. all live effects OnBattleEnd() at fight end

Hook selection cheatsheet

  • SkillHit_ex() Use for defender-side pre-hit interception, miss forcing, and hit-rate disruption.

  • SkillHit() Use for attacker-side power, crit, or skill-property changes before damage is computed.

  • CalculatePre() Use for temporary state rewrites that must exist during power calculation and then be restored.

  • OnSkill() Use for on-hit side effects, extra fixed damage setup, healing, status attach, or delayed-effect spawning.

  • ActionStartEx() Use for defender-side pre-action gates.

  • ActionStart() Use for attacker-side action gating, forced no-action behavior, and same-turn priority-sensitive logic.

  • Skill_Use_ex() Use for defender-side after-being-targeted behavior.

  • Skill_Use() Use for attacker-side after-using-skill behavior.

  • ComparePre() Use for priority changes before turn order is finalized.

  • TurnStart() Use for per-round setup or replacing the current round's selected action before execution.

  • TurnEnd() Use for countdown or expiry. The default node decrements positive durations and clears zero-duration effects.

  • OnBattleEnd() Use only when the effect truly settles at battle end. Confirm any reward path can be persisted from this hook.

Repo-specific cautions

  • EffectCache matters. Parsed skill effects are stored in EffectCache before execution. If a first-turn charge effect must suppress the rest of the skill's side effects, explicitly disable sibling cached effects for that turn.

  • addSubEffect(...) is lightweight. Read logic/service/fight/effect/sub_effect_helper.go before assuming helper behavior. The current helper forwards IDs and args, but does not automatically apply the duration argument to the sub-effect instance.

  • Team-wide healing is limited by current model. There is no generic battle-target abstraction for friendly bench targets. If the effect heals all owned pets, iterate AllPet and mutate non-active pets carefully.

  • Static task scans can be false positives. Task documents may flag effects as missing even when they already exist in grouped files or shared registration files. Verify before editing.

Implementation Rules

  • Prefer existing base structs in logic/service/fight/effect/sub_effect_helper.go when they already match duration behavior.
  • Verify helper semantics before using them. In this repo, some helpers are thinner than their names suggest.
  • For status effects, create them through InitEffect(input.EffectType.Status, ...) and add them through AddEffect(...) on the target input.
  • For healing, use Input.Heal(...) for the active battler and mutate non-active owned pets only when the current model already stores them in AllPet.
  • For battle-end rewards or delayed settlement, confirm the hook is actually executed in loop.go before coding against it.
  • Keep comments short and effect-focused.

Common Tasks

Random power or conditional power effects

Use SkillHit() when the effect changes SkillEntity.XML.Power before damage is calculated. Examples in repo: 139.go, effect_power_doblue.go, 600_605.go.

Hit-time status or side effects

Use OnSkill() when the effect should fire after hit/damage calculation setup and before final damage application is settled. For direct status application, initialize the status effect from the source input and add it to the opponent.

Round or delayed effects

For multi-turn logic, confirm whether the effect should:

  • modify this turn only,
  • start next turn,
  • trigger when attacked,
  • or replace the next selected skill.

For next-turn logic, inspect nearby effects such as 62, 407, 440, 499, 551, 560, and any adjacent ID patterns.

Two-turn charge effects

Preserve the repo's existing battle loop assumptions. A practical pattern is:

  • cache the release skill on the first turn,
  • suppress first-turn damage/effect output,
  • inject the cached skill into the next turn's selected action in TurnStart,
  • avoid double PP consumption in HookPP.

Reward-on-battle-end effects

Check OnBattleEnd() execution in logic/service/fight/loop.go. If a reward has a daily cap, prefer the shared counter utilities under common/data/share/ over inventing new state.

Validation

Run, at minimum:

  • cd /workspace/logic && go test ./service/fight/effect
  • cd /workspace/logic && go build ./...

If the task came from docs/effect-unimplemented-tasks/, remove the completed task file when the user asked for it.

Output

When finishing a task, report:

  • which effect IDs were truly implemented,
  • which IDs already existed and were left untouched,
  • validation commands actually run,
  • any remaining model limitations or behavior assumptions.