fun with layers, and inventory display refactor
This commit is contained in:
parent
50e3cb50bc
commit
b7b2061228
7 changed files with 122 additions and 129 deletions
88
src/gui.rs
88
src/gui.rs
|
|
@ -136,32 +136,9 @@ pub enum ItemMenuResult {
|
||||||
Selected,
|
Selected,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option<Entity>) {
|
pub fn print_options(inventory: BTreeMap<(String, String), i32>, mut y: i32, ctx: &mut Rltk) {
|
||||||
let player_entity = gs.ecs.fetch::<Entity>();
|
|
||||||
let names = gs.ecs.read_storage::<Name>();
|
|
||||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
|
||||||
let entities = gs.ecs.entities();
|
|
||||||
|
|
||||||
// FIXME: This is unwieldy. Having a separate data structure for (items, id) and (items, count) is not good.
|
|
||||||
// But it works, and this might get cut anyway as I get further along in the design, so leaving as is atm.
|
|
||||||
let mut inventory_ids: BTreeMap<String, Entity> = BTreeMap::new();
|
|
||||||
let mut player_inventory: BTreeMap<(String, String), i32> = BTreeMap::new();
|
|
||||||
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
|
||||||
player_inventory
|
|
||||||
.entry((name.name.to_string(), name.plural.to_string()))
|
|
||||||
.and_modify(|count| *count += 1)
|
|
||||||
.or_insert(1);
|
|
||||||
inventory_ids.entry(name.name.to_string()).or_insert(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = player_inventory.len();
|
|
||||||
let mut y = (25 - (count / 2)) as i32;
|
|
||||||
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
|
||||||
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Inventory");
|
|
||||||
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
|
||||||
|
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for (name, item_count) in &player_inventory {
|
for (name, item_count) in &inventory {
|
||||||
// Print the character required to access this item. i.e. (a)
|
// Print the character required to access this item. i.e. (a)
|
||||||
ctx.set(17, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437('('));
|
ctx.set(17, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437('('));
|
||||||
ctx.set(18, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), 97 + j as rltk::FontCharType);
|
ctx.set(18, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), 97 + j as rltk::FontCharType);
|
||||||
|
|
@ -191,6 +168,33 @@ pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option
|
||||||
y += 1;
|
y += 1;
|
||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show_inventory(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option<Entity>) {
|
||||||
|
let player_entity = gs.ecs.fetch::<Entity>();
|
||||||
|
let names = gs.ecs.read_storage::<Name>();
|
||||||
|
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||||
|
let entities = gs.ecs.entities();
|
||||||
|
|
||||||
|
// FIXME: This is unwieldy. Having a separate data structure for (name, id) and (name, count) is not good.
|
||||||
|
// But it works, and this might get cut anyway as I get further along in the design, so leaving as is atm.
|
||||||
|
let mut inventory_ids: BTreeMap<String, Entity> = BTreeMap::new();
|
||||||
|
let mut player_inventory: BTreeMap<(String, String), i32> = BTreeMap::new();
|
||||||
|
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
||||||
|
player_inventory
|
||||||
|
.entry((name.name.to_string(), name.plural.to_string()))
|
||||||
|
.and_modify(|count| *count += 1)
|
||||||
|
.or_insert(1);
|
||||||
|
inventory_ids.entry(name.name.to_string()).or_insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = player_inventory.len();
|
||||||
|
let y = (25 - (count / 2)) as i32;
|
||||||
|
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||||
|
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Inventory");
|
||||||
|
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
||||||
|
|
||||||
|
print_options(player_inventory, y, ctx);
|
||||||
|
|
||||||
match ctx.key {
|
match ctx.key {
|
||||||
None => (ItemMenuResult::NoResponse, None),
|
None => (ItemMenuResult::NoResponse, None),
|
||||||
|
|
@ -224,42 +228,12 @@ pub fn drop_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option
|
||||||
}
|
}
|
||||||
|
|
||||||
let count = player_inventory.len();
|
let count = player_inventory.len();
|
||||||
let mut y = (25 - (count / 2)) as i32;
|
let y = (25 - (count / 2)) as i32;
|
||||||
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
ctx.draw_box(15, y - 2, 45, (count + 3) as i32, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK));
|
||||||
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Drop what?");
|
ctx.print_color(18, y - 2, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "Drop what?");
|
||||||
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
ctx.print_color(18, y + count as i32 + 1, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "ESC to cancel");
|
||||||
|
|
||||||
let mut j = 0;
|
print_options(player_inventory, y, ctx);
|
||||||
for (name, item_count) in &player_inventory {
|
|
||||||
// Print the character required to access this item. i.e. (a)
|
|
||||||
ctx.set(17, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437('('));
|
|
||||||
ctx.set(18, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), 97 + j as rltk::FontCharType);
|
|
||||||
ctx.set(19, y, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), rltk::to_cp437(')'));
|
|
||||||
|
|
||||||
let mut x = 21;
|
|
||||||
if item_count > &1 {
|
|
||||||
// If more than one, print the number and pluralise
|
|
||||||
// i.e. (a) 3 daggers
|
|
||||||
ctx.print(x, y, item_count);
|
|
||||||
x += 2;
|
|
||||||
ctx.print(x, y, name.1.to_string());
|
|
||||||
} else {
|
|
||||||
if ['a', 'e', 'i', 'o', 'u'].iter().any(|&v| name.0.starts_with(v)) {
|
|
||||||
// If one and starts with a vowel, print 'an'
|
|
||||||
// i.e. (a) an apple
|
|
||||||
ctx.print(x, y, "an");
|
|
||||||
x += 3;
|
|
||||||
} else {
|
|
||||||
// If one and not a vowel, print 'a'
|
|
||||||
// i.e. (a) a dagger
|
|
||||||
ctx.print(x, y, "a");
|
|
||||||
x += 2;
|
|
||||||
}
|
|
||||||
ctx.print(x, y, name.0.to_string());
|
|
||||||
}
|
|
||||||
y += 1;
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
match ctx.key {
|
match ctx.key {
|
||||||
None => (ItemMenuResult::NoResponse, None),
|
None => (ItemMenuResult::NoResponse, None),
|
||||||
|
|
|
||||||
|
|
@ -411,13 +411,16 @@ impl GameState for State {
|
||||||
gui::GameOverResult::NoSelection => {}
|
gui::GameOverResult::NoSelection => {}
|
||||||
gui::GameOverResult::QuitToMenu => {
|
gui::GameOverResult::QuitToMenu => {
|
||||||
self.game_over_cleanup();
|
self.game_over_cleanup();
|
||||||
new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame };
|
new_runstate = RunState::MapGeneration;
|
||||||
|
self.mapgen_next_state =
|
||||||
|
Some(RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RunState::NextLevel => {
|
RunState::NextLevel => {
|
||||||
self.goto_next_level();
|
self.goto_next_level();
|
||||||
new_runstate = RunState::PreRun;
|
self.mapgen_next_state = Some(RunState::PreRun);
|
||||||
|
new_runstate = RunState::MapGeneration;
|
||||||
}
|
}
|
||||||
RunState::MagicMapReveal { row, cursed } => {
|
RunState::MagicMapReveal { row, cursed } => {
|
||||||
let mut map = self.ecs.fetch_mut::<Map>();
|
let mut map = self.ecs.fetch_mut::<Map>();
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ fn wall_glyph(map: &Map, x: i32, y: i32) -> rltk::FontCharType {
|
||||||
}
|
}
|
||||||
|
|
||||||
match mask {
|
match mask {
|
||||||
0 => 9, // Pillar because we can't see neighbors
|
0 => 254, // ■ (254) square pillar; but maybe ○ (9) looks better
|
||||||
1 => 186, // Wall only to the north
|
1 => 186, // Wall only to the north
|
||||||
2 => 186, // Wall only to the south
|
2 => 186, // Wall only to the south
|
||||||
3 => 186, // Wall to the north and south
|
3 => 186, // Wall to the north and south
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{BuilderMap, InitialMapBuilder, TileType};
|
use super::{BuilderMap, InitialMapBuilder, MetaMapBuilder, TileType};
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
pub struct CellularAutomataBuilder {}
|
pub struct CellularAutomataBuilder {}
|
||||||
|
|
@ -10,6 +10,13 @@ impl InitialMapBuilder for CellularAutomataBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for CellularAutomataBuilder {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn build_map(&mut self, _rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.apply_iteration(build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CellularAutomataBuilder {
|
impl CellularAutomataBuilder {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Box<CellularAutomataBuilder> {
|
pub fn new() -> Box<CellularAutomataBuilder> {
|
||||||
|
|
@ -34,6 +41,11 @@ impl CellularAutomataBuilder {
|
||||||
|
|
||||||
// Now we iteratively apply cellular automata rules
|
// Now we iteratively apply cellular automata rules
|
||||||
for _i in 0..15 {
|
for _i in 0..15 {
|
||||||
|
self.apply_iteration(build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_iteration(&mut self, build_data: &mut BuilderMap) {
|
||||||
let mut newtiles = build_data.map.tiles.clone();
|
let mut newtiles = build_data.map.tiles.clone();
|
||||||
|
|
||||||
for y in 1..build_data.map.height - 1 {
|
for y in 1..build_data.map.height - 1 {
|
||||||
|
|
@ -77,4 +89,3 @@ impl CellularAutomataBuilder {
|
||||||
build_data.take_snapshot();
|
build_data.take_snapshot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{paint, BuilderMap, InitialMapBuilder, Position, Symmetry, TileType};
|
use super::{paint, BuilderMap, InitialMapBuilder, MetaMapBuilder, Position, Symmetry, TileType};
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
|
@ -23,6 +23,13 @@ impl InitialMapBuilder for DLABuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for DLABuilder {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.build(rng, build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DLABuilder {
|
impl DLABuilder {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Box<DLABuilder> {
|
pub fn new() -> Box<DLABuilder> {
|
||||||
|
|
@ -74,6 +81,16 @@ impl DLABuilder {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn heavy_erosion() -> Box<DLABuilder> {
|
||||||
|
Box::new(DLABuilder {
|
||||||
|
algorithm: DLAAlgorithm::WalkInwards,
|
||||||
|
brush_size: 2,
|
||||||
|
symmetry: Symmetry::None,
|
||||||
|
floor_percent: 0.35,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::map_entry)]
|
#[allow(clippy::map_entry)]
|
||||||
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
// Carve a starting seed
|
// Carve a starting seed
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{paint, BuilderMap, InitialMapBuilder, Position, Symmetry, TileType};
|
use super::{paint, BuilderMap, InitialMapBuilder, MetaMapBuilder, Position, Symmetry, TileType};
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
|
@ -27,6 +27,13 @@ impl InitialMapBuilder for DrunkardsWalkBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MetaMapBuilder for DrunkardsWalkBuilder {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
|
self.build(rng, build_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DrunkardsWalkBuilder {
|
impl DrunkardsWalkBuilder {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new(settings: DrunkardSettings) -> DrunkardsWalkBuilder {
|
pub fn new(settings: DrunkardSettings) -> DrunkardsWalkBuilder {
|
||||||
|
|
|
||||||
|
|
@ -146,30 +146,11 @@ fn random_initial_builder(rng: &mut rltk::RandomNumberGenerator) -> (Box<dyn Ini
|
||||||
|
|
||||||
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator) -> BuilderChain {
|
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator) -> BuilderChain {
|
||||||
let mut builder = BuilderChain::new(new_depth);
|
let mut builder = BuilderChain::new(new_depth);
|
||||||
let (random_starter, has_rooms) = random_initial_builder(rng);
|
builder.start_with(simple_map::SimpleMapBuilder::new());
|
||||||
builder.start_with(random_starter);
|
builder.with(DLABuilder::heavy_erosion());
|
||||||
if has_rooms {
|
|
||||||
builder.with(RoomBasedSpawner::new());
|
|
||||||
builder.with(RoomBasedStairs::new());
|
|
||||||
builder.with(RoomBasedStartingPosition::new());
|
|
||||||
} else {
|
|
||||||
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
||||||
builder.with(CullUnreachable::new());
|
builder.with(CullUnreachable::new());
|
||||||
builder.with(VoronoiSpawning::new());
|
builder.with(VoronoiSpawning::new());
|
||||||
builder.with(DistantExit::new());
|
builder.with(DistantExit::new());
|
||||||
}
|
|
||||||
|
|
||||||
if rng.roll_dice(1, 3) == 1 {
|
|
||||||
builder.with(WaveFunctionCollapseBuilder::new());
|
|
||||||
builder.with(CullUnreachable::new());
|
|
||||||
builder.with(VoronoiSpawning::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
if rng.roll_dice(1, 20) == 1 {
|
|
||||||
builder.with(PrefabBuilder::sectional(prefab_builder::prefab_sections::UNDERGROUND_FORT));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.with(PrefabBuilder::vaults());
|
|
||||||
|
|
||||||
builder
|
builder
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue