Merge branch 'pfau/assets' into 'master'

Initial staff implementation

See merge request veloren/veloren!602
This commit is contained in:
Joshua Barretto 2019-10-17 20:59:37 +00:00
commit 687473c5e6
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)
({ // Debug Items
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,
),
// Weapons
@ -27,6 +31,14 @@
"voxel.weapon.hammer.rusty_2h",
(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
Consumable(Apple): VoxTrans(
"element.icons.item_apple",
@ -44,6 +56,10 @@
"voxel.sprite.velorite.velorite_ore",
(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
Ingredient(Flower): VoxTrans(
"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-1", (1, 1, 1))),
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: [
None,
beard: [
Some(("figure.beard.human.human-0", (4, 6, -2))),
Some(("figure.beard.human.human-1", (5, 10, -2))),
],
@ -206,10 +205,12 @@
head: ("figure.head.danari.male", (0, 2, 2)),
eyes: ("figure.eyes.danari.male-0", (5, 9, 4)),
hair: [
Some(("figure.hair.danari.male", (3, 1, 2))),
Some(("figure.hair.danari.male", (3, 1, 2))),
Some(("figure.hair.danari.male-0", (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: [
Some(("figure.accessory.danari.horns-0", (4, 8, 8))),]
),
@ -218,8 +219,8 @@
head: ("figure.head.danari.female", (0, 2, 2)),
eyes: ("figure.eyes.danari.female-0", (4, 9, 4)),
hair: [
Some(("figure.hair.danari.female", (3, -4, 1))),
Some(("figure.hair.danari.female", (3, -4, 1))),
Some(("figure.hair.danari.female-0", (3, -4, 1))),
Some(("figure.hair.danari.female-1", (1, 1, 3))),
],
beard: [None],
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
pub const DANARI_HAIR_COLORS: [(u8, u8, u8); 16] = [
pub const DANARI_HAIR_COLORS: [(u8, u8, u8); 11] = [
(198, 169, 113), // Philosopher's Grey
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown
(86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(107, 32, 60), // Grape Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(146, 32, 32), // Autumn Red
//(245, 232, 175), // Cream Blonde
//(228, 208, 147), // Gold Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Brown
//(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown
(86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(107, 32, 60), // Grape Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
//(146, 32, 32), // Autumn Red
];
pub const DWARF_HAIR_COLORS: [(u8, u8, u8); 20] = [
(245, 232, 175), // Cream Blonde
@ -165,24 +165,24 @@ pub const HUMAN_HAIR_COLORS: [(u8, u8, u8); 21] = [
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
];
pub const ORC_HAIR_COLORS: [(u8, u8, u8); 12] = [
(66, 66, 59), // Wise Grey
(107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown
(54, 30, 26), // Dark Chocolate
(86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(66, 83, 113), // Mysterious Blue
pub const ORC_HAIR_COLORS: [(u8, u8, u8); 10] = [
(66, 66, 59), // Wise Grey
//(107, 76, 51), // Oak Brown
//(203, 154, 98), // Light Brown
(64, 32, 18), // Chocolate Brown
(54, 30, 26), // Dark Chocolate
(86, 72, 71), // Ash Brown
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(66, 83, 113), // Mysterious Blue
];
pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 24] = [
(245, 232, 175), // Cream Blonde
pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 21] = [
//(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Brown
(203, 154, 98), // Light Brown
@ -198,7 +198,7 @@ pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 24] = [
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(66, 66, 59), // Decayed Grey
(224, 182, 184), // Candy Pink
//(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(0, 131, 122), // Rotten Green
(163, 186, 192), // Matte Green
@ -330,8 +330,8 @@ impl Race {
}
pub fn num_hair_styles(self, body_type: BodyType) -> u8 {
match (self, body_type) {
(Race::Danari, BodyType::Female) => 1,
(Race::Danari, BodyType::Male) => 1,
(Race::Danari, BodyType::Female) => 2,
(Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1,
(Race::Dwarf, BodyType::Male) => 3,
(Race::Elf, BodyType::Female) => 21,
@ -363,7 +363,7 @@ impl Race {
pub fn num_beards(self, body_type: BodyType) -> u8 {
match (self, body_type) {
(Race::Danari, BodyType::Female) => 1,
(Race::Danari, BodyType::Male) => 1,
(Race::Danari, BodyType::Male) => 2,
(Race::Dwarf, BodyType::Female) => 1,
(Race::Dwarf, BodyType::Male) => 20,
(Race::Elf, BodyType::Female) => 1,

View File

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

View File

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

View File

@ -69,52 +69,11 @@ impl Inventory {
impl Default for Inventory {
fn default() -> Inventory {
let mut inventory = Inventory {
slots: vec![None; 24],
slots: vec![None; 25],
};
inventory.push(Item::Debug(Debug::Boost));
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
}
}

View File

@ -23,8 +23,8 @@ pub use inputs::CanBuild;
pub use inventory::{item, Inventory, InventoryUpdate, Item};
pub use last::Last;
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 projectile::Projectile;
pub use stats::{Equipment, Exp, HealthSource, Level, Stats};
pub use stats::{Equipment, Exp, HealthChange, HealthSource, Level, Stats};
pub use visual::LightEmitter;

View File

@ -43,6 +43,13 @@ impl Component for Mass {
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)]
pub struct Sticky;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,8 @@
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},
state::{DeltaTime, Uid},
};
@ -109,7 +112,7 @@ impl<'a> System<'a> for Sys {
// Weapon gives base damage
let mut dmg =
if let Some(Item::Tool { power, .. }) = stat.equipment.main {
power
power as i32
} else {
1
};
@ -119,13 +122,15 @@ impl<'a> System<'a> for Sys {
&& ori_b.0.angle_between(pos.0 - pos_b.0).to_degrees()
< 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 {
uid: *uid_b,
dmg,
cause: HealthSource::Attack { by: *uid },
change: HealthChange {
amount: -dmg,
cause: HealthSource::Attack { by: *uid },
},
});
}
}

View File

@ -5,7 +5,7 @@ use super::{
use crate::{
comp::{
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},
};
@ -46,15 +46,16 @@ impl<'a> System<'a> for Sys {
bodies,
velocities,
physics_states,
uid,
uids,
mut character_states,
): Self::SystemData,
) {
let mut server_emitter = server_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,
&uids,
&mut controllers,
&stats,
&bodies,
@ -131,6 +132,7 @@ impl<'a> System<'a> for Sys {
match stats.equipment.main {
Some(Item::Tool {
kind: item::Tool::Bow,
power,
..
}) => {
if controller.primary
@ -147,15 +149,81 @@ impl<'a> System<'a> for Sys {
dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::Arrow),
light: None,
gravity: Some(comp::Gravity(0.3)),
projectile: Projectile {
owner: uid.get(entity).copied(),
owner: *uid,
hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Stick],
hit_entity: vec![
projectile::Effect::Damage(10),
projectile::Effect::Damage(HealthChange {
amount: -(power as i32),
cause: HealthSource::Attack { by: *uid },
}),
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;
server_emitter.emit(ServerEvent::Shoot {
entity,
gravity: Some(comp::Gravity(0.1)),
dir: controller.look_dir,
body: comp::Body::Object(comp::object::Body::PotionRed),
body: comp::Body::Object(comp::object::Body::ArrowSnake),
light: Some(comp::LightEmitter {
col: (0.0, 1.0, 0.3).into(),
..Default::default()
}),
projectile: Projectile {
owner: uid.get(entity).copied(),
hit_ground: vec![projectile::Effect::Vanish],
hit_wall: vec![projectile::Effect::Vanish],
owner: *uid,
hit_ground: vec![projectile::Effect::Stick],
hit_wall: vec![projectile::Effect::Stick],
hit_entity: vec![
projectile::Effect::Vanish,
projectile::Effect::Stick,
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 => {
// Attack

View File

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

View File

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

View File

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

View File

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

View File

@ -170,6 +170,7 @@ impl Server {
.with(comp::Controller::default())
.with(body)
.with(stats)
.with(comp::Gravity(1.0))
.with(comp::CharacterState::default())
}
@ -199,10 +200,9 @@ impl Server {
pos: comp::Pos,
vel: comp::Vel,
body: comp::Body,
maybe_light: Option<comp::LightEmitter>,
projectile: comp::Projectile,
) -> EcsEntityBuilder {
let builder = state
state
.ecs_mut()
.create_entity_synced()
.with(pos)
@ -211,13 +211,7 @@ impl Server {
.with(comp::Mass(0.0))
.with(body)
.with(projectile)
.with(comp::Sticky);
if let Some(light) = maybe_light {
builder.with(light)
} else {
builder
}
.with(comp::Sticky)
}
pub fn create_player_character(
@ -237,6 +231,7 @@ impl Server {
state.write_component(entity, comp::Pos(spawn_point));
state.write_component(entity, comp::Vel(Vec3::zero()));
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::Inventory::default());
state.write_component(entity, comp::InventoryUpdate);
@ -301,6 +296,7 @@ impl Server {
body,
light,
projectile,
gravity,
} => {
let mut pos = state
.ecs()
@ -312,22 +308,28 @@ impl Server {
// TODO: Player height
pos.z += 1.2;
Self::create_projectile(
let mut builder = Self::create_projectile(
state,
comp::Pos(pos),
comp::Vel(dir * 100.0),
body,
light,
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();
if let Some(entity) = ecs.entity_from_uid(uid.into()) {
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;
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) {
match effect {
Effect::Health(hp, source) => {
Effect::Health(change) => {
self.ecs_mut()
.write_storage::<comp::Stats>()
.get_mut(entity)
.map(|stats| stats.health.change_by(hp, source));
.map(|stats| stats.health.change_by(change));
}
Effect::Xp(xp) => {
self.ecs_mut()

View File

@ -107,6 +107,8 @@ image_ids! {
twohaxe_m2: "voxygen.element.icons.2haxe_m2",
bow_m1: "voxygen.element.icons.bow_m1",
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_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::Armor { kind, .. } => ItemKind::Armor(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()),
}
}

View File

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

View File

@ -902,18 +902,18 @@ impl CharSelectionUi {
self.imgs.icon_border
})
.middle_of(self.ids.staff)
//.hover_image(self.imgs.icon_border_mo)
//.press_image(self.imgs.icon_border_press)
//.with_tooltip(tooltip_manager, "Staff", "", &tooltip_human)
.hover_image(self.imgs.icon_border_mo)
.press_image(self.imgs.icon_border_press)
.with_tooltip(tooltip_manager, "Staff", "", &tooltip_human)
.set(self.ids.staff_button, ui_widgets)
.was_clicked()
{
//self.character_tool = Some(Tool::Staff);
self.character_tool = Some(Tool::Staff);
}
// REMOVE THIS AFTER IMPLEMENTATION
Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
.middle_of(self.ids.staff)
.set(self.ids.staff_grey, ui_widgets);
/*Rectangle::fill_with([67.0, 67.0], color::rgba(0.0, 0.0, 0.0, 0.8))
.middle_of(self.ids.staff)
.set(self.ids.staff_grey, ui_widgets);*/
// Sword
Image::new(self.imgs.sword)
.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::Shield => ("weapon.axe.rusty_2h", Vec3::new(-2.5, -6.5, -2.0)),
Tool::Bow => ("weapon.bow.simple-bow", Vec3::new(-1.0, -6.0, -2.0)),
Tool::Staff => ("weapon.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)),
_ => return Mesh::new(),
@ -581,7 +581,7 @@ pub fn mesh_object(obj: object::Body) -> Mesh<FigurePipeline> {
use object::Body;
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::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.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::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)
}

View File

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

View File

@ -82,7 +82,7 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
}),
BlockKind::BlueFlower => Some(SpriteConfig {
variations: 6,
variations: 7,
wind_sway: 0.1,
}),
BlockKind::PinkFlower => Some(SpriteConfig {
@ -90,7 +90,7 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
wind_sway: 0.1,
}),
BlockKind::RedFlower => Some(SpriteConfig {
variations: 2,
variations: 3,
wind_sway: 0.1,
}),
BlockKind::WhiteFlower => Some(SpriteConfig {
@ -135,6 +135,10 @@ fn sprite_config_for(kind: BlockKind) -> Option<SpriteConfig> {
variations: 1,
wind_sway: 0.0,
}),
BlockKind::VeloriteFrag => Some(SpriteConfig {
variations: 10,
wind_sway: 0.0,
}),
BlockKind::Chest => Some(SpriteConfig {
variations: 4,
wind_sway: 0.0,
@ -331,6 +335,13 @@ impl<V: RectRasterableVol> Terrain<V> {
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),
make_model(
@ -380,6 +391,13 @@ impl<V: RectRasterableVol> Terrain<V> {
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),
make_model(
@ -626,6 +644,76 @@ impl<V: RectRasterableVol> Terrain<V> {
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),
make_model(