2019-09-25 15:52:58 +00:00
|
|
|
use crate::{
|
2019-10-22 18:18:40 +00:00
|
|
|
assets::{self, Asset},
|
2020-03-16 11:32:57 +00:00
|
|
|
comp::{
|
|
|
|
body::{humanoid, object},
|
|
|
|
projectile, Body, CharacterAbility, HealthChange, HealthSource, Projectile,
|
|
|
|
},
|
2019-09-25 15:52:58 +00:00
|
|
|
effect::Effect,
|
|
|
|
terrain::{Block, BlockKind},
|
|
|
|
};
|
2020-01-26 22:57:06 +00:00
|
|
|
use rand::seq::SliceRandom;
|
2019-07-26 21:01:41 +00:00
|
|
|
use specs::{Component, FlaggedStorage};
|
2019-07-29 19:54:48 +00:00
|
|
|
use specs_idvs::IDVStorage;
|
2020-03-12 14:47:27 +00:00
|
|
|
use std::{fs::File, io::BufReader, time::Duration, vec::Vec};
|
2019-05-18 16:46:14 +00:00
|
|
|
|
2019-08-27 19:56:46 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-12-29 23:47:42 +00:00
|
|
|
pub enum SwordKind {
|
2020-03-18 20:05:20 +00:00
|
|
|
BasicSword,
|
2019-12-29 23:47:42 +00:00
|
|
|
Rapier,
|
2020-03-18 20:05:20 +00:00
|
|
|
Zweihander0,
|
|
|
|
WoodTraining,
|
2020-03-18 22:09:58 +00:00
|
|
|
Short0,
|
2019-12-29 23:47:42 +00:00
|
|
|
}
|
2020-03-17 17:27:52 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum AxeKind {
|
|
|
|
BasicAxe,
|
|
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum HammerKind {
|
|
|
|
BasicHammer,
|
|
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum BowKind {
|
|
|
|
BasicBow,
|
|
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum DaggerKind {
|
|
|
|
BasicDagger,
|
|
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum StaffKind {
|
|
|
|
BasicStaff,
|
|
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum ShieldKind {
|
|
|
|
BasicShield,
|
|
|
|
}
|
2019-12-29 23:47:42 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum ToolKind {
|
|
|
|
Sword(SwordKind),
|
2020-03-17 17:27:52 +00:00
|
|
|
Axe(AxeKind),
|
|
|
|
Hammer(HammerKind),
|
|
|
|
Bow(BowKind),
|
|
|
|
Dagger(DaggerKind),
|
|
|
|
Staff(StaffKind),
|
|
|
|
Shield(ShieldKind),
|
2020-03-14 15:40:29 +00:00
|
|
|
Debug(DebugKind),
|
2020-03-16 13:27:52 +00:00
|
|
|
/// This is an placeholder item, it is used by non-humanoid npcs to attack
|
|
|
|
Empty,
|
2020-01-05 23:17:22 +00:00
|
|
|
}
|
|
|
|
|
2019-12-29 23:47:42 +00:00
|
|
|
impl ToolData {
|
2020-02-03 21:02:32 +00:00
|
|
|
pub fn equip_time(&self) -> Duration { Duration::from_millis(self.equip_time_millis) }
|
2020-02-01 20:39:39 +00:00
|
|
|
|
2020-03-14 15:40:29 +00:00
|
|
|
pub fn get_abilities(&self) -> Vec<CharacterAbility> {
|
|
|
|
use CharacterAbility::*;
|
|
|
|
use DebugKind::*;
|
2020-03-12 14:47:27 +00:00
|
|
|
use ToolKind::*;
|
|
|
|
|
|
|
|
match self.kind {
|
2020-03-16 15:34:53 +00:00
|
|
|
Sword(_) => vec![
|
2020-03-19 22:40:03 +00:00
|
|
|
// BasicMelee {
|
|
|
|
// buildup_duration: Duration::from_millis(100),
|
|
|
|
// recover_duration: Duration::from_millis(500),
|
|
|
|
// base_damage: 6,
|
|
|
|
// },
|
|
|
|
CharacterAbility::TripleStrike { base_damage: 7 },
|
2020-03-16 15:34:53 +00:00
|
|
|
DashMelee {
|
|
|
|
buildup_duration: Duration::from_millis(500),
|
|
|
|
recover_duration: Duration::from_millis(500),
|
2020-03-16 18:55:12 +00:00
|
|
|
base_damage: 20,
|
2020-03-16 15:34:53 +00:00
|
|
|
},
|
|
|
|
],
|
2020-03-17 17:27:52 +00:00
|
|
|
Axe(_) => vec![BasicMelee {
|
2020-03-15 13:34:17 +00:00
|
|
|
buildup_duration: Duration::from_millis(700),
|
|
|
|
recover_duration: Duration::from_millis(100),
|
2020-03-16 18:55:12 +00:00
|
|
|
base_damage: 8,
|
2020-03-14 15:40:29 +00:00
|
|
|
}],
|
2020-03-17 17:27:52 +00:00
|
|
|
Hammer(_) => vec![BasicMelee {
|
2020-03-15 13:34:17 +00:00
|
|
|
buildup_duration: Duration::from_millis(700),
|
|
|
|
recover_duration: Duration::from_millis(300),
|
2020-03-16 18:55:12 +00:00
|
|
|
base_damage: 10,
|
2020-03-14 15:40:29 +00:00
|
|
|
}],
|
2020-03-17 17:27:52 +00:00
|
|
|
Bow(_) => vec![BasicRanged {
|
2020-03-16 11:32:57 +00:00
|
|
|
projectile: Projectile {
|
|
|
|
hit_ground: vec![projectile::Effect::Stick],
|
|
|
|
hit_wall: vec![projectile::Effect::Stick],
|
|
|
|
hit_entity: vec![
|
|
|
|
projectile::Effect::Damage(HealthChange {
|
|
|
|
// TODO: This should not be fixed (?)
|
2020-03-17 13:15:39 +00:00
|
|
|
amount: -3,
|
2020-03-16 11:32:57 +00:00
|
|
|
cause: HealthSource::Item,
|
|
|
|
}),
|
|
|
|
projectile::Effect::Vanish,
|
|
|
|
],
|
|
|
|
time_left: Duration::from_secs(15),
|
|
|
|
owner: None,
|
|
|
|
},
|
|
|
|
projectile_body: Body::Object(object::Body::Arrow),
|
|
|
|
recover_duration: Duration::from_millis(300),
|
|
|
|
}],
|
2020-03-17 17:27:52 +00:00
|
|
|
Dagger(_) => vec![BasicMelee {
|
2020-03-15 13:34:17 +00:00
|
|
|
buildup_duration: Duration::from_millis(100),
|
|
|
|
recover_duration: Duration::from_millis(400),
|
2020-03-16 18:55:12 +00:00
|
|
|
base_damage: 5,
|
2020-03-14 15:40:29 +00:00
|
|
|
}],
|
2020-03-17 17:27:52 +00:00
|
|
|
Staff(_) => vec![BasicMelee {
|
2020-03-15 13:34:17 +00:00
|
|
|
buildup_duration: Duration::from_millis(400),
|
|
|
|
recover_duration: Duration::from_millis(300),
|
2020-03-16 18:55:12 +00:00
|
|
|
base_damage: 7,
|
2020-03-14 15:40:29 +00:00
|
|
|
}],
|
2020-03-17 17:27:52 +00:00
|
|
|
Shield(_) => vec![BasicBlock],
|
2020-03-14 15:40:29 +00:00
|
|
|
Debug(kind) => match kind {
|
2020-03-16 11:32:57 +00:00
|
|
|
DebugKind::Boost => vec![
|
|
|
|
CharacterAbility::Boost {
|
2020-03-19 16:01:58 +00:00
|
|
|
duration: Duration::from_millis(50),
|
2020-03-16 11:32:57 +00:00
|
|
|
only_up: false,
|
|
|
|
},
|
|
|
|
CharacterAbility::Boost {
|
2020-03-19 16:01:58 +00:00
|
|
|
duration: Duration::from_millis(50),
|
2020-03-16 11:32:57 +00:00
|
|
|
only_up: true,
|
|
|
|
},
|
|
|
|
],
|
2020-03-17 13:15:39 +00:00
|
|
|
Possess => vec![BasicRanged {
|
|
|
|
projectile: Projectile {
|
|
|
|
hit_ground: vec![projectile::Effect::Stick],
|
|
|
|
hit_wall: vec![projectile::Effect::Stick],
|
|
|
|
hit_entity: vec![projectile::Effect::Stick, projectile::Effect::Possess],
|
|
|
|
time_left: Duration::from_secs(10),
|
|
|
|
owner: None,
|
|
|
|
},
|
|
|
|
projectile_body: Body::Object(object::Body::ArrowSnake),
|
|
|
|
recover_duration: Duration::from_millis(300),
|
|
|
|
}],
|
2020-03-12 14:47:27 +00:00
|
|
|
},
|
2020-03-16 13:27:52 +00:00
|
|
|
Empty => vec![],
|
2020-03-12 14:47:27 +00:00
|
|
|
}
|
|
|
|
}
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
|
|
|
|
2019-10-22 20:58:27 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2020-03-14 15:40:29 +00:00
|
|
|
pub enum DebugKind {
|
2019-10-22 20:58:27 +00:00
|
|
|
Boost,
|
|
|
|
Possess,
|
2019-06-28 23:42:51 +00:00
|
|
|
}
|
2019-07-29 13:44:16 +00:00
|
|
|
|
2020-01-05 23:21:37 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-05-18 16:46:14 +00:00
|
|
|
pub enum Armor {
|
2020-02-26 17:04:43 +00:00
|
|
|
Shoulder(humanoid::Shoulder),
|
|
|
|
Chest(humanoid::Chest),
|
|
|
|
Belt(humanoid::Belt),
|
|
|
|
Hand(humanoid::Hand),
|
|
|
|
Pants(humanoid::Pants),
|
|
|
|
Foot(humanoid::Foot),
|
2019-05-18 16:46:14 +00:00
|
|
|
}
|
|
|
|
|
2020-02-26 17:04:43 +00:00
|
|
|
pub type ArmorStats = u32;
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-09-25 14:56:57 +00:00
|
|
|
pub enum Consumable {
|
|
|
|
Apple,
|
2019-11-09 13:42:42 +00:00
|
|
|
Cheese,
|
2019-09-25 14:56:57 +00:00
|
|
|
Potion,
|
|
|
|
Mushroom,
|
2019-09-25 20:22:39 +00:00
|
|
|
Velorite,
|
2019-10-17 20:59:36 +00:00
|
|
|
VeloriteFrag,
|
2019-11-09 13:42:42 +00:00
|
|
|
PotionMinor,
|
2019-09-25 14:56:57 +00:00
|
|
|
}
|
|
|
|
|
2020-02-03 21:02:32 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2020-01-29 12:01:28 +00:00
|
|
|
pub enum Utility {
|
|
|
|
Collar,
|
|
|
|
}
|
|
|
|
|
2020-01-05 23:21:37 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-09-25 22:04:18 +00:00
|
|
|
pub enum Ingredient {
|
|
|
|
Flower,
|
|
|
|
Grass,
|
|
|
|
}
|
|
|
|
|
2020-03-14 15:40:29 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-12-29 23:47:42 +00:00
|
|
|
pub struct ToolData {
|
|
|
|
pub kind: ToolKind,
|
|
|
|
equip_time_millis: u64,
|
2020-03-15 13:34:17 +00:00
|
|
|
// TODO: item specific abilities
|
2019-12-29 23:47:42 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 13:30:50 +00:00
|
|
|
fn default_amount() -> u32 { 1 }
|
|
|
|
|
2020-02-26 17:04:43 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
2019-10-22 18:18:40 +00:00
|
|
|
pub enum ItemKind {
|
2020-03-15 13:34:17 +00:00
|
|
|
/// Something wieldable
|
2019-12-29 23:47:42 +00:00
|
|
|
Tool(ToolData),
|
2020-03-15 13:34:17 +00:00
|
|
|
Armor {
|
|
|
|
kind: Armor,
|
2020-02-26 17:04:43 +00:00
|
|
|
stats: ArmorStats,
|
2020-03-15 13:34:17 +00:00
|
|
|
},
|
|
|
|
Consumable {
|
|
|
|
kind: Consumable,
|
|
|
|
effect: Effect,
|
2020-03-19 16:44:13 +00:00
|
|
|
#[serde(default = "default_amount")]
|
2020-03-19 13:30:50 +00:00
|
|
|
amount: u32,
|
2020-03-15 13:34:17 +00:00
|
|
|
},
|
|
|
|
Utility {
|
|
|
|
kind: Utility,
|
2020-03-19 16:44:13 +00:00
|
|
|
#[serde(default = "default_amount")]
|
2020-03-19 13:30:50 +00:00
|
|
|
amount: u32,
|
|
|
|
},
|
|
|
|
Ingredient {
|
|
|
|
kind: Ingredient,
|
2020-03-19 16:44:13 +00:00
|
|
|
#[serde(default = "default_amount")]
|
2020-03-19 13:30:50 +00:00
|
|
|
amount: u32,
|
2020-03-15 13:34:17 +00:00
|
|
|
},
|
2019-07-29 13:44:16 +00:00
|
|
|
}
|
|
|
|
|
2019-10-22 18:18:40 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub struct Item {
|
|
|
|
name: String,
|
|
|
|
description: String,
|
|
|
|
pub kind: ItemKind,
|
|
|
|
}
|
2019-10-09 19:28:05 +00:00
|
|
|
|
2019-10-22 18:18:40 +00:00
|
|
|
impl Asset for Item {
|
|
|
|
const ENDINGS: &'static [&'static str] = &["ron"];
|
2020-02-01 20:39:39 +00:00
|
|
|
|
2019-10-22 18:18:40 +00:00
|
|
|
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
|
|
|
Ok(ron::de::from_reader(buf_reader).unwrap())
|
2019-10-09 19:28:05 +00:00
|
|
|
}
|
2019-10-22 18:18:40 +00:00
|
|
|
}
|
2019-10-09 19:28:05 +00:00
|
|
|
|
2019-10-22 18:18:40 +00:00
|
|
|
impl Item {
|
2020-03-16 13:27:52 +00:00
|
|
|
pub fn empty() -> Self {
|
|
|
|
Self {
|
|
|
|
name: "Empty Item".to_owned(),
|
|
|
|
description: "This item may grant abilities, but is invisible".to_owned(),
|
|
|
|
kind: ItemKind::Tool(ToolData {
|
|
|
|
kind: ToolKind::Empty,
|
|
|
|
equip_time_millis: 0,
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn name(&self) -> &str { &self.name }
|
|
|
|
|
|
|
|
pub fn description(&self) -> &str { &self.description }
|
|
|
|
|
2019-09-25 14:56:57 +00:00
|
|
|
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
|
|
|
match block.kind() {
|
2019-10-22 18:18:40 +00:00
|
|
|
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"))
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
2019-10-22 18:18:40 +00:00
|
|
|
BlockKind::RedFlower => Some(assets::load_expect_cloned("common.items.flowers.red")),
|
|
|
|
BlockKind::WhiteFlower => {
|
|
|
|
Some(assets::load_expect_cloned("common.items.flowers.white"))
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
2019-10-22 18:18:40 +00:00
|
|
|
BlockKind::YellowFlower => {
|
|
|
|
Some(assets::load_expect_cloned("common.items.flowers.yellow"))
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
2019-10-22 18:18:40 +00:00
|
|
|
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"))
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
2019-10-22 18:18:40 +00:00
|
|
|
BlockKind::ShortGrass => Some(assets::load_expect_cloned("common.items.grasses.short")),
|
2020-01-26 22:57:06 +00:00
|
|
|
BlockKind::Chest => Some(assets::load_expect_cloned(
|
|
|
|
[
|
|
|
|
"common.items.apple",
|
|
|
|
"common.items.velorite",
|
|
|
|
"common.items.veloritefrag",
|
|
|
|
"common.items.cheese",
|
|
|
|
"common.items.potion_minor",
|
2020-01-29 12:01:28 +00:00
|
|
|
"common.items.collar",
|
2020-01-26 22:57:06 +00:00
|
|
|
"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",
|
2020-03-20 00:11:02 +00:00
|
|
|
"common.items.armor.belt.plate_0",
|
|
|
|
"common.items.armor.belt.leather_0",
|
|
|
|
"common.items.armor.chest.plate_green_0",
|
|
|
|
"common.items.armor.chest.leather_0",
|
|
|
|
"common.items.armor.foot.plate_0",
|
|
|
|
"common.items.armor.foot.leather_0",
|
|
|
|
"common.items.armor.pants.plate_green_0",
|
|
|
|
"common.items.armor.belt.leather_0",
|
|
|
|
"common.items.armor.shoulder.plate_0",
|
|
|
|
"common.items.armor.shoulder.leather_1",
|
|
|
|
"common.items.armor.shoulder.leather_0",
|
|
|
|
"common.items.weapons.wood_sword",
|
|
|
|
"common.items.weapons.short_sword_0",
|
2020-01-26 22:57:06 +00:00
|
|
|
]
|
|
|
|
.choose(&mut rand::thread_rng())
|
|
|
|
.unwrap(), // Can't fail
|
|
|
|
)),
|
2019-09-25 14:56:57 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2019-07-25 22:52:28 +00:00
|
|
|
}
|
|
|
|
|
2019-05-18 16:46:14 +00:00
|
|
|
impl Component for Item {
|
2019-07-26 21:01:41 +00:00
|
|
|
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
2019-05-18 16:46:14 +00:00
|
|
|
}
|