use crate::{ models::user::{wristpad_hack_data, xp_to_hack_slots}, services::skills::calculate_total_stats_skills_for_user, static_content::room::room_map_by_code, }; use super::{ get_player_item_or_fail, user_error, UResult, UserError, UserVerb, UserVerbRef, VerbContext, }; use ansi::ansi; use async_trait::async_trait; pub struct Verb; #[async_trait] impl UserVerb for Verb { async fn handle( self: &Self, ctx: &mut VerbContext, _verb: &str, remaining: &str, ) -> UResult<()> { let player_item = get_player_item_or_fail(ctx).await?; let (loc_type, loc_code) = player_item .location .split_once("/") .ok_or_else(|| UserError("Your location is invalid".to_owned()))?; if loc_type != "room" { user_error("You can't find a hacking unit here.".to_owned())?; } let room = room_map_by_code() .get(&loc_code) .ok_or_else(|| UserError("Your location no longer exists!".to_owned()))?; let allowed_hack = room .wristpad_hack_allowed .as_ref() .ok_or_else(|| UserError("You can't find a hacking unit here.".to_owned()))?; let hack_data = wristpad_hack_data() .get(allowed_hack) .ok_or_else(|| UserError("The hacking unit is currently broken.".to_owned()))?; if hack_data.name.to_lowercase() != remaining.trim() { user_error(format!( ansi!("The equipment here only allows you to <bold>hack {}<reset>"), &hack_data.name ))?; } let user = ctx .user_dat .as_mut() .ok_or(UserError("Please log in first".to_owned()))?; let slots_available = xp_to_hack_slots(player_item.total_xp) as usize; let slots_used = user.wristpad_hacks.len(); if slots_used >= slots_available { user_error(format!( "Your wristpad crashes and reboots, flashing up an error that \ there was no space to install the hack. [You only have {} slots \ total on your wristpad to install hacks - try getting some \ more experience to earn more]", slots_available ))?; } if user.wristpad_hacks.contains(&allowed_hack) { user_error( "Your wristpad crashes and reboots, flashing up an error that \ the same hack was already found on the device." .to_owned(), )?; } user.wristpad_hacks.push(allowed_hack.clone()); ctx.trans.save_user_model(&user).await?; let mut player_mut = (*player_item).clone(); calculate_total_stats_skills_for_user(&mut player_mut, user); ctx.trans.save_item_model(&player_mut).await?; ctx.trans .queue_for_session( &ctx.session, Some(&format!( "Your wristpad beeps and reboots. You notice new icon on \ it indicating the {} hack has been applied succesfully!\n", hack_data.name )), ) .await?; Ok(()) } } static VERB_INT: Verb = Verb; pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;