firecore_battle/host/
player.rs1use core::{cell::Ref};
2use rand::Rng;
3
4use pokedex::{
5 item::{bag::SavedBag, Item},
6 moves::Move,
7 pokemon::{owned::SavedPokemon, party::Party, Pokemon},
8 Dex,
9};
10
11use crate::{
12 data::BattleData,
13 endpoint::{BattleEndpoint, ReceiveError},
14 message::{ClientMessage, ServerMessage},
15 party::{ActivePokemon, PlayerParty},
16 player::{ClientPlayerData, Player, PlayerSettings},
17};
18
19use super::pokemon::{ActiveBattlePokemon, HostPokemon};
20
21pub type BattlePlayer<ID, T> =
22 Player<ID, ActiveBattlePokemon<ID>, HostPokemon, T, Box<dyn BattleEndpoint<ID, T>>>;
23
24pub struct PlayerData<ID, T> {
25 pub id: ID,
26 pub name: Option<String>,
27 pub party: Party<SavedPokemon>,
28 pub bag: SavedBag,
29 pub trainer: Option<T>,
30 pub settings: PlayerSettings,
31 pub endpoint: Box<dyn BattleEndpoint<ID, T>>,
32}
33
34impl<ID, T> BattlePlayer<ID, T> {
35 pub fn send(&mut self, message: ServerMessage<ID, T>) {
36 self.endpoint.send(message)
37 }
38
39 pub fn receive(&mut self) -> Result<ClientMessage<ID>, Option<ReceiveError>> {
40 self.endpoint.receive()
41 }
42}
43
44impl<ID, T> PlayerData<ID, T> {
45 pub(crate) fn init<R: Rng>(
46 self,
47 random: &mut R,
48 active: usize,
49 pokedex: &Dex<Pokemon>,
50 movedex: &Dex<Move>,
51 itemdex: &Dex<Item>,
52 ) -> BattlePlayer<ID, T> {
53 let pokemon: Party<HostPokemon> = self
54 .party
55 .into_iter()
56 .flat_map(|p| p.init(random, pokedex, movedex, itemdex))
57 .map(Into::into)
58 .collect();
59
60 let mut party = PlayerParty::new(self.id, self.name, active, pokemon, self.trainer);
61
62 for index in party.active.iter().flatten().map(ActivePokemon::index) {
63 if let Some(pokemon) = party.pokemon.get_mut(index) {
64 pokemon.known = true;
65 }
66 }
67
68 let bag = self.bag.init(itemdex).unwrap_or_default();
69
70 BattlePlayer {
71 party,
72 bag,
73 settings: self.settings,
74 endpoint: self.endpoint,
75 }
76 }
77}
78
79impl<ID: Clone, T: Clone> ClientPlayerData<ID, T> {
80 pub fn new<'a, ITER: Iterator<Item = Ref<'a, BattlePlayer<ID, T>>>>(
81 data: BattleData,
82 player: &BattlePlayer<ID, T>,
83 others: ITER,
84 ) -> Self
85 where
86 ID: 'a,
87 T: 'a,
88 {
89 Self {
90 local: PlayerParty {
91 id: player.party.id().clone(),
92 name: player.party.name.clone(),
93 active: ActiveBattlePokemon::as_usize(&player.party.active),
94 pokemon: player
95 .party
96 .pokemon
97 .iter()
98 .map(|p| &p.p.p)
99 .cloned()
100 .map(|pokemon| pokemon.uninit())
101 .collect(),
102 trainer: player.party.trainer.clone(),
103 },
104 data,
105 remotes: others.map(|player| player.party.as_remote()).collect(),
106 bag: player.bag.clone().uninit(),
107 }
108 }
109}