1use crate::chat::ChatMessage;
5use crate::continent::coord::Coord;
6use crate::error::Result;
7use crate::event::{Event, 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::world::World;
14use nil_util::vec::VecExt as _;
15use smallvec::SmallVec;
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_city_owner(&self, coord: Coord, event: Event) -> Result<()> {
35 let city = self.city(coord)?;
36 if let Some(player) = city.player() {
37 self.emitter.emit_to(player.clone(), event)?;
38 }
39
40 Ok(())
41 }
42
43 pub(super) fn emit_chat_message(&self, message: ChatMessage) -> Result<()> {
45 let world = self.config.id();
46 self.broadcast(Event::ChatMessage { world, message })
47 }
48
49 pub(super) fn emit_city(&self, coord: Coord) -> Result<()> {
51 let world = self.config.id();
52 self.emit_to_city_owner(coord, Event::City { world, coord })
53 }
54
55 pub(super) fn emit_drop(&self) -> Result<()> {
58 let world = self.config.id();
59 self.broadcast(Event::Drop { world })
60 }
61
62 pub(super) fn emit_military(&self, player: PlayerId) -> Result<()> {
64 let world = self.config.id();
65 self.emit_to(player.clone(), Event::Military { world, player })
66 }
67
68 pub(super) fn emit_military_to_maneuver_players(&self, id: ManeuverId) -> Result<()> {
70 let maneuver = self.military.maneuver(id)?;
71 let mut players = SmallVec::<[_; 3]>::new();
72
73 if let Some(player) = self
74 .military
75 .army(maneuver.army())?
76 .owner()
77 .player()
78 {
79 players.push(player);
80 }
81
82 if let Some(player) = self.city(maneuver.origin())?.player() {
83 players.push_unique(player);
84 }
85
86 if let Some(player) = self.city(maneuver.destination())?.player() {
87 players.push_unique(player);
88 }
89
90 for player in players {
91 self.emit_military(player.clone())?;
92 }
93
94 Ok(())
95 }
96
97 pub(super) fn emit_player(&self, player: PlayerId) -> Result<()> {
99 let world = self.config.id();
100 self.emit_to(player.clone(), Event::Player { world, player })
101 }
102
103 pub(super) fn emit_public_city(&self, coord: Coord) -> Result<()> {
105 let world = self.config.id();
106 self.broadcast(Event::PublicCity { world, coord })
107 }
108
109 pub(super) fn emit_report(&self, player: PlayerId, report: ReportKind) -> Result<()> {
111 let world = self.config.id();
112 self.emit_to(player, Event::Report { world, report: Box::new(report) })
113 }
114
115 pub(super) fn emit_battle_report(&self, report: &BattleReport) -> Result<()> {
116 let mut players = SmallVec::<[_; 2]>::new();
117 if let Some(player) = report.attacker().player() {
118 players.push(player);
119 }
120
121 if let Some(player) = report.defender().player() {
122 players.push_unique(player);
123 }
124
125 for player in players {
126 self.emit_report(player.clone(), report.clone().into())?;
127 }
128
129 Ok(())
130 }
131
132 pub(super) fn emit_support_report(&self, report: &SupportReport) -> Result<()> {
133 let mut players = SmallVec::<[_; 2]>::new();
134 if let Some(player) = report.sender().player() {
135 players.push(player);
136 }
137
138 if let Some(player) = report.receiver().player() {
139 players.push_unique(player);
140 }
141
142 for player in players {
143 self.emit_report(player.clone(), report.clone().into())?;
144 }
145
146 Ok(())
147 }
148
149 pub(super) fn emit_round(&self) -> Result<()> {
151 let world = self.config.id();
152 let round = self.round.clone();
153 self.broadcast(Event::Round { world, round })
154 }
155}