poke_data/models/
item.rs

1use crate::data::link_context::LinkContext;
2use crate::data::linkable::Linkable;
3use crate::models::flavor_texts::FlavorTexts;
4use crate::models::generation::GenerationId;
5use crate::models::item_category::{ItemCategory, ItemCategoryId};
6use crate::models::item_flag::{ItemFlag, ItemFlagId};
7use crate::models::item_fling_effect::{ItemFlingEffect, ItemFlingEffectId};
8use crate::models::localized_effects::LocalizedEffects;
9use crate::models::localized_names::LocalizedStrings;
10use crate::traits::has_identifier::HasIdentifier;
11use crate::traits::has_localized_names::HasLocalizedNames;
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14use std::sync::Arc;
15
16pub type ItemId = u16;
17
18#[derive(Debug)]
19pub struct Item {
20    pub id: ItemId,
21    pub identifier: String,
22    pub names: LocalizedStrings,
23    pub flavor_texts: FlavorTexts,
24    pub effects: LocalizedEffects,
25    pub category: Arc<ItemCategory>,
26    pub cost: u32,
27    pub fling_power: Option<u8>,
28    pub fling_effect: Option<Arc<ItemFlingEffect>>,
29    pub flags: Vec<Arc<ItemFlag>>,
30    pub game_indices: ItemGameIndices,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct ItemGameIndices(HashMap<GenerationId, u16>);
35
36impl ItemGameIndices {
37    pub fn new(indices: HashMap<GenerationId, u16>) -> Self {
38        Self(indices)
39    }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct UnlinkedItem {
44    pub id: ItemId,
45    pub identifier: String,
46    pub names: LocalizedStrings,
47    pub flavor_texts: FlavorTexts,
48    pub effects: LocalizedEffects,
49    pub category_id: ItemCategoryId,
50    pub cost: u32,
51    pub fling_power: Option<u8>,
52    pub fling_effect_id: Option<ItemFlingEffectId>,
53    pub flag_ids: Vec<ItemFlagId>,
54    pub game_indices: ItemGameIndices,
55}
56
57impl Linkable for UnlinkedItem {
58    type Linked = Arc<Item>;
59
60    fn link(&self, context: &LinkContext) -> Self::Linked {
61        let category = context
62            .item_categories
63            .get(&self.category_id)
64            .unwrap_or_else(|| {
65                panic!(
66                    "No item category '{}' found for item '{}'",
67                    self.category_id, self.id
68                )
69            })
70            .clone();
71
72        let fling_effect = self.fling_effect_id.map(|effect_id| {
73            context
74                .item_fling_effects
75                .get(&effect_id)
76                .unwrap_or_else(|| {
77                    panic!(
78                        "No item fling effect '{}' found for item '{}'",
79                        effect_id, self.id
80                    )
81                })
82                .clone()
83        });
84
85        let flags = self
86            .flag_ids
87            .iter()
88            .map(|flag_id| {
89                context
90                    .item_flags
91                    .get(flag_id)
92                    .unwrap_or_else(|| {
93                        panic!("No item flag '{}' found for item '{}'", flag_id, self.id)
94                    })
95                    .clone()
96            })
97            .collect();
98
99        let item = Item {
100            id: self.id,
101            identifier: self.identifier.clone(),
102            names: self.names.clone(),
103            flavor_texts: self.flavor_texts.clone(),
104            effects: self.effects.clone(),
105            category,
106            cost: self.cost,
107            fling_power: self.fling_power,
108            fling_effect,
109            flags,
110            game_indices: self.game_indices.clone(),
111        };
112
113        Arc::new(item)
114    }
115}
116
117impl HasLocalizedNames for Item {
118    fn localized_names(&self) -> &LocalizedStrings {
119        &self.names
120    }
121}
122
123impl HasIdentifier for Item {
124    fn identifier(&self) -> &str {
125        &self.identifier
126    }
127}