obfuscates names of unidentified items
This commit is contained in:
parent
7795044d36
commit
9e768c5f73
9 changed files with 166 additions and 29 deletions
|
|
@ -24,7 +24,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "ranged": "12", "damage": "10" }
|
||||
"effects": { "ranged": "12", "damage": "10" },
|
||||
"magic": { "class": "common", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_fireball",
|
||||
|
|
@ -33,7 +34,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 150,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" }
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" },
|
||||
"magic": { "class": "rare", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_fireball_c",
|
||||
|
|
@ -42,7 +44,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 150,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "CURSED"],
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" }
|
||||
"effects": { "ranged": "10", "damage": "15", "aoe": "3" },
|
||||
"magic": { "class": "rare", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_confusion",
|
||||
|
|
@ -51,7 +54,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "ranged": "10", "confusion": "4" }
|
||||
"effects": { "ranged": "10", "confusion": "4" },
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_magicmap",
|
||||
|
|
@ -60,7 +64,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "magicmapper": "" }
|
||||
"effects": { "magicmapper": "" },
|
||||
"magic": { "class": "common", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_magicmap_c",
|
||||
|
|
@ -69,7 +74,8 @@
|
|||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "CURSED"],
|
||||
"effects": { "magicmapper": "" }
|
||||
"effects": { "magicmapper": "" },
|
||||
"magic": { "class": "common", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "equip_dagger",
|
||||
|
|
|
|||
|
|
@ -222,6 +222,12 @@ pub struct MagicItem {
|
|||
pub class: MagicItemClass,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ObfuscatedName {
|
||||
pub name: String,
|
||||
pub plural: String,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct EquipmentChanged {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::{
|
||||
ai::CARRY_CAPACITY_PER_STRENGTH, camera, gamelog, gamesystem, rex_assets::RexAssets, ArmourClassBonus, Attributes,
|
||||
Burden, Equipped, Hidden, HungerClock, HungerState, InBackpack, Map, Name, Player, Point, Pools, Position, Prop,
|
||||
Renderable, RunState, Skill, Skills, State, Viewshed,
|
||||
Burden, Equipped, Hidden, HungerClock, HungerState, InBackpack, MagicItem, Map, Name, ObfuscatedName, Player,
|
||||
Point, Pools, Position, Prop, Renderable, RunState, Skill, Skills, State, Viewshed,
|
||||
};
|
||||
use rltk::{Rltk, VirtualKeyCode, RGB};
|
||||
use specs::prelude::*;
|
||||
|
|
@ -143,13 +143,13 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
ctx.print_color(20, 20, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), "--- GODMODE: ON ---");
|
||||
}
|
||||
// Draw equipment
|
||||
let names = ecs.read_storage::<Name>();
|
||||
let renderables = ecs.read_storage::<Renderable>();
|
||||
let mut equipment: Vec<(String, RGB)> = Vec::new();
|
||||
for (_equipped, name, renderable) in
|
||||
(&equipped, &names, &renderables).join().filter(|item| item.0.owner == *player_entity)
|
||||
let entities = ecs.entities();
|
||||
for (entity, _equipped, renderable) in
|
||||
(&entities, &equipped, &renderables).join().filter(|item| item.1.owner == *player_entity)
|
||||
{
|
||||
equipment.push((name.name.to_string(), renderable.fg));
|
||||
equipment.push((get_item_display_name(ecs, entity).0, renderable.fg));
|
||||
}
|
||||
let mut y = 1;
|
||||
if !equipment.is_empty() {
|
||||
|
|
@ -205,12 +205,13 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
if entity == &*player_entity {
|
||||
draw = false;
|
||||
}
|
||||
let name = &names.get(*entity);
|
||||
if let Some(name) = name {
|
||||
if draw {
|
||||
let fg = renderables.get(*entity).unwrap().fg;
|
||||
seen_entities.push((name.name.to_string(), fg));
|
||||
}
|
||||
if draw {
|
||||
let fg = if let Some(renderable) = renderables.get(*entity) {
|
||||
renderable.fg
|
||||
} else {
|
||||
RGB::named(rltk::WHITE)
|
||||
};
|
||||
seen_entities.push((get_item_display_name(ecs, *entity).0, fg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -360,6 +361,25 @@ pub fn get_max_inventory_width(inventory: &BTreeMap<(String, String, (u8, u8, u8
|
|||
return width;
|
||||
}
|
||||
|
||||
pub fn get_item_display_name(ecs: &World, item: Entity) -> (String, 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());
|
||||
} else if let Some(obfuscated) = ecs.read_storage::<ObfuscatedName>().get(item) {
|
||||
return (obfuscated.name.clone(), obfuscated.plural.clone());
|
||||
} else {
|
||||
return ("unid magic item".to_string(), "unid magic items".to_string());
|
||||
}
|
||||
} else {
|
||||
return (name.name.clone(), name.plural.clone());
|
||||
}
|
||||
} else {
|
||||
return ("nameless item (bug)".to_string(), "nameless items (bug)".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn show_help(ctx: &mut Rltk) -> YesNoResult {
|
||||
let mut x = 3;
|
||||
let mut y = 12;
|
||||
|
|
@ -423,10 +443,8 @@ pub fn get_player_inventory(ecs: &World) -> (BTreeMap<(String, String, (u8, u8,
|
|||
} else {
|
||||
(255, 255, 255)
|
||||
};
|
||||
player_inventory
|
||||
.entry((name.name.to_string(), name.plural.to_string(), (r, g, b)))
|
||||
.and_modify(|count| *count += 1)
|
||||
.or_insert(1);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -505,10 +523,9 @@ pub fn drop_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Option
|
|||
|
||||
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 inventory = (&backpack).join().filter(|item| item.owner == *player_entity);
|
||||
let count = inventory.count();
|
||||
|
||||
let (x_offset, y_offset) = (1, 10);
|
||||
|
|
@ -523,8 +540,8 @@ pub fn remove_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Opti
|
|||
|
||||
let mut equippable: Vec<(Entity, String)> = Vec::new();
|
||||
let mut width = 3;
|
||||
for (entity, _pack, name) in (&entities, &backpack, &names).join().filter(|item| item.1.owner == *player_entity) {
|
||||
let this_name = &name.name;
|
||||
for (entity, _pack) in (&entities, &backpack).join().filter(|item| item.1.owner == *player_entity) {
|
||||
let this_name = &get_item_display_name(&gs.ecs, entity).0;
|
||||
let this_width = 3 + this_name.len();
|
||||
width = if width > this_width { width } else { this_width };
|
||||
equippable.push((entity, this_name.to_string()));
|
||||
|
|
|
|||
|
|
@ -526,6 +526,7 @@ fn main() -> rltk::BError {
|
|||
gs.ecs.register::<Viewshed>();
|
||||
gs.ecs.register::<Telepath>();
|
||||
gs.ecs.register::<Name>();
|
||||
gs.ecs.register::<ObfuscatedName>();
|
||||
gs.ecs.register::<BlocksTile>();
|
||||
gs.ecs.register::<BlocksVisibility>();
|
||||
gs.ecs.register::<Door>();
|
||||
|
|
|
|||
|
|
@ -3,17 +3,28 @@ use crate::{gamelog, map_builders, OtherLevelPosition, Position, Telepath, Views
|
|||
use rltk::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone)]
|
||||
pub struct MasterDungeonMap {
|
||||
maps: HashMap<i32, Map>,
|
||||
pub identified_items: HashSet<String>,
|
||||
pub scroll_map: HashMap<String, (String, String)>,
|
||||
}
|
||||
|
||||
impl MasterDungeonMap {
|
||||
/// Initialises a blank MasterDungeonMap
|
||||
pub fn new() -> MasterDungeonMap {
|
||||
return MasterDungeonMap { maps: HashMap::new() };
|
||||
let mut dm =
|
||||
MasterDungeonMap { maps: HashMap::new(), identified_items: HashSet::new(), scroll_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));
|
||||
}
|
||||
|
||||
return dm;
|
||||
}
|
||||
/// Stores the given map in the MasterDungeonMap
|
||||
pub fn store_map(&mut self, map: &Map) {
|
||||
|
|
@ -31,6 +42,52 @@ impl MasterDungeonMap {
|
|||
}
|
||||
}
|
||||
|
||||
fn make_scroll_name(rng: &mut RandomNumberGenerator) -> (String, String) {
|
||||
let len = 4 + rng.roll_dice(1, 4);
|
||||
let mut singular = "scroll of ".to_string();
|
||||
let mut plural = "scrolls of ".to_string();
|
||||
for i in 0..len {
|
||||
if i % 2 == 0 {
|
||||
let char = match rng.roll_dice(1, 5) {
|
||||
1 => "a",
|
||||
2 => "e",
|
||||
3 => "i",
|
||||
4 => "o",
|
||||
_ => "u",
|
||||
};
|
||||
singular += char;
|
||||
plural += char;
|
||||
} else {
|
||||
let char = match rng.roll_dice(1, 21) {
|
||||
1 => "b",
|
||||
2 => "c",
|
||||
3 => "d",
|
||||
4 => "f",
|
||||
5 => "g",
|
||||
6 => "h",
|
||||
7 => "j",
|
||||
8 => "k",
|
||||
9 => "l",
|
||||
10 => "m",
|
||||
11 => "n",
|
||||
12 => "p",
|
||||
13 => "q",
|
||||
14 => "r",
|
||||
15 => "s",
|
||||
16 => "t",
|
||||
17 => "v",
|
||||
18 => "w",
|
||||
19 => "x",
|
||||
20 => "y",
|
||||
_ => "z",
|
||||
};
|
||||
singular += char;
|
||||
plural += char;
|
||||
}
|
||||
}
|
||||
return (singular, plural);
|
||||
}
|
||||
|
||||
pub fn level_transition(ecs: &mut World, new_id: i32, offset: i32) -> Option<Vec<Map>> {
|
||||
// Obtain master
|
||||
let dungeon_master = ecs.read_resource::<MasterDungeonMap>();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ pub struct Item {
|
|||
pub value: Option<f32>,
|
||||
pub flags: Option<Vec<String>>,
|
||||
pub effects: Option<HashMap<String, String>>,
|
||||
pub magic: Option<MagicItem>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
|
@ -25,3 +26,9 @@ pub struct Renderable {
|
|||
pub bg: String,
|
||||
pub order: i32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct MagicItem {
|
||||
pub class: String,
|
||||
pub naming: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ pub fn spawn_named_entity(
|
|||
pub fn spawn_named_item(raws: &RawMaster, ecs: &mut World, key: &str, pos: SpawnType) -> Option<Entity> {
|
||||
if raws.item_index.contains_key(key) {
|
||||
let item_template = &raws.raws.items[raws.item_index[key]];
|
||||
let scroll_names = ecs.fetch::<crate::map::MasterDungeonMap>().scroll_map.clone();
|
||||
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||
|
||||
eb = eb.with(Name { name: item_template.name.name.clone(), plural: item_template.name.plural.clone() });
|
||||
|
|
@ -146,7 +147,6 @@ pub fn spawn_named_item(raws: &RawMaster, ecs: &mut World, key: &str, pos: Spawn
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut base_damage = "1d4";
|
||||
let mut hit_bonus = 0;
|
||||
|
||||
|
|
@ -168,6 +168,27 @@ pub fn spawn_named_item(raws: &RawMaster, ecs: &mut World, key: &str, pos: Spawn
|
|||
}
|
||||
}
|
||||
}
|
||||
if let Some(magic_item) = &item_template.magic {
|
||||
let item_class = match magic_item.class.as_str() {
|
||||
"common" => MagicItemClass::Common,
|
||||
"uncommon" => MagicItemClass::Uncommon,
|
||||
"rare" => MagicItemClass::Rare,
|
||||
"veryrare" => MagicItemClass::VeryRare,
|
||||
_ => MagicItemClass::Legendary,
|
||||
};
|
||||
eb = eb.with(MagicItem { class: item_class });
|
||||
|
||||
#[allow(clippy::single_match)]
|
||||
match magic_item.naming.as_str() {
|
||||
"scroll" => {
|
||||
eb = eb.with(ObfuscatedName {
|
||||
name: scroll_names[&item_template.name.name].0.clone(),
|
||||
plural: scroll_names[&item_template.name.name].1.clone(),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if weapon_type != -1 {
|
||||
let (n_dice, die_type, bonus) = parse_dice_string(base_damage);
|
||||
|
|
@ -621,3 +642,16 @@ pub fn get_mob_spawn_amount(rng: &mut RandomNumberGenerator, spawn_type: &Spawns
|
|||
_ => return roll,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_scroll_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 == "scroll" {
|
||||
result.push(item.name.name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ pub fn save_game(ecs: &mut World) {
|
|||
MultiAttack,
|
||||
NaturalAttacks,
|
||||
Name,
|
||||
ObfuscatedName,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
|
|
@ -198,6 +199,7 @@ pub fn load_game(ecs: &mut World) {
|
|||
MultiAttack,
|
||||
NaturalAttacks,
|
||||
Name,
|
||||
ObfuscatedName,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,13 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
raws::SpawnType::Equipped { by: player },
|
||||
0,
|
||||
);
|
||||
raws::spawn_named_entity(
|
||||
&raws::RAWS.lock().unwrap(),
|
||||
ecs,
|
||||
"equip_dagger",
|
||||
raws::SpawnType::Equipped { by: player },
|
||||
0,
|
||||
);
|
||||
raws::spawn_named_entity(
|
||||
&raws::RAWS.lock().unwrap(),
|
||||
ecs,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue