gw2lib_model/
items.rs

1pub mod itemstats;
2pub mod recipes;
3pub mod skins;
4
5use std::collections::BTreeSet;
6
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    game_mechanics::skills::SkillId,
11    guild::upgrades::GuildUpgradeId,
12    items::{itemstats::StatsId, recipes::RecipeId, skins::SkinId},
13    misc::{colors::ColorId, minis::MiniPetId},
14    BulkEndpoint, Endpoint, EndpointWithId,
15};
16
17pub type ItemId = u32;
18
19#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
20#[cfg_attr(test, serde(deny_unknown_fields))]
21pub enum ItemType {
22    Armor,
23    Back,
24    Bag,
25    Consumable,
26    Container,
27    CraftingMaterial,
28    Gathering,
29    Gizmo,
30    MiniPet,
31    Tool,
32    Trait,
33    Trinket,
34    Trophy,
35    UpgradeComponent,
36    Weapon,
37    Key,
38    PowerCore,
39    JadeTechModule,
40    Relic,
41}
42
43#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
44#[cfg_attr(test, serde(deny_unknown_fields))]
45pub enum Rarity {
46    Junk,
47    Basic,
48    Fine,
49    Masterwork,
50    Rare,
51    Exotic,
52    Ascended,
53    Legendary,
54}
55
56#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
57#[cfg_attr(test, serde(deny_unknown_fields))]
58pub enum Flags {
59    AccountBindOnUse,
60    AccountBound,
61    Attuned,
62    BulkConsume,
63    DeleteWarning,
64    HideSuffix,
65    Infused,
66    MonsterOnly,
67    NoMysticForge,
68    NoSalvage,
69    NoSell,
70    NotUpgradeable,
71    NoUnderwater,
72    SoulbindOnAcquire,
73    SoulBindOnUse,
74    Tonic,
75    Unique,
76}
77
78#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
79#[cfg_attr(test, serde(deny_unknown_fields))]
80pub enum GameTypes {
81    Activity,
82    Dungeon,
83    Pve,
84    Pvp,
85    PvpLobby,
86    Wvw,
87}
88
89#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
90#[cfg_attr(test, serde(deny_unknown_fields))]
91pub enum Restrictions {
92    Asura,
93    Charr,
94    Human,
95    Norn,
96    Sylvari,
97    Elementalist,
98    Engineer,
99    Guardian,
100    Mesmer,
101    Necromancer,
102    Ranger,
103    Thief,
104    Warrior,
105    Female,
106    Revenant,
107}
108
109#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
110#[cfg_attr(test, serde(deny_unknown_fields))]
111pub enum ArmorSlot {
112    Boots,
113    Coat,
114    Gloves,
115    Helm,
116    HelmAquatic,
117    Leggings,
118    Shoulders,
119}
120
121#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
122#[cfg_attr(test, serde(deny_unknown_fields))]
123pub enum WeightClass {
124    Heavy,
125    Medium,
126    Light,
127    Clothing,
128}
129
130#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
131#[cfg_attr(test, serde(deny_unknown_fields))]
132pub enum InfusionType {
133    Enrichment,
134    Infusion,
135}
136
137#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
138#[cfg_attr(test, serde(deny_unknown_fields))]
139pub struct InfusionSlot {
140    pub flags: BTreeSet<InfusionType>,
141    pub item_id: Option<ItemId>,
142}
143
144#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize, Ord, Eq, Hash)]
145#[cfg_attr(test, serde(deny_unknown_fields))]
146pub enum AttributeType {
147    AgonyResistance,
148    BoonDuration,
149    ConditionDamage,
150    ConditionDuration,
151    CritDamage,
152    Healing,
153    Power,
154    Precision,
155    Toughness,
156    Vitality,
157}
158
159#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
160#[cfg_attr(test, serde(deny_unknown_fields))]
161pub struct Attribute {
162    pub attribute: AttributeType,
163    pub modifier: u16,
164}
165
166#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
167#[cfg_attr(test, serde(deny_unknown_fields))]
168pub struct Buff {
169    pub skill_id: SkillId,
170    pub description: Option<String>,
171}
172
173#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
174#[cfg_attr(test, serde(deny_unknown_fields))]
175pub struct InfixUpgrade {
176    pub id: StatsId,
177    pub attributes: Vec<Attribute>,
178    pub buff: Option<Buff>,
179}
180
181#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
182#[cfg_attr(test, serde(deny_unknown_fields))]
183pub struct Upgrades {
184    pub attribute_adjustment: f32,
185    pub infusion_slots: Vec<InfusionSlot>,
186    pub infix_upgrade: Option<InfixUpgrade>,
187    pub suffix_item_id: Option<ItemId>,
188    pub secondary_suffix_item_id: Option<ItemId>,
189    pub stat_choices: Option<Vec<StatsId>>,
190}
191
192#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
193#[cfg_attr(test, serde(deny_unknown_fields))]
194pub struct ArmorDetails {
195    #[serde(rename = "type")]
196    pub _type: ArmorSlot,
197    pub weight_class: WeightClass,
198    pub defense: u16,
199    #[serde(flatten)]
200    pub upgrades: Upgrades,
201}
202
203#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
204#[cfg_attr(test, serde(deny_unknown_fields))]
205pub struct BackItemDetails {
206    #[serde(flatten)]
207    pub upgrades: Upgrades,
208}
209
210#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
211#[cfg_attr(test, serde(deny_unknown_fields))]
212pub struct BagDetails {
213    pub size: u8,
214    pub no_sell_or_sort: bool,
215}
216
217#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
218#[cfg_attr(test, serde(deny_unknown_fields))]
219pub enum ConsumableType {
220    AppearanceChange,
221    Booze,
222    ContractNpc,
223    Currency,
224    Food,
225    Generic,
226    Halloween,
227    Immediate,
228    MountRandomUnlock,
229    RandomUnlock,
230    Transmutation,
231    Unlock,
232    UpgradeRemoval,
233    Utility,
234    TeleportToFriend,
235}
236
237#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
238#[cfg_attr(test, serde(deny_unknown_fields))]
239pub enum UnlockType {
240    BagSlot,
241    BankTab,
242    Champion,
243    CollectibleCapacity,
244    Content,
245    CraftingRecipe,
246    Dye,
247    JadeBotSkin,
248    GliderSkin,
249    GearLoadoutTab,
250    BuildLibrarySlot,
251    BuildLoadoutTab,
252    MagicDoorSkin,
253    Minipet,
254    Ms,
255    Outfit,
256    RandomUnlock,
257    SharedSlot,
258}
259
260#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
261#[cfg_attr(test, serde(deny_unknown_fields))]
262pub struct ConsumableDetails {
263    #[serde(rename = "type")]
264    pub _type: ConsumableType,
265    pub description: Option<String>,
266    pub duration_ms: Option<u64>,
267    pub unlock_type: Option<UnlockType>,
268    pub color_id: Option<ColorId>,
269    pub recipe_id: Option<RecipeId>,
270    pub extra_recipe_ids: Option<Vec<RecipeId>>,
271    pub guild_upgrade_id: Option<GuildUpgradeId>,
272    pub apply_count: Option<u8>,
273    pub name: Option<String>,
274    pub icon: Option<String>,
275    pub skins: Option<Vec<u64>>,
276}
277
278#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
279#[cfg_attr(test, serde(deny_unknown_fields))]
280pub enum ContainerType {
281    Default,
282    GiftBox,
283    Immediate,
284    OpenUI,
285}
286
287#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
288#[cfg_attr(test, serde(deny_unknown_fields))]
289pub struct ContainerDetails {
290    #[serde(rename = "type")]
291    pub _type: ContainerType,
292}
293
294#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
295#[cfg_attr(test, serde(deny_unknown_fields))]
296pub enum GatheringToolsType {
297    Foraging,
298    Logging,
299    Mining,
300    Lure,
301    Bait,
302    Fishing,
303}
304
305#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
306#[cfg_attr(test, serde(deny_unknown_fields))]
307pub struct GatheringToolsDetails {
308    #[serde(rename = "type")]
309    pub _type: GatheringToolsType,
310}
311
312#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
313#[cfg_attr(test, serde(deny_unknown_fields))]
314pub enum GizmoType {
315    Default,
316    ContainerKey,
317    RentableContractNpc,
318    UnlimitedConsumable,
319}
320
321#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
322#[cfg_attr(test, serde(deny_unknown_fields))]
323pub struct GizmoDetails {
324    #[serde(rename = "type")]
325    pub _type: GizmoType,
326    pub guild_upgrade_id: Option<GuildUpgradeId>,
327    pub vendor_ids: Option<Vec<u64>>, // TODO: figure out if this is resolvable
328}
329
330#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
331#[cfg_attr(test, serde(deny_unknown_fields))]
332pub struct MiniatureDetails {
333    pub minipet_id: MiniPetId,
334}
335
336#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
337#[cfg_attr(test, serde(deny_unknown_fields))]
338pub enum SalvageKitType {
339    Salvage,
340}
341
342#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
343#[cfg_attr(test, serde(deny_unknown_fields))]
344pub struct SalvageKitDetails {
345    #[serde(rename = "type")]
346    pub _type: SalvageKitType,
347    pub charges: u8,
348}
349
350#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
351#[cfg_attr(test, serde(deny_unknown_fields))]
352pub enum TrinketType {
353    Accessory,
354    Amulet,
355    Ring,
356}
357
358#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
359#[cfg_attr(test, serde(deny_unknown_fields))]
360pub struct TrinketDetails {
361    #[serde(rename = "type")]
362    pub _type: TrinketType,
363    #[serde(flatten)]
364    pub upgrades: Upgrades,
365}
366
367#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
368#[cfg_attr(test, serde(deny_unknown_fields))]
369pub enum UpgradeComponentType {
370    Default,
371    Gem,
372    Rune,
373    Sigil,
374}
375
376#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
377#[cfg_attr(test, serde(deny_unknown_fields))]
378pub enum UpgradeComponentFlags {
379    Axe,
380    Dagger,
381    Focus,
382    Greatsword,
383    Hammer,
384    #[serde(rename = "Harpoon")]
385    Spear,
386    #[serde(alias = "Longbow")]
387    LongBow,
388    Mace,
389    Pistol,
390    Rifle,
391    Scepter,
392    Shield,
393    #[serde(alias = "Shortbow")]
394    ShortBow,
395    #[serde(rename = "Speargun")]
396    HarpoonGun,
397    Staff,
398    Sword,
399    Torch,
400    Trident,
401    Warhorn,
402    HeavyArmor,
403    MediumArmor,
404    LightArmor,
405    Trinket,
406}
407
408#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
409#[cfg_attr(test, serde(deny_unknown_fields))]
410pub enum InfusionUpgradeFlags {
411    Enrichment,
412    Infusion,
413    Defense,
414    Offense,
415    Utility,
416    Agony,
417}
418
419#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
420#[cfg_attr(test, serde(deny_unknown_fields))]
421pub struct UpgradeComponentDetails {
422    #[serde(rename = "type")]
423    pub _type: UpgradeComponentType,
424    pub flags: BTreeSet<UpgradeComponentFlags>,
425    pub infusion_upgrade_flags: BTreeSet<InfusionUpgradeFlags>,
426    pub suffix: String,
427    pub attribute_adjustment: f32,
428    pub infix_upgrade: InfixUpgrade,
429    pub bonuses: Option<Vec<String>>,
430}
431
432#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
433#[cfg_attr(test, serde(deny_unknown_fields))]
434pub enum WeaponType {
435    Axe,
436    Dagger,
437    Mace,
438    Pistol,
439    Scepter,
440    Sword,
441    Focus,
442    Shield,
443    Torch,
444    Warhorn,
445    Greatsword,
446    Hammer,
447    #[serde(alias = "Longbow")]
448    LongBow,
449    Rifle,
450    #[serde(alias = "Shortbow")]
451    ShortBow,
452    Staff,
453    #[serde(rename = "Harpoon", alias = "Spear")]
454    Spear,
455    #[serde(rename = "Speargun")]
456    HarpoonGun,
457    Trident,
458    LargeBundle,
459    SmallBundle,
460    Toy,
461    ToyTwoHanded,
462    None,
463}
464
465#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
466#[cfg_attr(test, serde(deny_unknown_fields))]
467pub enum DamageType {
468    Fire,
469    Ice,
470    Lightning,
471    Physical,
472    Choking,
473}
474
475#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
476#[cfg_attr(test, serde(deny_unknown_fields))]
477pub struct WeaponDetails {
478    #[serde(rename = "type")]
479    pub _type: WeaponType,
480    pub damage_type: DamageType,
481    pub min_power: u16,
482    pub max_power: u16,
483    pub defense: u16,
484    #[serde(flatten)]
485    pub upgrades: Upgrades,
486}
487
488#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
489#[serde(tag = "type", content = "details")]
490#[cfg_attr(test, serde(deny_unknown_fields))]
491pub enum Details {
492    Armor(ArmorDetails),
493    Back(BackItemDetails),
494    Bag(BagDetails),
495    Consumable(ConsumableDetails),
496    Container(ContainerDetails),
497    Gathering(GatheringToolsDetails),
498    Gizmo(GizmoDetails),
499    MiniPet(MiniatureDetails),
500    Tool(SalvageKitDetails),
501    Trinket(TrinketDetails),
502    UpgradeComponent(UpgradeComponentDetails),
503    Weapon(WeaponDetails),
504    CraftingMaterial,
505    Trophy,
506    Key,
507    PowerCore,
508    JadeTechModule,
509    Relic,
510}
511
512impl From<Details> for ItemType {
513    fn from(d: Details) -> Self {
514        match d {
515            Details::Armor(_) => ItemType::Armor,
516            Details::Back(_) => ItemType::Back,
517            Details::Bag(_) => ItemType::Bag,
518            Details::Consumable(_) => ItemType::Consumable,
519            Details::Container(_) => ItemType::Container,
520            Details::Gathering(_) => ItemType::Gathering,
521            Details::Gizmo(_) => ItemType::Gizmo,
522            Details::MiniPet(_) => ItemType::MiniPet,
523            Details::Tool(_) => ItemType::Tool,
524            Details::Trinket(_) => ItemType::Trinket,
525            Details::UpgradeComponent(_) => ItemType::UpgradeComponent,
526            Details::Weapon(_) => ItemType::Weapon,
527            Details::CraftingMaterial => ItemType::CraftingMaterial,
528            Details::Trophy => ItemType::Trophy,
529            Details::Key => ItemType::Key,
530            Details::PowerCore => ItemType::PowerCore,
531            Details::JadeTechModule => ItemType::JadeTechModule,
532            Details::Relic => ItemType::Relic,
533        }
534    }
535}
536
537#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
538#[cfg_attr(test, serde(deny_unknown_fields))]
539pub struct Item {
540    pub id: ItemId,
541    pub chat_link: String,
542    pub name: String,
543    pub icon: Option<String>,
544    pub description: Option<String>,
545    pub rarity: Rarity,
546    pub level: u8,
547    pub vendor_value: u64,
548    pub default_skin: Option<SkinId>,
549    pub flags: BTreeSet<Flags>,
550    pub game_types: BTreeSet<GameTypes>,
551    pub restrictions: BTreeSet<Restrictions>,
552    #[serde(flatten)]
553    pub details: Details,
554}
555
556impl EndpointWithId for Item {
557    type IdType = ItemId;
558}
559
560impl Endpoint for Item {
561    const AUTHENTICATED: bool = false;
562    const LOCALE: bool = true;
563    const URL: &'static str = "v2/items";
564    const VERSION: &'static str = "2022-07-22T00:00:00.000Z";
565}
566
567impl BulkEndpoint for Item {
568    const ALL: bool = false;
569
570    fn id(&self) -> &Self::IdType {
571        &self.id
572    }
573}