문서 추가: 레거시 이벤트 시스템 및 전투 해상도에 대한 상세 설명 추가

This commit is contained in:
2025-12-26 20:03:38 +00:00
parent 21e7c8ddff
commit c11527cce9
3 changed files with 125 additions and 8 deletions
+27 -3
View File
@@ -13,6 +13,19 @@ references include `legacy/hwe/sammo/TurnExecutionHelper.php`,
- `StaticEventHandler::handleEvent(...)`
- Invoked by many commands and API handlers to run per-action static hooks.
## Event Table Schema
`event` rows are stored in the legacy DB schema (`legacy/hwe/sql/schema.sql`):
- `id`: auto-increment primary key
- `target`: enum of `PRE_MONTH`, `MONTH`, `OCCUPY_CITY`, `DESTROY_NATION`, `UNITED`
- `priority`: higher first (default 1000)
- `condition`: JSON array (condition DSL)
- `action`: JSON array (action DSL)
Indexes: `(target, priority, id)` for dispatch ordering. Both `condition` and
`action` are JSON-validated by DB constraints.
## Event Table Dispatch
`runEventHandler()` drives the dynamic event pipeline:
@@ -71,6 +84,18 @@ Static events are hooks triggered directly by commands/APIs:
- These hooks are used to extend command behavior without modifying the
command code itself (e.g., troop join/exit side effects).
### Static Handler Map Sources
`GameConst::$staticEventHandlers` defaults to an empty array in
`legacy/hwe/sammo/GameConstBase.php`. Scenario JSON can override it:
- `legacy/hwe/scenario/scenario_911.json` (only observed override in repo)
- `sammo\\API\\Troop\\JoinTroop``event_부대탑승즉시이동`
- `sammo\\Command\\Nation\\che_발령``event_부대발령즉시집합`
Static handler names should map to classes in `legacy/hwe/sammo/StaticEvent/`
(class name matches handler key).
## RNG Notes
Dynamic event actions can use deterministic RNG by constructing
@@ -81,6 +106,5 @@ Examples include `RandomizeCityTradeRate` and `UpdateNationLevel`.
- `Event\Engine` is a stub with a TODO; it is not currently used in the main
turn pipeline.
- The full mapping of `GameConst::$staticEventHandlers` to events should be
extracted from scenario configs and command usage when documenting specific
rule packs.
- Verify whether any runtime code injects additional static handlers beyond
scenario JSON overrides.
+92 -2
View File
@@ -74,6 +74,96 @@ After `processWar_NG()`:
- Update `diplomacy.dead` for both sides
- If city conquered: call `ConquerCity()`
## Conflict Tracking (`city.conflict`)
City conflict tracks which nations contributed to siege damage, used to
resolve post-war ownership when multiple attackers participate.
Source: `WarUnitCity::addConflict()` in `legacy/hwe/sammo/WarUnitCity.php`.
- `city.conflict` is a JSON map `{ nationID: deadContribution }`.
- Contribution amount is based on city `dead` (minimum 1).
- First/last hit bonus: if no conflict exists yet or city HP is 0, `dead` is
multiplied by 1.05 ("선타, 막타 보너스").
- Contributions are sorted descending via `arsort()` after updates.
- `addConflict()` returns `true` when a new nation enters the conflict, which
triggers the global "분쟁" log in `processWar()`.
- `getConquerNation()` returns the first key of the sorted map to select the
final owner.
- `DeleteConflict($nation)` removes a nation from all city conflicts, used on
nation deletion and on the `che_방랑` flow.
## City Conquest Resolution (`ConquerCity`)
`ConquerCity()` finalizes city ownership, handles nation collapse, and applies
post-siege side effects. It is deterministic with the conquest RNG seed noted
below.
### Common Flow
- Logs conquest to attacker (general/nation/global) and defender nation history.
- Runs `EventTarget::OCCUPY_CITY` handlers via `TurnExecutionHelper::runEventHandler()`.
- Calls `onArbitraryAction(..., 'ConquerCity')` for each defender general in
the city, then persists them.
### Nation Collapse Path
Triggered when the defender nation owns exactly one city (the captured city):
- Calls `deleteNation()` using the defender lord (officer level 12).
- All defender generals lose 2050% of gold and rice, -10% experience, and
-50% dedication, with action logs. Loss amounts are aggregated.
- Optionally issues scout messages to fleeing generals (when `join_mode` allows).
- NPC defenders (NPC type 28 except 5) can auto-queue `che_임관` to the
attacker nation with a random delay (012 turns), gated by
`GameConst::$joinRuinedNPCProp`.
- Attacker reward:
- Half of defender nation gold/rice above base (`GameConst::$basegold`,
`GameConst::$baserice`) plus half of the aggregated general losses.
- Credited to attacker nation and logged to all chiefs (officer level >= 5).
- Runs `EventTarget::DESTROY_NATION` handlers.
### Nation Survives Path
If the defender nation still has other cities:
- Demotes city officers (태수/군사/종사) to general:
- `officer_level = 1`, `officer_city = 0`.
- If the city was the capital:
- Picks a new capital via `findNextCapital()` (closest distance, highest pop).
- Logs an emergency relocation message to global and all nation generals.
- Sets `nation.capital` to new city and halves nation gold/rice.
- Marks new capital as supply city; moves chiefs to it.
- Applies 20% morale loss to all generals (`atmos *= 0.8`).
- Refreshes cached nation static info.
### Final Ownership + City Reset
`getConquerNation()` inspects `city.conflict` to decide final owner. If the
attacker loses arbitration, the city is transferred to the conflict winner
and logs are emitted for both nations.
City stats are reset after ownership is settled:
- `supply = 1`, `term = 0`, `conflict = {}`, `nation = conquerNation`,
`officer_set = 0`.
- `agri/comm/secu` multiplied by 0.7.
- `def/wall` reset:
- If `level > 3`: both set to `GameConst::$defaultCityWall`.
- Else: set to `def_max/2`, `wall_max/2`.
- Frontline status recalculated for all nearby nations (`SetNationFront()`).
### Deterministic RNG
Conquest RNG seed:
`hiddenSeed + 'ConquerCity' + year + month + attackerNationID + attackerID + cityID`.
Used for:
- Defender general loss ratios (2050%).
- Scout message chance and NPC auto-join chance.
- Randomized join turn delay (012).
## `WarUnitGeneral` Highlights
- Train/atmos bonuses depend on city level and attacker/defender role.
@@ -105,5 +195,5 @@ After `processWar_NG()`:
## Open Questions / Follow-ups
- Detailed conquest outcomes (nation collapse, officer handling) extend beyond
the summary here; see `ConquerCity()` in `legacy/hwe/process_war.php`.
- No automatic decay for `city.conflict` is visible; confirm if any scheduled
cleanup exists outside explicit reset paths.
+6 -3
View File
@@ -21,8 +21,6 @@ Move items into the main docs once they are finalized.
## Trigger System
- Trigger evaluation order and priority conflicts
- Composition rules across traits, specials, and scenario effects
- Example trigger sets per scenario or rule pack
## Data and Profiles
@@ -34,6 +32,11 @@ Move items into the main docs once they are finalized.
- [AI suggestion] Expand monthly pipeline details (`preUpdateMonthly`, `postUpdateMonthly`, `turnDate`, `checkStatistic`) with concrete side effects and tables touched.
- [AI suggestion] Document `ConquerCity()` resolution paths (nation collapse, officer handling, reward/penalty rules).
- [AI suggestion] Clarify command prefix semantics (`che_`, `cr_`, `event_`) and add per-command effect summaries.
- [AI suggestion] Add per-command effect summaries (inputs, resource deltas, logs).
- [AI suggestion] Document `event` table schema and the static event handler map (`GameConst::$staticEventHandlers`) with command hook examples.
- [AI suggestion] Document auction scheduling (`registerAuction` call sites) and lifecycle timing rules.
- [AI suggestion] Document scenario-specific unit/map overrides and per-map city deltas.
- [AI suggestion] Document per-command `Constraint` env payload keys and lifecycle.
- [AI suggestion] Document `MessageType` values and message table schema used by diplomacy/mailbox flows.
- [AI suggestion] Document `PenaltyKey` effects and the `GeneralBase` / `LazyVarAndAuxUpdater` state conventions.
- [AI suggestion] Document personality/special selection RNG thresholds and scenario overrides.