Skip to main content

nil_core/world/
event.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::chat::ChatMessage;
5use crate::continent::Coord;
6use crate::error::Result;
7use crate::event::{Event, Listener};
8use crate::player::PlayerId;
9use crate::report::battle::BattleReport;
10use crate::report::support::SupportReport;
11use crate::report::{Report, ReportId};
12use crate::world::World;
13
14impl World {
15  #[inline]
16  pub fn subscribe(&self) -> Listener {
17    self.emitter.subscribe()
18  }
19
20  /// Emits the event to all players.
21  fn broadcast(&self, event: Event) -> Result<()> {
22    self.emitter.broadcast(event)
23  }
24
25  /// Emits the event for a specific player.
26  fn emit_to(&self, target: PlayerId, event: Event) -> Result<()> {
27    self.emitter.emit_to(target, event)
28  }
29
30  /// Emits the event to the owner of the city at the specified coordinate, if any.
31  fn emit_to_owner(&self, coord: Coord, event: Event) -> Result<()> {
32    if let Ok(city) = self.city(coord)
33      && let Some(player) = city.player()
34    {
35      self.emitter.emit_to(player, event)?;
36    }
37
38    Ok(())
39  }
40
41  pub(super) fn emit_battle_report(&self, report: &BattleReport) -> Result<()> {
42    if let Some(attacker) = report.attacker().player().cloned() {
43      self.emit_report(attacker, report.id())?;
44    }
45
46    if let Some(defender) = report.defender().player().cloned() {
47      debug_assert_ne!(report.attacker().player(), Some(&defender));
48      self.emit_report(defender, report.id())?;
49    }
50
51    Ok(())
52  }
53
54  /// Emits [`Event::ChatUpdated`].
55  pub(super) fn emit_chat_updated(&self, message: ChatMessage) -> Result<()> {
56    let world = self.config.id();
57    self.broadcast(Event::ChatUpdated { world, message })
58  }
59
60  /// Emits [`Event::CityUpdated`].
61  pub(super) fn emit_city_updated(&self, coord: Coord) -> Result<()> {
62    let world = self.config.id();
63    self.emit_to_owner(coord, Event::CityUpdated { world, coord })
64  }
65
66  /// Emits [`Event::Drop`].
67  /// This should never be called manually.
68  pub(super) fn emit_drop(&self) -> Result<()> {
69    let world = self.config.id();
70    self.broadcast(Event::Drop { world })
71  }
72
73  /// Emits [`Event::MilitaryUpdated`].
74  pub(super) fn emit_military_updated(&self, player: PlayerId) -> Result<()> {
75    let world = self.config.id();
76    self.emit_to(player.clone(), Event::MilitaryUpdated { world, player })
77  }
78
79  /// Emits [`Event::PlayerUpdated`].
80  pub(super) fn emit_player_updated(&self, player: PlayerId) -> Result<()> {
81    let world = self.config.id();
82    self.emit_to(player.clone(), Event::PlayerUpdated { world, player })
83  }
84
85  /// Emits [`Event::PublicCityUpdated`].
86  pub(super) fn emit_public_city_updated(&self, coord: Coord) -> Result<()> {
87    let world = self.config.id();
88    self.broadcast(Event::PublicCityUpdated { world, coord })
89  }
90
91  /// Emits [`Event::Report`].
92  pub(super) fn emit_report(&self, player: PlayerId, report: ReportId) -> Result<()> {
93    let world = self.config.id();
94    self.emit_to(player, Event::Report { world, report })
95  }
96
97  /// Emits [`Event::RoundUpdated`].
98  pub(super) fn emit_round_updated(&self) -> Result<()> {
99    let world = self.config.id();
100    let round = self.round.clone();
101    self.broadcast(Event::RoundUpdated { world, round })
102  }
103
104  pub(super) fn emit_support_report(&self, report: &SupportReport) -> Result<()> {
105    if let Some(sender) = report.sender().player().cloned() {
106      self.emit_report(sender, report.id())?;
107    }
108
109    if let Some(receiver) = report.receiver().player().cloned() {
110      debug_assert_ne!(report.sender().player(), Some(&receiver));
111      self.emit_report(receiver, report.id())?;
112    }
113
114    Ok(())
115  }
116}