Add ability to remove equipped items
This commit is contained in:
parent
b2ed5e7758
commit
a2ef1810d9
@ -175,3 +175,8 @@ pub struct MeleePowerBonus {
|
|||||||
pub struct DefenseBonus {
|
pub struct DefenseBonus {
|
||||||
pub defense: i32,
|
pub defense: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||||
|
pub struct WantsToRemoveItem {
|
||||||
|
pub item: Entity,
|
||||||
|
}
|
||||||
|
91
src/gui.rs
91
src/gui.rs
@ -1,5 +1,5 @@
|
|||||||
use crate::components::{CombatStats, InBackpack, Name, Player, Position, Viewshed};
|
use crate::components::{CombatStats, InBackpack, Name, Player, Position, Viewshed};
|
||||||
use crate::{game_log::GameLog, Map, RunState, State};
|
use crate::{game_log::GameLog, Equipped, Map, RunState, State};
|
||||||
use rltk::{Point, Rltk, VirtualKeyCode, RGB};
|
use rltk::{Point, Rltk, VirtualKeyCode, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
@ -530,3 +530,92 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
|||||||
selected: MainMenuSelection::NewGame,
|
selected: MainMenuSelection::NewGame,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_item_menu(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::<Equipped>();
|
||||||
|
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),
|
||||||
|
"Remove Which Item?",
|
||||||
|
);
|
||||||
|
ctx.print_color(
|
||||||
|
18,
|
||||||
|
y + count as i32 + 1,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
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]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(ItemMenuResult::NoResponse, None)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -319,3 +319,26 @@ impl<'a> System<'a> for ItemDropSystem {
|
|||||||
wants_drop.clear();
|
wants_drop.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ItemRemoveSystem {}
|
||||||
|
|
||||||
|
impl<'a> System<'a> for ItemRemoveSystem {
|
||||||
|
type SystemData = (
|
||||||
|
Entities<'a>,
|
||||||
|
WriteStorage<'a, WantsToRemoveItem>,
|
||||||
|
WriteStorage<'a, Equipped>,
|
||||||
|
WriteStorage<'a, InBackpack>
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
let (entities, mut wants_remove, mut equipped, mut backpack) = data;
|
||||||
|
|
||||||
|
for (entity, to_remove) in (&entities, &wants_remove).join() {
|
||||||
|
equipped.remove(to_remove.item);
|
||||||
|
backpack.insert(to_remove.item, InBackpack { owner: entity})
|
||||||
|
.expect("Unable to remove item and put in backpack");
|
||||||
|
}
|
||||||
|
|
||||||
|
wants_remove.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
25
src/main.rs
25
src/main.rs
@ -30,6 +30,7 @@ use monster_ai_system::MonsterAI;
|
|||||||
use player::*;
|
use player::*;
|
||||||
pub use rect::Rect;
|
pub use rect::Rect;
|
||||||
use visibility_system::VisibilitySystem;
|
use visibility_system::VisibilitySystem;
|
||||||
|
use crate::inventory_system::ItemRemoveSystem;
|
||||||
|
|
||||||
/// Cut down on the amount of syntax to register components
|
/// Cut down on the amount of syntax to register components
|
||||||
macro_rules! register {
|
macro_rules! register {
|
||||||
@ -61,6 +62,7 @@ pub enum RunState {
|
|||||||
},
|
},
|
||||||
SaveGame,
|
SaveGame,
|
||||||
NextLevel,
|
NextLevel,
|
||||||
|
ShowRemoveItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -97,6 +99,9 @@ impl State {
|
|||||||
let mut drop_items = ItemDropSystem {};
|
let mut drop_items = ItemDropSystem {};
|
||||||
drop_items.run_now(&self.ecs);
|
drop_items.run_now(&self.ecs);
|
||||||
|
|
||||||
|
let mut item_remove = ItemRemoveSystem {};
|
||||||
|
item_remove.run_now(&self.ecs);
|
||||||
|
|
||||||
self.ecs.maintain();
|
self.ecs.maintain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,6 +263,25 @@ impl GameState for State {
|
|||||||
self.goto_next_level();
|
self.goto_next_level();
|
||||||
newrunstate = RunState::PreRun;
|
newrunstate = RunState::PreRun;
|
||||||
}
|
}
|
||||||
|
RunState::ShowRemoveItem => {
|
||||||
|
let result = gui::remove_item_menu(self, ctx);
|
||||||
|
match result.0 {
|
||||||
|
gui::ItemMenuResult::Cancel => newrunstate = RunState::AwaitingInput,
|
||||||
|
gui::ItemMenuResult::NoResponse => {}
|
||||||
|
gui::ItemMenuResult::Selected => {
|
||||||
|
let item_entity = result.1.unwrap();
|
||||||
|
let mut intent = self.ecs.write_storage::<WantsToRemoveItem>();
|
||||||
|
intent
|
||||||
|
.insert(
|
||||||
|
*self.ecs.fetch::<Entity>(),
|
||||||
|
WantsToRemoveItem { item: item_entity },
|
||||||
|
)
|
||||||
|
.expect("Unable to insert intent to remove item");
|
||||||
|
|
||||||
|
newrunstate = RunState::PlayerTurn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -405,6 +429,7 @@ fn main() -> rltk::BError {
|
|||||||
Equipped,
|
Equipped,
|
||||||
MeleePowerBonus,
|
MeleePowerBonus,
|
||||||
DefenseBonus,
|
DefenseBonus,
|
||||||
|
WantsToRemoveItem,
|
||||||
);
|
);
|
||||||
|
|
||||||
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||||
|
@ -117,6 +117,9 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
|
|||||||
// Skip Turn
|
// Skip Turn
|
||||||
VirtualKeyCode::Numpad5 | VirtualKeyCode::Space => return skip_turn(&mut gs.ecs),
|
VirtualKeyCode::Numpad5 | VirtualKeyCode::Space => return skip_turn(&mut gs.ecs),
|
||||||
|
|
||||||
|
// Remove item
|
||||||
|
VirtualKeyCode::R => return RunState::ShowRemoveItem,
|
||||||
|
|
||||||
_ => return RunState::AwaitingInput,
|
_ => return RunState::AwaitingInput,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,11 @@ pub fn save_game(ecs: &mut World) {
|
|||||||
WantsToUseItem,
|
WantsToUseItem,
|
||||||
WantsToDropItem,
|
WantsToDropItem,
|
||||||
SerializationHelper,
|
SerializationHelper,
|
||||||
Equippable
|
Equippable,
|
||||||
|
Equipped,
|
||||||
|
MeleePowerBonus,
|
||||||
|
DefenseBonus,
|
||||||
|
WantsToRemoveItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +151,11 @@ pub fn load_game(ecs: &mut World) {
|
|||||||
WantsToUseItem,
|
WantsToUseItem,
|
||||||
WantsToDropItem,
|
WantsToDropItem,
|
||||||
SerializationHelper,
|
SerializationHelper,
|
||||||
Equippable
|
Equippable,
|
||||||
|
Equipped,
|
||||||
|
MeleePowerBonus,
|
||||||
|
DefenseBonus,
|
||||||
|
WantsToRemoveItem
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user