firecore_battle/host/
player.rs

1use 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}