change repair_tool application and add beams for salvager and repair_tool
This commit is contained in:
@@ -59,7 +59,7 @@ Simulation types shared across subsystems:
|
||||
- `Item` — `struct Item { ItemType type; }`. Items on belts have no persistent identity across ticks.
|
||||
- `Port` — `struct Port { QPoint tile; Rotation direction; }`. Identifies a belt-adjacent cell and the direction of flow across that cell.
|
||||
- `MovementIntent` — `struct MovementIntent { bool active; QVector2D target; }`. Written by the winning behavior's executor (see Movement Arbitration). Cleared (`active = false`) at the start of each tick; `tickMovement` brakes when inactive, otherwise drives toward `target`.
|
||||
- `WeaponFiredEvent` — `struct WeaponFiredEvent : public Event { entt::entity shooter; entt::entity target; Tick emittedAt; }`. Transient record emitted each time a weapon fires (REQ-SHP-FIRING, REQ-SHP-FIRING-BEAM). Buffered in a sim-owned vector during the tick, then drained and re-emitted via EventManager by the UI frame handler; see Sim → UI Events.
|
||||
- `BeamFiredEvent` — `struct BeamFiredEvent : public Event { BeamKind kind; entt::entity shooter; entt::entity target; Tick emittedAt; }`. Transient record emitted each time a weapon fires, a repair tool starts a heal cycle, or a salvage module starts a collection cycle (REQ-SHP-FIRING, REQ-SHP-FIRING-BEAM). `BeamKind` (`Weapon`/`Repair`/`Salvage`) selects the beam color. Buffered in a sim-owned vector during the tick, then drained and re-emitted via EventManager by the UI frame handler; see Sim → UI Events.
|
||||
- `SchematicChoiceOption` — `struct SchematicChoiceOption { string schematicId; SchematicType type; string displayName; bool isNewUnlock; int targetLevel; }`. Describes one option in the schematic choice dialog (REQ-DEF-SCHEMATIC-DROP). Up to three are generated when an enemy station set is destroyed. `SchematicType` is `Ship`, `Module`, or `Recipe`.
|
||||
- `SchematicChoicesAvailableEvent` — EventManager event carrying a `vector<SchematicChoiceOption>`. Sent by the UI each frame when pending choices are detected; handled by `MainWindow` which opens the schematic choice dialog.
|
||||
|
||||
@@ -85,9 +85,9 @@ The EventManager is thread-safe (mutex-guarded).
|
||||
|
||||
### Sim → UI Events
|
||||
|
||||
The simulation layer stays free of EventManager — it uses a plain `std::vector<WeaponFiredEvent>` internally (owned by `CombatSystem`). This preserves determinism, tick-order fidelity, and headless testability (Catch2 tests read the queue directly via `drainWeaponFiredEvents()` after `tick()`).
|
||||
The simulation layer stays free of EventManager — it uses a plain `std::vector<BeamFiredEvent>` internally (owned by `Simulation`, filled by the combat, repair, and salvage systems). This preserves determinism, tick-order fidelity, and headless testability (Catch2 tests read the queue directly via `drainBeamFiredEvents()` after `tick()`).
|
||||
|
||||
The UI frame handler (`GameWorldView::onFrame` / `ArenaView::onFrame`) bridges the gap: each frame it calls `simulation.drainWeaponFiredEvents()`, then re-emits each `WeaponFiredEvent` via `EventManager::sendEventImmediately()`. Subscribers (the same view's `handleEvent(WeaponFiredEvent)`) create `ActiveBeam` records tracked for 0.3 s of wall time, then discarded. If either the shooter or target entity is gone when the renderer looks them up, the beam is dropped early.
|
||||
The UI frame handler (`GameWorldView::onFrame` / `ArenaView::onFrame`) bridges the gap: each frame it calls `simulation.drainBeamFiredEvents()`, then re-emits each `BeamFiredEvent` via `EventManager::sendEventImmediately()`. Subscribers (the same view's `handleEvent(BeamFiredEvent)`) create `ActiveBeam` records tracked for 0.3 s of wall time, then discarded. If either the shooter or target entity is gone when the renderer looks them up, the beam is dropped early.
|
||||
|
||||
Schematic drops: when an enemy station set is destroyed, the simulation generates up to 3 `SchematicChoiceOption` entries and stores them as pending state. The UI polls `hasSchematicChoicesPending()` each frame and, when true, sends a `SchematicChoicesAvailableEvent` via EventManager. `MainWindow` handles this event by pausing the game and opening a modal `SchematicChoiceDialog`. The player's selection is fed back via `applySchematicChoice(index)`.
|
||||
|
||||
@@ -108,7 +108,7 @@ Within a single simulation tick, subsystems run in this fixed order. The order i
|
||||
5. **Building → belt push** — buildings push items from output buffer onto the belt tile at their output port (REQ-MAT-OUTPUT-PORT).
|
||||
6. **Belt tick** — advance items along belt tiles; apply splitter routing (REQ-BLD-SPLITTER).
|
||||
7. **Ship behavior systems** — clear `MovementIntent` on each ship, then the `AiSystem` runs three batched phases: every behavior **evaluator** scores its behavior and sets its target data; a **selection** pass records the highest-scoring behavior per ship in `SelectedBehaviorComponent`; each behavior **executor** runs for the winner, writing `MovementIntent` and preferred module targets. The module systems then perform world mutation: `SalvagerSystem` (scrap collection/delivery) and `RepairSystem` (healing). See Movement Arbitration.
|
||||
8. **Combat resolution** — ships and defence stations validate/acquire targets, fire, apply damage; queue deaths. Each fire appends a `WeaponFiredEvent` to the sim's weapon-fired-event queue (REQ-SHP-FIRING-BEAM).
|
||||
8. **Combat resolution** — ships and defence stations validate/acquire targets, fire, apply damage; queue deaths. Each fire appends a `BeamFiredEvent` to the sim's beam-fired-event queue (REQ-SHP-FIRING-BEAM). The repair and salvage module systems (tick step 7d) append their own `BeamFiredEvent`s to the same queue when they start a cycle.
|
||||
9. **Deaths & loot** — process queued deaths: drop scrap (REQ-RES-SCRAP-DROP); if a full enemy-defence-station set was destroyed this tick, generate up to 3 schematic choice options (REQ-DEF-SCHEMATIC-DROP) stored as pending state for the UI to present; remove entities.
|
||||
10. **`tickMovement`** — advance ship positions based on final `MovementIntent`.
|
||||
11. **Scrap despawn** — decrement scrap timers; remove expired scrap (REQ-RES-SCRAP-DROP).
|
||||
@@ -212,7 +212,8 @@ Ships follow a component-composition model using `std::optional<Component>` memb
|
||||
struct Weapon { float damage; float range; float fireRateHz; float cooldownTicks;
|
||||
std::optional<EntityId> currentTarget; };
|
||||
struct SalvageCargo { int capacity; int current; };
|
||||
struct RepairTool { float ratePerTick; std::optional<EntityId> currentTarget; };
|
||||
struct RepairTool { float repairAmountHp; int repairIntervalTicks; int cooldownTicksRemaining;
|
||||
float range; std::optional<EntityId> currentTarget; };
|
||||
```
|
||||
|
||||
### Behavior Components
|
||||
@@ -308,7 +309,7 @@ The game world is rendered by a single `GameWorldView` widget that inherits `QOp
|
||||
|
||||
### Threading
|
||||
|
||||
Sim and UI run on the same thread for v1. `paintEvent` reads sim state directly without locks. If profiling later justifies moving the sim to a worker thread, the pull-style `drainWeaponFiredEvents()` / `getPendingSchematicChoices()` / `applySchematicChoice()` / `forEachVisualItem()` APIs already support a clean snapshot-and-render split; a single mutex at the sim boundary would suffice. The `ArenaSimulation` used by the balancing tool runs headlessly on a worker thread; fire events accumulate in its internal vector and are only drained when `ArenaView` drives `tickOnce()` on the main thread during interactive inspection.
|
||||
Sim and UI run on the same thread for v1. `paintEvent` reads sim state directly without locks. If profiling later justifies moving the sim to a worker thread, the pull-style `drainBeamFiredEvents()` / `getPendingSchematicChoices()` / `applySchematicChoice()` / `forEachVisualItem()` APIs already support a clean snapshot-and-render split; a single mutex at the sim boundary would suffice. The `ArenaSimulation` used by the balancing tool runs headlessly on a worker thread; fire events accumulate in its internal vector and are only drained when `ArenaView` drives `tickOnce()` on the main thread during interactive inspection.
|
||||
|
||||
### Layer Order (back to front)
|
||||
|
||||
@@ -317,7 +318,7 @@ Sim and UI run on the same thread for v1. `paintEvent` reads sim state directly
|
||||
3. **Belt items** — 10×10 colored squares emitted by `BeltSystem::forEachVisualItem`.
|
||||
4. **Scrap** — glyphs at world positions.
|
||||
5. **Ships** — colored arrows oriented by velocity; color keyed to role (player combat / salvage / repair / enemy).
|
||||
6. **Laser beams** — lines derived from live `WeaponFiredEvent`s kept by the renderer for 0.3 s (REQ-SHP-FIRING-BEAM).
|
||||
6. **Laser beams** — lines derived from live `BeamFiredEvent`s kept by the renderer for 0.3 s, colored per `BeamKind` (weapon/repair/salvage) (REQ-SHP-FIRING-BEAM).
|
||||
7. **Build overlays** — ghost in builder mode (REQ-BLD-GHOST), demolish-mode tint, tile highlight under cursor, box-drag selection rectangle.
|
||||
8. **Screen-space UI** — screen-anchored elements, drawn after resetting the world-space transform.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user