refactor things out into functions
This commit is contained in:
parent
d7b162e68e
commit
4338bcff16
@ -1,13 +1,33 @@
|
|||||||
|
use super::vector3::Vector3;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::math::vector2::Vector2;
|
||||||
|
use num_traits::Euclid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::vector3::Vector3;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
/// Aka Block Position
|
/// Aka Block Position
|
||||||
pub struct WorldPosition(pub Vector3<i32>);
|
pub struct WorldPosition(pub Vector3<i32>);
|
||||||
|
|
||||||
|
impl WorldPosition {
|
||||||
|
pub fn chunk_and_chunk_relative_position(&self) -> (Vector2<i32>, Vector3<i32>) {
|
||||||
|
let (z_chunk, z_rem) = self.0.z.div_rem_euclid(&16);
|
||||||
|
let (x_chunk, x_rem) = self.0.x.div_rem_euclid(&16);
|
||||||
|
let chunk_coordinate = Vector2 {
|
||||||
|
x: x_chunk,
|
||||||
|
z: z_chunk,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Since we divide by 16 remnant can never exceed u8
|
||||||
|
let relative = Vector3 {
|
||||||
|
x: x_rem,
|
||||||
|
z: z_rem,
|
||||||
|
|
||||||
|
y: self.0.y,
|
||||||
|
};
|
||||||
|
(chunk_coordinate, relative)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Serialize for WorldPosition {
|
impl Serialize for WorldPosition {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y};
|
||||||
use derive_more::derive::{AsMut, AsRef, Display, Into};
|
use derive_more::derive::{AsMut, AsRef, Display, Into};
|
||||||
use num_traits::{PrimInt, Signed, Unsigned};
|
use num_traits::{PrimInt, Signed, Unsigned};
|
||||||
use pumpkin_core::math::vector2::Vector2;
|
use pumpkin_core::math::vector2::Vector2;
|
||||||
|
use pumpkin_core::math::vector3::Vector3;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y};
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
|
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
|
||||||
)]
|
)]
|
||||||
@ -130,3 +130,13 @@ impl ChunkRelativeXZBlockCoordinates {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Vector3<i32>> for ChunkRelativeBlockCoordinates {
|
||||||
|
fn from(value: Vector3<i32>) -> Self {
|
||||||
|
Self {
|
||||||
|
x: (value.x as u8).into(),
|
||||||
|
z: (value.z as u8).into(),
|
||||||
|
y: value.y.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::{
|
|||||||
client::Client,
|
client::Client,
|
||||||
entity::{player::Player, Entity},
|
entity::{player::Player, Entity},
|
||||||
};
|
};
|
||||||
use num_traits::{Euclid, ToPrimitive};
|
use num_traits::ToPrimitive;
|
||||||
use pumpkin_config::BasicConfiguration;
|
use pumpkin_config::BasicConfiguration;
|
||||||
use pumpkin_core::math::position::WorldPosition;
|
use pumpkin_core::math::position::WorldPosition;
|
||||||
use pumpkin_core::math::vector2::Vector2;
|
use pumpkin_core::math::vector2::Vector2;
|
||||||
@ -20,11 +20,12 @@ use pumpkin_protocol::{
|
|||||||
ClientPacket, VarInt,
|
ClientPacket, VarInt,
|
||||||
};
|
};
|
||||||
use pumpkin_world::block::BlockId;
|
use pumpkin_world::block::BlockId;
|
||||||
|
use pumpkin_world::chunk::ChunkData;
|
||||||
use pumpkin_world::coordinates::ChunkRelativeBlockCoordinates;
|
use pumpkin_world::coordinates::ChunkRelativeBlockCoordinates;
|
||||||
use pumpkin_world::level::Level;
|
use pumpkin_world::level::Level;
|
||||||
use scoreboard::Scoreboard;
|
use scoreboard::Scoreboard;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
use tokio::sync::{mpsc, RwLock};
|
||||||
|
|
||||||
pub mod scoreboard;
|
pub mod scoreboard;
|
||||||
|
|
||||||
@ -285,7 +286,7 @@ impl World {
|
|||||||
level.mark_chunk_as_newly_watched(chunks).await;
|
level.mark_chunk_as_newly_watched(chunks).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>, distance: i32) {
|
async fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>) {
|
||||||
if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
|
if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
log::info!(
|
log::info!(
|
||||||
"The connection with {} has closed before world chunks were spawned",
|
"The connection with {} has closed before world chunks were spawned",
|
||||||
@ -294,21 +295,10 @@ impl World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let inst = std::time::Instant::now();
|
let inst = std::time::Instant::now();
|
||||||
let (sender, mut chunk_receiver) = mpsc::channel(distance as usize);
|
let chunks = self.get_chunks(chunks).await;
|
||||||
let client_id = client.id;
|
|
||||||
|
|
||||||
{
|
|
||||||
let level = self.level.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
log::debug!("Spawned chunk fetcher for {}", client_id);
|
|
||||||
let level = level.lock().await;
|
|
||||||
level.fetch_chunks(&chunks, sender);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
log::debug!("Spawned chunk sender for {}", client_id);
|
for chunk_data in chunks {
|
||||||
while let Some(chunk_data) = chunk_receiver.recv().await {
|
|
||||||
let chunk_data = chunk_data.read().await;
|
let chunk_data = chunk_data.read().await;
|
||||||
let packet = CChunkData(&chunk_data);
|
let packet = CChunkData(&chunk_data);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@ -381,32 +371,32 @@ impl World {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
pub async fn set_block(&self, position: WorldPosition, block_id: BlockId) {
|
pub async fn set_block(&self, position: WorldPosition, block_id: BlockId) {
|
||||||
let (z_chunk, z_rem) = position.0.z.div_rem_euclid(&16);
|
let (chunk_coordinate, relative_coordinates) = position.chunk_and_chunk_relative_position();
|
||||||
let (x_chunk, x_rem) = position.0.x.div_rem_euclid(&16);
|
|
||||||
let chunk_coordinate = Vector2 {
|
|
||||||
x: x_chunk,
|
|
||||||
z: z_chunk,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Since we divide by 16 remnant can never exceed u8
|
// Since we divide by 16 remnant can never exceed u8
|
||||||
let relative = ChunkRelativeBlockCoordinates {
|
let relative = ChunkRelativeBlockCoordinates::from(relative_coordinates);
|
||||||
x: (x_rem as u8).into(),
|
|
||||||
z: (z_rem as u8).into(),
|
|
||||||
y: position.0.y.into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let chunk = self.get_chunks(vec![chunk_coordinate]).await[0].clone();
|
||||||
|
chunk.write().await.blocks.set_block(relative, block_id);
|
||||||
|
|
||||||
|
self.broadcast_packet_all(&CBlockUpdate::new(
|
||||||
|
&position,
|
||||||
|
i32::from(block_id.data).into(),
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_chunks(&self, chunks: Vec<Vector2<i32>>) -> Vec<Arc<RwLock<ChunkData>>> {
|
||||||
let (sender, mut receive) = mpsc::channel(1024);
|
let (sender, mut receive) = mpsc::channel(1024);
|
||||||
{
|
{
|
||||||
let level = self.level.clone();
|
let level = self.level.clone();
|
||||||
tokio::spawn(
|
tokio::spawn(async move { level.lock().await.fetch_chunks(&chunks, sender) });
|
||||||
async move { level.lock().await.fetch_chunks(&[chunk_coordinate], sender) },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if let Some(data) = receive.recv().await {
|
let mut received = vec![];
|
||||||
data.write().await.blocks.set_block(relative, block_id);
|
while let Some(chunk) = receive.recv().await {
|
||||||
self.broadcast_packet_all(&CBlockUpdate::new(&position, (block_id.data as i32).into()))
|
received.push(chunk);
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
received
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn break_block(&self, position: WorldPosition) {
|
pub async fn break_block(&self, position: WorldPosition) {
|
||||||
|
|||||||
@ -74,7 +74,9 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
|
|||||||
|
|
||||||
if !loading_chunks.is_empty() {
|
if !loading_chunks.is_empty() {
|
||||||
world.mark_chunks_as_watched(&loading_chunks).await;
|
world.mark_chunks_as_watched(&loading_chunks).await;
|
||||||
world.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance);
|
world
|
||||||
|
.spawn_world_chunks(player.client.clone(), loading_chunks)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unloading_chunks.is_empty() {
|
if !unloading_chunks.is_empty() {
|
||||||
@ -134,7 +136,8 @@ pub async fn update_position(player: &Player) {
|
|||||||
entity.world.mark_chunks_as_watched(&loading_chunks).await;
|
entity.world.mark_chunks_as_watched(&loading_chunks).await;
|
||||||
entity
|
entity
|
||||||
.world
|
.world
|
||||||
.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance);
|
.spawn_world_chunks(player.client.clone(), loading_chunks)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unloading_chunks.is_empty() {
|
if !unloading_chunks.is_empty() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user