use crate::prelude::*; use super::*; impl Dashboard { pub fn mock () -> Self { Dashboard { campaign: "В Поисках Дмитрия Шардалина".to_owned(), campaign_image: "https://assetsio.gnwcdn.com/dnd-5e-journeys-through-the-radiant-citadel-salted-legacy-artwork.jpg?width=690&quality=80&format=jpg&auto=webp".to_owned(), session: 12, date: NaiveDate::from_ymd_opt(1488, 3, 19).unwrap(), player: PlayerData { name: Name { first: "Абоба".to_string(), last: "Амогус".to_string(), alias: "Такелажник".to_string(), }, class: "Чувствительный молодой человек".to_string(), image: "https://i.pinimg.com/736x/25/58/32/2558329d333fda61615da6ce50dcddda.jpg".to_owned(), level: 8, xp: 3231, temp_hp: 12, hp: 1, max_hp: 61, balance: Balance { platinum: 12, gold: 200, electrum: 1, silver: 101, copper: 129021021 }, spell_slots: SpellSlots(core::array::from_fn(|i| SpellSlotLevel { used: 1, total: 9 - i as u8 })), attunements: Attunements([const { None }; 3]), hit_dice: HitDice { used: 1, total: 7 }, death_save_throws: DeathSaveThrows { failed: 1, succeeded: 3 }, prepared: PreparedSpells(vec![Spell { name: "Fire Bolt".to_owned() }]), inventory: generate_mock_inventory(), }, common: CommonData { balance: Balance { platinum: 1312, gold: 3211200, electrum: 231, silver: 1, copper: 21021 }, inventory: generate_mock_inventory(), }, quest_book: generate_mock_questbook(), notes: generate_mock_notebook(), people: generate_mock_contact_book(), } } } fn generate_mock_inventory() -> Inventory { let items = vec![ InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Vorpal Sword".to_string(), weight: Some(4.0), description: Some("A blade that severs heads with a single swing.".to_string()), tags: HashMap::from([ ("type".to_string(), "weapon".to_string()), ("rarity".to_string(), "legendary".to_string()), ]), }), }, InventoryEntry { quantity: 3, item: InventoryItem::Custom(CustomInventoryItem { name: "Potion of Healing".to_string(), weight: Some(0.5), description: Some("A vial of red liquid that restores vitality.".to_string()), tags: HashMap::from([ ("type".to_string(), "potion".to_string()), ("rarity".to_string(), "common".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Cloak of Elvenkind".to_string(), weight: Some(1.0), description: Some("A cloak that blends into shadows.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "uncommon".to_string()), ]), }), }, InventoryEntry { quantity: 2, item: InventoryItem::Custom(CustomInventoryItem { name: "Bag of Holding".to_string(), weight: Some(15.0), description: Some("A small bag with vast internal space.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "uncommon".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Mithril Chainmail".to_string(), weight: Some(20.0), description: Some("Lightweight armor that gleams like silver.".to_string()), tags: HashMap::from([ ("type".to_string(), "armor".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Wand of Fireballs".to_string(), weight: Some(0.2), description: Some("A wand that unleashes fiery explosions.".to_string()), tags: HashMap::from([ ("type".to_string(), "wand".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Ring of Invisibility".to_string(), weight: Some(0.1), description: Some("Grants the wearer invisibility.".to_string()), tags: HashMap::from([ ("type".to_string(), "ring".to_string()), ("rarity".to_string(), "legendary".to_string()), ]), }), }, InventoryEntry { quantity: 2, item: InventoryItem::Custom(CustomInventoryItem { name: "Boots of Speed".to_string(), weight: Some(1.5), description: Some("Boots that enhance the wearer's speed.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Dagger of Venom".to_string(), weight: Some(1.0), description: Some("A dagger coated with deadly poison.".to_string()), tags: HashMap::from([ ("type".to_string(), "weapon".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Staff of Power".to_string(), weight: Some(5.0), description: Some("A staff pulsing with arcane might.".to_string()), tags: HashMap::from([ ("type".to_string(), "staff".to_string()), ("rarity".to_string(), "very rare".to_string()), ]), }), }, InventoryEntry { quantity: 4, item: InventoryItem::Custom(CustomInventoryItem { name: "Torch".to_string(), weight: Some(1.0), description: Some("A simple torch for illumination.".to_string()), tags: HashMap::from([ ("type".to_string(), "tool".to_string()), ("rarity".to_string(), "common".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Amulet of Health".to_string(), weight: Some(0.3), description: Some("Boosts the wearer's vitality.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Flame Tongue".to_string(), weight: Some(3.0), description: Some("A sword that ignites on command.".to_string()), tags: HashMap::from([ ("type".to_string(), "weapon".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 5, item: InventoryItem::Custom(CustomInventoryItem { name: "Arrow of Slaying".to_string(), weight: Some(0.1), description: Some("An arrow designed to kill a specific foe.".to_string()), tags: HashMap::from([ ("type".to_string(), "ammunition".to_string()), ("rarity".to_string(), "very rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Cloak of Displacement".to_string(), weight: Some(1.0), description: Some("Makes the wearer hard to hit.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Helm of Teleportation".to_string(), weight: Some(3.0), description: Some("Allows teleportation to known locations.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Crystal Ball".to_string(), weight: Some(7.0), description: Some("A magical orb for scrying.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "very rare".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Gauntlets of Ogre Power".to_string(), weight: Some(2.0), description: Some("Grants the strength of an ogre.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "uncommon".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Robe of the Archmagi".to_string(), weight: Some(1.0), description: Some("Enhances a wizard's spellcasting.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "legendary".to_string()), ]), }), }, InventoryEntry { quantity: 1, item: InventoryItem::Custom(CustomInventoryItem { name: "Horn of Blasting".to_string(), weight: Some(2.0), description: Some("Emits a destructive sonic blast.".to_string()), tags: HashMap::from([ ("type".to_string(), "wondrous".to_string()), ("rarity".to_string(), "rare".to_string()), ]), }), }, ]; Inventory(items) } fn generate_mock_notebook () -> NoteBook { NoteBook(vec![ Note { session: 1, content: "Met Elminster in Waterdeep; hinted at Netherese ruin.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 4, 15).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-01 14:30:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Elminster".to_string(), "Waterdeep".to_string()]) }, Note { session: 2, content: "Zhentarim agents watching Baldur's Gate tavern.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 4, 16).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-02 09:15:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Zhentarim".to_string()]) }, Note { session: 3, content: "Phandalin: Redbrands extorting locals, hideout in manor.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 4, 20).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-03 18:45:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Phandalin".to_string(), "Redbrands".to_string()]) }, Note { session: 4, content: "Neverember offers 100gp for bandit leader's head.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 4, 22).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-04 11:20:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Neverwinter".to_string()]) }, Note { session: 5, content: "Strange rune in Underdark; ask Candlekeep scholars.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 1).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-05 20:10:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Underdark".to_string(), "Candlekeep".to_string()]) }, Note { session: 6, content: "Luskan pirates smuggling at docks; check crates.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 3).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-06 15:30:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Luskan".to_string()]) }, Note { session: 7, content: "Silverymoon wards flicker at midnight; sabotage?".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 5).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-07 22:00:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Silverymoon".to_string(), "Arcane".to_string()]) }, Note { session: 8, content: "Daggerford militia needs help with Cragmaw goblins.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 7).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-08 12:45:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Daggerford".to_string()]) }, Note { session: 9, content: "Suzail's Lathander temple requests festival guards.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 10).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-09 10:00:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Suzail".to_string(), "Lathander".to_string()]) }, Note { session: 10, content: "Rumors of dragon in Evermoors; need fire resistance.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 12).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-10 17:25:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Evermoors".to_string()]) }, Note { session: 11, content: "Harpers want Zhentarim plans from Zhentil Keep.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 15).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-11 08:50:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::from_iter(vec!["Harpers".to_string(), "Zhentarim".to_string()]) }, Note { session: 12, content: "Shady Cormyr merchant; possible doppelganger.".to_string(), date_ingame: NaiveDate::from_ymd_opt(1481, 5, 17).unwrap(), date_real: NaiveDateTime::parse_from_str("2025-09-11 14:00:00", "%Y-%m-%d %H:%M:%S").unwrap(), tags: HashSet::new() }, ]) } fn generate_mock_questbook () -> QuestBook { QuestBook(vec![ Quest { title: "Slay the Bandit Chief".to_string(), location_taken: Some("Waterdeep".to_string()), location_task: Some("Phandalin".to_string()), date_taken: Some(NaiveDate::from_ymd_opt(1481, 4, 15).unwrap()), date_by: Some(NaiveDate::from_ymd_opt(1481, 5, 15).unwrap()), description: Some("Kill the bandit leader.".to_string()), from: Some(Name { first: "Dagult".to_string(), last: "Neverember".to_string(), alias: "".to_string(), ..Default::default() }), reward: Some(Balance { platinum: 0, gold: 100, electrum: 0, silver: 0, copper: 0 }) }, Quest { title: "Find the Lost Artifact".to_string(), location_taken: Some("Baldur's Gate".to_string()), location_task: None, date_taken: Some(NaiveDate::from_ymd_opt(1481, 6, 1).unwrap()), date_by: None, description: Some("Seek a relic in ruins.".to_string()), from: Some(Name { first: "Elminster".to_string(), last: "".to_string(), alias: "The Sage of Shadowdale".to_string() }), reward: Some(Balance { platinum: 10, gold: 50, electrum: 0, silver: 0, copper: 0 }) }, Quest { title: "Escort the Caravan".to_string(), location_taken: Some("Neverwinter".to_string()), location_task: Some("Luskan".to_string()), date_taken: None, date_by: Some(NaiveDate::from_ymd_opt(1481, 7, 30).unwrap()), description: Some("Protect traders.".to_string()), from: None, reward: Some(Balance { platinum: 0, gold: 20, electrum: 0, silver: 50, copper: 0 }) }, Quest { title: "Clear the Goblin Den".to_string(), location_taken: Some("Daggerford".to_string()), location_task: Some("Cragmaw Hideout".to_string()), date_taken: Some(NaiveDate::from_ymd_opt(1481, 3, 10).unwrap()), date_by: Some(NaiveDate::from_ymd_opt(1481, 4, 10).unwrap()), description: None, from: Some(Name { first: "".to_string(), last: "".to_string(), alias: "Local Militia".to_string(), ..Default::default() }), reward: Some(Balance { platinum: 0, gold: 30, electrum: 0, silver: 0, copper: 100 }) }, Quest { title: "Rescue the Noble".to_string(), location_taken: None, location_task: Some("Underdark".to_string()), date_taken: Some(NaiveDate::from_ymd_opt(1481, 5, 20).unwrap()), date_by: None, description: Some("Save a kidnapped noble.".to_string()), from: Some(Name { first: "".to_string(), last: "Silverhand".to_string(), alias: "".to_string(), ..Default::default() }), reward: Some(Balance { platinum: 5, gold: 200, electrum: 0, silver: 0, copper: 0 }) }, Quest { title: "Steal the Zhentarim Plans".to_string(), location_taken: Some("Zhentil Keep".to_string()), location_task: Some("Zhentil Keep".to_string()), date_taken: None, date_by: Some(NaiveDate::from_ymd_opt(1481, 8, 15).unwrap()), description: None, from: Some(Name { first: "".to_string(), last: "".to_string(), alias: "Harpers".to_string(), ..Default::default() }), reward: Some(Balance { platinum: 0, gold: 75, electrum: 0, silver: 0, copper: 0 }) }, Quest { title: "Hunt the Dire Wolf".to_string(), location_taken: Some("Silverymoon".to_string()), location_task: Some("Evermoors".to_string()), date_taken: Some(NaiveDate::from_ymd_opt(1481, 2, 5).unwrap()), date_by: None, description: Some("Track and kill a beast.".to_string()), from: None, reward: Some(Balance { platinum: 0, gold: 15, electrum: 0, silver: 20, copper: 50 }) }, Quest { title: "Recover the Spellbook".to_string(), location_taken: Some("Candlekeep".to_string()), location_task: None, date_taken: Some(NaiveDate::from_ymd_opt(1481, 1, 10).unwrap()), date_by: Some(NaiveDate::from_ymd_opt(1481, 2, 10).unwrap()), description: Some("Find a stolen tome.".to_string()), from: Some(Name { first: "".to_string(), last: "".to_string(), alias: "Candlekeep Scholars".to_string(), ..Default::default() }), reward: None }, Quest { title: "Guard the Temple".to_string(), location_taken: Some("Suzail".to_string()), location_task: Some("Temple of Lathander".to_string()), date_taken: None, date_by: None, description: Some("Protect the shrine.".to_string()), from: Some(Name { first: "".to_string(), last: "".to_string(), alias: "Clerics of Lathander".to_string(), ..Default::default() }), reward: Some(Balance { platinum: 0, gold: 50, electrum: 0, silver: 0, copper: 0 }) }, Quest { title: "Explore the Ruins".to_string(), location_taken: Some("Cormyr".to_string()), location_task: Some("Netherese Ruins".to_string()), date_taken: Some(NaiveDate::from_ymd_opt(1481, 9, 1).unwrap()), date_by: Some(NaiveDate::from_ymd_opt(1481, 10, 1).unwrap()), description: None, from: None, reward: None }, ]) } fn generate_mock_contact_book () -> ContactBook { let mut contacts = HashMap::new(); // 40 Characters Met by Party (80%) contacts.insert("Elminster".to_string(), Contact { name: Name { first: "Elminster".to_string(), last: "".to_string(), alias: "The Sage of Shadowdale".to_string() }, image: None, status: Some(ContactStatus::Alive), location: Some("Shadowdale".to_string()), notes: Some("Wise but cryptic wizard.".to_string()) }); contacts.insert("Drizzt Do'Urden".to_string(), Contact { name: Name { first: "Drizzt".to_string(), last: "Do'Urden".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Icewind Dale".to_string()), notes: Some("Renegade drow ranger.".to_string()) }); contacts.insert("Lord Neverember".to_string(), Contact { name: Name { first: "Dagult".to_string(), last: "Neverember".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Neverwinter".to_string()), notes: Some("Ruler seeking bandit leader.".to_string()) }); contacts.insert("Minsc".to_string(), Contact { name: Name { first: "Minsc".to_string(), last: "".to_string(), alias: "Rascal of Rashemen".to_string() }, image: None, status: Some(ContactStatus::Alive), location: Some("Baldur's Gate".to_string()), notes: Some("Loud warrior with hamster.".to_string()) }); contacts.insert("Jarlaxle".to_string(), Contact { name: Name { first: "Jarlaxle".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Luskan".to_string()), notes: Some("Sly drow mercenary leader.".to_string()) }); contacts.insert("Volo".to_string(), Contact { name: Name { first: "Volothamp".to_string(), last: "Geddarm".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Waterdeep".to_string()), notes: Some("Exaggerates his travel tales.".to_string()) }); contacts.insert("Laeral Silverhand".to_string(), Contact { name: Name { first: "Laeral".to_string(), last: "Silverhand".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Waterdeep".to_string()), notes: Some("Open Lord, powerful mage.".to_string()) }); contacts.insert("Hammond Ardeep".to_string(), Contact { name: Name { first: "Hammond".to_string(), last: "Ardeep".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Daggerford".to_string()), notes: Some("Militia leader vs. goblins.".to_string()) }); contacts.insert("Sister Garaele".to_string(), Contact { name: Name { first: "Garaele".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Harper agent in temple.".to_string()) }); contacts.insert("Gundren Rockseeker".to_string(), Contact { name: Name { first: "Gundren".to_string(), last: "Rockseeker".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Dwarf seeking lost mine.".to_string()) }); contacts.insert("Sildar Hallwinter".to_string(), Contact { name: Name { first: "Sildar".to_string(), last: "Hallwinter".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Lord's Alliance knight.".to_string()) }); contacts.insert("Qelline Alderleaf".to_string(), Contact { name: Name { first: "Qelline".to_string(), last: "Alderleaf".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Halfling farmer, kind.".to_string()) }); contacts.insert("Toblen Stonehill".to_string(), Contact { name: Name { first: "Toblen".to_string(), last: "Stonehill".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Innkeeper, knows rumors.".to_string()) }); contacts.insert("Darathra Shendrel".to_string(), Contact { name: Name { first: "Darathra".to_string(), last: "Shendrel".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Triboar".to_string()), notes: Some("Lord Protector, fair.".to_string()) }); contacts.insert("Ziraj the Hunter".to_string(), Contact { name: Name { first: "Ziraj".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Neverwinter Wood".to_string()), notes: Some("Tracks orcs.".to_string()) }); contacts.insert("Eldrin Thalindra".to_string(), Contact { name: Name { first: "Eldrin".to_string(), last: "Thalindra".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Silverymoon".to_string()), notes: Some("Arcane ward keeper.".to_string()) }); contacts.insert("Randal Morn".to_string(), Contact { name: Name { first: "Randal".to_string(), last: "Morn".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Daggerdale".to_string()), notes: Some("Fights Zhentarim.".to_string()) }); contacts.insert("Khelben Blackstaff".to_string(), Contact { name: Name { first: "Khelben".to_string(), last: "Arunsun".to_string(), alias: "The Blackstaff".to_string() }, image: None, status: Some(ContactStatus::Dead), location: Some("Waterdeep".to_string()), notes: Some("Former archmage, deceased.".to_string()) }); contacts.insert("Mirt the Moneylender".to_string(), Contact { name: Name { first: "Mirt".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Waterdeep".to_string()), notes: Some("Harper ally, wealthy.".to_string()) }); contacts.insert("Durnan".to_string(), Contact { name: Name { first: "Durnan".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Waterdeep".to_string()), notes: Some("Yawning Portal owner.".to_string()) }); contacts.insert("Fzoul Chembryl".to_string(), Contact { name: Name { first: "Fzoul".to_string(), last: "Chembryl".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Dead), location: Some("Zhentil Keep".to_string()), notes: Some("Former Zhentarim leader.".to_string()) }); contacts.insert("Bruenor Battlehammer".to_string(), Contact { name: Name { first: "Bruenor".to_string(), last: "Battlehammer".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Mithral Hall".to_string()), notes: Some("Dwarf king, ally.".to_string()) }); contacts.insert("Catti-brie".to_string(), Contact { name: Name { first: "Catti-brie".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Mithral Hall".to_string()), notes: Some("Skilled archer.".to_string()) }); contacts.insert("Regis".to_string(), Contact { name: Name { first: "Regis".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Icewind Dale".to_string()), notes: Some("Halfling, sneaky.".to_string()) }); contacts.insert("Artemis Entreri".to_string(), Contact { name: Name { first: "Artemis".to_string(), last: "Entreri".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Calimport".to_string()), notes: Some("Dangerous assassin.".to_string()) }); contacts.insert("Storm Silverhand".to_string(), Contact { name: Name { first: "Storm".to_string(), last: "Silverhand".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Shadowdale".to_string()), notes: Some("Bard and Chosen.".to_string()) }); contacts.insert("Halia Thornton".to_string(), Contact { name: Name { first: "Halia".to_string(), last: "Thornton".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Zhentarim agent, subtle.".to_string()) }); contacts.insert("Darlia Greystone".to_string(), Contact { name: Name { first: "Darlia".to_string(), last: "Greystone".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Triboar".to_string()), notes: Some("Blacksmith, reliable.".to_string()) }); contacts.insert("Eldric Varn".to_string(), Contact { name: Name { first: "Eldric".to_string(), last: "Varn".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Luskan".to_string()), notes: Some("Ship captain, shady.".to_string()) }); contacts.insert("Tymora’s Priest".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "Tymora’s Priest".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Suzail".to_string()), notes: Some("Blesses adventurers.".to_string()) }); contacts.insert("Redbrand Leader".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "Glasstaff".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Phandalin".to_string()), notes: Some("Runs thug gang.".to_string()) }); contacts.insert("Brynna of Lathander".to_string(), Contact { name: Name { first: "Brynna".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Suzail".to_string()), notes: Some("Temple cleric.".to_string()) }); contacts.insert("Korgul the Tumbler".to_string(), Contact { name: Name { first: "Korgul".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Baldur's Gate".to_string()), notes: Some("Thieves’ guild contact.".to_string()) }); contacts.insert("Tharivol the Mage".to_string(), Contact { name: Name { first: "Tharivol".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Silverymoon".to_string()), notes: Some("Studies arcane wards.".to_string()) }); contacts.insert("Gorlag the Orc".to_string(), Contact { name: Name { first: "Gorlag".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Dead), location: Some("Neverwinter Wood".to_string()), notes: Some("Slain orc chieftain.".to_string()) }); contacts.insert("Lhara the Merchant".to_string(), Contact { name: Name { first: "Lhara".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Cormyr".to_string()), notes: Some("Sells rare goods.".to_string()) }); contacts.insert("Ebon the Rogue".to_string(), Contact { name: Name { first: "Ebon".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Zhentil Keep".to_string()), notes: Some("Sneaky informant.".to_string()) }); contacts.insert("Father Llymic".to_string(), Contact { name: Name { first: "Llymic".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Dead), location: Some("Icewind Dale".to_string()), notes: Some("Evil priest, defeated.".to_string()) }); contacts.insert("Sylvara the Druid".to_string(), Contact { name: Name { first: "Sylvara".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("High Forest".to_string()), notes: Some("Protects the woods.".to_string()) }); contacts.insert("Raul the Barkeep".to_string(), Contact { name: Name { first: "Raul".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Daggerford".to_string()), notes: Some("Hears local gossip.".to_string()) }); // 5 Contacts (10%) contacts.insert("Valthor the Fence".to_string(), Contact { name: Name { first: "Valthor".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Baldur's Gate".to_string()), notes: Some("Buys stolen goods.".to_string()) }); contacts.insert("Zyra the Alchemist".to_string(), Contact { name: Name { first: "Zyra".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Waterdeep".to_string()), notes: Some("Sells potions.".to_string()) }); contacts.insert("Kren the Smuggler".to_string(), Contact { name: Name { first: "Kren".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Luskan".to_string()), notes: Some("Moves contraband.".to_string()) }); contacts.insert("Mira the Scribe".to_string(), Contact { name: Name { first: "Mira".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Candlekeep".to_string()), notes: Some("Deciphers texts.".to_string()) }); contacts.insert("Thok the Armorer".to_string(), Contact { name: Name { first: "Thok".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Neverwinter".to_string()), notes: Some("Crafts fine armor.".to_string()) }); // 3 Present-Day Legends (6%) contacts.insert("Tiamat".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "The Dragon Queen".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: None, notes: Some("Evil dragon goddess.".to_string()) }); contacts.insert("Vecna".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: None, notes: Some("Lich god of secrets.".to_string()) }); contacts.insert("Claugiyliamatar".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "Old Gnawbone".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::Alive), location: Some("Kryptgarden Forest".to_string()), notes: Some("Ancient green dragon.".to_string()) }); // 2 Past Legends (4%, DeadBygone) contacts.insert("Manshoon".to_string(), Contact { name: Name { first: "Manshoon".to_string(), last: "".to_string(), alias: "".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::DeadBygone), location: Some("Zhentil Keep".to_string()), notes: Some("Zhentarim founder, long dead.".to_string()) }); contacts.insert("Netherese Archwizard".to_string(), Contact { name: Name { first: "".to_string(), last: "".to_string(), alias: "Netherese Archwizard".to_string(), ..Default::default() }, image: None, status: Some(ContactStatus::DeadBygone), location: None, notes: Some("Ancient mage of lost empire.".to_string()) }); ContactBook(contacts) }