@@ 54,6 54,8 @@ launch the game and the world should appear in the world list
| South | `J` |
| West | `H` |
| East | `L` |
+| rotate CCW | `<Shift>` and left mouse button |
+| rotate CW | `<Shift>` and right mouse button |
#### Camera movement
| Action | Key(s) / MouseButton |
@@ 78,7 80,7 @@ launch the game and the world should appear in the world list
| Page up | `<ArrowUp>` |
| Close Screen | `Q` or `<Escape>` |
-### Level Cration Screen
+### Level Creation Screen
| Action | Key(s) / MouseButton |
|--------|----------------------|
| Close Screen | `<Escape>` |
@@ 39,3 39,36 @@ pub enum Direction {
/// (bottom edge of screen)
South
}
+impl Direction {
+ /// tries to extract the direction from an angle
+ fn from_angle(deg: usize) -> Option<Self> {
+ if deg % 360 == 0 {
+ return Some(Self::North);
+ } else if deg % 270 == 0 {
+ return Some(Self::West);
+ } else if deg%180 == 0 {
+ return Some(Self::South);
+ } else if deg%90 == 0 {
+ return Some(Self::East);
+ }
+
+ None
+ }
+ /// converts the direction to an angle
+ fn to_angle(&self) -> usize {
+ match self {
+ Self::North => 360,
+ Self::West => 270,
+ Self::South => 180,
+ Self::East => 90
+ }
+ }
+ /// rotate counter clock wise
+ pub fn rotate_ccw(&self) -> Self {
+ Self::from_angle(self.to_angle() + 90).unwrap()
+ }
+ /// rotate clock wise
+ pub fn rotate_cw(&self) -> Self {
+ Self::from_angle(self.to_angle() - 90).unwrap()
+ }
+}
@@ 155,17 155,15 @@ impl World {
if let Some(dir) = get_data_dir() {
let json = World::serialize_json(self);
- let path = Path::new(&dir).join(name);
-
DirBuilder::new()
.recursive(true)
- .create(&path);
+ .create(Path::new(&dir)).unwrap();
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
- .open(path);
+ .open(Path::new(&dir).join(name));
if let Ok(file) = &mut file {
if file.write_all(json.as_bytes()).is_err() {
@@ 414,48 414,60 @@ impl GameComponent for BuildScreen {
// for a given pixel
let mut pos = Pos3::new(pos.x, pos.y, pos.z);
- if is_mouse_button_pressed(MouseButton::Right) {
- // if grid has only one block
- // the block can not be removed
- // because the palyer would not be able to place
- // new blocks if no block exists
- if world.grid.len() > 1 {
-
- // destroy block
- if let Some((block, _)) = world.destroy_block(&pos) {
- // transmit block destruction
- // if multiplayer mode enabled
- if let Some(mp) = &mut self.multiplayer {
- mp.perform_action(GameAction::RemoveBlock(pos.clone(), block));
+ if is_key_down(KeyCode::LeftShift) {
+ if let Some(block) = world.grid.get_mut(&pos) {
+ if is_mouse_button_pressed(MouseButton::Left) {
+ // rotate block CCW
+ block.1 = block.1.rotate_ccw();
+ } else if is_mouse_button_pressed(MouseButton::Right) {
+ // rotate block CW
+ block.1 = block.1.rotate_cw();
+ }
+ }
+ } else {
+ if is_mouse_button_pressed(MouseButton::Right) {
+ // if grid has only one block
+ // the block can not be removed
+ // because the palyer would not be able to place
+ // new blocks if no block exists
+ if world.grid.len() > 1 {
+
+ // destroy block
+ if let Some((block, _)) = world.destroy_block(&pos) {
+ // transmit block destruction
+ // if multiplayer mode enabled
+ if let Some(mp) = &mut self.multiplayer {
+ mp.perform_action(GameAction::RemoveBlock(pos.clone(), block));
+ }
}
}
}
- }
- if is_mouse_button_pressed(MouseButton::Left) {
- // place block
- let (x,y) = get_screen_coords(&pos, world.cam.scale, world.cam.center);
- let face = Face::from_xy(mx-x, my-y, world.cam.scale);
-
- match face.unwrap() {
- Face::Top => {
- pos.z+=1;
- },
- Face::Left => {
- pos.x+=1;
- },
- Face::Right => {
- pos.y+=1;
+ if is_mouse_button_pressed(MouseButton::Left) {
+ // place block
+ let (x,y) = get_screen_coords(&pos, world.cam.scale, world.cam.center);
+ let face = Face::from_xy(mx-x, my-y, world.cam.scale);
+
+ match face.unwrap() {
+ Face::Top => {
+ pos.z+=1;
+ },
+ Face::Left => {
+ pos.x+=1;
+ },
+ Face::Right => {
+ pos.y+=1;
+ }
}
- }
- if let Some(block) = &world.inventory.selected.clone() {
- if world.place_block(&pos, block.clone(), world.inventory.direction.clone()) {
+ if let Some(block) = &world.inventory.selected.clone() {
+ if world.place_block(&pos, block.clone(), world.inventory.direction.clone()) {
- // transmit block placement
- // if multiplayer mode enabled
- if let Some(mp) = &mut self.multiplayer {
- mp.perform_action(GameAction::PlaceBlock(pos, block.clone(), world.inventory.direction.clone()));
+ // transmit block placement
+ // if multiplayer mode enabled
+ if let Some(mp) = &mut self.multiplayer {
+ mp.perform_action(GameAction::PlaceBlock(pos, block.clone(), world.inventory.direction.clone()));
+ }
}
}
}
@@ 548,35 560,47 @@ impl GameComponent for BuildScreen {
}
}
+ } else {
+ // game has no world
+ if is_key_pressed(KeyCode::Q) || is_key_pressed(KeyCode::Escape) || is_key_pressed(KeyCode::I) {
+ return GameEvent::Quit;
+ }
}
- if let Some(mp) = &mut self.multiplayer {
- if let Some(task) = mp.get_next_task() {
- // match action
- // and perform neccesarry action
- match task {
- GameAction::RequestWorld => {
- if let Some(world) = &mut self.world {
- mp.perform_action(
- GameAction::TransmitWorld(world.clone()));
- }
- },
- GameAction::PlaceBlock(pos, block, dir) => {
- if let Some(world) = &mut self.world {
- // remove block from inventory
- world.place_block(&pos, block, dir);
- }
- },
- GameAction::RemoveBlock(pos, _block) => {
- if let Some(world) = &mut self.world {
- world.destroy_block(&pos);
- }
- },
- GameAction::TransmitWorld(world) => {
- self.upgrade(world);
- },
+
+ #[cfg(feature="multiplayer")]
+ {
+ // maybe user is waiting in lobby
+ // still check for p2p connections
+ if let Some(mp) = &mut self.multiplayer {
+ if let Some(task) = mp.get_next_task() {
+ // match action
+ // and perform neccesarry action
+ match task {
+ GameAction::RequestWorld => {
+ if let Some(world) = &mut self.world {
+ mp.perform_action(
+ GameAction::TransmitWorld(world.clone()));
+ }
+ },
+ GameAction::PlaceBlock(pos, block, dir) => {
+ if let Some(world) = &mut self.world {
+ // remove block from inventory
+ world.place_block(&pos, block, dir);
+ }
+ },
+ GameAction::RemoveBlock(pos, _block) => {
+ if let Some(world) = &mut self.world {
+ world.destroy_block(&pos);
+ }
+ },
+ GameAction::TransmitWorld(world) => {
+ self.upgrade(world);
+ },
+ }
}
}
}
+
GameEvent::None
}
}