WIP: 2.10
This commit is contained in:
parent
ecbecc1a58
commit
f2f4c40c28
@ -1,9 +1,11 @@
|
||||
use rltk::{Point, RGB};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::error::NoError;
|
||||
use specs::prelude::*;
|
||||
use specs::saveload::*;
|
||||
use specs::saveload::{ConvertSaveload, Marker};
|
||||
use specs_derive::*;
|
||||
|
||||
#[derive(Component, Clone, ConvertSaveload)]
|
||||
#[derive(Component, ConvertSaveload, Clone)]
|
||||
pub struct Position {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
@ -17,10 +19,10 @@ pub struct Renderable {
|
||||
pub render_order: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||
pub struct Player {}
|
||||
|
||||
#[derive(Component, Clone, ConvertSaveload)]
|
||||
#[derive(Component, ConvertSaveload, Clone)]
|
||||
pub struct Viewshed {
|
||||
pub visible_tiles: Vec<rltk::Point>,
|
||||
pub range: i32,
|
||||
@ -30,15 +32,15 @@ pub struct Viewshed {
|
||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||
pub struct Monster {}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct Name {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize)]
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct BlocksTile {}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct CombatStats {
|
||||
pub max_hp: i32,
|
||||
pub hp: i32,
|
||||
@ -46,12 +48,12 @@ pub struct CombatStats {
|
||||
pub power: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct WantsToMelee {
|
||||
pub target: Entity,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct SufferDamage {
|
||||
pub amount: Vec<i32>,
|
||||
}
|
||||
@ -69,15 +71,15 @@ impl SufferDamage {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize)]
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Item {}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct Potion {
|
||||
pub heal_amount: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct InBackpack {
|
||||
pub owner: Entity,
|
||||
}
|
||||
@ -88,7 +90,7 @@ pub struct WantsToPickupItem {
|
||||
pub item: Entity,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct WantsToUseItem {
|
||||
pub item: Entity,
|
||||
pub target: Option<Point>,
|
||||
@ -99,10 +101,10 @@ pub struct WantsToDropItem {
|
||||
pub item: Entity,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize)]
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Consumable {}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct ProvidesHealing {
|
||||
pub heal_amount: i32,
|
||||
}
|
||||
@ -117,19 +119,19 @@ pub struct InflictsDamage {
|
||||
pub damage: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct AreaOfEffect {
|
||||
pub radius: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload)]
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct Confusion {
|
||||
pub turns: i32,
|
||||
}
|
||||
|
||||
pub struct SerializeMe;
|
||||
|
||||
#[derive(Component, Clone, Serialize, Deserialize)]
|
||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||
pub struct SerializationHelper {
|
||||
pub map: super::map::Map,
|
||||
}
|
39
src/gui.rs
39
src/gui.rs
@ -1,14 +1,14 @@
|
||||
use rltk::Rltk;
|
||||
use rltk::RGB;
|
||||
use rltk::{Point, VirtualKeyCode};
|
||||
use rltk::RGB;
|
||||
use rltk::Rltk;
|
||||
use specs::prelude::*;
|
||||
|
||||
use crate::{CombatStats, InBackpack, RunState, State, Viewshed};
|
||||
use crate::gamelog::GameLog;
|
||||
use crate::Map;
|
||||
use crate::Name;
|
||||
use crate::Player;
|
||||
use crate::Position;
|
||||
use crate::{CombatStats, InBackpack, RunState, State, Viewshed};
|
||||
|
||||
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
||||
ctx.draw_box(
|
||||
@ -403,6 +403,7 @@ pub enum MainMenuResult {
|
||||
}
|
||||
|
||||
pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
||||
let save_exists = super::save_load_system::does_save_exist();
|
||||
let runstate = gs.ecs.fetch::<RunState>();
|
||||
|
||||
ctx.print_color_centered(
|
||||
@ -412,6 +413,7 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
||||
"Rust Roguelike Tutorial",
|
||||
);
|
||||
|
||||
|
||||
if let RunState::MainMenu {
|
||||
menu_selection: selection,
|
||||
} = *runstate
|
||||
@ -432,22 +434,25 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
||||
);
|
||||
}
|
||||
|
||||
if selection == MainMenuSelection::LoadGame {
|
||||
ctx.print_color_centered(
|
||||
25,
|
||||
RGB::named(rltk::MAGENTA),
|
||||
RGB::named(rltk::BLACK),
|
||||
"Load Game",
|
||||
);
|
||||
} else {
|
||||
ctx.print_color_centered(
|
||||
25,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::BLACK),
|
||||
"Load Game",
|
||||
);
|
||||
if save_exists {
|
||||
if selection == MainMenuSelection::LoadGame {
|
||||
ctx.print_color_centered(
|
||||
25,
|
||||
RGB::named(rltk::MAGENTA),
|
||||
RGB::named(rltk::BLACK),
|
||||
"Load Game",
|
||||
);
|
||||
} else {
|
||||
ctx.print_color_centered(
|
||||
25,
|
||||
RGB::named(rltk::WHITE),
|
||||
RGB::named(rltk::BLACK),
|
||||
"Load Game",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if selection == MainMenuSelection::Quit {
|
||||
ctx.print_color_centered(
|
||||
26,
|
||||
|
24
src/main.rs
24
src/main.rs
@ -206,7 +206,11 @@ impl GameState for State {
|
||||
}
|
||||
gui::MainMenuResult::Selected { selected } => match selected {
|
||||
gui::MainMenuSelection::NewGame => new_run_state = RunState::PreRun,
|
||||
gui::MainMenuSelection::LoadGame => new_run_state = RunState::PreRun,
|
||||
gui::MainMenuSelection::LoadGame => {
|
||||
save_load_system::load_game(&mut self.ecs);
|
||||
new_run_state = RunState::AwaitingInput;
|
||||
save_load_system::delete_save();
|
||||
}
|
||||
gui::MainMenuSelection::Quit => ::std::process::exit(0),
|
||||
},
|
||||
}
|
||||
@ -214,7 +218,7 @@ impl GameState for State {
|
||||
RunState::SaveGame => {
|
||||
save_load_system::save_game(&mut self.ecs);
|
||||
new_run_state = RunState::MainMenu {
|
||||
menu_selection: gui::MainMenuSelection::LoadGame,
|
||||
menu_selection: gui::MainMenuSelection::Quit,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -238,9 +242,6 @@ fn main() -> rltk::BError {
|
||||
let mut gs = State { ecs: World::new() };
|
||||
|
||||
gs.ecs.insert(rltk::RandomNumberGenerator::new());
|
||||
gs.ecs.insert(gamelog::GameLog {
|
||||
entries: vec!["Welcome to Rusty Roguelike".to_string()],
|
||||
});
|
||||
|
||||
gs.ecs.register::<Position>();
|
||||
gs.ecs.register::<Renderable>();
|
||||
@ -265,22 +266,27 @@ fn main() -> rltk::BError {
|
||||
gs.ecs.register::<Confusion>();
|
||||
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
||||
gs.ecs.register::<SerializationHelper>();
|
||||
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||
let map = Map::new_map_rooms_and_corridors();
|
||||
|
||||
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||
|
||||
let map = Map::new_map_rooms_and_corridors();
|
||||
let (player_x, player_y) = map.rooms[0].center();
|
||||
gs.ecs.insert(Point::new(player_x, player_y));
|
||||
|
||||
let player_entity = spawner::player(&mut gs.ecs, player_x, player_y);
|
||||
gs.ecs.insert(player_entity);
|
||||
|
||||
for room in map.rooms.iter().skip(1) {
|
||||
spawner::spawn_room(&mut gs.ecs, room);
|
||||
}
|
||||
|
||||
gs.ecs.insert(map);
|
||||
gs.ecs.insert(Point::new(player_x, player_y));
|
||||
gs.ecs.insert(player_entity);
|
||||
gs.ecs.insert(RunState::MainMenu {
|
||||
menu_selection: gui::MainMenuSelection::NewGame,
|
||||
});
|
||||
gs.ecs.insert(gamelog::GameLog {
|
||||
entries: vec!["Welcome to Rusty Roguelike".to_string()],
|
||||
});
|
||||
|
||||
rltk::main_loop(context, gs)
|
||||
}
|
||||
|
61
src/map.rs
61
src/map.rs
@ -65,6 +65,27 @@ impl Map {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn is_exit_valid(&self, x: i32, y: i32) -> bool {
|
||||
if x < 1 || x > self.width - 1 || y < 1 || y > self.height - 1 {
|
||||
return false;
|
||||
}
|
||||
let idx = self.xy_idx(x, y);
|
||||
!self.blocked[idx]
|
||||
}
|
||||
|
||||
pub fn populate_blocked(&mut self) {
|
||||
for (i, tile) in self.tiles.iter_mut().enumerate() {
|
||||
self.blocked[i] = *tile == TileType::Wall;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_content_index(&mut self) {
|
||||
for content in self.tile_content.iter_mut() {
|
||||
content.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_map_rooms_and_corridors() -> Map {
|
||||
let mut map = Map {
|
||||
tiles: vec![TileType::Wall; MAP_COUNT],
|
||||
@ -116,37 +137,11 @@ impl Map {
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
fn is_exit_valid(&self, x: i32, y: i32) -> bool {
|
||||
if x < 1 || x > self.width - 1 || y < 1 || y > self.height - 1 {
|
||||
return false;
|
||||
}
|
||||
let idx = self.xy_idx(x, y);
|
||||
!self.blocked[idx]
|
||||
}
|
||||
|
||||
pub fn populate_blocked(&mut self) {
|
||||
for (i, tile) in self.tiles.iter_mut().enumerate() {
|
||||
self.blocked[i] = *tile == TileType::Wall;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_content_index(&mut self) {
|
||||
for content in self.tile_content.iter_mut() {
|
||||
content.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm2D for Map {
|
||||
fn dimensions(&self) -> rltk::Point {
|
||||
Point::new(self.width, self.height)
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseMap for Map {
|
||||
fn is_opaque(&self, idx: usize) -> bool {
|
||||
self.tiles[idx as usize] == TileType::Wall
|
||||
self.tiles[idx] == TileType::Wall
|
||||
}
|
||||
|
||||
fn get_pathing_distance(&self, idx1: usize, idx2: usize) -> f32 {
|
||||
@ -192,6 +187,12 @@ impl BaseMap for Map {
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm2D for Map {
|
||||
fn dimensions(&self) -> rltk::Point {
|
||||
Point::new(self.width, self.height)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
|
||||
@ -203,12 +204,12 @@ pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
|
||||
let mut fg;
|
||||
match tile {
|
||||
TileType::Floor => {
|
||||
fg = RGB::from_f32(0.5, 0.5, 0.5);
|
||||
fg = RGB::from_f32(0.0, 0.5, 0.5);
|
||||
glyph = rltk::to_cp437('.');
|
||||
}
|
||||
|
||||
TileType::Wall => {
|
||||
fg = RGB::from_f32(0.0, 1.0, 0.0);
|
||||
fg = RGB::from_f32(0., 1.0, 0.);
|
||||
glyph = rltk::to_cp437('#');
|
||||
}
|
||||
}
|
||||
@ -219,7 +220,7 @@ pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
|
||||
}
|
||||
|
||||
x += 1;
|
||||
if x > 79 {
|
||||
if x > MAP_WIDTH as i32 - 1 {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ use std::cmp::{max, min};
|
||||
use rltk::{Point, Rltk, VirtualKeyCode};
|
||||
use specs::prelude::*;
|
||||
|
||||
use crate::gamelog::GameLog;
|
||||
use crate::{
|
||||
components::{CombatStats, Player, Position, Viewshed, WantsToMelee},
|
||||
map::Map,
|
||||
Item, RunState, State, WantsToPickupItem,
|
||||
Item,
|
||||
map::Map, RunState, State, WantsToPickupItem,
|
||||
};
|
||||
use crate::gamelog::GameLog;
|
||||
|
||||
pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||
let mut positions = ecs.write_storage::<Position>();
|
||||
@ -20,8 +20,9 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
|
||||
for (entity, _player, pos, viewshed) in
|
||||
(&entities, &mut players, &mut positions, &mut viewsheds).join()
|
||||
(&entities, &mut players, &mut positions, &mut viewsheds).join()
|
||||
{
|
||||
if pos.x + delta_x < 1 || pos.x + delta_x > map.width - 1 || pos.y + delta_y < 1 || pos.y + delta_y > map.height - 1 { return; }
|
||||
let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
|
||||
|
||||
for potential_target in map.tile_content[destination_idx].iter() {
|
||||
|
@ -168,7 +168,7 @@ pub fn magic_missile_scroll(ecs: &mut World, x: i32, y: i32) {
|
||||
.with(Item {})
|
||||
.with(Consumable {})
|
||||
.with(Ranged { range: 6 })
|
||||
.with(InflictsDamage { damage: 8 })
|
||||
.with(InflictsDamage { damage: 20 })
|
||||
.marked::<SimpleMarker<SerializeMe>>()
|
||||
.build();
|
||||
}
|
||||
@ -178,7 +178,7 @@ pub fn fireball_scroll(ecs: &mut World, x: i32, y: i32) {
|
||||
.with(Position { x, y })
|
||||
.with(Renderable {
|
||||
glyph: rltk::to_cp437(')'),
|
||||
fg: RGB::named(rltk::CYAN),
|
||||
fg: RGB::named(rltk::ORANGE),
|
||||
bg: RGB::named(rltk::BLACK),
|
||||
render_order: 2,
|
||||
})
|
||||
@ -199,7 +199,7 @@ pub fn confusion_scroll(ecs: &mut World, x: i32, y: i32) {
|
||||
.with(Position { x, y })
|
||||
.with(Renderable {
|
||||
glyph: rltk::to_cp437(')'),
|
||||
fg: RGB::named(rltk::CYAN),
|
||||
fg: RGB::named(rltk::PINK),
|
||||
bg: RGB::named(rltk::BLACK),
|
||||
render_order: 2,
|
||||
})
|
||||
|
@ -25,7 +25,6 @@ impl<'a> System<'a> for VisibilitySystem {
|
||||
}
|
||||
|
||||
viewshed.dirty = false;
|
||||
viewshed.visible_tiles.clear();
|
||||
viewshed.visible_tiles = field_of_view(Point::new(pos.x, pos.y), viewshed.range, &*map);
|
||||
viewshed
|
||||
.visible_tiles
|
||||
|
Loading…
Reference in New Issue
Block a user