lappy sync
This commit is contained in:
parent
95101b2c30
commit
9b9077fa01
@ -39,6 +39,7 @@ pub enum RunState {
|
|||||||
PreRun,
|
PreRun,
|
||||||
PlayerTurn,
|
PlayerTurn,
|
||||||
MonsterTurn,
|
MonsterTurn,
|
||||||
|
ShowInventory
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
|
|||||||
55
src/gui.rs
55
src/gui.rs
@ -1,6 +1,8 @@
|
|||||||
use rltk::{RGB, Rltk, Console, Point};
|
use rltk::{RGB, Rltk, Point, VirtualKeyCode};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use super::{CombatStats, Player, GameLog, Map, Name, Position};
|
use crate::{InBackpack, player};
|
||||||
|
|
||||||
|
use super::{CombatStats, Player, GameLog, Map, Name, Position, State};
|
||||||
|
|
||||||
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
@ -78,4 +80,53 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||||||
let mouse_pos = ctx.mouse_pos();
|
let mouse_pos = ctx.mouse_pos();
|
||||||
ctx.set_bg(mouse_pos.0, mouse_pos.1, RGB::named(rltk::MAGENTA));
|
ctx.set_bg(mouse_pos.0, mouse_pos.1, RGB::named(rltk::MAGENTA));
|
||||||
draw_tooltips(ecs, ctx);
|
draw_tooltips(ecs, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
pub enum ItemMenuResult { Cancel, NoResponse, Selected }
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
let inventory = (&backpack, &names).join().filter(|item| item.0.owner == *player_entity);
|
||||||
|
let count = inventory.count();
|
||||||
|
|
||||||
|
let mut y = (25 - (count / 2)) as i32;
|
||||||
|
ctx.draw_box(15, y - 2, 31, (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".to_string());
|
||||||
|
ctx.print_color(18, y+count as i32 + 1, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), "Escape to cancel");
|
||||||
|
|
||||||
|
let mut equippable : Vec<Entity> = Vec::new();
|
||||||
|
let mut j = 0;
|
||||||
|
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
||||||
|
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(')'));
|
||||||
|
|
||||||
|
ctx.print(21, y, &name.name.to_string());
|
||||||
|
equippable.push(entity);
|
||||||
|
y += 1;
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ctx.key {
|
||||||
|
None => (ItemMenuResult::NoResponse, None),
|
||||||
|
Some(key) => {
|
||||||
|
match key {
|
||||||
|
VirtualKeyCode::Escape => { (ItemMenuResult::Cancel, None) },
|
||||||
|
_ => {
|
||||||
|
let selection = rltk::letter_to_option(key);
|
||||||
|
if selection > -1 && selection < count as i32 {
|
||||||
|
return (ItemMenuResult::Selected, Some(equippable[selection as usize]));
|
||||||
|
}
|
||||||
|
return (ItemMenuResult::NoResponse, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
30
src/inventory_system.rs
Normal file
30
src/inventory_system.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use specs::prelude::*;
|
||||||
|
use super::{WantsToPickupItem, Name, InBackpack, Position, gamelog::GameLog};
|
||||||
|
|
||||||
|
pub struct ItemCollectionSystem {}
|
||||||
|
|
||||||
|
impl<'a> System<'a> for ItemCollectionSystem {
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
type SystemData = ( ReadExpect<'a, Entity>,
|
||||||
|
WriteExpect<'a, GameLog>,
|
||||||
|
WriteStorage<'a, WantsToPickupItem>,
|
||||||
|
WriteStorage<'a, Position>,
|
||||||
|
ReadStorage<'a, Name>,
|
||||||
|
WriteStorage<'a, InBackpack>
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run (&mut self, data : Self::SystemData) {
|
||||||
|
let (player_entity, mut log, mut wants_pickup, mut positions, names, mut backpack) = data;
|
||||||
|
|
||||||
|
for pickup in wants_pickup.join() {
|
||||||
|
positions.remove(pickup.item);
|
||||||
|
backpack.insert(pickup.item, InBackpack{ owner: pickup.collected_by }).expect("Unable to insert item");
|
||||||
|
|
||||||
|
if pickup.collected_by == *player_entity {
|
||||||
|
log.entries.push(format!("You pick up the {}.", names.get(pickup.item).unwrap().name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wants_pickup.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/main.rs
29
src/main.rs
@ -37,6 +37,9 @@ pub use gamelog::*;
|
|||||||
mod spawner;
|
mod spawner;
|
||||||
use spawner::*;
|
use spawner::*;
|
||||||
|
|
||||||
|
mod inventory_system;
|
||||||
|
use inventory_system::*;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub ecs: World,
|
pub ecs: World,
|
||||||
}
|
}
|
||||||
@ -53,6 +56,8 @@ impl State {
|
|||||||
melee_combat_system.run_now(&self.ecs);
|
melee_combat_system.run_now(&self.ecs);
|
||||||
let mut damage_system = DamageSystem {};
|
let mut damage_system = DamageSystem {};
|
||||||
damage_system.run_now(&self.ecs);
|
damage_system.run_now(&self.ecs);
|
||||||
|
let mut pickup = ItemCollectionSystem{};
|
||||||
|
pickup.run_now(&self.ecs);
|
||||||
self.ecs.maintain();
|
self.ecs.maintain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +65,10 @@ impl State {
|
|||||||
impl GameState for State {
|
impl GameState for State {
|
||||||
fn tick(&mut self, ctx: &mut Rltk) {
|
fn tick(&mut self, ctx: &mut Rltk) {
|
||||||
ctx.cls();
|
ctx.cls();
|
||||||
|
damage_system::delete_the_dead(&mut self.ecs);
|
||||||
|
draw_map(&self.ecs, ctx);
|
||||||
|
|
||||||
|
|
||||||
let mut newrunstate;
|
let mut newrunstate;
|
||||||
{
|
{
|
||||||
let runstate = self.ecs.fetch::<RunState>();
|
let runstate = self.ecs.fetch::<RunState>();
|
||||||
@ -82,6 +91,20 @@ impl GameState for State {
|
|||||||
self.run_systems();
|
self.run_systems();
|
||||||
newrunstate = RunState::AwaitingInput;
|
newrunstate = RunState::AwaitingInput;
|
||||||
}
|
}
|
||||||
|
RunState::ShowInventory => {
|
||||||
|
let result = gui::show_inventory(self, ctx);
|
||||||
|
match result.0 {
|
||||||
|
gui::ItemMenuResult::Cancel => newrunstate = RunState::AwaitingInput,
|
||||||
|
gui::ItemMenuResult::NoResponse => {},
|
||||||
|
gui::ItemMenuResult::Selected => {
|
||||||
|
let item_entity = result.1.unwrap();
|
||||||
|
let names = self.ecs.read_storage::<Name>();
|
||||||
|
let mut gamelog = self.ecs.fetch_mut::<gamelog::GameLog>();
|
||||||
|
gamelog.entries.push(format!("You try to use {} but it isn't written yet", names.get(item_entity).unwrap().name));
|
||||||
|
newrunstate = RunState::AwaitingInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -89,9 +112,7 @@ impl GameState for State {
|
|||||||
*runwriter = newrunstate;
|
*runwriter = newrunstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
damage_system::delete_the_dead(&mut self.ecs);
|
|
||||||
draw_map(&self.ecs, ctx);
|
|
||||||
|
|
||||||
let positions = self.ecs.read_storage::<Position>();
|
let positions = self.ecs.read_storage::<Position>();
|
||||||
let renderables = self.ecs.read_storage::<Renderable>();
|
let renderables = self.ecs.read_storage::<Renderable>();
|
||||||
let map = self.ecs.fetch::<Map>();
|
let map = self.ecs.fetch::<Map>();
|
||||||
@ -125,6 +146,8 @@ fn main() -> rltk::BError {
|
|||||||
gs.ecs.register::<SufferDamage>();
|
gs.ecs.register::<SufferDamage>();
|
||||||
gs.ecs.register::<Item>();
|
gs.ecs.register::<Item>();
|
||||||
gs.ecs.register::<Potion>();
|
gs.ecs.register::<Potion>();
|
||||||
|
gs.ecs.register::<InBackpack>();
|
||||||
|
gs.ecs.register::<WantsToPickupItem>();
|
||||||
|
|
||||||
let map = Map::new_map_rooms_and_corridors();
|
let map = Map::new_map_rooms_and_corridors();
|
||||||
let (player_x, player_y) = map.rooms[0].center();
|
let (player_x, player_y) = map.rooms[0].center();
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
use crate::WantsToMelee;
|
use super::{Map, Player, Position, RunState, State, Viewshed, CombatStats, WantsToMelee, Item, GameLog, WantsToPickupItem};
|
||||||
|
|
||||||
use super::{Map, Player, Position, RunState, State, Viewshed, CombatStats};
|
|
||||||
use rltk::{Point, Rltk, VirtualKeyCode};
|
use rltk::{Point, Rltk, VirtualKeyCode};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
@ -37,6 +35,31 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_item(ecs: &mut World) {
|
||||||
|
let player_pos = ecs.fetch::<Point>();
|
||||||
|
let player_entity = ecs.fetch::<Entity>();
|
||||||
|
let entities = ecs.entities();
|
||||||
|
let items = ecs.read_storage::<Item>();
|
||||||
|
let positions = ecs.read_storage::<Position>();
|
||||||
|
let mut gamelog = ecs.fetch_mut::<GameLog>();
|
||||||
|
|
||||||
|
let mut target_item : Option<Entity> = None;
|
||||||
|
for (item_entity, _item, position) in (&entities, &items, &positions).join() {
|
||||||
|
if position.x == player_pos.x && position.y == player_pos.y {
|
||||||
|
target_item = Some(item_entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match target_item {
|
||||||
|
None => gamelog.entries.push("There is nothing to pick up.".to_string()),
|
||||||
|
Some(item) => {
|
||||||
|
let mut pickup = ecs.write_storage::<WantsToPickupItem>();
|
||||||
|
pickup.insert(*player_entity, WantsToPickupItem{ collected_by: *player_entity, item}).expect("Unable to insert want to pickup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
|
pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
|
||||||
match ctx.key {
|
match ctx.key {
|
||||||
None => return RunState::AwaitingInput,
|
None => return RunState::AwaitingInput,
|
||||||
@ -61,6 +84,8 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
|
|||||||
VirtualKeyCode::Numpad7 | VirtualKeyCode::U => {try_move_player(-1, -1, &mut gs.ecs)}
|
VirtualKeyCode::Numpad7 | VirtualKeyCode::U => {try_move_player(-1, -1, &mut gs.ecs)}
|
||||||
VirtualKeyCode::Numpad3 | VirtualKeyCode::N => {try_move_player(1, 1, &mut gs.ecs)}
|
VirtualKeyCode::Numpad3 | VirtualKeyCode::N => {try_move_player(1, 1, &mut gs.ecs)}
|
||||||
VirtualKeyCode::Numpad1 | VirtualKeyCode::B => {try_move_player(-1, 1, &mut gs.ecs)}
|
VirtualKeyCode::Numpad1 | VirtualKeyCode::B => {try_move_player(-1, 1, &mut gs.ecs)}
|
||||||
|
VirtualKeyCode::G => get_item(&mut gs.ecs),
|
||||||
|
VirtualKeyCode::I => return RunState::ShowInventory,
|
||||||
_ => return RunState::AwaitingInput,
|
_ => return RunState::AwaitingInput,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user