--- name: fight-effect-impl description: 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` 3. 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. 4. 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.