itemtypes, and filtering items by itemtype/buc/etc.
This commit is contained in:
parent
f3af75bf44
commit
9c1298df6b
10 changed files with 386 additions and 227 deletions
|
|
@ -3,6 +3,7 @@
|
|||
"id": "potion_health",
|
||||
"name": { "name": "potion of health", "plural": "potions of health" },
|
||||
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 4 },
|
||||
"class": "potion",
|
||||
"weight": 1,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
|
|
@ -13,6 +14,7 @@
|
|||
"id": "potion_health_weak",
|
||||
"name": { "name": "potion of lesser health", "plural": "potions of lesser health" },
|
||||
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 4 },
|
||||
"class": "potion",
|
||||
"weight": 1,
|
||||
"value": 25,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
"id": "scroll_identify",
|
||||
"name": { "name": "scroll of identify", "plural": "scrolls of identify" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#0FFFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "IDENTIFY"],
|
||||
|
|
@ -32,6 +35,7 @@
|
|||
"id": "scroll_removecurse",
|
||||
"name": { "name": "scroll of remove curse", "plural": "scrolls of remove curse" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#0FFFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "REMOVE_CURSE"],
|
||||
|
|
@ -41,6 +45,7 @@
|
|||
"id": "scroll_health",
|
||||
"name": { "name": "scroll of healing word", "plural": "scrolls of healing word" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -51,6 +56,7 @@
|
|||
"id": "scroll_mass_health",
|
||||
"name": { "name": "scroll of mass healing word", "plural": "scrolls of mass healing word" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -61,6 +67,7 @@
|
|||
"id": "scroll_magicmissile",
|
||||
"name": { "name": "scroll of magic missile", "plural": "scrolls of magic missile" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -71,6 +78,7 @@
|
|||
"id": "scroll_embers",
|
||||
"name": { "name": "scroll of embers", "plural": "scrolls of embers" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -81,6 +89,7 @@
|
|||
"id": "scroll_fireball",
|
||||
"name": { "name": "scroll of fireball", "plural": "scrolls of fireball" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -96,6 +105,7 @@
|
|||
"id": "scroll_confusion",
|
||||
"name": { "name": "scroll of confusion", "plural": "scrolls of confusion" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -106,6 +116,7 @@
|
|||
"id": "scroll_mass_confusion",
|
||||
"name": { "name": "scroll of mass confusion", "plural": "scrolls of mass confusion" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
|
|
@ -116,6 +127,7 @@
|
|||
"id": "scroll_magicmap",
|
||||
"name": { "name": "scroll of magic mapping", "plural": "scrolls of magic mapping" },
|
||||
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "MAGICMAP"],
|
||||
|
|
@ -126,6 +138,7 @@
|
|||
"id": "equip_dagger",
|
||||
"name": { "name": "dagger", "plural": "daggers" },
|
||||
"renderable": { "glyph": ")", "fg": "#808080", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 1,
|
||||
"value": 2,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -135,6 +148,7 @@
|
|||
"id": "equip_shortsword",
|
||||
"name": { "name": "shortsword", "plural": "shortswords" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -144,6 +158,7 @@
|
|||
"id": "equip_rapier",
|
||||
"name": { "name": "rapier", "plural": "rapiers" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -153,6 +168,7 @@
|
|||
"id": "equip_pitchfork",
|
||||
"name": { "name": "pitchfork", "plural": "pitchforks" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -162,6 +178,7 @@
|
|||
"id": "equip_sickle",
|
||||
"name": { "name": "sickle", "plural": "sickles" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -171,6 +188,7 @@
|
|||
"id": "equip_handaxe",
|
||||
"name": { "name": "handaxe", "plural": "handaxes" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -180,6 +198,7 @@
|
|||
"id": "equip_longsword",
|
||||
"name": { "name": "longsword", "plural": "longswords" },
|
||||
"renderable": { "glyph": ")", "fg": "#FFF8DC", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 3,
|
||||
"value": 15,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -189,6 +208,7 @@
|
|||
"id": "artifact_icingdeath",
|
||||
"name": { "name": "Icingdeath", "plural": "Icingdeath" },
|
||||
"renderable": { "glyph": ")", "fg": "#37aecc", "bg": "#000000", "order": 4 },
|
||||
"class": "weapon",
|
||||
"weight": 3,
|
||||
"value": 300,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -198,6 +218,7 @@
|
|||
"id": "equip_smallshield",
|
||||
"name": { "name": "buckler", "plural": "bucklers" },
|
||||
"renderable": { "glyph": "[", "fg": "#808080", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -207,6 +228,7 @@
|
|||
"id": "equip_mediumshield",
|
||||
"name": { "name": "medium shield", "plural": "medium shields" },
|
||||
"renderable": { "glyph": "[", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -216,6 +238,7 @@
|
|||
"id": "equip_largeshield",
|
||||
"name": { "name": "large shield", "plural": "large shields" },
|
||||
"renderable": { "glyph": "[", "fg": "#FFF8DC", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 12,
|
||||
"value": 35,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -225,6 +248,7 @@
|
|||
"id": "equip_body_weakleather",
|
||||
"name": { "name": "leather jacket", "plural": "leather jackets" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 8,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -234,6 +258,7 @@
|
|||
"id": "equip_body_leather",
|
||||
"name": { "name": "leather chestpiece", "plural": "leather chestpiece" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -243,6 +268,7 @@
|
|||
"id": "equip_body_studdedleather",
|
||||
"name": { "name": "studded leather chestpiece", "plural": "studded leather chestpieces" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 13,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -252,6 +278,7 @@
|
|||
"id": "equip_body_ringmail_o",
|
||||
"name": { "name": "orcish ring mail", "plural": "orcish ring mail" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 45,
|
||||
"value": 50,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -261,6 +288,7 @@
|
|||
"id": "equip_body_ringmail",
|
||||
"name": { "name": "ring mail", "plural": "ring mail" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 45,
|
||||
"value": 70,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -270,6 +298,7 @@
|
|||
"id": "equip_head_leather",
|
||||
"name": { "name": "leather cap", "plural": "leather caps" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -279,6 +308,7 @@
|
|||
"id": "equip_head_elvish",
|
||||
"name": { "name": "elvish leather helm", "plural": "elvish leather helms" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -288,6 +318,7 @@
|
|||
"id": "equip_head_o",
|
||||
"name": { "name": "orcish helm", "plural": "orcish helm" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -297,6 +328,7 @@
|
|||
"id": "equip_head_iron",
|
||||
"name": { "name": "iron helm", "plural": "iron helm" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -306,6 +338,7 @@
|
|||
"id": "equip_feet_leather",
|
||||
"name": { "name": "leather shoes", "plural": "leather shoes" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_FEET"]
|
||||
|
|
@ -314,6 +347,7 @@
|
|||
"id": "equip_feet_elvish",
|
||||
"name": { "name": "elvish leather shoes", "plural": "elvish leather shoes" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -323,6 +357,7 @@
|
|||
"id": "equip_feet_o",
|
||||
"name": { "name": "orcish boots", "plural": "orcish boots" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -332,6 +367,7 @@
|
|||
"id": "equip_feet_iron",
|
||||
"name": { "name": "iron boots", "plural": "iron boots" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -341,6 +377,7 @@
|
|||
"id": "equip_neck_protection",
|
||||
"name": { "name": "amulet of protection", "plural": "amulets of protection" },
|
||||
"renderable": { "glyph": "\"", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "amulet",
|
||||
"weight": 1,
|
||||
"value": 200,
|
||||
"flags": ["EQUIP_NECK"],
|
||||
|
|
@ -350,6 +387,7 @@
|
|||
"id": "equip_back_protection",
|
||||
"name": { "name": "cloak of protection", "plural": "cloaks of protection" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
|
||||
"class": "armour",
|
||||
"weight": 1,
|
||||
"value": 200,
|
||||
"flags": ["EQUIP_BACK"],
|
||||
|
|
@ -359,6 +397,7 @@
|
|||
"id": "wand_magicmissile",
|
||||
"name": { "name": "wand of magic missile", "plural": "wands of magic missile" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 100,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -369,6 +408,7 @@
|
|||
"id": "wand_fireball",
|
||||
"name": { "name": "wand of fireball", "plural": "wands of fireball" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -379,6 +419,7 @@
|
|||
"id": "wand_confusion",
|
||||
"name": { "name": "wand of confusion", "plural": "wands of confusion" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 200,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -389,6 +430,7 @@
|
|||
"id": "wand_digging",
|
||||
"name": { "name": "wand of digging", "plural": "wands of digging" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["CHARGES", "DIGGER"],
|
||||
|
|
@ -399,6 +441,7 @@
|
|||
"id": "food_rations",
|
||||
"name": { "name": "rations", "plural": "rations" },
|
||||
"renderable": { "glyph": "%", "fg": "#FFA07A", "bg": "#000000", "order": 4 },
|
||||
"class": "comestible",
|
||||
"weight": 1,
|
||||
"value": 1,
|
||||
"flags": ["FOOD", "CONSUMABLE", "STACKABLE"]
|
||||
|
|
@ -407,6 +450,7 @@
|
|||
"id": "food_apple",
|
||||
"name": { "name": "apple", "plural": "apples" },
|
||||
"renderable": { "glyph": "%", "fg": "#00FF00", "bg": "#000000", "order": 4 },
|
||||
"class": "comestible",
|
||||
"weight": 0.5,
|
||||
"value": 1,
|
||||
"flags": ["FOOD", "CONSUMABLE", "STACKABLE"]
|
||||
|
|
|
|||
|
|
@ -437,10 +437,40 @@ pub struct Beatitude {
|
|||
pub known: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ItemType {
|
||||
Amulet,
|
||||
Weapon,
|
||||
Armour,
|
||||
Comestible,
|
||||
Scroll,
|
||||
Spellbook,
|
||||
Potion,
|
||||
Ring,
|
||||
Wand,
|
||||
}
|
||||
|
||||
impl ItemType {
|
||||
pub fn string(&self) -> &str {
|
||||
match self {
|
||||
ItemType::Amulet => "Amulets",
|
||||
ItemType::Weapon => "Weapons",
|
||||
ItemType::Armour => "Armour",
|
||||
ItemType::Comestible => "Comestibles",
|
||||
ItemType::Scroll => "Scrolls",
|
||||
ItemType::Spellbook => "Spellbooks",
|
||||
ItemType::Potion => "Potions",
|
||||
ItemType::Ring => "Rings",
|
||||
ItemType::Wand => "Wands",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Item {
|
||||
pub weight: f32, // in lbs
|
||||
pub value: f32, // base
|
||||
pub category: ItemType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ use super::{
|
|||
item_colour_ecs,
|
||||
obfuscate_name_ecs,
|
||||
print_options,
|
||||
unique_ecs,
|
||||
renderable_colour,
|
||||
ItemMenuResult,
|
||||
UniqueInventoryItem,
|
||||
BUC,
|
||||
Key,
|
||||
};
|
||||
use crate::{
|
||||
gamelog,
|
||||
|
|
@ -23,7 +25,7 @@ use crate::{
|
|||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Handles the Identify menu.
|
||||
pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) {
|
||||
|
|
@ -37,9 +39,12 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
let names = gs.ecs.read_storage::<Name>();
|
||||
let renderables = gs.ecs.read_storage::<Renderable>();
|
||||
let beatitudes = gs.ecs.read_storage::<Beatitude>();
|
||||
let keys = gs.ecs.read_storage::<Key>();
|
||||
|
||||
let build_identify_iterator = || {
|
||||
(&entities, &items, &renderables, &names).join().filter(|(item_entity, _i, _r, n)| {
|
||||
(&entities, &items, &renderables, &names, &keys)
|
||||
.join()
|
||||
.filter(|(item_entity, _i, _r, n, _k)| {
|
||||
// If not owned by the player, return false.
|
||||
let mut keep = false;
|
||||
if let Some(bp) = backpack.get(*item_entity) {
|
||||
|
|
@ -91,34 +96,15 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
.log();
|
||||
return (ItemMenuResult::Selected, Some(build_identify_iterator().nth(0).unwrap().0));
|
||||
}
|
||||
let mut player_inventory: super::PlayerInventory = BTreeMap::new();
|
||||
for (entity, _i, renderable, name) in build_identify_iterator() {
|
||||
let (singular, plural) = obfuscate_name_ecs(&gs.ecs, entity);
|
||||
let beatitude_status = if
|
||||
let Some(beatitude) = gs.ecs.read_storage::<Beatitude>().get(entity)
|
||||
{
|
||||
match beatitude.buc {
|
||||
BUC::Blessed => 1,
|
||||
BUC::Uncursed => 2,
|
||||
BUC::Cursed => 3,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let unique_item = UniqueInventoryItem {
|
||||
display_name: super::DisplayName { singular: singular.clone(), plural: plural.clone() },
|
||||
rgb: item_colour_ecs(&gs.ecs, entity),
|
||||
renderables: renderable_colour(&renderables, entity),
|
||||
glyph: renderable.glyph,
|
||||
beatitude_status: beatitude_status,
|
||||
name: name.name.clone(),
|
||||
};
|
||||
let mut player_inventory: super::PlayerInventory = HashMap::new();
|
||||
for (entity, _i, renderable, name, key) in build_identify_iterator() {
|
||||
let unique_item = unique_ecs(&gs.ecs, entity);
|
||||
player_inventory
|
||||
.entry(unique_item)
|
||||
.and_modify(|(_e, count)| {
|
||||
*count += 1;
|
||||
.and_modify(|slot| {
|
||||
slot.count += 1;
|
||||
})
|
||||
.or_insert((entity, 1));
|
||||
.or_insert(super::InventorySlot { item: entity, count: 1, idx: key.idx });
|
||||
}
|
||||
// Get display args
|
||||
let width = get_max_inventory_width(&player_inventory);
|
||||
|
|
@ -135,7 +121,7 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
|
||||
|
||||
// Input
|
||||
match ctx.key {
|
||||
/*match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
Some(key) =>
|
||||
match key {
|
||||
|
|
@ -161,4 +147,6 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
use notan::prelude::*;
|
||||
use notan::draw::{ Draw, Font };
|
||||
use notan::draw::{ Draw, Font, DrawTextSection };
|
||||
use specs::prelude::*;
|
||||
use super::TILESIZE;
|
||||
use crate::Fonts;
|
||||
use crate::{ Fonts, camera::get_offset };
|
||||
use super::{ items, Filter, print_options, ItemType };
|
||||
|
||||
pub fn draw_inventory(ecs: &World, draw: &mut Draw, font: &Fonts, x: i32, y: i32) {
|
||||
let inv = super::get_player_inventory(ecs);
|
||||
let inv = items(ecs, Filter::Backpack);
|
||||
let offsets = crate::camera::get_offset();
|
||||
super::print_options(
|
||||
print_options(
|
||||
ecs,
|
||||
draw,
|
||||
font,
|
||||
&inv,
|
||||
|
|
@ -15,3 +17,29 @@ pub fn draw_inventory(ecs: &World, draw: &mut Draw, font: &Fonts, x: i32, y: i32
|
|||
((y as f32) + (offsets.y as f32)) * TILESIZE
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw_all(ecs: &World, draw: &mut Draw, font: &Fonts, x: f32, y: f32) {
|
||||
let mut y = y;
|
||||
|
||||
let itemtypes = vec![
|
||||
ItemType::Weapon,
|
||||
ItemType::Armour,
|
||||
ItemType::Comestible,
|
||||
ItemType::Potion,
|
||||
ItemType::Scroll,
|
||||
ItemType::Spellbook,
|
||||
ItemType::Wand,
|
||||
ItemType::Amulet,
|
||||
ItemType::Ring
|
||||
];
|
||||
|
||||
for itemtype in itemtypes {
|
||||
let inv = items(ecs, Filter::Category(itemtype));
|
||||
if inv.is_empty() {
|
||||
continue;
|
||||
}
|
||||
draw.text(&font.b(), itemtype.string()).position(x, y).color(Color::WHITE);
|
||||
y += TILESIZE;
|
||||
y = print_options(ecs, draw, font, &inv, x, y) + TILESIZE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,65 @@
|
|||
use notan::prelude::*;
|
||||
|
||||
pub fn letter_to_option(key: KeyCode, shift: bool) -> i32 {
|
||||
pub fn letter_to_option(key: KeyCode, shift: bool) -> Option<usize> {
|
||||
if shift {
|
||||
match key {
|
||||
KeyCode::A => 26,
|
||||
KeyCode::B => 27,
|
||||
KeyCode::C => 28,
|
||||
KeyCode::D => 29,
|
||||
KeyCode::E => 30,
|
||||
KeyCode::F => 31,
|
||||
KeyCode::G => 32,
|
||||
KeyCode::H => 33,
|
||||
KeyCode::I => 34,
|
||||
KeyCode::J => 35,
|
||||
KeyCode::K => 36,
|
||||
KeyCode::L => 37,
|
||||
KeyCode::M => 38,
|
||||
KeyCode::N => 39,
|
||||
KeyCode::O => 40,
|
||||
KeyCode::P => 41,
|
||||
KeyCode::Q => 42,
|
||||
KeyCode::R => 43,
|
||||
KeyCode::S => 44,
|
||||
KeyCode::T => 45,
|
||||
KeyCode::U => 46,
|
||||
KeyCode::V => 47,
|
||||
KeyCode::W => 48,
|
||||
KeyCode::X => 49,
|
||||
KeyCode::Y => 50,
|
||||
KeyCode::Z => 51,
|
||||
_ => -1,
|
||||
KeyCode::A => Some(26),
|
||||
KeyCode::B => Some(27),
|
||||
KeyCode::C => Some(28),
|
||||
KeyCode::D => Some(29),
|
||||
KeyCode::E => Some(30),
|
||||
KeyCode::F => Some(31),
|
||||
KeyCode::G => Some(32),
|
||||
KeyCode::H => Some(33),
|
||||
KeyCode::I => Some(34),
|
||||
KeyCode::J => Some(35),
|
||||
KeyCode::K => Some(36),
|
||||
KeyCode::L => Some(37),
|
||||
KeyCode::M => Some(38),
|
||||
KeyCode::N => Some(39),
|
||||
KeyCode::O => Some(40),
|
||||
KeyCode::P => Some(41),
|
||||
KeyCode::Q => Some(42),
|
||||
KeyCode::R => Some(43),
|
||||
KeyCode::S => Some(44),
|
||||
KeyCode::T => Some(45),
|
||||
KeyCode::U => Some(46),
|
||||
KeyCode::V => Some(47),
|
||||
KeyCode::W => Some(48),
|
||||
KeyCode::X => Some(49),
|
||||
KeyCode::Y => Some(50),
|
||||
KeyCode::Z => Some(51),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
match key {
|
||||
KeyCode::A => 0,
|
||||
KeyCode::B => 1,
|
||||
KeyCode::C => 2,
|
||||
KeyCode::D => 3,
|
||||
KeyCode::E => 4,
|
||||
KeyCode::F => 5,
|
||||
KeyCode::G => 6,
|
||||
KeyCode::H => 7,
|
||||
KeyCode::I => 8,
|
||||
KeyCode::J => 9,
|
||||
KeyCode::K => 10,
|
||||
KeyCode::L => 11,
|
||||
KeyCode::M => 12,
|
||||
KeyCode::N => 13,
|
||||
KeyCode::O => 14,
|
||||
KeyCode::P => 15,
|
||||
KeyCode::Q => 16,
|
||||
KeyCode::R => 17,
|
||||
KeyCode::S => 18,
|
||||
KeyCode::T => 19,
|
||||
KeyCode::U => 20,
|
||||
KeyCode::V => 21,
|
||||
KeyCode::W => 22,
|
||||
KeyCode::X => 23,
|
||||
KeyCode::Y => 24,
|
||||
KeyCode::Z => 25,
|
||||
_ => -1,
|
||||
KeyCode::A => Some(0),
|
||||
KeyCode::B => Some(1),
|
||||
KeyCode::C => Some(2),
|
||||
KeyCode::D => Some(3),
|
||||
KeyCode::E => Some(4),
|
||||
KeyCode::F => Some(5),
|
||||
KeyCode::G => Some(6),
|
||||
KeyCode::H => Some(7),
|
||||
KeyCode::I => Some(8),
|
||||
KeyCode::J => Some(9),
|
||||
KeyCode::K => Some(10),
|
||||
KeyCode::L => Some(11),
|
||||
KeyCode::M => Some(12),
|
||||
KeyCode::N => Some(13),
|
||||
KeyCode::O => Some(14),
|
||||
KeyCode::P => Some(15),
|
||||
KeyCode::Q => Some(16),
|
||||
KeyCode::R => Some(17),
|
||||
KeyCode::S => Some(18),
|
||||
KeyCode::T => Some(19),
|
||||
KeyCode::U => Some(20),
|
||||
KeyCode::V => Some(21),
|
||||
KeyCode::W => Some(22),
|
||||
KeyCode::X => Some(23),
|
||||
KeyCode::Y => Some(24),
|
||||
KeyCode::Z => Some(25),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
239
src/gui/mod.rs
239
src/gui/mod.rs
|
|
@ -32,6 +32,9 @@ use super::{
|
|||
Skills,
|
||||
Viewshed,
|
||||
BUC,
|
||||
Key,
|
||||
Item,
|
||||
ItemType,
|
||||
consts::ids::get_local_col,
|
||||
};
|
||||
use crate::consts::prelude::*;
|
||||
|
|
@ -51,7 +54,8 @@ use notan::draw::{ Draw, DrawTextSection, DrawImages, DrawShapes };
|
|||
use std::collections::HashMap;
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{ BTreeMap, HashSet };
|
||||
use crate::invkeys::check_key;
|
||||
|
||||
mod character_creation;
|
||||
mod cheat_menu;
|
||||
|
|
@ -361,7 +365,8 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
|
|||
.size(FONTSIZE);
|
||||
}
|
||||
// Equipment
|
||||
let renderables = ecs.read_storage::<Renderable>();
|
||||
draw_all(ecs, draw, font, ((VIEWPORT_W + 3) as f32) * TILESIZE, TILESIZE);
|
||||
/*let renderables = ecs.read_storage::<Renderable>();
|
||||
let mut equipment: Vec<(String, RGB, RGB, FontCharType)> = Vec::new();
|
||||
let entities = ecs.entities();
|
||||
for (entity, _equipped, renderable) in (&entities, &equipped, &renderables)
|
||||
|
|
@ -424,8 +429,8 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
|
|||
)
|
||||
.position(((DISPLAYWIDTH - 1) as f32) * TILESIZE, (y as f32) * TILESIZE)
|
||||
.size(FONTSIZE)
|
||||
.h_align_right();
|
||||
let player_inventory = get_player_inventory(&ecs);
|
||||
.h_align_right();*/
|
||||
//let player_inventory = get_player_inventory(&ecs);
|
||||
// TODO: print_options()
|
||||
}
|
||||
}
|
||||
|
|
@ -690,7 +695,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) {
|
|||
)
|
||||
);
|
||||
y += 1;
|
||||
let player_inventory = get_player_inventory(&ecs);
|
||||
//let player_inventory = get_player_inventory(&ecs);
|
||||
// Draw spells - if we have any -- NYI!
|
||||
if let Some(known_spells) = ecs.read_storage::<KnownSpells>().get(*player_entity) {
|
||||
y += 1;
|
||||
|
|
@ -914,72 +919,84 @@ pub enum ItemMenuResult {
|
|||
}
|
||||
|
||||
pub fn print_options(
|
||||
ecs: &World,
|
||||
draw: &mut Draw,
|
||||
font: &Fonts,
|
||||
inventory: &PlayerInventory,
|
||||
mut x: f32,
|
||||
mut y: f32
|
||||
) -> (f32, i32) {
|
||||
let mut j = 0;
|
||||
) -> f32 {
|
||||
let initial_x: f32 = x;
|
||||
let mut width: i32 = -1;
|
||||
for (item, (_e, item_count)) in inventory {
|
||||
let mut sorted: Vec<_> = inventory.iter().collect();
|
||||
sorted.sort_by(|a, b| a.1.idx.cmp(&b.1.idx));
|
||||
for (info, slot) in sorted {
|
||||
x = initial_x;
|
||||
// Print the character required to access this item. i.e. (a)
|
||||
if j < 26 {
|
||||
draw.text(&font.b(), &format!("{} ", (97 + j) as u8 as char))
|
||||
if slot.idx < 26 {
|
||||
draw.text(&font.b(), &format!("{} ", (97 + slot.idx) as u8 as char))
|
||||
.position(x, y)
|
||||
.color(Color::YELLOW)
|
||||
.size(FONTSIZE);
|
||||
} else {
|
||||
// If we somehow have more than 26, start using capitals
|
||||
draw.text(&font.b(), &format!("{} ", (65 - 26 + j) as u8 as char))
|
||||
draw.text(&font.b(), &format!("{} ", (65 - 26 + slot.idx) as u8 as char))
|
||||
.position(x, y)
|
||||
.color(Color::YELLOW)
|
||||
.size(FONTSIZE);
|
||||
}
|
||||
x = draw.last_text_bounds().max_x();
|
||||
let fg = RGB::from_u8(item.renderables.0, item.renderables.1, item.renderables.2);
|
||||
draw.text(&font.n(), &format!("{} ", item.glyph as u8 as char))
|
||||
let fg = RGB::from_u8(info.renderables.0, info.renderables.1, info.renderables.2);
|
||||
draw.text(&font.n(), &format!("{} ", info.glyph as u8 as char))
|
||||
.position(x, y)
|
||||
.size(FONTSIZE)
|
||||
.color(Color::from_rgb(fg.r, fg.g, fg.b));
|
||||
x = draw.last_text_bounds().max_x();
|
||||
|
||||
let fg = RGB::from_u8(item.rgb.0, item.rgb.1, item.rgb.2);
|
||||
if item_count > &1 {
|
||||
draw.text(&font.n(), &format!("{} {}", item_count, item.display_name.plural))
|
||||
let fg = RGB::from_u8(info.rgb.0, info.rgb.1, info.rgb.2);
|
||||
if slot.count > 1 {
|
||||
draw.text(&font.n(), &format!("{} {}", slot.count, info.display_name.plural))
|
||||
.position(x, y)
|
||||
.color(Color::from_rgb(fg.r, fg.g, fg.b))
|
||||
.size(FONTSIZE);
|
||||
} else {
|
||||
let prefix = if item.display_name.singular.to_lowercase().ends_with("s") {
|
||||
let prefix = if info.display_name.singular.to_lowercase().ends_with("s") {
|
||||
"some"
|
||||
} else if
|
||||
['a', 'e', 'i', 'o', 'u']
|
||||
.iter()
|
||||
.any(|&v| item.display_name.singular.to_lowercase().starts_with(v))
|
||||
.any(|&v| info.display_name.singular.to_lowercase().starts_with(v))
|
||||
{
|
||||
"an"
|
||||
} else {
|
||||
"a"
|
||||
};
|
||||
draw.text(&font.n(), &format!("{} {}", prefix, item.display_name.singular))
|
||||
draw.text(&font.n(), &format!("{} {}", prefix, info.display_name.singular))
|
||||
.position(x, y)
|
||||
.color(Color::from_rgb(fg.r, fg.g, fg.b))
|
||||
.size(FONTSIZE);
|
||||
if let Some(worn) = ecs.read_storage::<Equipped>().get(slot.item) {
|
||||
x = draw.last_text_bounds().max_x();
|
||||
use crate::EquipmentSlot;
|
||||
let text = match worn.slot {
|
||||
EquipmentSlot::Melee | EquipmentSlot::Shield => "being held",
|
||||
_ => "being worn",
|
||||
};
|
||||
draw.text(&font.ib(), &format!(" ({})", text))
|
||||
.position(x, y)
|
||||
.color(Color::WHITE)
|
||||
.size(FONTSIZE);
|
||||
};
|
||||
}
|
||||
y += TILESIZE;
|
||||
j += 1;
|
||||
}
|
||||
return (y, width);
|
||||
return y;
|
||||
}
|
||||
|
||||
pub fn get_max_inventory_width(inventory: &PlayerInventory) -> i32 {
|
||||
let mut width: i32 = 0;
|
||||
for (item, (_e, count)) in inventory {
|
||||
for (item, slot) in inventory {
|
||||
let mut this_width = 4; // The spaces before and after the character to select this item, etc.
|
||||
if count <= &1 {
|
||||
if slot.count <= 1 {
|
||||
this_width += item.display_name.singular.len() as i32;
|
||||
if item.display_name.singular == item.display_name.plural {
|
||||
this_width += 4; // "some".len
|
||||
|
|
@ -992,7 +1009,7 @@ pub fn get_max_inventory_width(inventory: &PlayerInventory) -> i32 {
|
|||
}
|
||||
} else {
|
||||
this_width += item.display_name.plural.len() as i32;
|
||||
this_width += count.to_string().len() as i32; // i.e. "12".len
|
||||
this_width += slot.count.to_string().len() as i32; // i.e. "12".len
|
||||
}
|
||||
width = if width > this_width { width } else { this_width };
|
||||
}
|
||||
|
|
@ -1043,7 +1060,7 @@ pub fn obfuscate_name(
|
|||
if has_beatitude.known {
|
||||
let prefix = match has_beatitude.buc {
|
||||
BUC::Cursed => Some("cursed "),
|
||||
BUC::Uncursed => None,
|
||||
BUC::Uncursed => Some("uncursed "),
|
||||
BUC::Blessed => Some("blessed "),
|
||||
};
|
||||
if prefix.is_some() {
|
||||
|
|
@ -1098,6 +1115,12 @@ pub fn obfuscate_name_ecs(ecs: &World, item: Entity) -> (String, String) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if let Some(worn) = ecs.read_storage::<Equipped>().get(item) {
|
||||
if worn.owner == *ecs.fetch::<Entity>() {
|
||||
singular.insert_str(singular.len(), " (worn)");
|
||||
plural.insert_str(plural.len(), " (worn)");
|
||||
}
|
||||
}
|
||||
return (singular, plural);
|
||||
}
|
||||
|
||||
|
|
@ -1254,8 +1277,6 @@ pub struct UniqueInventoryItem {
|
|||
name: String,
|
||||
}
|
||||
|
||||
pub type PlayerInventory = BTreeMap<UniqueInventoryItem, (Entity, i32)>;
|
||||
|
||||
pub fn unique(
|
||||
entity: Entity,
|
||||
names: &ReadStorage<Name>,
|
||||
|
|
@ -1325,57 +1346,74 @@ pub fn unique_ecs(ecs: &World, entity: Entity) -> UniqueInventoryItem {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn get_player_inventory(ecs: &World) -> PlayerInventory {
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let backpack = ecs.read_storage::<InBackpack>();
|
||||
let entities = ecs.entities();
|
||||
let renderables = ecs.read_storage::<Renderable>();
|
||||
|
||||
let mut player_inventory: BTreeMap<UniqueInventoryItem, (Entity, i32)> = BTreeMap::new();
|
||||
for (entity, _pack, name, renderable) in (&entities, &backpack, &names, &renderables)
|
||||
.join()
|
||||
.filter(|item| item.1.owner == *player_entity) {
|
||||
// RGB can't be used as a key. This is converting the RGB (tuple of f32) into a tuple of u8s.
|
||||
let item_colour = item_colour_ecs(ecs, entity);
|
||||
let renderables = (
|
||||
(renderable.fg.r * 255.0) as u8,
|
||||
(renderable.fg.g * 255.0) as u8,
|
||||
(renderable.fg.b * 255.0) as u8,
|
||||
);
|
||||
let (singular, plural) = obfuscate_name_ecs(ecs, entity);
|
||||
let beatitude_status = if let Some(beatitude) = ecs.read_storage::<Beatitude>().get(entity) {
|
||||
match beatitude.buc {
|
||||
BUC::Blessed => 1,
|
||||
BUC::Uncursed => 2,
|
||||
BUC::Cursed => 3,
|
||||
pub struct InventorySlot {
|
||||
pub item: Entity,
|
||||
pub count: i32,
|
||||
pub idx: usize,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let unique_item = UniqueInventoryItem {
|
||||
display_name: DisplayName { singular: singular.clone(), plural: plural },
|
||||
rgb: item_colour,
|
||||
renderables: renderables,
|
||||
glyph: renderable.glyph,
|
||||
beatitude_status: beatitude_status,
|
||||
name: name.name.clone(),
|
||||
};
|
||||
player_inventory
|
||||
.entry(unique_item)
|
||||
.and_modify(|(_e, count)| {
|
||||
*count += 1;
|
||||
|
||||
pub type PlayerInventory = HashMap<UniqueInventoryItem, InventorySlot>;
|
||||
|
||||
pub enum Filter {
|
||||
All,
|
||||
Backpack,
|
||||
Equipped,
|
||||
Category(ItemType),
|
||||
}
|
||||
|
||||
macro_rules! includeitem {
|
||||
($inv:expr, $ecs:expr, $e:expr, $k:expr) => {
|
||||
$inv.entry(unique_ecs($ecs, $e))
|
||||
.and_modify(|slot| {
|
||||
slot.count += 1;
|
||||
})
|
||||
.or_insert((entity, 1));
|
||||
.or_insert(InventorySlot {
|
||||
item: $e,
|
||||
count: 1,
|
||||
idx: $k.idx,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return player_inventory;
|
||||
pub fn items(ecs: &World, filter: Filter) -> HashMap<UniqueInventoryItem, InventorySlot> {
|
||||
let entities = ecs.entities();
|
||||
let keys = ecs.read_storage::<Key>();
|
||||
|
||||
let mut inv: HashMap<UniqueInventoryItem, InventorySlot> = HashMap::new();
|
||||
|
||||
match filter {
|
||||
Filter::All => {
|
||||
for (e, k) in (&entities, &keys).join() {
|
||||
includeitem!(inv, ecs, e, k);
|
||||
}
|
||||
}
|
||||
Filter::Backpack => {
|
||||
let backpack = ecs.read_storage::<InBackpack>();
|
||||
for (e, k, _b) in (&entities, &keys, &backpack).join() {
|
||||
includeitem!(inv, ecs, e, k);
|
||||
}
|
||||
}
|
||||
Filter::Equipped => {
|
||||
let equipped = ecs.read_storage::<Equipped>();
|
||||
for (e, k, _e) in (&entities, &keys, &equipped).join() {
|
||||
includeitem!(inv, ecs, e, k);
|
||||
}
|
||||
}
|
||||
Filter::Category(itemtype) => {
|
||||
let items = ecs.read_storage::<Item>();
|
||||
for (e, k, _i) in (&entities, &keys, &items)
|
||||
.join()
|
||||
.filter(|e| e.2.category == itemtype) {
|
||||
includeitem!(inv, ecs, e, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inv
|
||||
}
|
||||
|
||||
pub fn show_inventory(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<Entity>) {
|
||||
let player_inventory = get_player_inventory(&gs.ecs);
|
||||
let on_overmap = gs.ecs.fetch::<Map>().overmap;
|
||||
let count = player_inventory.len();
|
||||
|
||||
let key = &ctx.keyboard;
|
||||
for keycode in key.pressed.iter() {
|
||||
|
|
@ -1385,20 +1423,27 @@ pub fn show_inventory(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<
|
|||
}
|
||||
_ => {
|
||||
let shift = key.shift();
|
||||
let selection = letter_to_option::letter_to_option(*keycode, shift);
|
||||
if selection > -1 && selection < (count as i32) {
|
||||
let selection = if
|
||||
let Some(key) = letter_to_option::letter_to_option(*keycode, shift)
|
||||
{
|
||||
key
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if check_key(selection) {
|
||||
if on_overmap {
|
||||
gamelog::Logger::new().append("You can't use items on the overmap.").log();
|
||||
} else {
|
||||
return (
|
||||
ItemMenuResult::Selected,
|
||||
Some(
|
||||
player_inventory
|
||||
.iter()
|
||||
.nth(selection as usize)
|
||||
.unwrap().1.0
|
||||
),
|
||||
);
|
||||
// Get the first entity with a Key {} component that has an idx matching "selection".
|
||||
let entities = gs.ecs.entities();
|
||||
let keyed_items = gs.ecs.read_storage::<Key>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
for (e, key, _b) in (&entities, &keyed_items, &backpack).join() {
|
||||
if key.idx == selection {
|
||||
return (ItemMenuResult::Selected, Some(e));
|
||||
}
|
||||
}
|
||||
// TODO: Probably some gamelog about not having the selected item?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1408,8 +1453,6 @@ pub fn show_inventory(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<
|
|||
}
|
||||
|
||||
pub fn drop_item_menu(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<Entity>) {
|
||||
let player_inventory = get_player_inventory(&gs.ecs);
|
||||
let count = player_inventory.len();
|
||||
let on_overmap = gs.ecs.fetch::<Map>().overmap;
|
||||
|
||||
let key = &ctx.keyboard;
|
||||
|
|
@ -1420,20 +1463,26 @@ pub fn drop_item_menu(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<
|
|||
}
|
||||
_ => {
|
||||
let shift = key.shift();
|
||||
let selection = letter_to_option::letter_to_option(*keycode, shift);
|
||||
if selection > -1 && selection < (count as i32) {
|
||||
let selection = if
|
||||
let Some(key) = letter_to_option::letter_to_option(*keycode, shift)
|
||||
{
|
||||
key
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if check_key(selection) {
|
||||
if on_overmap {
|
||||
gamelog::Logger::new().append("You can't drop items on the overmap.").log();
|
||||
} else {
|
||||
return (
|
||||
ItemMenuResult::Selected,
|
||||
Some(
|
||||
player_inventory
|
||||
.iter()
|
||||
.nth(selection as usize)
|
||||
.unwrap().1.0
|
||||
),
|
||||
);
|
||||
// Get the first entity with a Key {} component that has an idx matching "selection".
|
||||
let entities = gs.ecs.entities();
|
||||
let keyed_items = gs.ecs.read_storage::<Key>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
for (e, key, _b) in (&entities, &keyed_items, &backpack).join() {
|
||||
if key.idx == selection {
|
||||
return (ItemMenuResult::Selected, Some(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ use super::{
|
|||
item_colour_ecs,
|
||||
obfuscate_name_ecs,
|
||||
print_options,
|
||||
unique_ecs,
|
||||
renderable_colour,
|
||||
ItemMenuResult,
|
||||
UniqueInventoryItem,
|
||||
InventorySlot,
|
||||
};
|
||||
use crate::{
|
||||
gamelog,
|
||||
|
|
@ -18,10 +20,11 @@ use crate::{
|
|||
Renderable,
|
||||
states::state::*,
|
||||
BUC,
|
||||
Key,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Handles the Remove Curse menu.
|
||||
pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) {
|
||||
|
|
@ -33,11 +36,12 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
let beatitudes = gs.ecs.read_storage::<Beatitude>();
|
||||
let names = gs.ecs.read_storage::<Name>();
|
||||
let renderables = gs.ecs.read_storage::<Renderable>();
|
||||
let keys = gs.ecs.read_storage::<Key>();
|
||||
|
||||
let build_cursed_iterator = || {
|
||||
(&entities, &items, &beatitudes, &renderables, &names)
|
||||
(&entities, &items, &beatitudes, &renderables, &names, &keys)
|
||||
.join()
|
||||
.filter(|(item_entity, _i, b, _r, _n)| {
|
||||
.filter(|(item_entity, _i, b, _r, _n, _k)| {
|
||||
// Set all items to FALSE initially.
|
||||
let mut keep = false;
|
||||
// If found in the player's backpack, set to TRUE
|
||||
|
|
@ -86,8 +90,8 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
.log();
|
||||
return (ItemMenuResult::Selected, Some(item));
|
||||
}
|
||||
let mut player_inventory: super::PlayerInventory = BTreeMap::new();
|
||||
for (entity, _i, _b, renderable, name) in build_cursed_iterator() {
|
||||
let mut player_inventory: super::PlayerInventory = HashMap::new();
|
||||
for (entity, _i, _b, renderable, name, key) in build_cursed_iterator() {
|
||||
let (singular, plural) = obfuscate_name_ecs(&gs.ecs, entity);
|
||||
let beatitude_status = if
|
||||
let Some(beatitude) = gs.ecs.read_storage::<Beatitude>().get(entity)
|
||||
|
|
@ -100,20 +104,17 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
} else {
|
||||
0
|
||||
};
|
||||
let unique_item = UniqueInventoryItem {
|
||||
display_name: super::DisplayName { singular: singular.clone(), plural: plural.clone() },
|
||||
rgb: item_colour_ecs(&gs.ecs, entity),
|
||||
renderables: renderable_colour(&renderables, entity),
|
||||
glyph: renderable.glyph,
|
||||
beatitude_status: beatitude_status,
|
||||
name: name.name.clone(),
|
||||
};
|
||||
let unique_item = unique_ecs(&gs.ecs, entity);
|
||||
player_inventory
|
||||
.entry(unique_item)
|
||||
.and_modify(|(_e, count)| {
|
||||
*count += 1;
|
||||
.and_modify(|slot| {
|
||||
slot.count += 1;
|
||||
})
|
||||
.or_insert((entity, 1));
|
||||
.or_insert(InventorySlot {
|
||||
item: entity,
|
||||
count: 1,
|
||||
idx: key.idx,
|
||||
});
|
||||
}
|
||||
// Get display args
|
||||
let width = get_max_inventory_width(&player_inventory);
|
||||
|
|
@ -130,7 +131,7 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
|
||||
|
||||
// Input
|
||||
match ctx.key {
|
||||
/*match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
Some(key) =>
|
||||
match key {
|
||||
|
|
@ -155,5 +156,6 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ pub fn restore_invkeys(invkeys: HashMap<UniqueInventoryItem, usize>) {
|
|||
INVKEYS.lock().unwrap().extend(invkeys);
|
||||
}
|
||||
|
||||
pub fn check_key(idx: usize) -> bool {
|
||||
let lock = ASSIGNEDKEYS.lock().unwrap();
|
||||
lock[idx]
|
||||
}
|
||||
|
||||
pub fn item_exists(item: &UniqueInventoryItem) -> Option<usize> {
|
||||
let invkeys = INVKEYS.lock().unwrap();
|
||||
use bracket_lib::prelude::*;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ pub struct Item {
|
|||
pub id: String,
|
||||
pub name: Name,
|
||||
pub renderable: Option<Renderable>,
|
||||
pub class: String,
|
||||
pub weight: Option<f32>,
|
||||
pub value: Option<f32>,
|
||||
pub equip: Option<Equippable>,
|
||||
|
|
|
|||
|
|
@ -290,6 +290,18 @@ pub fn spawn_named_item(
|
|||
eb = eb.with(Item {
|
||||
weight: item_template.weight.unwrap_or(0.0),
|
||||
value: item_template.value.unwrap_or(0.0),
|
||||
category: match item_template.class.as_str() {
|
||||
"amulet" => ItemType::Amulet,
|
||||
"weapon" => ItemType::Weapon,
|
||||
"armour" => ItemType::Armour,
|
||||
"comestible" => ItemType::Comestible,
|
||||
"scroll" => ItemType::Scroll,
|
||||
"spellbook" => ItemType::Spellbook,
|
||||
"potion" => ItemType::Potion,
|
||||
"ring" => ItemType::Ring,
|
||||
"wand" => ItemType::Wand,
|
||||
_ => unreachable!("Unknown item type."),
|
||||
},
|
||||
});
|
||||
eb = spawn_position(pos, eb, key, raws);
|
||||
if needs_key {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue