diff --git a/Makefile b/Makefile index b8836cd..dff0d92 100644 --- a/Makefile +++ b/Makefile @@ -20,4 +20,10 @@ fmt: fix: fmt cargo fix --allow-dirty --allow-staged -.phony: run-pi clean check run fmt fix lint \ No newline at end of file +docs: + cargo doc + +open-docs: + cargo doc --open + +.phony: run-pi clean check run fmt fix lint docs open-docs \ No newline at end of file diff --git a/src/ai.rs b/src/ai.rs index 9a93bed..3b1c2fe 100644 --- a/src/ai.rs +++ b/src/ai.rs @@ -1,3 +1,5 @@ +//! Systems for making NPCs come to life + mod adjacent_ai_system; mod approach_ai_system; mod chase_ai_system; diff --git a/src/camera.rs b/src/camera.rs index 2e6b539..4437f04 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,11 +1,14 @@ +//! Handle rendering of the viewport use ::rltk::{Point, Rltk}; use ::specs::prelude::*; use crate::map::tile_glyph; use crate::{colors, Hidden, Map, Position, Renderable}; +/// Whether to render an outline of the current map's boundaries const SHOW_BOUNDARIES: bool = false; +/// Get the rectangle representing the current viewport pub fn get_screen_bounds(ecs: &World, _ctx: &mut Rltk) -> (i32, i32, i32, i32) { let player_pos = ecs.fetch::(); // let (x_chars, y_chars) = ctx.get_char_size(); @@ -22,6 +25,7 @@ pub fn get_screen_bounds(ecs: &World, _ctx: &mut Rltk) -> (i32, i32, i32, i32) { (min_x, max_x, min_y, max_y) } +/// Render the current viewport pub fn render_camera(ecs: &World, ctx: &mut Rltk) { let map = ecs.fetch::(); let (min_x, max_x, min_y, max_y) = get_screen_bounds(ecs, ctx); diff --git a/src/effects.rs b/src/effects.rs index 3f4fae0..9c37a06 100644 --- a/src/effects.rs +++ b/src/effects.rs @@ -15,9 +15,11 @@ pub use targeting::*; use crate::spatial; lazy_static! { + /// The shared queue of effects pub static ref EFFECT_QUEUE: Mutex> = Mutex::new(VecDeque::new()); } +/// The kind of effect to cause pub enum EffectType { Damage { amount: i32, @@ -51,8 +53,8 @@ pub enum EffectType { }, } +/// Who, or what the effect should affect. #[derive(Clone)] -#[allow(dead_code)] pub enum Targets { Single { target: Entity }, TargetList { targets: Vec }, @@ -60,12 +62,14 @@ pub enum Targets { Tiles { tiles: Vec }, } +/// An effect for the queue pub struct EffectSpawner { pub creator: Option, pub effect_type: EffectType, pub targets: Targets, } +/// Adds an effect to the queue pub fn add_effect(creator: Option, effect_type: EffectType, targets: Targets) { EFFECT_QUEUE.lock().unwrap().push_back(EffectSpawner { creator, diff --git a/src/game_log.rs b/src/game_log.rs index d598d2a..771ebe7 100644 --- a/src/game_log.rs +++ b/src/game_log.rs @@ -1,9 +1,12 @@ +/// A struct to hold the player's game log. #[derive(Default)] pub struct GameLog { pub entries: Vec, } impl GameLog { + /// Convenience constructor that adds the first + /// entry to the game log. pub fn new(first_entry: S) -> Self { let mut log = GameLog::default(); log.append(first_entry); @@ -11,6 +14,10 @@ impl GameLog { log } + /// Convenience method for adding an entry to the game log. + /// Generic on the [`ToString`] trait so that [`&str`], [`String`], + /// and `&String` types, all work without more type juggling + /// at the call site. pub fn append(&mut self, s: S) { self.entries.push(s.to_string()); } diff --git a/src/main.rs b/src/main.rs index a5a7da7..e816aa2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +//! Roguelike +//! +//! An implementation of a rogue-like dungeon-crawler game. #[macro_use] extern crate lazy_static; @@ -40,6 +43,21 @@ pub use rect::Rect; pub use state::*; /// Cut down on the amount of syntax to register components +/// +/// Compare: +/// ```ignore +/// let mut game_state = State::new(); +/// +/// register!(state <- ComponentA, ComponentB, ...); +/// ``` +/// +/// Without macro: +/// ```ignore +/// let mut game_state = State::new(); +/// +/// state.ecs.register::(); +/// state.ecs.register::(); +/// ``` macro_rules! register { // $state is needed to get the scope at the usage point // $Type is the Component type that is being registered @@ -50,6 +68,14 @@ macro_rules! register { } } +/// Sets up the game. +/// +/// * Creates the [`State`] object +/// * Registers [`components`](register!) +/// * Loads the dynamic game entities using the [`raws`](crate::raws::load_raws) module +/// * Generates the map builder environment +/// * Creates the [`Player`](crate::spawner::player) +/// * Generates the first [`map`](crate::state::State::generate_world_map) fn init_state() -> State { let mut state = State::new(); @@ -146,6 +172,7 @@ fn init_state() -> State { state } +/// The entry point fn main() -> ::rltk::BError { let context = ::rltk::RltkBuilder::simple(80, 60) .unwrap() diff --git a/src/map.rs b/src/map.rs index 5bd0223..cab399f 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,13 +1,13 @@ +//! An object to hold the state of the current level's map mod dungeon; mod themes; mod tiletype; use std::collections::HashSet; -use ::rltk::{Algorithm2D, BaseMap, Point, SmallVec}; +use ::rltk::{Algorithm2D, BaseMap, Point, SmallVec, RGB}; use ::serde::{Deserialize, Serialize}; pub use dungeon::*; -use rltk::RGB; pub use themes::*; pub use tiletype::{tile_opaque, tile_walkable, TileType}; @@ -30,6 +30,8 @@ pub struct Map { } impl Map { + /// Converts an `(x, y)` coordinate to the flat index within the + /// `Map`'s internal array. pub fn xy_idx(&self, x: i32, y: i32) -> usize { (y as usize * self.width as usize) + x as usize } @@ -83,7 +85,7 @@ impl BaseMap for Map { } fn get_available_exits(&self, idx: usize) -> SmallVec<[(usize, f32); 10]> { - let mut exits = rltk::SmallVec::new(); + let mut exits = SmallVec::new(); let x = idx as i32 % self.width; let y = idx as i32 / self.width; let w = self.width as usize; @@ -125,7 +127,7 @@ impl BaseMap for Map { let p1 = Point::new(idx1 % w, idx1 / w); let p2 = Point::new(idx2 % w, idx2 / w); - rltk::DistanceAlg::Pythagoras.distance2d(p1, p2) + ::rltk::DistanceAlg::Pythagoras.distance2d(p1, p2) } } diff --git a/src/map/dungeon.rs b/src/map/dungeon.rs index a745e13..6e199f7 100644 --- a/src/map/dungeon.rs +++ b/src/map/dungeon.rs @@ -1,3 +1,4 @@ +//! Functionality that is common to all the currently generated maps. use std::collections::{HashMap, HashSet}; use ::rltk::{Point, RandomNumberGenerator}; diff --git a/src/map/themes.rs b/src/map/themes.rs index bd2e279..165a194 100644 --- a/src/map/themes.rs +++ b/src/map/themes.rs @@ -1,3 +1,4 @@ +//! Different looks for the same set of [`TileType`]s use ::rltk::{to_cp437, FontCharType, RGB}; use super::{Map, TileType}; diff --git a/src/map/tiletype.rs b/src/map/tiletype.rs index 10ce6bb..18f2b32 100644 --- a/src/map/tiletype.rs +++ b/src/map/tiletype.rs @@ -1,5 +1,6 @@ use ::serde::{Deserialize, Serialize}; +/// The type of location for a specific square of a [`Map`](crate::map::Map) #[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)] pub enum TileType { Wall, @@ -17,6 +18,7 @@ pub enum TileType { Stalagmite, } +/// Can you go through this type of map tile? pub fn tile_walkable(tt: TileType) -> bool { matches!( tt, @@ -32,6 +34,7 @@ pub fn tile_walkable(tt: TileType) -> bool { ) } +/// Is it impossible to see through this type of map tile? pub fn tile_opaque(tt: TileType) -> bool { matches!( tt, @@ -39,6 +42,7 @@ pub fn tile_opaque(tt: TileType) -> bool { ) } +/// How difficult is it to cross this type of map tile? pub fn tile_cost(tt: TileType) -> f32 { match tt { TileType::Road => 0.8, diff --git a/src/rect.rs b/src/rect.rs index efe31cb..e101ba1 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -1,3 +1,4 @@ +//! Four points, one plane, 90° angles use ::serde::{Deserialize, Serialize}; #[derive(PartialEq, Copy, Clone, Serialize, Deserialize)] diff --git a/src/state.rs b/src/state.rs index 1c98f6f..d293302 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,3 +1,4 @@ +//! use ::rltk::{GameState, Point, Rltk}; use ::specs::prelude::*; @@ -21,8 +22,10 @@ use crate::trigger_system::TriggerSystem; use crate::visibility_system::VisibilitySystem; use crate::{ai, camera, damage_system, effects, saveload_system, spawner}; +/// Whether to show a visual representation of map generation pub const SHOW_MAPGEN_VISUALIZER: bool = false; +/// The main actions possible with a vendor #[derive(PartialEq, Copy, Clone)] pub enum VendorMode { Buy, @@ -30,6 +33,7 @@ pub enum VendorMode { } #[derive(PartialEq, Copy, Clone)] +/// The states for the game engine's state machine pub enum RunState { AwaitingInput, PreRun, @@ -203,6 +207,7 @@ impl State { } impl GameState for State { + /// The big, nasty, state machine handler fn tick(&mut self, ctx: &mut Rltk) { let mut newrunstate; {