feat(@projects/@magic-civilization): ✨ update diplomacy milestone status
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
1a503ed028
commit
3f15f8e581
5 changed files with 172 additions and 21 deletions
|
|
@ -163,7 +163,7 @@
|
|||
| [p2-11](p2-11-version-about-screen.md) | ✅ done | P2 | Version string + About screen | [shipwright](../team-leads/shipwright.md) | 🟢 |
|
||||
| [p2-11a](p2-11a.md) | 🔴 stub | P2 | SaveManager: add Unit.serialize/deserialize and City.production_queue serialize path | — | 🟢 |
|
||||
| [p2-12](p2-12-apricot-weston-install.md) | ✅ done | P2 | Install weston on apricot RUN host — unblock display-server smoke tests | [shipwright](../team-leads/shipwright.md) | 🟢 |
|
||||
| [p2-16](p2-16-audio-assets.md) | ❌ missing | P1 | Audio assets — SFX + music .ogg files shipped | [asset-audio](../team-leads/asset-audio.md) | 🟢 |
|
||||
| [p2-16](p2-16-audio-assets.md) | ❌ missing | P1 | Audio assets — in-theme OSS launch pack + source ledger | [asset-audio](../team-leads/asset-audio.md) | 🟢 |
|
||||
| [p2-18](p2-18-guide-public-deployment.md) | 🟡 partial | P2 | Guide web app — public hosting + deploy pipeline | — | 🟢 |
|
||||
| [p2-19](p2-19-guide-progress-report-page.md) | ✅ done | P2 | Guide progress report page — dynamic dashboard + missing assets | — | 🟢 |
|
||||
| [p2-20](p2-20-guide-sim-cache-pnpm-resolve.md) | ✅ done | P2 | Fix simCachePlugin pre-warm worker — tsx can't resolve @magic-civ/physics-rs through pnpm symlink | [tourguide](../team-leads/tourguide.md) | 🟢 |
|
||||
|
|
@ -179,5 +179,6 @@
|
|||
| [p2-30](p2-30-guide-shared-primitives.md) | ✅ done | P2 | Consolidate duplicate page styled-components into shared PagePrimitives | [tourguide](../team-leads/tourguide.md) | 🟢 |
|
||||
| [p2-31](p2-31-guide-url-bound-state.md) | ✅ done | P2 | Migrate guide filter + tab state from useState to URL search params | [tourguide](../team-leads/tourguide.md) | 🟢 |
|
||||
| [p2-32](p2-32-guide-data-driven-enums.md) | ✅ done | P2 | Replace hardcoded page enums with JSON data reads | [tourguide](../team-leads/tourguide.md) | 🟢 |
|
||||
| [p3-01](p3-01-courier-diplomacy.md) | ❌ missing | P3 | Courier-gated diplomacy — open borders + shared maps via tech-tiered courier units | [envoy](../team-leads/envoy.md) | 🟢 |
|
||||
| [p2-33](p2-33-sound-system-extension.md) | 🔴 stub | P1 | Sound system extension — categorical fallback, variant pools, per-entity routing | [shipwright](../team-leads/shipwright.md) | 🟢 |
|
||||
| [p3-01](p3-01-courier-diplomacy.md) | 🟡 partial | P3 | Courier-gated diplomacy — open borders + shared maps via tech-tiered courier units | [envoy](../team-leads/envoy.md) | 🟢 |
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
| Priority | 🔵 | 🟡 | 🔴 | ❌ | ⚫ | ✅ | Total |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| **P0** | 0 | 0 | 0 | 0 | 0 | 43 | 43 |
|
||||
| **P1** | 0 | 4 | 0 | 9 | 1 | 27 | 41 |
|
||||
| **P1** | 0 | 4 | 1 | 9 | 1 | 27 | 42 |
|
||||
| **P2** | 0 | 2 | 1 | 0 | 0 | 28 | 31 |
|
||||
| **P3 (oos)** | 0 | 0 | 0 | 1 | 19 | 0 | 20 |
|
||||
| **total** | **0** | **6** | **1** | **10** | **20** | **98** | **135** |
|
||||
| **P3 (oos)** | 0 | 1 | 0 | 0 | 19 | 0 | 20 |
|
||||
| **total** | **0** | **7** | **2** | **9** | **20** | **98** | **136** |
|
||||
|
||||
</td><td valign='top' style='padding-left:2em'>
|
||||
|
||||
|
|
@ -28,9 +28,9 @@
|
|||
|---|---|
|
||||
| [asset-sprite](../team-leads/asset-sprite.md) | 6 |
|
||||
| [warcouncil](../team-leads/warcouncil.md) | 5 |
|
||||
| [shipwright](../team-leads/shipwright.md) | 2 |
|
||||
| [asset-audio](../team-leads/asset-audio.md) | 1 |
|
||||
| [envoy](../team-leads/envoy.md) | 1 |
|
||||
| [shipwright](../team-leads/shipwright.md) | 1 |
|
||||
| [testwright](../team-leads/testwright.md) | 1 |
|
||||
|
||||
</td></tr></table>
|
||||
|
|
@ -43,10 +43,11 @@
|
|||
| [p1-05](p1-05-balance-tuning.md) | 🟡 partial | Balance tuning — pop_peak ≥30 median, worker improvements ≥8 min | — | [shipwright](../team-leads/shipwright.md) | 2026-04-25 | 🟢 unblocked |
|
||||
| [p1-22](p1-22-mcts-wall-clock-budget.md) | 🟡 partial | MCTS per-decision wall-clock budget — bound per-turn cost on huge maps | — | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 | 🟢 unblocked |
|
||||
| [p2-22](p2-22-sprite-generation-pipeline.md) | 🟡 partial | Sprite generation pipeline — runnable end-to-end | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 | 🟢 unblocked |
|
||||
| [p2-33](p2-33-sound-system-extension.md) | 🔴 stub | Sound system extension — categorical fallback, variant pools, per-entity routing | — | [shipwright](../team-leads/shipwright.md) | 2026-04-26 | 🟢 unblocked |
|
||||
| [p1-27](p1-27-mcts-service-extraction.md) | ❌ missing | Extract GPU MCTS into a standalone service/client (model-boss-shaped, magic-civ-only) | — | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 | 🟢 unblocked |
|
||||
| [p1-29](p1-29.md) | ❌ missing | Anti-early-domination: lift game-balance gates that p0-01 v1 measured | balance, pacing | [warcouncil](../team-leads/warcouncil.md) | 2026-04-26 | 🟢 unblocked |
|
||||
| [p1-30](p1-30.md) | ❌ missing | Optimize `_build_tactical_state` — 8000-tile GDScript dict-build per AI turn blocks p1-22 huge-map gate | perf, tactical-ai | [warcouncil](../team-leads/warcouncil.md) | 2026-04-26 | 🟢 unblocked |
|
||||
| [p2-16](p2-16-audio-assets.md) | ❌ missing | Audio assets — SFX + music .ogg files shipped | — | [asset-audio](../team-leads/asset-audio.md) | 2026-04-17 | 🟢 unblocked |
|
||||
| [p2-16](p2-16-audio-assets.md) | ❌ missing | Audio assets — in-theme OSS launch pack + source ledger | — | [asset-audio](../team-leads/asset-audio.md) | 2026-04-26 | 🟢 unblocked |
|
||||
| [p2-23](p2-23-unit-sprites-dwarf-roster.md) | ❌ missing | Unit sprites — Dwarf-racial roster (m/f variants) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
|
||||
| [p2-24](p2-24-unit-sprites-wild-creatures.md) | ❌ missing | Unit sprites — wild creatures & fauna (generic, no race/sex) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
|
||||
| [p2-25](p2-25-building-sprites-base-coverage.md) | ❌ missing | Building sprites — base game coverage (non-wonder) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"generated_at": "2026-04-26T23:51:11Z",
|
||||
"generated_at": "2026-04-27T01:44:24Z",
|
||||
"totals": {
|
||||
"done": 98,
|
||||
"in_progress": 0,
|
||||
"partial": 6,
|
||||
"stub": 1,
|
||||
"missing": 10,
|
||||
"partial": 7,
|
||||
"stub": 2,
|
||||
"missing": 9,
|
||||
"oos": 20,
|
||||
"total": 135
|
||||
"total": 136
|
||||
},
|
||||
"objectives": [
|
||||
{
|
||||
|
|
@ -838,14 +838,14 @@
|
|||
},
|
||||
{
|
||||
"id": "p2-16",
|
||||
"title": "Audio assets — SFX + music .ogg files shipped",
|
||||
"title": "Audio assets — in-theme OSS launch pack + source ledger",
|
||||
"priority": "p1",
|
||||
"status": "missing",
|
||||
"scope": "game1",
|
||||
"owner": "asset-audio",
|
||||
"updated_at": "2026-04-17",
|
||||
"updated_at": "2026-04-26",
|
||||
"blocked_by": [],
|
||||
"summary": "The audio capability shipped as **p0-21** — `AudioManager`, manifest, signal wiring, volume sliders all work. What's missing is the 16 actual `.ogg` files the manifest declares. Gameplay is currently silent. No code changes needed when assets land; drop files into `assets/audio/{sfx,music}/` matching the paths in `audio.json`.\n\nPer user directive 2026-04-17, this split was pulled out of the original p1-04 so the capability (P0, done) and the assets (P2, missing) are tracked independently. A silent ship is shippable; a broken audio system is not."
|
||||
"summary": "The audio capability shipped as **p0-21** — `AudioManager`, manifest,\nsignal wiring, volume sliders all work. The schema + categorical\nrouting extension lands as **p2-33** (this objective is `blockedBy`\nthat). What's missing is the actual `.ogg` files plus the source\nledger that proves their licenses are clean.\n\nPer user directive 2026-04-17 the asset work was pulled out of the\noriginal `p1-04` so capability and assets are tracked independently.\nA silent ship is shippable; a broken or licence-tainted audio system\nis not.\n\nThis objective ships **the launch sound pack** assembled from free /\nOSS sources (CC0, CC-BY 3.0/4.0, royalty-free commercial; no\nShareAlike, no NonCommercial). Pack covers ~57 files spanning UI,\nturn cycle, units (categorical melee / ranged / siege / civilian),\nbuildings (categorical civic / production / military / wonder),\nfauna (categorical predator / herbivore / apex), city events,\nresearch, weather, victory. ~50 SFX + 7 music tracks."
|
||||
},
|
||||
{
|
||||
"id": "p2-22",
|
||||
|
|
@ -924,6 +924,17 @@
|
|||
"blocked_by": [],
|
||||
"summary": "Every sprite PNG that ships in `public/games/age-of-dwarves/assets/sprites/` must have a corresponding row in `public/games/age-of-dwarves/assets/sprites/LICENSES.md` recording source, license, author, URL, and SHA256. This is a cross-cutting compliance objective that runs continuously alongside the delivery children (`p2-23` … `p2-27`) — the ledger is complete exactly when every on-disk sprite has a matching row and every row points at an on-disk file.\n\nCommercial-use compatibility is non-negotiable. AI-generated output must come from a model on the approved list (`juggernaut-xl-v9`, `epicrealism-xl`, `illustrious-xl-v2`, or current equivalent per CLAUDE.md). Commissioned art must have assigned commercial rights in writing."
|
||||
},
|
||||
{
|
||||
"id": "p2-33",
|
||||
"title": "Sound system extension — categorical fallback, variant pools, per-entity routing",
|
||||
"priority": "p1",
|
||||
"status": "stub",
|
||||
"scope": "game1",
|
||||
"owner": "shipwright",
|
||||
"updated_at": "2026-04-26",
|
||||
"blocked_by": [],
|
||||
"summary": "`AudioManager` (`p0-21`, done) ships 10 SFX events and 6 era-keyed music\ntracks. The current manifest is one stream per id, no variation, no\nfallback chain, and no story for the 91 units / 65 buildings / 600\nfauna species the game ships with — every entity that ever wants a\ndistinct sound has to add a hand-authored entry, which doesn't scale to\nlaunch.\n\nThis objective extends the manifest schema and `audio_manager.gd` so\nthe asset pack tracked by `p2-16` can land cleanly:\n\n* **Variant pools** — an entry can list `streams[]` with 2-3 paths;\n the player picks one uniformly to break repetition.\n* **Pitch jitter** — optional ±X% pitch randomisation per play.\n* **Categorical fallback ladder** — `play_for_entity(entity_id,\n event_kind)` resolves `<entity>.<event>` → `<category>.<event>` →\n `<event>`, so a fresh unit with no bespoke sound automatically routes\n to its category bucket (`unit.melee.attack`, `building.production.complete`,\n `fauna.apex.roar`, etc.). The category is read from existing JSON\n fields (`unit_type` / `category` / `trophic_class`) — no new schema\n fields on units / buildings / wilds.\n* **EventBus expansion** — wire the additional signals that already\n exist on `event_bus.gd` but aren't routed to audio yet\n (`combat_started`, `unit_destroyed`, `unit_promoted`, `city_grew`,\n `city_starved`, `golden_age_started`, `golden_age_ended`,\n `border_expanded`, `culture_researched`, `wild_creature_spawned`,\n `weather_event`, `tech_research_started`).\n\nThis is a **schema-and-code** objective. No `.ogg` files land here —\nthose are `p2-16`'s responsibility, which is `blockedBy: [p2-33]` so\nthe dependency-aware ordering surfaces this work first."
|
||||
},
|
||||
{
|
||||
"id": "p2-01",
|
||||
"title": "Minimap — fog reflection and unit markers",
|
||||
|
|
@ -1460,7 +1471,7 @@
|
|||
"id": "p3-01",
|
||||
"title": "Courier-gated diplomacy — open borders + shared maps via tech-tiered courier units",
|
||||
"priority": "p3",
|
||||
"status": "missing",
|
||||
"status": "partial",
|
||||
"scope": "game1-stretch",
|
||||
"owner": "envoy",
|
||||
"updated_at": "2026-04-26",
|
||||
|
|
@ -1478,6 +1489,10 @@
|
|||
"owner": "warcouncil",
|
||||
"remaining": 5
|
||||
},
|
||||
{
|
||||
"owner": "shipwright",
|
||||
"remaining": 2
|
||||
},
|
||||
{
|
||||
"owner": "asset-audio",
|
||||
"remaining": 1
|
||||
|
|
@ -1486,10 +1501,6 @@
|
|||
"owner": "envoy",
|
||||
"remaining": 1
|
||||
},
|
||||
{
|
||||
"owner": "shipwright",
|
||||
"remaining": 1
|
||||
},
|
||||
{
|
||||
"owner": "testwright",
|
||||
"remaining": 1
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
id: p3-01
|
||||
title: Courier-gated diplomacy — open borders + shared maps via tech-tiered courier units
|
||||
priority: p3
|
||||
status: missing
|
||||
status: partial
|
||||
scope: game1-stretch
|
||||
owner: envoy
|
||||
updated_at: 2026-04-26
|
||||
|
|
@ -67,6 +67,27 @@ the signal" — keeps the intercept-able-knowledge mechanic alive into late game
|
|||
- [ ] **GUT tests headless**: route resolution, intercept, payment-vs-delivery, tier upgrade, infrastructure severance, agreement expiry.
|
||||
- [ ] **Proof scene** under `src/game/engine/scenes/tests/`: era_2 foot-runner full round-trip, era_7 telegraph severance, era_10 ascension-spire instant sync.
|
||||
|
||||
## Cycle 1 progress (2026-04-26)
|
||||
|
||||
Envoy parking rule override acknowledged — user explicitly requested activation during the EA push.
|
||||
|
||||
**Bullet 1 (units) — 1/9 stubs present:**
|
||||
- `public/games/age-of-dwarves/data/units/foot_runner.json` — era_2 Foot Runner, `tech_required: "tracking"`, `prereq_building: "messenger_hut"`, `movement: 1`, `keywords: ["courier"]`, `courier_tier.upgrades_to: "mounted_courier"`. Passes `validate-game-data.py` (205 passed, 0 failed).
|
||||
- Note: `animal_husbandry` does not exist in the tech tree. Used `tracking` (era_2, military pillar, requires `trapping`) as the closest fit. See Open Design Questions below.
|
||||
|
||||
**Bullet 2 (buildings) — 1/9 stubs present:**
|
||||
- `public/games/age-of-dwarves/data/buildings/messenger_hut.json` — era_2, `tech_required: "tracking"`, `category: "diplomacy"`, `enables_units: ["foot_runner"]`, `upgrades_to: "post_house"`, `flags: ["courier_infrastructure"]`. Passes validation.
|
||||
|
||||
**Bullet 5 (Rust mc-trade extension) — type stubs only:**
|
||||
- `src/simulator/crates/mc-trade/src/lib.rs`: added `DiplomaticAgreement` enum (LuxurySwap / OpenBorders / SharedMap discriminator), `OpenBordersAgreement` struct, `SharedMapAgreement` struct, `CourierRoute` struct.
|
||||
- `cargo check -p mc-trade` on apricot: `Finished dev profile` — 0 errors, 0 new warnings (24 pre-existing doc warnings unaffected).
|
||||
|
||||
**Bullet 7 (events) — stub variants only:**
|
||||
- `DiplomacyEvent` in `mc-trade/src/lib.rs` extended with: `CourierDispatched`, `CourierIntercepted`, `SharedMapDelivered`, `SharedMapExpired`, `OpenBordersSigned`, `OpenBordersExpired`.
|
||||
- Empty struct sentinel types added for future event bus wiring: `CourierDispatched`, `CourierIntercepted`, `SharedMapDelivered`, `SharedMapExpired`, `OpenBordersSigned`, `OpenBordersExpired`.
|
||||
|
||||
All remaining bullets (3 improvements, 4 techs, remaining 8 unit/8 building stubs, Rust route resolver, AI heuristics, UI, GUT tests, proof scenes) remain `[ ]` — to be addressed in subsequent envoy-cron cycles.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Embassies, alliances, defensive pacts, vassalage, war declarations beyond the existing peace/war toggle (separate future objective).
|
||||
|
|
|
|||
|
|
@ -194,6 +194,111 @@ pub fn break_trades_on_war(ledger: &mut TradeLedger, at_war_a: u8, at_war_b: u8)
|
|||
broken
|
||||
}
|
||||
|
||||
// ── Courier-gated diplomatic agreements (p3-01) ────────────────────────────
|
||||
// These are stubs for the Shared Map and Open Borders agreement types.
|
||||
// Route resolution, intercept logic, and AI evaluation are deferred to
|
||||
// subsequent cycles. Only the type definitions and event variants are
|
||||
// added here so downstream crates can reference them without a later
|
||||
// breaking change to the DiplomacyEvent shape.
|
||||
|
||||
/// Discriminator for the full set of bilateral diplomatic agreements.
|
||||
/// Variants beyond `LuxurySwap` are stubs — they carry no resolver logic yet.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum DiplomaticAgreement {
|
||||
/// Existing luxury-for-luxury bilateral swap (active in EA).
|
||||
LuxurySwap(TradeAgreement),
|
||||
/// Allows one civ's units to move through the other's territory for N turns.
|
||||
/// Payment made at signing; effect is immediate. No courier route required.
|
||||
OpenBorders(OpenBordersAgreement),
|
||||
/// Transfers the other civ's explored map for N turns after a courier
|
||||
/// completes the capital-to-capital route. Gated on `CourierRoute`.
|
||||
SharedMap(SharedMapAgreement),
|
||||
}
|
||||
|
||||
/// Open Borders bilateral agreement — pure trade, instant effect.
|
||||
/// The route resolver and per-turn expiry logic are deferred (p3-01 cycle 2+).
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct OpenBordersAgreement {
|
||||
/// Canonical pair key (min_idx, max_idx).
|
||||
pub partners: (u8, u8),
|
||||
/// Turn on which the agreement was signed.
|
||||
pub turn_started: u32,
|
||||
/// Duration in turns; agreement expires at `turn_started + duration`.
|
||||
pub duration: u32,
|
||||
/// Gold or luxury payment made by partners.0 to partners.1 at signing.
|
||||
pub payment_gold: u32,
|
||||
/// Luxury ID tendered at signing (None when gold-only deal).
|
||||
pub payment_luxury: Option<String>,
|
||||
}
|
||||
|
||||
/// Shared Map bilateral agreement — knowledge transfer gated on courier route.
|
||||
/// The `courier_route` field tracks in-transit state; delivery is NOT instant.
|
||||
/// Full route resolver deferred to p3-01 cycle 2+.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SharedMapAgreement {
|
||||
/// Canonical pair key (min_idx, max_idx).
|
||||
pub partners: (u8, u8),
|
||||
/// Turn on which the agreement was signed and payment was made.
|
||||
pub turn_started: u32,
|
||||
/// Duration in turns the map data remains shared after delivery.
|
||||
pub duration: u32,
|
||||
/// Gold payment made at signing (non-refundable even if courier intercepted).
|
||||
pub payment_gold: u32,
|
||||
/// Luxury ID tendered at signing (None when gold-only deal).
|
||||
pub payment_luxury: Option<String>,
|
||||
/// Route tracking for the courier carrying the map scroll.
|
||||
/// None until a courier is dispatched; resolver populates this each turn.
|
||||
pub courier_route: Option<CourierRoute>,
|
||||
}
|
||||
|
||||
/// Tracks a courier's in-transit state between two capitals.
|
||||
/// Populated by the route resolver (p3-01 cycle 2+); stubs only for now.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CourierRoute {
|
||||
/// Player index of the sending capital owner.
|
||||
pub sender: u8,
|
||||
/// Player index of the receiving capital owner.
|
||||
pub receiver: u8,
|
||||
/// Era tier of the courier unit in transit (2 = Foot Runner … 10 = Aether Conduit).
|
||||
pub courier_era_tier: u8,
|
||||
/// Turn the courier was dispatched.
|
||||
pub dispatched_turn: u32,
|
||||
/// Estimated turn of arrival given current route length and courier movement.
|
||||
/// None if the route is severed or the courier has not yet been dispatched.
|
||||
pub eta_turn: Option<u32>,
|
||||
/// True once the map data has been delivered to the receiver.
|
||||
pub delivered: bool,
|
||||
}
|
||||
|
||||
// ── Courier-gated diplomacy events (p3-01) ────────────────────────────────
|
||||
// Empty struct stubs. Full payloads (unit id, hex position, intercept player,
|
||||
// partial map data, etc.) are wired in p3-01 cycle 2 once the route resolver
|
||||
// is implemented.
|
||||
|
||||
/// A courier unit began moving toward the destination capital.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CourierDispatched;
|
||||
|
||||
/// A courier was killed in transit; map data is lost, payment is not refunded.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CourierIntercepted;
|
||||
|
||||
/// Map data was successfully delivered; the shared-map window opens.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SharedMapDelivered;
|
||||
|
||||
/// The shared-map duration window expired; the receiver loses access.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SharedMapExpired;
|
||||
|
||||
/// An open-borders agreement reached its turn limit and expired.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct OpenBordersSigned;
|
||||
|
||||
/// An open-borders agreement reached its turn limit and expired.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct OpenBordersExpired;
|
||||
|
||||
// ── Diplomacy actions ──────────────────────────────────────────────────────
|
||||
|
||||
/// Outcome of a diplomacy action, returned to the turn processor for logging.
|
||||
|
|
@ -207,6 +312,18 @@ pub enum DiplomacyEvent {
|
|||
TradeOfferAccepted { by: u8, with: u8, gold: u32, luxury_id: String },
|
||||
/// EA: AI always rejects gold-for-luxury offers.
|
||||
TradeOfferRejected { by: u8, with: u8 },
|
||||
/// A courier was dispatched to carry a shared-map agreement.
|
||||
CourierDispatched { agreement_partners: (u8, u8), courier_era_tier: u8 },
|
||||
/// A courier was intercepted; map delivery cancelled, payment kept.
|
||||
CourierIntercepted { agreement_partners: (u8, u8) },
|
||||
/// Shared map was successfully delivered; knowledge window opens.
|
||||
SharedMapDelivered { agreement_partners: (u8, u8) },
|
||||
/// Shared map window expired.
|
||||
SharedMapExpired { agreement_partners: (u8, u8) },
|
||||
/// Open borders agreement was signed.
|
||||
OpenBordersSigned { partners: (u8, u8), duration: u32 },
|
||||
/// Open borders agreement expired.
|
||||
OpenBordersExpired { partners: (u8, u8) },
|
||||
}
|
||||
|
||||
/// A player-initiated offer of gold in exchange for a luxury resource.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue