veloren/common/src/comp/inventory/item.rs

211 lines
6.5 KiB
Rust

use crate::{
assets::{self, Asset},
comp::CharacterAbility,
effect::Effect,
terrain::{Block, BlockKind},
};
//use rand::prelude::*;
use rand::seq::SliceRandom;
use specs::{Component, FlaggedStorage};
use specs_idvs::IDVStorage;
use std::{fs::File, io::BufReader, time::Duration, vec::Vec};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum SwordKind {
Scimitar,
Rapier,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ToolKind {
Sword(SwordKind),
Axe,
Hammer,
Bow,
Dagger,
Staff,
Shield,
Debug(DebugKind),
}
impl ToolData {
pub fn equip_time(&self) -> Duration { Duration::from_millis(self.equip_time_millis) }
pub fn get_abilities(&self) -> Vec<CharacterAbility> {
use CharacterAbility::*;
use DebugKind::*;
use ToolKind::*;
match self.kind {
Sword(_) => vec![TimedCombo {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(1000),
tool: *self,
}],
Axe => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Hammer => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Bow => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Dagger => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Staff => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Shield => vec![BasicAttack {
buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(500),
}],
Debug(kind) => match kind {
Boost => vec![],
Possess => vec![],
},
_ => vec![],
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DebugKind {
Boost,
Possess,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Armor {
// TODO: Don't make armor be a body part. Wearing enemy's head is funny but also a creepy
// thing to do.
Helmet,
Shoulders,
Chestplate,
Belt,
Gloves,
Pants,
Boots,
Back,
Tabard,
Gem,
Necklace,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Consumable {
Apple,
Cheese,
Potion,
Mushroom,
Velorite,
VeloriteFrag,
PotionMinor,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Utility {
Collar,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Ingredient {
Flower,
Grass,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ToolData {
pub kind: ToolKind,
equip_time_millis: u64,
attack_buildup_millis: u64,
attack_recover_millis: u64,
range: u32,
pub base_damage: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ItemKind {
Tool(ToolData),
Armor { kind: Armor, power: u32 },
Consumable { kind: Consumable, effect: Effect },
Utility { kind: Utility },
Ingredient(Ingredient),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Item {
name: String,
description: String,
pub kind: ItemKind,
}
impl Asset for Item {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
Ok(ron::de::from_reader(buf_reader).unwrap())
}
}
impl Item {
pub fn name(&self) -> &str { &self.name }
pub fn description(&self) -> &str { &self.description }
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
match block.kind() {
BlockKind::Apple => Some(assets::load_expect_cloned("common.items.apple")),
BlockKind::Mushroom => Some(assets::load_expect_cloned("common.items.mushroom")),
BlockKind::Velorite => Some(assets::load_expect_cloned("common.items.velorite")),
BlockKind::BlueFlower => Some(assets::load_expect_cloned("common.items.flowers.blue")),
BlockKind::PinkFlower => Some(assets::load_expect_cloned("common.items.flowers.pink")),
BlockKind::PurpleFlower => {
Some(assets::load_expect_cloned("common.items.flowers.purple"))
},
BlockKind::RedFlower => Some(assets::load_expect_cloned("common.items.flowers.red")),
BlockKind::WhiteFlower => {
Some(assets::load_expect_cloned("common.items.flowers.white"))
},
BlockKind::YellowFlower => {
Some(assets::load_expect_cloned("common.items.flowers.yellow"))
},
BlockKind::Sunflower => Some(assets::load_expect_cloned("common.items.flowers.sun")),
BlockKind::LongGrass => Some(assets::load_expect_cloned("common.items.grasses.long")),
BlockKind::MediumGrass => {
Some(assets::load_expect_cloned("common.items.grasses.medium"))
},
BlockKind::ShortGrass => Some(assets::load_expect_cloned("common.items.grasses.short")),
BlockKind::Chest => Some(assets::load_expect_cloned(
[
"common.items.apple",
"common.items.velorite",
"common.items.veloritefrag",
"common.items.cheese",
"common.items.potion_minor",
"common.items.collar",
"common.items.weapons.starter_sword",
"common.items.weapons.starter_axe",
"common.items.weapons.starter_hammer",
"common.items.weapons.starter_bow",
"common.items.weapons.starter_staff",
]
.choose(&mut rand::thread_rng())
.unwrap(), // Can't fail
)),
_ => None,
}
}
}
impl Component for Item {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
}