mirror of
https://github.com/zyllian/classics.git
synced 2025-05-10 02:36:40 -07:00
implement server ticks, block updates, and classic fluid mechanics
This commit is contained in:
parent
8dc89d959e
commit
492da31ce0
6 changed files with 285 additions and 39 deletions
|
@ -5,10 +5,19 @@ use std::sync::Arc;
|
|||
|
||||
use tokio::{net::TcpListener, sync::RwLock};
|
||||
|
||||
use crate::{level::Level, player::Player};
|
||||
use crate::{
|
||||
level::{
|
||||
block::{BlockType, BLOCK_INFO},
|
||||
BlockUpdate, Level,
|
||||
},
|
||||
player::Player,
|
||||
util::neighbors_minus_up,
|
||||
};
|
||||
|
||||
use self::config::ServerConfig;
|
||||
|
||||
const TICK_DURATION: std::time::Duration = std::time::Duration::from_millis(50);
|
||||
|
||||
/// the server
|
||||
#[derive(Debug)]
|
||||
pub struct Server {
|
||||
|
@ -64,6 +73,10 @@ impl Server {
|
|||
|
||||
/// starts the server
|
||||
pub async fn run(&mut self) -> std::io::Result<()> {
|
||||
let data = self.data.clone();
|
||||
tokio::spawn(async move {
|
||||
handle_ticks(data).await;
|
||||
});
|
||||
loop {
|
||||
let (stream, addr) = self.listener.accept().await?;
|
||||
println!("connection from {addr}");
|
||||
|
@ -76,3 +89,85 @@ impl Server {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// function to tick the server
|
||||
async fn handle_ticks(data: Arc<RwLock<ServerData>>) {
|
||||
let mut current_tick = 0;
|
||||
loop {
|
||||
tick(&mut *data.write().await, current_tick);
|
||||
current_tick = current_tick.wrapping_add(1);
|
||||
tokio::time::sleep(TICK_DURATION).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// function which ticks the server once
|
||||
fn tick(data: &mut ServerData, tick: usize) {
|
||||
let level = &mut data.level;
|
||||
|
||||
let mut packets = level.apply_updates();
|
||||
|
||||
let awaiting_update = std::mem::take(&mut level.awaiting_update);
|
||||
if !awaiting_update.is_empty() {
|
||||
println!("hm");
|
||||
}
|
||||
for index in awaiting_update {
|
||||
let (x, y, z) = level.coordinates(index);
|
||||
let block_id = level.get_block(x, y, z);
|
||||
let block = BLOCK_INFO.get(&block_id).expect("should never fail");
|
||||
println!("{block:#?}");
|
||||
match &block.block_type {
|
||||
BlockType::FluidFlowing {
|
||||
stationary,
|
||||
ticks_to_spread,
|
||||
} => {
|
||||
if tick % ticks_to_spread == 0 {
|
||||
let update = BlockUpdate {
|
||||
index,
|
||||
block: *stationary,
|
||||
};
|
||||
level.updates.push(update);
|
||||
for (nx, ny, nz) in neighbors_minus_up(level, x, y, z) {
|
||||
let block_at = level.get_block(nx, ny, nz);
|
||||
let update = if block_at == 0 {
|
||||
level.awaiting_update.insert(level.index(nx, ny, nz));
|
||||
BlockUpdate {
|
||||
index: level.index(nx, ny, nz),
|
||||
block: block_id,
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
level.updates.push(update);
|
||||
}
|
||||
} else {
|
||||
level.awaiting_update.insert(index);
|
||||
}
|
||||
}
|
||||
BlockType::FluidStationary { moving } => {
|
||||
let mut needs_update = false;
|
||||
for (nx, ny, nz) in neighbors_minus_up(level, x, y, z) {
|
||||
if level.get_block(nx, ny, nz) == 0 {
|
||||
needs_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if needs_update {
|
||||
let index = level.index(x, y, z);
|
||||
level.updates.push(BlockUpdate {
|
||||
index,
|
||||
block: *moving,
|
||||
});
|
||||
level.awaiting_update.insert(index);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
packets.extend(level.apply_updates());
|
||||
for packet in packets {
|
||||
for player in &mut data.players {
|
||||
player.packets_to_send.push(packet.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue