Obfuscate names of scrolls and potions in other scenarios

This commit is contained in:
Timothy Warren 2022-01-19 14:35:13 -05:00
parent ce11412d54
commit 444b692779
4 changed files with 109 additions and 8 deletions

View File

@ -1,7 +1,7 @@
use ::rltk::Rltk; use ::rltk::Rltk;
use ::specs::prelude::*; use ::specs::prelude::*;
use crate::components::{Attributes, Hidden, Name, Pools, Position}; use crate::components::{Attributes, Hidden, Pools, Position};
use crate::{camera, colors, Map}; use crate::{camera, colors, Map};
struct Tooltip { struct Tooltip {
@ -58,12 +58,12 @@ pub(super) fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
let (min_x, _max_x, min_y, _max_y) = camera::get_screen_bounds(ecs, ctx); let (min_x, _max_x, min_y, _max_y) = camera::get_screen_bounds(ecs, ctx);
let map = ecs.fetch::<Map>(); let map = ecs.fetch::<Map>();
let names = ecs.read_storage::<Name>();
let positions = ecs.read_storage::<Position>(); let positions = ecs.read_storage::<Position>();
let hidden = ecs.read_storage::<Hidden>(); let hidden = ecs.read_storage::<Hidden>();
let attributes = ecs.read_storage::<Attributes>(); let attributes = ecs.read_storage::<Attributes>();
let pools = ecs.read_storage::<Pools>(); let pools = ecs.read_storage::<Pools>();
let entities = ecs.entities(); let entities = ecs.entities();
let mouse_pos = ctx.mouse_pos(); let mouse_pos = ctx.mouse_pos();
let mut mouse_map_pos = mouse_pos; let mut mouse_map_pos = mouse_pos;
mouse_map_pos.0 += min_x; mouse_map_pos.0 += min_x;
@ -82,10 +82,10 @@ pub(super) fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
} }
let mut tip_boxes: Vec<Tooltip> = Vec::new(); let mut tip_boxes: Vec<Tooltip> = Vec::new();
for (entity, name, position, _hidden) in (&entities, &names, &positions, !&hidden).join() { for (entity, position, _hidden) in (&entities, &positions, !&hidden).join() {
if position.x == mouse_map_pos.0 && position.y == mouse_map_pos.1 { if position.x == mouse_map_pos.0 && position.y == mouse_map_pos.1 {
let mut tip = Tooltip::new(); let mut tip = Tooltip::new();
tip.add(name.name.to_string()); tip.add(super::get_item_display_name(ecs, entity));
// Comment on attributes // Comment on attributes
if let Some(attr) = attributes.get(entity) { if let Some(attr) = attributes.get(entity) {

View File

@ -5,6 +5,30 @@ use crate::game_log::GameLog;
use crate::particle_system::ParticleBuilder; use crate::particle_system::ParticleBuilder;
use crate::{colors, raws, spatial, Map, MasterDungeonMap, RunState}; use crate::{colors, raws, spatial, Map, MasterDungeonMap, RunState};
fn obfuscate_name(
item: Entity,
names: &ReadStorage<Name>,
magic_items: &ReadStorage<MagicItem>,
obfuscated_names: &ReadStorage<ObfuscatedName>,
dm: &MasterDungeonMap,
) -> String {
if let Some(name) = names.get(item) {
if magic_items.get(item).is_some() {
if dm.identified_items.contains(&name.name) {
name.name.clone()
} else if let Some(obfuscated) = obfuscated_names.get(item) {
obfuscated.name.clone()
} else {
"Unidentified magic item".to_string()
}
} else {
name.name.clone()
}
} else {
"Nameless item (bug)".to_string()
}
}
pub struct ItemCollectionSystem {} pub struct ItemCollectionSystem {}
impl<'a> System<'a> for ItemCollectionSystem { impl<'a> System<'a> for ItemCollectionSystem {
@ -17,6 +41,9 @@ impl<'a> System<'a> for ItemCollectionSystem {
ReadStorage<'a, Name>, ReadStorage<'a, Name>,
WriteStorage<'a, InBackpack>, WriteStorage<'a, InBackpack>,
WriteStorage<'a, EquipmentChanged>, WriteStorage<'a, EquipmentChanged>,
ReadStorage<'a, MagicItem>,
ReadStorage<'a, ObfuscatedName>,
ReadExpect<'a, MasterDungeonMap>,
); );
fn run(&mut self, data: Self::SystemData) { fn run(&mut self, data: Self::SystemData) {
@ -28,6 +55,9 @@ impl<'a> System<'a> for ItemCollectionSystem {
names, names,
mut backpack, mut backpack,
mut dirty, mut dirty,
magic_items,
obfuscated_names,
dm,
) = data; ) = data;
for pickup in wants_pickup.join() { for pickup in wants_pickup.join() {
@ -47,7 +77,7 @@ impl<'a> System<'a> for ItemCollectionSystem {
if pickup.collected_by == *player_entity { if pickup.collected_by == *player_entity {
gamelog.append(format!( gamelog.append(format!(
"You pick up the {}.", "You pick up the {}.",
names.get(pickup.item).unwrap().name obfuscate_name(pickup.item, &names, &magic_items, &obfuscated_names, &dm)
)); ));
} }
} }
@ -408,6 +438,9 @@ impl<'a> System<'a> for ItemDropSystem {
WriteStorage<'a, Position>, WriteStorage<'a, Position>,
WriteStorage<'a, InBackpack>, WriteStorage<'a, InBackpack>,
WriteStorage<'a, EquipmentChanged>, WriteStorage<'a, EquipmentChanged>,
ReadStorage<'a, MagicItem>,
ReadStorage<'a, ObfuscatedName>,
ReadExpect<'a, MasterDungeonMap>,
); );
fn run(&mut self, data: Self::SystemData) { fn run(&mut self, data: Self::SystemData) {
@ -420,6 +453,9 @@ impl<'a> System<'a> for ItemDropSystem {
mut positions, mut positions,
mut backpack, mut backpack,
mut dirty, mut dirty,
magic_items,
obfuscated_names,
dm,
) = data; ) = data;
for (entity, to_drop) in (&entities, &wants_drop).join() { for (entity, to_drop) in (&entities, &wants_drop).join() {
@ -449,7 +485,7 @@ impl<'a> System<'a> for ItemDropSystem {
if entity == *player_entity { if entity == *player_entity {
gamelog.append(format!( gamelog.append(format!(
"You drop the {}.", "You drop the {}.",
names.get(to_drop.item).unwrap().name obfuscate_name(to_drop.item, &names, &magic_items, &obfuscated_names, &dm)
)); ));
} }
} }

View File

@ -7,12 +7,14 @@ use ::specs::prelude::*;
use crate::components::{OtherLevelPosition, Position, Viewshed}; use crate::components::{OtherLevelPosition, Position, Viewshed};
use crate::map::{Map, TileType}; use crate::map::{Map, TileType};
use crate::map_builders::level_builder; use crate::map_builders::level_builder;
use crate::raws;
#[derive(Default, Serialize, Deserialize, Clone)] #[derive(Default, Serialize, Deserialize, Clone)]
pub struct MasterDungeonMap { pub struct MasterDungeonMap {
maps: HashMap<i32, Map>, maps: HashMap<i32, Map>,
pub identified_items: HashSet<String>, pub identified_items: HashSet<String>,
pub scroll_mappings: HashMap<String, String>, pub scroll_mappings: HashMap<String, String>,
pub potion_mappings: HashMap<String, String>,
} }
impl MasterDungeonMap { impl MasterDungeonMap {
@ -21,15 +23,23 @@ impl MasterDungeonMap {
maps: HashMap::new(), maps: HashMap::new(),
identified_items: HashSet::new(), identified_items: HashSet::new(),
scroll_mappings: HashMap::new(), scroll_mappings: HashMap::new(),
potion_mappings: HashMap::new(),
}; };
let mut rng = RandomNumberGenerator::new(); let mut rng = RandomNumberGenerator::new();
for scroll_tag in crate::raws::get_scroll_tags().iter() { for scroll_tag in raws::get_scroll_tags().iter() {
let masked_name = make_scroll_name(&mut rng); let masked_name = make_scroll_name(&mut rng);
dm.scroll_mappings dm.scroll_mappings
.insert(scroll_tag.to_string(), masked_name); .insert(scroll_tag.to_string(), masked_name);
} }
let mut used_potion_names = HashSet::new();
for potion_tag in raws::get_potion_tags().iter() {
let masked_name = make_potion_name(&mut rng, &mut used_potion_names);
dm.potion_mappings
.insert(potion_tag.to_string(), masked_name);
}
dm dm
} }
@ -89,6 +99,36 @@ fn make_scroll_name(rng: &mut rltk::RandomNumberGenerator) -> String {
name name
} }
const POTION_COLORS: &[&str] = &[
"Red", "Orange", "Yellow", "Green", "Brown", "Indigo", "Violet",
];
const POTION_ADJECTIVES: &[&str] = &[
"Swirling",
"Effervescent",
"Slimey",
"Oiley",
"Viscous",
"Smelly",
"Glowing",
];
fn make_potion_name(rng: &mut RandomNumberGenerator, used_names: &mut HashSet<String>) -> String {
loop {
let mut name = POTION_ADJECTIVES
[rng.roll_dice(1, POTION_ADJECTIVES.len() as i32) as usize - 1]
.to_string();
name += " ";
name += POTION_COLORS[rng.roll_dice(1, POTION_COLORS.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_depth: i32, offset: i32) -> Option<Vec<Map>> { pub fn level_transition(ecs: &mut World, new_depth: i32, offset: i32) -> Option<Vec<Map>> {
// Obtain the master dungeon map // Obtain the master dungeon map
let dungeon_master = ecs.read_resource::<MasterDungeonMap>(); let dungeon_master = ecs.read_resource::<MasterDungeonMap>();

View File

@ -196,6 +196,21 @@ pub fn get_scroll_tags() -> Vec<String> {
result result
} }
pub fn get_potion_tags() -> Vec<String> {
let raws = &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.clone());
}
}
}
result
}
pub fn is_tag_magic(tag: &str) -> bool { pub fn is_tag_magic(tag: &str) -> bool {
let raws = &RAWS.lock().unwrap(); let raws = &RAWS.lock().unwrap();
if raws.item_index.contains_key(tag) { if raws.item_index.contains_key(tag) {
@ -264,6 +279,7 @@ pub fn spawn_named_item(
let dm = ecs.fetch::<MasterDungeonMap>(); let dm = ecs.fetch::<MasterDungeonMap>();
let scroll_names = dm.scroll_mappings.clone(); let scroll_names = dm.scroll_mappings.clone();
let potion_names = dm.potion_mappings.clone();
let identified = dm.identified_items.clone(); let identified = dm.identified_items.clone();
std::mem::drop(dm); std::mem::drop(dm);
@ -374,7 +390,16 @@ pub fn spawn_named_item(
name: scroll_names[&item_template.name].clone(), name: scroll_names[&item_template.name].clone(),
}) })
} }
_ => {} "potion" => {
eb = eb.with(ObfuscatedName {
name: potion_names[&item_template.name].clone(),
})
}
_ => {
eb = eb.with(ObfuscatedName {
name: magic.naming.clone(),
})
}
} }
} }
} }