mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Move figure meshing to a background thread.
This commit is contained in:
parent
1aec2ac6ef
commit
3a96b73b2c
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Overhauled world colours
|
||||
- Improved projectile physics
|
||||
- Improved overhead aiming
|
||||
- Figure meshing no longer blocks the main thread.
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.acacia.1",
|
||||
center: (17, 18, 4)
|
||||
@ -20,5 +21,4 @@
|
||||
specifier: "world.tree.acacia.5",
|
||||
center: (19, 19, 4)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.birch.1",
|
||||
center: (12, 9, 10)
|
||||
@ -48,5 +49,4 @@
|
||||
specifier: "world.tree.birch.12",
|
||||
center: (9, 10, 10)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,7 @@
|
||||
(
|
||||
[ (
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.structure.dungeon.jungle_temple.entrance.1",
|
||||
center: (50, 40, 10)
|
||||
),
|
||||
@ -43,6 +45,4 @@
|
||||
specifier: "world.structure.dungeon.misc_entrance.tower-ruin",
|
||||
center: (13, 16, 9)
|
||||
),
|
||||
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.fruit.1",
|
||||
center: (6, 6, 7)
|
||||
@ -24,5 +25,4 @@
|
||||
specifier: "world.tree.fruit.6",
|
||||
center: (7, 7, 7)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.mangroves.1",
|
||||
center: (19, 18, 8)
|
||||
@ -32,5 +33,4 @@
|
||||
specifier: "world.tree.mangroves.8",
|
||||
center: (18, 19, 9)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.oak_stump.1",
|
||||
center: (15, 18, 10)
|
||||
@ -36,5 +37,4 @@
|
||||
specifier: "world.tree.oak_stump.9",
|
||||
center:(26, 26, 10)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.oak_green.1",
|
||||
center: (15, 17, 14)
|
||||
@ -36,5 +37,4 @@
|
||||
specifier: "world.tree.oak_green.9",
|
||||
center:(21, 21, 14)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.desert_palm.1",
|
||||
center: (7, 8, 2)
|
||||
@ -40,5 +41,4 @@
|
||||
specifier: "world.tree.desert_palm.10",
|
||||
center: (6, 7, 2)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.pine_green.1",
|
||||
center: (15, 15, 14)
|
||||
@ -32,5 +33,4 @@
|
||||
specifier: "world.tree.pine_green.8",
|
||||
center: (12, 10, 12)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.structure.natural.witch-hut",
|
||||
center: (10, 13, 9)
|
||||
@ -8,5 +9,4 @@
|
||||
specifier: "world.structure.natural.tree-house",
|
||||
center: (20, 15, 10)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.structure.natural.ribcage-small",
|
||||
center: (7, 13, 4)
|
||||
@ -12,5 +13,4 @@
|
||||
specifier: "world.structure.natural.skull-large",
|
||||
center: (15, 20, 4)
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
(
|
||||
[
|
||||
#![enable(unwrap_newtypes)]
|
||||
|
||||
[
|
||||
(
|
||||
specifier: "world.tree.snow_pine.1",
|
||||
center: (15, 15, 14)
|
||||
@ -31,6 +32,5 @@
|
||||
(
|
||||
specifier: "world.tree.snow_pine.8",
|
||||
center: (12, 10, 12)
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
]
|
||||
|
@ -1,14 +1,14 @@
|
||||
//! Load assets (images or voxel data) from files
|
||||
pub mod watch;
|
||||
|
||||
use core::{any::Any, fmt, marker::PhantomData};
|
||||
use dot_vox::DotVoxData;
|
||||
use hashbrown::HashMap;
|
||||
use image::DynamicImage;
|
||||
use lazy_static::lazy_static;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt,
|
||||
fs::{self, File, ReadDir},
|
||||
io::{BufReader, Read},
|
||||
path::PathBuf,
|
||||
@ -61,39 +61,70 @@ lazy_static! {
|
||||
RwLock::new(HashMap::new());
|
||||
}
|
||||
|
||||
// TODO: Remove this function. It's only used in world/ in a really ugly way.To
|
||||
// do this properly assets should have all their necessary data in one file. A
|
||||
// ron file could be used to combine voxel data with positioning data for
|
||||
// example.
|
||||
/// Function used to load assets from the filesystem or the cache. Permits
|
||||
/// manipulating the loaded asset with a mapping function. Example usage:
|
||||
/// ```no_run
|
||||
/// use vek::*;
|
||||
/// use veloren_common::{assets, terrain::Structure};
|
||||
///
|
||||
/// let my_tree_structure = assets::load_map("world.tree.oak_green.1", |s: Structure| {
|
||||
/// s.with_center(Vec3::new(15, 18, 14))
|
||||
/// })
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
pub fn load_map<A: Asset + 'static, F: FnOnce(A) -> A>(
|
||||
fn reload<A: Asset>(specifier: &str) -> Result<(), Error>
|
||||
where
|
||||
A::Output: Send + Sync + 'static,
|
||||
{
|
||||
let asset = Arc::new(A::parse(load_file(specifier, A::ENDINGS)?)?);
|
||||
let mut assets_write = ASSETS.write().unwrap();
|
||||
match assets_write.get_mut(specifier) {
|
||||
Some(a) => *a = asset,
|
||||
None => {
|
||||
assets_write.insert(specifier.to_owned(), asset);
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The Asset trait, which is implemented by all structures that have their data
|
||||
/// stored in the filesystem.
|
||||
pub trait Asset: Sized {
|
||||
type Output = Self;
|
||||
|
||||
const ENDINGS: &'static [&'static str];
|
||||
/// Parse the input file and return the correct Asset.
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self::Output, Error>;
|
||||
|
||||
// TODO: Remove this function. It's only used in world/ in a really ugly way.To
|
||||
// do this properly assets should have all their necessary data in one file. A
|
||||
// ron file could be used to combine voxel data with positioning data for
|
||||
// example.
|
||||
/// Function used to load assets from the filesystem or the cache. Permits
|
||||
/// manipulating the loaded asset with a mapping function. Example usage:
|
||||
/// ```no_run
|
||||
/// use vek::*;
|
||||
/// use veloren_common::{assets::Asset, terrain::Structure};
|
||||
///
|
||||
/// let my_tree_structure = Structure::load_map("world.tree.oak_green.1", |s: Structure| {
|
||||
/// s.with_center(Vec3::new(15, 18, 14))
|
||||
/// })
|
||||
/// .unwrap();
|
||||
/// ```
|
||||
fn load_map<F: FnOnce(Self::Output) -> Self::Output>(
|
||||
specifier: &str,
|
||||
f: F,
|
||||
) -> Result<Arc<A>, Error> {
|
||||
) -> Result<Arc<Self::Output>, Error>
|
||||
where
|
||||
Self::Output: Send + Sync + 'static,
|
||||
{
|
||||
let assets_write = ASSETS.read().unwrap();
|
||||
match assets_write.get(specifier) {
|
||||
Some(asset) => Ok(Arc::clone(asset).downcast()?),
|
||||
None => {
|
||||
drop(assets_write); // Drop the asset hashmap to permit recursive loading
|
||||
let asset = Arc::new(f(A::parse(load_file(specifier, A::ENDINGS)?)?));
|
||||
let asset = Arc::new(f(Self::parse(load_file(specifier, Self::ENDINGS)?)?));
|
||||
let clone = Arc::clone(&asset);
|
||||
ASSETS.write().unwrap().insert(specifier.to_owned(), clone);
|
||||
Ok(asset)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_glob<A: Asset + 'static>(specifier: &str) -> Result<Arc<Vec<Arc<A>>>, Error> {
|
||||
fn load_glob(specifier: &str) -> Result<Arc<Vec<Arc<Self::Output>>>, Error>
|
||||
where
|
||||
Self::Output: Send + Sync + 'static,
|
||||
{
|
||||
if let Some(assets) = ASSETS.read().unwrap().get(specifier) {
|
||||
return Ok(Arc::clone(assets).downcast()?);
|
||||
}
|
||||
@ -118,11 +149,13 @@ pub fn load_glob<A: Asset + 'static>(specifier: &str) -> Result<Arc<Vec<Arc<A>>>
|
||||
glob_matches
|
||||
.into_iter()
|
||||
.filter_map(|name| {
|
||||
load(&specifier.replace("*", &name))
|
||||
Self::load(&specifier.replace("*", &name))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
?e,
|
||||
"Failed to load \"{}\" as part of glob \"{}\"", name, specifier
|
||||
"Failed to load \"{}\" as part of glob \"{}\"",
|
||||
name,
|
||||
specifier
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
@ -137,61 +170,76 @@ pub fn load_glob<A: Asset + 'static>(specifier: &str) -> Result<Arc<Vec<Arc<A>>>
|
||||
},
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Function used to load assets from the filesystem or the cache.
|
||||
/// Example usage:
|
||||
/// ```no_run
|
||||
/// use image::DynamicImage;
|
||||
/// use veloren_common::assets;
|
||||
///
|
||||
/// let my_image = assets::load::<DynamicImage>("core.ui.backgrounds.city").unwrap();
|
||||
/// ```
|
||||
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.
|
||||
/// Example usage:
|
||||
/// ```no_run
|
||||
/// use image::DynamicImage;
|
||||
/// use veloren_common::assets::Asset;
|
||||
///
|
||||
/// let my_image = DynamicImage::load("core.ui.backgrounds.city").unwrap();
|
||||
/// ```
|
||||
fn load(specifier: &str) -> Result<Arc<Self::Output>, Error>
|
||||
where
|
||||
Self::Output: Send + Sync + 'static,
|
||||
{
|
||||
Self::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 assets from the filesystem or the cache and return
|
||||
/// a clone.
|
||||
fn load_cloned(specifier: &str) -> Result<Self::Output, Error>
|
||||
where
|
||||
Self::Output: Clone + Send + Sync + 'static,
|
||||
{
|
||||
Self::load(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
|
||||
/// use image::DynamicImage;
|
||||
/// use veloren_common::assets;
|
||||
///
|
||||
/// let my_image = assets::load_expect::<DynamicImage>("core.ui.backgrounds.city");
|
||||
/// ```
|
||||
pub fn load_expect<A: Asset + 'static>(specifier: &str) -> Arc<A> {
|
||||
load(specifier).unwrap_or_else(|err| {
|
||||
/// 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
|
||||
/// use image::DynamicImage;
|
||||
/// use veloren_common::assets::Asset;
|
||||
///
|
||||
/// let my_image = DynamicImage::load_expect("core.ui.backgrounds.city");
|
||||
/// ```
|
||||
fn load_expect(specifier: &str) -> Arc<Self::Output>
|
||||
where
|
||||
Self::Output: Send + Sync + 'static,
|
||||
{
|
||||
Self::load(specifier).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Failed loading essential asset: {} (error={:?})",
|
||||
specifier, err
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// 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()
|
||||
}
|
||||
/// 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.
|
||||
fn load_expect_cloned(specifier: &str) -> Self::Output
|
||||
where
|
||||
Self::Output: Clone + Send + Sync + 'static,
|
||||
{
|
||||
Self::load_expect(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>(
|
||||
/// Load an asset while registering it to be watched and reloaded when it
|
||||
/// changes
|
||||
fn load_watched(
|
||||
specifier: &str,
|
||||
indicator: &mut watch::ReloadIndicator,
|
||||
) -> Result<Arc<A>, Error> {
|
||||
let asset = load(specifier)?;
|
||||
) -> Result<Arc<Self::Output>, Error>
|
||||
where
|
||||
Self::Output: Send + Sync + 'static,
|
||||
{
|
||||
let asset = Self::load(specifier)?;
|
||||
|
||||
// Determine path to watch
|
||||
let path = unpack_specifier(specifier);
|
||||
let mut path_with_extension = None;
|
||||
for ending in A::ENDINGS {
|
||||
for ending in Self::ENDINGS {
|
||||
let mut path = path.clone();
|
||||
path.set_extension(ending);
|
||||
|
||||
@ -203,37 +251,17 @@ pub fn load_watched<A: Asset + 'static>(
|
||||
|
||||
let owned_specifier = specifier.to_string();
|
||||
indicator.add(
|
||||
path_with_extension.ok_or_else(|| Error::NotFound(path.to_string_lossy().into_owned()))?,
|
||||
path_with_extension
|
||||
.ok_or_else(|| Error::NotFound(path.to_string_lossy().into_owned()))?,
|
||||
move || {
|
||||
if let Err(e) = reload::<A>(&owned_specifier) {
|
||||
if let Err(e) = reload::<Self>(&owned_specifier) {
|
||||
error!(?e, ?owned_specifier, "Error reloading owned_specifier");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Ok(asset)
|
||||
}
|
||||
|
||||
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);
|
||||
let mut assets_write = ASSETS.write().unwrap();
|
||||
match assets_write.get_mut(specifier) {
|
||||
Some(a) => *a = clone,
|
||||
None => {
|
||||
assets_write.insert(specifier.to_owned(), clone);
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 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.
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
impl Asset for DynamicImage {
|
||||
@ -265,13 +293,45 @@ impl Asset for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl Asset for String {
|
||||
const ENDINGS: &'static [&'static str] = &["glsl"];
|
||||
/// Load fron an arbitrary RON file.
|
||||
pub struct Ron<T>(pub PhantomData<T>);
|
||||
|
||||
fn parse(mut buf_reader: BufReader<File>) -> Result<Self, Error> {
|
||||
let mut string = String::new();
|
||||
buf_reader.read_to_string(&mut string)?;
|
||||
Ok(string)
|
||||
impl<T: Send + Sync + for<'de> Deserialize<'de>> Asset for Ron<T> {
|
||||
type Output = T;
|
||||
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<T, Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(Error::parse_error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Load from a specific asset path.
|
||||
pub struct AssetWith<T: Asset, const ASSET_PATH: &'static str> {
|
||||
pub asset: Arc<T::Output>,
|
||||
}
|
||||
|
||||
impl<T: Asset, const ASSET_PATH: &'static str> Clone for AssetWith<T, ASSET_PATH> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
asset: Arc::clone(&self.asset),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Asset, const ASSET_PATH: &'static str> AssetWith<T, ASSET_PATH>
|
||||
where
|
||||
T::Output: Send + Sync + 'static,
|
||||
{
|
||||
#[inline]
|
||||
pub fn load_watched(indicator: &mut watch::ReloadIndicator) -> Result<Self, Error> {
|
||||
T::load_watched(ASSET_PATH, indicator).map(|asset| Self { asset })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reload(&mut self) -> Result<(), Error> {
|
||||
self.asset = T::load(ASSET_PATH)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ pub mod tool;
|
||||
pub use tool::{Hands, Tool, ToolCategory, ToolKind};
|
||||
|
||||
use crate::{
|
||||
assets::{self, Asset},
|
||||
assets::{self, Asset, Ron},
|
||||
effect::Effect,
|
||||
lottery::Lottery,
|
||||
terrain::{Block, BlockKind},
|
||||
@ -14,7 +14,6 @@ use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::{fs::File, io::BufReader};
|
||||
use vek::Rgb;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -90,13 +89,7 @@ pub struct Item {
|
||||
pub kind: ItemKind,
|
||||
}
|
||||
|
||||
impl Asset for Item {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
|
||||
}
|
||||
}
|
||||
pub type ItemAsset = Ron<Item>;
|
||||
|
||||
impl Item {
|
||||
// TODO: consider alternatives such as default abilities that can be added to a
|
||||
@ -109,7 +102,7 @@ impl Item {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_from_asset(asset: &str) -> Self { (*assets::load_expect::<Self>(asset)).clone() }
|
||||
pub fn expect_from_asset(asset: &str) -> Self { (*ItemAsset::load_expect(asset)).clone() }
|
||||
|
||||
pub fn set_amount(&mut self, give_amount: u32) -> Result<(), assets::Error> {
|
||||
use ItemKind::*;
|
||||
@ -145,75 +138,44 @@ impl Item {
|
||||
}
|
||||
|
||||
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
||||
let chosen;
|
||||
let mut rng = rand::thread_rng();
|
||||
match block.kind() {
|
||||
BlockKind::Apple => Some(assets::load_expect_cloned("common.items.food.apple")),
|
||||
BlockKind::Mushroom => Some(assets::load_expect_cloned("common.items.food.mushroom")),
|
||||
BlockKind::Velorite => Some(assets::load_expect_cloned("common.items.ore.velorite")),
|
||||
BlockKind::VeloriteFrag => {
|
||||
Some(assets::load_expect_cloned("common.items.ore.veloritefrag"))
|
||||
},
|
||||
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::Coconut => Some(assets::load_expect_cloned("common.items.food.coconut")),
|
||||
Some(ItemAsset::load_expect_cloned(match block.kind() {
|
||||
BlockKind::Apple => "common.items.food.apple",
|
||||
BlockKind::Mushroom => "common.items.food.mushroom",
|
||||
BlockKind::Velorite => "common.items.ore.velorite",
|
||||
BlockKind::VeloriteFrag => "common.items.ore.veloritefrag",
|
||||
BlockKind::BlueFlower => "common.items.flowers.blue",
|
||||
BlockKind::PinkFlower => "common.items.flowers.pink",
|
||||
BlockKind::PurpleFlower => "common.items.flowers.purple",
|
||||
BlockKind::RedFlower => "common.items.flowers.red",
|
||||
BlockKind::WhiteFlower => "common.items.flowers.white",
|
||||
BlockKind::YellowFlower => "common.items.flowers.yellow",
|
||||
BlockKind::Sunflower => "common.items.flowers.sun",
|
||||
BlockKind::LongGrass => "common.items.grasses.long",
|
||||
BlockKind::MediumGrass => "common.items.grasses.medium",
|
||||
BlockKind::ShortGrass => "common.items.grasses.short",
|
||||
BlockKind::Coconut => "common.items.food.coconut",
|
||||
BlockKind::Chest => {
|
||||
let chosen = match rng.gen_range(0, 7) {
|
||||
0 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_uncommon",
|
||||
),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_common",
|
||||
),
|
||||
2 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_light",
|
||||
),
|
||||
3 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_cloth",
|
||||
),
|
||||
4 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_heavy",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
};
|
||||
let chosen = chosen.choose();
|
||||
Some(assets::load_expect_cloned(chosen))
|
||||
chosen = Lottery::<String>::load_expect(match rng.gen_range(0, 7) {
|
||||
0 => "common.loot_tables.loot_table_weapon_uncommon",
|
||||
1 => "common.loot_tables.loot_table_weapon_common",
|
||||
2 => "common.loot_tables.loot_table_armor_light",
|
||||
3 => "common.loot_tables.loot_table_armor_cloth",
|
||||
4 => "common.loot_tables.loot_table_armor_heavy",
|
||||
_ => "common.loot_tables.loot_table_armor_misc",
|
||||
});
|
||||
chosen.choose()
|
||||
},
|
||||
BlockKind::Crate => {
|
||||
let chosen =
|
||||
assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food");
|
||||
let chosen = chosen.choose();
|
||||
|
||||
Some(assets::load_expect_cloned(chosen))
|
||||
chosen = Lottery::<String>::load_expect("common.loot_tables.loot_table_food");
|
||||
chosen.choose()
|
||||
},
|
||||
BlockKind::Stones => Some(assets::load_expect_cloned(
|
||||
"common.items.crafting_ing.stones",
|
||||
)),
|
||||
BlockKind::Twigs => Some(assets::load_expect_cloned(
|
||||
"common.items.crafting_ing.twigs",
|
||||
)),
|
||||
BlockKind::ShinyGem => Some(assets::load_expect_cloned(
|
||||
"common.items.crafting_ing.shiny_gem",
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
BlockKind::Stones => "common.items.crafting_ing.stones",
|
||||
BlockKind::Twigs => "common.items.crafting_ing.twigs",
|
||||
BlockKind::ShinyGem => "common.items.crafting_ing.shiny_gem",
|
||||
_ => return None,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Determines whether two items are superficially equivalent to one another
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub mod item;
|
||||
pub mod slot;
|
||||
|
||||
use crate::{assets, recipe::Recipe};
|
||||
use item::{Item, ItemKind};
|
||||
use crate::{assets::Asset, recipe::Recipe};
|
||||
use item::{Item, ItemAsset, ItemKind};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage, HashMapStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -517,8 +517,8 @@ impl Default for Inventory {
|
||||
slots: vec![None; 36],
|
||||
amount: 0,
|
||||
};
|
||||
inventory.push(assets::load_expect_cloned("common.items.food.cheese"));
|
||||
inventory.push(assets::load_expect_cloned("common.items.food.apple"));
|
||||
inventory.push(ItemAsset::load_expect_cloned("common.items.food.cheese"));
|
||||
inventory.push(ItemAsset::load_expect_cloned("common.items.food.apple"));
|
||||
inventory
|
||||
}
|
||||
}
|
||||
|
@ -266,15 +266,16 @@ pub fn swap(
|
||||
///
|
||||
/// ```
|
||||
/// use veloren_common::{
|
||||
/// assets,
|
||||
/// assets::Asset,
|
||||
/// comp::{
|
||||
/// item::ItemAsset,
|
||||
/// slot::{equip, EquipSlot},
|
||||
/// Inventory, Item,
|
||||
/// },
|
||||
/// LoadoutBuilder,
|
||||
/// };
|
||||
///
|
||||
/// let boots: Option<Item> = Some(assets::load_expect_cloned(
|
||||
/// let boots: Option<Item> = Some(ItemAsset::load_expect_cloned(
|
||||
/// "common.items.testing.test_boots",
|
||||
/// ));
|
||||
///
|
||||
@ -361,7 +362,7 @@ pub fn unequip(slot: EquipSlot, inventory: &mut Inventory, loadout: &mut Loadout
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{assets, LoadoutBuilder};
|
||||
use crate::{assets::Asset, comp::item::ItemAsset, LoadoutBuilder};
|
||||
|
||||
#[test]
|
||||
fn test_unequip_items_both_hands() {
|
||||
@ -396,11 +397,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_equip_item() {
|
||||
let boots: Option<comp::Item> = Some(assets::load_expect_cloned(
|
||||
let boots: Option<comp::Item> = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.testing.test_boots",
|
||||
));
|
||||
|
||||
let starting_sandles: Option<comp::Item> = Some(assets::load_expect_cloned(
|
||||
let starting_sandles: Option<comp::Item> = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.sandals_0",
|
||||
));
|
||||
|
||||
@ -425,11 +426,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_loadout_replace() {
|
||||
let boots: Option<comp::Item> = Some(assets::load_expect_cloned(
|
||||
let boots: Option<comp::Item> = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.testing.test_boots",
|
||||
));
|
||||
|
||||
let starting_sandles: Option<comp::Item> = Some(assets::load_expect_cloned(
|
||||
let starting_sandles: Option<comp::Item> = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.sandals_0",
|
||||
));
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
use super::*;
|
||||
use crate::assets::Asset;
|
||||
use lazy_static::lazy_static;
|
||||
lazy_static! {
|
||||
static ref TEST_ITEMS: Vec<Item> = vec![
|
||||
assets::load_expect_cloned("common.items.debug.boost"),
|
||||
assets::load_expect_cloned("common.items.debug.possess")
|
||||
item::ItemAsset::load_expect_cloned("common.items.debug.boost"),
|
||||
item::ItemAsset::load_expect_cloned("common.items.debug.possess")
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
#![deny(unsafe_code)]
|
||||
#![allow(clippy::option_map_unit_fn)]
|
||||
#![allow(incomplete_features)]
|
||||
#![type_length_limit = "1664759"]
|
||||
#![feature(
|
||||
arbitrary_enum_discriminant,
|
||||
associated_type_defaults,
|
||||
const_checked_int_methods,
|
||||
const_generics,
|
||||
fundamental,
|
||||
option_unwrap_none,
|
||||
bool_to_option,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
comp::{
|
||||
item::{Item, ItemKind},
|
||||
item::{Item, ItemAsset, ItemKind},
|
||||
Body, CharacterAbility, ItemConfig, Loadout,
|
||||
},
|
||||
};
|
||||
@ -48,16 +48,16 @@ impl LoadoutBuilder {
|
||||
/// Set default armor items for the loadout. This may vary with game
|
||||
/// updates, but should be safe defaults for a new character.
|
||||
pub fn defaults(self) -> Self {
|
||||
self.chest(Some(assets::load_expect_cloned(
|
||||
self.chest(Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.rugged_chest",
|
||||
)))
|
||||
.pants(Some(assets::load_expect_cloned(
|
||||
.pants(Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.rugged_pants",
|
||||
)))
|
||||
.foot(Some(assets::load_expect_cloned(
|
||||
.foot(Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.sandals_0",
|
||||
)))
|
||||
.lantern(Some(assets::load_expect_cloned(
|
||||
.lantern(Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.lantern",
|
||||
)))
|
||||
}
|
||||
@ -66,7 +66,7 @@ impl LoadoutBuilder {
|
||||
pub fn animal(body: Body) -> Self {
|
||||
Self(Loadout {
|
||||
active_item: Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.empty.empty"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.empty.empty"),
|
||||
ability1: Some(CharacterAbility::BasicMelee {
|
||||
energy_cost: 10,
|
||||
buildup_duration: Duration::from_millis(600),
|
||||
@ -125,7 +125,7 @@ impl LoadoutBuilder {
|
||||
/// Get an [Item](../comp/struct.Item.html) by its string
|
||||
/// reference by loading its asset
|
||||
pub fn item_from_str(item_ref: Option<&str>) -> Option<Item> {
|
||||
item_ref.and_then(|specifier| assets::load_cloned::<Item>(&specifier).ok())
|
||||
item_ref.and_then(|specifier| ItemAsset::load_cloned(&specifier).ok())
|
||||
}
|
||||
|
||||
/// Get an item's (weapon's) default
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::assets::{self, Asset};
|
||||
use rand::prelude::*;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use std::{fs::File, io::BufReader};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
pub struct Lottery<T> {
|
||||
items: Vec<(f32, T)>,
|
||||
total: f32,
|
||||
@ -48,14 +48,14 @@ impl<T> Lottery<T> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{assets, comp::Item};
|
||||
use crate::comp::item::ItemAsset;
|
||||
#[test]
|
||||
fn test_loot_table() {
|
||||
let test = assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table");
|
||||
let test = Lottery::<String>::load_expect("common.loot_tables.loot_table");
|
||||
|
||||
for (_, item) in test.iter() {
|
||||
assert!(
|
||||
assets::load::<Item>(item).is_ok(),
|
||||
ItemAsset::load(item).is_ok(),
|
||||
"Invalid loot table item '{}'",
|
||||
item
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
comp::{self, AllBodies, Body},
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
@ -63,7 +63,7 @@ pub struct SpeciesNames {
|
||||
pub type NpcNames = AllBodies<BodyNames, SpeciesNames>;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref NPC_NAMES: Arc<NpcNames> = assets::load_expect("common.npc_names");
|
||||
pub static ref NPC_NAMES: Arc<NpcNames> = NpcNames::load_expect("common.npc_names");
|
||||
}
|
||||
|
||||
impl FromStr for NpcKind {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
assets::{self, Asset},
|
||||
comp::{Inventory, Item},
|
||||
comp::{item::ItemAsset, Inventory, Item},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -78,12 +78,12 @@ impl Asset for RecipeBook {
|
||||
.map::<Result<(String, Recipe), assets::Error>, _>(
|
||||
|(name, ((output, amount), inputs))| {
|
||||
Ok((name, Recipe {
|
||||
output: ((&*assets::load::<Item>(&output)?).clone(), amount),
|
||||
output: ((&*ItemAsset::load(&output)?).clone(), amount),
|
||||
inputs: inputs
|
||||
.into_iter()
|
||||
.map::<Result<(Item, usize), assets::Error>, _>(
|
||||
|(name, amount)| {
|
||||
Ok(((&*assets::load::<Item>(&name)?).clone(), amount))
|
||||
Ok(((&*ItemAsset::load(&name)?).clone(), amount))
|
||||
},
|
||||
)
|
||||
.collect::<Result<_, _>>()?,
|
||||
@ -96,4 +96,4 @@ impl Asset for RecipeBook {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_recipe_book() -> Arc<RecipeBook> { assets::load_expect("common.recipe_book") }
|
||||
pub fn default_recipe_book() -> Arc<RecipeBook> { RecipeBook::load_expect("common.recipe_book") }
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::BlockKind;
|
||||
use crate::{
|
||||
assets::{self, Asset},
|
||||
assets::{self, Asset, Ron},
|
||||
make_case_elim,
|
||||
vol::{BaseVol, ReadVol, SizedVol, Vox, WriteVol},
|
||||
volumes::dyna::{Dyna, DynaError},
|
||||
@ -53,14 +53,10 @@ pub struct Structure {
|
||||
|
||||
impl Structure {
|
||||
pub fn load_group(specifier: &str) -> Vec<Arc<Structure>> {
|
||||
let spec = assets::load::<StructuresSpec>(&["world.manifests.", specifier].concat());
|
||||
spec.unwrap()
|
||||
.0
|
||||
.iter()
|
||||
let spec = StructuresSpec::load_expect(&["world.manifests.", specifier].concat());
|
||||
spec.iter()
|
||||
.map(|sp| {
|
||||
assets::load_map(&sp.specifier[..], |s: Structure| {
|
||||
s.with_center(Vec3::from(sp.center))
|
||||
})
|
||||
Structure::load_map(&sp.specifier[..], |s| s.with_center(Vec3::from(sp.center)))
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
@ -170,13 +166,5 @@ struct StructureSpec {
|
||||
specifier: String,
|
||||
center: [i32; 3],
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct StructuresSpec(Vec<StructureSpec>);
|
||||
|
||||
impl Asset for StructuresSpec {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
|
||||
}
|
||||
}
|
||||
type StructuresSpec = Ron<Vec<StructureSpec>>;
|
||||
|
@ -5,9 +5,9 @@
|
||||
use crate::{client::Client, Server, StateExt};
|
||||
use chrono::{NaiveTime, Timelike};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
|
||||
comp::{self, ChatType, Item, LightEmitter, WaypointArea},
|
||||
comp::{self, item::ItemAsset, ChatType, Item, LightEmitter, WaypointArea},
|
||||
event::{EventBus, ServerEvent},
|
||||
msg::{Notification, PlayerListUpdate, ServerMsg},
|
||||
npc::{self, get_npc_name},
|
||||
@ -117,7 +117,7 @@ fn handle_give_item(
|
||||
scan_fmt_some!(&args, &action.arg_fmt(), String, u32)
|
||||
{
|
||||
let give_amount = give_amount_opt.unwrap_or(1);
|
||||
if let Ok(item) = assets::load_cloned(&item_name) {
|
||||
if let Ok(item) = ItemAsset::load_cloned(&item_name) {
|
||||
let mut item: Item = item;
|
||||
if let Ok(()) = item.set_amount(give_amount.min(2000)) {
|
||||
server
|
||||
@ -1640,7 +1640,7 @@ fn handle_debug(
|
||||
_args: String,
|
||||
_action: &ChatCommand,
|
||||
) {
|
||||
if let Ok(items) = assets::load_glob::<Item>("common.items.debug.*") {
|
||||
if let Ok(items) = ItemAsset::load_glob("common.items.debug.*") {
|
||||
server
|
||||
.state()
|
||||
.ecs()
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{client::Client, comp::quadruped_small, Server, SpawnPoint, StateExt};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
comp::{
|
||||
self, object, Alignment, Body, Damage, DamageSource, Group, HealthChange, HealthSource,
|
||||
Player, Pos, Stats,
|
||||
self, item::ItemAsset, object, Alignment, Body, Damage, DamageSource, Group, HealthChange,
|
||||
HealthSource, Player, Pos, Stats,
|
||||
},
|
||||
lottery::Lottery,
|
||||
msg::{PlayerListUpdate, ServerMsg},
|
||||
@ -186,130 +186,68 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
// Decide for a loot drop before turning into a lootbag
|
||||
let old_body = state.ecs().write_storage::<Body>().remove(entity);
|
||||
let mut rng = rand::thread_rng();
|
||||
let drop = match old_body {
|
||||
let drop = Lottery::<String>::load_expect(match old_body {
|
||||
Some(common::comp::Body::Humanoid(_)) => match rng.gen_range(0, 4) {
|
||||
0 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_humanoids",
|
||||
),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_light",
|
||||
),
|
||||
2 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_cloth",
|
||||
),
|
||||
3 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_common",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_humanoids",
|
||||
),
|
||||
0 => "common.loot_tables.loot_table_humanoids",
|
||||
1 => "common.loot_tables.loot_table_armor_light",
|
||||
2 => "common.loot_tables.loot_table_armor_cloth",
|
||||
3 => "common.loot_tables.loot_table_weapon_common",
|
||||
_ => "common.loot_tables.loot_table_humanoids",
|
||||
},
|
||||
Some(common::comp::Body::QuadrupedSmall(quadruped_small)) => {
|
||||
match quadruped_small.species {
|
||||
quadruped_small::Species::Dodarock => match rng.gen_range(0, 6) {
|
||||
0 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_rocks",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_rocks",
|
||||
),
|
||||
0 => "common.loot_tables.loot_table_armor_misc",
|
||||
1 => "common.loot_tables.loot_table_rocks",
|
||||
_ => "common.loot_tables.loot_table_rocks",
|
||||
},
|
||||
_ => match rng.gen_range(0, 4) {
|
||||
0 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_food",
|
||||
),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
2 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_animal_parts",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_animal_parts",
|
||||
),
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_armor_misc",
|
||||
2 => "common.loot_tables.loot_table_animal_parts",
|
||||
_ => "common.loot_tables.loot_table_animal_parts",
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(common::comp::Body::QuadrupedMedium(_)) => match rng.gen_range(0, 4) {
|
||||
0 => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food"),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
2 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_animal_parts",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_animal_parts",
|
||||
),
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_armor_misc",
|
||||
2 => "common.loot_tables.loot_table_animal_parts",
|
||||
_ => "common.loot_tables.loot_table_animal_parts",
|
||||
},
|
||||
Some(common::comp::Body::BirdMedium(_)) => match rng.gen_range(0, 3) {
|
||||
0 => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food"),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table"),
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_armor_misc",
|
||||
_ => "common.loot_tables.loot_table",
|
||||
},
|
||||
Some(common::comp::Body::BipedLarge(_)) => match rng.gen_range(0, 8) {
|
||||
0 => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food"),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_nature",
|
||||
),
|
||||
3 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_heavy",
|
||||
),
|
||||
5 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_uncommon",
|
||||
),
|
||||
6 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_rare",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_cave_large",
|
||||
),
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_armor_nature",
|
||||
3 => "common.loot_tables.loot_table_armor_heavy",
|
||||
5 => "common.loot_tables.loot_table_weapon_uncommon",
|
||||
6 => "common.loot_tables.loot_table_weapon_rare",
|
||||
_ => "common.loot_tables.loot_table_cave_large",
|
||||
},
|
||||
Some(common::comp::Body::Golem(_)) => match rng.gen_range(0, 9) {
|
||||
0 => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food"),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
2 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_light",
|
||||
),
|
||||
3 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_heavy",
|
||||
),
|
||||
4 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_armor_misc",
|
||||
),
|
||||
5 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_common",
|
||||
),
|
||||
6 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_uncommon",
|
||||
),
|
||||
7 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_weapon_rare",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table"),
|
||||
},
|
||||
Some(common::comp::Body::Critter(_)) => {
|
||||
assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_animal_parts")
|
||||
},
|
||||
Some(common::comp::Body::Dragon(_)) => {
|
||||
assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_weapon_rare")
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_armor_misc",
|
||||
2 => "common.loot_tables.loot_table_armor_light",
|
||||
3 => "common.loot_tables.loot_table_armor_heavy",
|
||||
4 => "common.loot_tables.loot_table_armor_misc",
|
||||
5 => "common.loot_tables.loot_table_weapon_common",
|
||||
6 => "common.loot_tables.loot_table_weapon_uncommon",
|
||||
7 => "common.loot_tables.loot_table_weapon_rare",
|
||||
_ => "common.loot_tables.loot_table",
|
||||
},
|
||||
Some(common::comp::Body::Critter(_)) => "common.loot_tables.loot_table_animal_parts",
|
||||
Some(common::comp::Body::Dragon(_)) => "common.loot_tables.loot_table_weapon_rare",
|
||||
Some(common::comp::Body::QuadrupedLow(_)) => match rng.gen_range(0, 3) {
|
||||
0 => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table_food"),
|
||||
1 => assets::load_expect::<Lottery<String>>(
|
||||
"common.loot_tables.loot_table_animal_parts",
|
||||
),
|
||||
_ => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table"),
|
||||
0 => "common.loot_tables.loot_table_food",
|
||||
1 => "common.loot_tables.loot_table_animal_parts",
|
||||
_ => "common.loot_tables.loot_table",
|
||||
},
|
||||
_ => assets::load_expect::<Lottery<String>>("common.loot_tables.loot_table"),
|
||||
};
|
||||
_ => "common.loot_tables.loot_table",
|
||||
});
|
||||
let drop = drop.choose();
|
||||
// Replace npc with lootbag containing drop
|
||||
let _ = state
|
||||
@ -321,7 +259,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
item_drops.remove(entity);
|
||||
item_drop.0
|
||||
} else {
|
||||
assets::load_expect_cloned(drop)
|
||||
ItemAsset::load_expect_cloned(drop)
|
||||
};
|
||||
|
||||
let _ = state.ecs().write_storage().insert(entity, item);
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
Server,
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
comp::{self, item},
|
||||
msg::ServerMsg,
|
||||
sync::{Uid, WorldSyncExt},
|
||||
@ -125,7 +125,7 @@ pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) {
|
||||
.expect("Could not read loadouts component while possessing")
|
||||
.or_insert(comp::Loadout::default());
|
||||
|
||||
let item = assets::load_expect_cloned::<comp::Item>("common.items.debug.possess");
|
||||
let item = item::ItemAsset::load_expect_cloned("common.items.debug.possess");
|
||||
if let item::ItemKind::Tool(tool) = &item.kind {
|
||||
let mut abilities = tool.get_abilities();
|
||||
let mut ability_drain = abilities.drain(..);
|
||||
|
@ -1,8 +1,12 @@
|
||||
use super::SysTimer;
|
||||
use crate::{chunk_generator::ChunkGenerator, client::Client, Tick};
|
||||
use common::{
|
||||
assets,
|
||||
comp::{self, bird_medium, item, Alignment, CharacterAbility, ItemConfig, Player, Pos},
|
||||
assets::Asset,
|
||||
comp::{
|
||||
self, bird_medium,
|
||||
item::{self, ItemAsset},
|
||||
Alignment, CharacterAbility, ItemConfig, Player, Pos,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
generation::get_npc_name,
|
||||
msg::ServerMsg,
|
||||
@ -135,7 +139,7 @@ impl<'a> System<'a> for Sys {
|
||||
} else {
|
||||
Some(ItemConfig {
|
||||
// We need the empty item so npcs can attack
|
||||
item: assets::load_expect_cloned("common.items.weapons.empty.empty"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.empty.empty"),
|
||||
ability1: Some(CharacterAbility::BasicMelee {
|
||||
energy_cost: 0,
|
||||
buildup_duration: Duration::from_millis(0),
|
||||
@ -156,7 +160,7 @@ impl<'a> System<'a> for Sys {
|
||||
active_item,
|
||||
second_item: None,
|
||||
shoulder: None,
|
||||
chest: Some(assets::load_expect_cloned(
|
||||
chest: Some(ItemAsset::load_expect_cloned(
|
||||
match rand::thread_rng().gen_range(0, 10) {
|
||||
0 => "common.items.npc_armor.chest.worker_green_0",
|
||||
1 => "common.items.npc_armor.chest.worker_green_1",
|
||||
@ -170,14 +174,14 @@ impl<'a> System<'a> for Sys {
|
||||
_ => "common.items.npc_armor.chest.worker_orange_1",
|
||||
},
|
||||
)),
|
||||
belt: Some(assets::load_expect_cloned(
|
||||
belt: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.belt.leather_0",
|
||||
)),
|
||||
hand: None,
|
||||
pants: Some(assets::load_expect_cloned(
|
||||
pants: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.pants.worker_blue_0",
|
||||
)),
|
||||
foot: Some(assets::load_expect_cloned(
|
||||
foot: Some(ItemAsset::load_expect_cloned(
|
||||
match rand::thread_rng().gen_range(0, 2) {
|
||||
0 => "common.items.armor.foot.leather_0",
|
||||
_ => "common.items.armor.starter.sandals_0",
|
||||
@ -193,30 +197,32 @@ impl<'a> System<'a> for Sys {
|
||||
comp::Alignment::Enemy => comp::Loadout {
|
||||
active_item,
|
||||
second_item: None,
|
||||
shoulder: Some(assets::load_expect_cloned(
|
||||
shoulder: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.shoulder.cultist_shoulder_purple",
|
||||
)),
|
||||
chest: Some(assets::load_expect_cloned(
|
||||
chest: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.chest.cultist_chest_purple",
|
||||
)),
|
||||
belt: Some(assets::load_expect_cloned(
|
||||
belt: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.belt.cultist_belt",
|
||||
)),
|
||||
hand: Some(assets::load_expect_cloned(
|
||||
hand: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.hand.cultist_hands_purple",
|
||||
)),
|
||||
pants: Some(assets::load_expect_cloned(
|
||||
pants: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.pants.cultist_legs_purple",
|
||||
)),
|
||||
foot: Some(assets::load_expect_cloned(
|
||||
foot: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.foot.cultist_boots",
|
||||
)),
|
||||
back: Some(assets::load_expect_cloned(
|
||||
back: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_armor.back.dungeon_purple-0",
|
||||
)),
|
||||
ring: None,
|
||||
neck: None,
|
||||
lantern: Some(assets::load_expect_cloned("common.items.lantern.black_0")),
|
||||
lantern: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.lantern.black_0",
|
||||
)),
|
||||
head: None,
|
||||
tabard: None,
|
||||
},
|
||||
@ -259,7 +265,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
loadout = comp::Loadout {
|
||||
active_item: Some(comp::ItemConfig {
|
||||
item: assets::load_expect_cloned(
|
||||
item: ItemAsset::load_expect_cloned(
|
||||
"common.items.npc_weapons.sword.zweihander_sword_0",
|
||||
),
|
||||
ability1: Some(CharacterAbility::BasicMelee {
|
||||
@ -276,22 +282,22 @@ impl<'a> System<'a> for Sys {
|
||||
dodge_ability: None,
|
||||
}),
|
||||
second_item: None,
|
||||
shoulder: Some(assets::load_expect_cloned(
|
||||
shoulder: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.shoulder.plate_0",
|
||||
)),
|
||||
chest: Some(assets::load_expect_cloned(
|
||||
chest: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.chest.plate_green_0",
|
||||
)),
|
||||
belt: Some(assets::load_expect_cloned(
|
||||
belt: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.belt.plate_0",
|
||||
)),
|
||||
hand: Some(assets::load_expect_cloned(
|
||||
hand: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.hand.plate_0",
|
||||
)),
|
||||
pants: Some(assets::load_expect_cloned(
|
||||
pants: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.pants.plate_green_0",
|
||||
)),
|
||||
foot: Some(assets::load_expect_cloned(
|
||||
foot: Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.foot.plate_0",
|
||||
)),
|
||||
back: None,
|
||||
|
@ -5,10 +5,14 @@ use std::{
|
||||
};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use common::{assets, comp};
|
||||
use common::{
|
||||
assets::{self, Asset},
|
||||
comp,
|
||||
};
|
||||
use comp::item::{
|
||||
armor::{ArmorKind, Protection},
|
||||
tool::ToolKind,
|
||||
ItemAsset,
|
||||
};
|
||||
|
||||
#[derive(StructOpt)]
|
||||
@ -43,7 +47,7 @@ fn armor_stats() -> Result<(), Box<dyn Error>> {
|
||||
.to_string()
|
||||
.replace("/", ".");
|
||||
|
||||
let asset = assets::load_expect_cloned::<comp::Item>(asset_identifier);
|
||||
let asset = ItemAsset::load_expect_cloned(asset_identifier);
|
||||
|
||||
match &asset.kind {
|
||||
comp::item::ItemKind::Armor(armor) => {
|
||||
@ -109,7 +113,7 @@ fn weapon_stats() -> Result<(), Box<dyn Error>> {
|
||||
.display()
|
||||
.to_string()
|
||||
.replace("/", ".");
|
||||
let asset = assets::load_expect_cloned::<comp::Item>(asset_identifier);
|
||||
let asset = ItemAsset::load_expect_cloned(asset_identifier);
|
||||
|
||||
match &asset.kind {
|
||||
comp::item::ItemKind::Tool(tool) => {
|
||||
|
@ -10,10 +10,12 @@ pub use self::{
|
||||
wield::WieldAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::biped_large::Body;
|
||||
|
||||
skeleton_impls!(struct BipedLargeSkeleton {
|
||||
+ head,
|
||||
+ jaw,
|
||||
@ -36,6 +38,7 @@ skeleton_impls!(struct BipedLargeSkeleton {
|
||||
|
||||
impl Skeleton for BipedLargeSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 15;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -115,8 +118,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::biped_large::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::biped_large::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::biped_large::{BodyType::*, Species::*};
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
|
@ -6,10 +6,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{feed::FeedAnimation, fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::bird_medium::Body;
|
||||
|
||||
skeleton_impls!(struct BirdMediumSkeleton {
|
||||
+ head,
|
||||
+ torso,
|
||||
@ -22,6 +24,7 @@ skeleton_impls!(struct BirdMediumSkeleton {
|
||||
|
||||
impl Skeleton for BirdMediumSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 7;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -82,8 +85,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::bird_medium::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::bird_medium::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::bird_medium::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::bird_small::Body;
|
||||
|
||||
skeleton_impls!(struct BirdSmallSkeleton {
|
||||
+ head,
|
||||
+ torso,
|
||||
@ -18,6 +20,7 @@ skeleton_impls!(struct BirdSmallSkeleton {
|
||||
|
||||
impl Skeleton for BirdSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 4;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -59,6 +62,6 @@ impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::bird_small::Body> for SkeletonAttr {
|
||||
fn from(_body: &'a comp::bird_small::Body) -> Self { Self }
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
||||
|
@ -36,10 +36,12 @@ pub use self::{
|
||||
swimwield::SwimWieldAnimation, wield::WieldAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp;
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::humanoid::Body;
|
||||
|
||||
skeleton_impls!(struct CharacterSkeleton {
|
||||
+ head,
|
||||
+ chest,
|
||||
@ -65,6 +67,7 @@ skeleton_impls!(struct CharacterSkeleton {
|
||||
|
||||
impl Skeleton for CharacterSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 16;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -156,7 +159,7 @@ impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
}
|
||||
|
||||
impl SkeletonAttr {
|
||||
pub fn calculate_scale(body: &comp::humanoid::Body) -> f32 {
|
||||
pub fn calculate_scale(body: &Body) -> f32 {
|
||||
use comp::humanoid::{BodyType::*, Species::*};
|
||||
match (body.species, body.body_type) {
|
||||
(Orc, Male) => 1.14,
|
||||
@ -175,9 +178,9 @@ impl SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
#[allow(clippy::match_single_binding)] // TODO: Pending review in #587
|
||||
fn from(body: &'a comp::humanoid::Body) -> Self {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::humanoid::{BodyType::*, Species::*};
|
||||
Self {
|
||||
scaler: SkeletonAttr::calculate_scale(body),
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::critter::Body;
|
||||
|
||||
skeleton_impls!(struct CritterSkeleton {
|
||||
+ head,
|
||||
+ chest,
|
||||
@ -27,6 +29,7 @@ pub struct CritterAttr {
|
||||
|
||||
impl Skeleton for CritterSkeleton {
|
||||
type Attr = CritterAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 5;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -84,8 +87,8 @@ impl Default for CritterAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::critter::Body> for CritterAttr {
|
||||
fn from(body: &'a comp::critter::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for CritterAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::critter::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::dragon::Body;
|
||||
|
||||
skeleton_impls!(struct DragonSkeleton {
|
||||
+ head_upper,
|
||||
+ head_lower,
|
||||
@ -29,6 +31,7 @@ skeleton_impls!(struct DragonSkeleton {
|
||||
|
||||
impl Skeleton for DragonSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 15;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -115,8 +118,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::dragon::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::dragon::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::dragon::Species::*;
|
||||
Self {
|
||||
head_upper: match (body.species, body.body_type) {
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::fish_medium::Body;
|
||||
|
||||
skeleton_impls!(struct FishMediumSkeleton {
|
||||
+ head,
|
||||
+ torso,
|
||||
@ -20,6 +22,7 @@ skeleton_impls!(struct FishMediumSkeleton {
|
||||
|
||||
impl Skeleton for FishMediumSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 6;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -63,6 +66,6 @@ impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::fish_medium::Body> for SkeletonAttr {
|
||||
fn from(_body: &'a comp::fish_medium::Body) -> Self { Self }
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::fish_small::Body;
|
||||
|
||||
skeleton_impls!(struct FishSmallSkeleton {
|
||||
+ torso,
|
||||
+ tail,
|
||||
@ -16,6 +18,7 @@ skeleton_impls!(struct FishSmallSkeleton {
|
||||
|
||||
impl Skeleton for FishSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 2;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -55,6 +58,6 @@ impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::fish_small::Body> for SkeletonAttr {
|
||||
fn from(_body: &'a comp::fish_small::Body) -> Self { Self }
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
|
||||
pub type Body = ();
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct FixtureSkeleton;
|
||||
|
||||
@ -17,6 +19,7 @@ impl<'a, Factor> Lerp<Factor> for &'a FixtureSkeleton {
|
||||
|
||||
impl Skeleton for FixtureSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 1;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -33,3 +36,11 @@ impl Skeleton for FixtureSkeleton {
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
||||
|
@ -5,10 +5,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::golem::Body;
|
||||
|
||||
skeleton_impls!(struct GolemSkeleton {
|
||||
+ head,
|
||||
+ upper_torso,
|
||||
@ -25,6 +27,7 @@ skeleton_impls!(struct GolemSkeleton {
|
||||
|
||||
impl Skeleton for GolemSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 10;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -90,8 +93,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::golem::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::golem::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::golem::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
|
@ -9,14 +9,14 @@ macro_rules! skeleton_impls {
|
||||
#[derive(Clone, Default)]
|
||||
pub struct $Skeleton {
|
||||
$(
|
||||
$bone: Bone,
|
||||
$bone: $crate::Bone,
|
||||
)*
|
||||
}
|
||||
|
||||
impl<'a, Factor> Lerp<Factor> for &'a $Skeleton
|
||||
impl<'a, Factor> $crate::vek::Lerp<Factor> for &'a $Skeleton
|
||||
where
|
||||
Factor: Copy,
|
||||
Bone: Lerp<Factor, Output=Bone>
|
||||
$crate::Bone: Lerp<Factor, Output=$crate::Bone>
|
||||
{
|
||||
type Output = $Skeleton;
|
||||
|
||||
@ -79,6 +79,7 @@ pub type Bone = Transform<f32, f32, f32>;
|
||||
|
||||
pub trait Skeleton: Send + Sync + 'static {
|
||||
type Attr;
|
||||
type Body;
|
||||
|
||||
const BONE_COUNT: usize;
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
|
||||
pub type Body = comp::object::Body;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ObjectSkeleton;
|
||||
@ -19,6 +22,7 @@ const SCALE: f32 = 1.0 / 11.0;
|
||||
|
||||
impl Skeleton for ObjectSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 1;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -34,3 +38,11 @@ impl Skeleton for ObjectSkeleton {
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
||||
|
@ -8,10 +8,12 @@ pub use self::{
|
||||
alpha::AlphaAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::quadruped_low::Body;
|
||||
|
||||
skeleton_impls!(struct QuadrupedLowSkeleton {
|
||||
+ head_upper,
|
||||
+ head_lower,
|
||||
@ -27,6 +29,7 @@ skeleton_impls!(struct QuadrupedLowSkeleton {
|
||||
|
||||
impl Skeleton for QuadrupedLowSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 10;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -102,8 +105,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::quadruped_low::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::quadruped_low::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::quadruped_low::Species::*;
|
||||
Self {
|
||||
head_upper: match (body.species, body.body_type) {
|
||||
|
@ -8,10 +8,12 @@ pub use self::{
|
||||
alpha::AlphaAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::quadruped_medium::Body;
|
||||
|
||||
skeleton_impls!(struct QuadrupedMediumSkeleton {
|
||||
+ head_upper,
|
||||
+ head_lower,
|
||||
@ -32,6 +34,7 @@ skeleton_impls!(struct QuadrupedMediumSkeleton {
|
||||
|
||||
impl Skeleton for QuadrupedMediumSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 15;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -124,8 +127,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::quadruped_medium::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::quadruped_medium::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::quadruped_medium::Species::*;
|
||||
Self {
|
||||
head_upper: match (body.species, body.body_type) {
|
||||
|
@ -6,10 +6,12 @@ pub mod run;
|
||||
// Reexports
|
||||
pub use self::{feed::FeedAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, Bone, FigureBoneData, Skeleton};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::quadruped_small::Body;
|
||||
|
||||
skeleton_impls!(struct QuadrupedSmallSkeleton {
|
||||
+ head,
|
||||
+ chest,
|
||||
@ -22,6 +24,7 @@ skeleton_impls!(struct QuadrupedSmallSkeleton {
|
||||
|
||||
impl Skeleton for QuadrupedSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 7;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
@ -90,8 +93,8 @@ impl Default for SkeletonAttr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a comp::quadruped_small::Body> for SkeletonAttr {
|
||||
fn from(body: &'a comp::quadruped_small::Body) -> Self {
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::quadruped_small::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
|
@ -1,8 +1,11 @@
|
||||
use super::*;
|
||||
use crate::audio::sfx::SfxEvent;
|
||||
use common::{
|
||||
assets,
|
||||
comp::{item::tool::ToolCategory, CharacterAbilityType, CharacterState, ItemConfig, Loadout},
|
||||
assets::Asset,
|
||||
comp::{
|
||||
item::{tool::ToolCategory, ItemAsset},
|
||||
CharacterAbilityType, CharacterState, ItemConfig, Loadout,
|
||||
},
|
||||
states,
|
||||
};
|
||||
use std::time::{Duration, Instant};
|
||||
@ -12,7 +15,7 @@ fn maps_wield_while_equipping() {
|
||||
let mut loadout = Loadout::default();
|
||||
|
||||
loadout.active_item = Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.axe.starter_axe"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.axe.starter_axe"),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
@ -40,7 +43,7 @@ fn maps_unwield() {
|
||||
let mut loadout = Loadout::default();
|
||||
|
||||
loadout.active_item = Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.bow.starter_bow"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.bow.starter_bow"),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
@ -66,7 +69,7 @@ fn maps_basic_melee() {
|
||||
let mut loadout = Loadout::default();
|
||||
|
||||
loadout.active_item = Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.axe.starter_axe"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.axe.starter_axe"),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
@ -102,7 +105,7 @@ fn matches_ability_stage() {
|
||||
let mut loadout = Loadout::default();
|
||||
|
||||
loadout.active_item = Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.sword.starter_sword"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.sword.starter_sword"),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
@ -143,7 +146,7 @@ fn ignores_different_ability_stage() {
|
||||
let mut loadout = Loadout::default();
|
||||
|
||||
loadout.active_item = Some(ItemConfig {
|
||||
item: assets::load_expect_cloned("common.items.weapons.sword.starter_sword"),
|
||||
item: ItemAsset::load_expect_cloned("common.items.weapons.sword.starter_sword"),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
|
@ -97,7 +97,7 @@ impl ItemImgs {
|
||||
pub fn new(ui: &mut Ui, not_found: Id) -> Self {
|
||||
let mut indicator = ReloadIndicator::new();
|
||||
Self {
|
||||
map: assets::load_watched::<ItemImagesSpec>(
|
||||
map: ItemImagesSpec::load_watched(
|
||||
"voxygen.item_image_manifest",
|
||||
&mut indicator,
|
||||
)
|
||||
@ -118,7 +118,7 @@ impl ItemImgs {
|
||||
/// Reuses img ids
|
||||
pub fn reload_if_changed(&mut self, ui: &mut Ui) {
|
||||
if self.indicator.reloaded() {
|
||||
for (kind, spec) in assets::load::<ItemImagesSpec>("voxygen.item_image_manifest")
|
||||
for (kind, spec) in ItemImagesSpec::load("voxygen.item_image_manifest")
|
||||
.expect("Unable to load item image manifest")
|
||||
.0
|
||||
.iter()
|
||||
@ -160,21 +160,21 @@ impl ItemImgs {
|
||||
// TODO: remove code dup?
|
||||
fn graceful_load_vox(specifier: &str) -> Arc<DotVoxData> {
|
||||
let full_specifier: String = ["voxygen.", specifier].concat();
|
||||
match assets::load::<DotVoxData>(full_specifier.as_str()) {
|
||||
match DotVoxData::load(full_specifier.as_str()) {
|
||||
Ok(dot_vox) => dot_vox,
|
||||
Err(_) => {
|
||||
error!(?full_specifier, "Could not load vox file for item images",);
|
||||
assets::load_expect::<DotVoxData>("voxygen.voxel.not_found")
|
||||
DotVoxData::load_expect("voxygen.voxel.not_found")
|
||||
},
|
||||
}
|
||||
}
|
||||
fn graceful_load_img(specifier: &str) -> Arc<DynamicImage> {
|
||||
let full_specifier: String = ["voxygen.", specifier].concat();
|
||||
match assets::load::<DynamicImage>(full_specifier.as_str()) {
|
||||
match DynamicImage::load(full_specifier.as_str()) {
|
||||
Ok(img) => img,
|
||||
Err(_) => {
|
||||
error!(?full_specifier, "Could not load image file for item images");
|
||||
assets::load_expect::<DynamicImage>("voxygen.element.not_found")
|
||||
DynamicImage::load_expect("voxygen.element.not_found")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ use crate::{
|
||||
GlobalState,
|
||||
};
|
||||
use client::Client;
|
||||
use common::{assets::load_expect, comp, sync::Uid, terrain::TerrainChunk, vol::RectRasterableVol};
|
||||
use common::{assets::Asset, comp, sync::Uid, terrain::TerrainChunk, vol::RectRasterableVol};
|
||||
use conrod_core::{
|
||||
text::cursor::Index,
|
||||
widget::{self, Button, Image, Text},
|
||||
@ -602,7 +602,7 @@ impl Hud {
|
||||
// Load item images.
|
||||
let item_imgs = ItemImgs::new(&mut ui, imgs.not_found);
|
||||
// Load language.
|
||||
let voxygen_i18n = load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
let voxygen_i18n = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
// Load fonts.
|
||||
|
@ -1,7 +1,4 @@
|
||||
use common::{
|
||||
assets,
|
||||
assets::{load_expect, load_glob, Asset},
|
||||
};
|
||||
use common::assets::{self, Asset};
|
||||
use deunicode::deunicode;
|
||||
use ron::de::from_reader;
|
||||
use serde_derive::*;
|
||||
@ -100,7 +97,7 @@ impl VoxygenLocalization {
|
||||
/// Return the missing keys compared to the reference language
|
||||
pub fn list_missing_entries(&self) -> (HashSet<String>, HashSet<String>) {
|
||||
let reference_localization =
|
||||
load_expect::<VoxygenLocalization>(i18n_asset_key(REFERENCE_LANG).as_ref());
|
||||
VoxygenLocalization::load_expect(i18n_asset_key(REFERENCE_LANG).as_ref());
|
||||
|
||||
let reference_string_keys: HashSet<_> =
|
||||
reference_localization.string_map.keys().cloned().collect();
|
||||
@ -169,7 +166,7 @@ impl Asset for VoxygenLocalization {
|
||||
/// Load all the available languages located in the Voxygen asset directory
|
||||
pub fn list_localizations() -> Vec<LanguageMetadata> {
|
||||
let voxygen_locales_assets = "voxygen.i18n.*";
|
||||
let lang_list = load_glob::<VoxygenLocalization>(voxygen_locales_assets).unwrap();
|
||||
let lang_list = VoxygenLocalization::load_glob(voxygen_locales_assets).unwrap();
|
||||
lang_list.iter().map(|e| (*e).metadata.clone()).collect()
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ use veloren_voxygen::{
|
||||
};
|
||||
|
||||
use common::{
|
||||
assets::{load_watched, watch},
|
||||
assets::{watch, Asset},
|
||||
clock::Clock,
|
||||
};
|
||||
use std::panic;
|
||||
@ -132,7 +132,7 @@ fn main() {
|
||||
let profile = Profile::load();
|
||||
|
||||
let mut localization_watcher = watch::ReloadIndicator::new();
|
||||
let localized_strings = load_watched::<VoxygenLocalization>(
|
||||
let localized_strings = VoxygenLocalization::load_watched(
|
||||
&i18n_asset_key(&settings.language.selected_language),
|
||||
&mut localization_watcher,
|
||||
)
|
||||
@ -144,7 +144,7 @@ fn main() {
|
||||
"Impossible to load language: change to the default language (English) instead.",
|
||||
);
|
||||
settings.language.selected_language = i18n::REFERENCE_LANG.to_owned();
|
||||
load_watched::<VoxygenLocalization>(
|
||||
VoxygenLocalization::load_watched(
|
||||
&i18n_asset_key(&settings.language.selected_language),
|
||||
&mut localization_watcher,
|
||||
)
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
Direction, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use client::{self, Client};
|
||||
use common::{assets, comp, msg::ClientState, state::DeltaTime};
|
||||
use common::{assets::Asset, comp, msg::ClientState, state::DeltaTime};
|
||||
use specs::WorldExt;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use tracing::error;
|
||||
@ -126,6 +126,7 @@ impl PlayState for CharSelectionState {
|
||||
time: client.state().get_time(),
|
||||
delta_time: client.state().ecs().read_resource::<DeltaTime>().0,
|
||||
tick: client.get_tick(),
|
||||
thread_pool: client.thread_pool(),
|
||||
body: humanoid_body,
|
||||
gamma: global_state.settings.graphics.gamma,
|
||||
mouse_smoothing: global_state.settings.gameplay.smooth_pan_enable,
|
||||
@ -143,7 +144,7 @@ impl PlayState for CharSelectionState {
|
||||
}
|
||||
|
||||
// Tick the client (currently only to keep the connection alive).
|
||||
let localized_strings = assets::load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
let localized_strings = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
|
||||
|
@ -11,10 +11,9 @@ use crate::{
|
||||
};
|
||||
use client::Client;
|
||||
use common::{
|
||||
assets,
|
||||
assets::load_expect,
|
||||
assets::Asset,
|
||||
character::{Character, CharacterItem, MAX_CHARACTERS_PER_PLAYER},
|
||||
comp::{self, humanoid},
|
||||
comp::{self, humanoid, item::ItemAsset},
|
||||
LoadoutBuilder,
|
||||
};
|
||||
use conrod_core::{
|
||||
@ -321,7 +320,7 @@ impl CharSelectionUi {
|
||||
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
||||
let rot_imgs = ImgsRot::load(&mut ui).expect("Failed to load images!");
|
||||
// Load language
|
||||
let voxygen_i18n = load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
let voxygen_i18n = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
// Load fonts.
|
||||
@ -378,20 +377,24 @@ impl CharSelectionUi {
|
||||
},
|
||||
Mode::Create { loadout, tool, .. } => {
|
||||
loadout.active_item = tool.map(|tool| comp::ItemConfig {
|
||||
item: (*load_expect::<comp::Item>(tool)).clone(),
|
||||
// FIXME: Error gracefully.
|
||||
item: (*ItemAsset::load_expect(tool)).clone(),
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
block_ability: None,
|
||||
dodge_ability: None,
|
||||
});
|
||||
loadout.chest = Some(assets::load_expect_cloned(
|
||||
// FIXME: Error gracefully.
|
||||
loadout.chest = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.rugged_chest",
|
||||
));
|
||||
loadout.pants = Some(assets::load_expect_cloned(
|
||||
// FIXME: Error gracefully.
|
||||
loadout.pants = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.rugged_pants",
|
||||
));
|
||||
loadout.foot = Some(assets::load_expect_cloned(
|
||||
// FIXME: Error gracefully.
|
||||
loadout.foot = Some(ItemAsset::load_expect_cloned(
|
||||
"common.items.armor.starter.sandals_0",
|
||||
));
|
||||
Some(loadout.clone())
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
PlayStateResult,
|
||||
};
|
||||
use client_init::{ClientInit, Error as InitError, Msg as InitMsg};
|
||||
use common::{assets::load_expect, comp};
|
||||
use common::{assets::Asset, comp};
|
||||
use tracing::{error, warn};
|
||||
use ui::{Event as MainMenuEvent, MainMenuUi};
|
||||
|
||||
@ -46,7 +46,7 @@ impl PlayState for MainMenuState {
|
||||
}
|
||||
|
||||
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>) -> PlayStateResult {
|
||||
let localized_strings = load_expect::<crate::i18n::VoxygenLocalization>(
|
||||
let localized_strings = crate::i18n::VoxygenLocalization::load_expect(
|
||||
&crate::i18n::i18n_asset_key(&global_state.settings.language.selected_language),
|
||||
);
|
||||
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
},
|
||||
GlobalState,
|
||||
};
|
||||
use common::assets::load_expect;
|
||||
use common::assets::Asset;
|
||||
use conrod_core::{
|
||||
color,
|
||||
color::TRANSPARENT,
|
||||
@ -17,6 +17,7 @@ use conrod_core::{
|
||||
widget::{text_box::Event as TextBoxEvent, Button, Image, List, Rectangle, Text, TextBox},
|
||||
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
use image::DynamicImage;
|
||||
use rand::{seq::SliceRandom, thread_rng, Rng};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -205,12 +206,12 @@ impl<'a> MainMenuUi {
|
||||
let imgs = Imgs::load(&mut ui).expect("Failed to load images");
|
||||
let rot_imgs = ImgsRot::load(&mut ui).expect("Failed to load images!");
|
||||
let bg_img_id = ui.add_graphic(Graphic::Image(
|
||||
load_expect(bg_imgs.choose(&mut rng).unwrap()),
|
||||
DynamicImage::load_expect(bg_imgs.choose(&mut rng).unwrap()),
|
||||
None,
|
||||
));
|
||||
//let chosen_tip = *tips.choose(&mut rng).unwrap();
|
||||
// Load language
|
||||
let voxygen_i18n = load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
let voxygen_i18n = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
// Load fonts.
|
||||
|
@ -12,7 +12,7 @@ use super::{
|
||||
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, RenderMode,
|
||||
ShadowMapMode, ShadowMode, WrapMode,
|
||||
};
|
||||
use common::assets::{self, watch::ReloadIndicator};
|
||||
use common::assets::{self, watch::ReloadIndicator, Asset};
|
||||
use core::convert::TryFrom;
|
||||
use gfx::{
|
||||
self,
|
||||
@ -21,6 +21,11 @@ use gfx::{
|
||||
traits::{Device, Factory, FactoryExt},
|
||||
};
|
||||
use glsl_include::Context as IncludeContext;
|
||||
use image::DynamicImage;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufReader, Read},
|
||||
};
|
||||
use tracing::{error, warn};
|
||||
use vek::*;
|
||||
|
||||
@ -87,6 +92,21 @@ pub type ColLightInfo = (
|
||||
Vec2<u16>,
|
||||
);
|
||||
|
||||
/// Load from a GLSL file.
|
||||
pub struct Glsl;
|
||||
|
||||
impl Asset for Glsl {
|
||||
type Output = String;
|
||||
|
||||
const ENDINGS: &'static [&'static str] = &["glsl"];
|
||||
|
||||
fn parse(mut buf_reader: BufReader<File>) -> Result<String, assets::Error> {
|
||||
let mut string = String::new();
|
||||
buf_reader.read_to_string(&mut string)?;
|
||||
Ok(string)
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that holds shadow map data. Since shadow mapping may not be
|
||||
/// supported on all platforms, we try to keep it separate.
|
||||
pub struct ShadowMapRenderer {
|
||||
@ -240,7 +260,7 @@ impl Renderer {
|
||||
|
||||
let noise_tex = Texture::new(
|
||||
&mut factory,
|
||||
&assets::load_expect("voxygen.texture.noise"),
|
||||
&DynamicImage::load_expect("voxygen.texture.noise"),
|
||||
Some(gfx::texture::FilterMethod::Bilinear),
|
||||
Some(gfx::texture::WrapMode::Tile),
|
||||
None,
|
||||
@ -1654,32 +1674,19 @@ fn create_pipelines(
|
||||
),
|
||||
RenderError,
|
||||
> {
|
||||
let constants = assets::load_watched::<String>(
|
||||
"voxygen.shaders.include.constants",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap();
|
||||
let constants =
|
||||
Glsl::load_watched("voxygen.shaders.include.constants", shader_reload_indicator).unwrap();
|
||||
let globals =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.globals", shader_reload_indicator)
|
||||
.unwrap();
|
||||
let sky =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.sky", shader_reload_indicator)
|
||||
.unwrap();
|
||||
Glsl::load_watched("voxygen.shaders.include.globals", shader_reload_indicator).unwrap();
|
||||
let sky = Glsl::load_watched("voxygen.shaders.include.sky", shader_reload_indicator).unwrap();
|
||||
let light =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.light", shader_reload_indicator)
|
||||
.unwrap();
|
||||
let srgb =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.srgb", shader_reload_indicator)
|
||||
.unwrap();
|
||||
Glsl::load_watched("voxygen.shaders.include.light", shader_reload_indicator).unwrap();
|
||||
let srgb = Glsl::load_watched("voxygen.shaders.include.srgb", shader_reload_indicator).unwrap();
|
||||
let random =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.random", shader_reload_indicator)
|
||||
.unwrap();
|
||||
let lod =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.lod", shader_reload_indicator)
|
||||
.unwrap();
|
||||
Glsl::load_watched("voxygen.shaders.include.random", shader_reload_indicator).unwrap();
|
||||
let lod = Glsl::load_watched("voxygen.shaders.include.lod", shader_reload_indicator).unwrap();
|
||||
let shadows =
|
||||
assets::load_watched::<String>("voxygen.shaders.include.shadows", shader_reload_indicator)
|
||||
.unwrap();
|
||||
Glsl::load_watched("voxygen.shaders.include.shadows", shader_reload_indicator).unwrap();
|
||||
|
||||
// We dynamically add extra configuration settings to the constants file.
|
||||
let constants = format!(
|
||||
@ -1716,7 +1723,7 @@ fn create_pipelines(
|
||||
},
|
||||
);
|
||||
|
||||
let anti_alias = assets::load_watched::<String>(
|
||||
let anti_alias = Glsl::load_watched(
|
||||
&["voxygen.shaders.antialias.", match mode.aa {
|
||||
AaMode::None | AaMode::SsaaX4 => "none",
|
||||
AaMode::Fxaa => "fxaa",
|
||||
@ -1729,7 +1736,7 @@ fn create_pipelines(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let cloud = assets::load_watched::<String>(
|
||||
let cloud = Glsl::load_watched(
|
||||
&["voxygen.shaders.include.cloud.", match mode.cloud {
|
||||
CloudMode::None => "none",
|
||||
CloudMode::Regular => "regular",
|
||||
@ -1752,28 +1759,27 @@ fn create_pipelines(
|
||||
include_ctx.include("cloud.glsl", &cloud);
|
||||
|
||||
let figure_vert =
|
||||
assets::load_watched::<String>("voxygen.shaders.figure-vert", shader_reload_indicator)
|
||||
.unwrap();
|
||||
Glsl::load_watched("voxygen.shaders.figure-vert", shader_reload_indicator).unwrap();
|
||||
|
||||
let terrain_point_shadow_vert = assets::load_watched::<String>(
|
||||
let terrain_point_shadow_vert = Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-vert",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let terrain_directed_shadow_vert = assets::load_watched::<String>(
|
||||
let terrain_directed_shadow_vert = Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-directed-vert",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let figure_directed_shadow_vert = assets::load_watched::<String>(
|
||||
let figure_directed_shadow_vert = Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-figure-vert",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let directed_shadow_frag = &assets::load_watched::<String>(
|
||||
let directed_shadow_frag = Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-directed-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
@ -1783,10 +1789,8 @@ fn create_pipelines(
|
||||
let skybox_pipeline = create_pipeline(
|
||||
factory,
|
||||
skybox::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.skybox-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.skybox-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.skybox-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.skybox-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1796,8 +1800,7 @@ fn create_pipelines(
|
||||
factory,
|
||||
figure::pipe::new(),
|
||||
&figure_vert,
|
||||
&assets::load_watched::<String>("voxygen.shaders.figure-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.figure-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1806,10 +1809,8 @@ fn create_pipelines(
|
||||
let terrain_pipeline = create_pipeline(
|
||||
factory,
|
||||
terrain::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.terrain-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.terrain-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.terrain-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.terrain-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1818,9 +1819,8 @@ fn create_pipelines(
|
||||
let fluid_pipeline = create_pipeline(
|
||||
factory,
|
||||
fluid::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.fluid-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>(
|
||||
&Glsl::load_watched("voxygen.shaders.fluid-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched(
|
||||
&["voxygen.shaders.fluid-frag.", match mode.fluid {
|
||||
FluidMode::Cheap => "cheap",
|
||||
FluidMode::Shiny => "shiny",
|
||||
@ -1837,10 +1837,8 @@ fn create_pipelines(
|
||||
let sprite_pipeline = create_pipeline(
|
||||
factory,
|
||||
sprite::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.sprite-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.sprite-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.sprite-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.sprite-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1849,10 +1847,8 @@ fn create_pipelines(
|
||||
let particle_pipeline = create_pipeline(
|
||||
factory,
|
||||
particle::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.particle-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.particle-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.particle-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.particle-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1861,10 +1857,8 @@ fn create_pipelines(
|
||||
let ui_pipeline = create_pipeline(
|
||||
factory,
|
||||
ui::pipe::new(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.ui-vert", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>("voxygen.shaders.ui-frag", shader_reload_indicator)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.ui-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.ui-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1873,16 +1867,8 @@ fn create_pipelines(
|
||||
let lod_terrain_pipeline = create_pipeline(
|
||||
factory,
|
||||
lod_terrain::pipe::new(),
|
||||
&assets::load_watched::<String>(
|
||||
"voxygen.shaders.lod-terrain-vert",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>(
|
||||
"voxygen.shaders.lod-terrain-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.lod-terrain-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.lod-terrain-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1891,16 +1877,8 @@ fn create_pipelines(
|
||||
let postprocess_pipeline = create_pipeline(
|
||||
factory,
|
||||
postprocess::pipe::new(),
|
||||
&assets::load_watched::<String>(
|
||||
"voxygen.shaders.postprocess-vert",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
&assets::load_watched::<String>(
|
||||
"voxygen.shaders.postprocess-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.postprocess-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.postprocess-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
@ -1918,7 +1896,7 @@ fn create_pipelines(
|
||||
..figure::pipe::new()
|
||||
},
|
||||
&figure_vert,
|
||||
&assets::load_watched::<String>(
|
||||
&Glsl::load_watched(
|
||||
"voxygen.shaders.player-shadow-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
@ -1933,13 +1911,13 @@ fn create_pipelines(
|
||||
shadow::pipe::new(),
|
||||
&terrain_point_shadow_vert,
|
||||
Some(
|
||||
&assets::load_watched::<String>(
|
||||
&Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-geom",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
&assets::load_watched::<String>(
|
||||
&Glsl::load_watched(
|
||||
"voxygen.shaders.light-shadows-frag",
|
||||
shader_reload_indicator,
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -6,10 +6,9 @@ pub use load::load_mesh; // TODO: Don't make this public.
|
||||
|
||||
use crate::{
|
||||
ecs::comp::Interpolated,
|
||||
mesh::greedy::GreedyMesh,
|
||||
render::{
|
||||
ColLightFmt, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel, Mesh,
|
||||
RenderError, Renderer, ShadowPipeline, TerrainPipeline, Texture,
|
||||
ColLightFmt, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||
Mesh, RenderError, Renderer, ShadowPipeline, TerrainPipeline, Texture,
|
||||
},
|
||||
scene::{
|
||||
camera::{Camera, CameraMode, Dependents},
|
||||
@ -308,6 +307,7 @@ pub struct FigureMgr {
|
||||
fish_medium_model_cache: FigureModelCache<FishMediumSkeleton>,
|
||||
fish_small_model_cache: FigureModelCache<FishSmallSkeleton>,
|
||||
biped_large_model_cache: FigureModelCache<BipedLargeSkeleton>,
|
||||
object_model_cache: FigureModelCache<ObjectSkeleton>,
|
||||
golem_model_cache: FigureModelCache<GolemSkeleton>,
|
||||
states: FigureMgrStates,
|
||||
}
|
||||
@ -327,6 +327,7 @@ impl FigureMgr {
|
||||
fish_medium_model_cache: FigureModelCache::new(),
|
||||
fish_small_model_cache: FigureModelCache::new(),
|
||||
biped_large_model_cache: FigureModelCache::new(),
|
||||
object_model_cache: FigureModelCache::new(),
|
||||
golem_model_cache: FigureModelCache::new(),
|
||||
states: FigureMgrStates::default(),
|
||||
}
|
||||
@ -354,6 +355,7 @@ impl FigureMgr {
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.biped_large_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.object_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.golem_model_cache.clean(&mut self.col_lights, tick);
|
||||
}
|
||||
|
||||
@ -685,7 +687,7 @@ impl FigureMgr {
|
||||
};
|
||||
|
||||
match body {
|
||||
Body::Humanoid(_) => {
|
||||
Body::Humanoid(body) => {
|
||||
let (model, skeleton_attr) = self.model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -694,6 +696,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1046,7 +1049,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1054,7 +1057,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedSmall(_) => {
|
||||
Body::QuadrupedSmall(body) => {
|
||||
let (model, skeleton_attr) =
|
||||
self.quadruped_small_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
@ -1064,6 +1067,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1147,7 +1151,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1155,7 +1159,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedMedium(_) => {
|
||||
Body::QuadrupedMedium(body) => {
|
||||
let (model, skeleton_attr) =
|
||||
self.quadruped_medium_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
@ -1165,6 +1169,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1248,7 +1253,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1256,7 +1261,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::QuadrupedLow(_) => {
|
||||
Body::QuadrupedLow(body) => {
|
||||
let (model, skeleton_attr) =
|
||||
self.quadruped_low_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
@ -1266,6 +1271,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1347,7 +1353,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1355,7 +1361,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::BirdMedium(_) => {
|
||||
Body::BirdMedium(body) => {
|
||||
let (model, skeleton_attr) = self.bird_medium_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1364,6 +1370,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1443,7 +1450,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1451,7 +1458,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::FishMedium(_) => {
|
||||
Body::FishMedium(body) => {
|
||||
let (model, skeleton_attr) = self.fish_medium_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1460,6 +1467,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1528,7 +1536,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1536,7 +1544,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::Dragon(_) => {
|
||||
Body::Dragon(body) => {
|
||||
let (model, skeleton_attr) = self.dragon_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1545,6 +1553,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state =
|
||||
@ -1609,7 +1618,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1617,7 +1626,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::Critter(_) => {
|
||||
Body::Critter(body) => {
|
||||
let (model, skeleton_attr) = self.critter_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1626,6 +1635,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state =
|
||||
@ -1691,7 +1701,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1699,7 +1709,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::BirdSmall(_) => {
|
||||
Body::BirdSmall(body) => {
|
||||
let (model, skeleton_attr) = self.bird_small_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1708,6 +1718,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1776,7 +1787,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1784,7 +1795,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::FishSmall(_) => {
|
||||
Body::FishSmall(body) => {
|
||||
let (model, skeleton_attr) = self.fish_small_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1793,6 +1804,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1861,7 +1873,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1869,7 +1881,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::BipedLarge(_) => {
|
||||
Body::BipedLarge(body) => {
|
||||
let (model, skeleton_attr) = self.biped_large_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1878,6 +1890,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1966,7 +1979,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -1974,7 +1987,7 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::Golem(_) => {
|
||||
Body::Golem(body) => {
|
||||
let (model, skeleton_attr) = self.golem_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
@ -1983,6 +1996,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state =
|
||||
@ -2048,7 +2062,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
@ -2056,8 +2070,8 @@ impl FigureMgr {
|
||||
&mut update_buf,
|
||||
);
|
||||
},
|
||||
Body::Object(_) => {
|
||||
let (model, _) = &self.model_cache.get_or_create_model(
|
||||
Body::Object(body) => {
|
||||
let (model, _) = self.object_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
*body,
|
||||
@ -2065,6 +2079,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state =
|
||||
@ -2080,7 +2095,7 @@ impl FigureMgr {
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
&model,
|
||||
model,
|
||||
lpindex,
|
||||
true,
|
||||
is_player,
|
||||
@ -2102,7 +2117,7 @@ impl FigureMgr {
|
||||
}
|
||||
|
||||
pub fn render_shadows(
|
||||
&mut self,
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
state: &State,
|
||||
tick: u64,
|
||||
@ -2127,7 +2142,6 @@ impl FigureMgr {
|
||||
.filter(|(_, _, _, _, stats, _, _)| stats.map_or(true, |s| !s.is_dead))
|
||||
.for_each(|(entity, pos, _, body, _, loadout, _)| {
|
||||
if let Some((locals, bone_consts, model, _)) = self.get_model_for_render(
|
||||
renderer,
|
||||
tick,
|
||||
camera,
|
||||
None,
|
||||
@ -2153,7 +2167,7 @@ impl FigureMgr {
|
||||
|
||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||
pub fn render(
|
||||
&mut self,
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
state: &State,
|
||||
player_entity: EcsEntity,
|
||||
@ -2184,7 +2198,6 @@ impl FigureMgr {
|
||||
|
||||
if !is_player {
|
||||
if let Some((locals, bone_consts, model, col_lights)) = self.get_model_for_render(
|
||||
renderer,
|
||||
tick,
|
||||
camera,
|
||||
character_state,
|
||||
@ -2204,7 +2217,7 @@ impl FigureMgr {
|
||||
|
||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||
pub fn render_player(
|
||||
&mut self,
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
state: &State,
|
||||
player_entity: EcsEntity,
|
||||
@ -2233,7 +2246,6 @@ impl FigureMgr {
|
||||
let loadout = loadout_storage.get(player_entity);
|
||||
|
||||
if let Some((locals, bone_consts, model, col_lights)) = self.get_model_for_render(
|
||||
renderer,
|
||||
tick,
|
||||
camera,
|
||||
character_state,
|
||||
@ -2260,8 +2272,7 @@ impl FigureMgr {
|
||||
|
||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||
fn get_model_for_render(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
&self,
|
||||
tick: u64,
|
||||
camera: &Camera,
|
||||
character_state: Option<&CharacterState>,
|
||||
@ -2283,7 +2294,7 @@ impl FigureMgr {
|
||||
let character_state = if is_player { character_state } else { None };
|
||||
|
||||
let FigureMgr {
|
||||
col_lights: ref mut col_lights_,
|
||||
col_lights: ref col_lights_,
|
||||
model_cache,
|
||||
critter_model_cache,
|
||||
quadruped_small_model_cache,
|
||||
@ -2295,6 +2306,7 @@ impl FigureMgr {
|
||||
fish_medium_model_cache,
|
||||
fish_small_model_cache,
|
||||
biped_large_model_cache,
|
||||
object_model_cache,
|
||||
golem_model_cache,
|
||||
states:
|
||||
FigureMgrStates {
|
||||
@ -2313,269 +2325,232 @@ impl FigureMgr {
|
||||
object_states,
|
||||
},
|
||||
} = self;
|
||||
let col_lights = &mut *col_lights_;
|
||||
let col_lights = &*col_lights_;
|
||||
if let Some((locals, bone_consts, model_entry)) = match body {
|
||||
Body::Humanoid(_) => character_states
|
||||
Body::Humanoid(body) => character_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::QuadrupedSmall(_) => quadruped_small_states
|
||||
Body::QuadrupedSmall(body) => quadruped_small_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&quadruped_small_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
quadruped_small_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::QuadrupedMedium(_) => quadruped_medium_states
|
||||
Body::QuadrupedMedium(body) => quadruped_medium_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&quadruped_medium_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
quadruped_medium_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::QuadrupedLow(_) => quadruped_low_states
|
||||
Body::QuadrupedLow(body) => quadruped_low_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&quadruped_low_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
quadruped_low_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::BirdMedium(_) => bird_medium_states
|
||||
Body::BirdMedium(body) => bird_medium_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&bird_medium_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
bird_medium_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::FishMedium(_) => fish_medium_states
|
||||
Body::FishMedium(body) => fish_medium_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&fish_medium_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
fish_medium_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::Critter(_) => critter_states
|
||||
Body::Critter(body) => critter_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&critter_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
critter_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::Dragon(_) => dragon_states
|
||||
Body::Dragon(body) => dragon_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&dragon_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
dragon_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::BirdSmall(_) => bird_small_states
|
||||
Body::BirdSmall(body) => bird_small_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&bird_small_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
bird_small_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::FishSmall(_) => fish_small_states
|
||||
Body::FishSmall(body) => fish_small_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&fish_small_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
fish_small_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::BipedLarge(_) => biped_large_states
|
||||
Body::BipedLarge(body) => biped_large_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&biped_large_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
biped_large_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::Golem(_) => golem_states
|
||||
Body::Golem(body) => golem_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&golem_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
golem_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::Object(_) => object_states
|
||||
Body::Object(body) => object_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
object_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
loadout,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
)
|
||||
.0,
|
||||
),
|
||||
)
|
||||
}),
|
||||
} {
|
||||
let model_entry = model_entry?;
|
||||
|
||||
let figure_low_detail_distance = figure_lod_render_distance * 0.75;
|
||||
let figure_mid_detail_distance = figure_lod_render_distance * 0.5;
|
||||
|
||||
@ -2627,14 +2602,13 @@ impl FigureColLights {
|
||||
/// NOTE: Panics if the vertex range bounds are not in range of the opaque
|
||||
/// model stored in the BoneMeshes parameter. This is part of the
|
||||
/// function contract.
|
||||
pub fn create_figure<'a, const N: usize>(
|
||||
pub fn create_figure<const N: usize>(
|
||||
&mut self,
|
||||
renderer: &mut Renderer,
|
||||
greedy: GreedyMesh<'a>,
|
||||
(tex, tex_size): ColLightInfo,
|
||||
(opaque, bounds): (Mesh<TerrainPipeline>, math::Aabb<f32>),
|
||||
vertex_range: [Range<u32>; N],
|
||||
) -> Result<FigureModelEntry<N>, RenderError> {
|
||||
let (tex, tex_size) = greedy.finalize();
|
||||
let atlas = &mut self.atlas;
|
||||
let allocation = atlas
|
||||
.allocate(guillotiere::Size::new(
|
||||
@ -2771,14 +2745,31 @@ impl<S: Skeleton> FigureState<S> {
|
||||
col: vek::Rgba<f32>,
|
||||
dt: f32,
|
||||
state_animation_rate: f32,
|
||||
model: &FigureModelEntry<N>,
|
||||
model: Option<&FigureModelEntry<N>>,
|
||||
_lpindex: u8,
|
||||
_visible: bool,
|
||||
is_player: bool,
|
||||
camera: &Camera,
|
||||
_camera: &Camera,
|
||||
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
|
||||
) {
|
||||
let _frustum = camera.frustum();
|
||||
// NOTE: As long as update() always gets called after get_or_create_model(), and
|
||||
// visibility is not set again until after the model is rendered, we
|
||||
// know we don't pair the character model with invalid model state.
|
||||
//
|
||||
// Currently, the only exception to this during normal gameplay is in the very
|
||||
// first tick after a model is created (so there's no `last_character`
|
||||
// state). So in theory, we could have incorrect model data during this
|
||||
// tick. It is possible to resolve this in a few ways, but since
|
||||
// currently we don't actually use the model state for anything, we
|
||||
// currently ignore this potential issue.
|
||||
//
|
||||
// FIXME: Address the above at some point.
|
||||
let model = if let Some(model) = model {
|
||||
model
|
||||
} else {
|
||||
self.visible = false;
|
||||
return;
|
||||
};
|
||||
|
||||
// Approximate as a sphere with radius equal to the
|
||||
// largest dimension (if we were exact, it should just be half the largest
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
comp::{item::Reagent, object, Body, CharacterState, Pos},
|
||||
figure::Segment,
|
||||
outcome::Outcome,
|
||||
@ -369,7 +369,7 @@ fn default_cache(renderer: &mut Renderer) -> HashMap<&'static str, Model<Particl
|
||||
let mut model_cache = HashMap::new();
|
||||
|
||||
model_cache.entry(DEFAULT_MODEL_KEY).or_insert_with(|| {
|
||||
let vox = assets::load_expect::<DotVoxData>(DEFAULT_MODEL_KEY);
|
||||
let vox = DotVoxData::load_expect(DEFAULT_MODEL_KEY);
|
||||
|
||||
// NOTE: If we add texturing we may eventually try to share it among all
|
||||
// particles in a single atlas.
|
||||
|
@ -19,7 +19,7 @@ use anim::{
|
||||
};
|
||||
use client::Client;
|
||||
use common::{
|
||||
comp::{humanoid, item::ItemKind, Body, Loadout},
|
||||
comp::{humanoid, item::ItemKind, Loadout},
|
||||
figure::Segment,
|
||||
terrain::BlockKind,
|
||||
vol::{BaseVol, ReadVol, Vox},
|
||||
@ -87,10 +87,11 @@ pub struct Scene {
|
||||
char_ori: f32,
|
||||
}
|
||||
|
||||
pub struct SceneData {
|
||||
pub struct SceneData<'a> {
|
||||
pub time: f64,
|
||||
pub delta_time: f32,
|
||||
pub tick: u64,
|
||||
pub thread_pool: &'a uvth::ThreadPool,
|
||||
pub body: Option<humanoid::Body>,
|
||||
pub gamma: f32,
|
||||
pub figure_lod_render_distance: f32,
|
||||
@ -164,7 +165,7 @@ impl Scene {
|
||||
// 2^27, which fits in a u32.
|
||||
let range = range.start as u32..range.end as u32;
|
||||
let model = col_lights
|
||||
.create_figure(renderer, greedy, (opaque_mesh, bounds), [range])
|
||||
.create_figure(renderer, greedy.finalize(), (opaque_mesh, bounds), [range])
|
||||
.unwrap();
|
||||
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
||||
state.update(
|
||||
@ -175,7 +176,7 @@ impl Scene {
|
||||
Rgba::broadcast(1.0),
|
||||
15.0, // Want to get there immediately.
|
||||
1.0,
|
||||
&model,
|
||||
Some(&model),
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
@ -304,16 +305,17 @@ impl Scene {
|
||||
*self.figure_state.skeleton_mut() =
|
||||
anim::vek::Lerp::lerp(&*self.figure_state.skeleton_mut(), &tgt_skeleton, dt_lerp);
|
||||
|
||||
let model = &self
|
||||
let model = self
|
||||
.figure_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
Body::Humanoid(body),
|
||||
body,
|
||||
loadout,
|
||||
scene_data.tick,
|
||||
CameraMode::default(),
|
||||
None,
|
||||
scene_data.thread_pool,
|
||||
)
|
||||
.0;
|
||||
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
||||
@ -325,7 +327,7 @@ impl Scene {
|
||||
Rgba::broadcast(1.0),
|
||||
scene_data.delta_time,
|
||||
1.0,
|
||||
&model,
|
||||
model,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
@ -350,19 +352,16 @@ impl Scene {
|
||||
);
|
||||
|
||||
if let Some(body) = body {
|
||||
let model = &self
|
||||
.figure_model_cache
|
||||
.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
Body::Humanoid(body),
|
||||
let model = &self.figure_model_cache.get_model(
|
||||
&self.col_lights,
|
||||
body,
|
||||
loadout,
|
||||
tick,
|
||||
CameraMode::default(),
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
);
|
||||
|
||||
if let Some(model) = model {
|
||||
renderer.render_figure(
|
||||
&model.models[0],
|
||||
&self.col_lights.texture(model),
|
||||
@ -372,6 +371,7 @@ impl Scene {
|
||||
&self.lod,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((model, state)) = &self.backdrop {
|
||||
renderer.render_figure(
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
|
||||
use super::{math, LodData, SceneData};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
figure::Segment,
|
||||
spiral::Spiral2d,
|
||||
terrain::{Block, BlockKind, TerrainChunk},
|
||||
@ -25,6 +25,7 @@ use crossbeam::channel;
|
||||
use dot_vox::DotVoxData;
|
||||
use guillotiere::AtlasAllocator;
|
||||
use hashbrown::HashMap;
|
||||
use image::DynamicImage;
|
||||
use std::sync::Arc;
|
||||
use tracing::warn;
|
||||
use treeculler::{BVol, Frustum, AABB};
|
||||
@ -525,7 +526,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// NOTE: Tracks the start vertex of the next model to be meshed.
|
||||
let mut make_models = |(kind, variation), s, offset, lod_axes: Vec3<f32>| {
|
||||
let scaled = [1.0, 0.8, 0.6, 0.4, 0.2];
|
||||
let model = assets::load_expect::<DotVoxData>(s);
|
||||
let model = DotVoxData::load_expect(s);
|
||||
let zero = Vec3::zero();
|
||||
let model_size = model
|
||||
.models
|
||||
@ -2401,7 +2402,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
sprite_col_lights,
|
||||
waves: renderer
|
||||
.create_texture(
|
||||
&assets::load_expect("voxygen.texture.waves"),
|
||||
&DynamicImage::load_expect("voxygen.texture.waves"),
|
||||
Some(gfx::texture::FilterMethod::Trilinear),
|
||||
Some(gfx::texture::WrapMode::Tile),
|
||||
None,
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
};
|
||||
use client::{self, Client};
|
||||
use common::{
|
||||
assets::{load_expect, load_watched},
|
||||
assets::Asset,
|
||||
comp,
|
||||
comp::{
|
||||
ChatMsg, ChatType, InventoryUpdateEvent, Pos, Vel, MAX_MOUNT_RANGE_SQR,
|
||||
@ -72,7 +72,7 @@ impl SessionState {
|
||||
.camera_mut()
|
||||
.set_fov_deg(global_state.settings.graphics.fov);
|
||||
let hud = Hud::new(global_state, &client.borrow());
|
||||
let voxygen_i18n = load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
let voxygen_i18n = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
|
||||
@ -196,7 +196,7 @@ impl PlayState for SessionState {
|
||||
|
||||
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>) -> PlayStateResult {
|
||||
// NOTE: Not strictly necessary, but useful for hotloading translation changes.
|
||||
self.voxygen_i18n = load_expect::<VoxygenLocalization>(&i18n_asset_key(
|
||||
self.voxygen_i18n = VoxygenLocalization::load_expect(&i18n_asset_key(
|
||||
&global_state.settings.language.selected_language,
|
||||
));
|
||||
|
||||
@ -991,7 +991,7 @@ impl PlayState for SessionState {
|
||||
HudEvent::ChangeLanguage(new_language) => {
|
||||
global_state.settings.language.selected_language =
|
||||
new_language.language_identifier;
|
||||
self.voxygen_i18n = load_watched::<VoxygenLocalization>(
|
||||
self.voxygen_i18n = VoxygenLocalization::load_watched(
|
||||
&i18n_asset_key(&global_state.settings.language.selected_language),
|
||||
&mut global_state.localization_watcher,
|
||||
)
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::i18n::{Font, VoxygenFonts};
|
||||
use common::assets::Asset;
|
||||
|
||||
pub struct ConrodVoxygenFont {
|
||||
metadata: Font,
|
||||
@ -10,7 +11,7 @@ impl ConrodVoxygenFont {
|
||||
pub fn new(font: &Font, ui: &mut crate::ui::Ui) -> ConrodVoxygenFont {
|
||||
return Self {
|
||||
metadata: font.clone(),
|
||||
conrod_id: ui.new_font(common::assets::load_expect(&font.asset_key)),
|
||||
conrod_id: ui.new_font(crate::ui::Font::load_expect(&font.asset_key)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{Graphic, SampleStrat, Transform};
|
||||
use common::{
|
||||
assets::{load, Error},
|
||||
assets::{Asset, Error},
|
||||
figure::Segment,
|
||||
};
|
||||
use dot_vox::DotVoxData;
|
||||
@ -24,7 +24,7 @@ impl<'a> GraphicCreator<'a> for ImageGraphic {
|
||||
type Specifier = &'a str;
|
||||
|
||||
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
||||
Ok(Graphic::Image(load::<DynamicImage>(specifier)?, None))
|
||||
Ok(Graphic::Image(DynamicImage::load(specifier)?, None))
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ pub enum VoxelSs9Graphic {}
|
||||
pub enum VoxelPixArtGraphic {}
|
||||
|
||||
fn load_segment(specifier: &str) -> Result<Arc<Segment>, Error> {
|
||||
let dot_vox = load::<DotVoxData>(specifier)?;
|
||||
let dot_vox = DotVoxData::load(specifier)?;
|
||||
let seg = dot_vox.as_ref().into();
|
||||
Ok(Arc::new(seg))
|
||||
}
|
||||
|
@ -13,10 +13,10 @@ use common::{
|
||||
vol::{ReadVol, Vox},
|
||||
};
|
||||
use core::ops::{Div, Mul, Range};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub pyramid: (u8, u8, u8),
|
||||
// TODO(@Sharp): After the merge, construct enough infrastructure to make it convenient to
|
||||
|
@ -13,7 +13,7 @@ use common::{
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use noise::NoiseFn;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
f32, f64,
|
||||
@ -26,7 +26,7 @@ pub struct ColumnGen<'a> {
|
||||
pub sim: &'a WorldSim,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub cold_grass: (f32, f32, f32),
|
||||
pub warm_grass: (f32, f32, f32),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{site::Site, Colors};
|
||||
use common::{
|
||||
assets::{self, watch::ReloadIndicator},
|
||||
assets::{watch::ReloadIndicator, Asset, Ron},
|
||||
store::Store,
|
||||
};
|
||||
use core::ops::Deref;
|
||||
@ -53,7 +53,7 @@ impl Index {
|
||||
/// NOTE: Panics if the color manifest cannot be loaded.
|
||||
pub fn new(seed: u32) -> (Self, Arc<Colors>) {
|
||||
let mut indicator = ReloadIndicator::new();
|
||||
let colors = assets::load_watched::<Colors>(WORLD_COLORS_MANIFEST, &mut indicator)
|
||||
let colors = Ron::<Colors>::load_watched(WORLD_COLORS_MANIFEST, &mut indicator)
|
||||
.expect("Could not load world colors!");
|
||||
|
||||
(
|
||||
@ -90,7 +90,7 @@ impl IndexOwned {
|
||||
) -> Option<R> {
|
||||
self.indicator.reloaded().then(move || {
|
||||
// We know the asset was loaded before, so load_expect should be fine.
|
||||
self.colors = assets::load_expect::<Colors>(WORLD_COLORS_MANIFEST);
|
||||
self.colors = Ron::<Colors>::load_expect(WORLD_COLORS_MANIFEST);
|
||||
reload(self)
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ use crate::{
|
||||
IndexRef, CONFIG,
|
||||
};
|
||||
use common::{
|
||||
assets, comp,
|
||||
assets::Asset,
|
||||
comp,
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
lottery::Lottery,
|
||||
terrain::{Block, BlockKind},
|
||||
@ -13,14 +14,14 @@ use common::{
|
||||
};
|
||||
use noise::NoiseFn;
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
f32,
|
||||
ops::{Mul, Sub},
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub bridge: (u8, u8, u8),
|
||||
pub stalagtite: (u8, u8, u8),
|
||||
@ -505,7 +506,7 @@ pub fn apply_caves_to<'a>(
|
||||
if RandomField::new(index.seed).chance(wpos2d.into(), 0.001 * difficulty.powf(1.5))
|
||||
&& cave_base < surface_z as i32 - 25
|
||||
{
|
||||
let kind = *assets::load_expect::<Lottery<BlockKind>>("common.cave_scatter")
|
||||
let kind = *Lottery::<BlockKind>::load_expect("common.cave_scatter")
|
||||
.choose_seeded(RandomField::new(index.seed + 1).get(wpos2d.into()));
|
||||
let _ = vol.set(
|
||||
Vec3::new(offs.x, offs.y, cave_base),
|
||||
|
@ -34,7 +34,6 @@ use crate::{
|
||||
util::{Grid, Sampler},
|
||||
};
|
||||
use common::{
|
||||
assets::{self, Asset},
|
||||
comp::{self, bird_medium, critter, quadruped_low, quadruped_medium, quadruped_small},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
msg::server::WorldMapMsg,
|
||||
@ -42,8 +41,8 @@ use common::{
|
||||
vol::{ReadVol, RectVolSize, Vox, WriteVol},
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fs::File, io::BufReader, time::Duration};
|
||||
use serde::Deserialize;
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -56,7 +55,7 @@ pub struct World {
|
||||
civs: civ::Civs,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub deep_stone_color: (u8, u8, u8),
|
||||
pub block: block::Colors,
|
||||
@ -65,14 +64,6 @@ pub struct Colors {
|
||||
pub site: site::Colors,
|
||||
}
|
||||
|
||||
impl Asset for Colors {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn generate(seed: u32, opts: sim::WorldOpts) -> (Self, IndexOwned) {
|
||||
// NOTE: Generating index first in order to quickly fail if the color manifest
|
||||
|
@ -15,7 +15,7 @@ use common::{
|
||||
};
|
||||
use core::f32;
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
struct Keep {
|
||||
@ -49,7 +49,7 @@ pub struct GenCtx<'a, R: Rng> {
|
||||
rng: &'a mut R,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors;
|
||||
|
||||
impl Castle {
|
||||
|
@ -8,9 +8,9 @@ use crate::{
|
||||
IndexRef,
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
astar::Astar,
|
||||
comp,
|
||||
comp::{self, item::ItemAsset},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
lottery::Lottery,
|
||||
npc,
|
||||
@ -22,7 +22,7 @@ use core::{f32, hash::BuildHasherDefault};
|
||||
use fxhash::FxHasher64;
|
||||
use lazy_static::lazy_static;
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use std::sync::Arc;
|
||||
use vek::*;
|
||||
|
||||
@ -40,7 +40,7 @@ pub struct GenCtx<'a, R: Rng> {
|
||||
rng: &'a mut R,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub stone: (u8, u8, u8),
|
||||
}
|
||||
@ -461,8 +461,7 @@ impl Floor {
|
||||
&& !tile_is_pillar
|
||||
{
|
||||
// Bad
|
||||
let chosen =
|
||||
assets::load_expect::<Lottery<String>>(match rng.gen_range(0, 5) {
|
||||
let chosen = Lottery::<String>::load_expect(match rng.gen_range(0, 5) {
|
||||
0 => "common.loot_tables.loot_table_humanoids",
|
||||
1 => "common.loot_tables.loot_table_armor_misc",
|
||||
_ => "common.loot_tables.loot_table_cultists",
|
||||
@ -479,8 +478,8 @@ impl Floor {
|
||||
.with_alignment(comp::Alignment::Enemy)
|
||||
.with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
|
||||
.with_automatic_name()
|
||||
.with_loot_drop(assets::load_expect_cloned(chosen))
|
||||
.with_main_tool(assets::load_expect_cloned(match rng.gen_range(0, 6) {
|
||||
.with_loot_drop(ItemAsset::load_expect_cloned(chosen))
|
||||
.with_main_tool(ItemAsset::load_expect_cloned(match rng.gen_range(0, 6) {
|
||||
0 => "common.items.npc_weapons.axe.malachite_axe-0",
|
||||
1 => "common.items.npc_weapons.sword.cultist_purp_2h-0",
|
||||
2 => "common.items.npc_weapons.sword.cultist_purp_2h-0",
|
||||
@ -507,7 +506,7 @@ impl Floor {
|
||||
boss_spawn_tile + if boss_tile_is_pillar { 1 } else { 0 };
|
||||
|
||||
if tile_pos == boss_spawn_tile && tile_wcenter.xy() == wpos2d {
|
||||
let chosen = assets::load_expect::<Lottery<String>>(
|
||||
let chosen = Lottery::<String>::load_expect(
|
||||
"common.loot_tables.loot_table_boss_cultist-leader",
|
||||
);
|
||||
let chosen = chosen.choose();
|
||||
@ -520,7 +519,7 @@ impl Floor {
|
||||
"Cult Leader {}",
|
||||
npc::get_npc_name(npc::NpcKind::Humanoid)
|
||||
))
|
||||
.with_main_tool(assets::load_expect_cloned(
|
||||
.with_main_tool(ItemAsset::load_expect_cloned(
|
||||
match rng.gen_range(0, 1) {
|
||||
//Add more possible cult leader npc_weapons here
|
||||
_ => {
|
||||
@ -528,7 +527,7 @@ impl Floor {
|
||||
},
|
||||
},
|
||||
))
|
||||
.with_loot_drop(assets::load_expect_cloned(chosen));
|
||||
.with_loot_drop(ItemAsset::load_expect_cloned(chosen));
|
||||
|
||||
supplement.add_entity(entity);
|
||||
}
|
||||
|
@ -17,10 +17,10 @@ use common::{
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, WriteVol},
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub castle: castle::Colors,
|
||||
pub dungeon: dungeon::Colors,
|
||||
|
@ -12,10 +12,10 @@ use common::{
|
||||
vol::Vox,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub foundation: (u8, u8, u8),
|
||||
pub floor: (u8, u8, u8),
|
||||
|
@ -10,10 +10,10 @@ use common::{
|
||||
vol::Vox,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub brick_base: (u8, u8, u8),
|
||||
pub floor_base: (u8, u8, u8),
|
||||
|
@ -4,10 +4,10 @@ pub mod keep;
|
||||
use super::skeleton::*;
|
||||
use crate::{site::BlockMask, IndexRef};
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub house: house::Colors,
|
||||
pub keep: keep::Colors,
|
||||
|
@ -10,10 +10,10 @@ pub use self::{
|
||||
use crate::IndexRef;
|
||||
use common::terrain::Block;
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub archetype: archetype::Colors,
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ use crate::{
|
||||
IndexRef,
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
assets::Asset,
|
||||
astar::Astar,
|
||||
comp::{self, bird_medium, humanoid, object, quadruped_small},
|
||||
comp::{self, bird_medium, humanoid, item::ItemAsset, object, quadruped_small},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
path::Path,
|
||||
spiral::Spiral2d,
|
||||
@ -26,11 +26,11 @@ use common::{
|
||||
use fxhash::FxHasher64;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use std::{collections::VecDeque, f32, hash::BuildHasherDefault};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colors {
|
||||
pub building: building::Colors,
|
||||
|
||||
@ -904,7 +904,7 @@ impl Settlement {
|
||||
comp::Alignment::Tame
|
||||
})
|
||||
.do_if(is_human && rng.gen(), |entity| {
|
||||
entity.with_main_tool(assets::load_expect_cloned(
|
||||
entity.with_main_tool(ItemAsset::load_expect_cloned(
|
||||
match rng.gen_range(0, 7) {
|
||||
0 => "common.items.npc_weapons.tool.broom",
|
||||
1 => "common.items.npc_weapons.tool.hoe",
|
||||
|
Loading…
Reference in New Issue
Block a user