mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Item icons, chests and more
This commit is contained in:
parent
c0732d7787
commit
d82ec6715a
BIN
assets/voxygen/element/bag/slot.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/bag/slot.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/buttons/inv_slot.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/buttons/inv_slot.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/buttons/inv_slot_sel.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/buttons/inv_slot_sel.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/icons/item_apple.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/item_apple.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/item_flower.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/icons/item_flower.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/element/icons/item_flower.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/item_flower.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/item_grass.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/item_grass.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/item_mushroom.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/item_mushroom.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/not_found.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/element/not_found.png
(Stored with Git LFS)
Normal file
Binary file not shown.
56
assets/voxygen/item_image_manifest.ron
Normal file
56
assets/voxygen/item_image_manifest.ron
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Png(specifier),
|
||||||
|
// Vox(specier),
|
||||||
|
// VoxTrans(specifier, offset, (x_rot, y_rot, z_rot), zoom)
|
||||||
|
({ // Debug Items
|
||||||
|
Debug(Boost): VoxTrans(
|
||||||
|
"voxel.weapon.debug_wand",
|
||||||
|
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
|
||||||
|
),
|
||||||
|
// Weapons
|
||||||
|
Tool(Bow): VoxTrans(
|
||||||
|
"voxel.weapon.bow.simple-bow",
|
||||||
|
(0.0, 0.0, 0.0), (90.0, 90.0, 0.0), 1.0,
|
||||||
|
),
|
||||||
|
Tool(Dagger): VoxTrans(
|
||||||
|
"voxel.weapon.dagger.dagger_rusty",
|
||||||
|
(0.0, 0.0, -4.0), (-120.0, 90.0, 0.0), 1.1,
|
||||||
|
),
|
||||||
|
Tool(Sword): VoxTrans(
|
||||||
|
"voxel.weapon.sword.rusty_2h",
|
||||||
|
(0.0, 9.0, 0.0), (-90.0, 90.0, 0.0), 2.4,
|
||||||
|
),
|
||||||
|
Tool(Axe): VoxTrans(
|
||||||
|
"voxel.weapon.axe.rusty_2h",
|
||||||
|
(0.0, -8.0, 0.0), (-90.0, 90.0, 0.0), 2.0,
|
||||||
|
),
|
||||||
|
Tool(Hammer): VoxTrans(
|
||||||
|
"voxel.weapon.hammer.rusty_2h",
|
||||||
|
(0.0, -8.0, 0.0), (-90.0, 90.0, 0.0), 2.0,
|
||||||
|
),
|
||||||
|
// Consumables
|
||||||
|
Consumable(Apple): VoxTrans(
|
||||||
|
"element.icons.item_apple",
|
||||||
|
(0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 1.0,
|
||||||
|
),
|
||||||
|
Consumable(Potion): VoxTrans(
|
||||||
|
"voxel.object.potion_red",
|
||||||
|
(0.0, 0.0, 0.0), (90.0, 90.0, 0.0), 1.0,
|
||||||
|
),
|
||||||
|
Consumable(Mushroom): VoxTrans(
|
||||||
|
"voxel.sprite.mushrooms.mushroom-4",
|
||||||
|
(0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0,
|
||||||
|
),
|
||||||
|
Consumable(Velorite): VoxTrans(
|
||||||
|
"voxel.sprite.velorite.velorite_ore",
|
||||||
|
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||||
|
),
|
||||||
|
// Ingredients
|
||||||
|
Ingredient(Flower): VoxTrans(
|
||||||
|
"voxel.sprite.flowers.flower_red_2",
|
||||||
|
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||||
|
),
|
||||||
|
Ingredient(Grass): VoxTrans(
|
||||||
|
"voxel.sprite.grass.grass_long_5",
|
||||||
|
(0.0, 0.0, 0.0), (-90.0, 50.0, 0.0), 1.0,
|
||||||
|
),
|
||||||
|
})
|
BIN
assets/voxygen/voxel/sprite/chests/chest.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_dark.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_dark.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_demon.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_demon.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_gold.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_gold.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_light.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_light.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_skull.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_skull.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/chests/chest_vines.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/sprite/chests/chest_vines.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/structure/dungeon/meso_sewer_temple.vox
(Stored with Git LFS)
BIN
assets/world/structure/dungeon/meso_sewer_temple.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/structure/dungeon/ruins.vox
(Stored with Git LFS)
BIN
assets/world/structure/dungeon/ruins.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/structure/natural/tower-ruin.vox
(Stored with Git LFS)
BIN
assets/world/structure/natural/tower-ruin.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/structure/natural/witch-hut.vox
(Stored with Git LFS)
BIN
assets/world/structure/natural/witch-hut.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/mangroves/5.vox
(Stored with Git LFS)
BIN
assets/world/tree/mangroves/5.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/mangroves/7.vox
(Stored with Git LFS)
BIN
assets/world/tree/mangroves/7.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/oak_green/3.vox
(Stored with Git LFS)
BIN
assets/world/tree/oak_green/3.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/oak_green/5.vox
(Stored with Git LFS)
BIN
assets/world/tree/oak_green/5.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/oak_green/9.vox
(Stored with Git LFS)
BIN
assets/world/tree/oak_green/9.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/world/tree/oak_stump/3.vox
(Stored with Git LFS)
BIN
assets/world/tree/oak_stump/3.vox
(Stored with Git LFS)
Binary file not shown.
@ -3,13 +3,14 @@ use crate::{
|
|||||||
effect::Effect,
|
effect::Effect,
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
};
|
};
|
||||||
|
use rand::prelude::*;
|
||||||
use specs::{Component, FlaggedStorage};
|
use specs::{Component, FlaggedStorage};
|
||||||
use specs_idvs::IDVStorage;
|
use specs_idvs::IDVStorage;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Tool {
|
pub enum Tool {
|
||||||
Daggers,
|
Dagger,
|
||||||
SwordShield,
|
Shield,
|
||||||
Sword,
|
Sword,
|
||||||
Axe,
|
Axe,
|
||||||
Hammer,
|
Hammer,
|
||||||
@ -20,20 +21,43 @@ pub enum Tool {
|
|||||||
impl Tool {
|
impl Tool {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Tool::Daggers => "daggers",
|
Tool::Dagger => "Dagger",
|
||||||
Tool::SwordShield => "sword and shield",
|
Tool::Shield => "Shield",
|
||||||
Tool::Sword => "sword",
|
Tool::Sword => "Sword",
|
||||||
Tool::Axe => "axe",
|
Tool::Axe => "Axe",
|
||||||
Tool::Hammer => "hammer",
|
Tool::Hammer => "Hammer",
|
||||||
Tool::Bow => "bow",
|
Tool::Bow => "Bow",
|
||||||
Tool::Staff => "staff",
|
Tool::Staff => "Staff",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Tool::Dagger => "A basic kitchen knife.",
|
||||||
|
Tool::Shield => {
|
||||||
|
"This shield belonged to many adventurers.\n\
|
||||||
|
Now it's yours.\n\
|
||||||
|
NOT YET AVAILABLE."
|
||||||
|
}
|
||||||
|
Tool::Sword => "When closing one eye it's nearly like it wasn't rusty at all!",
|
||||||
|
Tool::Axe => {
|
||||||
|
"It has a name written on it.\n\
|
||||||
|
Sounds dwarvish."
|
||||||
|
}
|
||||||
|
Tool::Hammer => "Use with caution around nails.",
|
||||||
|
Tool::Bow => "An old but sturdy hunting bow.",
|
||||||
|
Tool::Staff => {
|
||||||
|
"A carved stick.\n\
|
||||||
|
The wood smells like magic.\n\
|
||||||
|
NOT YET AVAILABLE."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ALL_TOOLS: [Tool; 7] = [
|
pub const ALL_TOOLS: [Tool; 7] = [
|
||||||
Tool::Daggers,
|
Tool::Dagger,
|
||||||
Tool::SwordShield,
|
Tool::Shield,
|
||||||
Tool::Sword,
|
Tool::Sword,
|
||||||
Tool::Axe,
|
Tool::Axe,
|
||||||
Tool::Hammer,
|
Tool::Hammer,
|
||||||
@ -43,7 +67,7 @@ pub const ALL_TOOLS: [Tool; 7] = [
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Armor {
|
pub enum Armor {
|
||||||
// TODO: Don't make armor be a body part. Wearing enemy's head is funny but also creepy thing to do.
|
// TODO: Don't make armor be a body part. Wearing enemy's head is funny but also a creepy thing to do.
|
||||||
Helmet,
|
Helmet,
|
||||||
Shoulders,
|
Shoulders,
|
||||||
Chestplate,
|
Chestplate,
|
||||||
@ -60,19 +84,23 @@ pub enum Armor {
|
|||||||
impl Armor {
|
impl Armor {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Armor::Helmet => "helmet",
|
Armor::Helmet => "Helmet",
|
||||||
Armor::Shoulders => "shoulder pads",
|
Armor::Shoulders => "Shoulder Pads",
|
||||||
Armor::Chestplate => "chestplate",
|
Armor::Chestplate => "Chestplate",
|
||||||
Armor::Belt => "belt",
|
Armor::Belt => "Belt",
|
||||||
Armor::Gloves => "gloves",
|
Armor::Gloves => "Gloves",
|
||||||
Armor::Pants => "pants",
|
Armor::Pants => "Pants",
|
||||||
Armor::Boots => "boots",
|
Armor::Boots => "Boots",
|
||||||
Armor::Back => "back",
|
Armor::Back => "Back",
|
||||||
Armor::Tabard => "tabard",
|
Armor::Tabard => "Tabard",
|
||||||
Armor::Gem => "gem",
|
Armor::Gem => "Gem",
|
||||||
Armor::Necklace => "necklace",
|
Armor::Necklace => "Necklace",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> &'static str {
|
||||||
|
self.name()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
@ -86,10 +114,19 @@ pub enum Consumable {
|
|||||||
impl Consumable {
|
impl Consumable {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Consumable::Apple => "apple",
|
Consumable::Apple => "Apple",
|
||||||
Consumable::Potion => "potion",
|
Consumable::Potion => "Potion",
|
||||||
Consumable::Mushroom => "mushroom",
|
Consumable::Mushroom => "Mushroom",
|
||||||
Consumable::Velorite => "velorite",
|
Consumable::Velorite => "Velorite",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Consumable::Apple => "A tasty Apple.",
|
||||||
|
Consumable::Potion => "This Potion contains the essence of Life.",
|
||||||
|
Consumable::Mushroom => "A common Mushroom.",
|
||||||
|
Consumable::Velorite => "Has a subtle turqoise glow.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,8 +140,15 @@ pub enum Ingredient {
|
|||||||
impl Ingredient {
|
impl Ingredient {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Ingredient::Flower => "flower",
|
Ingredient::Flower => "Flower",
|
||||||
Ingredient::Grass => "grass",
|
Ingredient::Grass => "Grass",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Ingredient::Flower => "It smells great.",
|
||||||
|
Ingredient::Grass => "Greener than an orc's snout.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +156,7 @@ impl Ingredient {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Debug {
|
pub enum Debug {
|
||||||
Boost,
|
Boost,
|
||||||
|
Possess,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
@ -119,11 +164,17 @@ pub enum Item {
|
|||||||
Tool {
|
Tool {
|
||||||
kind: Tool,
|
kind: Tool,
|
||||||
power: u32,
|
power: u32,
|
||||||
|
stamina: i32,
|
||||||
|
strength: i32,
|
||||||
|
dexterity: i32,
|
||||||
|
intelligence: i32,
|
||||||
},
|
},
|
||||||
Armor {
|
Armor {
|
||||||
kind: Armor,
|
kind: Armor,
|
||||||
defense: i32,
|
stamina: i32,
|
||||||
health_bonus: i32,
|
strength: i32,
|
||||||
|
dexterity: i32,
|
||||||
|
intelligence: i32,
|
||||||
},
|
},
|
||||||
Consumable {
|
Consumable {
|
||||||
kind: Consumable,
|
kind: Consumable,
|
||||||
@ -141,23 +192,43 @@ impl Item {
|
|||||||
Item::Tool { kind, .. } => kind.name(),
|
Item::Tool { kind, .. } => kind.name(),
|
||||||
Item::Armor { kind, .. } => kind.name(),
|
Item::Armor { kind, .. } => kind.name(),
|
||||||
Item::Consumable { kind, .. } => kind.name(),
|
Item::Consumable { kind, .. } => kind.name(),
|
||||||
Item::Ingredient { kind } => kind.name(),
|
Item::Ingredient { kind, .. } => kind.name(),
|
||||||
Item::Debug(_) => "Debugging item",
|
Item::Debug(_) => "Debugging item",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn title(&self) -> String {
|
||||||
|
format!("{} ({})", self.name(), self.category())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Item::Tool { power, .. } => format!("{:+} attack", power),
|
||||||
|
Item::Armor { .. } => String::new(),
|
||||||
|
Item::Consumable { effect, .. } => format!("{}", effect.info()),
|
||||||
|
Item::Ingredient { .. } => String::new(),
|
||||||
|
Item::Debug(_) => format!("+99999 insanity"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn category(&self) -> &'static str {
|
pub fn category(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Item::Tool { .. } => "tool",
|
Item::Tool { .. } => "Tool",
|
||||||
Item::Armor { .. } => "armour",
|
Item::Armor { .. } => "Armor",
|
||||||
Item::Consumable { .. } => "consumable",
|
Item::Consumable { .. } => "Consumable",
|
||||||
Item::Ingredient { .. } => "ingredient",
|
Item::Ingredient { .. } => "Ingredient",
|
||||||
Item::Debug(_) => "debug",
|
Item::Debug(_) => "Debug",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn description(&self) -> String {
|
pub fn description(&self) -> String {
|
||||||
format!("{} ({})", self.name(), self.category())
|
match self {
|
||||||
|
Item::Tool { kind, .. } => format!("{}", kind.description()),
|
||||||
|
Item::Armor { kind, .. } => format!("{}", kind.description()),
|
||||||
|
Item::Consumable { kind, .. } => format!("{}", kind.description()),
|
||||||
|
Item::Ingredient { kind, .. } => format!("{}", kind.description()),
|
||||||
|
Item::Debug(_) => format!("Debugging item"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
|
||||||
@ -175,6 +246,19 @@ impl Item {
|
|||||||
BlockKind::LongGrass => Some(Self::grass()),
|
BlockKind::LongGrass => Some(Self::grass()),
|
||||||
BlockKind::MediumGrass => Some(Self::grass()),
|
BlockKind::MediumGrass => Some(Self::grass()),
|
||||||
BlockKind::ShortGrass => Some(Self::grass()),
|
BlockKind::ShortGrass => Some(Self::grass()),
|
||||||
|
BlockKind::Chest => Some(match rand::random::<usize>() % 3 {
|
||||||
|
0 => Self::apple(),
|
||||||
|
1 => Self::velorite(),
|
||||||
|
2 => Item::Tool {
|
||||||
|
kind: *(&ALL_TOOLS).choose(&mut rand::thread_rng()).unwrap(),
|
||||||
|
power: 8 + rand::random::<u32>() % (rand::random::<u32>() % 30),
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +268,7 @@ impl Item {
|
|||||||
pub fn apple() -> Self {
|
pub fn apple() -> Self {
|
||||||
Item::Consumable {
|
Item::Consumable {
|
||||||
kind: Consumable::Apple,
|
kind: Consumable::Apple,
|
||||||
effect: Effect::Health(20, comp::HealthSource::Item),
|
effect: Effect::Health(50, comp::HealthSource::Item),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,8 +281,8 @@ impl Item {
|
|||||||
|
|
||||||
pub fn velorite() -> Self {
|
pub fn velorite() -> Self {
|
||||||
Item::Consumable {
|
Item::Consumable {
|
||||||
kind: Consumable::Mushroom,
|
kind: Consumable::Velorite,
|
||||||
effect: Effect::Xp(250),
|
effect: Effect::Xp(50),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +304,10 @@ impl Default for Item {
|
|||||||
Item::Tool {
|
Item::Tool {
|
||||||
kind: Tool::Hammer,
|
kind: Tool::Hammer,
|
||||||
power: 0,
|
power: 0,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
//Re-Exports
|
|
||||||
pub mod item;
|
pub mod item;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
@ -77,22 +76,42 @@ impl Default for Inventory {
|
|||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Bow,
|
kind: Tool::Bow,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
});
|
});
|
||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Daggers,
|
kind: Tool::Dagger,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
});
|
});
|
||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Sword,
|
kind: Tool::Sword,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
});
|
});
|
||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Axe,
|
kind: Tool::Axe,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
});
|
});
|
||||||
inventory.push(Item::Tool {
|
inventory.push(Item::Tool {
|
||||||
kind: Tool::Hammer,
|
kind: Tool::Hammer,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
inventory
|
inventory
|
||||||
|
@ -6,3 +6,12 @@ pub enum Effect {
|
|||||||
Health(i32, comp::HealthSource),
|
Health(i32, comp::HealthSource),
|
||||||
Xp(i64),
|
Xp(i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Effect {
|
||||||
|
pub fn info(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Effect::Health(n, _) => format!("{:+} health", n),
|
||||||
|
Effect::Xp(n) => format!("{:+} exp", n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ pub enum BlockKind {
|
|||||||
Mushroom,
|
Mushroom,
|
||||||
Liana,
|
Liana,
|
||||||
Velorite,
|
Velorite,
|
||||||
|
Chest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockKind {
|
impl BlockKind {
|
||||||
@ -63,6 +64,7 @@ impl BlockKind {
|
|||||||
BlockKind::Mushroom => true,
|
BlockKind::Mushroom => true,
|
||||||
BlockKind::Liana => true,
|
BlockKind::Liana => true,
|
||||||
BlockKind::Velorite => true,
|
BlockKind::Velorite => true,
|
||||||
|
BlockKind::Chest => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,6 +100,7 @@ impl BlockKind {
|
|||||||
BlockKind::Mushroom => false,
|
BlockKind::Mushroom => false,
|
||||||
BlockKind::Liana => false,
|
BlockKind::Liana => false,
|
||||||
BlockKind::Velorite => false,
|
BlockKind::Velorite => false,
|
||||||
|
BlockKind::Chest => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,6 +128,7 @@ impl BlockKind {
|
|||||||
BlockKind::Apple => true,
|
BlockKind::Apple => true,
|
||||||
BlockKind::Mushroom => false,
|
BlockKind::Mushroom => false,
|
||||||
BlockKind::Liana => false,
|
BlockKind::Liana => false,
|
||||||
|
BlockKind::Chest => true,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,6 +148,7 @@ impl BlockKind {
|
|||||||
BlockKind::Apple => true,
|
BlockKind::Apple => true,
|
||||||
BlockKind::Mushroom => true,
|
BlockKind::Mushroom => true,
|
||||||
BlockKind::Velorite => true,
|
BlockKind::Velorite => true,
|
||||||
|
BlockKind::Chest => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ pub enum StructureBlock {
|
|||||||
Water,
|
Water,
|
||||||
GreenSludge,
|
GreenSludge,
|
||||||
Fruit,
|
Fruit,
|
||||||
|
Chest,
|
||||||
Hollow,
|
Hollow,
|
||||||
Liana,
|
Liana,
|
||||||
Normal(Rgb<u8>),
|
Normal(Rgb<u8>),
|
||||||
@ -116,6 +117,7 @@ impl Asset for Structure {
|
|||||||
6 => StructureBlock::GreenSludge,
|
6 => StructureBlock::GreenSludge,
|
||||||
7 => StructureBlock::Fruit,
|
7 => StructureBlock::Fruit,
|
||||||
9 => StructureBlock::Liana,
|
9 => StructureBlock::Liana,
|
||||||
|
10 => StructureBlock::Chest,
|
||||||
15 => StructureBlock::Hollow,
|
15 => StructureBlock::Hollow,
|
||||||
index => {
|
index => {
|
||||||
let color = palette
|
let color = palette
|
||||||
|
@ -567,6 +567,10 @@ impl Server {
|
|||||||
Some(comp::Item::Tool {
|
Some(comp::Item::Tool {
|
||||||
kind: comp::item::Tool::Sword,
|
kind: comp::item::Tool::Sword,
|
||||||
power: 5,
|
power: 5,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
let body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
||||||
@ -588,6 +592,10 @@ impl Server {
|
|||||||
Some(comp::Item::Tool {
|
Some(comp::Item::Tool {
|
||||||
kind: comp::item::Tool::Sword,
|
kind: comp::item::Tool::Sword,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
||||||
@ -1020,7 +1028,14 @@ impl Server {
|
|||||||
client,
|
client,
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
main.map(|t| comp::Item::Tool { kind: t, power: 10 }),
|
main.map(|t| comp::Item::Tool {
|
||||||
|
kind: t,
|
||||||
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
|
}),
|
||||||
&server_settings,
|
&server_settings,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ impl Animation for BlockAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::SwordShield => {
|
Tool::Shield => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
@ -203,7 +203,7 @@ impl Animation for BlockAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::Daggers => {
|
Tool::Dagger => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
|
@ -152,7 +152,7 @@ impl Animation for BlockIdleAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::SwordShield => {
|
Tool::Shield => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
@ -202,7 +202,7 @@ impl Animation for BlockIdleAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::Daggers => {
|
Tool::Dagger => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
|
@ -160,7 +160,7 @@ impl Animation for CidleAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::SwordShield => {
|
Tool::Shield => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
@ -214,7 +214,7 @@ impl Animation for CidleAnimation {
|
|||||||
* Quaternion::rotation_z(0.85);
|
* Quaternion::rotation_z(0.85);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::Daggers => {
|
Tool::Dagger => {
|
||||||
next.l_hand.offset = Vec3::new(
|
next.l_hand.offset = Vec3::new(
|
||||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||||
3.5 + wave_ultra_slow_cos * 0.5,
|
3.5 + wave_ultra_slow_cos * 0.5,
|
||||||
|
@ -96,7 +96,7 @@ impl Animation for WieldAnimation {
|
|||||||
* Quaternion::rotation_z(0.0);
|
* Quaternion::rotation_z(0.0);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::SwordShield => {
|
Tool::Shield => {
|
||||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||||
next.l_hand.scale = Vec3::one() * 1.01;
|
next.l_hand.scale = Vec3::one() * 1.01;
|
||||||
@ -134,7 +134,7 @@ impl Animation for WieldAnimation {
|
|||||||
* Quaternion::rotation_z(0.85);
|
* Quaternion::rotation_z(0.85);
|
||||||
next.weapon.scale = Vec3::one();
|
next.weapon.scale = Vec3::one();
|
||||||
}
|
}
|
||||||
Tool::Daggers => {
|
Tool::Dagger => {
|
||||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||||
next.l_hand.scale = Vec3::one() * 1.01;
|
next.l_hand.scale = Vec3::one() * 1.01;
|
||||||
|
@ -150,20 +150,20 @@ impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
|
|||||||
Tool::Sword => 0.0,
|
Tool::Sword => 0.0,
|
||||||
Tool::Axe => 3.0,
|
Tool::Axe => 3.0,
|
||||||
Tool::Hammer => 0.0,
|
Tool::Hammer => 0.0,
|
||||||
Tool::SwordShield => 3.0,
|
Tool::Shield => 3.0,
|
||||||
Tool::Staff => 3.0,
|
Tool::Staff => 3.0,
|
||||||
Tool::Bow => 0.0,
|
Tool::Bow => 0.0,
|
||||||
Tool::Daggers => 0.0,
|
Tool::Dagger => 0.0,
|
||||||
},
|
},
|
||||||
weapon_y: match Tool::Hammer {
|
weapon_y: match Tool::Hammer {
|
||||||
// TODO: Inventory
|
// TODO: Inventory
|
||||||
Tool::Sword => -1.25,
|
Tool::Sword => -1.25,
|
||||||
Tool::Axe => 0.0,
|
Tool::Axe => 0.0,
|
||||||
Tool::Hammer => -2.0,
|
Tool::Hammer => -2.0,
|
||||||
Tool::SwordShield => 0.0,
|
Tool::Shield => 0.0,
|
||||||
Tool::Staff => 0.0,
|
Tool::Staff => 0.0,
|
||||||
Tool::Bow => -2.0,
|
Tool::Bow => -2.0,
|
||||||
Tool::Daggers => -2.0,
|
Tool::Dagger => -2.0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::{Imgs, ImgsRot},
|
img_ids::{Imgs, ImgsRot},
|
||||||
|
item_imgs::{ItemImgs, ItemKind},
|
||||||
Event as HudEvent, Fonts, TEXT_COLOR,
|
Event as HudEvent, Fonts, TEXT_COLOR,
|
||||||
};
|
};
|
||||||
use crate::ui::{ImageFrame, Tooltip, TooltipManager, Tooltipable};
|
use crate::ui::{ImageFrame, Tooltip, TooltipManager, Tooltipable};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color,
|
color, image,
|
||||||
position::Relative,
|
position::Relative,
|
||||||
widget::{self, Button, Image, Rectangle /*, Scrollbar*/},
|
widget::{self, Button, Image, Rectangle /*, Scrollbar*/},
|
||||||
widget_ids, Color, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
|
widget_ids, Color, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
|
||||||
@ -33,6 +34,7 @@ widget_ids! {
|
|||||||
pub struct Bag<'a> {
|
pub struct Bag<'a> {
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
|
item_imgs: &'a ItemImgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
common: widget::CommonBuilder,
|
common: widget::CommonBuilder,
|
||||||
@ -44,6 +46,7 @@ impl<'a> Bag<'a> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
|
item_imgs: &'a ItemImgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
rot_imgs: &'a ImgsRot,
|
rot_imgs: &'a ImgsRot,
|
||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
@ -51,6 +54,7 @@ impl<'a> Bag<'a> {
|
|||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
imgs,
|
imgs,
|
||||||
|
item_imgs,
|
||||||
fonts,
|
fonts,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
@ -61,6 +65,7 @@ impl<'a> Bag<'a> {
|
|||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
|
img_id_cache: Vec<Option<(ItemKind, image::Id)>>,
|
||||||
selected_slot: Option<usize>,
|
selected_slot: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +84,7 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
||||||
State {
|
State {
|
||||||
ids: Ids::new(id_gen),
|
ids: Ids::new(id_gen),
|
||||||
|
img_id_cache: Vec::new(),
|
||||||
selected_slot: None,
|
selected_slot: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,27 +117,28 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.title_font_size(15)
|
.title_font_size(15)
|
||||||
.desc_font_size(10)
|
.parent(ui.window)
|
||||||
|
.desc_font_size(12)
|
||||||
.title_text_color(TEXT_COLOR)
|
.title_text_color(TEXT_COLOR)
|
||||||
.desc_text_color(TEXT_COLOR);
|
.desc_text_color(TEXT_COLOR);
|
||||||
|
|
||||||
// Bag parts
|
// Bag parts
|
||||||
Image::new(self.imgs.bag_bot)
|
Image::new(self.imgs.bag_bot)
|
||||||
.w_h(61.0 * BAG_SCALE, 9.0 * BAG_SCALE)
|
.w_h(58.0 * BAG_SCALE, 9.0 * BAG_SCALE)
|
||||||
.bottom_right_with_margins_on(ui.window, 60.0, 5.0)
|
.bottom_right_with_margins_on(ui.window, 60.0, 5.0)
|
||||||
.set(state.ids.bag_bot, ui);
|
.set(state.ids.bag_bot, ui);
|
||||||
let mid_height = ((inventory.len() + 4) / 5) as f64 * 44.0;
|
let mid_height = ((inventory.len() + 4) / 5) as f64 * 44.0;
|
||||||
Image::new(self.imgs.bag_mid)
|
Image::new(self.imgs.bag_mid)
|
||||||
.w_h(61.0 * BAG_SCALE, mid_height)
|
.w_h(58.0 * BAG_SCALE, mid_height)
|
||||||
.up_from(state.ids.bag_bot, 0.0)
|
.up_from(state.ids.bag_bot, 0.0)
|
||||||
.set(state.ids.bag_mid, ui);
|
.set(state.ids.bag_mid, ui);
|
||||||
Image::new(self.imgs.bag_top)
|
Image::new(self.imgs.bag_top)
|
||||||
.w_h(61.0 * BAG_SCALE, 9.0 * BAG_SCALE)
|
.w_h(58.0 * BAG_SCALE, 9.0 * BAG_SCALE)
|
||||||
.up_from(state.ids.bag_mid, 0.0)
|
.up_from(state.ids.bag_mid, 0.0)
|
||||||
.set(state.ids.bag_top, ui);
|
.set(state.ids.bag_top, ui);
|
||||||
|
|
||||||
// Alignment for Grid
|
// Alignment for Grid
|
||||||
Rectangle::fill_with([54.0 * BAG_SCALE, mid_height], color::TRANSPARENT)
|
Rectangle::fill_with([56.0 * BAG_SCALE, mid_height], color::TRANSPARENT)
|
||||||
.top_left_with_margins_on(state.ids.bag_mid, 0.0, 3.0 * BAG_SCALE)
|
.top_left_with_margins_on(state.ids.bag_mid, 0.0, 3.0 * BAG_SCALE)
|
||||||
.scroll_kids_vertically()
|
.scroll_kids_vertically()
|
||||||
.set(state.ids.inv_alignment, ui);
|
.set(state.ids.inv_alignment, ui);
|
||||||
@ -151,6 +158,12 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
.resize(inventory.len(), &mut ui.widget_id_generator());
|
.resize(inventory.len(), &mut ui.widget_id_generator());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Expand img id cache to the number of slots
|
||||||
|
if state.img_id_cache.len() < inventory.len() {
|
||||||
|
state.update(|s| {
|
||||||
|
s.img_id_cache.resize(inventory.len(), None);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Display inventory contents
|
// Display inventory contents
|
||||||
for (i, item) in inventory.slots().iter().enumerate() {
|
for (i, item) in inventory.slots().iter().enumerate() {
|
||||||
@ -160,11 +173,15 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
let is_selected = Some(i) == state.selected_slot;
|
let is_selected = Some(i) == state.selected_slot;
|
||||||
|
|
||||||
// Slot
|
// Slot
|
||||||
let slot_widget = Button::image(self.imgs.inv_slot)
|
let slot_widget = Button::image(if !is_selected {
|
||||||
|
self.imgs.inv_slot
|
||||||
|
} else {
|
||||||
|
self.imgs.inv_slot_sel
|
||||||
|
})
|
||||||
.top_left_with_margins_on(
|
.top_left_with_margins_on(
|
||||||
state.ids.inv_alignment,
|
state.ids.inv_alignment,
|
||||||
4.0 + y as f64 * (40.0 + 4.0),
|
0.0 + y as f64 * (40.0 + 2.0),
|
||||||
4.0 + x as f64 * (40.0 + 4.0),
|
0.0 + x as f64 * (40.0 + 2.0),
|
||||||
) // conrod uses a (y,x) format for placing...
|
) // conrod uses a (y,x) format for placing...
|
||||||
// (the margin placement functions do this because that is the same order as "top left")
|
// (the margin placement functions do this because that is the same order as "top left")
|
||||||
.w_h(40.0, 40.0)
|
.w_h(40.0, 40.0)
|
||||||
@ -178,8 +195,8 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
slot_widget
|
slot_widget
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&item.description(),
|
&item.title(),
|
||||||
&item.category(),
|
&format!("{}\n{}", item.info(), item.description()),
|
||||||
&item_tooltip,
|
&item_tooltip,
|
||||||
)
|
)
|
||||||
.set(state.ids.inv_slots[i], ui)
|
.set(state.ids.inv_slots[i], ui)
|
||||||
@ -205,17 +222,27 @@ impl<'a> Widget for Bag<'a> {
|
|||||||
state.update(|s| s.selected_slot = selected_slot);
|
state.update(|s| s.selected_slot = selected_slot);
|
||||||
}
|
}
|
||||||
// Item
|
// Item
|
||||||
if item.is_some() {
|
if let Some(kind) = item.as_ref().map(|i| ItemKind::from(i)) {
|
||||||
Button::image(self.imgs.flower) // TODO: Insert variable image depending on the item displayed in that slot
|
Button::image(match &state.img_id_cache[i] {
|
||||||
.w_h(28.0, 28.0) // TODO: Fix height and scale width correctly to that to avoid a stretched item image
|
Some((cached_kind, id)) if cached_kind == &kind => *id,
|
||||||
|
_ => {
|
||||||
|
let id = self
|
||||||
|
.item_imgs
|
||||||
|
.img_id(kind.clone())
|
||||||
|
.unwrap_or(self.imgs.not_found);
|
||||||
|
state.update(|s| s.img_id_cache[i] = Some((kind, id)));
|
||||||
|
id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.w_h(30.0, 30.0)
|
||||||
.middle_of(state.ids.inv_slots[i]) // TODO: Items need to be assigned to a certain slot and then placed like in this example
|
.middle_of(state.ids.inv_slots[i]) // TODO: Items need to be assigned to a certain slot and then placed like in this example
|
||||||
.label("5x") // TODO: Quantity goes here...
|
//.label("5x") // TODO: Quantity goes here...
|
||||||
.label_font_id(self.fonts.opensans)
|
//.label_font_id(self.fonts.opensans)
|
||||||
.label_font_size(12)
|
//.label_font_size(12)
|
||||||
.label_x(Relative::Scalar(10.0))
|
//.label_x(Relative::Scalar(10.0))
|
||||||
.label_y(Relative::Scalar(-10.0))
|
//.label_y(Relative::Scalar(-10.0))
|
||||||
.label_color(TEXT_COLOR)
|
//.label_color(TEXT_COLOR)
|
||||||
.parent(state.ids.inv_slots[i])
|
//.parent(state.ids.inv_slots[i])
|
||||||
.graphics_for(state.ids.inv_slots[i])
|
.graphics_for(state.ids.inv_slots[i])
|
||||||
.set(state.ids.items[i], ui);
|
.set(state.ids.items[i], ui);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ image_ids! {
|
|||||||
bag_contents: "voxygen.element.frames.bag",
|
bag_contents: "voxygen.element.frames.bag",
|
||||||
inv_grid: "voxygen.element.frames.inv_grid",
|
inv_grid: "voxygen.element.frames.inv_grid",
|
||||||
inv_slot: "voxygen.element.buttons.inv_slot",
|
inv_slot: "voxygen.element.buttons.inv_slot",
|
||||||
|
inv_slot_sel: "voxygen.element.buttons.inv_slot_sel",
|
||||||
grid_inv: "voxygen.element.buttons.grid_inv",
|
grid_inv: "voxygen.element.buttons.grid_inv",
|
||||||
bag_top: "voxygen.element.bag.top",
|
bag_top: "voxygen.element.bag.top",
|
||||||
bag_mid: "voxygen.element.bag.mid",
|
bag_mid: "voxygen.element.bag.mid",
|
||||||
@ -223,6 +224,8 @@ image_ids! {
|
|||||||
|
|
||||||
<ImageGraphic>
|
<ImageGraphic>
|
||||||
|
|
||||||
|
not_found:"voxygen.element.not_found",
|
||||||
|
|
||||||
help:"voxygen.element.help",
|
help:"voxygen.element.help",
|
||||||
|
|
||||||
charwindow_gradient:"voxygen.element.misc_bg.charwindow",
|
charwindow_gradient:"voxygen.element.misc_bg.charwindow",
|
||||||
|
163
voxygen/src/hud/item_imgs.rs
Normal file
163
voxygen/src/hud/item_imgs.rs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
use crate::ui::{Graphic, Transform, Ui};
|
||||||
|
use common::{
|
||||||
|
assets::{self, watch::ReloadIndicator, Asset},
|
||||||
|
comp::item::{Armor, Consumable, Debug, Ingredient, Item, Tool},
|
||||||
|
};
|
||||||
|
use conrod_core::image::Id;
|
||||||
|
use dot_vox::DotVoxData;
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use image::DynamicImage;
|
||||||
|
use log::{error, warn};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::{fs::File, io::BufReader, sync::Arc};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub enum ItemKind {
|
||||||
|
Tool(Tool),
|
||||||
|
Armor(Armor),
|
||||||
|
Consumable(Consumable),
|
||||||
|
Ingredient(Ingredient),
|
||||||
|
Debug(Debug),
|
||||||
|
}
|
||||||
|
impl From<&Item> for ItemKind {
|
||||||
|
fn from(item: &Item) -> Self {
|
||||||
|
match item {
|
||||||
|
Item::Tool { kind, .. } => ItemKind::Tool(kind.clone()),
|
||||||
|
Item::Armor { kind, .. } => ItemKind::Armor(kind.clone()),
|
||||||
|
Item::Consumable { kind, .. } => ItemKind::Consumable(kind.clone()),
|
||||||
|
Item::Ingredient { kind } => ItemKind::Ingredient(kind.clone()),
|
||||||
|
Item::Debug(kind) => ItemKind::Debug(kind.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum ImageSpec {
|
||||||
|
Png(String),
|
||||||
|
Vox(String),
|
||||||
|
// (specifier, offset, (axis, 2 * angle / pi), zoom)
|
||||||
|
VoxTrans(String, [f32; 3], [f32; 3], f32),
|
||||||
|
}
|
||||||
|
impl ImageSpec {
|
||||||
|
fn create_graphic(&self) -> Graphic {
|
||||||
|
match self {
|
||||||
|
ImageSpec::Png(specifier) => Graphic::Image(graceful_load_img(&specifier)),
|
||||||
|
ImageSpec::Vox(specifier) => Graphic::Voxel(
|
||||||
|
graceful_load_vox(&specifier),
|
||||||
|
Transform {
|
||||||
|
stretch: false,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
ImageSpec::VoxTrans(specifier, offset, [rot_x, rot_y, rot_z], zoom) => Graphic::Voxel(
|
||||||
|
graceful_load_vox(&specifier),
|
||||||
|
Transform {
|
||||||
|
ori: Quaternion::rotation_x(rot_x * std::f32::consts::PI / 180.0)
|
||||||
|
.rotated_y(rot_y * std::f32::consts::PI / 180.0)
|
||||||
|
.rotated_z(rot_z * std::f32::consts::PI / 180.0),
|
||||||
|
offset: Vec3::from(*offset),
|
||||||
|
zoom: *zoom,
|
||||||
|
orth: true, // TODO: Is this what we want here? @Pfau
|
||||||
|
stretch: false,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct ItemImagesSpec(HashMap<ItemKind, ImageSpec>);
|
||||||
|
impl Asset for ItemImagesSpec {
|
||||||
|
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||||
|
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||||
|
Ok(ron::de::from_reader(buf_reader).expect("Error parsing item images spec"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ItemImgs {
|
||||||
|
map: HashMap<ItemKind, Id>,
|
||||||
|
indicator: ReloadIndicator,
|
||||||
|
}
|
||||||
|
impl ItemImgs {
|
||||||
|
pub fn new(ui: &mut Ui) -> Self {
|
||||||
|
let mut indicator = ReloadIndicator::new();
|
||||||
|
Self {
|
||||||
|
map: assets::load_watched::<ItemImagesSpec>(
|
||||||
|
"voxygen.item_image_manifest",
|
||||||
|
&mut indicator,
|
||||||
|
)
|
||||||
|
.expect("Unable to load item image manifest")
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.map(|(kind, spec)| (kind.clone(), ui.add_graphic(spec.create_graphic())))
|
||||||
|
.collect(),
|
||||||
|
indicator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Checks if the manifest has been changed and reloads the images if so
|
||||||
|
/// 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")
|
||||||
|
.expect("Unable to load item image manifest")
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
|
// Load new graphic
|
||||||
|
let graphic = spec.create_graphic();
|
||||||
|
// See if we already have an id we can use
|
||||||
|
match self.map.get(&kind) {
|
||||||
|
Some(id) => ui.replace_graphic(*id, graphic),
|
||||||
|
// Otherwise, generate new id and insert it into our Id -> ItemKind map
|
||||||
|
None => {
|
||||||
|
self.map.insert(kind.clone(), ui.add_graphic(graphic));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn img_id(&self, item_kind: ItemKind) -> Option<Id> {
|
||||||
|
match self.map.get(&item_kind) {
|
||||||
|
Some(id) => Some(*id),
|
||||||
|
// There was no specification in the ron
|
||||||
|
None => {
|
||||||
|
warn!(
|
||||||
|
"{:?} has no specified image file (note: hot-reloading won't work here)",
|
||||||
|
item_kind
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied from figure/load.rs
|
||||||
|
// 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()) {
|
||||||
|
Ok(dot_vox) => dot_vox,
|
||||||
|
Err(_) => {
|
||||||
|
error!(
|
||||||
|
"Could not load vox file for item images: {}",
|
||||||
|
full_specifier
|
||||||
|
);
|
||||||
|
assets::load_expect::<DotVoxData>("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()) {
|
||||||
|
Ok(img) => img,
|
||||||
|
Err(_) => {
|
||||||
|
error!(
|
||||||
|
"Could not load image file for item images: {}",
|
||||||
|
full_specifier
|
||||||
|
);
|
||||||
|
assets::load_expect::<DynamicImage>("voxygen.element.not_found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ mod character_window;
|
|||||||
mod chat;
|
mod chat;
|
||||||
mod esc_menu;
|
mod esc_menu;
|
||||||
mod img_ids;
|
mod img_ids;
|
||||||
|
mod item_imgs;
|
||||||
mod map;
|
mod map;
|
||||||
mod minimap;
|
mod minimap;
|
||||||
mod quest;
|
mod quest;
|
||||||
@ -22,6 +23,7 @@ use chat::Chat;
|
|||||||
use chrono::NaiveTime;
|
use chrono::NaiveTime;
|
||||||
use esc_menu::EscMenu;
|
use esc_menu::EscMenu;
|
||||||
use img_ids::Imgs;
|
use img_ids::Imgs;
|
||||||
|
use item_imgs::ItemImgs;
|
||||||
use map::Map;
|
use map::Map;
|
||||||
use minimap::MiniMap;
|
use minimap::MiniMap;
|
||||||
use quest::Quest;
|
use quest::Quest;
|
||||||
@ -370,6 +372,7 @@ pub struct Hud {
|
|||||||
ui: Ui,
|
ui: Ui,
|
||||||
ids: Ids,
|
ids: Ids,
|
||||||
imgs: Imgs,
|
imgs: Imgs,
|
||||||
|
item_imgs: ItemImgs,
|
||||||
fonts: Fonts,
|
fonts: Fonts,
|
||||||
rot_imgs: ImgsRot,
|
rot_imgs: ImgsRot,
|
||||||
new_messages: VecDeque<ClientEvent>,
|
new_messages: VecDeque<ClientEvent>,
|
||||||
@ -394,6 +397,8 @@ impl Hud {
|
|||||||
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
||||||
// Load rotation images.
|
// Load rotation images.
|
||||||
let rot_imgs = ImgsRot::load(&mut ui).expect("Failed to load rot images!");
|
let rot_imgs = ImgsRot::load(&mut ui).expect("Failed to load rot images!");
|
||||||
|
// Load item images.
|
||||||
|
let item_imgs = ItemImgs::new(&mut ui);
|
||||||
// Load fonts.
|
// Load fonts.
|
||||||
let fonts = Fonts::load(&mut ui).expect("Failed to load fonts!");
|
let fonts = Fonts::load(&mut ui).expect("Failed to load fonts!");
|
||||||
|
|
||||||
@ -401,6 +406,7 @@ impl Hud {
|
|||||||
ui,
|
ui,
|
||||||
imgs,
|
imgs,
|
||||||
rot_imgs,
|
rot_imgs,
|
||||||
|
item_imgs,
|
||||||
fonts,
|
fonts,
|
||||||
ids,
|
ids,
|
||||||
new_messages: VecDeque::new(),
|
new_messages: VecDeque::new(),
|
||||||
@ -743,6 +749,7 @@ impl Hud {
|
|||||||
match Bag::new(
|
match Bag::new(
|
||||||
client,
|
client,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
|
&self.item_imgs,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
&self.rot_imgs,
|
&self.rot_imgs,
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
@ -1112,6 +1119,10 @@ impl Hud {
|
|||||||
&mut global_state.window.renderer_mut(),
|
&mut global_state.window.renderer_mut(),
|
||||||
Some((view_mat, fov)),
|
Some((view_mat, fov)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check if item images need to be reloaded
|
||||||
|
self.item_imgs.reload_if_changed(&mut self.ui);
|
||||||
|
|
||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,10 @@ impl PlayState for CharSelectionState {
|
|||||||
Some(comp::Item::Tool {
|
Some(comp::Item::Tool {
|
||||||
kind: kind,
|
kind: kind,
|
||||||
power: 10,
|
power: 10,
|
||||||
|
stamina: 0,
|
||||||
|
strength: 0,
|
||||||
|
dexterity: 0,
|
||||||
|
intelligence: 0,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -939,7 +939,7 @@ impl CharSelectionUi {
|
|||||||
.w_h(70.0, 70.0)
|
.w_h(70.0, 70.0)
|
||||||
.right_from(self.ids.sword, 2.0)
|
.right_from(self.ids.sword, 2.0)
|
||||||
.set(self.ids.daggers, ui_widgets);
|
.set(self.ids.daggers, ui_widgets);
|
||||||
if Button::image(if let Some(Tool::Daggers) = self.character_tool {
|
if Button::image(if let Some(Tool::Dagger) = self.character_tool {
|
||||||
self.imgs.icon_border_pressed
|
self.imgs.icon_border_pressed
|
||||||
} else {
|
} else {
|
||||||
self.imgs.icon_border
|
self.imgs.icon_border
|
||||||
|
@ -253,9 +253,8 @@ impl MainMenuUi {
|
|||||||
Before you dive into the fun, please keep a few things in mind:\n\
|
Before you dive into the fun, please keep a few things in mind:\n\
|
||||||
\n\
|
\n\
|
||||||
- This is a very early alpha. Expect bugs, extremely unfinished gameplay, unpolished mechanics, and missing features. \n\
|
- This is a very early alpha. Expect bugs, extremely unfinished gameplay, unpolished mechanics, and missing features. \n\
|
||||||
If you are a reviewer, please DO NOT review this version.\n\
|
|
||||||
\n\
|
\n\
|
||||||
- If you have constructive feedback or bug reports, you can contact us via Reddit, GitLab, or our community Discord server.\n\
|
-If you have constructive feedback or bug reports, you can contact us via Reddit, GitLab, or our community Discord server.\n\
|
||||||
\n\
|
\n\
|
||||||
- Veloren is licensed under the GPL 3 open-source licence. That means you're free to play, modify, and redistribute the game however you wish \n\
|
- Veloren is licensed under the GPL 3 open-source licence. That means you're free to play, modify, and redistribute the game however you wish \n\
|
||||||
(provided derived work is also under GPL 3).
|
(provided derived work is also under GPL 3).
|
||||||
|
@ -217,7 +217,7 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
self,
|
self,
|
||||||
pos,
|
pos,
|
||||||
offs,
|
offs,
|
||||||
&colors,
|
&colors, //&[[[colors[1][1][1]; 3]; 3]; 3],
|
||||||
|pos, norm, col, ao, light| {
|
|pos, norm, col, ao, light| {
|
||||||
TerrainVertex::new(pos, norm, col, light.min(ao))
|
TerrainVertex::new(pos, norm, col, light.min(ao))
|
||||||
},
|
},
|
||||||
|
@ -146,7 +146,7 @@ impl Camera {
|
|||||||
let t = self.tgt_dist + delta;
|
let t = self.tgt_dist + delta;
|
||||||
match self.mode {
|
match self.mode {
|
||||||
CameraMode::ThirdPerson => {
|
CameraMode::ThirdPerson => {
|
||||||
if t < 2_f32 {
|
if t < 1_f32 {
|
||||||
self.set_mode(CameraMode::FirstPerson);
|
self.set_mode(CameraMode::FirstPerson);
|
||||||
} else {
|
} else {
|
||||||
self.tgt_dist = t;
|
self.tgt_dist = t;
|
||||||
|
@ -355,8 +355,8 @@ pub fn mesh_main(item: Option<&Item>) -> Mesh<FigurePipeline> {
|
|||||||
Tool::Sword => ("weapon.sword.rusty_2h", Vec3::new(-1.5, -6.5, -4.0)),
|
Tool::Sword => ("weapon.sword.rusty_2h", Vec3::new(-1.5, -6.5, -4.0)),
|
||||||
Tool::Axe => ("weapon.axe.rusty_2h", Vec3::new(-1.5, -5.0, -4.0)),
|
Tool::Axe => ("weapon.axe.rusty_2h", Vec3::new(-1.5, -5.0, -4.0)),
|
||||||
Tool::Hammer => ("weapon.hammer.rusty_2h", Vec3::new(-2.5, -5.5, -4.0)),
|
Tool::Hammer => ("weapon.hammer.rusty_2h", Vec3::new(-2.5, -5.5, -4.0)),
|
||||||
Tool::Daggers => ("weapon.hammer.rusty_2h", Vec3::new(-2.5, -5.5, -4.0)),
|
Tool::Dagger => ("weapon.hammer.rusty_2h", Vec3::new(-2.5, -5.5, -4.0)),
|
||||||
Tool::SwordShield => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
|
Tool::Shield => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
|
||||||
Tool::Bow => ("weapon.bow.simple-bow", Vec3::new(-1.0, -6.0, -2.0)),
|
Tool::Bow => ("weapon.bow.simple-bow", Vec3::new(-1.0, -6.0, -2.0)),
|
||||||
Tool::Staff => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
|
Tool::Staff => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
|
||||||
},
|
},
|
||||||
|
@ -132,7 +132,8 @@ impl Scene {
|
|||||||
}
|
}
|
||||||
// Zoom the camera when a zoom event occurs
|
// Zoom the camera when a zoom event occurs
|
||||||
Event::Zoom(delta) => {
|
Event::Zoom(delta) => {
|
||||||
self.camera.zoom_switch(delta * 0.3);
|
self.camera
|
||||||
|
.zoom_switch(delta * (0.05 + self.camera.get_distance() * 0.01));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
// All other events are unhandled
|
// All other events are unhandled
|
||||||
|
@ -135,6 +135,10 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
|
|||||||
variations: 1,
|
variations: 1,
|
||||||
wind_sway: 0.0,
|
wind_sway: 0.0,
|
||||||
}),
|
}),
|
||||||
|
BlockKind::Chest => Some(SpriteConfig {
|
||||||
|
variations: 4,
|
||||||
|
wind_sway: 0.0,
|
||||||
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,6 +625,34 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
Vec3::new(-5.0, -5.0, -5.0),
|
Vec3::new(-5.0, -5.0, -5.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
(BlockKind::Chest, 0),
|
||||||
|
make_model(
|
||||||
|
"voxygen.voxel.sprite.chests.chest",
|
||||||
|
Vec3::new(-7.0, -5.0, -0.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(BlockKind::Chest, 1),
|
||||||
|
make_model(
|
||||||
|
"voxygen.voxel.sprite.chests.chest_gold",
|
||||||
|
Vec3::new(-7.0, -5.0, -0.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(BlockKind::Chest, 2),
|
||||||
|
make_model(
|
||||||
|
"voxygen.voxel.sprite.chests.chest_dark",
|
||||||
|
Vec3::new(-7.0, -5.0, -0.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(BlockKind::Chest, 3),
|
||||||
|
make_model(
|
||||||
|
"voxygen.voxel.sprite.chests.chest_vines",
|
||||||
|
Vec3::new(-7.0, -5.0, -0.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -61,6 +61,9 @@ impl Cache {
|
|||||||
pub fn add_graphic(&mut self, graphic: Graphic) -> GraphicId {
|
pub fn add_graphic(&mut self, graphic: Graphic) -> GraphicId {
|
||||||
self.graphic_cache.add_graphic(graphic)
|
self.graphic_cache.add_graphic(graphic)
|
||||||
}
|
}
|
||||||
|
pub fn replace_graphic(&mut self, id: GraphicId, graphic: Graphic) {
|
||||||
|
self.graphic_cache.replace_graphic(id, graphic)
|
||||||
|
}
|
||||||
// Resizes and clears the GraphicCache
|
// Resizes and clears the GraphicCache
|
||||||
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
|
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
|
||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
|
@ -8,10 +8,30 @@ use log::{error, warn};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Transform {
|
||||||
|
pub ori: Quaternion<f32>,
|
||||||
|
pub offset: Vec3<f32>,
|
||||||
|
pub zoom: f32,
|
||||||
|
pub orth: bool,
|
||||||
|
pub stretch: bool,
|
||||||
|
}
|
||||||
|
impl Default for Transform {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
ori: Quaternion::identity(),
|
||||||
|
offset: Vec3::zero(),
|
||||||
|
zoom: 1.0,
|
||||||
|
orth: true,
|
||||||
|
stretch: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Graphic {
|
pub enum Graphic {
|
||||||
Image(Arc<DynamicImage>),
|
Image(Arc<DynamicImage>),
|
||||||
Voxel(Arc<DotVoxData>, Option<Quaternion<f32>>, Option<u8>),
|
Voxel(Arc<DotVoxData>, Transform, Option<u8>),
|
||||||
Blank,
|
Blank,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +92,26 @@ impl GraphicCache {
|
|||||||
|
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
pub fn replace_graphic(&mut self, id: Id, graphic: Graphic) {
|
||||||
|
self.graphic_map.insert(id, graphic);
|
||||||
|
|
||||||
|
// Remove from caches
|
||||||
|
// Maybe make this more efficient if replace graphic is used more often
|
||||||
|
self.transfer_ready.retain(|(p, _)| p.0 != id);
|
||||||
|
let uses = self
|
||||||
|
.soft_cache
|
||||||
|
.keys()
|
||||||
|
.filter(|k| k.0 == id)
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
for p in uses {
|
||||||
|
self.soft_cache.remove(&p);
|
||||||
|
if let Some(details) = self.cache_map.remove(&p) {
|
||||||
|
// Deallocate
|
||||||
|
self.atlas.deallocate(details.alloc_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> {
|
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> {
|
||||||
self.graphic_map.get(&id)
|
self.graphic_map.get(&id)
|
||||||
}
|
}
|
||||||
@ -129,9 +169,12 @@ impl GraphicCache {
|
|||||||
image::FilterType::Nearest,
|
image::FilterType::Nearest,
|
||||||
)
|
)
|
||||||
.to_rgba(),
|
.to_rgba(),
|
||||||
Some(Graphic::Voxel(ref vox, ori, min_samples)) => {
|
Some(Graphic::Voxel(ref vox, trans, min_samples)) => renderer::draw_vox(
|
||||||
renderer::draw_vox(&vox.as_ref().into(), dims, *ori, *min_samples)
|
&vox.as_ref().into(),
|
||||||
}
|
dims,
|
||||||
|
trans.clone(),
|
||||||
|
*min_samples,
|
||||||
|
),
|
||||||
None => {
|
None => {
|
||||||
warn!("A graphic was requested via an id which is not in use");
|
warn!("A graphic was requested via an id which is not in use");
|
||||||
return None;
|
return None;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::Transform;
|
||||||
use common::{
|
use common::{
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
util::{linear_to_srgba, srgba_to_linear},
|
util::{linear_to_srgba, srgba_to_linear},
|
||||||
@ -61,7 +62,7 @@ impl<'a> Pipeline for Voxel {
|
|||||||
pub fn draw_vox(
|
pub fn draw_vox(
|
||||||
segment: &Segment,
|
segment: &Segment,
|
||||||
output_size: Vec2<u16>,
|
output_size: Vec2<u16>,
|
||||||
ori: Option<Quaternion<f32>>,
|
transform: Transform,
|
||||||
min_samples: Option<u8>,
|
min_samples: Option<u8>,
|
||||||
) -> RgbaImage {
|
) -> RgbaImage {
|
||||||
let scale = min_samples.map_or(1.0, |s| s as f32).sqrt().ceil() as usize;
|
let scale = min_samples.map_or(1.0, |s| s as f32).sqrt().ceil() as usize;
|
||||||
@ -71,17 +72,35 @@ pub fn draw_vox(
|
|||||||
|
|
||||||
let (w, h, d) = segment.size().map(|e| e as f32).into_tuple();
|
let (w, h, d) = segment.size().map(|e| e as f32).into_tuple();
|
||||||
|
|
||||||
let mvp = Mat4::<f32>::orthographic_rh_no(FrustumPlanes {
|
let mvp = if transform.orth {
|
||||||
|
Mat4::<f32>::orthographic_rh_no(FrustumPlanes {
|
||||||
left: -1.0,
|
left: -1.0,
|
||||||
right: 1.0,
|
right: 1.0,
|
||||||
bottom: -1.0,
|
bottom: -1.0,
|
||||||
top: 1.0,
|
top: 1.0,
|
||||||
near: 0.0,
|
near: 0.0,
|
||||||
far: 1.0,
|
far: 1.0,
|
||||||
}) * Mat4::from(ori.unwrap_or(Quaternion::identity()))
|
})
|
||||||
* Mat4::rotation_x(-std::f32::consts::PI / 2.0) // TODO: remove
|
} else {
|
||||||
* Mat4::scaling_3d([2.0 / w, 2.0 / h, 2.0 / d])
|
Mat4::<f32>::perspective_fov_rh_no(
|
||||||
|
1.1, // fov
|
||||||
|
dims[0] as f32, // width
|
||||||
|
dims[1] as f32, // height
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
)
|
||||||
|
} * Mat4::scaling_3d(
|
||||||
|
// TODO replace with camera-like parameters?
|
||||||
|
if transform.stretch {
|
||||||
|
Vec3::new(2.0 / w, 2.0 / d, 2.0 / h) // Only works with flipped models :(
|
||||||
|
} else {
|
||||||
|
let s = w.max(h).max(d);
|
||||||
|
Vec3::new(2.0 / s, 2.0 / s, 2.0 / s)
|
||||||
|
} * transform.zoom,
|
||||||
|
) * Mat4::translation_3d(transform.offset)
|
||||||
|
* Mat4::from(transform.ori)
|
||||||
* Mat4::translation_3d([-w / 2.0, -h / 2.0, -d / 2.0]);
|
* Mat4::translation_3d([-w / 2.0, -h / 2.0, -d / 2.0]);
|
||||||
|
|
||||||
Voxel { mvp }.draw::<rasterizer::Triangles<_>, _>(
|
Voxel { mvp }.draw::<rasterizer::Triangles<_>, _>(
|
||||||
&generate_mesh(segment, Vec3::from(0.0)),
|
&generate_mesh(segment, Vec3::from(0.0)),
|
||||||
&mut color,
|
&mut color,
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use super::Graphic;
|
use super::{Graphic, Transform};
|
||||||
use common::assets::{load, Error};
|
use common::assets::{load, Error};
|
||||||
use dot_vox::DotVoxData;
|
use dot_vox::DotVoxData;
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
pub enum BlankGraphic {}
|
pub enum BlankGraphic {}
|
||||||
pub enum ImageGraphic {}
|
pub enum ImageGraphic {}
|
||||||
@ -31,7 +32,14 @@ pub enum VoxelMs9Graphic {}
|
|||||||
impl<'a> GraphicCreator<'a> for VoxelGraphic {
|
impl<'a> GraphicCreator<'a> for VoxelGraphic {
|
||||||
type Specifier = &'a str;
|
type Specifier = &'a str;
|
||||||
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
||||||
Ok(Graphic::Voxel(load::<DotVoxData>(specifier)?, None, None))
|
Ok(Graphic::Voxel(
|
||||||
|
load::<DotVoxData>(specifier)?,
|
||||||
|
Transform {
|
||||||
|
ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> GraphicCreator<'a> for VoxelMsGraphic {
|
impl<'a> GraphicCreator<'a> for VoxelMsGraphic {
|
||||||
@ -39,7 +47,10 @@ impl<'a> GraphicCreator<'a> for VoxelMsGraphic {
|
|||||||
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
||||||
Ok(Graphic::Voxel(
|
Ok(Graphic::Voxel(
|
||||||
load::<DotVoxData>(specifier.0)?,
|
load::<DotVoxData>(specifier.0)?,
|
||||||
None,
|
Transform {
|
||||||
|
ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
Some(specifier.1),
|
Some(specifier.1),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -49,7 +60,10 @@ impl<'a> GraphicCreator<'a> for VoxelMs4Graphic {
|
|||||||
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
||||||
Ok(Graphic::Voxel(
|
Ok(Graphic::Voxel(
|
||||||
load::<DotVoxData>(specifier)?,
|
load::<DotVoxData>(specifier)?,
|
||||||
None,
|
Transform {
|
||||||
|
ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
Some(4),
|
Some(4),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -59,7 +73,10 @@ impl<'a> GraphicCreator<'a> for VoxelMs9Graphic {
|
|||||||
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
|
||||||
Ok(Graphic::Voxel(
|
Ok(Graphic::Voxel(
|
||||||
load::<DotVoxData>(specifier)?,
|
load::<DotVoxData>(specifier)?,
|
||||||
None,
|
Transform {
|
||||||
|
ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
Some(9),
|
Some(9),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ pub mod img_ids;
|
|||||||
mod font_ids;
|
mod font_ids;
|
||||||
|
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use graphic::Graphic;
|
pub use graphic::{Graphic, Transform};
|
||||||
pub use scale::{Scale, ScaleMode};
|
pub use scale::{Scale, ScaleMode};
|
||||||
pub use widgets::{
|
pub use widgets::{
|
||||||
image_frame::ImageFrame,
|
image_frame::ImageFrame,
|
||||||
@ -41,7 +41,7 @@ use conrod_core::{
|
|||||||
Rect, UiBuilder, UiCell,
|
Rect, UiBuilder, UiCell,
|
||||||
};
|
};
|
||||||
use graphic::Rotation;
|
use graphic::Rotation;
|
||||||
use log::warn;
|
use log::{error, warn};
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{BufReader, Read},
|
io::{BufReader, Read},
|
||||||
@ -175,6 +175,17 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn replace_graphic(&mut self, id: image::Id, graphic: Graphic) {
|
||||||
|
let graphic_id = if let Some((graphic_id, _)) = self.image_map.get(&id) {
|
||||||
|
*graphic_id
|
||||||
|
} else {
|
||||||
|
error!("Failed to replace graphic the provided id is not in use");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.cache.replace_graphic(graphic_id, graphic);
|
||||||
|
self.image_map.replace(id, (graphic_id, Rotation::None));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_font(&mut self, font: Arc<Font>) -> font::Id {
|
pub fn new_font(&mut self, font: Arc<Font>) -> font::Id {
|
||||||
self.ui.fonts.insert(font.as_ref().0.clone())
|
self.ui.fonts.insert(font.as_ref().0.clone())
|
||||||
}
|
}
|
||||||
|
@ -176,10 +176,10 @@ impl<'a> BlockGen<'a> {
|
|||||||
let wposf = wpos.map(|e| e as f64);
|
let wposf = wpos.map(|e| e as f64);
|
||||||
|
|
||||||
let (block, height) = if !only_structures {
|
let (block, height) = if !only_structures {
|
||||||
let (_definitely_underground, height, water_height) =
|
let (_definitely_underground, height, on_cliff, water_height) =
|
||||||
if (wposf.z as f32) < alt - 64.0 * chaos {
|
if (wposf.z as f32) < alt - 64.0 * chaos {
|
||||||
// Shortcut warping
|
// Shortcut warping
|
||||||
(true, alt, CONFIG.sea_level /*water_level*/)
|
(true, alt, false, CONFIG.sea_level /*water_level*/)
|
||||||
} else {
|
} else {
|
||||||
// Apply warping
|
// Apply warping
|
||||||
let warp = world
|
let warp = world
|
||||||
@ -190,9 +190,11 @@ impl<'a> BlockGen<'a> {
|
|||||||
.mul((chaos - 0.1).max(0.0).powf(2.0))
|
.mul((chaos - 0.1).max(0.0).powf(2.0))
|
||||||
.mul(48.0);
|
.mul(48.0);
|
||||||
|
|
||||||
let height = if (wposf.z as f32) < alt + warp - 10.0 {
|
let surface_height = alt + warp;
|
||||||
|
|
||||||
|
let (height, on_cliff) = if (wposf.z as f32) < alt + warp - 10.0 {
|
||||||
// Shortcut cliffs
|
// Shortcut cliffs
|
||||||
alt + warp
|
(surface_height, false)
|
||||||
} else {
|
} else {
|
||||||
let turb = Vec2::new(
|
let turb = Vec2::new(
|
||||||
world.sim().gen_ctx.fast_turb_x_nz.get(wposf.div(25.0)) as f32,
|
world.sim().gen_ctx.fast_turb_x_nz.get(wposf.div(25.0)) as f32,
|
||||||
@ -209,12 +211,16 @@ impl<'a> BlockGen<'a> {
|
|||||||
0.0,
|
0.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
(alt + warp).max(cliff_height)
|
(
|
||||||
|
surface_height.max(cliff_height),
|
||||||
|
cliff_height > surface_height + 16.0,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
false,
|
false,
|
||||||
height,
|
height,
|
||||||
|
on_cliff,
|
||||||
/*(water_level + warp).max(*/ CONFIG.sea_level, /*)*/
|
/*(water_level + warp).max(*/ CONFIG.sea_level, /*)*/
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -270,6 +276,11 @@ impl<'a> BlockGen<'a> {
|
|||||||
&& (marble * 3173.7).fract() < 0.6
|
&& (marble * 3173.7).fract() < 0.6
|
||||||
&& humidity > 0.4
|
&& humidity > 0.4
|
||||||
{
|
{
|
||||||
|
let treasures = [
|
||||||
|
BlockKind::Chest,
|
||||||
|
//BlockKind::Velorite,
|
||||||
|
];
|
||||||
|
|
||||||
let flowers = [
|
let flowers = [
|
||||||
BlockKind::BlueFlower,
|
BlockKind::BlueFlower,
|
||||||
BlockKind::PinkFlower,
|
BlockKind::PinkFlower,
|
||||||
@ -288,7 +299,9 @@ impl<'a> BlockGen<'a> {
|
|||||||
];
|
];
|
||||||
|
|
||||||
Some(Block::new(
|
Some(Block::new(
|
||||||
if (height * 1271.0).fract() < 0.1 {
|
if on_cliff && (height * 1271.0).fract() < 0.015 {
|
||||||
|
treasures[(height * 731.3) as usize % treasures.len()]
|
||||||
|
} else if (height * 1271.0).fract() < 0.1 {
|
||||||
flowers[(height * 0.2) as usize % flowers.len()]
|
flowers[(height * 0.2) as usize % flowers.len()]
|
||||||
} else {
|
} else {
|
||||||
grasses[(height * 103.3) as usize % grasses.len()]
|
grasses[(height * 103.3) as usize % grasses.len()]
|
||||||
@ -604,6 +617,7 @@ pub fn block_from_structure(
|
|||||||
.map(|e| e as u8),
|
.map(|e| e as u8),
|
||||||
)),
|
)),
|
||||||
StructureBlock::Fruit => Some(Block::new(BlockKind::Apple, Rgb::new(194, 30, 37))),
|
StructureBlock::Fruit => Some(Block::new(BlockKind::Apple, Rgb::new(194, 30, 37))),
|
||||||
|
StructureBlock::Chest => Some(Block::new(BlockKind::Chest, Rgb::new(0, 0, 0))),
|
||||||
StructureBlock::Liana => Some(Block::new(
|
StructureBlock::Liana => Some(Block::new(
|
||||||
BlockKind::Liana,
|
BlockKind::Liana,
|
||||||
Lerp::lerp(
|
Lerp::lerp(
|
||||||
|
Loading…
Reference in New Issue
Block a user