mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Render item drops instead of placeholder textures
This commit is contained in:
parent
75e88c2fb8
commit
9d98cd9e58
@ -82,6 +82,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Friendly creatures will now defend each other
|
||||
- Creatures will now defend their pets
|
||||
- [WorldGen] Change path colors
|
||||
- Render item drops instead of placeholder textures
|
||||
|
||||
### Removed
|
||||
|
||||
|
@ -1013,6 +1013,13 @@
|
||||
),
|
||||
species: ()
|
||||
),
|
||||
item_drop: (
|
||||
body: (
|
||||
keyword: "item_drop",
|
||||
names_0: []
|
||||
),
|
||||
species: ()
|
||||
),
|
||||
ship: (
|
||||
body: (
|
||||
keyword: "ship",
|
||||
|
2932
assets/voxygen/voxel/item_drop_manifest.ron
Normal file
2932
assets/voxygen/voxel/item_drop_manifest.ron
Normal file
File diff suppressed because it is too large
Load Diff
@ -263,6 +263,7 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
Body::FishMedium(_) => 0.75,
|
||||
Body::BipedLarge(_) => 0.0,
|
||||
Body::Object(_) => 0.0,
|
||||
Body::ItemDrop(_) => 0.0,
|
||||
Body::Golem(_) => 0.0,
|
||||
Body::Theropod(_) => 0.0,
|
||||
Body::Ship(_) => 0.0,
|
||||
|
@ -8,6 +8,7 @@ pub mod fish_medium;
|
||||
pub mod fish_small;
|
||||
pub mod golem;
|
||||
pub mod humanoid;
|
||||
pub mod item_drop;
|
||||
pub mod object;
|
||||
pub mod quadruped_low;
|
||||
pub mod quadruped_medium;
|
||||
@ -50,6 +51,7 @@ make_case_elim!(
|
||||
QuadrupedLow(body: quadruped_low::Body) = 13,
|
||||
Ship(body: ship::Body) = 14,
|
||||
Arthropod(body: arthropod::Body) = 15,
|
||||
ItemDrop(body: item_drop::Body) = 16,
|
||||
}
|
||||
);
|
||||
|
||||
@ -83,6 +85,7 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
|
||||
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_small: BodyData<BodyMeta, biped_small::AllSpecies<SpeciesMeta>>,
|
||||
pub object: BodyData<BodyMeta, ()>,
|
||||
pub item_drop: BodyData<BodyMeta, ()>,
|
||||
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
||||
pub theropod: BodyData<BodyMeta, theropod::AllSpecies<SpeciesMeta>>,
|
||||
pub quadruped_low: BodyData<BodyMeta, quadruped_low::AllSpecies<SpeciesMeta>>,
|
||||
@ -133,6 +136,7 @@ impl<'a, BodyMeta, SpeciesMeta> core::ops::Index<&'a Body> for AllBodies<BodyMet
|
||||
Body::BipedLarge(_) => &self.biped_large.body,
|
||||
Body::BipedSmall(_) => &self.biped_small.body,
|
||||
Body::Object(_) => &self.object.body,
|
||||
Body::ItemDrop(_) => &self.item_drop.body,
|
||||
Body::Golem(_) => &self.golem.body,
|
||||
Body::Theropod(_) => &self.theropod.body,
|
||||
Body::QuadrupedLow(_) => &self.quadruped_low.body,
|
||||
@ -196,6 +200,7 @@ impl Body {
|
||||
_ => false,
|
||||
},
|
||||
Body::Object(_) => false,
|
||||
Body::ItemDrop(_) => false,
|
||||
Body::Golem(b1) => match other {
|
||||
Body::Golem(b2) => b1.species == b2.species,
|
||||
_ => false,
|
||||
@ -235,6 +240,7 @@ impl Body {
|
||||
Body::Humanoid(_) => HUMAN_DENSITY,
|
||||
Body::Ship(ship) => ship.density().0,
|
||||
Body::Object(object) => object.density().0,
|
||||
Body::ItemDrop(item_drop) => item_drop.density().0,
|
||||
_ => HUMAN_DENSITY,
|
||||
};
|
||||
Density(d)
|
||||
@ -287,6 +293,7 @@ impl Body {
|
||||
65.0 * humanoid.height() / 1.75f32
|
||||
},
|
||||
Body::Object(obj) => obj.mass().0,
|
||||
Body::ItemDrop(item_drop) => item_drop.mass().0,
|
||||
Body::QuadrupedLow(body) => match body.species {
|
||||
quadruped_low::Species::Alligator => 360.0, // ~✅
|
||||
quadruped_low::Species::Asp => 300.0,
|
||||
@ -411,6 +418,7 @@ impl Body {
|
||||
Vec3::new(height / 1.3, 1.75 / 2.0, height)
|
||||
},
|
||||
Body::Object(object) => object.dimensions(),
|
||||
Body::ItemDrop(item_drop) => item_drop.dimensions(),
|
||||
Body::QuadrupedMedium(body) => match body.species {
|
||||
quadruped_medium::Species::Barghest => Vec3::new(2.0, 4.4, 2.7),
|
||||
quadruped_medium::Species::Bear => Vec3::new(2.0, 3.8, 3.0),
|
||||
@ -696,6 +704,7 @@ impl Body {
|
||||
object::Body::SeaLantern => 100,
|
||||
_ => 1000,
|
||||
},
|
||||
Body::ItemDrop(_) => 1000,
|
||||
Body::Golem(golem) => match golem.species {
|
||||
golem::Species::ClayGolem => 450,
|
||||
_ => 1000,
|
||||
|
150
common/src/comp/body/item_drop.rs
Normal file
150
common/src/comp/body/item_drop.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
item::{
|
||||
armor::ArmorKind,
|
||||
tool::{Tool, ToolKind},
|
||||
Item, ItemKind, Utility,
|
||||
},
|
||||
Density, Mass, Ori,
|
||||
},
|
||||
consts::WATER_DENSITY,
|
||||
make_case_elim,
|
||||
util::Dir,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::f32::consts::PI;
|
||||
use vek::Vec3;
|
||||
|
||||
make_case_elim!(
|
||||
armor,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum ItemDropArmorKind {
|
||||
Shoulder = 0,
|
||||
Chest = 1,
|
||||
Belt = 2,
|
||||
Hand = 3,
|
||||
Pants = 4,
|
||||
Foot = 5,
|
||||
Back = 6,
|
||||
Ring = 7,
|
||||
Neck = 8,
|
||||
Head = 9,
|
||||
Tabard = 10,
|
||||
Bag = 11,
|
||||
}
|
||||
);
|
||||
|
||||
make_case_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Body {
|
||||
Tool(tool: ToolKind) = 0,
|
||||
ModularComponent = 1,
|
||||
Lantern = 2,
|
||||
Glider = 3,
|
||||
Armor(armor: ItemDropArmorKind) = 4,
|
||||
Utility = 5,
|
||||
Consumable = 6,
|
||||
Throwable = 7,
|
||||
Ingredient = 8,
|
||||
Coins = 9,
|
||||
CoinPouch = 10,
|
||||
Empty = 11,
|
||||
}
|
||||
);
|
||||
|
||||
impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::ItemDrop(body) }
|
||||
}
|
||||
|
||||
impl From<&Item> for Body {
|
||||
fn from(item: &Item) -> Self {
|
||||
match item.kind() {
|
||||
ItemKind::Tool(Tool { kind, .. }) => Body::Tool(*kind),
|
||||
ItemKind::ModularComponent(_) => Body::ModularComponent,
|
||||
ItemKind::Lantern(_) => Body::Lantern,
|
||||
ItemKind::Glider(_) => Body::Glider,
|
||||
ItemKind::Armor(armor) => match armor.kind {
|
||||
ArmorKind::Shoulder(_) => Body::Armor(ItemDropArmorKind::Shoulder),
|
||||
ArmorKind::Chest(_) => Body::Armor(ItemDropArmorKind::Chest),
|
||||
ArmorKind::Belt(_) => Body::Armor(ItemDropArmorKind::Belt),
|
||||
ArmorKind::Hand(_) => Body::Armor(ItemDropArmorKind::Hand),
|
||||
ArmorKind::Pants(_) => Body::Armor(ItemDropArmorKind::Pants),
|
||||
ArmorKind::Foot(_) => Body::Armor(ItemDropArmorKind::Foot),
|
||||
ArmorKind::Back(_) => Body::Armor(ItemDropArmorKind::Back),
|
||||
ArmorKind::Ring(_) => Body::Armor(ItemDropArmorKind::Ring),
|
||||
ArmorKind::Neck(_) => Body::Armor(ItemDropArmorKind::Neck),
|
||||
ArmorKind::Head(_) => Body::Armor(ItemDropArmorKind::Head),
|
||||
ArmorKind::Tabard(_) => Body::Armor(ItemDropArmorKind::Tabard),
|
||||
ArmorKind::Bag(_) => Body::Armor(ItemDropArmorKind::Bag),
|
||||
},
|
||||
ItemKind::Utility { kind, .. } => match kind {
|
||||
Utility::Coins => {
|
||||
if item.amount() > 100 {
|
||||
Body::CoinPouch
|
||||
} else {
|
||||
Body::Coins
|
||||
}
|
||||
},
|
||||
_ => Body::Utility,
|
||||
},
|
||||
ItemKind::Consumable { .. } => Body::Consumable,
|
||||
ItemKind::Throwable { .. } => Body::Throwable,
|
||||
ItemKind::Ingredient { .. } => Body::Ingredient,
|
||||
_ => Body::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Body {
|
||||
pub fn to_string(self) -> &'static str {
|
||||
match self {
|
||||
Body::Tool(_) => "tool",
|
||||
Body::ModularComponent => "modular_component",
|
||||
Body::Lantern => "lantern",
|
||||
Body::Glider => "glider",
|
||||
Body::Armor(_) => "armor",
|
||||
Body::Utility => "utility",
|
||||
Body::Consumable => "consumable",
|
||||
Body::Throwable => "throwable",
|
||||
Body::Ingredient => "ingredient",
|
||||
Body::Coins => "coins",
|
||||
Body::CoinPouch => "coin_pouch",
|
||||
Body::Empty => "empty",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn density(&self) -> Density { Density(1.1 * WATER_DENSITY) }
|
||||
|
||||
pub fn mass(&self) -> Mass { Mass(2.0) }
|
||||
|
||||
pub fn dimensions(&self) -> Vec3<f32> { Vec3::new(0.0, 0.1, 0.0) }
|
||||
|
||||
pub fn orientation(&self, rng: &mut impl Rng) -> Ori {
|
||||
let random = rng.gen_range(-1.0..1.0f32);
|
||||
let default = Ori::default();
|
||||
match self {
|
||||
Body::Tool(_) => default
|
||||
.pitched_down(PI / 2.0)
|
||||
.yawed_left(PI / 2.0)
|
||||
.pitched_towards(
|
||||
Dir::from_unnormalized(Vec3::new(
|
||||
random,
|
||||
rng.gen_range(-1.0..1.0f32),
|
||||
rng.gen_range(-1.0..1.0f32),
|
||||
))
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
Body::Armor(kind) => match kind {
|
||||
ItemDropArmorKind::Neck | ItemDropArmorKind::Back | ItemDropArmorKind::Tabard => {
|
||||
default.pitched_down(PI / -2.0)
|
||||
},
|
||||
_ => default.yawed_left(random),
|
||||
},
|
||||
_ => default.yawed_left(random),
|
||||
}
|
||||
}
|
||||
}
|
@ -306,6 +306,12 @@ impl Body {
|
||||
},
|
||||
},
|
||||
|
||||
Body::ItemDrop(_) => {
|
||||
let dim = self.dimensions();
|
||||
const CD: f32 = 2.0;
|
||||
CD * (PI / 6.0 * dim.x * dim.y * dim.z).powf(2.0 / 3.0)
|
||||
},
|
||||
|
||||
Body::Ship(_) => {
|
||||
// Airships tend to use the square of the cube root of its volume for
|
||||
// reference area
|
||||
|
51
common/src/comp/inventory/item/item_key.rs
Normal file
51
common/src/comp/inventory/item/item_key.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::{
|
||||
assets::AssetExt,
|
||||
comp::inventory::item::{
|
||||
armor::{Armor, ArmorKind},
|
||||
Glider, ItemDef, ItemDesc, ItemKind, Lantern, Throwable, Utility,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)]
|
||||
pub enum ItemKey {
|
||||
Tool(String),
|
||||
ModularComponent(String),
|
||||
Lantern(String),
|
||||
Glider(String),
|
||||
Armor(ArmorKind),
|
||||
Utility(Utility),
|
||||
Consumable(String),
|
||||
Throwable(Throwable),
|
||||
Ingredient(String),
|
||||
TagExamples(Vec<ItemKey>),
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl<T: ItemDesc> From<&T> for ItemKey {
|
||||
fn from(item_desc: &T) -> Self {
|
||||
let item_kind = item_desc.kind();
|
||||
let item_definition_id = item_desc.item_definition_id();
|
||||
|
||||
match item_kind {
|
||||
ItemKind::Tool(_) => ItemKey::Tool(item_definition_id.to_owned()),
|
||||
ItemKind::ModularComponent(_) => {
|
||||
ItemKey::ModularComponent(item_definition_id.to_owned())
|
||||
},
|
||||
ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(kind.clone()),
|
||||
ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()),
|
||||
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
|
||||
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
|
||||
ItemKind::Consumable { .. } => ItemKey::Consumable(item_definition_id.to_owned()),
|
||||
ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind),
|
||||
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
|
||||
ItemKind::TagExamples { item_ids } => ItemKey::TagExamples(
|
||||
item_ids
|
||||
.iter()
|
||||
.map(|id| ItemKey::from(&*Arc::<ItemDef>::load_expect_cloned(id)))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod armor;
|
||||
pub mod item_key;
|
||||
pub mod modular;
|
||||
pub mod tool;
|
||||
|
||||
|
@ -60,8 +60,8 @@ pub use self::{
|
||||
beam::{Beam, BeamSegment},
|
||||
body::{
|
||||
arthropod, biped_large, biped_small, bird_large, bird_medium, dragon, fish_medium,
|
||||
fish_small, golem, humanoid, object, quadruped_low, quadruped_medium, quadruped_small,
|
||||
ship, theropod, AllBodies, Body, BodyData,
|
||||
fish_small, golem, humanoid, item_drop, object, quadruped_low, quadruped_medium,
|
||||
quadruped_small, ship, theropod, AllBodies, Body, BodyData,
|
||||
},
|
||||
buff::{
|
||||
Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffId, BuffKind, BuffSource, Buffs,
|
||||
@ -83,6 +83,7 @@ pub use self::{
|
||||
inventory::{
|
||||
item::{
|
||||
self,
|
||||
item_key::ItemKey,
|
||||
tool::{self, AbilityItem},
|
||||
Item, ItemConfig, ItemDrop,
|
||||
},
|
||||
|
@ -109,6 +109,7 @@ impl Body {
|
||||
_ => 80.0,
|
||||
},
|
||||
Body::Object(_) => 0.0,
|
||||
Body::ItemDrop(_) => 0.0,
|
||||
Body::Golem(_) => 60.0,
|
||||
Body::Theropod(_) => 135.0,
|
||||
Body::QuadrupedLow(quadruped_low) => match quadruped_low.species {
|
||||
@ -183,6 +184,7 @@ impl Body {
|
||||
Body::BipedLarge(_) => 2.7,
|
||||
Body::BipedSmall(_) => 3.5,
|
||||
Body::Object(_) => 2.0,
|
||||
Body::ItemDrop(_) => 2.0,
|
||||
Body::Golem(_) => 2.0,
|
||||
Body::Theropod(theropod) => match theropod.species {
|
||||
theropod::Species::Archaeos => 2.3,
|
||||
@ -208,6 +210,7 @@ impl Body {
|
||||
pub fn swim_thrust(&self) -> Option<f32> {
|
||||
match self {
|
||||
Body::Object(_) => None,
|
||||
Body::ItemDrop(_) => None,
|
||||
Body::BipedLarge(_) | Body::Golem(_) => Some(200.0 * self.mass().0),
|
||||
Body::BipedSmall(_) => Some(100.0 * self.mass().0),
|
||||
Body::BirdMedium(_) => Some(50.0 * self.mass().0),
|
||||
@ -247,7 +250,7 @@ impl Body {
|
||||
/// Returns jump impulse if the body type can jump, otherwise None
|
||||
pub fn jump_impulse(&self) -> Option<f32> {
|
||||
match self {
|
||||
Body::Object(_) | Body::Ship(_) => None,
|
||||
Body::Object(_) | Body::Ship(_) | Body::ItemDrop(_) => None,
|
||||
Body::BipedLarge(_) | Body::Dragon(_) | Body::Golem(_) | Body::QuadrupedLow(_) => {
|
||||
Some(0.1 * self.mass().0)
|
||||
},
|
||||
|
@ -476,7 +476,7 @@ fn handle_drop_all(
|
||||
|
||||
server
|
||||
.state
|
||||
.create_object(Default::default(), comp::object::Body::Pouch)
|
||||
.create_item_drop(Default::default(), &item)
|
||||
.with(comp::Pos(Vec3::new(
|
||||
pos.0.x + rng.gen_range(5.0..10.0),
|
||||
pos.0.y + rng.gen_range(5.0..10.0),
|
||||
|
@ -17,8 +17,8 @@ use common::{
|
||||
self, aura, buff,
|
||||
chat::{KillSource, KillType},
|
||||
inventory::item::MaterialStatManifest,
|
||||
object, Alignment, Auras, Body, CharacterState, Energy, Group, Health, HealthChange,
|
||||
Inventory, Player, Poise, Pos, SkillSet, Stats,
|
||||
Alignment, Auras, Body, CharacterState, Energy, Group, Health, HealthChange, Inventory,
|
||||
Player, Poise, Pos, SkillSet, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -427,7 +427,6 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
|
||||
// and if it is not owned by another entity (not a pet)
|
||||
|
||||
// Decide for a loot drop before turning into a lootbag
|
||||
let old_body = state.ecs().write_storage::<Body>().remove(entity);
|
||||
|
||||
let item = {
|
||||
let mut item_drop = state.ecs().write_storage::<comp::ItemDrop>();
|
||||
@ -442,23 +441,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
|
||||
// render the items on the ground, rather than changing the texture depending on
|
||||
// the body type
|
||||
let _ = state
|
||||
.create_object(comp::Pos(pos.0 + Vec3::unit_z() * 0.25), match old_body {
|
||||
Some(common::comp::Body::Humanoid(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::BipedSmall(_))
|
||||
| Some(common::comp::Body::BipedLarge(_)) => object::Body::Pouch,
|
||||
Some(common::comp::Body::Golem(_)) => object::Body::Chest,
|
||||
Some(common::comp::Body::QuadrupedSmall(_)) => object::Body::SmallMeat,
|
||||
Some(common::comp::Body::FishMedium(_))
|
||||
| Some(common::comp::Body::FishSmall(_)) => object::Body::FishMeat,
|
||||
Some(common::comp::Body::QuadrupedMedium(_)) => object::Body::BeastMeat,
|
||||
Some(common::comp::Body::QuadrupedLow(_)) => object::Body::ToughMeat,
|
||||
Some(common::comp::Body::BirdLarge(_))
|
||||
| Some(common::comp::Body::BirdMedium(_)) => object::Body::BirdMeat,
|
||||
Some(common::comp::Body::Theropod(_)) => object::Body::BeastMeat,
|
||||
Some(common::comp::Body::Dragon(_)) => object::Body::BeastMeat,
|
||||
Some(common::comp::Body::Object(_)) => object::Body::Chest,
|
||||
_ => object::Body::Pouch,
|
||||
})
|
||||
.create_item_drop(comp::Pos(pos.0 + Vec3::unit_z() * 0.25), &item)
|
||||
.maybe_with(vel)
|
||||
.with(item)
|
||||
.build();
|
||||
|
@ -379,7 +379,7 @@ pub fn handle_mine_block(
|
||||
}
|
||||
}
|
||||
state
|
||||
.create_object(Default::default(), comp::object::Body::Pouch)
|
||||
.create_item_drop(Default::default(), &item)
|
||||
.with(comp::Pos(pos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0)))
|
||||
.with(item)
|
||||
.build();
|
||||
|
@ -247,14 +247,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
}
|
||||
drop(inventories);
|
||||
if let Some(item) = drop_item {
|
||||
// TODO: Choose a body appropriate for the item
|
||||
let body = match item.item_definition_id() {
|
||||
"common.items.utility.coins" => comp::object::Body::Coins,
|
||||
_ => comp::object::Body::Pouch,
|
||||
};
|
||||
|
||||
state
|
||||
.create_object(Default::default(), body)
|
||||
.create_item_drop(Default::default(), &item)
|
||||
.with(comp::Pos(
|
||||
Vec3::new(pos.x as f32, pos.y as f32, pos.z as f32) + Vec3::unit_z(),
|
||||
))
|
||||
@ -712,12 +706,6 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
.into_iter()
|
||||
.filter(|(_, _, i)| !matches!(i.quality(), item::Quality::Debug))
|
||||
{
|
||||
// hack: special case coins for now
|
||||
let body = match item.item_definition_id() {
|
||||
"common.items.utility.coins" => comp::object::Body::Coins,
|
||||
_ => comp::object::Body::Pouch,
|
||||
};
|
||||
|
||||
// If item is a container check inside of it for Debug items and remove them
|
||||
item.slots_mut().iter_mut().for_each(|x| {
|
||||
if let Some(contained_item) = &x {
|
||||
@ -728,7 +716,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
});
|
||||
|
||||
state
|
||||
.create_object(Default::default(), body)
|
||||
.create_item_drop(Default::default(), &item)
|
||||
.with(comp::Pos(pos.0 + *ori.look_dir() + Vec3::unit_z()))
|
||||
.with(item)
|
||||
.with(comp::Vel(Vec3::zero()))
|
||||
|
@ -15,7 +15,7 @@ use common::{
|
||||
comp::{
|
||||
self,
|
||||
skills::{GeneralSkill, Skill},
|
||||
Group, Inventory, Poise,
|
||||
Group, Inventory, Item, Poise,
|
||||
},
|
||||
effect::Effect,
|
||||
link::{Link, LinkHandle},
|
||||
@ -54,6 +54,7 @@ pub trait StateExt {
|
||||
) -> EcsEntityBuilder;
|
||||
/// Build a static object entity
|
||||
fn create_object(&mut self, pos: comp::Pos, object: comp::object::Body) -> EcsEntityBuilder;
|
||||
fn create_item_drop(&mut self, pos: comp::Pos, item: &Item) -> EcsEntityBuilder;
|
||||
fn create_ship<F: FnOnce(comp::ship::Body) -> comp::Collider>(
|
||||
&mut self,
|
||||
pos: comp::Pos,
|
||||
@ -269,6 +270,20 @@ impl StateExt for State {
|
||||
.with(body)
|
||||
}
|
||||
|
||||
fn create_item_drop(&mut self, pos: comp::Pos, item: &Item) -> EcsEntityBuilder {
|
||||
let item_drop = comp::item_drop::Body::from(item);
|
||||
let body = comp::Body::ItemDrop(item_drop);
|
||||
self.ecs_mut()
|
||||
.create_entity_synced()
|
||||
.with(pos)
|
||||
.with(comp::Vel(Vec3::zero()))
|
||||
.with(item_drop.orientation(&mut thread_rng()))
|
||||
.with(item_drop.mass())
|
||||
.with(item_drop.density())
|
||||
.with(capsule(&body))
|
||||
.with(body)
|
||||
}
|
||||
|
||||
fn create_ship<F: FnOnce(comp::ship::Body) -> comp::Collider>(
|
||||
&mut self,
|
||||
pos: comp::Pos,
|
||||
|
29
voxygen/anim/src/item_drop/idle.rs
Normal file
29
voxygen/anim/src/item_drop/idle.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
ItemDropSkeleton, SkeletonAttr,
|
||||
};
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency<'a> = f32;
|
||||
type Skeleton = ItemDropSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"item_drop_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "item_drop_idle")]
|
||||
fn update_skeleton_inner<'a>(
|
||||
skeleton: &Self::Skeleton,
|
||||
_: Self::Dependency<'a>,
|
||||
_anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
95
voxygen/anim/src/item_drop/mod.rs
Normal file
95
voxygen/anim/src/item_drop/mod.rs
Normal file
@ -0,0 +1,95 @@
|
||||
pub mod idle;
|
||||
|
||||
// Reexports
|
||||
pub use self::idle::IdleAnimation;
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton};
|
||||
use common::comp::{self, item_drop::ItemDropArmorKind};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::item_drop::Body;
|
||||
|
||||
skeleton_impls!(struct ItemDropSkeleton {
|
||||
+ bone0,
|
||||
});
|
||||
|
||||
impl Skeleton for ItemDropSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 1;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"item_drop_compute_mats\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "item_drop_compute_mats")]
|
||||
fn compute_matrices_inner(
|
||||
&self,
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
body: Self::Body,
|
||||
) -> Offsets {
|
||||
let scale_mat = Mat4::scaling_3d(1.0 / 11.0 * Self::scale(&body));
|
||||
|
||||
let bone0_mat = base_mat * scale_mat * Mat4::<f32>::from(self.bone0);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) =
|
||||
[make_bone(bone0_mat)];
|
||||
Offsets {
|
||||
lantern: None,
|
||||
mount_bone: Transform {
|
||||
position: common::comp::Body::ItemDrop(body)
|
||||
.mount_offset()
|
||||
.into_tuple()
|
||||
.into(),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemDropSkeleton {
|
||||
pub fn scale(body: &Body) -> f32 {
|
||||
match body {
|
||||
Body::Tool(_) => 0.8,
|
||||
Body::Glider => 0.45,
|
||||
Body::Coins => 0.5,
|
||||
Body::Armor(kind) => match kind {
|
||||
ItemDropArmorKind::Neck | ItemDropArmorKind::Ring => 0.5,
|
||||
ItemDropArmorKind::Back => 0.7,
|
||||
_ => 0.8,
|
||||
},
|
||||
_ => 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr {
|
||||
bone0: (f32, f32, f32),
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
|
||||
match body {
|
||||
comp::Body::ItemDrop(body) => Ok(SkeletonAttr::from(body)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bone0: (0.0, 0.0, 0.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self {
|
||||
Self {
|
||||
bone0: (0.0, 0.0, 0.0),
|
||||
}
|
||||
}
|
||||
}
|
@ -58,6 +58,7 @@ pub mod fish_medium;
|
||||
pub mod fish_small;
|
||||
pub mod fixture;
|
||||
pub mod golem;
|
||||
pub mod item_drop;
|
||||
pub mod object;
|
||||
pub mod quadruped_low;
|
||||
pub mod quadruped_medium;
|
||||
|
@ -728,6 +728,7 @@ fn body_species(body: &Body) -> String {
|
||||
Body::BipedLarge(body) => format!("{:?}", body.species),
|
||||
Body::BipedSmall(body) => format!("{:?}", body.species),
|
||||
Body::Object(body) => format!("{:?}", body),
|
||||
Body::ItemDrop(body) => format!("{:?}", body),
|
||||
Body::Golem(body) => format!("{:?}", body.species),
|
||||
Body::Theropod(body) => format!("{:?}", body.species),
|
||||
Body::QuadrupedLow(body) => format!("{:?}", body.species),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{
|
||||
get_quality_col,
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
item_imgs::{animate_by_pulse, ItemImgs, ItemKey::Tool},
|
||||
item_imgs::{animate_by_pulse, ItemImgs},
|
||||
Show, TEXT_COLOR, TEXT_DULL_RED_COLOR, TEXT_GRAY_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||
};
|
||||
use crate::ui::{
|
||||
@ -13,7 +13,8 @@ use common::{
|
||||
assets::AssetExt,
|
||||
comp::{
|
||||
item::{
|
||||
ItemDef, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality, TagExampleInfo,
|
||||
item_key::ItemKey, ItemDef, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality,
|
||||
TagExampleInfo,
|
||||
},
|
||||
Inventory,
|
||||
},
|
||||
@ -634,7 +635,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
Button::image(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool(station_img_str.to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool(station_img_str.to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.image_color(color::LIGHT_RED)
|
||||
@ -815,7 +816,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool(station_img.to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool(station_img.to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.w_h(25.0, 25.0)
|
||||
@ -1056,7 +1057,7 @@ impl<'a> Widget for Crafting<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("DismantlingBench".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("DismantlingBench".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh([size; 2])
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
item_imgs::{animate_by_pulse, ItemImgs, ItemKey::Tool},
|
||||
item_imgs::{animate_by_pulse, ItemImgs},
|
||||
Position, PositionSpecifier, Show, BLACK, CRITICAL_HP_COLOR, HP_COLOR, TEXT_COLOR,
|
||||
UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR,
|
||||
};
|
||||
@ -34,6 +34,7 @@ use common::{
|
||||
ability::{Ability, ActiveAbilities, AuxiliaryAbility, MAX_ABILITIES},
|
||||
inventory::{
|
||||
item::{
|
||||
item_key::ItemKey,
|
||||
tool::{MaterialStatManifest, ToolKind},
|
||||
ItemKind,
|
||||
},
|
||||
@ -1358,7 +1359,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_general_combat_left".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_general_combat_left".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -1367,9 +1368,9 @@ impl<'a> Diary<'a> {
|
||||
.set(state.ids.general_combat_render_0, ui);
|
||||
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_general_combat_right".to_string())),
|
||||
&self.item_imgs.img_ids_or_not_found_img(ItemKey::Tool(
|
||||
"example_general_combat_right".to_string(),
|
||||
)),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -1536,7 +1537,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_sword".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_sword".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -1707,7 +1708,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_hammer".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_hammer".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -1865,7 +1866,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_axe".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_axe".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -2023,7 +2024,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_sceptre".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_sceptre".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -2175,7 +2176,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_bow".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_bow".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -2333,7 +2334,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_staff_fire".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_staff_fire".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
@ -2480,7 +2481,7 @@ impl<'a> Diary<'a> {
|
||||
Image::new(animate_by_pulse(
|
||||
&self
|
||||
.item_imgs
|
||||
.img_ids_or_not_found_img(Tool("example_pick".to_string())),
|
||||
.img_ids_or_not_found_img(ItemKey::Tool("example_pick".to_string())),
|
||||
self.pulse,
|
||||
))
|
||||
.wh(ART_SIZE)
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::hud::item_imgs::ItemKey;
|
||||
use common::comp::{self, inventory::item::Item};
|
||||
use common::comp::{
|
||||
self,
|
||||
inventory::item::{item_key::ItemKey, Item},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
@ -1,10 +1,7 @@
|
||||
use crate::ui::{Graphic, SampleStrat, Transform, Ui};
|
||||
use common::{
|
||||
assets::{self, AssetExt, AssetHandle, DotVoxAsset, ReloadWatcher},
|
||||
comp::item::{
|
||||
armor::{Armor, ArmorKind},
|
||||
Glider, ItemDef, ItemDesc, ItemKind, Lantern, Throwable, Utility,
|
||||
},
|
||||
comp::item::item_key::ItemKey,
|
||||
figure::Segment,
|
||||
};
|
||||
use conrod_core::image::Id;
|
||||
@ -20,48 +17,6 @@ pub fn animate_by_pulse(ids: &[Id], pulse: f32) -> Id {
|
||||
ids[animation_frame % ids.len()]
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ItemKey {
|
||||
Tool(String),
|
||||
ModularComponent(String),
|
||||
Lantern(String),
|
||||
Glider(String),
|
||||
Armor(ArmorKind),
|
||||
Utility(Utility),
|
||||
Consumable(String),
|
||||
Throwable(Throwable),
|
||||
Ingredient(String),
|
||||
TagExamples(Vec<ItemKey>),
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl<T: ItemDesc> From<&T> for ItemKey {
|
||||
fn from(item_desc: &T) -> Self {
|
||||
let item_kind = item_desc.kind();
|
||||
let item_definition_id = item_desc.item_definition_id();
|
||||
|
||||
match item_kind {
|
||||
ItemKind::Tool(_) => ItemKey::Tool(item_definition_id.to_owned()),
|
||||
ItemKind::ModularComponent(_) => {
|
||||
ItemKey::ModularComponent(item_definition_id.to_owned())
|
||||
},
|
||||
ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(kind.clone()),
|
||||
ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()),
|
||||
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
|
||||
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
|
||||
ItemKind::Consumable { .. } => ItemKey::Consumable(item_definition_id.to_owned()),
|
||||
ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind),
|
||||
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
|
||||
ItemKind::TagExamples { item_ids } => ItemKey::TagExamples(
|
||||
item_ids
|
||||
.iter()
|
||||
.map(|id| ItemKey::from(&*Arc::<ItemDef>::load_expect_cloned(id)))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum ImageSpec {
|
||||
Png(String),
|
||||
@ -97,6 +52,7 @@ impl ImageSpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ItemImagesSpec(HashMap<ItemKey, ImageSpec>);
|
||||
impl assets::Asset for ItemImagesSpec {
|
||||
|
@ -1,14 +1,14 @@
|
||||
use super::{
|
||||
hotbar::{self, Slot as HotbarSlot},
|
||||
img_ids,
|
||||
item_imgs::{ItemImgs, ItemKey},
|
||||
item_imgs::ItemImgs,
|
||||
util,
|
||||
};
|
||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||
use common::comp::{
|
||||
ability::{Ability, AbilityInput, AuxiliaryAbility},
|
||||
slot::InvSlotId,
|
||||
ActiveAbilities, Body, Energy, Inventory, SkillSet,
|
||||
ActiveAbilities, Body, Energy, Inventory, ItemKey, SkillSet,
|
||||
};
|
||||
use conrod_core::{image, Color};
|
||||
use specs::Entity as EcsEntity;
|
||||
|
@ -14,6 +14,7 @@ use common::{
|
||||
},
|
||||
item::{
|
||||
armor::{Armor, ArmorKind},
|
||||
item_key::ItemKey,
|
||||
Item, ItemKind,
|
||||
},
|
||||
CharacterState,
|
||||
@ -60,9 +61,12 @@ const LOD_COUNT: usize = 3;
|
||||
type FigureModelEntryLod<'b> = Option<&'b FigureModelEntry<LOD_COUNT>>;
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
/// TODO: merge item_key and extra field into an enum
|
||||
pub struct FigureKey<Body> {
|
||||
/// Body pointed to by this key.
|
||||
pub(super) body: Body,
|
||||
/// Only used by Body::ItemDrop
|
||||
pub item_key: Option<Arc<ItemKey>>,
|
||||
/// Extra state.
|
||||
pub(super) extra: Option<Arc<CharacterCacheKey>>,
|
||||
}
|
||||
@ -323,10 +327,12 @@ where
|
||||
_tick: u64,
|
||||
camera_mode: CameraMode,
|
||||
character_state: Option<&CharacterState>,
|
||||
item_key: Option<ItemKey>,
|
||||
) -> FigureModelEntryLod<'b> {
|
||||
// TODO: Use raw entries to avoid lots of allocation (among other things).
|
||||
let key = FigureKey {
|
||||
body,
|
||||
item_key: item_key.map(Arc::new),
|
||||
extra: inventory.map(|inventory| {
|
||||
Arc::new(CharacterCacheKey::from(
|
||||
character_state,
|
||||
@ -343,6 +349,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn get_or_create_model<'c>(
|
||||
&'c mut self,
|
||||
renderer: &mut Renderer,
|
||||
@ -354,6 +361,7 @@ where
|
||||
camera_mode: CameraMode,
|
||||
character_state: Option<&CharacterState>,
|
||||
slow_jobs: &SlowJobPool,
|
||||
item_key: Option<ItemKey>,
|
||||
) -> (FigureModelEntryLod<'c>, &'c Skel::Attr)
|
||||
where
|
||||
for<'a> &'a Skel::Body: Into<Skel::Attr>,
|
||||
@ -363,6 +371,7 @@ where
|
||||
let skeleton_attr = (&body).into();
|
||||
let key = FigureKey {
|
||||
body,
|
||||
item_key: item_key.map(Arc::new),
|
||||
extra: inventory.map(|inventory| {
|
||||
Arc::new(CharacterCacheKey::from(
|
||||
character_state,
|
||||
@ -417,7 +426,8 @@ where
|
||||
|
||||
slow_jobs.spawn("FIGURE_MESHING", move || {
|
||||
// First, load all the base vertex data.
|
||||
let meshes = <Skel::Body as BodySpec>::bone_meshes(&key, &manifests, extra);
|
||||
let meshes =
|
||||
<Skel::Body as BodySpec>::bone_meshes(&key, &manifests, extra);
|
||||
|
||||
// Then, set up meshing context.
|
||||
let mut greedy = FigureModel::make_greedy();
|
||||
@ -447,9 +457,7 @@ where
|
||||
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i as u8, bm)))
|
||||
.for_each(|(i, (segment, offset))| {
|
||||
// Generate this mesh.
|
||||
let (_opaque_mesh, bounds) =
|
||||
generate_mesh(&mut greedy, &mut opaque, segment, *offset, i);
|
||||
|
||||
let (_opaque_mesh, bounds) = generate_mesh(&mut greedy, &mut opaque, segment, *offset, i);
|
||||
// Update the figure bounds to the largest granularity seen so far
|
||||
// (NOTE: this is more than a little imperfect).
|
||||
//
|
||||
|
@ -12,8 +12,8 @@ use common::{
|
||||
fish_small::{self, BodyType as FSBodyType, Species as FSSpecies},
|
||||
golem::{self, BodyType as GBodyType, Species as GSpecies},
|
||||
humanoid::{self, Body, BodyType, EyeColor, Skin, Species},
|
||||
item::{ItemDef, ModularComponentKind},
|
||||
object,
|
||||
item::{item_key::ItemKey, ItemDef, ModularComponentKind},
|
||||
item_drop, object,
|
||||
quadruped_low::{self, BodyType as QLBodyType, Species as QLSpecies},
|
||||
quadruped_medium::{self, BodyType as QMBodyType, Species as QMSpecies},
|
||||
quadruped_small::{self, BodyType as QSBodyType, Species as QSSpecies},
|
||||
@ -23,7 +23,7 @@ use common::{
|
||||
},
|
||||
theropod::{self, BodyType as TBodyType, Species as TSpecies},
|
||||
},
|
||||
figure::{Cell, DynaUnionizer, MatSegment, Material, Segment},
|
||||
figure::{Cell, DynaUnionizer, MatCell, MatSegment, Material, Segment},
|
||||
vol::Vox,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
@ -137,7 +137,6 @@ macro_rules! make_vox_spec {
|
||||
type Manifests = AssetHandle<Self::Spec>;
|
||||
type Extra = ();
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn load_spec() -> Result<Self::Manifests, assets::Error> {
|
||||
Self::Spec::load("")
|
||||
}
|
||||
@ -398,7 +397,7 @@ make_vox_spec!(
|
||||
// TODO: Add these.
|
||||
/* tabard: HumArmorTabardSpec = "voxygen.voxel.humanoid_armor_tabard_manifest", */
|
||||
},
|
||||
|FigureKey { body, extra }, spec| {
|
||||
|FigureKey { body, item_key: _, extra }, spec| {
|
||||
const DEFAULT_LOADOUT: super::cache::CharacterCacheKey = super::cache::CharacterCacheKey {
|
||||
third_person: None,
|
||||
tool: None,
|
||||
@ -2888,7 +2887,7 @@ make_vox_spec!(
|
||||
armor_tail: BipedSmallArmorTailSpec = "voxygen.voxel.biped_small_armor_tail_manifest",
|
||||
|
||||
},
|
||||
|FigureKey { body: _, extra }, spec| {
|
||||
|FigureKey { body: _, item_key: _, extra }, spec| {
|
||||
const DEFAULT_LOADOUT: super::cache::CharacterCacheKey = super::cache::CharacterCacheKey {
|
||||
third_person: None,
|
||||
tool: None,
|
||||
@ -3917,7 +3916,7 @@ make_vox_spec!(
|
||||
main: BipedLargeMainSpec = "voxygen.voxel.biped_weapon_manifest",
|
||||
second: BipedLargeSecondSpec = "voxygen.voxel.biped_weapon_manifest",
|
||||
},
|
||||
|FigureKey { body, extra }, spec| {
|
||||
|FigureKey { body, item_key: _, extra }, spec| {
|
||||
const DEFAULT_LOADOUT: super::cache::CharacterCacheKey = super::cache::CharacterCacheKey {
|
||||
third_person: None,
|
||||
tool: None,
|
||||
@ -4902,6 +4901,75 @@ impl ObjectCentralSpec {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ItemDropCentralSpec(HashMap<ItemKey, (String, [f32; 3], [f32; 3], f32)>);
|
||||
|
||||
make_vox_spec!(
|
||||
item_drop::Body,
|
||||
struct ItemDropSpec {
|
||||
central: ItemDropCentralSpec = "voxygen.voxel.item_drop_manifest",
|
||||
},
|
||||
| FigureKey { body, item_key, .. }, spec| {
|
||||
[
|
||||
Some(spec.central.read().0.mesh_bone0(body, item_key.as_deref().unwrap_or(&ItemKey::Empty))),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
impl ItemDropCentralSpec {
|
||||
fn mesh_bone0(&self, item_drop: &item_drop::Body, item_key: &ItemKey) -> BoneMeshes {
|
||||
let coin_pouch = (
|
||||
"voxel.object.pouch".to_string(),
|
||||
[-5.0, -5.0, 0.0],
|
||||
[-10.0, 15.0, 0.0],
|
||||
0.8,
|
||||
);
|
||||
|
||||
if let Some(spec) = match item_drop {
|
||||
item_drop::Body::CoinPouch => Some(&coin_pouch),
|
||||
_ => self.0.get(item_key),
|
||||
} {
|
||||
let full_spec: String = ["voxygen.", spec.0.as_str()].concat();
|
||||
(
|
||||
match item_drop {
|
||||
item_drop::Body::Armor(_) => {
|
||||
MatSegment::from(&graceful_load_vox_fullspec(&full_spec).read().0)
|
||||
.map(|mat_cell| match mat_cell {
|
||||
MatCell::None => None,
|
||||
MatCell::Mat(_) => Some(MatCell::None),
|
||||
MatCell::Normal(data) => data.is_hollow().then(|| MatCell::None),
|
||||
})
|
||||
.to_segment(|_| Default::default())
|
||||
},
|
||||
_ => graceful_load_segment_fullspec(&full_spec),
|
||||
},
|
||||
Vec3::from(spec.1),
|
||||
)
|
||||
} else {
|
||||
error!(
|
||||
"No specification exists for {:?}, {:?}",
|
||||
item_drop, item_key
|
||||
);
|
||||
load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mesh_ship_bone<K: fmt::Debug + Eq + Hash, V, F: Fn(&V) -> &ShipCentralSubSpec>(
|
||||
map: &HashMap<K, V>,
|
||||
obj: &K,
|
||||
@ -4925,7 +4993,6 @@ impl BodySpec for ship::Body {
|
||||
type Manifests = AssetHandle<Self::Spec>;
|
||||
type Spec = ShipSpec;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn load_spec() -> Result<Self::Manifests, assets::Error> { Self::Spec::load("") }
|
||||
|
||||
fn reload_watcher(manifests: &Self::Manifests) -> ReloadWatcher { manifests.reload_watcher() }
|
||||
|
@ -24,16 +24,17 @@ use anim::{
|
||||
arthropod::ArthropodSkeleton, biped_large::BipedLargeSkeleton, biped_small::BipedSmallSkeleton,
|
||||
bird_large::BirdLargeSkeleton, bird_medium::BirdMediumSkeleton, character::CharacterSkeleton,
|
||||
dragon::DragonSkeleton, fish_medium::FishMediumSkeleton, fish_small::FishSmallSkeleton,
|
||||
golem::GolemSkeleton, object::ObjectSkeleton, quadruped_low::QuadrupedLowSkeleton,
|
||||
quadruped_medium::QuadrupedMediumSkeleton, quadruped_small::QuadrupedSmallSkeleton,
|
||||
ship::ShipSkeleton, theropod::TheropodSkeleton, Animation, Skeleton,
|
||||
golem::GolemSkeleton, item_drop::ItemDropSkeleton, object::ObjectSkeleton,
|
||||
quadruped_low::QuadrupedLowSkeleton, quadruped_medium::QuadrupedMediumSkeleton,
|
||||
quadruped_small::QuadrupedSmallSkeleton, ship::ShipSkeleton, theropod::TheropodSkeleton,
|
||||
Animation, Skeleton,
|
||||
};
|
||||
use common::{
|
||||
comp::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{Hands, ItemKind, ToolKind},
|
||||
Body, CharacterState, Collider, Controller, Health, Inventory, Item, Last, LightAnimation,
|
||||
LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel,
|
||||
Body, CharacterState, Collider, Controller, Health, Inventory, Item, ItemKey, Last,
|
||||
LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel,
|
||||
},
|
||||
link::Is,
|
||||
mounting::Rider,
|
||||
@ -117,6 +118,7 @@ struct FigureMgrStates {
|
||||
biped_small_states: HashMap<EcsEntity, FigureState<BipedSmallSkeleton>>,
|
||||
golem_states: HashMap<EcsEntity, FigureState<GolemSkeleton>>,
|
||||
object_states: HashMap<EcsEntity, FigureState<ObjectSkeleton>>,
|
||||
item_drop_states: HashMap<EcsEntity, FigureState<ItemDropSkeleton>>,
|
||||
ship_states: HashMap<EcsEntity, FigureState<ShipSkeleton>>,
|
||||
volume_states: HashMap<EcsEntity, FigureState<VolumeKey>>,
|
||||
arthropod_states: HashMap<EcsEntity, FigureState<ArthropodSkeleton>>,
|
||||
@ -139,6 +141,7 @@ impl FigureMgrStates {
|
||||
biped_small_states: HashMap::new(),
|
||||
golem_states: HashMap::new(),
|
||||
object_states: HashMap::new(),
|
||||
item_drop_states: HashMap::new(),
|
||||
ship_states: HashMap::new(),
|
||||
volume_states: HashMap::new(),
|
||||
arthropod_states: HashMap::new(),
|
||||
@ -202,6 +205,10 @@ impl FigureMgrStates {
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::Golem(_) => self.golem_states.get_mut(entity).map(DerefMut::deref_mut),
|
||||
Body::Object(_) => self.object_states.get_mut(entity).map(DerefMut::deref_mut),
|
||||
Body::ItemDrop(_) => self
|
||||
.item_drop_states
|
||||
.get_mut(entity)
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::Ship(ship) => {
|
||||
if ship.manifest_entry().is_some() {
|
||||
self.ship_states.get_mut(entity).map(DerefMut::deref_mut)
|
||||
@ -236,6 +243,7 @@ impl FigureMgrStates {
|
||||
Body::BipedSmall(_) => self.biped_small_states.remove(entity).map(|e| e.meta),
|
||||
Body::Golem(_) => self.golem_states.remove(entity).map(|e| e.meta),
|
||||
Body::Object(_) => self.object_states.remove(entity).map(|e| e.meta),
|
||||
Body::ItemDrop(_) => self.item_drop_states.remove(entity).map(|e| e.meta),
|
||||
Body::Ship(ship) => {
|
||||
if ship.manifest_entry().is_some() {
|
||||
self.ship_states.remove(entity).map(|e| e.meta)
|
||||
@ -263,6 +271,7 @@ impl FigureMgrStates {
|
||||
self.biped_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.golem_states.retain(|k, v| f(k, &mut *v));
|
||||
self.object_states.retain(|k, v| f(k, &mut *v));
|
||||
self.item_drop_states.retain(|k, v| f(k, &mut *v));
|
||||
self.ship_states.retain(|k, v| f(k, &mut *v));
|
||||
self.volume_states.retain(|k, v| f(k, &mut *v));
|
||||
self.arthropod_states.retain(|k, v| f(k, &mut *v));
|
||||
@ -284,6 +293,7 @@ impl FigureMgrStates {
|
||||
+ self.biped_small_states.len()
|
||||
+ self.golem_states.len()
|
||||
+ self.object_states.len()
|
||||
+ self.item_drop_states.len()
|
||||
+ self.ship_states.len()
|
||||
+ self.volume_states.len()
|
||||
+ self.arthropod_states.len()
|
||||
@ -359,6 +369,11 @@ impl FigureMgrStates {
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
+ self
|
||||
.item_drop_states
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
+ self
|
||||
.arthropod_states
|
||||
.iter()
|
||||
@ -388,6 +403,7 @@ pub struct FigureMgr {
|
||||
biped_large_model_cache: FigureModelCache<BipedLargeSkeleton>,
|
||||
biped_small_model_cache: FigureModelCache<BipedSmallSkeleton>,
|
||||
object_model_cache: FigureModelCache<ObjectSkeleton>,
|
||||
item_drop_model_cache: FigureModelCache<ItemDropSkeleton>,
|
||||
ship_model_cache: FigureModelCache<ShipSkeleton>,
|
||||
golem_model_cache: FigureModelCache<GolemSkeleton>,
|
||||
volume_model_cache: FigureModelCache<VolumeKey>,
|
||||
@ -412,6 +428,7 @@ impl FigureMgr {
|
||||
biped_large_model_cache: FigureModelCache::new(),
|
||||
biped_small_model_cache: FigureModelCache::new(),
|
||||
object_model_cache: FigureModelCache::new(),
|
||||
item_drop_model_cache: FigureModelCache::new(),
|
||||
ship_model_cache: FigureModelCache::new(),
|
||||
golem_model_cache: FigureModelCache::new(),
|
||||
volume_model_cache: FigureModelCache::new(),
|
||||
@ -446,6 +463,7 @@ impl FigureMgr {
|
||||
self.biped_small_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.object_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.item_drop_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.ship_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.golem_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.volume_model_cache.clean(&mut self.col_lights, tick);
|
||||
@ -864,6 +882,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let holding_lantern = inventory
|
||||
@ -1759,6 +1778,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -1957,6 +1977,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -2272,6 +2293,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -2627,6 +2649,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -2729,6 +2752,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -2810,6 +2834,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -3207,6 +3232,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self.states.dragon_states.entry(entity).or_insert_with(|| {
|
||||
@ -3292,6 +3318,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -3469,6 +3496,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -3759,6 +3787,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -4080,6 +4109,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -4161,6 +4191,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -4781,6 +4812,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self.states.golem_states.entry(entity).or_insert_with(|| {
|
||||
@ -5020,6 +5052,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self.states.object_states.entry(entity).or_insert_with(|| {
|
||||
@ -5135,6 +5168,68 @@ impl FigureMgr {
|
||||
body,
|
||||
);
|
||||
},
|
||||
Body::ItemDrop(body) => {
|
||||
let item_key = item.map(ItemKey::from);
|
||||
let (model, skeleton_attr) = self.item_drop_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
body,
|
||||
inventory,
|
||||
(),
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
item_key,
|
||||
);
|
||||
|
||||
let state = self
|
||||
.states
|
||||
.item_drop_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, ItemDropSkeleton::default(), body)
|
||||
});
|
||||
|
||||
// Average velocity relative to the current ground
|
||||
let _rel_avg_vel = state.avg_vel - physics.ground_vel;
|
||||
|
||||
let (character, last_character) = match (character, last_character) {
|
||||
(Some(c), Some(l)) => (c, l),
|
||||
_ => (
|
||||
&CharacterState::Idle(common::states::idle::Data {
|
||||
is_sneaking: false,
|
||||
}),
|
||||
&Last {
|
||||
0: CharacterState::Idle(common::states::idle::Data {
|
||||
is_sneaking: false,
|
||||
}),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
if !character.same_variant(&last_character.0) {
|
||||
state.state_time = 0.0;
|
||||
}
|
||||
|
||||
let target_bones = anim::item_drop::IdleAnimation::update_skeleton(
|
||||
&ItemDropSkeleton::default(),
|
||||
time,
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
);
|
||||
|
||||
state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp);
|
||||
state.update(
|
||||
renderer,
|
||||
&mut update_buf,
|
||||
&common_params,
|
||||
state_animation_rate,
|
||||
model,
|
||||
body,
|
||||
);
|
||||
},
|
||||
Body::Ship(body) => {
|
||||
let (model, skeleton_attr) = if let Some(Collider::Volume(vol)) = collider {
|
||||
let vk = VolumeKey {
|
||||
@ -5151,6 +5246,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
);
|
||||
|
||||
let state = self
|
||||
@ -5180,6 +5276,7 @@ impl FigureMgr {
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
&slow_jobs,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
// No way to determine model (this is okay, we might just not have received
|
||||
@ -5282,6 +5379,7 @@ impl FigureMgr {
|
||||
) {
|
||||
span!(_guard, "render_shadows", "FigureManager::render_shadows");
|
||||
let ecs = state.ecs();
|
||||
let items = ecs.read_storage::<Item>();
|
||||
|
||||
(
|
||||
&ecs.entities(),
|
||||
@ -5312,6 +5410,7 @@ impl FigureMgr {
|
||||
_ => 0,
|
||||
},
|
||||
|state| state.can_shadow_sun(),
|
||||
if matches!(body, Body::ItemDrop(_)) { items.get(entity).map(ItemKey::from) } else { None },
|
||||
) {
|
||||
drawer.draw(model, bound);
|
||||
}
|
||||
@ -5331,7 +5430,7 @@ impl FigureMgr {
|
||||
|
||||
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
|
||||
let character_state = character_state_storage.get(player_entity);
|
||||
|
||||
let items = ecs.read_storage::<Item>();
|
||||
for (entity, pos, body, _, inventory, scale, collider) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<Pos>(),
|
||||
@ -5362,6 +5461,11 @@ impl FigureMgr {
|
||||
_ => 0,
|
||||
},
|
||||
|state| state.visible(),
|
||||
if matches!(body, Body::ItemDrop(_)) {
|
||||
items.get(entity).map(ItemKey::from)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
) {
|
||||
drawer.draw(model, bound, col_lights);
|
||||
}
|
||||
@ -5381,6 +5485,7 @@ impl FigureMgr {
|
||||
|
||||
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
|
||||
let character_state = character_state_storage.get(player_entity);
|
||||
let items = ecs.read_storage::<Item>();
|
||||
|
||||
if let (Some(pos), Some(body)) = (
|
||||
ecs.read_storage::<Pos>().get(player_entity),
|
||||
@ -5407,6 +5512,11 @@ impl FigureMgr {
|
||||
figure_lod_render_distance,
|
||||
0,
|
||||
|state| state.visible(),
|
||||
if matches!(body, Body::ItemDrop(_)) {
|
||||
items.get(player_entity).map(ItemKey::from)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
) {
|
||||
drawer.draw(model, bound, col_lights);
|
||||
/*renderer.render_player_shadow(
|
||||
@ -5435,6 +5545,7 @@ impl FigureMgr {
|
||||
figure_lod_render_distance: f32,
|
||||
mut_count: usize,
|
||||
filter_state: impl Fn(&FigureStateMeta) -> bool,
|
||||
item_key: Option<ItemKey>,
|
||||
) -> Option<FigureModelRef> {
|
||||
let body = *body;
|
||||
|
||||
@ -5462,6 +5573,7 @@ impl FigureMgr {
|
||||
biped_large_model_cache,
|
||||
biped_small_model_cache,
|
||||
object_model_cache,
|
||||
item_drop_model_cache,
|
||||
ship_model_cache,
|
||||
golem_model_cache,
|
||||
volume_model_cache,
|
||||
@ -5482,6 +5594,7 @@ impl FigureMgr {
|
||||
biped_small_states,
|
||||
golem_states,
|
||||
object_states,
|
||||
item_drop_states,
|
||||
ship_states,
|
||||
volume_states,
|
||||
arthropod_states,
|
||||
@ -5502,6 +5615,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5518,6 +5632,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5534,6 +5649,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5550,6 +5666,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5566,6 +5683,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5582,6 +5700,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5598,6 +5717,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5614,6 +5734,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5630,6 +5751,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5646,6 +5768,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5662,6 +5785,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5678,6 +5802,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5694,6 +5819,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5710,6 +5836,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5726,6 +5853,24 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::ItemDrop(body) => item_drop_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.bound(),
|
||||
item_drop_model_cache.get_model(
|
||||
col_lights,
|
||||
body,
|
||||
inventory,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
item_key,
|
||||
),
|
||||
)
|
||||
}),
|
||||
@ -5744,6 +5889,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
})
|
||||
@ -5761,6 +5907,7 @@ impl FigureMgr {
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
None,
|
||||
),
|
||||
)
|
||||
})
|
||||
|
@ -325,6 +325,7 @@ impl Scene {
|
||||
CameraMode::default(),
|
||||
None,
|
||||
scene_data.slow_job_pool,
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
||||
@ -369,6 +370,7 @@ impl Scene {
|
||||
tick,
|
||||
CameraMode::default(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
if let Some((model, figure_state)) = model.zip(self.figure_state.as_ref()) {
|
||||
|
@ -2,7 +2,7 @@ use super::image_frame::ImageFrame;
|
||||
use crate::hud::{
|
||||
get_quality_col,
|
||||
img_ids::Imgs,
|
||||
item_imgs::{animate_by_pulse, ItemImgs, ItemKey},
|
||||
item_imgs::{animate_by_pulse, ItemImgs},
|
||||
util,
|
||||
};
|
||||
use client::Client;
|
||||
@ -11,6 +11,7 @@ use common::{
|
||||
comp::{
|
||||
item::{
|
||||
armor::{ArmorKind, Protection},
|
||||
item_key::ItemKey,
|
||||
Item, ItemDesc, ItemKind, ItemTag, MaterialStatManifest, Quality,
|
||||
},
|
||||
Energy,
|
||||
|
Loading…
Reference in New Issue
Block a user