diff --git a/assets/voxygen/voxel/sprite/velorite/velorite.vox b/assets/voxygen/voxel/sprite/velorite/velorite.vox new file mode 100644 index 0000000000..0c871bed62 --- /dev/null +++ b/assets/voxygen/voxel/sprite/velorite/velorite.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e82355fc12f3798647dc3e29d004170b6a3b5d84546dbeeb20f6a40bc98760d +size 57041 diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_1.vox b/assets/voxygen/voxel/sprite/velorite/velorite_1.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_1.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_1.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_10.vox b/assets/voxygen/voxel/sprite/velorite/velorite_10.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_10.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_10.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_2.vox b/assets/voxygen/voxel/sprite/velorite/velorite_2.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_2.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_2.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_3.vox b/assets/voxygen/voxel/sprite/velorite/velorite_3.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_3.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_3.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_4.vox b/assets/voxygen/voxel/sprite/velorite/velorite_4.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_4.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_4.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_5.vox b/assets/voxygen/voxel/sprite/velorite/velorite_5.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_5.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_5.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_6.vox b/assets/voxygen/voxel/sprite/velorite/velorite_6.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_6.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_6.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_7.vox b/assets/voxygen/voxel/sprite/velorite/velorite_7.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_7.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_7.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_8.vox b/assets/voxygen/voxel/sprite/velorite/velorite_8.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_8.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_8.vox diff --git a/assets/voxygen/voxel/sprite/velorite_small/velorite_9.vox b/assets/voxygen/voxel/sprite/velorite/velorite_9.vox similarity index 100% rename from assets/voxygen/voxel/sprite/velorite_small/velorite_9.vox rename to assets/voxygen/voxel/sprite/velorite/velorite_9.vox diff --git a/common/src/comp/inventory/item.rs b/common/src/comp/inventory/item.rs index 2305318770..d83095d2ca 100644 --- a/common/src/comp/inventory/item.rs +++ b/common/src/comp/inventory/item.rs @@ -80,6 +80,7 @@ pub enum Consumable { Apple, Potion, Mushroom, + Velorite, } impl Consumable { @@ -88,6 +89,7 @@ impl Consumable { Consumable::Apple => "apple", Consumable::Potion => "potion", Consumable::Mushroom => "mushroom", + Consumable::Velorite => "velorite", } } } @@ -145,6 +147,7 @@ impl Item { match block.kind() { BlockKind::Apple => Some(Self::apple()), BlockKind::Mushroom => Some(Self::mushroom()), + BlockKind::Velorite => Some(Self::velorite()), _ => None, } } @@ -164,6 +167,13 @@ impl Item { effect: Effect::Health(10, comp::HealthSource::Item), } } + + pub fn velorite() -> Self { + Item::Consumable { + kind: Consumable::Mushroom, + effect: Effect::Xp(250), + } + } } impl Default for Item { diff --git a/common/src/comp/location.rs b/common/src/comp/location.rs new file mode 100644 index 0000000000..eeebf7ce4d --- /dev/null +++ b/common/src/comp/location.rs @@ -0,0 +1,22 @@ +use specs::{Component, FlaggedStorage}; +use specs_idvs::IDVStorage; +use vek::*; + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Waypoint { + pos: Vec3, +} + +impl Waypoint { + pub fn new(pos: Vec3) -> Self { + Self { pos } + } + + pub fn get_pos(&self) -> Vec3 { + self.pos + } +} + +impl Component for Waypoint { + type Storage = FlaggedStorage>; +} diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index b6e1d4dcbe..fb04b9f253 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -6,6 +6,7 @@ mod controller; mod inputs; mod inventory; mod last; +mod location; mod phys; mod player; mod stats; @@ -20,7 +21,8 @@ pub use controller::{ControlEvent, Controller, MountState, Mounting}; pub use inputs::CanBuild; pub use inventory::{item, Inventory, InventoryUpdate, Item}; pub use last::Last; -pub use phys::{ForceUpdate, Ori, PhysicsState, Pos, Scale, Vel}; +pub use location::Waypoint; +pub use phys::{ForceUpdate, Mass, Ori, PhysicsState, Pos, Scale, Vel}; pub use player::Player; pub use stats::{Equipment, Exp, HealthSource, Level, Stats}; pub use visual::LightEmitter; diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index db6bd2447b..eb22625800 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -34,6 +34,14 @@ impl Component for Scale { type Storage = FlaggedStorage>; } +// Mass +#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct Mass(pub f32); + +impl Component for Mass { + type Storage = FlaggedStorage>; +} + // PhysicsState #[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct PhysicsState { diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index 54c3591f07..2b129023a3 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -29,6 +29,7 @@ sphynx::sum_type! { Scale(comp::Scale), MountState(comp::MountState), Mounting(comp::Mounting), + Mass(comp::Mass), } } // Automatically derive From for EcsCompPhantom @@ -48,6 +49,7 @@ sphynx::sum_type! { Scale(PhantomData), MountState(PhantomData), Mounting(PhantomData), + Mass(PhantomData), } } impl sphynx::CompPacket for EcsCompPacket { diff --git a/common/src/state.rs b/common/src/state.rs index fb800002a4..488bd91a06 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -131,6 +131,7 @@ impl State { ecs.register_synced::(); ecs.register_synced::(); ecs.register_synced::(); + ecs.register_synced::(); // Register components send from clients -> server ecs.register::(); @@ -155,6 +156,7 @@ impl State { ecs.register::(); ecs.register::(); ecs.register::(); + ecs.register::(); // Register synced resources used by the ECS. ecs.insert_synced(TimeOfDay(0.0)); diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index b7047acc38..e63234a5c1 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -1,6 +1,6 @@ use { crate::{ - comp::{Body, Mounting, Ori, PhysicsState, Pos, Scale, Vel}, + comp::{Body, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Vel}, event::{EventBus, LocalEvent}, state::DeltaTime, terrain::{Block, TerrainGrid}, @@ -45,6 +45,7 @@ impl<'a> System<'a> for Sys { Read<'a, DeltaTime>, Read<'a, EventBus>, ReadStorage<'a, Scale>, + ReadStorage<'a, Mass>, ReadStorage<'a, Body>, WriteStorage<'a, PhysicsState>, WriteStorage<'a, Pos>, @@ -61,6 +62,7 @@ impl<'a> System<'a> for Sys { dt, event_bus, scales, + masses, bodies, mut physics_states, mut positions, @@ -320,9 +322,10 @@ impl<'a> System<'a> for Sys { } // Apply pushback - for (pos, scale, vel, _, _) in ( + for (pos, scale, mass, vel, _, _) in ( &positions, scales.maybe(), + masses.maybe(), &mut velocities, &bodies, !&mountings, @@ -330,10 +333,18 @@ impl<'a> System<'a> for Sys { .join() { let scale = scale.map(|s| s.0).unwrap_or(1.0); - for (pos_other, scale_other, _, _) in - (&positions, scales.maybe(), &bodies, !&mountings).join() + let mass = mass.map(|m| m.0).unwrap_or(scale); + for (pos_other, scale_other, mass_other, _, _) in ( + &positions, + scales.maybe(), + masses.maybe(), + &bodies, + !&mountings, + ) + .join() { let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0); + let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other); let diff = Vec2::::from(pos.0 - pos_other.0); let collision_dist = 0.95 * (scale + scale_other); @@ -343,8 +354,9 @@ impl<'a> System<'a> for Sys { && pos.0.z + 1.6 * scale > pos_other.0.z && pos.0.z < pos_other.0.z + 1.6 * scale_other { - vel.0 += - Vec3::from(diff.normalized()) * (collision_dist - diff.magnitude()) * 1.0; + let force = (collision_dist - diff.magnitude()) * 2.0 * mass_other + / (mass + mass_other); + vel.0 += Vec3::from(diff.normalized()) * force; } } } diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index f2b19361ee..d5ae62fbd9 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -29,6 +29,7 @@ pub enum BlockKind { Apple, Mushroom, Liana, + Velorite, } impl BlockKind { @@ -61,6 +62,7 @@ impl BlockKind { BlockKind::Apple => true, BlockKind::Mushroom => true, BlockKind::Liana => true, + BlockKind::Velorite => true, _ => false, } } @@ -95,6 +97,7 @@ impl BlockKind { BlockKind::Apple => false, BlockKind::Mushroom => false, BlockKind::Liana => false, + BlockKind::Velorite => false, _ => true, } } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index df5cbe63d7..c6d3c02322 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -189,14 +189,21 @@ lazy_static! { "explosion", "{}", "/explosion : Explodes the ground around you", - false, + true, handle_explosion, ), + ChatCommand::new( + "waypoint", + "{}", + "/waypoint : Set your waypoint to your current position", + true, + handle_waypoint, + ), ChatCommand::new( "adminify", "{}", "/adminify : Temporarily gives a player admin permissions or removes them", - true, + false, // TODO: NO handle_adminify, ), ChatCommand::new( @@ -757,6 +764,25 @@ fn handle_explosion(server: &mut Server, entity: EcsEntity, args: String, action } } +fn handle_waypoint(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) { + match server.state.read_component_cloned::(entity) { + Some(pos) => { + let _ = server + .state + .ecs() + .write_storage::() + .insert(entity, comp::Waypoint::new(pos.0)); + server + .clients + .notify(entity, ServerMsg::private(String::from("Waypoint set!"))); + } + None => server.clients.notify( + entity, + ServerMsg::private(String::from("You have no position!")), + ), + } +} + fn handle_adminify(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { if let Ok(alias) = scan_fmt!(&args, action.arg_fmt, String) { let ecs = server.state.ecs(); diff --git a/server/src/lib.rs b/server/src/lib.rs index 2a286db8f2..cb48ea2b29 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -356,6 +356,11 @@ impl Server { ServerEvent::Respawn(entity) => { // Only clients can respawn if let Some(client) = clients.get_mut(&entity) { + let respawn_point = state + .read_component_cloned::(entity) + .map(|wp| wp.get_pos()) + .unwrap_or(state.ecs().read_resource::().0); + client.allow_state(ClientState::Character); state .ecs_mut() @@ -366,7 +371,7 @@ impl Server { .ecs_mut() .write_storage::() .get_mut(entity) - .map(|pos| pos.0.z += 20.0); + .map(|pos| pos.0 = respawn_point); let _ = state .ecs_mut() .write_storage() diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 46915fd864..b1c8b94d6c 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -108,7 +108,7 @@ impl FigureMgr { .and_then(|stats| stats.health.last_change) .map(|(_, time, _)| { Rgba::broadcast(1.0) - + Rgba::new(1.0, 1.0, 1.0, 0.0) + + Rgba::new(2.0, 2.0, 2.0, 0.0) .map(|c| (c / (1.0 + DAMAGE_FADE_COEFFICIENT * time)) as f32) }) .unwrap_or(Rgba::broadcast(1.0)); diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 2dde8e58bc..3279193000 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -131,6 +131,10 @@ fn sprite_config_for(kind: BlockKind) -> Option { variations: 2, wind_sway: 0.05, }), + BlockKind::Velorite => Some(SpriteConfig { + variations: 1, + wind_sway: 0.0, + }), _ => None, } } @@ -596,6 +600,13 @@ impl Terrain { Vec3::new(-1.0, -0.5, -55.0), ), ), + ( + (BlockKind::Velorite, 0), + make_model( + "voxygen.voxel.sprite.velorite.velorite", + Vec3::new(-5.0, -5.0, -0.0), + ), + ), ] .into_iter() .collect(), diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 7482575993..a435d58eb9 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -315,6 +315,14 @@ impl<'a> BlockGen<'a> { }, Rgb::broadcast(0), )) + } else if (wposf.z as f32) < height + 0.9 + && chaos > 0.6 + && (wposf.z as f32 > water_height + 3.0) + && marble > 0.75 + && marble_small > 0.5 + && (marble * 7323.07).fract() < 0.75 + { + Some(Block::new(BlockKind::Velorite, Rgb::broadcast(0))) } else { None }