Merge branch 'master' of https://gitlab.com/veloren/veloren into xvar/wgpu-egui

This commit is contained in:
Ben Wallis 2021-06-18 22:04:36 +01:00
commit 0cf42e9c84
67 changed files with 253 additions and 121 deletions

2
.gitattributes vendored
View File

@ -1,4 +1,6 @@
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.vox filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text

View File

@ -13,7 +13,7 @@ variables:
# https://docs.gitlab.com/ee/ci/yaml/#shallow-cloning
GIT_DEPTH: 3
GIT_CLEAN_FLAGS: -f
CACHE_IMAGE_TAG: 8490f4b9
CACHE_IMAGE_TAG: c6476744
default:
# https://docs.gitlab.com/ee/ci/pipelines/settings.html#auto-cancel-pending-pipelines

View File

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Entity-entity pushback is no longer applied in forced movement states like rolling and leaping.
- Updated audio library (rodio 0.13 -> 0.14).
- Improve entity-terrain physics performance by reducing the number of voxel lookups.
### Removed

7
Cargo.lock generated
View File

@ -713,6 +713,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "comma"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96677551532ffe910f470bd767a9a7daf9ba53b1f5532e0891dba6c735f692e5"
[[package]]
name = "concurrent-queue"
version = "1.2.2"
@ -6112,6 +6118,7 @@ dependencies = [
"bincode",
"bytemuck",
"chrono",
"comma",
"conrod_core",
"conrod_winit",
"copy_dir",

View File

@ -89,8 +89,27 @@ opt-level = 3
overflow-checks = false
debug-assertions = false
lto = true
debug = 1 # line tables so we can have useful backtraces
debug = false
panic = "abort" # don't need unwinding so we can skip including the landing pads for that
# line tables so we can have useful backtraces for in-house crates
[profile.release.package."veloren-network"]
debug = 1
[profile.release.package."veloren-network-protocol"]
debug = 1
[profile.release.package."veloren-common"]
debug = 1
[profile.release.package."veloren-common-systems"]
debug = 1
[profile.release.package."veloren-client"]
debug = 1
[profile.release.package."veloren-server"]
debug = 1
[profile.release.package."veloren-server-cli"]
debug = 1
[profile.release.package."veloren-voxygen"]
debug = 1
[profile.release.package."veloren-world"]
debug = 1
# used for cargo bench
[profile.bench]

View File

@ -831,6 +831,19 @@
],
threshold: 0.2,
),
Utterance(Angry, Alligator): (
files: [
"voxygen.audio.sfx.utterance.alligator_angry1",
"voxygen.audio.sfx.utterance.alligator_angry2",
],
threshold: 1.0,
),
Utterance(Angry, Antelope): (
files: [
"voxygen.audio.sfx.utterance.antelope_angry1",
],
threshold: 1.0,
),
Utterance(Angry, BipedLarge): (
files: [
"voxygen.audio.sfx.utterance.ogre_angry1",
@ -844,12 +857,6 @@
],
threshold: 1.0,
),
Utterance(Calm, Pig): (
files: [
"voxygen.audio.sfx.utterance.pig_calm1",
],
threshold: 1.0,
),
Utterance(Angry, Adlet): (
files: [
"voxygen.audio.sfx.utterance.adlet_angry1",
@ -857,16 +864,10 @@
],
threshold: 1.0,
),
Utterance(Angry, Alligator): (
Utterance(Angry, Pig): (
files: [
"voxygen.audio.sfx.utterance.alligator_angry1",
"voxygen.audio.sfx.utterance.alligator_angry2",
],
threshold: 1.0,
),
Utterance(Angry, Antelope): (
files: [
"voxygen.audio.sfx.utterance.antelope_angry1",
"voxygen.audio.sfx.utterance.pig_angry1",
"voxygen.audio.sfx.utterance.pig_angry2",
],
threshold: 1.0,
),
@ -889,6 +890,13 @@
],
threshold: 1.0,
),
Utterance(Calm, Cat): (
files: [
"voxygen.audio.sfx.utterance.cat_calm1",
"voxygen.audio.sfx.utterance.cat_calm2",
],
threshold: 1.0,
),
Utterance(Calm, Cow): (
files: [
"voxygen.audio.sfx.utterance.cow_calm1",
@ -897,6 +905,19 @@
],
threshold: 1.0,
),
Utterance(Calm, Goat): (
files: [
"voxygen.audio.sfx.utterance.goat_calm1",
],
threshold: 1.0,
),
Utterance(Calm, Pig): (
files: [
"voxygen.audio.sfx.utterance.pig_calm1",
"voxygen.audio.sfx.utterance.pig_calm2",
],
threshold: 1.0,
),
Utterance(Calm, Sheep): (
files: [
"voxygen.audio.sfx.utterance.sheep_calm1",
@ -922,6 +943,12 @@
],
threshold: 1.0,
),
Utterance(Hurt, BipedLarge): (
files: [
"voxygen.audio.sfx.utterance.ogre_hurt1",
],
threshold: 1.0,
),
Utterance(Hurt, HumanMale): (
files: [
"voxygen.audio.sfx.utterance.humanmale_hurt1",

BIN
assets/voxygen/audio/sfx/utterance/cat_calm1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/cat_calm2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/goat_calm1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/lion_hurt1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/ogre_hurt1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/pig_angry1.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/pig_angry2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/pig_calm2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/pig_calm3.ogg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/background/bg_1.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_1.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_10.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_10.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_11.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_11.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_12.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_12.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_13.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_13.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_2.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_2.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_3.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_3.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_4.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_4.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_5.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_5.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_6.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_6.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_7.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_7.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_8.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_8.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_9.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_9.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/background/bg_main.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/background/bg_main.png (Stored with Git LFS)

Binary file not shown.

View File

@ -808,9 +808,9 @@ impl Client {
//Only in game, terrain
ClientGeneral::TerrainChunkRequest { .. } => &mut self.terrain_stream,
//Always possible
ClientGeneral::ChatMsg(_) | ClientGeneral::Terminate => {
&mut self.general_stream
},
ClientGeneral::ChatMsg(_)
| ClientGeneral::Command(_, _)
| ClientGeneral::Terminate => &mut self.general_stream,
};
stream.send(msg)
},
@ -1370,6 +1370,11 @@ impl Client {
}
}
/// Send a command to the server.
pub fn send_command(&mut self, name: String, args: Vec<String>) {
self.send_msg(ClientGeneral::Command(name, args));
}
/// Remove all cached terrain
pub fn clear_terrain(&mut self) {
self.state.clear_terrain();

View File

@ -97,19 +97,20 @@ impl Image {
pub fn to_image(&self) -> Arc<DynamicImage> { Arc::clone(&self.0) }
}
pub struct PngLoader;
impl Loader<Image> for PngLoader {
fn load(content: Cow<[u8]>, _: &str) -> Result<Image, BoxedError> {
let format = image::ImageFormat::Png;
pub struct ImageLoader;
impl Loader<Image> for ImageLoader {
fn load(content: Cow<[u8]>, ext: &str) -> Result<Image, BoxedError> {
let format = image::ImageFormat::from_extension(ext)
.ok_or_else(|| format!("Invalid file extension {}", ext))?;
let image = image::load_from_memory_with_format(&content, format)?;
Ok(Image(Arc::new(image)))
}
}
impl Asset for Image {
type Loader = PngLoader;
type Loader = ImageLoader;
const EXTENSION: &'static str = "png";
const EXTENSIONS: &'static [&'static str] = &["png", "jpg"];
}
pub struct DotVoxAsset(pub DotVoxData);

View File

@ -55,7 +55,7 @@ fn main() {
// Check if git-lfs is working
if std::env::var("DISABLE_GIT_LFS_CHECK").is_err() && cfg!(not(feature = "no-assets")) {
let asset_path: PathBuf = ["..", "assets", "voxygen", "background", "bg_main.png"]
let asset_path: PathBuf = ["..", "assets", "voxygen", "background", "bg_main.jpg"]
.iter()
.collect();
let asset_file = match File::open(&asset_path) {

View File

@ -80,6 +80,7 @@ pub enum ClientGeneral {
},
//Always possible
ChatMsg(String),
Command(String, Vec<String>),
Terminate,
RequestPlayerPhysics {
server_authoritative: bool,
@ -129,7 +130,9 @@ impl ClientMsg {
c_type == ClientType::Game && presence.is_some()
},
//Always possible
ClientGeneral::ChatMsg(_) | ClientGeneral::Terminate => true,
ClientGeneral::ChatMsg(_)
| ClientGeneral::Command(_, _)
| ClientGeneral::Terminate => true,
}
},
ClientMsg::Ping(_) => true,

View File

@ -295,7 +295,11 @@ impl ChatCommand {
"Spawns an airship",
Some(Admin),
),
ChatCommand::Alias => cmd(vec![Any("name", Required)], "Change your alias", None),
ChatCommand::Alias => cmd(
vec![Any("name", Required)],
"Change your alias",
Some(Moderator),
),
ChatCommand::ApplyBuff => cmd(
vec![
Enum("buff", BUFFS.clone(), Required),

View File

@ -103,6 +103,9 @@ pub enum UtteranceKind {
Surprised,
Hurt,
Greeting,
/* Death,
* TODO: Wait for more post-death features (i.e. animiations) before implementing death
* sounds */
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -140,7 +140,7 @@ pub enum ServerEvent {
ClientDisconnect(EcsEntity, DisconnectReason),
ClientDisconnectWithoutPersistence(EcsEntity),
ChunkRequest(EcsEntity, Vec2<i32>),
ChatCmd(EcsEntity, String),
Command(EcsEntity, String, Vec<String>),
/// Send a chat message to the player from an npc or other player
Chat(comp::UnresolvedChatMsg),
Aura {

View File

@ -1283,11 +1283,22 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
near_iter.filter_map(move |(i, j, k)| {
let block_pos = pos.map(|e| e.floor() as i32) + Vec3::new(i, j, k);
// `near_iter` could be a few blocks too large due to being integer aligned and
// rounding up, so skip points outside of the tighter bounds before looking them
// up in the terrain (which incurs a hashmap cost for volgrids)
let player_aabb = Aabb {
min: pos + Vec3::new(-radius, -radius, z_range.start),
max: pos + Vec3::new(radius, radius, z_range.end),
};
let block_approx = Aabb {
min: block_pos.as_(),
max: block_pos.as_() + Vec3::new(1.0, 1.0, Block::MAX_HEIGHT),
};
if !player_aabb.collides_with_aabb(block_approx) {
return None;
}
if let Some(block) = terrain.get(block_pos).ok().copied().filter(hit) {
let player_aabb = Aabb {
min: pos + Vec3::new(-radius, -radius, z_range.start),
max: pos + Vec3::new(radius, radius, z_range.end),
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32) + Vec3::new(1.0, 1.0, height(&block)),

View File

@ -52,11 +52,15 @@ use scan_fmt::{scan_fmt, scan_fmt_some};
use tracing::{error, info, warn};
pub trait ChatCommandExt {
fn execute(&self, server: &mut Server, entity: EcsEntity, args: String);
fn execute(&self, server: &mut Server, entity: EcsEntity, args: Vec<String>);
}
impl ChatCommandExt for ChatCommand {
#[allow(clippy::needless_return)] // TODO: Pending review in #587
fn execute(&self, server: &mut Server, entity: EcsEntity, args: String) {
fn execute(&self, server: &mut Server, entity: EcsEntity, args: Vec<String>) {
// TODO: Pass arguments to commands as Vec<String>, not String, to support
// proper parsing.
let args = args.join(" ");
if let Err(err) = do_command(server, entity, entity, args, self) {
server.notify_client(
entity,
@ -101,6 +105,7 @@ fn do_command(
cmd.keyword()
));
}
let handler: CommandHandler = match cmd {
ChatCommand::Adminify => handle_adminify,
ChatCommand::Airship => handle_spawn_airship,

View File

@ -51,7 +51,7 @@ impl Server {
let mut frontend_events = Vec::new();
let mut requested_chunks = Vec::new();
let mut chat_commands = Vec::new();
let mut commands = Vec::new();
let mut chat_messages = Vec::new();
let events = self
@ -188,8 +188,8 @@ impl Server {
ServerEvent::ChunkRequest(entity, key) => {
requested_chunks.push((entity, key));
},
ServerEvent::ChatCmd(entity, cmd) => {
chat_commands.push((entity, cmd));
ServerEvent::Command(entity, name, args) => {
commands.push((entity, name, args));
},
ServerEvent::Chat(msg) => {
chat_messages.push(msg);
@ -229,8 +229,8 @@ impl Server {
self.generate_chunk(entity, key);
}
for (entity, cmd) in chat_commands {
self.process_chat_cmd(entity, cmd);
for (entity, name, args) in commands {
self.process_command(entity, name, args);
}
for msg in chat_messages {

View File

@ -983,16 +983,9 @@ impl Server {
);
}
fn process_chat_cmd(&mut self, entity: EcsEntity, cmd: String) {
// Separate string into keyword and arguments.
let sep = cmd.find(' ');
let (kwd, args) = match sep {
Some(i) => (cmd[..i].to_string(), cmd[(i + 1)..].to_string()),
None => (cmd, "".to_string()),
};
fn process_command(&mut self, entity: EcsEntity, name: String, args: Vec<String>) {
// Find the command object and run its handler.
if let Ok(command) = kwd.parse::<ChatCommand>() {
if let Ok(command) = name.parse::<ChatCommand>() {
command.execute(self, entity, args);
} else {
#[cfg(feature = "plugins")]
@ -1020,8 +1013,8 @@ impl Server {
let rs = plugin_manager.execute_event(
&ecs_world,
&plugin_api::event::ChatCommandEvent {
command: kwd.clone(),
command_args: args.split(' ').map(|x| x.to_owned()).collect(),
command: name.clone(),
command_args: args.clone(),
player: plugin_api::event::Player { id: uid },
},
);
@ -1035,7 +1028,7 @@ impl Server {
format!(
"Unknown command '/{}'.\nType '/help' for available \
commands",
kwd
name
),
),
);
@ -1059,7 +1052,7 @@ impl Server {
comp::ChatType::CommandError,
format!(
"Error occurred while executing command '/{}'.\n{}",
kwd, e
name, e
),
),
);
@ -1068,7 +1061,7 @@ impl Server {
}
},
Err(e) => {
error!(?e, "Can't execute command {} {}", kwd, args);
error!(?e, "Can't execute command {} {:?}", name, args);
self.notify_client(
entity,
ServerGeneral::server_msg(
@ -1076,7 +1069,7 @@ impl Server {
format!(
"Internal error while executing '/{}'.\nContact the server \
administrator",
kwd
name
),
),
);

View File

@ -29,12 +29,7 @@ impl Sys {
if player.is_some() {
match validate_chat_msg(&message) {
Ok(()) => {
if let Some(message) = message.strip_prefix('/') {
if !message.is_empty() {
let argv = String::from(message);
server_emitter.emit(ServerEvent::ChatCmd(entity, argv));
}
} else if let Some(from) = uids.get(entity) {
if let Some(from) = uids.get(entity) {
const CHAT_MODE_DEFAULT: &ChatMode = &ChatMode::default();
let mode = chat_modes.get(entity).unwrap_or(CHAT_MODE_DEFAULT);
// Send chat message
@ -52,6 +47,11 @@ impl Sys {
}
}
},
ClientGeneral::Command(name, args) => {
if player.is_some() {
server_emitter.emit(ServerEvent::Command(entity, name, args));
}
},
ClientGeneral::Terminate => {
debug!(?entity, "Client send message to terminate session");
server_emitter.emit(ServerEvent::ClientDisconnect(

View File

@ -89,6 +89,7 @@ backtrace = "0.3.40"
bincode = "1.3.1"
chrono = { version = "0.4.9", features = ["serde"] }
cpal = "0.13"
comma = "0.1"
copy_dir = "0.1.2"
crossbeam-utils = "0.8.1"
crossbeam-channel = "0.5"

View File

@ -207,6 +207,8 @@ pub enum VoiceKind {
Antelope,
Alligator,
Saurok,
Cat,
Goat,
}
fn body_to_voice(body: &Body) -> Option<VoiceKind> {
@ -223,6 +225,8 @@ fn body_to_voice(body: &Body) -> Option<VoiceKind> {
Body::QuadrupedSmall(body) => match body.species {
quadruped_small::Species::Sheep => VoiceKind::Sheep,
quadruped_small::Species::Pig | quadruped_small::Species::Boar => VoiceKind::Pig,
quadruped_small::Species::Cat => VoiceKind::Cat,
quadruped_small::Species::Goat => VoiceKind::Goat,
_ => VoiceKind::Critter,
},
Body::QuadrupedMedium(body) => match body.species {
@ -410,7 +414,7 @@ impl SfxMgr {
},
Outcome::GroundSlam { pos, .. } => {
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::GroundSlam);
audio.emit_sfx(sfx_trigger_item, *pos, Some(1.0), false);
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), false);
},
Outcome::ProjectileShot { pos, body, .. } => {
match body {

View File

@ -168,6 +168,7 @@ pub struct State {
pub enum Event {
TabCompletionStart(String),
SendMessage(String),
SendCommand(String, Vec<String>),
Focus(Id),
ChangeChatTab(Option<usize>),
ShowChatTabSettings(usize),
@ -645,7 +646,17 @@ impl<'a> Widget for Chat<'a> {
s.history.truncate(self.history_max);
}
});
events.push(Event::SendMessage(msg));
if let Some(msg) = msg.strip_prefix('/') {
match msg.parse::<comma::Command>() {
Ok(cmd) => events.push(Event::SendCommand(cmd.name, cmd.arguments)),
Err(err) => self.new_messages.push_back(ChatMsg {
chat_type: ChatType::CommandError,
message: err.to_string(),
}),
}
} else {
events.push(Event::SendMessage(msg));
}
}
events
}

View File

@ -359,6 +359,7 @@ pub struct HudInfo {
#[derive(Clone)]
pub enum Event {
SendMessage(String),
SendCommand(String, Vec<String>),
CharacterSelection,
UseSlot {
@ -2706,6 +2707,9 @@ impl Hud {
chat::Event::SendMessage(message) => {
events.push(Event::SendMessage(message));
},
chat::Event::SendCommand(name, args) => {
events.push(Event::SendCommand(name, args));
},
chat::Event::Focus(focus_id) => {
self.to_focus = Some(Some(focus_id));
},

View File

@ -22,6 +22,7 @@ pub enum Error {
mismatched_server_info: Option<ServerInfo>,
},
ClientCrashed,
ServerNotFound,
}
#[allow(clippy::large_enum_variant)] // TODO: Pending review in #587
@ -125,11 +126,10 @@ impl ClientInit {
tokio::time::sleep(Duration::from_secs(5)).await;
}
// Only possibility for no last_err is aborting
let _ = tx.send(Msg::Done(Err(last_err.unwrap_or(Error::ClientError {
error: ClientError::Other("Connection attempt aborted by user".to_owned()),
mismatched_server_info: None,
}))));
// Parsing/host name resolution successful but no connection succeeded
// If last_err is None this typically means there was no server up at the input
// address and all the attempts timed out.
let _ = tx.send(Msg::Done(Err(last_err.unwrap_or(Error::ServerNotFound))));
// Safe drop runtime
tokio::task::block_in_place(move || drop(runtime2));

View File

@ -435,6 +435,7 @@ fn get_client_msg_error(e: client_init::Error, localized_strings: &LocalizationH
},
},
InitError::ClientCrashed => localization.get("main.login.client_crashed").into(),
InitError::ServerNotFound => localization.get("main.login.server_not_found").into(),
}
}

View File

@ -1041,6 +1041,9 @@ impl PlayState for SessionState {
// TODO: Handle result
self.client.borrow_mut().send_chat(msg);
},
HudEvent::SendCommand(name, args) => {
self.client.borrow_mut().send_command(name, args);
},
HudEvent::CharacterSelection => {
self.client.borrow_mut().request_remove_character()
},