refactor: create_projectile doesn't take a light

It returns a builder so the caller can just do it
This commit is contained in:
Monty Marz
2019-10-17 20:59:36 +00:00
committed by Joshua Barretto
parent 1f39659a54
commit fdfab6a807
73 changed files with 507 additions and 222 deletions

BIN
assets/voxygen/element/icons/staff_m1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/staff_m2.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -3,7 +3,11 @@
// VoxTrans(specifier, offset, (x_rot, y_rot, z_rot), zoom) // VoxTrans(specifier, offset, (x_rot, y_rot, z_rot), zoom)
({ // Debug Items ({ // Debug Items
Debug(Boost): VoxTrans( Debug(Boost): VoxTrans(
"voxel.weapon.debug_wand", "voxel.weapon.debug_wand-0",
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
),
Debug(Possess): VoxTrans(
"voxel.weapon.debug_wand-1",
(0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6, (0.0, -7.0, 0.0), (90.0, 90.0, 0.0), 1.6,
), ),
// Weapons // Weapons
@ -27,6 +31,14 @@
"voxel.weapon.hammer.rusty_2h", "voxel.weapon.hammer.rusty_2h",
(0.0, -8.0, 0.0), (-90.0, 90.0, 0.0), 2.0, (0.0, -8.0, 0.0), (-90.0, 90.0, 0.0), 2.0,
), ),
Tool(Staff): VoxTrans(
"voxel.weapon.staff.wood-0",
(0.0, -9.0, 0.0), (90.0, 90.0, 0.0), 2.5,
),
Tool(Shield): VoxTrans(
"voxel.weapon.shield.wood-0",
(0.0, 9.0, 0.0), (-90.0, 90.0, 0.0), 2.4,
),
// Consumables // Consumables
Consumable(Apple): VoxTrans( Consumable(Apple): VoxTrans(
"element.icons.item_apple", "element.icons.item_apple",
@ -44,6 +56,10 @@
"voxel.sprite.velorite.velorite_ore", "voxel.sprite.velorite.velorite_ore",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Consumable(VeloriteFrag): VoxTrans(
"voxel.sprite.velorite.velorite_1",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
// Ingredients // Ingredients
Ingredient(Flower): VoxTrans( Ingredient(Flower): VoxTrans(
"voxel.sprite.flowers.flower_red_2", "voxel.sprite.flowers.flower_red_2",

BIN
assets/voxygen/voxel/figure/beard/danari/danari-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/danari/female-1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/danari/male-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/danari/male-1.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-10.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-11.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-12.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-13.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-14.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-15.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-16.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-17.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-18.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-19.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-4.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-5.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-6.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-7.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-8.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/hair/human/male-9.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -7,10 +7,9 @@
Some(("figure.hair.human.male-0", (1, 1, 1))), Some(("figure.hair.human.male-0", (1, 1, 1))),
Some(("figure.hair.human.male-1", (1, 1, 1))), Some(("figure.hair.human.male-1", (1, 1, 1))),
Some(("figure.hair.human.male-2", (0, -1, 0))), Some(("figure.hair.human.male-2", (0, -1, 0))),
Some(("figure.hair.human.male-3", (0, -1, 0))), Some(("figure.hair.human.male-3", (0, -1, 0))),
], ],
beard: [ beard: [
None,
Some(("figure.beard.human.human-0", (4, 6, -2))), Some(("figure.beard.human.human-0", (4, 6, -2))),
Some(("figure.beard.human.human-1", (5, 10, -2))), Some(("figure.beard.human.human-1", (5, 10, -2))),
], ],
@ -206,10 +205,12 @@
head: ("figure.head.danari.male", (0, 2, 2)), head: ("figure.head.danari.male", (0, 2, 2)),
eyes: ("figure.eyes.danari.male-0", (5, 9, 4)), eyes: ("figure.eyes.danari.male-0", (5, 9, 4)),
hair: [ hair: [
Some(("figure.hair.danari.male", (3, 1, 2))), Some(("figure.hair.danari.male-0", (3, 1, 2))),
Some(("figure.hair.danari.male", (3, 1, 2))), Some(("figure.hair.danari.male-1", (3, 1, 2))),
], ],
beard: [None], beard: [
Some(("figure.beard.danari.danari-0", (4, 6, -1))),
],
accessory: [ accessory: [
Some(("figure.accessory.danari.horns-0", (4, 8, 8))),] Some(("figure.accessory.danari.horns-0", (4, 8, 8))),]
), ),
@ -218,8 +219,8 @@
head: ("figure.head.danari.female", (0, 2, 2)), head: ("figure.head.danari.female", (0, 2, 2)),
eyes: ("figure.eyes.danari.female-0", (4, 9, 4)), eyes: ("figure.eyes.danari.female-0", (4, 9, 4)),
hair: [ hair: [
Some(("figure.hair.danari.female", (3, -4, 1))), Some(("figure.hair.danari.female-0", (3, -4, 1))),
Some(("figure.hair.danari.female", (3, -4, 1))), Some(("figure.hair.danari.female-1", (1, 1, 3))),
], ],
beard: [None], beard: [None],
accessory: [ accessory: [

BIN
assets/voxygen/voxel/sprite/flowers/flower_blue_7.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/flowers/flower_red_3.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/debug_wand-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/debug_wand-1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fire-bolt-2.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/fire-bolt.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/projectile/snake-arrow.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/shield/wood-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/staff/wood-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/world/tree/snow_pine/1.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/2.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/3.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/4.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/5.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/6.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/7.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/world/tree/snow_pine/8.vox (Stored with Git LFS)

Binary file not shown.

View File

@ -77,23 +77,23 @@ pub const ALL_RACES: [Race; 6] = [
]; ];
// Hair Colors // Hair Colors
pub const DANARI_HAIR_COLORS: [(u8, u8, u8); 16] = [ pub const DANARI_HAIR_COLORS: [(u8, u8, u8); 11] = [
(198, 169, 113), // Philosopher's Grey (198, 169, 113), // Philosopher's Grey
(245, 232, 175), // Cream Blonde //(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde //(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde //(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde (199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Brown (107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown //(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown (64, 32, 18), // Chocolate Brown
(86, 72, 71), // Ash Brown (86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black (57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple (101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple (101, 57, 90), // Witch Purple
(107, 32, 60), // Grape Purple (107, 32, 60), // Grape Purple
(135, 38, 39), // Dark Red (135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red (88, 26, 29), // Wine Red
(146, 32, 32), // Autumn Red //(146, 32, 32), // Autumn Red
]; ];
pub const DWARF_HAIR_COLORS: [(u8, u8, u8); 20] = [ pub const DWARF_HAIR_COLORS: [(u8, u8, u8); 20] = [
(245, 232, 175), // Cream Blonde (245, 232, 175), // Cream Blonde
@ -165,24 +165,24 @@ pub const HUMAN_HAIR_COLORS: [(u8, u8, u8); 21] = [
(84, 139, 107), // Grass Green (84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green (48, 61, 52), // Dark Green
]; ];
pub const ORC_HAIR_COLORS: [(u8, u8, u8); 12] = [ pub const ORC_HAIR_COLORS: [(u8, u8, u8); 10] = [
(66, 66, 59), // Wise Grey (66, 66, 59), // Wise Grey
(107, 76, 51), // Oak Brown //(107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown //(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown (64, 32, 18), // Chocolate Brown
(54, 30, 26), // Dark Chocolate (54, 30, 26), // Dark Chocolate
(86, 72, 71), // Ash Brown (86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black (57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple (101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple (101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red (135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red (88, 26, 29), // Wine Red
(66, 83, 113), // Mysterious Blue (66, 83, 113), // Mysterious Blue
]; ];
pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 24] = [ pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 21] = [
(245, 232, 175), // Cream Blonde //(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde (228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde //(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde (199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Brown (107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown (203, 154, 98), // Light Brown
@ -198,7 +198,7 @@ pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 24] = [
(92, 80, 144), // Kingfisher Blue (92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue (146, 198, 238), // Lagoon Blue
(66, 66, 59), // Decayed Grey (66, 66, 59), // Decayed Grey
(224, 182, 184), // Candy Pink //(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink (174, 148, 161), // Matte Pink
(0, 131, 122), // Rotten Green (0, 131, 122), // Rotten Green
(163, 186, 192), // Matte Green (163, 186, 192), // Matte Green
@ -330,8 +330,8 @@ impl Race {
} }
pub fn num_hair_styles(self, body_type: BodyType) -> u8 { pub fn num_hair_styles(self, body_type: BodyType) -> u8 {
match (self, body_type) { match (self, body_type) {
(Race::Danari, BodyType::Female) => 1, (Race::Danari, BodyType::Female) => 2,
(Race::Danari, BodyType::Male) => 1, (Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1, (Race::Dwarf, BodyType::Female) => 1,
(Race::Dwarf, BodyType::Male) => 3, (Race::Dwarf, BodyType::Male) => 3,
(Race::Elf, BodyType::Female) => 21, (Race::Elf, BodyType::Female) => 21,
@ -363,7 +363,7 @@ impl Race {
pub fn num_beards(self, body_type: BodyType) -> u8 { pub fn num_beards(self, body_type: BodyType) -> u8 {
match (self, body_type) { match (self, body_type) {
(Race::Danari, BodyType::Female) => 1, (Race::Danari, BodyType::Female) => 1,
(Race::Danari, BodyType::Male) => 1, (Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1, (Race::Dwarf, BodyType::Female) => 1,
(Race::Dwarf, BodyType::Male) => 20, (Race::Dwarf, BodyType::Male) => 20,
(Race::Elf, BodyType::Female) => 1, (Race::Elf, BodyType::Female) => 1,

View File

@ -51,6 +51,8 @@ pub enum Body {
CarpetHumanSquircle, CarpetHumanSquircle,
Pouch, Pouch,
CraftingBench, CraftingBench,
BoltFire,
ArrowSnake,
} }
impl Body { impl Body {
@ -60,7 +62,7 @@ impl Body {
} }
} }
const ALL_OBJECTS: [Body; 48] = [ const ALL_OBJECTS: [Body; 50] = [
Body::Arrow, Body::Arrow,
Body::Bomb, Body::Bomb,
Body::Scarecrow, Body::Scarecrow,
@ -109,4 +111,6 @@ const ALL_OBJECTS: [Body; 48] = [
Body::CarpetHumanSquare2, Body::CarpetHumanSquare2,
Body::CarpetHumanSquircle, Body::CarpetHumanSquircle,
Body::CraftingBench, Body::CraftingBench,
Body::BoltFire,
Body::ArrowSnake,
]; ];

View File

@ -33,7 +33,10 @@ impl Tool {
pub fn description(&self) -> &'static str { pub fn description(&self) -> &'static str {
match self { match self {
Tool::Dagger => "A basic kitchen knife.", Tool::Dagger => {
"A basic kitchen knife.\n\
NOT YET AVAILABLE."
}
Tool::Shield => { Tool::Shield => {
"This shield belonged to many adventurers.\n\ "This shield belonged to many adventurers.\n\
Now it's yours.\n\ Now it's yours.\n\
@ -109,6 +112,7 @@ pub enum Consumable {
Potion, Potion,
Mushroom, Mushroom,
Velorite, Velorite,
VeloriteFrag,
} }
impl Consumable { impl Consumable {
@ -118,6 +122,7 @@ impl Consumable {
Consumable::Potion => "Potion", Consumable::Potion => "Potion",
Consumable::Mushroom => "Mushroom", Consumable::Mushroom => "Mushroom",
Consumable::Velorite => "Velorite", Consumable::Velorite => "Velorite",
Consumable::VeloriteFrag => "Glowing Fragment",
} }
} }
@ -127,6 +132,7 @@ impl Consumable {
Consumable::Potion => "This Potion contains the essence of Life.", Consumable::Potion => "This Potion contains the essence of Life.",
Consumable::Mushroom => "A common Mushroom.", Consumable::Mushroom => "A common Mushroom.",
Consumable::Velorite => "Has a subtle turqoise glow.", Consumable::Velorite => "Has a subtle turqoise glow.",
Consumable::VeloriteFrag => "Seems to be the fragment of a bigger piece...",
} }
} }
} }
@ -246,7 +252,7 @@ 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 { BlockKind::Chest => Some(match rand::random::<usize>() % 4 {
0 => Self::apple(), 0 => Self::apple(),
1 => Self::velorite(), 1 => Self::velorite(),
2 => Item::Tool { 2 => Item::Tool {
@ -257,6 +263,7 @@ impl Item {
dexterity: 0, dexterity: 0,
intelligence: 0, intelligence: 0,
}, },
3 => Self::veloritefrag(),
_ => unreachable!(), _ => unreachable!(),
}), }),
_ => None, _ => None,
@ -268,14 +275,20 @@ impl Item {
pub fn apple() -> Self { pub fn apple() -> Self {
Item::Consumable { Item::Consumable {
kind: Consumable::Apple, kind: Consumable::Apple,
effect: Effect::Health(50, comp::HealthSource::Item), effect: Effect::Health(comp::HealthChange {
amount: 50,
cause: comp::HealthSource::Item,
}),
} }
} }
pub fn mushroom() -> Self { pub fn mushroom() -> Self {
Item::Consumable { Item::Consumable {
kind: Consumable::Mushroom, kind: Consumable::Mushroom,
effect: Effect::Health(10, comp::HealthSource::Item), effect: Effect::Health(comp::HealthChange {
amount: 10,
cause: comp::HealthSource::Item,
}),
} }
} }
@ -285,6 +298,12 @@ impl Item {
effect: Effect::Xp(50), effect: Effect::Xp(50),
} }
} }
pub fn veloritefrag() -> Self {
Item::Consumable {
kind: Consumable::VeloriteFrag,
effect: Effect::Xp(20),
}
}
pub fn flower() -> Self { pub fn flower() -> Self {
Item::Ingredient { Item::Ingredient {

View File

@ -69,52 +69,11 @@ impl Inventory {
impl Default for Inventory { impl Default for Inventory {
fn default() -> Inventory { fn default() -> Inventory {
let mut inventory = Inventory { let mut inventory = Inventory {
slots: vec![None; 24], slots: vec![None; 25],
}; };
inventory.push(Item::Debug(Debug::Boost)); inventory.push(Item::Debug(Debug::Boost));
inventory.push(Item::Debug(Debug::Possess)); inventory.push(Item::Debug(Debug::Possess));
inventory.push(Item::Tool {
kind: Tool::Bow,
power: 10,
stamina: 0,
strength: 0,
dexterity: 0,
intelligence: 0,
});
inventory.push(Item::Tool {
kind: Tool::Dagger,
power: 10,
stamina: 0,
strength: 0,
dexterity: 0,
intelligence: 0,
});
inventory.push(Item::Tool {
kind: Tool::Sword,
power: 10,
stamina: 0,
strength: 0,
dexterity: 0,
intelligence: 0,
});
inventory.push(Item::Tool {
kind: Tool::Axe,
power: 10,
stamina: 0,
strength: 0,
dexterity: 0,
intelligence: 0,
});
inventory.push(Item::Tool {
kind: Tool::Hammer,
power: 10,
stamina: 0,
strength: 0,
dexterity: 0,
intelligence: 0,
});
inventory inventory
} }
} }

View File

@ -23,8 +23,8 @@ pub use inputs::CanBuild;
pub use inventory::{item, Inventory, InventoryUpdate, Item}; pub use inventory::{item, Inventory, InventoryUpdate, Item};
pub use last::Last; pub use last::Last;
pub use location::Waypoint; pub use location::Waypoint;
pub use phys::{ForceUpdate, Mass, Ori, PhysicsState, Pos, Scale, Sticky, Vel}; pub use phys::{ForceUpdate, Gravity, Mass, Ori, PhysicsState, Pos, Scale, Sticky, Vel};
pub use player::Player; pub use player::Player;
pub use projectile::Projectile; pub use projectile::Projectile;
pub use stats::{Equipment, Exp, HealthSource, Level, Stats}; pub use stats::{Equipment, Exp, HealthChange, HealthSource, Level, Stats};
pub use visual::LightEmitter; pub use visual::LightEmitter;

View File

@ -43,6 +43,13 @@ impl Component for Mass {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>; type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
} }
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Gravity(pub f32);
impl Component for Gravity {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Sticky; pub struct Sticky;

View File

@ -1,3 +1,4 @@
use crate::comp;
use crate::state::Uid; use crate::state::Uid;
use specs::{Component, FlaggedStorage}; use specs::{Component, FlaggedStorage};
use specs_idvs::IDVStorage; use specs_idvs::IDVStorage;
@ -5,7 +6,7 @@ use std::time::Duration;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Effect { pub enum Effect {
Damage(u32), Damage(comp::HealthChange),
Vanish, Vanish,
Stick, Stick,
Possess, Possess,
@ -13,7 +14,7 @@ pub enum Effect {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Projectile { pub struct Projectile {
pub owner: Option<Uid>, pub owner: Uid,
pub hit_ground: Vec<Effect>, pub hit_ground: Vec<Effect>,
pub hit_wall: Vec<Effect>, pub hit_wall: Vec<Effect>,
pub hit_entity: Vec<Effect>, pub hit_entity: Vec<Effect>,

View File

@ -2,6 +2,12 @@ use crate::{comp, state::Uid};
use specs::{Component, FlaggedStorage}; use specs::{Component, FlaggedStorage};
use specs_idvs::IDVStorage; use specs_idvs::IDVStorage;
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct HealthChange {
pub amount: i32,
pub cause: HealthSource,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum HealthSource { pub enum HealthSource {
Attack { by: Uid }, // TODO: Implement weapon Attack { by: Uid }, // TODO: Implement weapon
@ -24,7 +30,7 @@ pub enum EnergySource {
pub struct Health { pub struct Health {
current: u32, current: u32,
maximum: u32, maximum: u32,
pub last_change: Option<(i32, f64, HealthSource)>, pub last_change: (f64, HealthChange),
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
@ -63,13 +69,19 @@ impl Health {
pub fn set_to(&mut self, amount: u32, cause: HealthSource) { pub fn set_to(&mut self, amount: u32, cause: HealthSource) {
let amount = amount.min(self.maximum); let amount = amount.min(self.maximum);
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause)); self.last_change = (
0.0,
HealthChange {
amount: amount as i32 - self.current as i32,
cause,
},
);
self.current = amount; self.current = amount;
} }
pub fn change_by(&mut self, amount: i32, cause: HealthSource) { pub fn change_by(&mut self, change: HealthChange) {
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum); self.current = ((self.current as i32 + change.amount).max(0) as u32).min(self.maximum);
self.last_change = Some((amount, 0.0, cause)); self.last_change = (0.0, change);
} }
pub fn set_maximum(&mut self, amount: u32) { pub fn set_maximum(&mut self, amount: u32) {
@ -179,7 +191,13 @@ impl Stats {
health: Health { health: Health {
current: 0, current: 0,
maximum: 0, maximum: 0,
last_change: None, last_change: (
0.0,
HealthChange {
amount: 0,
cause: HealthSource::Revive,
},
),
}, },
level: Level { amount: 1 }, level: Level { amount: 1 },
exp: Exp { exp: Exp {

View File

@ -3,14 +3,14 @@ use crate::comp;
/// An effect that may be applied to an entity /// An effect that may be applied to an entity
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Effect { pub enum Effect {
Health(i32, comp::HealthSource), Health(comp::HealthChange),
Xp(i64), Xp(i64),
} }
impl Effect { impl Effect {
pub fn info(&self) -> String { pub fn info(&self) -> String {
match self { match self {
Effect::Health(n, _) => format!("{:+} health", n), Effect::Health(c) => format!("{:+} health", c.amount),
Effect::Xp(n) => format!("{:+} exp", n), Effect::Xp(n) => format!("{:+} exp", n),
} }
} }

View File

@ -24,8 +24,7 @@ pub enum ServerEvent {
}, },
Damage { Damage {
uid: Uid, uid: Uid,
dmg: u32, change: comp::HealthChange,
cause: comp::HealthSource,
}, },
Destroy { Destroy {
entity: EcsEntity, entity: EcsEntity,
@ -38,6 +37,7 @@ pub enum ServerEvent {
body: comp::Body, body: comp::Body,
light: Option<comp::LightEmitter>, light: Option<comp::LightEmitter>,
projectile: comp::Projectile, projectile: comp::Projectile,
gravity: Option<comp::Gravity>,
}, },
LandOnGround { LandOnGround {
entity: EcsEntity, entity: EcsEntity,

View File

@ -31,6 +31,7 @@ sphynx::sum_type! {
Mounting(comp::Mounting), Mounting(comp::Mounting),
Mass(comp::Mass), Mass(comp::Mass),
Projectile(comp::Projectile), Projectile(comp::Projectile),
Gravity(comp::Gravity),
Sticky(comp::Sticky), Sticky(comp::Sticky),
} }
} }
@ -53,6 +54,7 @@ sphynx::sum_type! {
Mounting(PhantomData<comp::Mounting>), Mounting(PhantomData<comp::Mounting>),
Mass(PhantomData<comp::Mass>), Mass(PhantomData<comp::Mass>),
Projectile(PhantomData<comp::Projectile>), Projectile(PhantomData<comp::Projectile>),
Gravity(PhantomData<comp::Gravity>),
Sticky(PhantomData<comp::Sticky>), Sticky(PhantomData<comp::Sticky>),
} }
} }

View File

@ -133,6 +133,7 @@ impl State {
ecs.register_synced::<comp::MountState>(); ecs.register_synced::<comp::MountState>();
ecs.register_synced::<comp::Mass>(); ecs.register_synced::<comp::Mass>();
ecs.register_synced::<comp::Sticky>(); ecs.register_synced::<comp::Sticky>();
ecs.register_synced::<comp::Gravity>();
ecs.register_synced::<comp::Projectile>(); ecs.register_synced::<comp::Projectile>();
// Register components send from clients -> server // Register components send from clients -> server

View File

@ -1,5 +1,8 @@
use crate::{ use crate::{
comp::{item::Item, ActionState::*, CharacterState, Controller, HealthSource, Ori, Pos, Stats}, comp::{
item::Item, ActionState::*, CharacterState, Controller, HealthChange, HealthSource, Ori,
Pos, Stats,
},
event::{EventBus, LocalEvent, ServerEvent}, event::{EventBus, LocalEvent, ServerEvent},
state::{DeltaTime, Uid}, state::{DeltaTime, Uid},
}; };
@ -109,7 +112,7 @@ impl<'a> System<'a> for Sys {
// Weapon gives base damage // Weapon gives base damage
let mut dmg = let mut dmg =
if let Some(Item::Tool { power, .. }) = stat.equipment.main { if let Some(Item::Tool { power, .. }) = stat.equipment.main {
power power as i32
} else { } else {
1 1
}; };
@ -119,13 +122,15 @@ impl<'a> System<'a> for Sys {
&& ori_b.0.angle_between(pos.0 - pos_b.0).to_degrees() && ori_b.0.angle_between(pos.0 - pos_b.0).to_degrees()
< BLOCK_ANGLE / 2.0 < BLOCK_ANGLE / 2.0
{ {
dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as u32 dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as i32
} }
server_emitter.emit(ServerEvent::Damage { server_emitter.emit(ServerEvent::Damage {
uid: *uid_b, uid: *uid_b,
dmg, change: HealthChange {
cause: HealthSource::Attack { by: *uid }, amount: -dmg,
cause: HealthSource::Attack { by: *uid },
},
}); });
} }
} }

View File

@ -5,7 +5,7 @@ use super::{
use crate::{ use crate::{
comp::{ comp::{
self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller, self, item, projectile, ActionState::*, Body, CharacterState, ControlEvent, Controller,
Item, MovementState::*, PhysicsState, Projectile, Stats, Vel, HealthChange, HealthSource, Item, MovementState::*, PhysicsState, Projectile, Stats, Vel,
}, },
event::{EventBus, LocalEvent, ServerEvent}, event::{EventBus, LocalEvent, ServerEvent},
}; };
@ -46,15 +46,16 @@ impl<'a> System<'a> for Sys {
bodies, bodies,
velocities, velocities,
physics_states, physics_states,
uid, uids,
mut character_states, mut character_states,
): Self::SystemData, ): Self::SystemData,
) { ) {
let mut server_emitter = server_bus.emitter(); let mut server_emitter = server_bus.emitter();
let mut local_emitter = local_bus.emitter(); let mut local_emitter = local_bus.emitter();
for (entity, controller, stats, body, vel, physics, mut character) in ( for (entity, uid, controller, stats, body, vel, physics, mut character) in (
&entities, &entities,
&uids,
&mut controllers, &mut controllers,
&stats, &stats,
&bodies, &bodies,
@ -131,6 +132,7 @@ impl<'a> System<'a> for Sys {
match stats.equipment.main { match stats.equipment.main {
Some(Item::Tool { Some(Item::Tool {
kind: item::Tool::Bow, kind: item::Tool::Bow,
power,
.. ..
}) => { }) => {
if controller.primary if controller.primary
@ -147,15 +149,81 @@ impl<'a> System<'a> for Sys {
dir: controller.look_dir, dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::Arrow), body: comp::Body::Object(comp::object::Body::Arrow),
light: None, light: None,
gravity: Some(comp::Gravity(0.3)),
projectile: Projectile { projectile: Projectile {
owner: uid.get(entity).copied(), owner: *uid,
hit_ground: vec![projectile::Effect::Stick], hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Stick], hit_wall: vec![projectile::Effect::Stick],
hit_entity: vec![ hit_entity: vec![
projectile::Effect::Damage(10), projectile::Effect::Damage(HealthChange {
amount: -(power as i32),
cause: HealthSource::Attack { by: *uid },
}),
projectile::Effect::Vanish, projectile::Effect::Vanish,
], ],
time_left: Duration::from_secs(60 * 5), time_left: Duration::from_secs(30),
},
});
}
}
}
}
Some(Item::Tool {
kind: item::Tool::Staff,
power,
..
}) => {
// Melee Attack
if controller.primary
&& (character.movement == Stand
|| character.movement == Run
|| character.movement == Jump)
{
if let Wield { time_left } = character.action {
if time_left == Duration::default() {
character.action = Attack {
time_left: ATTACK_DURATION,
applied: false,
};
}
}
}
// Magical Bolt
if controller.secondary
&& (
character.movement == Stand
//|| character.movement == Run
//|| character.movement == Jump
)
{
if let Wield { time_left } = character.action {
if time_left == Duration::default() {
character.action = Attack {
time_left: ATTACK_DURATION,
applied: false,
};
server_emitter.emit(ServerEvent::Shoot {
entity,
dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::BoltFire),
gravity: Some(comp::Gravity(0.0)),
light: Some(comp::LightEmitter {
col: (0.72, 0.11, 0.11).into(),
strength: 10.0,
offset: Vec3::new(0.0, -5.0, 2.0),
}),
projectile: Projectile {
owner: *uid,
hit_ground: vec![projectile::Effect::Vanish],
hit_wall: vec![projectile::Effect::Vanish],
hit_entity: vec![
projectile::Effect::Damage(HealthChange {
amount: -(power as i32),
cause: HealthSource::Attack { by: *uid },
}),
projectile::Effect::Vanish,
],
time_left: Duration::from_secs(5),
}, },
}); });
} }
@ -220,26 +288,40 @@ impl<'a> System<'a> for Sys {
character.action = Idle; character.action = Idle;
server_emitter.emit(ServerEvent::Shoot { server_emitter.emit(ServerEvent::Shoot {
entity, entity,
gravity: Some(comp::Gravity(0.1)),
dir: controller.look_dir, dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::PotionRed), body: comp::Body::Object(comp::object::Body::ArrowSnake),
light: Some(comp::LightEmitter { light: Some(comp::LightEmitter {
col: (0.0, 1.0, 0.3).into(), col: (0.0, 1.0, 0.3).into(),
..Default::default() ..Default::default()
}), }),
projectile: Projectile { projectile: Projectile {
owner: uid.get(entity).copied(), owner: *uid,
hit_ground: vec![projectile::Effect::Vanish], hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Vanish], hit_wall: vec![projectile::Effect::Stick],
hit_entity: vec![ hit_entity: vec![
projectile::Effect::Vanish, projectile::Effect::Stick,
projectile::Effect::Possess, projectile::Effect::Possess,
], ],
time_left: Duration::from_secs(60 * 5), time_left: Duration::from_secs(10),
}, },
}); });
} }
} }
} }
// Block
if controller.secondary
&& (character.movement == Stand || character.movement == Run)
&& character.action.is_wield()
{
character.action = Block {
time_left: Duration::from_secs(5),
};
} else if !controller.secondary && character.action.is_block() {
character.action = Wield {
time_left: Duration::default(),
};
}
} }
None => { None => {
// Attack // Attack

View File

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
comp::{Body, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Sticky, Vel}, comp::{Body, Gravity, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Sticky, Vel},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
state::DeltaTime, state::DeltaTime,
terrain::{Block, TerrainGrid}, terrain::{Block, TerrainGrid},
@ -49,6 +49,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Scale>, ReadStorage<'a, Scale>,
ReadStorage<'a, Sticky>, ReadStorage<'a, Sticky>,
ReadStorage<'a, Mass>, ReadStorage<'a, Mass>,
ReadStorage<'a, Gravity>,
ReadStorage<'a, Body>, ReadStorage<'a, Body>,
WriteStorage<'a, PhysicsState>, WriteStorage<'a, PhysicsState>,
WriteStorage<'a, Pos>, WriteStorage<'a, Pos>,
@ -68,6 +69,7 @@ impl<'a> System<'a> for Sys {
scales, scales,
stickies, stickies,
masses, masses,
gravities,
bodies, bodies,
mut physics_states, mut physics_states,
mut positions, mut positions,
@ -130,7 +132,7 @@ impl<'a> System<'a> for Sys {
(1.0 - BOUYANCY) * GRAVITY (1.0 - BOUYANCY) * GRAVITY
} else { } else {
GRAVITY GRAVITY
}; } * gravities.get(entity).map(|g| g.0).unwrap_or_default();
vel.0 = integrate_forces(dt.0, vel.0, downward_force, friction); vel.0 = integrate_forces(dt.0, vel.0, downward_force, friction);
// Don't move if we're not in a loaded chunk // Don't move if we're not in a loaded chunk

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
comp::{projectile, HealthSource, Ori, PhysicsState, Projectile, Vel}, comp::{projectile, /*HealthChange,*/ HealthSource, Ori, PhysicsState, Projectile, Vel},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
state::DeltaTime, state::DeltaTime,
}; };
@ -70,25 +70,15 @@ impl<'a> System<'a> for Sys {
else if let Some(other) = physics.touch_entity { else if let Some(other) = physics.touch_entity {
for effect in projectile.hit_entity.drain(..) { for effect in projectile.hit_entity.drain(..) {
match effect { match effect {
projectile::Effect::Damage(power) => { projectile::Effect::Damage(change) => {
server_emitter.emit(ServerEvent::Damage { server_emitter.emit(ServerEvent::Damage { uid: other, change })
uid: other,
dmg: power,
cause: match projectile.owner {
Some(uid) => HealthSource::Attack { by: uid },
None => HealthSource::Unknown,
},
})
} }
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity, entity,
cause: HealthSource::World, cause: HealthSource::World,
}), }),
projectile::Effect::Possess => { projectile::Effect::Possess => server_emitter
if let Some(uid) = projectile.owner { .emit(ServerEvent::Possess(projectile.owner.into(), other)),
server_emitter.emit(ServerEvent::Possess(uid.into(), other))
}
}
_ => {} _ => {}
} }
} }

View File

@ -3,7 +3,6 @@ use crate::{
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
state::DeltaTime, state::DeltaTime,
}; };
use log::warn;
use specs::{Entities, Join, Read, System, WriteStorage}; use specs::{Entities, Join, Read, System, WriteStorage};
/// This system kills players /// This system kills players
@ -23,21 +22,13 @@ impl<'a> System<'a> for Sys {
if stat.should_die() && !stat.is_dead { if stat.should_die() && !stat.is_dead {
event_emitter.emit(ServerEvent::Destroy { event_emitter.emit(ServerEvent::Destroy {
entity, entity,
cause: match stat.health.last_change { cause: stat.health.last_change.1.cause,
Some(change) => change.2,
None => {
warn!("Nothing caused an entity to die!");
HealthSource::Unknown
}
},
}); });
stat.is_dead = true; stat.is_dead = true;
} }
if let Some(change) = &mut stat.health.last_change { stat.health.last_change.0 += f64::from(dt.0);
change.1 += f64::from(dt.0);
}
if stat.exp.current() >= stat.exp.maximum() { if stat.exp.current() >= stat.exp.maximum() {
while stat.exp.current() >= stat.exp.maximum() { while stat.exp.current() >= stat.exp.maximum() {

View File

@ -30,6 +30,7 @@ pub enum BlockKind {
Mushroom, Mushroom,
Liana, Liana,
Velorite, Velorite,
VeloriteFrag,
Chest, Chest,
} }
@ -64,6 +65,7 @@ impl BlockKind {
BlockKind::Mushroom => true, BlockKind::Mushroom => true,
BlockKind::Liana => true, BlockKind::Liana => true,
BlockKind::Velorite => true, BlockKind::Velorite => true,
BlockKind::VeloriteFrag => true,
BlockKind::Chest => true, BlockKind::Chest => true,
_ => false, _ => false,
} }
@ -100,6 +102,7 @@ impl BlockKind {
BlockKind::Mushroom => false, BlockKind::Mushroom => false,
BlockKind::Liana => false, BlockKind::Liana => false,
BlockKind::Velorite => false, BlockKind::Velorite => false,
BlockKind::VeloriteFrag => false,
BlockKind::Chest => false, BlockKind::Chest => false,
_ => true, _ => true,
} }
@ -135,19 +138,20 @@ impl BlockKind {
pub fn is_collectible(&self) -> bool { pub fn is_collectible(&self) -> bool {
match self { match self {
BlockKind::BlueFlower => true, BlockKind::BlueFlower => false,
BlockKind::PinkFlower => true, BlockKind::PinkFlower => false,
BlockKind::PurpleFlower => true, BlockKind::PurpleFlower => false,
BlockKind::RedFlower => true, BlockKind::RedFlower => false,
BlockKind::WhiteFlower => true, BlockKind::WhiteFlower => false,
BlockKind::YellowFlower => true, BlockKind::YellowFlower => false,
BlockKind::Sunflower => true, BlockKind::Sunflower => false,
BlockKind::LongGrass => true, BlockKind::LongGrass => false,
BlockKind::MediumGrass => true, BlockKind::MediumGrass => false,
BlockKind::ShortGrass => true, BlockKind::ShortGrass => false,
BlockKind::Apple => true, BlockKind::Apple => true,
BlockKind::Mushroom => true, BlockKind::Mushroom => true,
BlockKind::Velorite => true, BlockKind::Velorite => true,
BlockKind::VeloriteFrag => true,
BlockKind::Chest => true, BlockKind::Chest => true,
_ => false, _ => false,
} }

View File

@ -170,6 +170,7 @@ impl Server {
.with(comp::Controller::default()) .with(comp::Controller::default())
.with(body) .with(body)
.with(stats) .with(stats)
.with(comp::Gravity(1.0))
.with(comp::CharacterState::default()) .with(comp::CharacterState::default())
} }
@ -199,10 +200,9 @@ impl Server {
pos: comp::Pos, pos: comp::Pos,
vel: comp::Vel, vel: comp::Vel,
body: comp::Body, body: comp::Body,
maybe_light: Option<comp::LightEmitter>,
projectile: comp::Projectile, projectile: comp::Projectile,
) -> EcsEntityBuilder { ) -> EcsEntityBuilder {
let builder = state state
.ecs_mut() .ecs_mut()
.create_entity_synced() .create_entity_synced()
.with(pos) .with(pos)
@ -211,13 +211,7 @@ impl Server {
.with(comp::Mass(0.0)) .with(comp::Mass(0.0))
.with(body) .with(body)
.with(projectile) .with(projectile)
.with(comp::Sticky); .with(comp::Sticky)
if let Some(light) = maybe_light {
builder.with(light)
} else {
builder
}
} }
pub fn create_player_character( pub fn create_player_character(
@ -237,6 +231,7 @@ impl Server {
state.write_component(entity, comp::Pos(spawn_point)); state.write_component(entity, comp::Pos(spawn_point));
state.write_component(entity, comp::Vel(Vec3::zero())); state.write_component(entity, comp::Vel(Vec3::zero()));
state.write_component(entity, comp::Ori(Vec3::unit_y())); state.write_component(entity, comp::Ori(Vec3::unit_y()));
state.write_component(entity, comp::Gravity(1.0));
state.write_component(entity, comp::CharacterState::default()); state.write_component(entity, comp::CharacterState::default());
state.write_component(entity, comp::Inventory::default()); state.write_component(entity, comp::Inventory::default());
state.write_component(entity, comp::InventoryUpdate); state.write_component(entity, comp::InventoryUpdate);
@ -301,6 +296,7 @@ impl Server {
body, body,
light, light,
projectile, projectile,
gravity,
} => { } => {
let mut pos = state let mut pos = state
.ecs() .ecs()
@ -312,22 +308,28 @@ impl Server {
// TODO: Player height // TODO: Player height
pos.z += 1.2; pos.z += 1.2;
Self::create_projectile( let mut builder = Self::create_projectile(
state, state,
comp::Pos(pos), comp::Pos(pos),
comp::Vel(dir * 100.0), comp::Vel(dir * 100.0),
body, body,
light,
projectile, projectile,
) );
.build(); if let Some(light) = light {
builder = builder.with(light)
}
if let Some(gravity) = gravity {
builder = builder.with(gravity)
}
builder.build();
} }
ServerEvent::Damage { uid, dmg, cause } => { ServerEvent::Damage { uid, change } => {
let ecs = state.ecs_mut(); let ecs = state.ecs_mut();
if let Some(entity) = ecs.entity_from_uid(uid.into()) { if let Some(entity) = ecs.entity_from_uid(uid.into()) {
if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(entity) { if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(entity) {
stats.health.change_by(-(dmg as i32), cause); stats.health.change_by(change);
} }
} }
} }
@ -415,7 +417,10 @@ impl Server {
{ {
let falldmg = (vel.z / 5.0) as i32; let falldmg = (vel.z / 5.0) as i32;
if falldmg < 0 { if falldmg < 0 {
stats.health.change_by(falldmg, comp::HealthSource::World); stats.health.change_by(comp::HealthChange {
amount: falldmg,
cause: comp::HealthSource::World,
});
} }
} }
} }
@ -1585,11 +1590,11 @@ impl StateExt for State {
fn apply_effect(&mut self, entity: EcsEntity, effect: Effect) { fn apply_effect(&mut self, entity: EcsEntity, effect: Effect) {
match effect { match effect {
Effect::Health(hp, source) => { Effect::Health(change) => {
self.ecs_mut() self.ecs_mut()
.write_storage::<comp::Stats>() .write_storage::<comp::Stats>()
.get_mut(entity) .get_mut(entity)
.map(|stats| stats.health.change_by(hp, source)); .map(|stats| stats.health.change_by(change));
} }
Effect::Xp(xp) => { Effect::Xp(xp) => {
self.ecs_mut() self.ecs_mut()

View File

@ -107,6 +107,8 @@ image_ids! {
twohaxe_m2: "voxygen.element.icons.2haxe_m2", twohaxe_m2: "voxygen.element.icons.2haxe_m2",
bow_m1: "voxygen.element.icons.bow_m1", bow_m1: "voxygen.element.icons.bow_m1",
bow_m2: "voxygen.element.icons.bow_m2", bow_m2: "voxygen.element.icons.bow_m2",
staff_m1: "voxygen.element.icons.staff_m1",
staff_m2: "voxygen.element.icons.staff_m2",
flyingrod_m1: "voxygen.element.icons.debug_wand_m1", flyingrod_m1: "voxygen.element.icons.debug_wand_m1",
flyingrod_m2: "voxygen.element.icons.debug_wand_m2", flyingrod_m2: "voxygen.element.icons.debug_wand_m2",

View File

@ -26,7 +26,7 @@ impl From<&Item> for ItemKind {
Item::Tool { kind, .. } => ItemKind::Tool(kind.clone()), Item::Tool { kind, .. } => ItemKind::Tool(kind.clone()),
Item::Armor { kind, .. } => ItemKind::Armor(kind.clone()), Item::Armor { kind, .. } => ItemKind::Armor(kind.clone()),
Item::Consumable { kind, .. } => ItemKind::Consumable(kind.clone()), Item::Consumable { kind, .. } => ItemKind::Consumable(kind.clone()),
Item::Ingredient { kind } => ItemKind::Ingredient(kind.clone()), Item::Ingredient { kind, .. } => ItemKind::Ingredient(kind.clone()),
Item::Debug(kind) => ItemKind::Debug(kind.clone()), Item::Debug(kind) => ItemKind::Debug(kind.clone()),
} }
} }

View File

@ -513,6 +513,7 @@ impl<'a> Widget for Skillbar<'a> {
Tool::Hammer => self.imgs.twohhammer_m1, Tool::Hammer => self.imgs.twohhammer_m1,
Tool::Axe => self.imgs.twohaxe_m1, Tool::Axe => self.imgs.twohaxe_m1,
Tool::Bow => self.imgs.bow_m1, Tool::Bow => self.imgs.bow_m1,
Tool::Staff => self.imgs.staff_m1,
_ => self.imgs.twohaxe_m1, _ => self.imgs.twohaxe_m1,
}, },
Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m1, Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m1,
@ -537,6 +538,7 @@ impl<'a> Widget for Skillbar<'a> {
Tool::Hammer => self.imgs.twohhammer_m2, Tool::Hammer => self.imgs.twohhammer_m2,
Tool::Axe => self.imgs.twohaxe_m2, Tool::Axe => self.imgs.twohaxe_m2,
Tool::Bow => self.imgs.bow_m2, Tool::Bow => self.imgs.bow_m2,
Tool::Staff => self.imgs.staff_m2,
_ => self.imgs.twohaxe_m2, _ => self.imgs.twohaxe_m2,
}, },
Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m2, Some(Item::Debug(Debug::Boost)) => self.imgs.flyingrod_m2,

View File

@ -902,18 +902,18 @@ impl CharSelectionUi {
self.imgs.icon_border self.imgs.icon_border
}) })
.middle_of(self.ids.staff) .middle_of(self.ids.staff)
//.hover_image(self.imgs.icon_border_mo) .hover_image(self.imgs.icon_border_mo)
//.press_image(self.imgs.icon_border_press) .press_image(self.imgs.icon_border_press)
//.with_tooltip(tooltip_manager, "Staff", "", &tooltip_human) .with_tooltip(tooltip_manager, "Staff", "", &tooltip_human)
.set(self.ids.staff_button, ui_widgets) .set(self.ids.staff_button, ui_widgets)
.was_clicked() .was_clicked()
{ {
//self.character_tool = Some(Tool::Staff); self.character_tool = Some(Tool::Staff);
} }
// REMOVE THIS AFTER IMPLEMENTATION // REMOVE THIS AFTER IMPLEMENTATION
Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8)) /*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
.middle_of(self.ids.staff) .middle_of(self.ids.staff)
.set(self.ids.staff_grey, ui_widgets); .set(self.ids.staff_grey, ui_widgets);*/
// Sword // Sword
Image::new(self.imgs.sword) Image::new(self.imgs.sword)
.w_h(70.0, 70.0) .w_h(70.0, 70.0)

View File

@ -358,7 +358,7 @@ pub fn mesh_main(item: Option<&Item>) -> Mesh<FigurePipeline> {
Tool::Dagger => ("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::Shield => ("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.staff.wood-0", Vec3::new(-1.0, -6.0, -3.0)),
}, },
Item::Debug(_) => ("weapon.debug_wand", Vec3::new(-1.5, -9.5, -4.0)), Item::Debug(_) => ("weapon.debug_wand", Vec3::new(-1.5, -9.5, -4.0)),
_ => return Mesh::new(), _ => return Mesh::new(),
@ -581,7 +581,7 @@ pub fn mesh_object(obj: object::Body) -> Mesh<FigurePipeline> {
use object::Body; use object::Body;
let (name, offset) = match obj { let (name, offset) = match obj {
Body::Arrow => ("weapon.bow.simple-arrow", Vec3::new(-5.5, -5.5, 0.0)), Body::Arrow => ("weapon.projectile.simple-arrow", Vec3::new(-5.5, -5.5, 0.0)),
Body::Bomb => ("object.bomb", Vec3::new(-5.5, -5.5, 0.0)), Body::Bomb => ("object.bomb", Vec3::new(-5.5, -5.5, 0.0)),
Body::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.0, 0.0)), Body::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.0, 0.0)),
Body::Cauldron => ("object.cauldron", Vec3::new(-10.0, -10.0, 0.0)), Body::Cauldron => ("object.cauldron", Vec3::new(-10.0, -10.0, 0.0)),
@ -636,6 +636,8 @@ pub fn mesh_object(obj: object::Body) -> Mesh<FigurePipeline> {
), ),
Body::Pouch => ("object.pouch", Vec3::new(-5.5, -4.5, 0.0)), Body::Pouch => ("object.pouch", Vec3::new(-5.5, -4.5, 0.0)),
Body::CraftingBench => ("object.crafting_bench", Vec3::new(-9.5, -7.0, 0.0)), Body::CraftingBench => ("object.crafting_bench", Vec3::new(-9.5, -7.0, 0.0)),
Body::ArrowSnake => ("weapon.projectile.snake-arrow", Vec3::new(-1.5, -6.5, 0.0)),
Body::BoltFire => ("weapon.projectile.fire-bolt", Vec3::new(-3.0, -5.5, -3.0)),
}; };
load_mesh(name, offset) load_mesh(name, offset)
} }

View File

@ -104,11 +104,11 @@ impl FigureMgr {
// Change in health as color! // Change in health as color!
let col = stats let col = stats
.and_then(|stats| stats.health.last_change) .map(|s| {
.map(|(_, time, _)| {
Rgba::broadcast(1.0) Rgba::broadcast(1.0)
+ Rgba::new(2.0, 2.0, 2.0, 0.0) + Rgba::new(2.0, 2.0, 2.0, 0.0).map(|c| {
.map(|c| (c / (1.0 + DAMAGE_FADE_COEFFICIENT * time)) as f32) (c / (1.0 + DAMAGE_FADE_COEFFICIENT * s.health.last_change.0)) as f32
})
}) })
.unwrap_or(Rgba::broadcast(1.0)); .unwrap_or(Rgba::broadcast(1.0));

View File

@ -82,7 +82,7 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
}), }),
BlockKind::BlueFlower => Some(SpriteConfig { BlockKind::BlueFlower => Some(SpriteConfig {
variations: 6, variations: 7,
wind_sway: 0.1, wind_sway: 0.1,
}), }),
BlockKind::PinkFlower => Some(SpriteConfig { BlockKind::PinkFlower => Some(SpriteConfig {
@ -90,7 +90,7 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
wind_sway: 0.1, wind_sway: 0.1,
}), }),
BlockKind::RedFlower => Some(SpriteConfig { BlockKind::RedFlower => Some(SpriteConfig {
variations: 2, variations: 3,
wind_sway: 0.1, wind_sway: 0.1,
}), }),
BlockKind::WhiteFlower => Some(SpriteConfig { BlockKind::WhiteFlower => Some(SpriteConfig {
@ -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::VeloriteFrag => Some(SpriteConfig {
variations: 10,
wind_sway: 0.0,
}),
BlockKind::Chest => Some(SpriteConfig { BlockKind::Chest => Some(SpriteConfig {
variations: 4, variations: 4,
wind_sway: 0.0, wind_sway: 0.0,
@ -331,6 +335,13 @@ impl<V: RectRasterableVol> Terrain<V> {
Vec3::new(-6.0, -6.0, 0.0), Vec3::new(-6.0, -6.0, 0.0),
), ),
), ),
(
(BlockKind::BlueFlower, 6),
make_model(
"voxygen.voxel.sprite.flowers.flower_blue_7",
Vec3::new(-6.0, -6.0, 0.0),
),
),
( (
(BlockKind::PinkFlower, 0), (BlockKind::PinkFlower, 0),
make_model( make_model(
@ -380,6 +391,13 @@ impl<V: RectRasterableVol> Terrain<V> {
Vec3::new(-6.0, -6.0, 0.0), Vec3::new(-6.0, -6.0, 0.0),
), ),
), ),
(
(BlockKind::RedFlower, 2),
make_model(
"voxygen.voxel.sprite.flowers.flower_red_3",
Vec3::new(-6.0, -6.0, 0.0),
),
),
( (
(BlockKind::WhiteFlower, 0), (BlockKind::WhiteFlower, 0),
make_model( make_model(
@ -626,6 +644,76 @@ impl<V: RectRasterableVol> Terrain<V> {
Vec3::new(-5.0, -5.0, -5.0), Vec3::new(-5.0, -5.0, -5.0),
), ),
), ),
(
(BlockKind::VeloriteFrag, 0),
make_model(
"voxygen.voxel.sprite.velorite.velorite_1",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 1),
make_model(
"voxygen.voxel.sprite.velorite.velorite_2",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 2),
make_model(
"voxygen.voxel.sprite.velorite.velorite_3",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 3),
make_model(
"voxygen.voxel.sprite.velorite.velorite_4",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 4),
make_model(
"voxygen.voxel.sprite.velorite.velorite_5",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 5),
make_model(
"voxygen.voxel.sprite.velorite.velorite_6",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 6),
make_model(
"voxygen.voxel.sprite.velorite.velorite_7",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 7),
make_model(
"voxygen.voxel.sprite.velorite.velorite_8",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 8),
make_model(
"voxygen.voxel.sprite.velorite.velorite_9",
Vec3::new(-3.0, -5.0, 0.0),
),
),
(
(BlockKind::VeloriteFrag, 9),
make_model(
"voxygen.voxel.sprite.velorite.velorite_10",
Vec3::new(-3.0, -5.0, 0.0),
),
),
( (
(BlockKind::Chest, 0), (BlockKind::Chest, 0),
make_model( make_model(