1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use crate::{WorldDuration, WorldInstant, CHUNK_HEIGHT, CHUNK_WIDTH};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// Contains the map tiles, spawn points (if any), and player characters for a
/// limited area in the game.
///
/// Chunks are the main level of granularity within the game: each Chunk can be
/// updated independently, and when players move between chunks, they get
/// removed from one and added to the other, so that players are always in one
/// specific chunk.
#[derive(Clone, Serialize, Deserialize)]
pub struct Chunk {
/// The wall layer of this chunk. Walls block movement. The [Vec] contains
/// [CHUNK_WIDTH] × [CHUNK_HEIGHT] elements. The tile for coordinates X and
/// Y can be found at index `X + Y * CHUNK_WIDTH`. The value is [None] if
/// there's no wall at the given position.
pub walls: Vec<Option<TileIndex>>,
/// The floor layer of this chunk. The [Vec] contains [CHUNK_WIDTH] ×
/// [CHUNK_HEIGHT] elements. The tile for coordinates X and Y can be found
/// at index `X + Y * CHUNK_WIDTH`. The value is [None] if there's just
/// empty floor at the given position.
pub floors: Vec<Option<TileIndex>>,
/// The list of points in this Chunk where a player can be spawned when
/// they're initially added into the world.
pub spawns: Vec<Point>,
/// The player characters in this chunk.
pub pcs: HashMap<PcHandle, PlayerCharacter>,
}
impl Chunk {
/// Returns true if there's a wall at the given coordinates.
pub fn is_wall(&self, x: i32, y: i32) -> bool {
if x >= 0 && x < CHUNK_WIDTH as i32 && y >= 0 && y < CHUNK_HEIGHT as i32 {
self.walls[x as usize + y as usize * CHUNK_WIDTH].is_some()
} else {
false
}
}
}
/// An identifier for different looking tiles.
///
/// The inner value refers to the index of the sprite in the tileset, starting
/// from top-left, going row-by-row from left to right, up to down.
#[derive(Clone, Serialize, Deserialize)]
pub struct TileIndex(pub u32);
/// A randomly generated identifier that differentiates different player
/// characters.
///
/// One player character will retain the same PcHandle for their entire
/// lifetime.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PcHandle(pub u64);
/// Player character information, relative to the chunk the player is in.
#[derive(Clone, Serialize, Deserialize)]
pub struct PlayerCharacter {
/// The position of the player within the [Chunk] the player is in.
pub position: Point,
/// Information about the player's movement, [None] if they're not moving.
pub current_move: Option<MoveStatus>,
}
/// Information about a character moving from point A to B.
#[derive(Clone, Serialize, Deserialize)]
pub struct MoveStatus {
/// How many timesteps the move will take.
pub duration: WorldDuration,
/// The timestep during which the movement started.
pub start_frame: WorldInstant,
/// The point where the player was during the start of the move. May be
/// outside the bounds of the chunks, if the move originated from a
/// neighboring chunk.
pub from: Point,
/// The point where the player ends up as a result of the move.
pub to: Point,
}
/// Coordinates.
///
/// The inner values represent the X and Y coordinates, in that order.
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct Point(pub i32, pub i32);