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