1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! Item details which are specific to a particular kind of an item.

use std::iter;
use std::time::Duration;

use super::experience::Experience;
use super::mods::Mod;


/// Details of the particular items, if known.
#[derive(Debug)]
pub enum ItemDetails {
    // TODO: consider extracting struct types for Map, Gem, Gear

    /// An unidentified item. No details available.
    Unidentified,
    /// Map item.
    Map {
        /// Map tier.
        tier: u32,
        /// Percentage bonus to the quantity of items dropped by this map.
        item_quantity: i32,
        /// Percentage bonus to the rarity of items dropped by this map.
        item_rarity: i32,
        /// Percentage bonus to the size of monster packs in this map.
        monster_pack_size: i32,
        /// Mods this map has.
        ///
        /// These are the mods which affect map difficulty
        /// as well as quantity and rarity of items dropped.
        mods: Vec<Mod>,
    },
    /// Skill gem.
    Gem {
        /// Current level of the gem.
        ///
        /// Gems start at level 1.
        /// Standalone gems (not in gear) currently shouldn't have levels above 21
        /// (at least outside of glitches/bugs).
        level: u32,
        /// The amount of experience a gem has and requires for the next level.
        experience: Experience,
    },
    /// Flask item.
    Flask {
        /// Duration of the flask effect.
        duration: Duration,
        /// How many charges are consumed on use.
        charges_per_use: u32,
        // TODO: max_charges (which comes from "Consumes %0 of %0 Charges on use"
        // and requires support for multi-value Properties)

        /// Utility mods of the flask.
        ///
        /// These are typically the on-use effect (like bleed/freeze/etc. removal),
        /// mods affecting charges, etc.
        mods: Vec<Mod>,
    },
    /// Item that goes in a gear slot.
    ///
    /// This also includes jewels that go in the passive tree or into abyssal sockets.
    Gear {
        /// Implicit mods an item has
        /// (those displayed in navy color above a horizontal line in the UI).
        ///
        /// Currently, PoE only supports a single implicit mod,
        /// but this may change in the future.
        implicit: Vec<Mod>,

        /// Enchantments an item has
        /// (i.e. mods displayed in light blue color above a horizontal line in the UI).
        ///
        /// Currently, PoE only supports a single enchantment,
        /// but this may change in the future.
        enchants: Vec<Mod>,

        /// Explicit mods of an item
        /// (those displayed in navy color in the main item pane).
        ///
        /// Note that these the mods which are visible in the UI,
        /// as opposed to *affixes* (prefixes & suffixes) which cannot be reliably
        /// extrapolated from mods.
        /// The practical consequence is that there may be more than 6 mods
        /// which would seemingly contradict the "3 prefixes + 3 suffixes" rule
        /// (due to the so-called hybrid affixes that result in multiple mods).
        explicit: Vec<Mod>,

        /// Crafted mods on an item
        /// (those displayed in light blue color in the main item pane, below explicit mods).
        crafted: Vec<Mod>,
    },
}

impl ItemDetails {
    /// Whether the item has been identified.
    #[inline]
    pub fn is_identified(&self) -> bool {
        match *self {
            ItemDetails::Unidentified => false,
            _ => true,
        }
    }

    /// All mods that the item has, if any,
    /// in the top-down order with respect to the in-game UI.
    pub fn mods<'m>(&'m self) -> Box<Iterator<Item=&'m Mod> + 'm> {
        match *self {
            ItemDetails::Map{ ref mods, .. } |
            ItemDetails::Flask{ ref mods, .. } => Box::new(mods.iter()),
            ItemDetails::Gear{
                ref implicit, ref enchants, ref explicit, ref crafted,
            } => Box::new(
                implicit.iter()
                    .chain(enchants.iter())
                    .chain(explicit.iter())
                    .chain(crafted.iter())
            ),
            _ => Box::new(iter::empty()),
        }
    }
}