mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added view distance configuration
Former-commit-id: b3c7a21631ce0c6b058f25aede0e3e2895a16f81
This commit is contained in:
parent
0349461533
commit
3508e4afcb
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,6 +17,7 @@
|
||||
# Veloren
|
||||
voxygen/keybinds.toml
|
||||
settings.toml
|
||||
voxygen/settings/
|
||||
*.rar
|
||||
*.log
|
||||
run.sh
|
||||
|
@ -44,7 +44,7 @@ pub struct Client {
|
||||
tick: u64,
|
||||
state: State,
|
||||
entity: EcsEntity,
|
||||
view_distance: u64,
|
||||
view_distance: Option<u32>,
|
||||
|
||||
pending_chunks: HashMap<Vec2<i32>, Instant>,
|
||||
}
|
||||
@ -52,7 +52,7 @@ pub struct Client {
|
||||
impl Client {
|
||||
/// Create a new `Client`.
|
||||
#[allow(dead_code)]
|
||||
pub fn new<A: Into<SocketAddr>>(addr: A, view_distance: u64) -> Result<Self, Error> {
|
||||
pub fn new<A: Into<SocketAddr>>(addr: A, view_distance: Option<u32>) -> Result<Self, Error> {
|
||||
let mut client_state = Some(ClientState::Connected);
|
||||
let mut postbox = PostBox::to(addr)?;
|
||||
|
||||
@ -94,6 +94,12 @@ impl Client {
|
||||
self.postbox.send_message(ClientMsg::Register { player });
|
||||
}
|
||||
|
||||
pub fn set_view_distance(&mut self, view_distance: u32) {
|
||||
self.view_distance = Some(view_distance.max(5).min(25));
|
||||
self.postbox
|
||||
.send_message(ClientMsg::SetViewDistance(self.view_distance.unwrap())); // Can't fail
|
||||
}
|
||||
|
||||
/// Get a reference to the client's worker thread pool. This pool should be used for any
|
||||
/// computationally expensive operations that run outside of the main thread (i.e., threads that
|
||||
/// block on I/O operations are exempt).
|
||||
@ -198,16 +204,16 @@ impl Client {
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(self.entity)
|
||||
.cloned();
|
||||
if let Some(pos) = pos {
|
||||
if let (Some(pos), Some(view_distance)) = (pos, self.view_distance) {
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
|
||||
// Remove chunks that are too far from the player.
|
||||
let mut chunks_to_remove = Vec::new();
|
||||
self.state.terrain().iter().for_each(|(key, _)| {
|
||||
if (Vec2::from(chunk_pos) - Vec2::from(key))
|
||||
.map(|e: i32| e.abs())
|
||||
.map(|e: i32| e.abs() as u32)
|
||||
.reduce_max()
|
||||
> 10
|
||||
> view_distance
|
||||
{
|
||||
chunks_to_remove.push(key);
|
||||
}
|
||||
@ -218,7 +224,7 @@ impl Client {
|
||||
|
||||
// Request chunks from the server.
|
||||
// TODO: This is really inefficient.
|
||||
'outer: for dist in 0..10 {
|
||||
'outer: for dist in 0..view_distance as i32 {
|
||||
for i in chunk_pos.x - dist..chunk_pos.x + dist + 1 {
|
||||
for j in chunk_pos.y - dist..chunk_pos.y + dist + 1 {
|
||||
let key = Vec2::new(i, j);
|
||||
|
@ -3,11 +3,15 @@ use specs::{Component, FlaggedStorage, VecStorage};
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Player {
|
||||
pub alias: String,
|
||||
pub view_distance: Option<u32>,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn new(alias: String) -> Self {
|
||||
Self { alias }
|
||||
pub fn new(alias: String, view_distance: Option<u32>) -> Self {
|
||||
Self {
|
||||
alias,
|
||||
view_distance,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ pub enum ClientMsg {
|
||||
body: comp::Body,
|
||||
},
|
||||
RequestState(ClientState),
|
||||
SetViewDistance(u32),
|
||||
Ping,
|
||||
Pong,
|
||||
Chat(String),
|
||||
|
@ -135,9 +135,14 @@ fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
|
||||
fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
|
||||
let opt_alias = scan_fmt!(&args, action.arg_fmt, String);
|
||||
match opt_alias {
|
||||
Some(alias) => server
|
||||
.state
|
||||
.write_component(entity, comp::player::Player { alias }),
|
||||
Some(alias) => {
|
||||
server
|
||||
.state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Player>()
|
||||
.get_mut(entity)
|
||||
.map(|player| player.alias = alias);
|
||||
}
|
||||
None => server
|
||||
.clients
|
||||
.notify(entity, ServerMsg::Chat(String::from(action.help_string))),
|
||||
|
@ -198,9 +198,9 @@ impl Server {
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
let dist = (Vec2::from(chunk_pos) - Vec2::from(key))
|
||||
.map(|e: i32| e.abs())
|
||||
.reduce_max();
|
||||
.reduce_max() as u32;
|
||||
|
||||
if dist < 10 {
|
||||
if player.view_distance.map(|vd| dist < vd).unwrap_or(false) {
|
||||
self.clients.notify(
|
||||
entity,
|
||||
ServerMsg::TerrainChunkUpdate {
|
||||
@ -218,10 +218,10 @@ impl Server {
|
||||
// Remove chunks that are too far from players.
|
||||
let mut chunks_to_remove = Vec::new();
|
||||
self.state.terrain().iter().for_each(|(key, _)| {
|
||||
let mut min_dist = i32::MAX;
|
||||
let mut should_drop = true;
|
||||
|
||||
// For each player with a position, calculate the distance.
|
||||
for (_, pos) in (
|
||||
for (player, pos) in (
|
||||
&self.state.ecs().read_storage::<comp::Player>(),
|
||||
&self.state.ecs().read_storage::<comp::phys::Pos>(),
|
||||
)
|
||||
@ -229,12 +229,15 @@ impl Server {
|
||||
{
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
let dist = Vec2::from(chunk_pos - key)
|
||||
.map(|e: i32| e.abs())
|
||||
.map(|e: i32| e.abs() as u32)
|
||||
.reduce_max();
|
||||
min_dist = min_dist.min(dist);
|
||||
|
||||
if player.view_distance.map(|vd| dist <= vd).unwrap_or(false) {
|
||||
should_drop = false;
|
||||
}
|
||||
}
|
||||
|
||||
if min_dist > 10 {
|
||||
if should_drop {
|
||||
chunks_to_remove.push(key);
|
||||
}
|
||||
});
|
||||
@ -340,6 +343,16 @@ impl Server {
|
||||
// Use RequestState instead (No need to send `player` again).
|
||||
_ => client.error_state(RequestStateError::Impossible),
|
||||
},
|
||||
ClientMsg::SetViewDistance(view_distance) => match client.client_state {
|
||||
ClientState::Character { .. } => {
|
||||
state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Player>()
|
||||
.get_mut(entity)
|
||||
.map(|player| player.view_distance = Some(view_distance));
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
ClientMsg::Character { name, body } => match client.client_state {
|
||||
// Become Registered first.
|
||||
ClientState::Connected => {
|
||||
|
@ -90,7 +90,7 @@ font_ids! {
|
||||
|
||||
pub enum Event {
|
||||
SendMessage(String),
|
||||
AdjustVd(u8),
|
||||
AdjustViewDistance(u32),
|
||||
Logout,
|
||||
Quit,
|
||||
}
|
||||
@ -209,7 +209,7 @@ pub struct Hud {
|
||||
settings: Settings,
|
||||
force_ungrab: bool,
|
||||
// TODO: move to settings
|
||||
current_vd: u8,
|
||||
current_vd: u32,
|
||||
}
|
||||
|
||||
impl Hud {
|
||||
@ -386,9 +386,9 @@ impl Hud {
|
||||
}
|
||||
settings_window::Event::ToggleDebug => self.show.debug = !self.show.debug,
|
||||
settings_window::Event::Close => self.show.open_windows = Windows::None,
|
||||
settings_window::Event::AdjustVd(new_vd) => {
|
||||
self.current_vd = new_vd;
|
||||
events.push(Event::AdjustVd(new_vd));
|
||||
settings_window::Event::AdjustViewDistance(view_distance) => {
|
||||
self.current_vd = view_distance;
|
||||
events.push(Event::AdjustViewDistance(view_distance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,14 +62,14 @@ pub struct SettingsWindow<'a> {
|
||||
imgs: &'a Imgs,
|
||||
fonts: &'a Fonts,
|
||||
|
||||
current_vd: u8,
|
||||
current_vd: u32,
|
||||
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
}
|
||||
|
||||
impl<'a> SettingsWindow<'a> {
|
||||
pub fn new(show: &'a Show, imgs: &'a Imgs, fonts: &'a Fonts, current_vd: u8) -> Self {
|
||||
pub fn new(show: &'a Show, imgs: &'a Imgs, fonts: &'a Fonts, current_vd: u32) -> Self {
|
||||
Self {
|
||||
show,
|
||||
imgs,
|
||||
@ -91,7 +91,7 @@ pub enum Event {
|
||||
ToggleInventoryTestButton,
|
||||
ToggleDebug,
|
||||
Close,
|
||||
AdjustVd(u8),
|
||||
AdjustViewDistance(u32),
|
||||
}
|
||||
|
||||
impl<'a> Widget for SettingsWindow<'a> {
|
||||
@ -489,7 +489,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
||||
.pad_track((5.0, 5.0))
|
||||
.set(state.ids.vd_slider, ui)
|
||||
{
|
||||
events.push(Event::AdjustVd(new_val));
|
||||
events.push(Event::AdjustViewDistance(new_val as u32));
|
||||
}
|
||||
}
|
||||
// 5 Sound
|
||||
|
@ -24,13 +24,8 @@ pub struct ClientInit {
|
||||
rx: Receiver<Result<Client, Error>>,
|
||||
}
|
||||
impl ClientInit {
|
||||
pub fn new(
|
||||
connection_args: (String, u16, bool),
|
||||
client_args: (comp::Player, u64),
|
||||
wait: bool,
|
||||
) -> Self {
|
||||
pub fn new(connection_args: (String, u16, bool), player: comp::Player, wait: bool) -> Self {
|
||||
let (server_address, default_port, prefer_ipv6) = connection_args;
|
||||
let (player, view_distance) = client_args;
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
@ -53,7 +48,7 @@ impl ClientInit {
|
||||
let mut last_err = None;
|
||||
|
||||
for socket_addr in first_addrs.into_iter().chain(second_addrs) {
|
||||
match Client::new(socket_addr, view_distance) {
|
||||
match Client::new(socket_addr, player.view_distance) {
|
||||
Ok(mut client) => {
|
||||
client.register(player);
|
||||
let _ = tx.send(Ok(client));
|
||||
|
@ -106,7 +106,7 @@ impl PlayState for MainMenuState {
|
||||
// Don't try to connect if there is already a connection in progress.
|
||||
client_init = client_init.or(Some(ClientInit::new(
|
||||
(server_address, DEFAULT_PORT, false),
|
||||
(comp::Player::new(username.clone()), 300),
|
||||
comp::Player::new(username.clone(), Some(10)),
|
||||
false,
|
||||
)));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ impl PlayState for StartSingleplayerState {
|
||||
|
||||
let client_init = ClientInit::new(
|
||||
(server_address.clone(), self.sock.port(), false),
|
||||
(comp::Player::new(username.clone()), 300),
|
||||
comp::Player::new(username.clone(), Some(10)),
|
||||
true,
|
||||
);
|
||||
|
||||
|
@ -190,9 +190,8 @@ impl PlayState for SessionState {
|
||||
HudEvent::Quit => {
|
||||
return PlayStateResult::Shutdown;
|
||||
}
|
||||
HudEvent::AdjustVd(new_vd) => {
|
||||
println!("New VD is {}, TODO: Actually change VD", new_vd);
|
||||
//self.client.borrow_mut().set_vd(new_vd);
|
||||
HudEvent::AdjustViewDistance(view_distance) => {
|
||||
self.client.borrow_mut().set_view_distance(view_distance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,6 +216,8 @@ pub enum Event {
|
||||
KeyUp(Key),
|
||||
/// Event that the ui uses.
|
||||
Ui(ui::Event),
|
||||
// The view distance has been changed
|
||||
ViewDistanceChanged(u32),
|
||||
/// Game settings have changed.
|
||||
SettingsChanged,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user