mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'timo-items-as-ron' into 'master'
feat: store items as RON files See merge request veloren/veloren!618
This commit is contained in:
commit
0ae15bb251
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3609,6 +3609,7 @@ dependencies = [
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
11
assets/common/items/apple.ron
Normal file
11
assets/common/items/apple.ron
Normal file
@ -0,0 +1,11 @@
|
||||
Item(
|
||||
name: "An apple",
|
||||
description: "Looks refreshing",
|
||||
kind: Consumable(
|
||||
kind: Apple,
|
||||
effect: Health((
|
||||
amount: 10,
|
||||
cause: Item,
|
||||
)),
|
||||
),
|
||||
)
|
8
assets/common/items/debug/boost.ron
Normal file
8
assets/common/items/debug/boost.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Boost rod",
|
||||
description: "Your legs feel full of energy while holding this",
|
||||
kind: Tool(
|
||||
kind: Debug(Boost),
|
||||
power: 0,
|
||||
),
|
||||
)
|
8
assets/common/items/debug/possess.ron
Normal file
8
assets/common/items/debug/possess.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Possession rod",
|
||||
description: "Your body seems loose while holding this",
|
||||
kind: Tool(
|
||||
kind: Debug(Possess),
|
||||
power: 0,
|
||||
),
|
||||
)
|
5
assets/common/items/flowers/blue.ron
Normal file
5
assets/common/items/flowers/blue.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A blue flower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/flowers/pink.ron
Normal file
5
assets/common/items/flowers/pink.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A pink flower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/flowers/red.ron
Normal file
5
assets/common/items/flowers/red.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A red flower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/flowers/sun.ron
Normal file
5
assets/common/items/flowers/sun.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A sunflower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/flowers/white.ron
Normal file
5
assets/common/items/flowers/white.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A white flower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/flowers/yellow.ron
Normal file
5
assets/common/items/flowers/yellow.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "A yellow flower",
|
||||
description: "Look beautiful",
|
||||
kind: Ingredient(Flower),
|
||||
)
|
5
assets/common/items/grasses/long.ron
Normal file
5
assets/common/items/grasses/long.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "Long grass",
|
||||
description: "Just some grass",
|
||||
kind: Ingredient(Grass),
|
||||
)
|
5
assets/common/items/grasses/medium.ron
Normal file
5
assets/common/items/grasses/medium.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "Medium grass",
|
||||
description: "Just some grass",
|
||||
kind: Ingredient(Grass),
|
||||
)
|
5
assets/common/items/grasses/short.ron
Normal file
5
assets/common/items/grasses/short.ron
Normal file
@ -0,0 +1,5 @@
|
||||
Item(
|
||||
name: "Short grass",
|
||||
description: "Just some grass",
|
||||
kind: Ingredient(Grass),
|
||||
)
|
11
assets/common/items/mushroom.ron
Normal file
11
assets/common/items/mushroom.ron
Normal file
@ -0,0 +1,11 @@
|
||||
Item(
|
||||
name: "A mushroom",
|
||||
description: "It's dirty, but looks edible",
|
||||
kind: Consumable(
|
||||
kind: Mushroom,
|
||||
effect: Health((
|
||||
amount: 10,
|
||||
cause: Item,
|
||||
)),
|
||||
),
|
||||
)
|
8
assets/common/items/velorite.ron
Normal file
8
assets/common/items/velorite.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Velorite",
|
||||
description: "It's smooth and looks edible",
|
||||
kind: Consumable(
|
||||
kind: Velorite,
|
||||
effect: Xp(50),
|
||||
),
|
||||
)
|
8
assets/common/items/veloritefrag.ron
Normal file
8
assets/common/items/veloritefrag.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Velorite Fragment",
|
||||
description: "It's dirty, but looks edible",
|
||||
kind: Consumable(
|
||||
kind: VeloriteFrag,
|
||||
effect: Xp(20),
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_axe.ron
Normal file
8
assets/common/items/weapons/starter_axe.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first axe",
|
||||
description: "A dusty axe that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Axe,
|
||||
power: 10,
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_bow.ron
Normal file
8
assets/common/items/weapons/starter_bow.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first bow",
|
||||
description: "A dusty bow that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Bow,
|
||||
power: 10,
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_dagger.ron
Normal file
8
assets/common/items/weapons/starter_dagger.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first dagger",
|
||||
description: "A dusty dagger that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Dagger,
|
||||
power: 10,
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_hammer.ron
Normal file
8
assets/common/items/weapons/starter_hammer.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first hammer",
|
||||
description: "A dusty hammer that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Hammer,
|
||||
power: 10,
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_staff.ron
Normal file
8
assets/common/items/weapons/starter_staff.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first staff",
|
||||
description: "A dusty staff that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Staff,
|
||||
power: 10,
|
||||
),
|
||||
)
|
8
assets/common/items/weapons/starter_sword.ron
Normal file
8
assets/common/items/weapons/starter_sword.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Your first sword",
|
||||
description: "A dusty sword that looks surprisingly weak",
|
||||
kind: Tool(
|
||||
kind: Sword,
|
||||
power: 10,
|
||||
),
|
||||
)
|
@ -1,15 +1,7 @@
|
||||
// Png(specifier),
|
||||
// Vox(specier),
|
||||
// VoxTrans(specifier, offset, (x_rot, y_rot, z_rot), zoom)
|
||||
({ // Debug Items
|
||||
Debug(Boost): VoxTrans(
|
||||
"voxel.weapon.debug_wand-0",
|
||||
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
|
||||
),
|
||||
Debug(Possess): VoxTrans(
|
||||
"voxel.weapon.debug_wand-1",
|
||||
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
|
||||
),
|
||||
({
|
||||
// Weapons
|
||||
Tool(Bow): VoxTrans(
|
||||
"voxel.weapon.bow.simple-bow",
|
||||
@ -69,4 +61,13 @@
|
||||
"voxel.sprite.grass.grass_long_5",
|
||||
(0.0, 0.0, 0.0), (-90.0, 50.0, 0.0), 1.0,
|
||||
),
|
||||
// Debug Items
|
||||
Tool(Debug(Boost)): VoxTrans(
|
||||
"voxel.weapon.debug_wand-0",
|
||||
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
|
||||
),
|
||||
Tool(Debug(Possess)): VoxTrans(
|
||||
"voxel.weapon.debug_wand-1",
|
||||
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
|
||||
),
|
||||
})
|
||||
|
@ -169,12 +169,7 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Request a state transition to `ClientState::Character`.
|
||||
pub fn request_character(
|
||||
&mut self,
|
||||
name: String,
|
||||
body: comp::Body,
|
||||
main: Option<comp::item::Tool>,
|
||||
) {
|
||||
pub fn request_character(&mut self, name: String, body: comp::Body, main: Option<String>) {
|
||||
self.postbox
|
||||
.send_message(ClientMsg::Character { name, body, main });
|
||||
self.client_state = ClientState::Pending;
|
||||
|
@ -17,6 +17,7 @@ mio-extras = "2.0.5"
|
||||
serde = "1.0.98"
|
||||
serde_derive = "1.0.98"
|
||||
serde_json = "1.0.40"
|
||||
ron = "0.5.1"
|
||||
bincode = "1.1.4"
|
||||
log = "0.4.8"
|
||||
rand = "0.7.0"
|
||||
|
@ -72,6 +72,43 @@ pub fn load_map<A: Asset + 'static, F: FnOnce(A) -> A>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_glob<A: Asset + 'static>(specifier: &str) -> Result<Arc<Vec<Arc<A>>>, Error> {
|
||||
if let Some(assets) = ASSETS.read().unwrap().get(specifier) {
|
||||
return Ok(Arc::clone(assets).downcast()?);
|
||||
}
|
||||
|
||||
// Get glob matches
|
||||
let glob_matches = read_dir(specifier.trim_end_matches(".*")).map(|dir| {
|
||||
dir.filter_map(|direntry| {
|
||||
direntry.ok().and_then(|file| {
|
||||
file.file_name()
|
||||
.to_string_lossy()
|
||||
.rsplitn(2, '.')
|
||||
.last()
|
||||
.map(|s| s.to_owned())
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
match glob_matches {
|
||||
Ok(glob_matches) => {
|
||||
let assets = Arc::new(
|
||||
glob_matches
|
||||
.into_iter()
|
||||
.filter_map(|name| load(&specifier.replace("*", &name)).ok())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let clone = Arc::clone(&assets);
|
||||
|
||||
let mut assets_write = ASSETS.write().unwrap();
|
||||
assets_write.insert(specifier.to_owned(), clone);
|
||||
Ok(assets)
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
}
|
||||
|
||||
/// Function used to load assets from the filesystem or the cache.
|
||||
/// Example usage:
|
||||
/// ```no_run
|
||||
@ -84,6 +121,11 @@ pub fn load<A: Asset + 'static>(specifier: &str) -> Result<Arc<A>, Error> {
|
||||
load_map(specifier, |x| x)
|
||||
}
|
||||
|
||||
/// Function used to load assets from the filesystem or the cache and return a clone.
|
||||
pub fn load_cloned<A: Asset + Clone + 'static>(specifier: &str) -> Result<A, Error> {
|
||||
load::<A>(specifier).map(|asset| (*asset).clone())
|
||||
}
|
||||
|
||||
/// Function used to load essential assets from the filesystem or the cache. It will panic if the asset is not found.
|
||||
/// Example usage:
|
||||
/// ```no_run
|
||||
@ -96,6 +138,11 @@ pub fn load_expect<A: Asset + 'static>(specifier: &str) -> Arc<A> {
|
||||
load(specifier).unwrap_or_else(|_| panic!("Failed loading essential asset: {}", specifier))
|
||||
}
|
||||
|
||||
/// Function used to load essential assets from the filesystem or the cache and return a clone. It will panic if the asset is not found.
|
||||
pub fn load_expect_cloned<A: Asset + Clone + 'static>(specifier: &str) -> A {
|
||||
load_expect::<A>(specifier).as_ref().clone()
|
||||
}
|
||||
|
||||
/// Load an asset while registering it to be watched and reloaded when it changes
|
||||
pub fn load_watched<A: Asset + 'static>(
|
||||
specifier: &str,
|
||||
@ -129,8 +176,6 @@ pub fn load_watched<A: Asset + 'static>(
|
||||
Ok(asset)
|
||||
}
|
||||
|
||||
/// The Asset trait, which is implemented by all structures that have their data stored in the
|
||||
/// filesystem.
|
||||
fn reload<A: Asset + 'static>(specifier: &str) -> Result<(), Error> {
|
||||
let asset = Arc::new(A::parse(load_file(specifier, A::ENDINGS)?)?);
|
||||
let clone = Arc::clone(&asset);
|
||||
@ -145,7 +190,8 @@ fn reload<A: Asset + 'static>(specifier: &str) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Asset Trait
|
||||
/// The Asset trait, which is implemented by all structures that have their data stored in the
|
||||
/// filesystem.
|
||||
pub trait Asset: Send + Sync + Sized {
|
||||
const ENDINGS: &'static [&'static str];
|
||||
/// Parse the input file and return the correct Asset.
|
||||
@ -256,6 +302,22 @@ pub fn load_file(specifier: &str, endings: &[&str]) -> Result<BufReader<File>, E
|
||||
Err(Error::NotFound(path.to_string_lossy().into_owned()))
|
||||
}
|
||||
|
||||
/// Loads a file based on the specifier and possible extensions
|
||||
pub fn load_file_glob(specifier: &str, endings: &[&str]) -> Result<BufReader<File>, Error> {
|
||||
let path = unpack_specifier(specifier);
|
||||
for ending in endings {
|
||||
let mut path = path.clone();
|
||||
path.set_extension(ending);
|
||||
|
||||
debug!("Trying to access \"{:?}\"", path);
|
||||
if let Ok(file) = File::open(path) {
|
||||
return Ok(BufReader::new(file));
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::NotFound(path.to_string_lossy().into_owned()))
|
||||
}
|
||||
|
||||
/// Read directory from `veloren/assets/*`
|
||||
pub fn read_dir(specifier: &str) -> Result<ReadDir, Error> {
|
||||
let dir_name = unpack_specifier(specifier);
|
||||
|
@ -1,11 +1,13 @@
|
||||
use crate::{
|
||||
comp,
|
||||
assets::{self, Asset},
|
||||
effect::Effect,
|
||||
terrain::{Block, BlockKind},
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Tool {
|
||||
@ -16,54 +18,15 @@ pub enum Tool {
|
||||
Hammer,
|
||||
Bow,
|
||||
Staff,
|
||||
Debug(Debug),
|
||||
}
|
||||
|
||||
impl Tool {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Tool::Dagger => "Dagger",
|
||||
Tool::Shield => "Shield",
|
||||
Tool::Sword => "Sword",
|
||||
Tool::Axe => "Axe",
|
||||
Tool::Hammer => "Hammer",
|
||||
Tool::Bow => "Bow",
|
||||
Tool::Staff => "Staff",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &'static str {
|
||||
match self {
|
||||
Tool::Dagger => {
|
||||
"A basic kitchen knife.\n\
|
||||
NOT YET AVAILABLE."
|
||||
}
|
||||
Tool::Shield => {
|
||||
"This shield belonged to many adventurers.\n\
|
||||
Now it's yours.\n\
|
||||
NOT YET AVAILABLE."
|
||||
}
|
||||
Tool::Sword => "When closing one eye it's nearly like it wasn't rusty at all!",
|
||||
Tool::Axe => {
|
||||
"It has a name written on it.\n\
|
||||
Sounds dwarvish."
|
||||
}
|
||||
Tool::Hammer => "Use with caution around nails.",
|
||||
Tool::Bow => "An old but sturdy hunting bow.",
|
||||
Tool::Staff => "The wood smells like magic.",
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Debug {
|
||||
Boost,
|
||||
Possess,
|
||||
}
|
||||
|
||||
pub const ALL_TOOLS: [Tool; 7] = [
|
||||
Tool::Dagger,
|
||||
Tool::Shield,
|
||||
Tool::Sword,
|
||||
Tool::Axe,
|
||||
Tool::Hammer,
|
||||
Tool::Bow,
|
||||
Tool::Staff,
|
||||
];
|
||||
|
||||
#[derive(Clone, 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.
|
||||
@ -80,28 +43,6 @@ pub enum Armor {
|
||||
Necklace,
|
||||
}
|
||||
|
||||
impl Armor {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Armor::Helmet => "Helmet",
|
||||
Armor::Shoulders => "Shoulder Pads",
|
||||
Armor::Chestplate => "Chestplate",
|
||||
Armor::Belt => "Belt",
|
||||
Armor::Gloves => "Gloves",
|
||||
Armor::Pants => "Pants",
|
||||
Armor::Boots => "Boots",
|
||||
Armor::Back => "Back",
|
||||
Armor::Tabard => "Tabard",
|
||||
Armor::Gem => "Gem",
|
||||
Armor::Necklace => "Necklace",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &'static str {
|
||||
self.name()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Consumable {
|
||||
Apple,
|
||||
@ -111,220 +52,78 @@ pub enum Consumable {
|
||||
VeloriteFrag,
|
||||
}
|
||||
|
||||
impl Consumable {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Consumable::Apple => "Apple",
|
||||
Consumable::Potion => "Potion",
|
||||
Consumable::Mushroom => "Mushroom",
|
||||
Consumable::Velorite => "Velorite",
|
||||
Consumable::VeloriteFrag => "Glowing Fragment",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &'static str {
|
||||
match self {
|
||||
Consumable::Apple => "A tasty Apple.",
|
||||
Consumable::Potion => "This Potion contains the essence of Life.",
|
||||
Consumable::Mushroom => "A common Mushroom.",
|
||||
Consumable::Velorite => "Has a subtle turqoise glow.",
|
||||
Consumable::VeloriteFrag => "Seems to be the fragment of a bigger piece...",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Ingredient {
|
||||
Flower,
|
||||
Grass,
|
||||
}
|
||||
|
||||
impl Ingredient {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Ingredient::Flower => "Flower",
|
||||
Ingredient::Grass => "Grass",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &'static str {
|
||||
match self {
|
||||
Ingredient::Flower => "It smells great.",
|
||||
Ingredient::Grass => "Greener than an orc's snout.",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Debug {
|
||||
Boost,
|
||||
Possess,
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ItemKind {
|
||||
Tool { kind: Tool, power: u32 },
|
||||
Armor { kind: Armor, power: u32 },
|
||||
Consumable { kind: Consumable, effect: Effect },
|
||||
Ingredient(Ingredient),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum Item {
|
||||
Tool {
|
||||
kind: Tool,
|
||||
power: u32,
|
||||
stamina: i32,
|
||||
strength: i32,
|
||||
dexterity: i32,
|
||||
intelligence: i32,
|
||||
},
|
||||
Armor {
|
||||
kind: Armor,
|
||||
stamina: i32,
|
||||
strength: i32,
|
||||
dexterity: i32,
|
||||
intelligence: i32,
|
||||
},
|
||||
Consumable {
|
||||
kind: Consumable,
|
||||
effect: Effect,
|
||||
},
|
||||
Ingredient {
|
||||
kind: Ingredient,
|
||||
},
|
||||
Debug(Debug),
|
||||
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) -> &'static str {
|
||||
match self {
|
||||
Item::Tool { kind, .. } => kind.name(),
|
||||
Item::Armor { kind, .. } => kind.name(),
|
||||
Item::Consumable { kind, .. } => kind.name(),
|
||||
Item::Ingredient { kind, .. } => kind.name(),
|
||||
Item::Debug(_) => "Debugging item",
|
||||
}
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn title(&self) -> String {
|
||||
format!("{} ({})", self.name(), self.category())
|
||||
pub fn description(&self) -> &str {
|
||||
&self.description
|
||||
}
|
||||
|
||||
pub fn info(&self) -> String {
|
||||
match self {
|
||||
Item::Tool { power, .. } => format!("{:+} attack", power),
|
||||
Item::Armor { .. } => String::new(),
|
||||
Item::Consumable { effect, .. } => format!("{}", effect.info()),
|
||||
Item::Ingredient { .. } => String::new(),
|
||||
Item::Debug(_) => format!("+99999 insanity"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn category(&self) -> &'static str {
|
||||
match self {
|
||||
Item::Tool { .. } => "Tool",
|
||||
Item::Armor { .. } => "Armor",
|
||||
Item::Consumable { .. } => "Consumable",
|
||||
Item::Ingredient { .. } => "Ingredient",
|
||||
Item::Debug(_) => "Debug",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn description(&self) -> String {
|
||||
match self {
|
||||
Item::Tool { kind, .. } => format!("{}", kind.description()),
|
||||
Item::Armor { kind, .. } => format!("{}", kind.description()),
|
||||
Item::Consumable { kind, .. } => format!("{}", kind.description()),
|
||||
Item::Ingredient { kind, .. } => format!("{}", kind.description()),
|
||||
Item::Debug(_) => format!("Debugging item"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
||||
match block.kind() {
|
||||
BlockKind::Apple => Some(Self::apple()),
|
||||
BlockKind::Mushroom => Some(Self::mushroom()),
|
||||
BlockKind::Velorite => Some(Self::velorite()),
|
||||
BlockKind::BlueFlower => Some(Self::flower()),
|
||||
BlockKind::PinkFlower => Some(Self::flower()),
|
||||
BlockKind::PurpleFlower => Some(Self::flower()),
|
||||
BlockKind::RedFlower => Some(Self::flower()),
|
||||
BlockKind::WhiteFlower => Some(Self::flower()),
|
||||
BlockKind::YellowFlower => Some(Self::flower()),
|
||||
BlockKind::Sunflower => Some(Self::flower()),
|
||||
BlockKind::LongGrass => Some(Self::grass()),
|
||||
BlockKind::MediumGrass => Some(Self::grass()),
|
||||
BlockKind::ShortGrass => Some(Self::grass()),
|
||||
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(match rand::random::<usize>() % 4 {
|
||||
0 => Self::apple(),
|
||||
1 => Self::velorite(),
|
||||
2 => Item::Tool {
|
||||
kind: *(&ALL_TOOLS).choose(&mut rand::thread_rng()).unwrap(),
|
||||
power: 8 + rand::random::<u32>() % (rand::random::<u32>() % 29 + 1),
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
},
|
||||
3 => Self::veloritefrag(),
|
||||
0 => assets::load_expect_cloned("common.items.apple"),
|
||||
1 => assets::load_expect_cloned("common.items.velorite"),
|
||||
2 => (**assets::load_glob::<Item>("common.items.weapons.*")
|
||||
.expect("Error getting glob")
|
||||
.choose(&mut rand::thread_rng())
|
||||
.expect("Empty glob"))
|
||||
.clone(),
|
||||
3 => assets::load_expect_cloned("common.items.veloritefrag"),
|
||||
_ => unreachable!(),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// General item constructors
|
||||
|
||||
pub fn apple() -> Self {
|
||||
Item::Consumable {
|
||||
kind: Consumable::Apple,
|
||||
effect: Effect::Health(comp::HealthChange {
|
||||
amount: 50,
|
||||
cause: comp::HealthSource::Item,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mushroom() -> Self {
|
||||
Item::Consumable {
|
||||
kind: Consumable::Mushroom,
|
||||
effect: Effect::Health(comp::HealthChange {
|
||||
amount: 10,
|
||||
cause: comp::HealthSource::Item,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn velorite() -> Self {
|
||||
Item::Consumable {
|
||||
kind: Consumable::Velorite,
|
||||
effect: Effect::Xp(50),
|
||||
}
|
||||
}
|
||||
pub fn veloritefrag() -> Self {
|
||||
Item::Consumable {
|
||||
kind: Consumable::VeloriteFrag,
|
||||
effect: Effect::Xp(20),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flower() -> Self {
|
||||
Item::Ingredient {
|
||||
kind: Ingredient::Flower,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn grass() -> Self {
|
||||
Item::Ingredient {
|
||||
kind: Ingredient::Grass,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Item {
|
||||
fn default() -> Self {
|
||||
Item::Tool {
|
||||
kind: Tool::Hammer,
|
||||
power: 0,
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Item {
|
||||
|
@ -1,8 +1,9 @@
|
||||
pub mod item;
|
||||
|
||||
// Reexports
|
||||
pub use item::{Debug, Item, Tool};
|
||||
pub use item::{Debug, Item, ItemKind, Tool};
|
||||
|
||||
use crate::assets;
|
||||
use specs::{Component, HashMapStorage, NullStorage};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -72,8 +73,8 @@ impl Default for Inventory {
|
||||
slots: vec![None; 25],
|
||||
};
|
||||
|
||||
inventory.push(Item::Debug(Debug::Boost));
|
||||
inventory.push(Item::Debug(Debug::Possess));
|
||||
inventory.push(assets::load_expect_cloned("common.items.debug.boost"));
|
||||
inventory.push(assets::load_expect_cloned("common.items.debug.possess"));
|
||||
inventory
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ pub use controller::{
|
||||
ControlEvent, Controller, ControllerInputs, InventoryManip, MountState, Mounting,
|
||||
};
|
||||
pub use inputs::CanBuild;
|
||||
pub use inventory::{item, Inventory, InventoryUpdate, Item};
|
||||
pub use inventory::{item, Inventory, InventoryUpdate, Item, ItemKind};
|
||||
pub use last::Last;
|
||||
pub use location::Waypoint;
|
||||
pub use phys::{ForceUpdate, Gravity, Mass, Ori, PhysicsState, Pos, Scale, Sticky, Vel};
|
||||
|
@ -51,7 +51,7 @@ pub enum ServerEvent {
|
||||
entity: EcsEntity,
|
||||
name: String,
|
||||
body: comp::Body,
|
||||
main: Option<comp::Item>,
|
||||
main: Option<String>,
|
||||
},
|
||||
CreateNpc {
|
||||
pos: comp::Pos,
|
||||
|
@ -12,7 +12,7 @@ pub enum ClientMsg {
|
||||
Character {
|
||||
name: String,
|
||||
body: comp::Body,
|
||||
main: Option<comp::item::Tool>,
|
||||
main: Option<String>, // Specifier for the weapon
|
||||
},
|
||||
ControllerInputs(comp::ControllerInputs),
|
||||
ControlEvent(comp::ControlEvent),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
item::Item, ActionState::*, CharacterState, Controller, HealthChange, HealthSource, Ori,
|
||||
Pos, Stats,
|
||||
ActionState::*, CharacterState, Controller, HealthChange, HealthSource, ItemKind, Ori, Pos,
|
||||
Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::{DeltaTime, Uid},
|
||||
@ -110,12 +110,13 @@ impl<'a> System<'a> for Sys {
|
||||
&& ori2.angle_between(pos_b2 - pos2) < (1.0 / pos2.distance(pos_b2)).atan()
|
||||
{
|
||||
// Weapon gives base damage
|
||||
let mut dmg =
|
||||
if let Some(Item::Tool { power, .. }) = stat.equipment.main {
|
||||
power as i32
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let mut dmg = if let Some(ItemKind::Tool { power, .. }) =
|
||||
stat.equipment.main.as_ref().map(|i| &i.kind)
|
||||
{
|
||||
*power as i32
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
// Block
|
||||
if character_b.action.is_block()
|
||||
|
@ -5,7 +5,8 @@ use super::{
|
||||
use crate::{
|
||||
comp::{
|
||||
self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller,
|
||||
HealthChange, HealthSource, Item, MovementState::*, PhysicsState, Projectile, Stats, Vel,
|
||||
HealthChange, HealthSource, ItemKind, MovementState::*, PhysicsState, Projectile, Stats,
|
||||
Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
};
|
||||
@ -131,8 +132,8 @@ impl<'a> System<'a> for Sys {
|
||||
};
|
||||
}
|
||||
|
||||
match stats.equipment.main {
|
||||
Some(Item::Tool {
|
||||
match stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Bow,
|
||||
power,
|
||||
..
|
||||
@ -158,7 +159,7 @@ impl<'a> System<'a> for Sys {
|
||||
hit_wall: vec![projectile::Effect::Stick],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(power as i32),
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
@ -170,7 +171,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Item::Tool {
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Staff,
|
||||
power,
|
||||
..
|
||||
@ -220,7 +221,7 @@ impl<'a> System<'a> for Sys {
|
||||
hit_wall: vec![projectile::Effect::Vanish],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
amount: -(power as i32),
|
||||
amount: -(*power as i32),
|
||||
cause: HealthSource::Attack { by: *uid },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
@ -232,38 +233,10 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Item::Tool { .. }) => {
|
||||
// Melee Attack
|
||||
if inputs.primary
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block
|
||||
if inputs.secondary
|
||||
&& (character.movement == Stand || character.movement == Run)
|
||||
&& character.action.is_wield()
|
||||
{
|
||||
character.action = Block {
|
||||
time_left: Duration::from_secs(5),
|
||||
};
|
||||
} else if !inputs.secondary && character.action.is_block() {
|
||||
character.action = Wield {
|
||||
time_left: Duration::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
Some(Item::Debug(item::Debug::Boost)) => {
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Debug(item::Debug::Boost),
|
||||
..
|
||||
}) => {
|
||||
if inputs.primary {
|
||||
local_emitter.emit(LocalEvent::Boost {
|
||||
entity,
|
||||
@ -278,7 +251,10 @@ impl<'a> System<'a> for Sys {
|
||||
});
|
||||
}
|
||||
}
|
||||
Some(Item::Debug(item::Debug::Possess)) => {
|
||||
Some(ItemKind::Tool {
|
||||
kind: item::Tool::Debug(item::Debug::Possess),
|
||||
..
|
||||
}) => {
|
||||
if inputs.primary
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
@ -325,6 +301,38 @@ impl<'a> System<'a> for Sys {
|
||||
};
|
||||
}
|
||||
}
|
||||
// All other tools
|
||||
Some(ItemKind::Tool { .. }) => {
|
||||
// Attack
|
||||
if inputs.primary
|
||||
&& (character.movement == Stand
|
||||
|| character.movement == Run
|
||||
|| character.movement == Jump)
|
||||
{
|
||||
if let Wield { time_left } = character.action {
|
||||
if time_left == Duration::default() {
|
||||
character.action = Attack {
|
||||
time_left: ATTACK_DURATION,
|
||||
applied: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block
|
||||
if inputs.secondary
|
||||
&& (character.movement == Stand || character.movement == Run)
|
||||
&& character.action.is_wield()
|
||||
{
|
||||
character.action = Block {
|
||||
time_left: Duration::from_secs(5),
|
||||
};
|
||||
} else if !inputs.secondary && character.action.is_block() {
|
||||
character.action = Wield {
|
||||
time_left: Duration::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Attack
|
||||
if inputs.primary
|
||||
|
@ -5,7 +5,7 @@
|
||||
use crate::{Server, StateExt};
|
||||
use chrono::{NaiveTime, Timelike};
|
||||
use common::{
|
||||
comp,
|
||||
assets, comp,
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::ServerMsg,
|
||||
npc::{get_npc_name, NpcKind},
|
||||
@ -82,6 +82,12 @@ impl ChatCommand {
|
||||
lazy_static! {
|
||||
/// Static list of chat commands available to the server.
|
||||
pub static ref CHAT_COMMANDS: Vec<ChatCommand> = vec![
|
||||
ChatCommand::new(
|
||||
"giveitem",
|
||||
"{d}",
|
||||
"/giveitem <name> : Give yourself an item.",
|
||||
true,
|
||||
handle_give,),
|
||||
ChatCommand::new(
|
||||
"jump",
|
||||
"{d} {d} {d}",
|
||||
@ -233,7 +239,23 @@ lazy_static! {
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
fn handle_give(server: &mut Server, entity: EcsEntity, args: String, _action: &ChatCommand) {
|
||||
if let Ok(item) = assets::load_cloned(&args) {
|
||||
server
|
||||
.state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.map(|inv| inv.push(item));
|
||||
let _ = server
|
||||
.state
|
||||
.ecs()
|
||||
.write_storage::<comp::InventoryUpdate>()
|
||||
.insert(entity, comp::InventoryUpdate);
|
||||
} else {
|
||||
server.notify_client(entity, ServerMsg::private(String::from("Invalid item!")));
|
||||
}
|
||||
}
|
||||
fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
||||
if let Ok((x, y, z)) = scan_fmt!(&args, action.arg_fmt, f32, f32, f32) {
|
||||
match server.state.read_component_cloned::<comp::Pos>(entity) {
|
||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||
cmd::CHAT_COMMANDS,
|
||||
};
|
||||
use common::{
|
||||
comp,
|
||||
assets, comp,
|
||||
effect::Effect,
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{ClientMsg, ClientState, ServerError, ServerInfo, ServerMsg},
|
||||
@ -201,9 +201,12 @@ impl Server {
|
||||
entity: EcsEntity,
|
||||
name: String,
|
||||
body: comp::Body,
|
||||
main: Option<comp::Item>,
|
||||
main: Option<String>,
|
||||
server_settings: &ServerSettings,
|
||||
) {
|
||||
// Give no item when an invalid specifier is given
|
||||
let main = main.and_then(|specifier| assets::load_cloned(&specifier).ok());
|
||||
|
||||
let spawn_point = state.ecs().read_resource::<SpawnPoint>().0;
|
||||
|
||||
state.write_component(entity, body);
|
||||
@ -428,40 +431,44 @@ impl Server {
|
||||
}
|
||||
|
||||
comp::InventoryManip::Use(slot) => {
|
||||
let item = state
|
||||
let item_opt = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.and_then(|inv| inv.remove(slot));
|
||||
|
||||
match item {
|
||||
Some(comp::Item::Tool { .. }) | Some(comp::Item::Debug(_)) => {
|
||||
if let Some(stats) =
|
||||
state.ecs().write_storage::<comp::Stats>().get_mut(entity)
|
||||
{
|
||||
// Insert old item into inventory
|
||||
if let Some(old_item) = stats.equipment.main.take() {
|
||||
state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.map(|inv| inv.insert(slot, old_item));
|
||||
}
|
||||
match item_opt {
|
||||
Some(item) => match item.kind {
|
||||
comp::ItemKind::Tool { .. } => {
|
||||
if let Some(stats) = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Stats>()
|
||||
.get_mut(entity)
|
||||
{
|
||||
// Insert old item into inventory
|
||||
if let Some(old_item) = stats.equipment.main.take() {
|
||||
state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.map(|inv| inv.insert(slot, old_item));
|
||||
}
|
||||
|
||||
stats.equipment.main = item;
|
||||
stats.equipment.main = Some(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(comp::Item::Consumable { effect, .. }) => {
|
||||
state.apply_effect(entity, effect);
|
||||
}
|
||||
Some(item) => {
|
||||
// Re-insert it if unused
|
||||
let _ = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.map(|inv| inv.insert(slot, item));
|
||||
}
|
||||
comp::ItemKind::Consumable { effect, .. } => {
|
||||
state.apply_effect(entity, effect);
|
||||
}
|
||||
_ => {
|
||||
// Re-insert it if unused
|
||||
let _ = state
|
||||
.ecs()
|
||||
.write_storage::<comp::Inventory>()
|
||||
.get_mut(entity)
|
||||
.map(|inv| inv.insert(slot, item));
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -610,14 +617,15 @@ impl Server {
|
||||
{
|
||||
let mut inventories = ecs.write_storage::<comp::Inventory>();
|
||||
if let Some(inventory) = inventories.get_mut(possesse) {
|
||||
inventory
|
||||
.push(comp::Item::Debug(comp::item::Debug::Possess));
|
||||
inventory.push(assets::load_expect_cloned(
|
||||
"common.items.debug.possess",
|
||||
));
|
||||
} else {
|
||||
let _ = inventories.insert(
|
||||
possesse,
|
||||
comp::Inventory {
|
||||
slots: vec![Some(comp::Item::Debug(
|
||||
comp::item::Debug::Possess,
|
||||
slots: vec![Some(assets::load_expect_cloned(
|
||||
"common.items.debug.possess",
|
||||
))],
|
||||
},
|
||||
);
|
||||
|
@ -1,7 +1,8 @@
|
||||
use super::SysTimer;
|
||||
use crate::{auth_provider::AuthProvider, client::Client, CLIENT_TIMEOUT};
|
||||
use common::{
|
||||
comp::{Admin, Body, CanBuild, Controller, Item, Ori, Player, Pos, Vel},
|
||||
assets,
|
||||
comp::{Admin, Body, CanBuild, Controller, Ori, Player, Pos, Vel},
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{validate_chat_msg, ChatMsgValidationError, MAX_BYTES_CHAT_MSG},
|
||||
msg::{ClientMsg, ClientState, RequestStateError, ServerMsg},
|
||||
@ -168,14 +169,8 @@ impl<'a> System<'a> for Sys {
|
||||
entity,
|
||||
name,
|
||||
body,
|
||||
main: main.map(|t| Item::Tool {
|
||||
kind: t,
|
||||
power: 10,
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
}),
|
||||
main: main
|
||||
.and_then(|specifier| assets::load_cloned(&specifier).ok()),
|
||||
});
|
||||
}
|
||||
ClientState::Character => client.error_state(RequestStateError::Already),
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::SysTimer;
|
||||
use crate::{chunk_generator::ChunkGenerator, client::Client, Tick};
|
||||
use common::{
|
||||
assets,
|
||||
comp::{self, Player, Pos},
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::ServerMsg,
|
||||
@ -95,14 +96,9 @@ impl<'a> System<'a> for Sys {
|
||||
let (mut stats, mut body) = if rand::random() {
|
||||
let stats = comp::Stats::new(
|
||||
"Humanoid".to_string(),
|
||||
Some(comp::Item::Tool {
|
||||
kind: comp::item::Tool::Sword,
|
||||
power: 5,
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
}),
|
||||
Some(assets::load_expect_cloned(
|
||||
"common.items.weapons.starter_sword",
|
||||
)),
|
||||
);
|
||||
let body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
||||
(stats, body)
|
||||
@ -120,14 +116,9 @@ impl<'a> System<'a> for Sys {
|
||||
if rand::random::<f32>() < 0.8 {
|
||||
stats = comp::Stats::new(
|
||||
"Humanoid".to_string(),
|
||||
Some(comp::Item::Tool {
|
||||
kind: comp::item::Tool::Sword,
|
||||
power: 10,
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
}),
|
||||
Some(assets::load_expect_cloned(
|
||||
"common.items.weapons.starter_sword",
|
||||
)),
|
||||
);
|
||||
body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
||||
}
|
||||
|
@ -224,6 +224,27 @@ impl Animation for BlockAnimation {
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Debug(_) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5, 6.5);
|
||||
next.l_hand.ori = Quaternion::rotation_x(2.07)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 2.5, 3.75);
|
||||
next.r_hand.ori = Quaternion::rotation_x(2.07)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
//next.l_foot.offset = Vec3::new(-3.4, 0.3, 8.0 + wave_ultra_slow_cos * 0.1);
|
||||
//next.l_foot.ori = Quaternion::rotation_x(-0.3);
|
||||
|
@ -223,6 +223,27 @@ impl Animation for BlockIdleAnimation {
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Debug(_) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.5 + wave_ultra_slow * 2.0, 6.5);
|
||||
next.l_hand.ori = Quaternion::rotation_x(2.07)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 2.5 + wave_ultra_slow * 2.0, 3.75);
|
||||
next.r_hand.ori = Quaternion::rotation_x(2.07)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + wave_ultra_slow * 2.0 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(-0.85);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.3, 8.0 + wave_ultra_slow_cos * 0.1);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.3);
|
||||
|
@ -235,6 +235,27 @@ impl Animation for CidleAnimation {
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Debug(_) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(1.27 + wave_ultra_slow * -0.1)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 2.5, -1.25);
|
||||
next.r_hand.ori = Quaternion::rotation_x(1.27 + wave_ultra_slow * -0.1)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave_ultra_slow * 0.2);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
next.l_foot.offset = Vec3::new(-3.4, -1.5, 8.0 + wave_slow * 0.2);
|
||||
next.l_foot.ori = Quaternion::rotation_x(wave_ultra_slow_cos * 0.015);
|
||||
|
@ -151,6 +151,27 @@ impl Animation for WieldAnimation {
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Debug(_) => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 4.0, 3.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(1.27 + wave * 0.25)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 2.5, -1.25);
|
||||
next.r_hand.ori = Quaternion::rotation_x(1.27 + wave * 0.25)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.27)
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
|
||||
next
|
||||
|
@ -154,6 +154,7 @@ impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
|
||||
Tool::Staff => 3.0,
|
||||
Tool::Bow => 0.0,
|
||||
Tool::Dagger => 0.0,
|
||||
Tool::Debug(_) => 0.0,
|
||||
},
|
||||
weapon_y: match Tool::Hammer {
|
||||
// TODO: Inventory
|
||||
@ -164,6 +165,7 @@ impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
|
||||
Tool::Staff => 0.0,
|
||||
Tool::Bow => -2.0,
|
||||
Tool::Dagger => -2.0,
|
||||
Tool::Debug(_) => 0.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
item_imgs::{ItemImgs, ItemKind},
|
||||
item_imgs::{ItemImgs, ItemKey},
|
||||
Event as HudEvent, Fonts, TEXT_COLOR,
|
||||
};
|
||||
use crate::ui::{ImageFrame, Tooltip, TooltipManager, Tooltipable};
|
||||
@ -65,7 +65,7 @@ impl<'a> Bag<'a> {
|
||||
|
||||
pub struct State {
|
||||
ids: Ids,
|
||||
img_id_cache: Vec<Option<(ItemKind, image::Id)>>,
|
||||
img_id_cache: Vec<Option<(ItemKey, image::Id)>>,
|
||||
selected_slot: Option<usize>,
|
||||
}
|
||||
|
||||
@ -195,8 +195,8 @@ impl<'a> Widget for Bag<'a> {
|
||||
slot_widget
|
||||
.with_tooltip(
|
||||
self.tooltip_manager,
|
||||
&item.title(),
|
||||
&format!("{}\n{}", item.info(), item.description()),
|
||||
&item.name(),
|
||||
&format!("{}\n{}", item.name(), item.description()),
|
||||
&item_tooltip,
|
||||
)
|
||||
.set(state.ids.inv_slots[i], ui)
|
||||
@ -222,7 +222,7 @@ impl<'a> Widget for Bag<'a> {
|
||||
state.update(|s| s.selected_slot = selected_slot);
|
||||
}
|
||||
// Item
|
||||
if let Some(kind) = item.as_ref().map(|i| ItemKind::from(i)) {
|
||||
if let Some(kind) = item.as_ref().map(|i| ItemKey::from(i)) {
|
||||
Button::image(match &state.img_id_cache[i] {
|
||||
Some((cached_kind, id)) if cached_kind == &kind => *id,
|
||||
_ => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ui::{Graphic, Transform, Ui};
|
||||
use common::{
|
||||
assets::{self, watch::ReloadIndicator, Asset},
|
||||
comp::item::{Armor, Consumable, Debug, Ingredient, Item, Tool},
|
||||
comp::item::{Armor, Consumable, Ingredient, Item, ItemKind, Tool},
|
||||
};
|
||||
use conrod_core::image::Id;
|
||||
use dot_vox::DotVoxData;
|
||||
@ -13,21 +13,19 @@ use std::{fs::File, io::BufReader, sync::Arc};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ItemKind {
|
||||
pub enum ItemKey {
|
||||
Tool(Tool),
|
||||
Armor(Armor),
|
||||
Consumable(Consumable),
|
||||
Ingredient(Ingredient),
|
||||
Debug(Debug),
|
||||
}
|
||||
impl From<&Item> for ItemKind {
|
||||
impl From<&Item> for ItemKey {
|
||||
fn from(item: &Item) -> Self {
|
||||
match item {
|
||||
Item::Tool { kind, .. } => ItemKind::Tool(kind.clone()),
|
||||
Item::Armor { kind, .. } => ItemKind::Armor(kind.clone()),
|
||||
Item::Consumable { kind, .. } => ItemKind::Consumable(kind.clone()),
|
||||
Item::Ingredient { kind, .. } => ItemKind::Ingredient(kind.clone()),
|
||||
Item::Debug(kind) => ItemKind::Debug(kind.clone()),
|
||||
match &item.kind {
|
||||
ItemKind::Tool { kind, .. } => ItemKey::Tool(kind.clone()),
|
||||
ItemKind::Armor { kind, .. } => ItemKey::Armor(kind.clone()),
|
||||
ItemKind::Consumable { kind, .. } => ItemKey::Consumable(kind.clone()),
|
||||
ItemKind::Ingredient(kind) => ItemKey::Ingredient(kind.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +66,7 @@ impl ImageSpec {
|
||||
}
|
||||
}
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ItemImagesSpec(HashMap<ItemKind, ImageSpec>);
|
||||
struct ItemImagesSpec(HashMap<ItemKey, ImageSpec>);
|
||||
impl Asset for ItemImagesSpec {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
@ -77,7 +75,7 @@ impl Asset for ItemImagesSpec {
|
||||
}
|
||||
|
||||
pub struct ItemImgs {
|
||||
map: HashMap<ItemKind, Id>,
|
||||
map: HashMap<ItemKey, Id>,
|
||||
indicator: ReloadIndicator,
|
||||
}
|
||||
impl ItemImgs {
|
||||
@ -110,7 +108,7 @@ impl ItemImgs {
|
||||
// See if we already have an id we can use
|
||||
match self.map.get(&kind) {
|
||||
Some(id) => ui.replace_graphic(*id, graphic),
|
||||
// Otherwise, generate new id and insert it into our Id -> ItemKind map
|
||||
// Otherwise, generate new id and insert it into our Id -> ItemKey map
|
||||
None => {
|
||||
self.map.insert(kind.clone(), ui.add_graphic(graphic));
|
||||
}
|
||||
@ -118,7 +116,7 @@ impl ItemImgs {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn img_id(&self, item_kind: ItemKind) -> Option<Id> {
|
||||
pub fn img_id(&self, item_kind: ItemKey) -> Option<Id> {
|
||||
match self.map.get(&item_kind) {
|
||||
Some(id) => Some(*id),
|
||||
// There was no specification in the ron
|
||||
|
@ -3,8 +3,7 @@ use super::{
|
||||
/*FOCUS_COLOR, RAGE_COLOR,*/ HP_COLOR, LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR,
|
||||
};
|
||||
use crate::GlobalState;
|
||||
use common::comp::{item::Debug, item::Tool, Item, Stats};
|
||||
|
||||
use common::comp::{item::Debug, item::Tool, ItemKind, Stats};
|
||||
use conrod_core::{
|
||||
color,
|
||||
widget::{self, Button, Image, Rectangle, Text},
|
||||
@ -506,8 +505,8 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
// M1 Slot
|
||||
Image::new(self.imgs.skillbar_slot_big_bg)
|
||||
.w_h(36.0 * scale, 36.0 * scale)
|
||||
.color(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.color(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => Some(BG_COLOR_2),
|
||||
Tool::Staff => Some(BG_COLOR_2),
|
||||
_ => Some(BG_COLOR_2),
|
||||
@ -516,28 +515,28 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
})
|
||||
.middle_of(state.ids.m1_slot)
|
||||
.set(state.ids.m1_slot_bg, ui);
|
||||
Button::image(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
Button::image(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Sword => self.imgs.twohsword_m1,
|
||||
Tool::Hammer => self.imgs.twohhammer_m1,
|
||||
Tool::Axe => self.imgs.twohaxe_m1,
|
||||
Tool::Bow => self.imgs.bow_m1,
|
||||
Tool::Staff => self.imgs.staff_m1,
|
||||
Tool::Debug(Debug::Boost) => self.imgs.flyingrod_m1,
|
||||
_ => self.imgs.twohaxe_m1,
|
||||
},
|
||||
Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m1,
|
||||
_ => self.imgs.twohaxe_m1,
|
||||
}) // Insert Icon here
|
||||
.w(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.w(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => 30.0 * scale,
|
||||
Tool::Staff => 30.0 * scale,
|
||||
_ => 38.0 * scale,
|
||||
},
|
||||
_ => 38.0 * scale,
|
||||
})
|
||||
.h(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.h(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => 30.0 * scale,
|
||||
Tool::Staff => 36.0 * scale,
|
||||
_ => 38.0 * scale,
|
||||
@ -553,8 +552,8 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.m2_slot, ui);
|
||||
Image::new(self.imgs.skillbar_slot_big_bg)
|
||||
.w_h(36.0 * scale, 36.0 * scale)
|
||||
.color(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.color(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => Some(BG_COLOR_2),
|
||||
Tool::Staff => Some(BG_COLOR_2),
|
||||
_ => Some(BG_COLOR_2),
|
||||
@ -563,28 +562,28 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
})
|
||||
.middle_of(state.ids.m2_slot)
|
||||
.set(state.ids.m2_slot_bg, ui);
|
||||
Button::image(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
Button::image(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Sword => self.imgs.twohsword_m2,
|
||||
Tool::Hammer => self.imgs.twohhammer_m2,
|
||||
Tool::Axe => self.imgs.twohaxe_m2,
|
||||
Tool::Bow => self.imgs.bow_m2,
|
||||
Tool::Staff => self.imgs.staff_m2,
|
||||
Tool::Debug(Debug::Boost) => self.imgs.flyingrod_m2,
|
||||
_ => self.imgs.twohaxe_m2,
|
||||
},
|
||||
Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m2,
|
||||
_ => self.imgs.twohaxe_m2,
|
||||
}) // Insert Icon here
|
||||
.w(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.w(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => 30.0 * scale,
|
||||
Tool::Staff => 30.0 * scale,
|
||||
_ => 38.0 * scale,
|
||||
},
|
||||
_ => 38.0 * scale,
|
||||
})
|
||||
.h(match self.stats.equipment.main {
|
||||
Some(Item::Tool { kind, .. }) => match kind {
|
||||
.h(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
|
||||
Some(ItemKind::Tool { kind, .. }) => match kind {
|
||||
Tool::Bow => 30.0 * scale,
|
||||
Tool::Staff => 30.0 * scale,
|
||||
_ => 38.0 * scale,
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
PlayStateResult,
|
||||
};
|
||||
use client::{self, Client};
|
||||
use common::{clock::Clock, comp, msg::ClientState};
|
||||
use common::{assets, clock::Clock, comp, msg::ClientState};
|
||||
use log::error;
|
||||
use scene::Scene;
|
||||
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||
@ -67,7 +67,9 @@ impl PlayState for CharSelectionState {
|
||||
self.client.borrow_mut().request_character(
|
||||
self.char_selection_ui.character_name.clone(),
|
||||
comp::Body::Humanoid(self.char_selection_ui.character_body),
|
||||
self.char_selection_ui.character_tool,
|
||||
self.char_selection_ui
|
||||
.character_tool
|
||||
.map(|specifier| specifier.to_owned()),
|
||||
);
|
||||
return PlayStateResult::Push(Box::new(SessionState::new(
|
||||
global_state,
|
||||
@ -93,18 +95,10 @@ impl PlayState for CharSelectionState {
|
||||
&self.client.borrow(),
|
||||
self.char_selection_ui.character_body,
|
||||
&comp::Equipment {
|
||||
main: if let Some(kind) = self.char_selection_ui.character_tool {
|
||||
Some(comp::Item::Tool {
|
||||
kind: kind,
|
||||
power: 10,
|
||||
stamina: 0,
|
||||
strength: 0,
|
||||
dexterity: 0,
|
||||
intelligence: 0,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
},
|
||||
main: self
|
||||
.char_selection_ui
|
||||
.character_tool
|
||||
.and_then(|specifier| assets::load_cloned(&specifier).ok()),
|
||||
alt: None,
|
||||
},
|
||||
);
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
GlobalState,
|
||||
};
|
||||
use client::Client;
|
||||
use common::comp::{humanoid, item::Tool};
|
||||
use common::comp::humanoid;
|
||||
use conrod_core::{
|
||||
color,
|
||||
color::TRANSPARENT,
|
||||
@ -17,6 +17,13 @@ use conrod_core::{
|
||||
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, UiCell, Widget,
|
||||
};
|
||||
|
||||
const STARTER_HAMMER: &str = "common.items.weapons.starter_hammer";
|
||||
const STARTER_BOW: &str = "common.items.weapons.starter_bow";
|
||||
const STARTER_AXE: &str = "common.items.weapons.starter_axe";
|
||||
const STARTER_STAFF: &str = "common.items.weapons.starter_staff";
|
||||
const STARTER_SWORD: &str = "common.items.weapons.starter_sword";
|
||||
const STARTER_DAGGER: &str = "common.items.weapons.starter_dagger";
|
||||
|
||||
widget_ids! {
|
||||
struct Ids {
|
||||
// Background and logo
|
||||
@ -249,7 +256,7 @@ pub struct CharSelectionUi {
|
||||
//deletion_confirmation: bool,
|
||||
pub character_name: String,
|
||||
pub character_body: humanoid::Body,
|
||||
pub character_tool: Option<Tool>,
|
||||
pub character_tool: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl CharSelectionUi {
|
||||
@ -280,7 +287,7 @@ impl CharSelectionUi {
|
||||
character_creation: false,
|
||||
character_name: "Character Name".to_string(),
|
||||
character_body: humanoid::Body::random(),
|
||||
character_tool: Some(Tool::Sword),
|
||||
character_tool: Some(STARTER_SWORD),
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,7 +476,7 @@ impl CharSelectionUi {
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_creation = true;
|
||||
self.character_tool = Some(Tool::Sword);
|
||||
self.character_tool = Some(STARTER_SWORD);
|
||||
}
|
||||
|
||||
// Alpha Version
|
||||
@ -852,7 +859,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.bottom_left_with_margins_on(self.ids.creation_buttons_alignment_2, 0.0, 0.0)
|
||||
.set(self.ids.hammer, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Hammer) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_HAMMER) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -864,7 +871,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.hammer_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_tool = Some(Tool::Hammer);
|
||||
self.character_tool = Some(STARTER_HAMMER);
|
||||
}
|
||||
// REMOVE THIS AFTER IMPLEMENTATION
|
||||
/*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
|
||||
@ -877,7 +884,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.right_from(self.ids.hammer, 2.0)
|
||||
.set(self.ids.bow, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Bow) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_BOW) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -889,7 +896,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.bow_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_tool = Some(Tool::Bow);
|
||||
self.character_tool = Some(STARTER_BOW);
|
||||
}
|
||||
// REMOVE THIS AFTER IMPLEMENTATION
|
||||
/*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
|
||||
@ -900,7 +907,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.right_from(self.ids.bow, 2.0)
|
||||
.set(self.ids.staff, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Staff) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_STAFF) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -912,7 +919,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.staff_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_tool = Some(Tool::Staff);
|
||||
self.character_tool = Some(STARTER_STAFF);
|
||||
}
|
||||
// REMOVE THIS AFTER IMPLEMENTATION
|
||||
/*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
|
||||
@ -923,7 +930,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.up_from(self.ids.hammer, 2.0)
|
||||
.set(self.ids.sword, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Sword) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_SWORD) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -935,7 +942,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.sword_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_tool = Some(Tool::Sword);
|
||||
self.character_tool = Some(STARTER_SWORD);
|
||||
}
|
||||
|
||||
// Daggers
|
||||
@ -943,7 +950,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.right_from(self.ids.sword, 2.0)
|
||||
.set(self.ids.daggers, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Dagger) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_DAGGER) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -955,7 +962,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.daggers_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
// self.character_tool = Some(Tool::Daggers);
|
||||
// self.character_tool = Some(STARTER_DAGGER);
|
||||
} // REMOVE THIS AFTER IMPLEMENTATION
|
||||
Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
|
||||
.middle_of(self.ids.daggers)
|
||||
@ -966,7 +973,7 @@ impl CharSelectionUi {
|
||||
.w_h(70.0, 70.0)
|
||||
.right_from(self.ids.daggers, 2.0)
|
||||
.set(self.ids.axe, ui_widgets);
|
||||
if Button::image(if let Some(Tool::Axe) = self.character_tool {
|
||||
if Button::image(if let Some(STARTER_AXE) = self.character_tool {
|
||||
self.imgs.icon_border_pressed
|
||||
} else {
|
||||
self.imgs.icon_border
|
||||
@ -978,7 +985,7 @@ impl CharSelectionUi {
|
||||
.set(self.ids.axe_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
self.character_tool = Some(Tool::Axe);
|
||||
self.character_tool = Some(STARTER_AXE);
|
||||
}
|
||||
// REMOVE THIS AFTER IMPLEMENTATION
|
||||
/*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
|
||||
|
@ -10,7 +10,7 @@ use common::{
|
||||
Belt, BodyType, Chest, EyeColor, Eyebrows, Foot, Hand, Pants, Race, Shoulder, Skin,
|
||||
},
|
||||
item::Tool,
|
||||
object, quadruped, quadruped_medium, Item,
|
||||
object, quadruped, quadruped_medium, Item, ItemKind,
|
||||
},
|
||||
figure::{DynaUnionizer, MatSegment, Material, Segment},
|
||||
};
|
||||
@ -511,8 +511,8 @@ impl HumArmorFootSpec {
|
||||
|
||||
pub fn mesh_main(item: Option<&Item>) -> Mesh<FigurePipeline> {
|
||||
if let Some(item) = item {
|
||||
let (name, offset) = match item {
|
||||
Item::Tool { kind, .. } => match kind {
|
||||
let (name, offset) = match item.kind {
|
||||
ItemKind::Tool { kind, .. } => match kind {
|
||||
Tool::Sword => ("weapon.sword.rusty_2h", Vec3::new(-1.5, -6.5, -4.0)),
|
||||
Tool::Axe => ("weapon.axe.rusty_2h", Vec3::new(-1.5, -5.0, -4.0)),
|
||||
Tool::Hammer => ("weapon.hammer.rusty_2h", Vec3::new(-2.5, -5.5, -4.0)),
|
||||
@ -520,8 +520,8 @@ pub fn mesh_main(item: Option<&Item>) -> Mesh<FigurePipeline> {
|
||||
Tool::Shield => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
|
||||
Tool::Bow => ("weapon.bow.simple-bow", Vec3::new(-1.0, -6.0, -2.0)),
|
||||
Tool::Staff => ("weapon.staff.wood-fire", Vec3::new(-1.0, -6.0, -3.0)),
|
||||
Tool::Debug(_) => ("weapon.debug_wand", Vec3::new(-1.5, -9.5, -4.0)),
|
||||
},
|
||||
Item::Debug(_) => ("weapon.debug_wand", Vec3::new(-1.5, -9.5, -4.0)),
|
||||
_ => return Mesh::new(),
|
||||
};
|
||||
load_mesh(name, offset)
|
||||
|
Loading…
Reference in New Issue
Block a user