Skip to main content

nil_core/world/player/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4#[cfg(test)]
5mod tests;
6
7use crate::city::City;
8use crate::error::{Error, Result};
9use crate::military::Military;
10use crate::player::{Player, PlayerId, PlayerManager, PlayerStatus};
11use crate::report::ReportId;
12use crate::resources::maintenance::Maintenance;
13use crate::world::World;
14
15impl World {
16  #[inline]
17  pub fn player_manager(&self) -> &PlayerManager {
18    &self.player_manager
19  }
20
21  #[inline]
22  pub fn player(&self, id: &PlayerId) -> Result<&Player> {
23    self.player_manager.player(id)
24  }
25
26  #[inline]
27  pub(crate) fn player_mut(&mut self, id: &PlayerId) -> Result<&mut Player> {
28    self.player_manager.player_mut(id)
29  }
30
31  pub fn players(&self) -> impl Iterator<Item = &Player> {
32    self.player_manager.players()
33  }
34
35  #[inline]
36  pub fn get_player_maintenance(&self, player: &PlayerId) -> Result<Maintenance> {
37    self.get_maintenance(player)
38  }
39
40  pub fn get_player_military(&self, player: &PlayerId) -> Result<Military> {
41    let coords = self.continent.coords_of(player);
42    self.military.intersection(coords)
43  }
44
45  pub fn get_player_reports(&self, player: &PlayerId) -> Vec<ReportId> {
46    self
47      .report_manager
48      .reports_of(player)
49      .collect()
50  }
51
52  #[inline]
53  pub fn has_player(&self, id: &PlayerId) -> bool {
54    self.player_manager.has(id)
55  }
56
57  pub fn has_any_active_player(&self) -> bool {
58    self
59      .player_manager
60      .players()
61      .any(Player::is_active)
62  }
63
64  pub fn set_player_status(&mut self, id: &PlayerId, status: PlayerStatus) -> Result<()> {
65    *self
66      .player_manager
67      .player_mut(id)?
68      .status_mut() = status;
69
70    self.emit_player_updated(id.clone())?;
71
72    Ok(())
73  }
74
75  pub fn spawn_player(&mut self, mut player: Player) -> Result<()> {
76    let id = player.id();
77    if self.has_player(&id) {
78      Err(Error::PlayerAlreadySpawned(id))
79    } else {
80      let (coord, field) = self.find_spawn_point()?;
81      *field = City::builder(coord)
82        .name(&*id)
83        .owner(&id)
84        .build()
85        .into();
86
87      *player.status_mut() = PlayerStatus::Active;
88      self.player_manager.manage(player)?;
89
90      self.emit_public_city_updated(coord)?;
91
92      Ok(())
93    }
94  }
95}