mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added chunk deletion
Former-commit-id: 63c29e43c4dc28097aaf4e0ff72977c7db5cc28f
This commit is contained in:
parent
f136a63f69
commit
5e38eee8d4
@ -146,10 +146,8 @@ impl Client {
|
||||
// Handle new messages from the server
|
||||
frontend_events.append(&mut self.handle_new_messages()?);
|
||||
|
||||
self.state.terrain().iter().for_each(|(k, _)| {
|
||||
//println!("Chunk at {:?}", k);
|
||||
});
|
||||
|
||||
// Pass character control from frontend input to the player's entity
|
||||
// TODO: Only do this if the entity already has a Control component!
|
||||
self.state.write_component(
|
||||
self.entity,
|
||||
comp::Control {
|
||||
@ -186,16 +184,28 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
// Request chunks from the server
|
||||
if let Some(pos) = self
|
||||
let pos = self
|
||||
.state
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(self.entity)
|
||||
{
|
||||
.cloned();
|
||||
if let Some(pos) = pos {
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
|
||||
for i in chunk_pos.x - 1..chunk_pos.x + 1 {
|
||||
for j in chunk_pos.y - 1..chunk_pos.y + 1 {
|
||||
// Remove chunks that are too far from the player
|
||||
let mut chunks_to_remove = Vec::new();
|
||||
self.state.terrain().iter().for_each(|(k, _)| {
|
||||
if (chunk_pos - k).map(|e| e.abs()).reduce_max() > 3 {
|
||||
chunks_to_remove.push(k);
|
||||
}
|
||||
});
|
||||
for key in chunks_to_remove {
|
||||
self.state.remove_chunk(key);
|
||||
}
|
||||
|
||||
// Request chunks from the server
|
||||
for i in chunk_pos.x - 1..chunk_pos.x + 2 {
|
||||
for j in chunk_pos.y - 1..chunk_pos.y + 2 {
|
||||
for k in 0..2 {
|
||||
let key = Vec3::new(i, j, k);
|
||||
if self.state.terrain().get_key(key).is_none()
|
||||
|
@ -183,6 +183,17 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the chunk with the given key from this state's terrain, if it exists
|
||||
pub fn remove_chunk(&mut self, key: Vec3<i32>) {
|
||||
if self.ecs
|
||||
.write_resource::<TerrainMap>()
|
||||
.remove(key)
|
||||
.is_some()
|
||||
{
|
||||
self.changes.removed_chunks.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute a single tick, simulating the game state by the given duration.
|
||||
pub fn tick(&mut self, dt: Duration) {
|
||||
// Change the time accordingly
|
||||
|
@ -8,10 +8,20 @@ pub mod input;
|
||||
// Reexports
|
||||
pub use crate::{error::Error, input::Input};
|
||||
|
||||
use crate::{
|
||||
client::{Client, Clients},
|
||||
cmd::CHAT_COMMANDS,
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::SocketAddr,
|
||||
sync::mpsc,
|
||||
time::Duration,
|
||||
i32,
|
||||
};
|
||||
use specs::{
|
||||
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
|
||||
Entity as EcsEntity,
|
||||
};
|
||||
use threadpool::ThreadPool;
|
||||
use vek::*;
|
||||
use world::World;
|
||||
use common::{
|
||||
comp,
|
||||
comp::character::Animation,
|
||||
@ -20,14 +30,10 @@ use common::{
|
||||
state::{State, Uid},
|
||||
terrain::TerrainChunk,
|
||||
};
|
||||
use specs::{
|
||||
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
|
||||
Entity as EcsEntity,
|
||||
use crate::{
|
||||
client::{Client, Clients},
|
||||
cmd::CHAT_COMMANDS,
|
||||
};
|
||||
use std::{collections::HashSet, net::SocketAddr, sync::mpsc, time::Duration};
|
||||
use threadpool::ThreadPool;
|
||||
use vek::*;
|
||||
use world::World;
|
||||
|
||||
const CLIENT_TIMEOUT: f64 = 20.0; // Seconds
|
||||
|
||||
@ -187,9 +193,7 @@ impl Server {
|
||||
&self.state.ecs().entities(),
|
||||
&self.state.ecs().read_storage::<comp::Player>(),
|
||||
&self.state.ecs().read_storage::<comp::phys::Pos>(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
).join() {
|
||||
// TODO: Distance check
|
||||
// if self.state.terrain().key_pos(key)
|
||||
|
||||
@ -200,6 +204,30 @@ impl Server {
|
||||
}
|
||||
|
||||
self.state.insert_chunk(key, chunk);
|
||||
self.pending_chunks.remove(&key);
|
||||
}
|
||||
|
||||
// Remove chunks that are too far from players
|
||||
let mut chunks_to_remove = Vec::new();
|
||||
self.state.terrain().iter().for_each(|(k, _)| {
|
||||
let mut min_dist = i32::MAX;
|
||||
|
||||
// For each player with a position, calculate the distance
|
||||
for (_, pos) in (
|
||||
&self.state.ecs().read_storage::<comp::Player>(),
|
||||
&self.state.ecs().read_storage::<comp::phys::Pos>(),
|
||||
).join() {
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
let dist = (chunk_pos - k).map(|e| e.abs()).reduce_max();
|
||||
min_dist = min_dist.min(dist);
|
||||
}
|
||||
|
||||
if min_dist > 3 {
|
||||
chunks_to_remove.push(k);
|
||||
}
|
||||
});
|
||||
for key in chunks_to_remove {
|
||||
self.state.remove_chunk(key);
|
||||
}
|
||||
|
||||
// Synchronise clients with the new state of the world
|
||||
|
Loading…
Reference in New Issue
Block a user