id bugfixes
This commit is contained in:
parent
b8d7194f28
commit
1ec876a10d
7 changed files with 122 additions and 45 deletions
|
|
@ -6,7 +6,8 @@
|
|||
"weight": 1,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "provides_healing": "12" }
|
||||
"effects": { "provides_healing": "12" },
|
||||
"magic": { "class": "common", "naming": "potion" }
|
||||
},
|
||||
{
|
||||
"id": "potion_health_weak",
|
||||
|
|
@ -15,7 +16,8 @@
|
|||
"weight": 1,
|
||||
"value": 25,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "provides_healing": "6" }
|
||||
"effects": { "provides_healing": "6" },
|
||||
"magic": { "class": "common", "naming": "potion" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_magicmissile",
|
||||
|
|
@ -272,7 +274,8 @@
|
|||
"weight": 2,
|
||||
"value": 100,
|
||||
"flags": ["WAND"],
|
||||
"effects": { "ranged": "12", "damage": "10" }
|
||||
"effects": { "ranged": "12", "damage": "10" },
|
||||
"magic": { "class": "uncommon", "naming": "wand" }
|
||||
},
|
||||
{
|
||||
"id": "wand_fireball",
|
||||
|
|
@ -281,7 +284,8 @@
|
|||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["WAND"],
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" }
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" },
|
||||
"magic": { "class": "rare", "naming": "wand" }
|
||||
},
|
||||
{
|
||||
"id": "wand_confusion",
|
||||
|
|
@ -290,7 +294,8 @@
|
|||
"weight": 2,
|
||||
"value": 200,
|
||||
"flags": ["WAND"],
|
||||
"effects": { "ranged": "10", "confusion": "4" }
|
||||
"effects": { "ranged": "10", "confusion": "4" },
|
||||
"magic": { "class": "uncommon", "naming": "wand" }
|
||||
},
|
||||
{
|
||||
"id": "wand_digging",
|
||||
|
|
@ -299,7 +304,8 @@
|
|||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["WAND"],
|
||||
"effects": { "ranged": "10", "digger": "" }
|
||||
"effects": { "ranged": "10", "digger": "" },
|
||||
"magic": { "class": "rare", "naming": "wand" }
|
||||
},
|
||||
{
|
||||
"id": "food_rations",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ pub fn show_cheat_menu(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult {
|
|||
// Godmode
|
||||
ctx.set(x_offset + 2, y, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), rltk::to_cp437('g'));
|
||||
ctx.print(x_offset + 4, y, "GOD MODE");
|
||||
y += 1;
|
||||
// Match keys
|
||||
match ctx.key {
|
||||
None => CheatMenuResult::NoResponse,
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ pub enum ItemMenuResult {
|
|||
}
|
||||
|
||||
pub fn print_options(
|
||||
inventory: BTreeMap<(String, String, (u8, u8, u8)), i32>,
|
||||
inventory: BTreeMap<UniqueInventoryItem, i32>,
|
||||
mut x: i32,
|
||||
mut y: i32,
|
||||
ctx: &mut Rltk,
|
||||
|
|
@ -300,8 +300,8 @@ pub fn print_options(
|
|||
let mut j = 0;
|
||||
let initial_x: i32 = x;
|
||||
let mut width: i32 = -1;
|
||||
for (name, item_count) in &inventory {
|
||||
let fg = RGB::from_u8(name.2 .0, name.2 .1, name.2 .2);
|
||||
for (item, item_count) in &inventory {
|
||||
let fg = RGB::from_u8(item.rgb.0, item.rgb.1, item.rgb.2);
|
||||
x = initial_x;
|
||||
// Print the character required to access this item. i.e. (a)
|
||||
if j < 26 {
|
||||
|
|
@ -318,12 +318,12 @@ pub fn print_options(
|
|||
// i.e. (a) 3 daggers
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), item_count);
|
||||
x += 2;
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), name.1.to_string());
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), item.display_name.singular.to_string());
|
||||
} else {
|
||||
if name.0.ends_with("s") {
|
||||
if item.display_name.singular.ends_with("s") {
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), "some");
|
||||
x += 5;
|
||||
} else if ['a', 'e', 'i', 'o', 'u'].iter().any(|&v| name.0.starts_with(v)) {
|
||||
} else if ['a', 'e', 'i', 'o', 'u'].iter().any(|&v| item.display_name.singular.starts_with(v)) {
|
||||
// If one and starts with a vowel, print 'an'
|
||||
// i.e. (a) an apple
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), "an");
|
||||
|
|
@ -334,9 +334,9 @@ pub fn print_options(
|
|||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), "a");
|
||||
x += 2;
|
||||
}
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), name.0.to_string());
|
||||
ctx.print_color(x, y, fg, RGB::named(rltk::BLACK), item.display_name.singular.to_string());
|
||||
}
|
||||
let this_width = x - initial_x + name.0.len() as i32;
|
||||
let this_width = x - initial_x + item.display_name.singular.len() as i32;
|
||||
width = if width > this_width { width } else { this_width };
|
||||
|
||||
y += 1;
|
||||
|
|
@ -346,15 +346,15 @@ pub fn print_options(
|
|||
return (y, width);
|
||||
}
|
||||
|
||||
pub fn get_max_inventory_width(inventory: &BTreeMap<(String, String, (u8, u8, u8)), i32>) -> i32 {
|
||||
pub fn get_max_inventory_width(inventory: &BTreeMap<UniqueInventoryItem, i32>) -> i32 {
|
||||
let mut width: i32 = 0;
|
||||
for (name, count) in inventory {
|
||||
let mut this_width = name.0.len() as i32;
|
||||
for (item, count) in inventory {
|
||||
let mut this_width = item.display_name.singular.len() as i32;
|
||||
if count < &1 {
|
||||
this_width += 4;
|
||||
if name.0.ends_with("s") {
|
||||
if item.display_name.singular.ends_with("s") {
|
||||
this_width += 3;
|
||||
} else if ['a', 'e', 'i', 'o', 'u'].iter().any(|&v| name.0.starts_with(v)) {
|
||||
} else if ['a', 'e', 'i', 'o', 'u'].iter().any(|&v| item.display_name.singular.starts_with(v)) {
|
||||
this_width += 1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -366,22 +366,29 @@ pub fn get_max_inventory_width(inventory: &BTreeMap<(String, String, (u8, u8, u8
|
|||
}
|
||||
|
||||
pub fn get_item_display_name(ecs: &World, item: Entity) -> (String, String) {
|
||||
let (mut singular, mut plural) = ("nameless item (bug)".to_string(), "nameless items (bug)".to_string());
|
||||
if let Some(name) = ecs.read_storage::<Name>().get(item) {
|
||||
if ecs.read_storage::<MagicItem>().get(item).is_some() {
|
||||
let dm = ecs.fetch::<crate::map::MasterDungeonMap>();
|
||||
if dm.identified_items.contains(&name.name) {
|
||||
return (name.name.clone(), name.plural.clone());
|
||||
(singular, plural) = (name.name.clone(), name.plural.clone());
|
||||
} else if let Some(obfuscated) = ecs.read_storage::<ObfuscatedName>().get(item) {
|
||||
return (obfuscated.name.clone(), obfuscated.plural.clone());
|
||||
(singular, plural) = (obfuscated.name.clone(), obfuscated.plural.clone());
|
||||
} else {
|
||||
return ("unid magic item".to_string(), "unid magic items".to_string());
|
||||
(singular, plural) = ("unid magic item".to_string(), "unid magic items".to_string());
|
||||
}
|
||||
} else {
|
||||
return (name.name.clone(), name.plural.clone());
|
||||
(singular, plural) = (name.name.clone(), name.plural.clone());
|
||||
}
|
||||
} else {
|
||||
return ("nameless item (bug)".to_string(), "nameless items (bug)".to_string());
|
||||
}
|
||||
if let Some(wand) = ecs.read_storage::<crate::Wand>().get(item) {
|
||||
let used = wand.max_uses - wand.uses;
|
||||
for _i in 0..used {
|
||||
singular.push_str("*");
|
||||
plural.push_str("*");
|
||||
}
|
||||
}
|
||||
return (singular, plural);
|
||||
}
|
||||
|
||||
pub fn show_help(ctx: &mut Rltk) -> YesNoResult {
|
||||
|
|
@ -431,7 +438,20 @@ pub fn show_help(ctx: &mut Rltk) -> YesNoResult {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_player_inventory(ecs: &World) -> (BTreeMap<(String, String, (u8, u8, u8)), i32>, BTreeMap<String, Entity>) {
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct DisplayName {
|
||||
singular: String,
|
||||
plural: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UniqueInventoryItem {
|
||||
display_name: DisplayName,
|
||||
rgb: (u8, u8, u8),
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub fn get_player_inventory(ecs: &World) -> (BTreeMap<UniqueInventoryItem, i32>, BTreeMap<String, Entity>) {
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let backpack = ecs.read_storage::<InBackpack>();
|
||||
|
|
@ -439,7 +459,7 @@ pub fn get_player_inventory(ecs: &World) -> (BTreeMap<(String, String, (u8, u8,
|
|||
let renderables = ecs.read_storage::<Renderable>();
|
||||
|
||||
let mut inventory_ids: BTreeMap<String, Entity> = BTreeMap::new();
|
||||
let mut player_inventory: BTreeMap<(String, String, (u8, u8, u8)), i32> = BTreeMap::new();
|
||||
let mut player_inventory: BTreeMap<UniqueInventoryItem, i32> = BTreeMap::new();
|
||||
for (entity, _pack, name) in (&entities, &backpack, &names).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 (r, g, b): (u8, u8, u8) = if let Some(renderable) = renderables.get(entity) {
|
||||
|
|
@ -448,8 +468,15 @@ pub fn get_player_inventory(ecs: &World) -> (BTreeMap<(String, String, (u8, u8,
|
|||
(255, 255, 255)
|
||||
};
|
||||
let (singular, plural) = get_item_display_name(ecs, entity);
|
||||
player_inventory.entry((singular, plural, (r, g, b))).and_modify(|count| *count += 1).or_insert(1);
|
||||
inventory_ids.entry(name.name.to_string()).or_insert(entity);
|
||||
player_inventory
|
||||
.entry(UniqueInventoryItem {
|
||||
display_name: DisplayName { singular: singular.clone(), plural: plural },
|
||||
rgb: (r, g, b),
|
||||
name: name.name.clone(),
|
||||
})
|
||||
.and_modify(|count| *count += 1)
|
||||
.or_insert(1);
|
||||
inventory_ids.entry(singular).or_insert(entity);
|
||||
}
|
||||
|
||||
return (player_inventory, inventory_ids);
|
||||
|
|
|
|||
|
|
@ -136,9 +136,6 @@ impl<'a> System<'a> for ItemUseSystem {
|
|||
consumables.insert(wants_to_use.item, Consumable {}).expect("Could not insert consumable");
|
||||
}
|
||||
verb = "zap";
|
||||
// TODO: Change this to track uses better, after adding in identification.
|
||||
name.name.push_str("*");
|
||||
name.plural.push_str("*");
|
||||
wand.uses -= 1;
|
||||
}
|
||||
|
||||
|
|
@ -435,6 +432,7 @@ impl<'a> System<'a> for ItemIdentificationSystem {
|
|||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (player, mut identified, mut dm, items, names, mut obfuscated_names, entities) = data;
|
||||
for (_p, id) in (&player, &identified).join() {
|
||||
rltk::console::log(id.name.clone());
|
||||
let tag = crate::raws::get_id_from_name(id.name.clone());
|
||||
if !dm.identified_items.contains(&id.name) && crate::raws::is_tag_magic(&tag) {
|
||||
dm.identified_items.insert(id.name.clone());
|
||||
|
|
|
|||
|
|
@ -10,19 +10,29 @@ pub struct MasterDungeonMap {
|
|||
maps: HashMap<i32, Map>,
|
||||
pub identified_items: HashSet<String>,
|
||||
pub scroll_map: HashMap<String, (String, String)>,
|
||||
pub potion_map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl MasterDungeonMap {
|
||||
/// Initialises a blank MasterDungeonMap
|
||||
pub fn new() -> MasterDungeonMap {
|
||||
let mut dm =
|
||||
MasterDungeonMap { maps: HashMap::new(), identified_items: HashSet::new(), scroll_map: HashMap::new() };
|
||||
let mut dm = MasterDungeonMap {
|
||||
maps: HashMap::new(),
|
||||
identified_items: HashSet::new(),
|
||||
scroll_map: HashMap::new(),
|
||||
potion_map: HashMap::new(),
|
||||
};
|
||||
// TODO: Use stored RNG
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
for scroll_tag in crate::raws::get_scroll_tags().iter() {
|
||||
let (unid_singular, unid_plural) = make_scroll_name(&mut rng);
|
||||
dm.scroll_map.insert(scroll_tag.to_string(), (unid_singular, unid_plural));
|
||||
}
|
||||
let mut used_potion_names: HashSet<String> = HashSet::new();
|
||||
for potion_tag in crate::raws::get_potion_tags().iter() {
|
||||
let unid_singular = make_potion_name(&mut rng, &mut used_potion_names);
|
||||
dm.potion_map.insert(potion_tag.to_string(), unid_singular);
|
||||
}
|
||||
|
||||
return dm;
|
||||
}
|
||||
|
|
@ -88,6 +98,25 @@ fn make_scroll_name(rng: &mut RandomNumberGenerator) -> (String, String) {
|
|||
return (singular, plural);
|
||||
}
|
||||
|
||||
const POTION_COLOURS: &[&str] =
|
||||
&["red", "orange", "yellow", "green", "blue", "indigo", "violet", "black", "white", "silver", "gold"];
|
||||
const POTION_ADJECTIVES: &[&str] = &["swirling", "viscous", "effervescent", "slimy", "oily", "metallic"];
|
||||
|
||||
fn make_potion_name(rng: &mut RandomNumberGenerator, used_names: &mut HashSet<String>) -> String {
|
||||
loop {
|
||||
let mut name: String =
|
||||
POTION_ADJECTIVES[rng.roll_dice(1, POTION_ADJECTIVES.len() as i32) as usize - 1].to_string();
|
||||
name += " ";
|
||||
name += POTION_COLOURS[rng.roll_dice(1, POTION_COLOURS.len() as i32) as usize - 1];
|
||||
name += " potion";
|
||||
|
||||
if !used_names.contains(&name) {
|
||||
used_names.insert(name.clone());
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn level_transition(ecs: &mut World, new_id: i32, offset: i32) -> Option<Vec<Map>> {
|
||||
// Obtain master
|
||||
let dungeon_master = ecs.read_resource::<MasterDungeonMap>();
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ pub fn spawn_named_item(raws: &RawMaster, ecs: &mut World, key: &str, pos: Spawn
|
|||
let item_template = &raws.raws.items[raws.item_index[key]];
|
||||
let dm = ecs.fetch::<crate::map::MasterDungeonMap>();
|
||||
let scroll_names = dm.scroll_map.clone();
|
||||
let potion_names = dm.potion_map.clone();
|
||||
let identified_items = dm.identified_items.clone();
|
||||
std::mem::drop(dm);
|
||||
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||
|
|
@ -190,7 +191,18 @@ pub fn spawn_named_item(raws: &RawMaster, ecs: &mut World, key: &str, pos: Spawn
|
|||
plural: scroll_names[&item_template.name.name].1.clone(),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
"potion" => {
|
||||
let singular = potion_names[&item_template.name.name].clone();
|
||||
let mut plural = singular.clone();
|
||||
plural += "s";
|
||||
eb = eb.with(ObfuscatedName { name: singular, plural: plural })
|
||||
}
|
||||
_ => {
|
||||
let singular = magic_item.naming.clone();
|
||||
let mut plural = singular.clone();
|
||||
plural += "s";
|
||||
eb = eb.with(ObfuscatedName { name: singular, plural: plural })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -661,6 +673,19 @@ pub fn get_scroll_tags() -> Vec<String> {
|
|||
return result;
|
||||
}
|
||||
|
||||
pub fn get_potion_tags() -> Vec<String> {
|
||||
let raws = &super::RAWS.lock().unwrap();
|
||||
let mut result = Vec::new();
|
||||
for item in raws.raws.items.iter() {
|
||||
if let Some(magic) = &item.magic {
|
||||
if &magic.naming == "potion" {
|
||||
result.push(item.name.name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn get_id_from_name(name: String) -> String {
|
||||
let raws = &super::RAWS.lock().unwrap();
|
||||
for item in &raws.raws.items {
|
||||
|
|
|
|||
|
|
@ -72,21 +72,14 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
raws::spawn_named_entity(
|
||||
&raws::RAWS.lock().unwrap(),
|
||||
ecs,
|
||||
"scroll_fireball",
|
||||
"wand_fireball",
|
||||
raws::SpawnType::Carried { by: player },
|
||||
0,
|
||||
);
|
||||
raws::spawn_named_entity(
|
||||
&raws::RAWS.lock().unwrap(),
|
||||
ecs,
|
||||
"scroll_fireball",
|
||||
raws::SpawnType::Carried { by: player },
|
||||
0,
|
||||
);
|
||||
raws::spawn_named_entity(
|
||||
&raws::RAWS.lock().unwrap(),
|
||||
ecs,
|
||||
"scroll_fireball",
|
||||
"wand_magicmissile",
|
||||
raws::SpawnType::Carried { by: player },
|
||||
0,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue