87 lines
4.1 KiB
Rust
87 lines
4.1 KiB
Rust
use super::{
|
|
VerbContext, UserVerb, UserVerbRef, UResult, user_error,
|
|
get_player_item_or_fail,
|
|
parsing::parse_offset,
|
|
};
|
|
use crate::{
|
|
static_content::room,
|
|
static_content::possession_type::possession_data,
|
|
models::item::Item,
|
|
};
|
|
use async_trait::async_trait;
|
|
use ansi::ansi;
|
|
|
|
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?;
|
|
|
|
if player_item.is_dead {
|
|
user_error("Nobody seems to listen when you try to buy... possibly because you're dead.".to_owned())?
|
|
}
|
|
let (heretype, herecode) = player_item.location.split_once("/").unwrap_or(("room", "repro_xv_chargen"));
|
|
if heretype != "room" {
|
|
user_error("Can't buy anything because you're not in a shop.".to_owned())?;
|
|
}
|
|
let room = match room::room_map_by_code().get(herecode) {
|
|
None => user_error("Can't find that shop.".to_owned())?,
|
|
Some(r) => r
|
|
};
|
|
if room.stock_list.is_empty() {
|
|
user_error("Can't buy anything because you're not in a shop.".to_owned())?
|
|
}
|
|
|
|
let (offset_m, remaining) = parse_offset(remaining);
|
|
let mut offset_remaining = offset_m.unwrap_or(1);
|
|
let match_item = remaining.trim().to_lowercase();
|
|
|
|
if match_item == "" {
|
|
user_error("You need to specify what to buy.".to_owned())?
|
|
}
|
|
|
|
for stock in &room.stock_list {
|
|
if let Some(possession_type) = possession_data().get(&stock.possession_type) {
|
|
if possession_type.display.to_lowercase().starts_with(&match_item) ||
|
|
possession_type.display_less_explicit.map(|d| d.to_lowercase().starts_with(&match_item)).unwrap_or(false) ||
|
|
possession_type.aliases.iter().any(|al| al.starts_with(&match_item)) {
|
|
if offset_remaining <= 1 {
|
|
if let Some(mut user) = ctx.user_dat.as_mut() {
|
|
if user.credits < stock.list_price {
|
|
user_error("You don't have enough credits to buy that!".to_owned())?;
|
|
}
|
|
user.credits -= stock.list_price;
|
|
let item_code = ctx.trans.alloc_item_code().await?;
|
|
let new_item = Item {
|
|
item_type: "possession".to_owned(),
|
|
item_code: format!("{}", item_code),
|
|
possession_type: Some(stock.possession_type.clone()),
|
|
display: possession_type.display.to_owned(),
|
|
display_less_explicit: possession_type.display_less_explicit.map(|d| d.to_owned()),
|
|
details: Some(possession_type.details.to_owned()),
|
|
details_less_explicit: possession_type.details_less_explicit.map(|d| d.to_owned()),
|
|
aliases: possession_type.aliases.iter().map(|al| (*al).to_owned()).collect(),
|
|
location: format!("player/{}", &player_item.item_code),
|
|
health: possession_type.max_health,
|
|
..Default::default()
|
|
};
|
|
ctx.trans.create_item(&new_item).await?;
|
|
ctx.trans.queue_for_session(
|
|
&ctx.session,
|
|
Some(&format!("Your wristpad beeps for a deduction of {} credits.\n", stock.list_price))
|
|
).await?;
|
|
}
|
|
return Ok(());
|
|
} else {
|
|
offset_remaining -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
user_error(ansi!("That doesn't seem to be for sale. Try <bold>list<reset>").to_owned())
|
|
}
|
|
}
|
|
static VERB_INT: Verb = Verb;
|
|
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|