Allow pausing and clearing the conway example

This commit is contained in:
Ryan 2022-08-31 04:51:13 -07:00
parent 79399c153e
commit 6e0a7e0a88

View file

@ -29,6 +29,7 @@ pub fn main() -> ShutdownResult {
}, },
ServerState { ServerState {
player_list: None, player_list: None,
paused: false,
board: vec![false; SIZE_X * SIZE_Z].into_boxed_slice(), board: vec![false; SIZE_X * SIZE_Z].into_boxed_slice(),
board_buf: vec![false; SIZE_X * SIZE_Z].into_boxed_slice(), board_buf: vec![false; SIZE_X * SIZE_Z].into_boxed_slice(),
}, },
@ -41,10 +42,17 @@ struct Game {
struct ServerState { struct ServerState {
player_list: Option<PlayerListId>, player_list: Option<PlayerListId>,
paused: bool,
board: Box<[bool]>, board: Box<[bool]>,
board_buf: Box<[bool]>, board_buf: Box<[bool]>,
} }
#[derive(Default)]
struct ClientState {
entity_id: EntityId,
sneaking: bool,
}
const MAX_PLAYERS: usize = 10; const MAX_PLAYERS: usize = 10;
const SIZE_X: usize = 100; const SIZE_X: usize = 100;
@ -54,7 +62,7 @@ const BOARD_Y: i32 = 50;
#[async_trait] #[async_trait]
impl Config for Game { impl Config for Game {
type ServerState = ServerState; type ServerState = ServerState;
type ClientState = EntityId; type ClientState = ClientState;
type EntityState = (); type EntityState = ();
type WorldState = (); type WorldState = ();
type ChunkState = (); type ChunkState = ();
@ -114,6 +122,8 @@ impl Config for Game {
SIZE_Z as f64 / 2.0, SIZE_Z as f64 / 2.0,
]; ];
server.state.paused = false;
server.clients.retain(|_, client| { server.clients.retain(|_, client| {
if client.created_this_tick() { if client.created_this_tick() {
if self if self
@ -131,7 +141,7 @@ impl Config for Game {
.entities .entities
.insert_with_uuid(EntityKind::Player, client.uuid(), ()) .insert_with_uuid(EntityKind::Player, client.uuid(), ())
{ {
Some((id, _)) => client.state = id, Some((id, _)) => client.state.entity_id = id,
None => { None => {
client.disconnect("Conflicting UUID"); client.disconnect("Conflicting UUID");
return false; return false;
@ -155,43 +165,56 @@ impl Config for Game {
} }
client.send_message("Welcome to Conway's game of life in Minecraft!".italic()); client.send_message("Welcome to Conway's game of life in Minecraft!".italic());
client.send_message("Hold the left mouse button to bring blocks to life.".italic()); client.send_message(
"Sneak and hold the left mouse button to bring blocks to life.".italic(),
);
} }
if client.is_disconnected() { if client.is_disconnected() {
self.player_count.fetch_sub(1, Ordering::SeqCst); self.player_count.fetch_sub(1, Ordering::SeqCst);
server.entities.remove(client.state); server.entities.remove(client.state.entity_id);
if let Some(id) = &server.state.player_list { if let Some(id) = &server.state.player_list {
server.player_lists.get_mut(id).remove(client.uuid()); server.player_lists.get_mut(id).remove(client.uuid());
} }
return false; return false;
} }
let player = server.entities.get_mut(client.state).unwrap(); let player = server.entities.get_mut(client.state.entity_id).unwrap();
if client.position().y <= 0.0 { if client.position().y <= 0.0 {
client.teleport(spawn_pos, client.yaw(), client.pitch()); client.teleport(spawn_pos, client.yaw(), client.pitch());
server.state.board.fill(false);
} }
while let Some(event) = client_event_boilerplate(client, player) { while let Some(event) = client_event_boilerplate(client, player) {
if let ClientEvent::Digging { position, .. } = event { match event {
ClientEvent::Digging { position, .. } => {
if (0..SIZE_X as i32).contains(&position.x) if (0..SIZE_X as i32).contains(&position.x)
&& (0..SIZE_Z as i32).contains(&position.z) && (0..SIZE_Z as i32).contains(&position.z)
&& position.y == BOARD_Y && position.y == BOARD_Y
{ {
server.state.board[position.x as usize + position.z as usize * SIZE_X] = server.state.board
true; [position.x as usize + position.z as usize * SIZE_X] = true;
} }
} }
ClientEvent::StartSneaking => {
client.state.sneaking = true;
}
ClientEvent::StopSneaking => {
client.state.sneaking = false;
}
_ => {}
}
}
if client.state.sneaking {
server.state.paused = true;
} }
true true
}); });
if server.shared.current_tick() % 4 != 0 { if !server.state.paused {
return;
}
server server
.state .state
.board_buf .board_buf
@ -222,6 +245,7 @@ impl Config for Game {
}); });
mem::swap(&mut server.state.board, &mut server.state.board_buf); mem::swap(&mut server.state.board, &mut server.state.board_buf);
}
let min_y = server.shared.dimensions().next().unwrap().1.min_y; let min_y = server.shared.dimensions().next().unwrap().1.min_y;