poke_data/models/species/
evolution.rs1use 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}