Allow inspecting things for sale in shops.

This commit is contained in:
Condorra 2024-06-22 22:37:16 +10:00
parent 851e3d8d1e
commit b8011420e6
2 changed files with 55 additions and 2 deletions

View File

@ -49,7 +49,12 @@ northwest: *movement
up: *movement up: *movement
down: *movement down: *movement
in: *movement in: *movement
look: &look Try <bold>look<reset>, <bold>l<reset>, <bold>examine<reset> or <bold>ex<reset> to look at the current room. Follow it with the name of an exit to look at an adjacent room. Or name an object or player in the room to look at that. look: &look >-
Try <bold>look<reset>, <bold>l<reset>, <bold>examine<reset> or <bold>ex<reset> to look at the current room.
Follow it with the name of an exit to look at an adjacent room.
Or name an object or player in the room to look at that.
You can also use <bold>look at<reset> thing <bold>for sale<reset> while in a shop to inspect the wares before
you buy.
l: *look l: *look
ex: *look ex: *look
read: *look read: *look

View File

@ -20,7 +20,7 @@ use crate::{
static_content::{ static_content::{
dynzone, dynzone,
possession_type::{possession_data, recipe_craft_by_recipe}, possession_type::{possession_data, recipe_craft_by_recipe},
room::{self, Direction}, room::{self, room_map_by_code, Direction},
species::species_info_map, species::species_info_map,
}, },
}; };
@ -706,6 +706,38 @@ pub async fn direction_to_item(
Ok(trans.find_item_by_type_code("room", &new_room.code).await?) Ok(trans.find_item_by_type_code("room", &new_room.code).await?)
} }
async fn describe_store_item(
ctx: &VerbContext<'_>,
player_item: &Item,
location_type: &str,
location_code: &str,
item: &str,
) -> UResult<()> {
if location_type != "room" {
user_error("Nothing is for sale here.".to_owned())?;
}
let room = room_map_by_code()
.get(location_code)
.ok_or_else(|| UserError("Couldn't find your room to look.".to_owned()))?;
if room.stock_list.is_empty() {
user_error("Nothing is for sale here.".to_owned())?
}
let (poss_type, _poss_data) = room
.stock_list
.iter()
.filter(|rs| rs.can_buy)
.filter_map(|rs| match possession_data().get(&rs.possession_type) {
Some(pd) => Some((rs.possession_type.clone(), pd)),
None => None,
})
.find(|(_, pd)| {
pd.display.starts_with(item) || pd.aliases.iter().any(|a| a.starts_with(item))
})
.ok_or_else(|| UserError("Couldn't find anything like that for sale.".to_owned()))?;
let tmp_item: Item = poss_type.clone().into();
describe_normal_item(&player_item, ctx, &tmp_item).await
}
pub struct Verb; pub struct Verb;
#[async_trait] #[async_trait]
impl UserVerb for Verb { impl UserVerb for Verb {
@ -722,6 +754,9 @@ impl UserVerb for Verb {
if rem_trim.starts_with("in ") { if rem_trim.starts_with("in ") {
rem_trim = rem_trim[3..].trim_start().to_owned(); rem_trim = rem_trim[3..].trim_start().to_owned();
} }
if rem_trim.starts_with("at ") {
rem_trim = rem_trim[3..].trim_start().to_owned();
}
let use_location = if player_item.death_data.is_some() { let use_location = if player_item.death_data.is_some() {
"room/repro_xv_respawn" "room/repro_xv_respawn"
} else { } else {
@ -730,6 +765,18 @@ impl UserVerb for Verb {
let (heretype, herecode) = use_location let (heretype, herecode) = use_location
.split_once("/") .split_once("/")
.unwrap_or(("room", "repro_xv_chargen")); .unwrap_or(("room", "repro_xv_chargen"));
if rem_trim.ends_with(" for sale") {
return Ok(describe_store_item(
ctx,
&player_item,
heretype,
herecode,
rem_trim[0..(rem_trim.len() - 9)].trim_end(),
)
.await?);
}
let item: Arc<Item> = if rem_trim == "" { let item: Arc<Item> = if rem_trim == "" {
ctx.trans ctx.trans
.find_item_by_type_code(heretype, herecode) .find_item_by_type_code(heretype, herecode)
@ -838,5 +885,6 @@ impl UserVerb for Verb {
Ok(()) Ok(())
} }
} }
static VERB_INT: Verb = Verb; static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef; pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;