mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add LoD zone data to char select screen
This commit is contained in:
parent
5d4133eea5
commit
5bc60f2436
@ -242,6 +242,7 @@ pub struct Client {
|
|||||||
available_recipes: HashMap<String, Option<SpriteKind>>,
|
available_recipes: HashMap<String, Option<SpriteKind>>,
|
||||||
lod_zones: HashMap<Vec2<i32>, lod::Zone>,
|
lod_zones: HashMap<Vec2<i32>, lod::Zone>,
|
||||||
lod_last_requested: Option<Instant>,
|
lod_last_requested: Option<Instant>,
|
||||||
|
lod_pos_fallback: Option<Vec2<f32>>,
|
||||||
force_update_counter: u64,
|
force_update_counter: u64,
|
||||||
|
|
||||||
max_group_size: u32,
|
max_group_size: u32,
|
||||||
@ -753,6 +754,7 @@ impl Client {
|
|||||||
|
|
||||||
lod_zones: HashMap::new(),
|
lod_zones: HashMap::new(),
|
||||||
lod_last_requested: None,
|
lod_last_requested: None,
|
||||||
|
lod_pos_fallback: None,
|
||||||
|
|
||||||
force_update_counter: 0,
|
force_update_counter: 0,
|
||||||
|
|
||||||
@ -890,7 +892,7 @@ impl Client {
|
|||||||
| ClientGeneral::DeleteCharacter(_)
|
| ClientGeneral::DeleteCharacter(_)
|
||||||
| ClientGeneral::Character(_, _)
|
| ClientGeneral::Character(_, _)
|
||||||
| ClientGeneral::Spectate(_) => &mut self.character_screen_stream,
|
| ClientGeneral::Spectate(_) => &mut self.character_screen_stream,
|
||||||
//Only in game
|
// Only in game
|
||||||
ClientGeneral::ControllerInputs(_)
|
ClientGeneral::ControllerInputs(_)
|
||||||
| ClientGeneral::ControlEvent(_)
|
| ClientGeneral::ControlEvent(_)
|
||||||
| ClientGeneral::ControlAction(_)
|
| ClientGeneral::ControlAction(_)
|
||||||
@ -911,7 +913,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
&mut self.in_game_stream
|
&mut self.in_game_stream
|
||||||
},
|
},
|
||||||
//Only in game, terrain
|
// Terrain
|
||||||
ClientGeneral::TerrainChunkRequest { .. }
|
ClientGeneral::TerrainChunkRequest { .. }
|
||||||
| ClientGeneral::LodZoneRequest { .. } => {
|
| ClientGeneral::LodZoneRequest { .. } => {
|
||||||
#[cfg(feature = "tracy")]
|
#[cfg(feature = "tracy")]
|
||||||
@ -920,7 +922,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
&mut self.terrain_stream
|
&mut self.terrain_stream
|
||||||
},
|
},
|
||||||
//Always possible
|
// Always possible
|
||||||
ClientGeneral::ChatMsg(_)
|
ClientGeneral::ChatMsg(_)
|
||||||
| ClientGeneral::Command(_, _)
|
| ClientGeneral::Command(_, _)
|
||||||
| ClientGeneral::Terminate => &mut self.general_stream,
|
| ClientGeneral::Terminate => &mut self.general_stream,
|
||||||
@ -1196,6 +1198,10 @@ impl Client {
|
|||||||
|
|
||||||
pub fn lod_zones(&self) -> &HashMap<Vec2<i32>, lod::Zone> { &self.lod_zones }
|
pub fn lod_zones(&self) -> &HashMap<Vec2<i32>, lod::Zone> { &self.lod_zones }
|
||||||
|
|
||||||
|
/// Set the fallback position used for loading LoD zones when the client
|
||||||
|
/// entity does not have a position.
|
||||||
|
pub fn set_lod_pos_fallback(&mut self, pos: Vec2<f32>) { self.lod_pos_fallback = Some(pos); }
|
||||||
|
|
||||||
/// Returns whether the specified recipe can be crafted and the sprite, if
|
/// Returns whether the specified recipe can be crafted and the sprite, if
|
||||||
/// any, that is required to do so.
|
/// any, that is required to do so.
|
||||||
pub fn can_craft_recipe(&self, recipe: &str, amount: u32) -> (bool, Option<SpriteKind>) {
|
pub fn can_craft_recipe(&self, recipe: &str, amount: u32) -> (bool, Option<SpriteKind>) {
|
||||||
@ -2088,9 +2094,11 @@ impl Client {
|
|||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
self.pending_chunks
|
self.pending_chunks
|
||||||
.retain(|_, created| now.duration_since(*created) < Duration::from_secs(3));
|
.retain(|_, created| now.duration_since(*created) < Duration::from_secs(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(lod_pos) = pos.map(|p| p.0.xy()).or(self.lod_pos_fallback) {
|
||||||
// Manage LoD zones
|
// Manage LoD zones
|
||||||
let lod_zone = pos.0.xy().map(|e| lod::from_wpos(e as i32));
|
let lod_zone = lod_pos.map(|e| lod::from_wpos(e as i32));
|
||||||
|
|
||||||
// Request LoD zones that are in range
|
// Request LoD zones that are in range
|
||||||
if self
|
if self
|
||||||
|
@ -128,7 +128,6 @@ impl ClientMsg {
|
|||||||
| ClientGeneral::ExitInGame
|
| ClientGeneral::ExitInGame
|
||||||
| ClientGeneral::PlayerPhysics { .. }
|
| ClientGeneral::PlayerPhysics { .. }
|
||||||
| ClientGeneral::TerrainChunkRequest { .. }
|
| ClientGeneral::TerrainChunkRequest { .. }
|
||||||
| ClientGeneral::LodZoneRequest { .. }
|
|
||||||
| ClientGeneral::UnlockSkill(_)
|
| ClientGeneral::UnlockSkill(_)
|
||||||
| ClientGeneral::RequestSiteInfo(_)
|
| ClientGeneral::RequestSiteInfo(_)
|
||||||
| ClientGeneral::RequestPlayerPhysics { .. }
|
| ClientGeneral::RequestPlayerPhysics { .. }
|
||||||
@ -140,7 +139,9 @@ impl ClientMsg {
|
|||||||
//Always possible
|
//Always possible
|
||||||
ClientGeneral::ChatMsg(_)
|
ClientGeneral::ChatMsg(_)
|
||||||
| ClientGeneral::Command(_, _)
|
| ClientGeneral::Command(_, _)
|
||||||
| ClientGeneral::Terminate => true,
|
| ClientGeneral::Terminate
|
||||||
|
// LodZoneRequest is required by the char select screen
|
||||||
|
| ClientGeneral::LodZoneRequest { .. } => true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientMsg::Ping(_) => true,
|
ClientMsg::Ping(_) => true,
|
||||||
|
@ -324,7 +324,6 @@ impl ServerMsg {
|
|||||||
| ServerGeneral::InventoryUpdate(_, _)
|
| ServerGeneral::InventoryUpdate(_, _)
|
||||||
| ServerGeneral::GroupInventoryUpdate(_, _, _)
|
| ServerGeneral::GroupInventoryUpdate(_, _, _)
|
||||||
| ServerGeneral::TerrainChunkUpdate { .. }
|
| ServerGeneral::TerrainChunkUpdate { .. }
|
||||||
| ServerGeneral::LodZoneUpdate { .. }
|
|
||||||
| ServerGeneral::TerrainBlockUpdates(_)
|
| ServerGeneral::TerrainBlockUpdates(_)
|
||||||
| ServerGeneral::SetViewDistance(_)
|
| ServerGeneral::SetViewDistance(_)
|
||||||
| ServerGeneral::Outcomes(_)
|
| ServerGeneral::Outcomes(_)
|
||||||
@ -348,7 +347,8 @@ impl ServerMsg {
|
|||||||
| ServerGeneral::CreateEntity(_)
|
| ServerGeneral::CreateEntity(_)
|
||||||
| ServerGeneral::DeleteEntity(_)
|
| ServerGeneral::DeleteEntity(_)
|
||||||
| ServerGeneral::Disconnect(_)
|
| ServerGeneral::Disconnect(_)
|
||||||
| ServerGeneral::Notification(_) => true,
|
| ServerGeneral::Notification(_)
|
||||||
|
| ServerGeneral::LodZoneUpdate { .. } => true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ServerMsg::Ping(_) => true,
|
ServerMsg::Ping(_) => true,
|
||||||
|
@ -192,7 +192,7 @@ impl Client {
|
|||||||
| ServerGeneral::SpectatePosition(_) => {
|
| ServerGeneral::SpectatePosition(_) => {
|
||||||
PreparedMsg::new(2, &g, &self.in_game_stream_params)
|
PreparedMsg::new(2, &g, &self.in_game_stream_params)
|
||||||
},
|
},
|
||||||
//In-game related, terrain
|
// Terrain
|
||||||
ServerGeneral::TerrainChunkUpdate { .. }
|
ServerGeneral::TerrainChunkUpdate { .. }
|
||||||
| ServerGeneral::LodZoneUpdate { .. }
|
| ServerGeneral::LodZoneUpdate { .. }
|
||||||
| ServerGeneral::TerrainBlockUpdates(_) => {
|
| ServerGeneral::TerrainBlockUpdates(_) => {
|
||||||
|
@ -61,61 +61,63 @@ impl<'a> System<'a> for Sys {
|
|||||||
|(chunk_send_emitter, server_emitter), (entity, client, maybe_presence)| {
|
|(chunk_send_emitter, server_emitter), (entity, client, maybe_presence)| {
|
||||||
let mut chunk_requests = Vec::new();
|
let mut chunk_requests = Vec::new();
|
||||||
let _ = super::try_recv_all(client, 5, |client, msg| {
|
let _ = super::try_recv_all(client, 5, |client, msg| {
|
||||||
let presence = match maybe_presence {
|
// SPECIAL CASE: LOD zone requests can be sent by non-present players
|
||||||
Some(g) => g,
|
if let ClientGeneral::LodZoneRequest { key } = &msg {
|
||||||
None => {
|
client.send(ServerGeneral::LodZoneUpdate {
|
||||||
debug!(?entity, "client is not in_game, ignoring msg");
|
key: *key,
|
||||||
trace!(?msg, "ignored msg content");
|
zone: lod.zone(*key).clone(),
|
||||||
if matches!(msg, ClientGeneral::TerrainChunkRequest { .. }) {
|
})?;
|
||||||
network_metrics.chunks_request_dropped.inc();
|
} else {
|
||||||
}
|
let presence = match maybe_presence {
|
||||||
return Ok(());
|
Some(g) => g,
|
||||||
},
|
None => {
|
||||||
};
|
debug!(?entity, "client is not in_game, ignoring msg");
|
||||||
match msg {
|
trace!(?msg, "ignored msg content");
|
||||||
ClientGeneral::TerrainChunkRequest { key } => {
|
if matches!(msg, ClientGeneral::TerrainChunkRequest { .. }) {
|
||||||
let in_vd = if let Some(pos) = positions.get(entity) {
|
network_metrics.chunks_request_dropped.inc();
|
||||||
pos.0.xy().map(|e| e as f64).distance_squared(
|
|
||||||
key.map(|e| e as f64 + 0.5)
|
|
||||||
* TerrainChunkSize::RECT_SIZE.map(|e| e as f64),
|
|
||||||
) < ((presence.terrain_view_distance.current() as f64 - 1.0
|
|
||||||
+ 2.5 * 2.0_f64.sqrt())
|
|
||||||
* TerrainChunkSize::RECT_SIZE.x as f64)
|
|
||||||
.powi(2)
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
if in_vd {
|
|
||||||
if terrain.get_key_arc(key).is_some() {
|
|
||||||
network_metrics.chunks_served_from_memory.inc();
|
|
||||||
chunk_send_emitter.emit(ChunkSendEntry {
|
|
||||||
chunk_key: key,
|
|
||||||
entity,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
network_metrics.chunks_generation_triggered.inc();
|
|
||||||
chunk_requests.push(ChunkRequest { entity, key });
|
|
||||||
}
|
}
|
||||||
} else {
|
return Ok(());
|
||||||
network_metrics.chunks_request_dropped.inc();
|
},
|
||||||
}
|
};
|
||||||
},
|
match msg {
|
||||||
ClientGeneral::LodZoneRequest { key } => {
|
ClientGeneral::TerrainChunkRequest { key } => {
|
||||||
client.send(ServerGeneral::LodZoneUpdate {
|
let in_vd = if let Some(pos) = positions.get(entity) {
|
||||||
key,
|
pos.0.xy().map(|e| e as f64).distance_squared(
|
||||||
zone: lod.zone(key).clone(),
|
key.map(|e| e as f64 + 0.5)
|
||||||
})?;
|
* TerrainChunkSize::RECT_SIZE.map(|e| e as f64),
|
||||||
},
|
) < ((presence.terrain_view_distance.current() as f64 - 1.0
|
||||||
_ => {
|
+ 2.5 * 2.0_f64.sqrt())
|
||||||
debug!(
|
* TerrainChunkSize::RECT_SIZE.x as f64)
|
||||||
"Kicking possibly misbehaving client due to invalud terrain \
|
.powi(2)
|
||||||
request"
|
} else {
|
||||||
);
|
true
|
||||||
server_emitter.emit(ServerEvent::ClientDisconnect(
|
};
|
||||||
entity,
|
if in_vd {
|
||||||
common::comp::DisconnectReason::NetworkError,
|
if terrain.get_key_arc(key).is_some() {
|
||||||
));
|
network_metrics.chunks_served_from_memory.inc();
|
||||||
},
|
chunk_send_emitter.emit(ChunkSendEntry {
|
||||||
|
chunk_key: key,
|
||||||
|
entity,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
network_metrics.chunks_generation_triggered.inc();
|
||||||
|
chunk_requests.push(ChunkRequest { entity, key });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
network_metrics.chunks_request_dropped.inc();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
debug!(
|
||||||
|
"Kicking possibly misbehaving client due to invalud terrain \
|
||||||
|
request"
|
||||||
|
);
|
||||||
|
server_emitter.emit(ServerEvent::ClientDisconnect(
|
||||||
|
entity,
|
||||||
|
common::comp::DisconnectReason::NetworkError,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,7 @@ impl CharSelectionState {
|
|||||||
pub fn new(global_state: &mut GlobalState, client: Rc<RefCell<Client>>) -> Self {
|
pub fn new(global_state: &mut GlobalState, client: Rc<RefCell<Client>>) -> Self {
|
||||||
let scene = Scene::new(
|
let scene = Scene::new(
|
||||||
global_state.window.renderer_mut(),
|
global_state.window.renderer_mut(),
|
||||||
&client.borrow(),
|
&mut client.borrow_mut(),
|
||||||
&global_state.settings,
|
&global_state.settings,
|
||||||
);
|
);
|
||||||
let char_selection_ui = CharSelectionUi::new(global_state, &client.borrow());
|
let char_selection_ui = CharSelectionUi::new(global_state, &client.borrow());
|
||||||
|
@ -96,7 +96,7 @@ pub struct SceneData<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
pub fn new(renderer: &mut Renderer, client: &Client, settings: &Settings) -> Self {
|
pub fn new(renderer: &mut Renderer, client: &mut Client, settings: &Settings) -> Self {
|
||||||
let start_angle = -90.0f32.to_radians();
|
let start_angle = -90.0f32.to_radians();
|
||||||
let resolution = renderer.resolution().map(|e| e as f32);
|
let resolution = renderer.resolution().map(|e| e as f32);
|
||||||
|
|
||||||
@ -132,6 +132,8 @@ impl Scene {
|
|||||||
.get(char_chunk)
|
.get(char_chunk)
|
||||||
.map_or(0.0, |z| *z as f32 + 100.0),
|
.map_or(0.0, |z| *z as f32 + 100.0),
|
||||||
);
|
);
|
||||||
|
client.set_lod_pos_fallback(char_pos.xy());
|
||||||
|
client.set_lod_distance(settings.graphics.lod_distance);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
|
Loading…
Reference in New Issue
Block a user