Allow identifying items by use or purchase
This commit is contained in:
parent
dd8a3b4f6f
commit
2dc2a4549a
@ -384,6 +384,11 @@ pub struct ObfuscatedName {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct IdentifiedItem {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
|
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
|
||||||
// Entity.
|
// Entity.
|
||||||
|
|
||||||
|
@ -761,8 +761,8 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
|||||||
|
|
||||||
ctx.draw_box_double(24, 18, 31, 10, colors::WHEAT, colors::BLACK);
|
ctx.draw_box_double(24, 18, 31, 10, colors::WHEAT, colors::BLACK);
|
||||||
|
|
||||||
ctx.print_color_centered(20, colors::YELLOW, colors::BLACK, "Rust Roguelike Tutorial");
|
ctx.print_color_centered(20, colors::YELLOW, colors::BLACK, "Rust Roguelike");
|
||||||
ctx.print_color_centered(21, colors::CYAN, colors::BLACK, "by Herbert Wolverson");
|
ctx.print_color_centered(21, colors::CYAN, colors::BLACK, "by Timothy J. Warren");
|
||||||
ctx.print_color_centered(
|
ctx.print_color_centered(
|
||||||
22,
|
22,
|
||||||
colors::GRAY,
|
colors::GRAY,
|
||||||
|
@ -3,7 +3,7 @@ use ::specs::prelude::*;
|
|||||||
use crate::components::*;
|
use crate::components::*;
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::particle_system::ParticleBuilder;
|
use crate::particle_system::ParticleBuilder;
|
||||||
use crate::{colors, spatial, Map, RunState};
|
use crate::{colors, raws, spatial, Map, MasterDungeonMap, RunState};
|
||||||
|
|
||||||
pub struct ItemCollectionSystem {}
|
pub struct ItemCollectionSystem {}
|
||||||
|
|
||||||
@ -85,6 +85,7 @@ impl<'a> System<'a> for ItemUseSystem {
|
|||||||
WriteExpect<'a, RunState>,
|
WriteExpect<'a, RunState>,
|
||||||
WriteStorage<'a, EquipmentChanged>,
|
WriteStorage<'a, EquipmentChanged>,
|
||||||
ReadStorage<'a, TownPortal>,
|
ReadStorage<'a, TownPortal>,
|
||||||
|
WriteStorage<'a, IdentifiedItem>,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
@ -114,6 +115,7 @@ impl<'a> System<'a> for ItemUseSystem {
|
|||||||
mut runstate,
|
mut runstate,
|
||||||
mut dirty,
|
mut dirty,
|
||||||
town_portal,
|
town_portal,
|
||||||
|
mut identified_item,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
for (entity, useitem) in (&entities, &wants_use).join() {
|
for (entity, useitem) in (&entities, &wants_use).join() {
|
||||||
@ -161,6 +163,18 @@ impl<'a> System<'a> for ItemUseSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Identify
|
||||||
|
if entity == *player_entity {
|
||||||
|
identified_item
|
||||||
|
.insert(
|
||||||
|
entity,
|
||||||
|
IdentifiedItem {
|
||||||
|
name: names.get(useitem.item).unwrap().name.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Unable to identify item");
|
||||||
|
}
|
||||||
|
|
||||||
// If it is equippable, then we want to equip it - and unequip whatever else was in that slot
|
// If it is equippable, then we want to equip it - and unequip whatever else was in that slot
|
||||||
match equippable.get(useitem.item) {
|
match equippable.get(useitem.item) {
|
||||||
None => {}
|
None => {}
|
||||||
@ -468,3 +482,37 @@ impl<'a> System<'a> for ItemRemoveSystem {
|
|||||||
wants_remove.clear();
|
wants_remove.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ItemIdentificationSystem {}
|
||||||
|
|
||||||
|
impl<'a> System<'a> for ItemIdentificationSystem {
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
type SystemData = (
|
||||||
|
ReadStorage<'a, Player>,
|
||||||
|
WriteStorage<'a, IdentifiedItem>,
|
||||||
|
WriteExpect<'a, MasterDungeonMap>,
|
||||||
|
ReadStorage<'a, Item>,
|
||||||
|
ReadStorage<'a, Name>,
|
||||||
|
WriteStorage<'a, ObfuscatedName>,
|
||||||
|
Entities<'a>,
|
||||||
|
);
|
||||||
|
|
||||||
|
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() {
|
||||||
|
if !dm.identified_items.contains(&id.name) && raws::is_tag_magic(&id.name) {
|
||||||
|
dm.identified_items.insert(id.name.clone());
|
||||||
|
|
||||||
|
for (entity, _item, name) in (&entities, &items, &names).join() {
|
||||||
|
if name.name == id.name {
|
||||||
|
obfuscated_names.remove(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
identified.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -78,6 +78,7 @@ fn main() -> ::rltk::BError {
|
|||||||
Faction,
|
Faction,
|
||||||
Hidden,
|
Hidden,
|
||||||
HungerClock,
|
HungerClock,
|
||||||
|
IdentifiedItem,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
Initiative,
|
Initiative,
|
||||||
|
@ -196,6 +196,16 @@ pub fn get_scroll_tags() -> Vec<String> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_tag_magic(tag: &str) -> bool {
|
||||||
|
let raws = &RAWS.lock().unwrap();
|
||||||
|
if raws.item_index.contains_key(tag) {
|
||||||
|
let item_template = &raws.raws.items[raws.item_index[tag]];
|
||||||
|
item_template.magic.is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn spawn_position<'a>(
|
fn spawn_position<'a>(
|
||||||
pos: SpawnType,
|
pos: SpawnType,
|
||||||
new_entity: EntityBuilder<'a>,
|
new_entity: EntityBuilder<'a>,
|
||||||
@ -251,7 +261,12 @@ pub fn spawn_named_item(
|
|||||||
) -> Option<Entity> {
|
) -> Option<Entity> {
|
||||||
if raws.item_index.contains_key(key) {
|
if raws.item_index.contains_key(key) {
|
||||||
let item_template = &raws.raws.items[raws.item_index[key]];
|
let item_template = &raws.raws.items[raws.item_index[key]];
|
||||||
let scroll_names = ecs.fetch::<MasterDungeonMap>().scroll_mappings.clone();
|
|
||||||
|
let dm = ecs.fetch::<MasterDungeonMap>();
|
||||||
|
let scroll_names = dm.scroll_mappings.clone();
|
||||||
|
let identified = dm.identified_items.clone();
|
||||||
|
std::mem::drop(dm);
|
||||||
|
|
||||||
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||||
|
|
||||||
// Spawn in the specified location
|
// Spawn in the specified location
|
||||||
@ -351,6 +366,7 @@ pub fn spawn_named_item(
|
|||||||
};
|
};
|
||||||
eb = eb.with(MagicItem { class });
|
eb = eb.with(MagicItem { class });
|
||||||
|
|
||||||
|
if !identified.contains(&item_template.name) {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match magic.naming.as_str() {
|
match magic.naming.as_str() {
|
||||||
"scroll" => {
|
"scroll" => {
|
||||||
@ -361,6 +377,7 @@ pub fn spawn_named_item(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Some(eb.build());
|
return Some(eb.build());
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ pub fn save_game(ecs: &mut World) {
|
|||||||
Faction,
|
Faction,
|
||||||
Hidden,
|
Hidden,
|
||||||
HungerClock,
|
HungerClock,
|
||||||
|
IdentifiedItem,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
Initiative,
|
Initiative,
|
||||||
@ -195,6 +196,7 @@ pub fn load_game(ecs: &mut World) {
|
|||||||
Faction,
|
Faction,
|
||||||
Hidden,
|
Hidden,
|
||||||
HungerClock,
|
HungerClock,
|
||||||
|
IdentifiedItem,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
Initiative,
|
Initiative,
|
||||||
|
16
src/state.rs
16
src/state.rs
@ -7,7 +7,7 @@ use crate::game_log::GameLog;
|
|||||||
use crate::gui::{self, show_cheat_mode, CheatMenuResult, MainMenuSelection};
|
use crate::gui::{self, show_cheat_mode, CheatMenuResult, MainMenuSelection};
|
||||||
use crate::hunger_system::HungerSystem;
|
use crate::hunger_system::HungerSystem;
|
||||||
use crate::inventory_system::{
|
use crate::inventory_system::{
|
||||||
ItemCollectionSystem, ItemDropSystem, ItemRemoveSystem, ItemUseSystem,
|
ItemCollectionSystem, ItemDropSystem, ItemIdentificationSystem, ItemRemoveSystem, ItemUseSystem,
|
||||||
};
|
};
|
||||||
use crate::lighting_system::LightingSystem;
|
use crate::lighting_system::LightingSystem;
|
||||||
use crate::map::{self, *};
|
use crate::map::{self, *};
|
||||||
@ -127,6 +127,9 @@ impl State {
|
|||||||
let mut items = ItemUseSystem {};
|
let mut items = ItemUseSystem {};
|
||||||
items.run_now(&self.ecs);
|
items.run_now(&self.ecs);
|
||||||
|
|
||||||
|
let mut item_id = ItemIdentificationSystem {};
|
||||||
|
item_id.run_now(&self.ecs);
|
||||||
|
|
||||||
let mut drop_items = ItemDropSystem {};
|
let mut drop_items = ItemDropSystem {};
|
||||||
drop_items.run_now(&self.ecs);
|
drop_items.run_now(&self.ecs);
|
||||||
|
|
||||||
@ -466,7 +469,16 @@ impl GameState for State {
|
|||||||
let tag = result.2.unwrap();
|
let tag = result.2.unwrap();
|
||||||
let price = result.3.unwrap();
|
let price = result.3.unwrap();
|
||||||
let mut pools = self.ecs.write_storage::<Pools>();
|
let mut pools = self.ecs.write_storage::<Pools>();
|
||||||
let player_pools = pools.get_mut(*self.ecs.fetch::<Entity>()).unwrap();
|
let player_entity = self.ecs.fetch::<Entity>();
|
||||||
|
|
||||||
|
let mut identified = self.ecs.write_storage::<IdentifiedItem>();
|
||||||
|
identified
|
||||||
|
.insert(*player_entity, IdentifiedItem { name: tag.clone() })
|
||||||
|
.expect("Unable to identify item");
|
||||||
|
std::mem::drop(identified);
|
||||||
|
|
||||||
|
let player_pools = pools.get_mut(*player_entity).unwrap();
|
||||||
|
std::mem::drop(player_entity);
|
||||||
if player_pools.gold >= price {
|
if player_pools.gold >= price {
|
||||||
player_pools.gold -= price;
|
player_pools.gold -= price;
|
||||||
std::mem::drop(pools);
|
std::mem::drop(pools);
|
||||||
|
Loading…
Reference in New Issue
Block a user