Finalize shops, interactions and world data
All checks were successful
Smoke tests / Build and smoke test (push) Successful in 1m53s
All checks were successful
Smoke tests / Build and smoke test (push) Successful in 1m53s
This commit is contained in:
@@ -1476,11 +1476,8 @@ async fn cmd_spells(pid: usize, state: &SharedState) -> CommandResult {
|
||||
|
||||
async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult {
|
||||
let mut st = state.lock().await;
|
||||
let (conn, rid) = match st.players.get_mut(&pid) {
|
||||
Some(c) => {
|
||||
let rid = c.player.room_id.clone();
|
||||
(c, rid)
|
||||
}
|
||||
let rid = match st.players.get(&pid) {
|
||||
Some(c) => c.player.room_id.clone(),
|
||||
None => return simple("Error\r\n"),
|
||||
};
|
||||
|
||||
@@ -1543,22 +1540,25 @@ async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult
|
||||
if subargs.is_empty() {
|
||||
return simple("Buy what?\r\n");
|
||||
}
|
||||
let (shop, _npc_name) = {
|
||||
let npc = st.world.get_npc(&merchant_id).unwrap();
|
||||
let shop = npc.shop.as_ref().unwrap().clone();
|
||||
(npc.shop.as_ref().unwrap().clone(), npc.name.clone())
|
||||
};
|
||||
|
||||
let item_to_buy = shop.sells.iter().find(|id| {
|
||||
let item_id = shop.sells.iter().find(|id| {
|
||||
if let Some(obj) = st.world.get_object(*id) {
|
||||
obj.name.to_lowercase().contains(&subargs.to_lowercase())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
}).cloned();
|
||||
|
||||
if let Some(item_id) = item_to_buy {
|
||||
let obj = st.world.get_object(item_id).unwrap().clone();
|
||||
if let Some(id) = item_id {
|
||||
let obj = st.world.get_object(&id).unwrap().clone();
|
||||
let total_copper = (obj.value_gold * 10000 + obj.value_silver * 100 + obj.value_copper) as f32;
|
||||
let price_copper = (total_copper * shop.markup).ceil() as i32;
|
||||
|
||||
if let Some(conn) = st.players.get_mut(&pid) {
|
||||
let player_total_copper = conn.player.gold * 10000 + conn.player.silver * 100 + conn.player.copper;
|
||||
if player_total_copper < price_copper {
|
||||
return simple("You don't have enough money.\r\n");
|
||||
@@ -1579,6 +1579,9 @@ async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult
|
||||
ansi::color(ansi::CYAN, &obj.name),
|
||||
price_copper
|
||||
))
|
||||
} else {
|
||||
simple("Error\r\n")
|
||||
}
|
||||
} else {
|
||||
simple("The merchant doesn't sell that.\r\n")
|
||||
}
|
||||
@@ -1588,14 +1591,16 @@ async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult
|
||||
if subargs.is_empty() {
|
||||
return simple("Sell what?\r\n");
|
||||
}
|
||||
let npc = st.world.get_npc(&merchant_id).unwrap();
|
||||
let shop = npc.shop.as_ref().unwrap().clone();
|
||||
let shop = st.world.get_npc(&merchant_id).unwrap().shop.as_ref().unwrap().clone();
|
||||
|
||||
let item_idx = conn.player.inventory.iter().position(|o| o.name.to_lowercase().contains(&subargs.to_lowercase()));
|
||||
|
||||
if let Some(idx) = item_idx {
|
||||
let obj = conn.player.inventory[idx].clone();
|
||||
let item_info = if let Some(conn) = st.players.get(&pid) {
|
||||
conn.player.inventory.iter().position(|o| o.name.to_lowercase().contains(&subargs.to_lowercase()))
|
||||
.map(|idx| (idx, conn.player.inventory[idx].clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some((idx, obj)) = item_info {
|
||||
// Check if merchant buys this kind of item
|
||||
let can_sell = shop.buys.is_empty() || shop.buys.iter().any(|k| {
|
||||
if let Some(kind) = &obj.kind {
|
||||
@@ -1612,6 +1617,7 @@ async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult
|
||||
let total_copper = (obj.value_gold * 10000 + obj.value_silver * 100 + obj.value_copper) as f32;
|
||||
let price_copper = (total_copper * shop.markdown).floor() as i32;
|
||||
|
||||
if let Some(conn) = st.players.get_mut(&pid) {
|
||||
// Add money to player
|
||||
let mut player_total_copper = conn.player.gold * 10000 + conn.player.silver * 100 + conn.player.copper;
|
||||
player_total_copper += price_copper;
|
||||
@@ -1628,6 +1634,9 @@ async fn cmd_shop(pid: usize, args: &str, state: &SharedState) -> CommandResult
|
||||
ansi::color(ansi::CYAN, &obj.name),
|
||||
price_copper
|
||||
))
|
||||
} else {
|
||||
simple("Error\r\n")
|
||||
}
|
||||
} else {
|
||||
simple("You don't have that in your inventory.\r\n")
|
||||
}
|
||||
|
||||
24
src/db.rs
24
src/db.rs
@@ -78,7 +78,7 @@ impl SqliteDb {
|
||||
.map_err(|e| format!("Failed to set pragmas: {e}"))?;
|
||||
|
||||
conn.execute_batch(
|
||||
CREATE TABLE IF NOT EXISTS players (
|
||||
r#"CREATE TABLE IF NOT EXISTS players (
|
||||
name TEXT PRIMARY KEY,
|
||||
race_id TEXT NOT NULL,
|
||||
class_id TEXT NOT NULL,
|
||||
@@ -89,8 +89,8 @@ impl SqliteDb {
|
||||
max_hp INTEGER NOT NULL,
|
||||
attack INTEGER NOT NULL,
|
||||
defense INTEGER NOT NULL,
|
||||
inventory_json TEXT NOT NULL DEFAULT '[]',
|
||||
equipped_json TEXT NOT NULL DEFAULT '{}',
|
||||
inventory_json TEXT NOT NULL DEFAULT "[]",
|
||||
equipped_json TEXT NOT NULL DEFAULT "{}",
|
||||
is_admin INTEGER NOT NULL DEFAULT 0,
|
||||
mana INTEGER NOT NULL DEFAULT 0,
|
||||
max_mana INTEGER NOT NULL DEFAULT 0,
|
||||
@@ -127,13 +127,13 @@ impl SqliteDb {
|
||||
guild_id TEXT NOT NULL,
|
||||
level INTEGER NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (player_name, guild_id)
|
||||
);",
|
||||
);"#,
|
||||
)
|
||||
.map_err(|e| format!("Failed to create tables: {e}"))?;
|
||||
|
||||
// Migration: add is_admin column if missing
|
||||
let has_admin: bool = conn
|
||||
.prepare("SELECT COUNT(*) FROM pragma_table_info('players') WHERE name='is_admin'")
|
||||
.prepare(r#"SELECT COUNT(*) FROM pragma_table_info("players") WHERE name="is_admin""#)
|
||||
.and_then(|mut s| s.query_row([], |r| r.get::<_, i32>(0)))
|
||||
.map(|c| c > 0)
|
||||
.unwrap_or(false);
|
||||
@@ -146,34 +146,34 @@ impl SqliteDb {
|
||||
|
||||
// Migration: equipped_weapon_json/equipped_armor_json -> equipped_json
|
||||
let has_old_weapon: bool = conn
|
||||
.prepare("SELECT COUNT(*) FROM pragma_table_info('players') WHERE name='equipped_weapon_json'")
|
||||
.prepare(r#"SELECT COUNT(*) FROM pragma_table_info("players") WHERE name="equipped_weapon_json""#)
|
||||
.and_then(|mut s| s.query_row([], |r| r.get::<_, i32>(0)))
|
||||
.map(|c| c > 0)
|
||||
.unwrap_or(false);
|
||||
let has_equipped: bool = conn
|
||||
.prepare("SELECT COUNT(*) FROM pragma_table_info('players') WHERE name='equipped_json'")
|
||||
.prepare(r#"SELECT COUNT(*) FROM pragma_table_info("players") WHERE name="equipped_json""#)
|
||||
.and_then(|mut s| s.query_row([], |r| r.get::<_, i32>(0)))
|
||||
.map(|c| c > 0)
|
||||
.unwrap_or(false);
|
||||
if has_old_weapon && !has_equipped {
|
||||
let _ = conn.execute(
|
||||
"ALTER TABLE players ADD COLUMN equipped_json TEXT NOT NULL DEFAULT '{}'",
|
||||
r#"ALTER TABLE players ADD COLUMN equipped_json TEXT NOT NULL DEFAULT "{}"#,
|
||||
[],
|
||||
);
|
||||
log::info!("Migrating equipped_weapon_json/equipped_armor_json to equipped_json...");
|
||||
let _ = conn.execute_batch(
|
||||
"UPDATE players SET equipped_json = '{}' WHERE equipped_weapon_json IS NULL AND equipped_armor_json IS NULL;"
|
||||
r#"UPDATE players SET equipped_json = "{}" WHERE equipped_weapon_json IS NULL AND equipped_armor_json IS NULL;"#
|
||||
);
|
||||
} else if !has_equipped {
|
||||
let _ = conn.execute(
|
||||
"ALTER TABLE players ADD COLUMN equipped_json TEXT NOT NULL DEFAULT '{}'",
|
||||
r#"ALTER TABLE players ADD COLUMN equipped_json TEXT NOT NULL DEFAULT "{}"#,
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
// Migration: add mana/endurance columns
|
||||
let has_mana: bool = conn
|
||||
.prepare("SELECT COUNT(*) FROM pragma_table_info('players') WHERE name='mana'")
|
||||
.prepare(r#"SELECT COUNT(*) FROM pragma_table_info("players") WHERE name="mana""#)
|
||||
.and_then(|mut s| s.query_row([], |r| r.get::<_, i32>(0)))
|
||||
.map(|c| c > 0)
|
||||
.unwrap_or(false);
|
||||
@@ -186,7 +186,7 @@ impl SqliteDb {
|
||||
|
||||
// Migration: add currency columns
|
||||
let has_gold: bool = conn
|
||||
.prepare("SELECT COUNT(*) FROM pragma_table_info('players') WHERE name='gold'")
|
||||
.prepare(r#"SELECT COUNT(*) FROM pragma_table_info("players") WHERE name="gold""#)
|
||||
.and_then(|mut s| s.query_row([], |r| r.get::<_, i32>(0)))
|
||||
.map(|c| c > 0)
|
||||
.unwrap_or(false);
|
||||
|
||||
@@ -2,7 +2,7 @@ name = "Breda"
|
||||
description = "Breda is haughty in bearing, with thin auburn hair and narrow blue eyes. She wears simple clothing and several small tools hang from her belt. Breda will purchase monster teeth for a silver coin each."
|
||||
room = "lawold:well_market_trade_stalls"
|
||||
race = "race:human"
|
||||
base_attitude = "aggressive"
|
||||
base_attitude = "neutral"
|
||||
|
||||
[dialogue]
|
||||
greeting = "What do you want? I'm busy. Unless you have some teeth to sell?"
|
||||
|
||||
Reference in New Issue
Block a user