More journals, including concept of ones for visiting a room

This commit is contained in:
Condorra 2023-09-27 23:22:37 +10:00
parent 90a6b3f31b
commit 546f19d3cb
5 changed files with 71 additions and 2 deletions

View File

@ -3,7 +3,12 @@ use std::collections::BTreeSet;
#[derive(Serialize, Deserialize, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum JournalType {
// Kill journals
SlayedMeanDog,
TookOutAKillbot,
// Visit journals
JoinedHackerClub,
// Misc
Died,
}

View File

@ -13,6 +13,7 @@ use once_cell::sync::OnceCell;
use std::collections::BTreeMap;
mod first_dog;
mod killed_killbot;
#[allow(unused)]
pub enum KillSubscriptionType {
@ -46,6 +47,16 @@ pub fn journal_types() -> &'static BTreeMap<JournalType, JournalData> {
details: "killing a mean street dog for the first time.",
xp: 100
}),
(JournalType::TookOutAKillbot, JournalData {
name: "Killed a killbot",
details: "realising that in soviet melbs, you kill the killbots.",
xp: 200
}),
(JournalType::JoinedHackerClub, JournalData {
name: "Joined the Hackers' club",
details: "finding the secret Hackers' club.",
xp: 250
}),
(JournalType::Died, JournalData {
name: "Carked it",
details: "dying for the first time. Fortunately, you can come back by recloning in to a fresh body, just with fewer credits, a bit less experience, and a bruised ego! All your stuff is still on your body, so better go find it, or give up on it.",
@ -56,7 +67,7 @@ pub fn journal_types() -> &'static BTreeMap<JournalType, JournalData> {
pub fn journal_checkers() -> &'static Vec<&'static (dyn JournalChecker + Sync + Send)> {
static CHECKERS: OnceCell<Vec<&'static (dyn JournalChecker + Sync + Send)>> = OnceCell::new();
CHECKERS.get_or_init(|| vec![&first_dog::CHECKER])
CHECKERS.get_or_init(|| vec![&first_dog::CHECKER, &killed_killbot::CHECKER])
}
pub fn checkers_by_species(

View File

@ -0,0 +1,36 @@
use super::{award_journal_if_needed, JournalChecker, KillSubscriptionType};
#[double]
use crate::db::DBTrans;
use crate::{
models::{item::Item, journal::JournalType, user::User},
static_content::species::SpeciesType,
DResult,
};
use async_trait::async_trait;
use mockall_double::double;
pub struct KillbotChecker;
#[async_trait]
impl JournalChecker for KillbotChecker {
fn kill_subscriptions(&self) -> Vec<KillSubscriptionType> {
vec![KillSubscriptionType::SpecificNPCSpecies {
species: SpeciesType::Robot,
}]
}
async fn handle_kill(
&self,
trans: &DBTrans,
user: &mut User,
player: &mut Item,
victim: &Item,
) -> DResult<bool> {
if victim.display.contains("Killbot") {
award_journal_if_needed(trans, user, player, JournalType::TookOutAKillbot).await
} else {
Ok(false)
}
}
}
pub static CHECKER: KillbotChecker = KillbotChecker;

View File

@ -1,10 +1,11 @@
use super::{possession_type::PossessionType, StaticItem};
use super::{journals::award_journal_if_needed, possession_type::PossessionType, StaticItem};
#[double]
use crate::db::DBTrans;
use crate::{
message_handler::user_commands::UResult,
models::{
item::{DoorState, Item, ItemFlag},
journal::JournalType,
user::WristpadHack,
},
regular_tasks::queued_command::QueuedCommandContext,
@ -350,6 +351,7 @@ pub struct Room {
pub has_power: bool,
pub door_states: Option<BTreeMap<Direction, DoorState>>,
pub wristpad_hack_allowed: Option<WristpadHack>,
pub journal: Option<JournalType>,
pub enter_trigger: Option<&'static (dyn RoomEnterTrigger + Sync + Send)>,
}
@ -374,6 +376,7 @@ impl Default for Room {
has_power: false,
door_states: None,
wristpad_hack_allowed: None,
journal: None,
enter_trigger: None,
}
}
@ -512,6 +515,18 @@ pub async fn check_for_enter_action(ctx: &mut QueuedCommandContext<'_>) -> UResu
Some(r) => r,
_ => return Ok(()),
};
match room.journal {
Some(ref journal) if ctx.item.item_type == "player" => {
if let Some(mut user) = ctx.trans.find_by_username(&ctx.item.item_code).await? {
if award_journal_if_needed(&ctx.trans, &mut user, &mut ctx.item, journal.clone())
.await?
{
ctx.trans.save_user_model(&user).await?;
}
}
}
_ => {}
}
match room.enter_trigger {
Some(trigger) => trigger.handle_enter(ctx, room).await?,
_ => {}

View File

@ -1,6 +1,7 @@
use crate::{
models::{
item::{DoorState, LocationActionType},
journal::JournalType,
user::WristpadHack,
},
static_content::{
@ -186,6 +187,7 @@ pub fn room_list() -> Vec<Room> {
)
].into_iter().collect()),
should_caption: true,
journal: Some(JournalType::JoinedHackerClub),
wristpad_hack_allowed: Some(WristpadHack::Superdork),
..Default::default()
},