1use crate::chat::ChatMessage;
5use crate::continent::coord::Coord;
6use crate::error::Result;
7use crate::event::{Event, EventId, Listener};
8use crate::military::maneuver::ManeuverId;
9use crate::player::PlayerId;
10use crate::report::ReportKind;
11use crate::report::battle::BattleReport;
12use crate::report::support::SupportReport;
13use crate::ruler::Ruler;
14use crate::world::World;
15use std::collections::HashSet;
16
17impl World {
18 #[inline]
19 pub fn subscribe(&self) -> Listener {
20 self.emitter.subscribe()
21 }
22
23 fn broadcast(&self, event: Event) -> Result<()> {
25 self.emitter.broadcast(event)
26 }
27
28 fn emit_to(&self, target: PlayerId, event: Event) -> Result<()> {
30 self.emitter.emit_to(target, event)
31 }
32
33 fn emit_to_ruler(&self, ruler: &Ruler, event: Event) -> Result<()> {
35 if let Some(player) = ruler.player() {
36 self.emitter.emit_to(player.clone(), event)?;
37 }
38
39 Ok(())
40 }
41
42 fn emit_to_city_owner(&self, coord: Coord, event: Event) -> Result<()> {
44 let city = self.city(coord)?;
45 self.emit_to_ruler(city.owner(), event)?;
46 Ok(())
47 }
48
49 pub(super) fn emit_chat_message(&self, message: ChatMessage) -> Result<()> {
51 let world = self.config.id();
52 self.broadcast(Event::ChatMessage { id: EventId::new(), world, message })
53 }
54
55 pub(super) fn emit_city(&self, coord: Coord) -> Result<()> {
57 let world = self.config.id();
58 self.emit_to_city_owner(coord, Event::City { id: EventId::new(), world, coord })
59 }
60
61 pub(super) fn emit_drop(&self) -> Result<()> {
64 let world = self.config.id();
65 self.broadcast(Event::Drop { id: EventId::new(), world })
66 }
67
68 pub(super) fn emit_market(&self) -> Result<()> {
70 let world = self.config.id();
71 self.broadcast(Event::Market { id: EventId::new(), world })
72 }
73
74 pub(super) fn emit_military(&self, player: PlayerId) -> Result<()> {
76 let world = self.config.id();
77 let event = Event::Military {
78 id: EventId::new(),
79 world,
80 player: player.clone(),
81 };
82
83 self.emit_to(player, event)
84 }
85
86 pub(super) fn emit_military_to_maneuver_players(&self, id: ManeuverId) -> Result<()> {
88 let maneuver = self.military.maneuver(id)?;
89 let mut players = HashSet::with_capacity(3);
90
91 if let Some(player) = self
92 .military
93 .army(maneuver.army())?
94 .owner()
95 .player()
96 {
97 players.insert(player);
98 }
99
100 if let Some(player) = self.city(maneuver.origin())?.player() {
101 players.insert(player);
102 }
103
104 if let Some(player) = self.city(maneuver.destination())?.player() {
105 players.insert(player);
106 }
107
108 for player in players {
109 self.emit_military(player.clone())?;
110 }
111
112 Ok(())
113 }
114
115 pub(super) fn emit_player(&self, player: PlayerId) -> Result<()> {
117 let world = self.config.id();
118 let event = Event::Player {
119 id: EventId::new(),
120 world,
121 player: player.clone(),
122 };
123
124 self.emit_to(player, event)
125 }
126
127 pub(super) fn emit_public_city(&self, coord: Coord) -> Result<()> {
129 let world = self.config.id();
130 self.broadcast(Event::PublicCity { id: EventId::new(), world, coord })?;
131 self.emit_city(coord)?;
132 Ok(())
133 }
134
135 pub(super) fn emit_report(&self, player: PlayerId, report: ReportKind) -> Result<()> {
137 let world = self.config.id();
138 let event = Event::Report {
139 id: EventId::new(),
140 world,
141 report: Box::new(report),
142 };
143
144 self.emit_to(player, event)
145 }
146
147 pub(super) fn emit_ruler(&self, ruler: &Ruler) -> Result<()> {
149 if let Some(player) = ruler.player() {
150 self.emit_player(player.clone())?;
151 }
152
153 Ok(())
154 }
155
156 pub(super) fn emit_battle_report(&self, report: &BattleReport) -> Result<()> {
157 let mut players = HashSet::with_capacity(2);
158 if let Some(player) = report.attacker().player() {
159 players.insert(player);
160 }
161
162 if let Some(player) = report.defender().player() {
163 players.insert(player);
164 }
165
166 for player in players {
167 self.emit_report(player.clone(), report.clone().into())?;
168 }
169
170 Ok(())
171 }
172
173 pub(super) fn emit_support_report(&self, report: &SupportReport) -> Result<()> {
174 let mut players = HashSet::with_capacity(2);
175 if let Some(player) = report.sender().player() {
176 players.insert(player);
177 }
178
179 if let Some(player) = report.receiver().player() {
180 players.insert(player);
181 }
182
183 for player in players {
184 self.emit_report(player.clone(), report.clone().into())?;
185 }
186
187 Ok(())
188 }
189
190 pub(super) fn emit_round(&self) -> Result<()> {
192 let world = self.config.id();
193 let round = self.round.clone();
194 self.broadcast(Event::Round { id: EventId::new(), world, round })
195 }
196}