Separate binary from game engine
This commit is contained in:
parent
73525db8dd
commit
4a8b791acb
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "roguelike_tutorial"
|
||||
name = "tim_rogue"
|
||||
version = "0.1.0"
|
||||
rust-version = "1.56"
|
||||
edition = "2021"
|
||||
|
2
Makefile
2
Makefile
@ -46,6 +46,6 @@ fix: $(call print-help, fix, Fixes some warnings, then runs the formatter)
|
||||
make fmt
|
||||
|
||||
docs: $(call print-help, docs, Generates code docs)
|
||||
cargo doc --features $(FEATURES)
|
||||
cargo doc --features $(FEATURES) --document-private-items
|
||||
|
||||
.phony: run-pi clean check run fmt fix lint docs build build-wasm check-wasm build-wasm-dev
|
@ -73,4 +73,6 @@ If you want to see what else you can run with Makefile, run `make help`. This wi
|
||||
* Added a macro to register components for `specs`, like was in the tutorial for saving/loading.
|
||||
* Game state machine is moved to `src/state.rs`
|
||||
* Colors (Bracket-lib `RGB` struct) have been converted to static values in `src/colors.rs`, to cut down on boilerplate and numbers of ways of generating color values.
|
||||
* All references to `rltk` have been converted to `bracket_lib`, as `rltk` was a facade in `bracket_lib`
|
||||
* All references to `rltk` have been converted to `bracket_lib`, as `rltk` was a facade in `bracket_lib`
|
||||
* Made the crate a library and binary, with the binary just starting and running the game engine
|
||||
* Submodules use named files as the module base, rather than `mod.rs`
|
@ -10,6 +10,7 @@ use std::collections::{HashSet, VecDeque};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::specs::prelude::*;
|
||||
pub use targeting::*;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::lazy_static::lazy_static;
|
||||
|
||||
lazy_static! {
|
||||
static ref EVENTS: Mutex<HashMap<String, i32>> = Mutex::new(HashMap::new());
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::lazy_static::lazy_static;
|
||||
|
||||
use super::LogFragment;
|
||||
use crate::colors;
|
||||
|
185
src/lib.rs
Normal file
185
src/lib.rs
Normal file
@ -0,0 +1,185 @@
|
||||
//! Roguelike
|
||||
//!
|
||||
//! An implementation of a rogue-like dungeon-crawler game.
|
||||
|
||||
mod colors;
|
||||
mod components;
|
||||
mod damage_system;
|
||||
mod effects;
|
||||
mod gamelog;
|
||||
mod gamesystem;
|
||||
mod gui;
|
||||
mod map;
|
||||
mod map_builders;
|
||||
mod player;
|
||||
mod random_table;
|
||||
pub mod raws;
|
||||
mod rect;
|
||||
mod rex_assets;
|
||||
mod rng;
|
||||
mod saveload_system;
|
||||
mod spatial;
|
||||
mod spawner;
|
||||
mod state;
|
||||
mod systems;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::specs::prelude::*;
|
||||
use ::specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
||||
use components::*;
|
||||
use map::*;
|
||||
use rect::Rect;
|
||||
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::<ComponentA>();
|
||||
/// state.ecs.register::<ComponentB>();
|
||||
/// ```
|
||||
macro_rules! register {
|
||||
// $state is needed to get the scope at the usage point
|
||||
// $Type is the Component type that is being registered
|
||||
($state: ident <- $( $Type: ty ),*,) => {
|
||||
$(
|
||||
$state.ecs.register::<$Type>();
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Register the Component Structs with Specs
|
||||
fn register_components() -> State {
|
||||
let mut state = State::new();
|
||||
|
||||
register!(
|
||||
state <-
|
||||
AlwaysTargetsSelf,
|
||||
ApplyMove,
|
||||
ApplyTeleport,
|
||||
AreaOfEffect,
|
||||
AttributeBonus,
|
||||
Attributes,
|
||||
BlocksTile,
|
||||
BlocksVisibility,
|
||||
Chasing,
|
||||
Confusion,
|
||||
Consumable,
|
||||
CursedItem,
|
||||
DamageOverTime,
|
||||
DMSerializationHelper,
|
||||
Door,
|
||||
Duration,
|
||||
EntityMoved,
|
||||
EntryTrigger,
|
||||
EquipmentChanged,
|
||||
Equippable,
|
||||
Equipped,
|
||||
Faction,
|
||||
Hidden,
|
||||
HungerClock,
|
||||
IdentifiedItem,
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
Initiative,
|
||||
Item,
|
||||
KnownSpells,
|
||||
LightSource,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
MagicMapper,
|
||||
MoveMode,
|
||||
MyTurn,
|
||||
Name,
|
||||
NaturalAttackDefense,
|
||||
ObfuscatedName,
|
||||
OnDeath,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
Pools,
|
||||
Position,
|
||||
ProvidesFood,
|
||||
ProvidesHealing,
|
||||
ProvidesIdentification,
|
||||
ProvidesMana,
|
||||
ProvidesRemoveCurse,
|
||||
Quips,
|
||||
Ranged,
|
||||
Renderable,
|
||||
SerializationHelper,
|
||||
SimpleMarker<SerializeMe>,
|
||||
SingleActivation,
|
||||
Skills,
|
||||
Slow,
|
||||
SpawnParticleBurst,
|
||||
SpawnParticleLine,
|
||||
SpecialAbilities,
|
||||
SpellTemplate,
|
||||
StatusEffect,
|
||||
Target,
|
||||
TeachesSpell,
|
||||
TeleportTo,
|
||||
TileSize,
|
||||
TownPortal,
|
||||
Vendor,
|
||||
Viewshed,
|
||||
WantsToApproach,
|
||||
WantsToCastSpell,
|
||||
WantsToDropItem,
|
||||
WantsToFlee,
|
||||
WantsToMelee,
|
||||
WantsToPickupItem,
|
||||
WantsToRemoveItem,
|
||||
WantsToShoot,
|
||||
WantsToUseItem,
|
||||
Weapon,
|
||||
Wearable,
|
||||
);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
/// 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)
|
||||
pub fn init_state() -> State {
|
||||
use systems::particle_system::ParticleBuilder;
|
||||
|
||||
let mut state = register_components();
|
||||
|
||||
state
|
||||
.ecs
|
||||
.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||
|
||||
raws::load_raws();
|
||||
|
||||
state.ecs.insert(MasterDungeonMap::new());
|
||||
state.ecs.insert(Map::new(1, 64, 64, "New Map"));
|
||||
state.ecs.insert(Point::zero());
|
||||
|
||||
let player_entity = spawner::player(&mut state.ecs, 0, 0);
|
||||
state.ecs.insert(player_entity);
|
||||
|
||||
state.ecs.insert(RunState::MapGeneration {});
|
||||
state.ecs.insert(ParticleBuilder::new());
|
||||
state.ecs.insert(rex_assets::RexAssets::new());
|
||||
|
||||
state.generate_world_map(1, 0);
|
||||
|
||||
state
|
||||
}
|
186
src/main.rs
186
src/main.rs
@ -1,188 +1,4 @@
|
||||
//! Roguelike
|
||||
//!
|
||||
//! An implementation of a rogue-like dungeon-crawler game.
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
mod colors;
|
||||
mod components;
|
||||
mod damage_system;
|
||||
mod effects;
|
||||
mod gamelog;
|
||||
mod gamesystem;
|
||||
mod gui;
|
||||
mod map;
|
||||
pub mod map_builders;
|
||||
mod player;
|
||||
mod random_table;
|
||||
mod raws;
|
||||
mod rect;
|
||||
mod rex_assets;
|
||||
mod rng;
|
||||
mod saveload_system;
|
||||
mod spatial;
|
||||
mod spawner;
|
||||
mod state;
|
||||
mod systems;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::specs::prelude::*;
|
||||
use ::specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
||||
use components::*;
|
||||
pub use map::*;
|
||||
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::<ComponentA>();
|
||||
/// state.ecs.register::<ComponentB>();
|
||||
/// ```
|
||||
macro_rules! register {
|
||||
// $state is needed to get the scope at the usage point
|
||||
// $Type is the Component type that is being registered
|
||||
($state: ident <- $( $Type: ty ),*,) => {
|
||||
$(
|
||||
$state.ecs.register::<$Type>();
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Register the Component Structs with Specs
|
||||
fn register_components(state: &mut State) {
|
||||
register!(
|
||||
state <-
|
||||
AlwaysTargetsSelf,
|
||||
ApplyMove,
|
||||
ApplyTeleport,
|
||||
AreaOfEffect,
|
||||
AttributeBonus,
|
||||
Attributes,
|
||||
BlocksTile,
|
||||
BlocksVisibility,
|
||||
Chasing,
|
||||
Confusion,
|
||||
Consumable,
|
||||
CursedItem,
|
||||
DamageOverTime,
|
||||
DMSerializationHelper,
|
||||
Door,
|
||||
Duration,
|
||||
EntityMoved,
|
||||
EntryTrigger,
|
||||
EquipmentChanged,
|
||||
Equippable,
|
||||
Equipped,
|
||||
Faction,
|
||||
Hidden,
|
||||
HungerClock,
|
||||
IdentifiedItem,
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
Initiative,
|
||||
Item,
|
||||
KnownSpells,
|
||||
LightSource,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
MagicMapper,
|
||||
MoveMode,
|
||||
MyTurn,
|
||||
Name,
|
||||
NaturalAttackDefense,
|
||||
ObfuscatedName,
|
||||
OnDeath,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
Pools,
|
||||
Position,
|
||||
ProvidesFood,
|
||||
ProvidesHealing,
|
||||
ProvidesIdentification,
|
||||
ProvidesMana,
|
||||
ProvidesRemoveCurse,
|
||||
Quips,
|
||||
Ranged,
|
||||
Renderable,
|
||||
SerializationHelper,
|
||||
SimpleMarker<SerializeMe>,
|
||||
SingleActivation,
|
||||
Skills,
|
||||
Slow,
|
||||
SpawnParticleBurst,
|
||||
SpawnParticleLine,
|
||||
SpecialAbilities,
|
||||
SpellTemplate,
|
||||
StatusEffect,
|
||||
Target,
|
||||
TeachesSpell,
|
||||
TeleportTo,
|
||||
TileSize,
|
||||
TownPortal,
|
||||
Vendor,
|
||||
Viewshed,
|
||||
WantsToApproach,
|
||||
WantsToCastSpell,
|
||||
WantsToDropItem,
|
||||
WantsToFlee,
|
||||
WantsToMelee,
|
||||
WantsToPickupItem,
|
||||
WantsToRemoveItem,
|
||||
WantsToShoot,
|
||||
WantsToUseItem,
|
||||
Weapon,
|
||||
Wearable,
|
||||
);
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
use systems::particle_system::ParticleBuilder;
|
||||
|
||||
let mut state = State::new();
|
||||
|
||||
register_components(&mut state);
|
||||
|
||||
state
|
||||
.ecs
|
||||
.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||
|
||||
raws::load_raws();
|
||||
|
||||
state.ecs.insert(MasterDungeonMap::new());
|
||||
state.ecs.insert(Map::new(1, 64, 64, "New Map"));
|
||||
state.ecs.insert(Point::zero());
|
||||
|
||||
let player_entity = spawner::player(&mut state.ecs, 0, 0);
|
||||
state.ecs.insert(player_entity);
|
||||
|
||||
state.ecs.insert(RunState::MapGeneration {});
|
||||
state.ecs.insert(ParticleBuilder::new());
|
||||
state.ecs.insert(rex_assets::RexAssets::new());
|
||||
|
||||
state.generate_world_map(1, 0);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
/// The entry point
|
||||
fn main() -> BError {
|
||||
@ -194,5 +10,5 @@ fn main() -> BError {
|
||||
.with_vsync(false)
|
||||
.build()?;
|
||||
|
||||
main_loop(context, init_state())
|
||||
main_loop(context, ::tim_rogue::init_state())
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ mod weapon_traits;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::serde::Deserialize;
|
||||
pub use faction_structs::*;
|
||||
use item_structs::*;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::regex::Regex;
|
||||
use ::specs::prelude::*;
|
||||
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
|
@ -1,6 +1,8 @@
|
||||
//! The random number generator, using a mutex to share the instance
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::bracket_lib::prelude::*;
|
||||
use ::lazy_static::lazy_static;
|
||||
|
||||
lazy_static! {
|
||||
static ref RNG: Mutex<RandomNumberGenerator> = Mutex::new(RandomNumberGenerator::new());
|
||||
@ -11,10 +13,12 @@ pub fn reseed(seed: u64) {
|
||||
*RNG.lock().unwrap() = RandomNumberGenerator::seeded(seed);
|
||||
}
|
||||
|
||||
/// Rolls `n` dice, with `die_type` sides
|
||||
pub fn roll_dice(n: i32, die_type: i32) -> i32 {
|
||||
RNG.lock().unwrap().roll_dice(n, die_type)
|
||||
}
|
||||
|
||||
/// Returns a number in the range given
|
||||
pub fn range(min: i32, max: i32) -> i32 {
|
||||
RNG.lock().unwrap().range(min, max)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use crate::{tile_walkable, Map, RunState};
|
||||
|
Loading…
Reference in New Issue
Block a user