211 lines
7.7 KiB
Markdown
211 lines
7.7 KiB
Markdown
# Legacy Trigger System (iAction + Trigger Callers)
|
|
|
|
This document explains how the legacy Trigger system is built on `iAction`
|
|
and `TriggerCaller`, and how it affects both command outcomes and battle flow.
|
|
Primary references include `legacy/hwe/sammo/iAction.php`,
|
|
`legacy/hwe/sammo/TriggerCaller.php`, `legacy/hwe/sammo/General.php`,
|
|
`legacy/hwe/process_war.php`, and `legacy/hwe/sammo/WarUnit.php`.
|
|
|
|
## Core Concepts
|
|
|
|
### `iAction`: modifier hooks + trigger provider
|
|
|
|
`iAction` is the unified interface for traits, specials, crew types, items,
|
|
scenario effects, and hidden buffs. It provides:
|
|
|
|
- Modifier hooks (`onCalcDomestic`, `onCalcStat`, `onCalcOpposeStat`,
|
|
`onCalcStrategic`, `onCalcNationalIncome`, `getWarPowerMultiplier`).
|
|
- Trigger hooks (`getPreTurnExecuteTriggerList`,
|
|
`getBattleInitSkillTriggerList`, `getBattlePhaseSkillTriggerList`).
|
|
- Ad-hoc hooks (`onArbitraryAction`) for non-turn side effects.
|
|
|
|
Action sources are merged into a single list in `General::getActionList()`:
|
|
|
|
1. Nation type
|
|
2. Officer level
|
|
3. Domestic special
|
|
4. War special
|
|
5. Personality
|
|
6. Crew type (`GameUnitDetail`)
|
|
7. Inheritance buff (`TriggerInheritBuff`)
|
|
8. Scenario effect
|
|
9. Items
|
|
|
|
The order above is the execution order for modifier hooks, and also the merge
|
|
order for trigger lists (later actions override duplicates with the same
|
|
unique trigger ID).
|
|
|
|
Crew types (`GameUnitDetail`) are special:
|
|
|
|
- They implement `iAction`.
|
|
- They expose `initSkillTrigger` and `phaseSkillTrigger` arrays defined in
|
|
scenario data (`buildWarUnitTriggerClass`).
|
|
- They can include an `iActionList` (crew-type-specific actions) which
|
|
themselves implement `iAction`.
|
|
|
|
### `ObjectTrigger` and `TriggerCaller`
|
|
|
|
Triggers are small, prioritized actions:
|
|
|
|
- `ObjectTrigger` defines priorities and a single `action()` method.
|
|
- `TriggerCaller` groups triggers by priority, merges lists, and `fire()`s
|
|
them in priority order.
|
|
|
|
Priority constants (lower runs earlier):
|
|
|
|
- `PRIORITY_BEGIN` = 10000
|
|
- `PRIORITY_PRE` = 20000
|
|
- `PRIORITY_BODY` = 30000
|
|
- `PRIORITY_POST` = 40000
|
|
- `PRIORITY_FINAL` = 50000
|
|
|
|
`TriggerCaller` uses a unique ID (`priority + class + object id`) for dedup.
|
|
`BaseWarUnitTrigger` extends this with `raiseType` to separate item-based
|
|
triggers from trait-based ones.
|
|
|
|
Specialized callers enforce type safety:
|
|
|
|
- `GeneralTriggerCaller` accepts `BaseGeneralTrigger`.
|
|
- `WarUnitTriggerCaller` accepts `BaseWarUnitTrigger`.
|
|
|
|
## Modifier Hooks (Command + Stat + War)
|
|
|
|
### `onCalcDomestic`
|
|
|
|
Used by general commands to adjust cost, success, failure, and score. Inputs:
|
|
|
|
- `turnType`: command key (`징병`, `조달`, `주민선정`, `정착장려`, 등).
|
|
- `varType`: `cost`, `rice`, `train`, `atmos`, `success`, `fail`, `score`.
|
|
- `aux`: extra context (ex: `armType` in `che_징병`).
|
|
|
|
Examples:
|
|
|
|
- `Command/General/che_징병.php` uses `cost`, `rice`, `train`, `atmos`.
|
|
- `Command/General/che_주민선정.php` uses `score`, `success`, `fail`.
|
|
- `GeneralTrigger/che_병력군량소모.php` uses `징집인구:score`.
|
|
|
|
### `onCalcStrategic`
|
|
|
|
Used by nation commands to adjust delays/limits:
|
|
|
|
- `varType` often `delay`, `globalDelay`, `strategic_cmd_limit`.
|
|
- Examples: `Command/Nation/che_급습.php`, `che_백성동원.php`, `che_수몰.php`.
|
|
|
|
### `onCalcNationalIncome`
|
|
|
|
Used by `Event/Action/ProcessSemiAnnual.php` to adjust population growth and
|
|
income ratios at the nation level. Nation types (e.g., 유가/법가/병가 계열)이
|
|
여기에서 보정을 걸어준다.
|
|
|
|
### `onCalcStat` / `onCalcOpposeStat`
|
|
|
|
Used for base stats and battle-derived parameters. Common `statName` keys:
|
|
|
|
- Base stats: `leadership`, `strength`, `intel` (General stat calc).
|
|
- Progression: `addDex`, `experience`, `dedication`.
|
|
- Battle timing: `initWarPhase` (phase count from `WarUnitGeneral`).
|
|
- Battle accuracy: `dex{armType}` (e.g., `dex2`).
|
|
- Train/atmos: `bonusTrain`, `bonusAtmos`.
|
|
- Combat odds: `warCriticalRatio`, `warAvoidRatio`.
|
|
- War magic: `warMagicTrialProb`, `warMagicSuccessProb`,
|
|
`warMagicSuccessDamage`, `warMagicFailDamage`.
|
|
- Damage range: `criticalDamageRange` (in `WarUnit::criticalDamage()`).
|
|
- Supply cost: `killRice` (war rice consumption).
|
|
- Battle order: `cityBattleOrder` (opponent modifies city order).
|
|
|
|
`aux` carries context such as `isAttacker`, `opposeType`, or magic name
|
|
(`반목`, `화계`, etc.).
|
|
|
|
## Pre-Turn General Triggers
|
|
|
|
`TurnExecutionHelper::preprocessCommand()` runs pre-turn triggers:
|
|
|
|
1. `General::getPreTurnExecuteTriggerList()` merges triggers from all actions.
|
|
2. Base triggers are appended:
|
|
- `GeneralTrigger/che_부상경감` (priority 10000 / BEGIN)
|
|
- `GeneralTrigger/che_병력군량소모` (priority 50000 / FINAL)
|
|
3. `TriggerCaller::fire()` executes them before the command runs.
|
|
|
|
General triggers use `General::activateSkill()` for logging and gating.
|
|
`TurnExecutionHelper::processCommand()` clears activated skills after the
|
|
command completes.
|
|
|
|
## Battle Triggers
|
|
|
|
Battle triggers are fired in two stages inside `process_war.php`:
|
|
|
|
### Battle-init triggers
|
|
|
|
- Fired once per engagement when a defender is first set (`phase == 0`).
|
|
- Constructed via `General::getBattleInitSkillTriggerList()`.
|
|
- Used for start-of-battle setup (ex: `che_부상무효` from `견고`).
|
|
|
|
### Phase triggers
|
|
|
|
Every phase:
|
|
|
|
1. `WarUnit::beginPhase()` clears activated skills and recomputes war power.
|
|
2. `General::getBattlePhaseSkillTriggerList()` builds the trigger list.
|
|
- Base triggers (always included):
|
|
- `che_필살시도`, `che_필살발동`
|
|
- `che_회피시도`, `che_회피발동`
|
|
- `che_계략시도`, `che_계략발동`, `che_계략실패`
|
|
3. Attacker/defender trigger lists are merged and fired.
|
|
4. Damage is calculated using `getWarPower()` (after trigger multipliers).
|
|
|
|
### Attempt → Execute pattern (PRE/POST)
|
|
|
|
Most battle skills split into two triggers:
|
|
|
|
- **Attempt (PRE)**: check conditions, set flags or env payload.
|
|
- **Execute (POST)**: read env/flags and apply damage or status.
|
|
|
|
Examples:
|
|
|
|
- `WarUnitTrigger/che_저격시도.php` (PRE) sets `저격발동자`, wound ranges,
|
|
then `che_저격발동.php` (POST) applies wounds and logs.
|
|
- `WarUnitTrigger/che_계략시도.php` (PRE) sets `magic` and success/failure,
|
|
then `che_계략발동.php` / `che_계략실패.php` (POST) applies multipliers.
|
|
- `WarUnitTrigger/che_필살시도.php` → `che_필살발동.php` adjusts war power.
|
|
|
|
### Battle env and stop flags
|
|
|
|
`BaseWarUnitTrigger::action()` supplies a mutable env:
|
|
|
|
- `e_attacker` / `e_defender`: per-side state map.
|
|
- `stopNextAction`: if true, later triggers are skipped.
|
|
|
|
Triggers can return `false` from `actionWar()` to set `stopNextAction`.
|
|
|
|
### Item-based triggers and consumption
|
|
|
|
`BaseWarUnitTrigger` uses a `raiseType` bitmask to tag item-based triggers:
|
|
|
|
- `TYPE_ITEM`: item-triggered, with `아이템사용` skill gating.
|
|
- `TYPE_CONSUMABLE_ITEM`: consumes and deletes the item.
|
|
- `TYPE_DEDUP_TYPE_BASE`: offset for dedup grouping.
|
|
|
|
`processConsumableItem()` handles the consumption flow and logging. Item
|
|
triggers typically pass `raiseType` so the same skill can coexist with
|
|
non-item versions (see `ActionItem/che_저격_매화수전.php`).
|
|
|
|
## Interaction Notes for Porting
|
|
|
|
- Preserve `General::getActionList()` order; modifier hooks stack in sequence.
|
|
- Apply `onCalcOpposeStat` using the opponent's action list after the
|
|
general's own `onCalcStat` adjustments.
|
|
- Keep priority-based execution (`PRIORITY_*`) and the PRE/POST split.
|
|
- Replicate trigger dedup semantics (`getUniqueID` + `raiseType`).
|
|
- Maintain `beginPhase()` clearing of activated skills; battle triggers assume
|
|
per-phase activation.
|
|
- Ensure RNG usage stays deterministic (`RandUtil` everywhere in triggers).
|
|
|
|
## Related Files
|
|
|
|
- `legacy/hwe/sammo/iAction.php`
|
|
- `legacy/hwe/sammo/TriggerCaller.php`
|
|
- `legacy/hwe/sammo/ObjectTrigger.php`
|
|
- `legacy/hwe/sammo/General.php`
|
|
- `legacy/hwe/sammo/WarUnit.php`
|
|
- `legacy/hwe/process_war.php`
|