poke_data/models/species/
evolution.rs

1use crate::data::link_context::LinkContext;
2use crate::data::linkable::Linkable;
3use crate::models::evolution_trigger::{EvolutionTrigger, EvolutionTriggerId};
4use crate::models::item::{Item, ItemId};
5use crate::models::location::{Location, LocationId};
6use crate::models::pokemon_move::{PokemonMove, PokemonMoveId};
7use crate::models::species::SpeciesId;
8use crate::types::gender::Gender;
9use crate::types::pokemon_type::Type;
10use crate::types::time_of_day::TimeOfDay;
11use serde::{Deserialize, Serialize};
12use std::sync::Arc;
13
14#[derive(Debug)]
15pub struct Evolution {
16    pub evolves_into_species_id: SpeciesId,
17    pub trigger: Arc<EvolutionTrigger>,
18    pub trigger_item: Option<Arc<Item>>,
19    pub minimum_level: Option<u8>,
20    pub gender: Option<Gender>,
21    pub location: Option<Arc<Location>>,
22    pub held_item: Option<Arc<Item>>,
23    pub time_of_day: Option<TimeOfDay>,
24    pub known_move: Option<Arc<PokemonMove>>,
25    pub known_move_type: Option<Type>,
26    pub min_happiness: Option<u8>,
27    pub min_beauty: Option<u8>,
28    pub min_affection: Option<u8>,
29    pub relative_physical_stats: Option<i8>,
30    pub party_species_id: Option<SpeciesId>,
31    pub party_type: Option<Type>,
32    pub trade_species_id: Option<SpeciesId>,
33    pub needs_overworld_rain: Option<bool>,
34    pub turn_upside_down: Option<bool>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct UnlinkedEvolution {
39    pub evolves_into_species_id: SpeciesId,
40    pub trigger_id: EvolutionTriggerId,
41    pub trigger_item_id: Option<ItemId>,
42    pub minimum_level: Option<u8>,
43    pub gender: Option<Gender>,
44    pub location_id: Option<LocationId>,
45    pub held_item_id: Option<ItemId>,
46    pub time_of_day: Option<TimeOfDay>,
47    pub known_move_id: Option<PokemonMoveId>,
48    pub known_move_type: Option<Type>,
49    pub min_happiness: Option<u8>,
50    pub min_beauty: Option<u8>,
51    pub min_affection: Option<u8>,
52    pub relative_physical_stats: Option<i8>,
53    pub party_species_id: Option<SpeciesId>,
54    pub party_type: Option<Type>,
55    pub trade_species_id: Option<SpeciesId>,
56    pub needs_overworld_rain: Option<bool>,
57    pub turn_upside_down: Option<bool>,
58}
59
60impl Linkable for UnlinkedEvolution {
61    type Linked = Evolution;
62
63    fn link(&self, context: &LinkContext) -> Self::Linked {
64        let trigger = context
65            .evolution_triggers
66            .get(&self.trigger_id)
67            .unwrap_or_else(|| {
68                panic!(
69                    "No evolution trigger '{}' found for evolution",
70                    self.trigger_id
71                )
72            })
73            .clone();
74
75        let trigger_item = self.trigger_item_id.map(|item_id| {
76            context
77                .items
78                .get(&item_id)
79                .unwrap_or_else(|| panic!("No trigger item '{}' found for evolution", item_id))
80                .clone()
81        });
82
83        let location = self.location_id.map(|location_id| {
84            context
85                .locations
86                .get(&location_id)
87                .unwrap_or_else(|| panic!("No location '{}' found for evolution", location_id))
88                .clone()
89        });
90
91        let held_item = self.held_item_id.map(|item_id| {
92            context
93                .items
94                .get(&item_id)
95                .unwrap_or_else(|| panic!("No held item '{}' found for evolution", item_id))
96                .clone()
97        });
98
99        let known_move = self.known_move_id.map(|move_id| {
100            context
101                .moves
102                .get(&move_id)
103                .unwrap_or_else(|| panic!("No known move '{}' found for evolution", move_id))
104                .clone()
105        });
106
107        Evolution {
108            evolves_into_species_id: self.evolves_into_species_id,
109            trigger,
110            trigger_item,
111            minimum_level: self.minimum_level,
112            gender: self.gender,
113            location,
114            held_item,
115            time_of_day: self.time_of_day,
116            known_move,
117            known_move_type: self.known_move_type,
118            min_happiness: self.min_happiness,
119            min_beauty: self.min_beauty,
120            min_affection: self.min_affection,
121            relative_physical_stats: self.relative_physical_stats,
122            party_species_id: self.party_species_id,
123            party_type: self.party_type,
124            trade_species_id: self.trade_species_id,
125            needs_overworld_rain: self.needs_overworld_rain,
126            turn_upside_down: self.turn_upside_down,
127        }
128    }
129}