Compare commits
3 Commits
9dc6e9f50e
...
15a2f37a3d
Author | SHA1 | Date | |
---|---|---|---|
15a2f37a3d | |||
484c7b22f5 | |||
dd2deb971b |
@ -100,14 +100,15 @@ announcement = "I love cheese! I am at {location}."
|
|||||||
# The buy_prices and sell_prices tables are required. The keys are item definition IDs and the
|
# The buy_prices and sell_prices tables are required. The keys are item definition IDs and the
|
||||||
# values are the price in coins. You may type in-game "/give_item common.items." and press Tab to
|
# values are the price in coins. You may type in-game "/give_item common.items." and press Tab to
|
||||||
# explore the item definition IDs. Then just leave off the "common.items." part in this file.
|
# explore the item definition IDs. Then just leave off the "common.items." part in this file.
|
||||||
|
|
||||||
[buy_prices]
|
[buy_prices]
|
||||||
"food.cheese" = 50
|
"food.cheese" = 50
|
||||||
|
|
||||||
[sell_prices]
|
[sell_prices]
|
||||||
"consumable.potion_minor" = 150
|
"consumable.potion_minor" = 150
|
||||||
|
|
||||||
# Modular weapons listed by that components: "material|primary|secondary".
|
# Modular weapons are listed by their components: "material|primary|secondary". The material is
|
||||||
|
# snake_cased and you can omit the "common.items.modular.weapon.[primary|secondary]" from the
|
||||||
|
# modular components.
|
||||||
"iron|sword.greatsword|sword.long" = 1_000
|
"iron|sword.greatsword|sword.long" = 1_000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -7,4 +7,148 @@ orientation = 0
|
|||||||
|
|
||||||
[sell_prices]
|
[sell_prices]
|
||||||
"consumable.potion_minor" = 150
|
"consumable.potion_minor" = 150
|
||||||
"iron|sword.greatsword|sword.long" = 1_000
|
|
||||||
|
# Modular Weapons
|
||||||
|
## Axes
|
||||||
|
"orichalcum|axe.axe|axe.long" = 45_000
|
||||||
|
"orichalcum|axe.axe|axe.medium" = 45_000
|
||||||
|
"orichalcum|axe.axe|axe.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.greataxe|axe.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.poleaxe|axe.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.battleaxe|axe.long" = 45_000
|
||||||
|
"orichalcum|axe.battleaxe|axe.medium" = 45_000
|
||||||
|
"orichalcum|axe.battleaxe|axe.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.jagged|axe.long" = 45_000
|
||||||
|
"orichalcum|axe.jagged|axe.medium" = 45_000
|
||||||
|
"orichalcum|axe.jagged|axe.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.labrys|axe.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|axe.ornate|axe.long" = 45_000
|
||||||
|
"orichalcum|axe.ornate|axe.medium" = 45_000
|
||||||
|
"orichalcum|axe.ornate|axe.short" = 45_000
|
||||||
|
|
||||||
|
## Swords
|
||||||
|
"orichalcum|sword.greatsword|sword.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.katana|sword.long" = 45_000
|
||||||
|
"orichalcum|sword.katana|sword.medium" = 45_000
|
||||||
|
"orichalcum|sword.katana|sword.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.longsword|sword.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.ornate|sword.long" = 45_000
|
||||||
|
"orichalcum|sword.ornate|sword.medium" = 45_000
|
||||||
|
"orichalcum|sword.ornate|sword.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.sabre|sword.long" = 45_000
|
||||||
|
"orichalcum|sword.sabre|sword.medium" = 45_000
|
||||||
|
"orichalcum|sword.sabre|sword.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.sawblade|sword.long" = 45_000
|
||||||
|
"orichalcum|sword.sawblade|sword.medium" = 45_000
|
||||||
|
"orichalcum|sword.sawblade|sword.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|sword.zweihander|sword.long" = 45_000
|
||||||
|
|
||||||
|
## Hammers
|
||||||
|
"orichalcum|hammer.hammer|hammer.long" = 45_000
|
||||||
|
"orichalcum|hammer.hammer|hammer.medium" = 45_000
|
||||||
|
"orichalcum|hammer.hammer|hammer.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.ornate|hammer.long" = 45_000
|
||||||
|
"orichalcum|hammer.ornate|hammer.medium" = 45_000
|
||||||
|
"orichalcum|hammer.ornate|hammer.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.greathammer|hammer.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.maul|hammer.long" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.warhammer|hammer.long" = 45_000
|
||||||
|
"orichalcum|hammer.warhammer|hammer.medium" = 45_000
|
||||||
|
"orichalcum|hammer.warhammer|hammer.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.spikedmace|hammer.long" = 45_000
|
||||||
|
"orichalcum|hammer.spikedmace|hammer.medium" = 45_000
|
||||||
|
"orichalcum|hammer.spikedmace|hammer.short" = 45_000
|
||||||
|
|
||||||
|
"orichalcum|hammer.greatmace|hammer.long" = 45_000
|
||||||
|
|
||||||
|
## Bows
|
||||||
|
"eldwood|bow.bow|bow.long" = 20_000
|
||||||
|
"eldwood|bow.composite|bow.long" = 20_000
|
||||||
|
"eldwood|bow.greatbow|bow.long" = 20_000
|
||||||
|
"eldwood|bow.longbow|bow.long" = 20_000
|
||||||
|
"eldwood|bow.ornate|bow.long" = 20_000
|
||||||
|
"eldwood|bow.shortbow|bow.long" = 20_000
|
||||||
|
"eldwood|bow.warbow|bow.long" = 20_000
|
||||||
|
|
||||||
|
"eldwood|bow.bow|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.composite|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.greatbow|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.longbow|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.ornate|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.shortbow|bow.medium" = 20_000
|
||||||
|
"eldwood|bow.warbow|bow.medium" = 20_000
|
||||||
|
|
||||||
|
"eldwood|bow.bow|bow.short" = 20_000
|
||||||
|
"eldwood|bow.composite|bow.short" = 20_000
|
||||||
|
"eldwood|bow.greatbow|bow.short" = 20_000
|
||||||
|
"eldwood|bow.longbow|bow.short" = 20_000
|
||||||
|
"eldwood|bow.ornate|bow.short" = 20_000
|
||||||
|
"eldwood|bow.shortbow|bow.short" = 20_000
|
||||||
|
"eldwood|bow.warbow|bow.short" = 20_000
|
||||||
|
|
||||||
|
## Staffs
|
||||||
|
"eldwood|staff.brand|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.grandstaff|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.longpole|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.ornate|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.pole|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.rod|staff.heavy" = 20_000
|
||||||
|
"eldwood|staff.staff|staff.heavy" = 20_000
|
||||||
|
|
||||||
|
"eldwood|staff.brand|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.grandstaff|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.longpole|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.ornate|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.pole|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.rod|staff.medium" = 20_000
|
||||||
|
"eldwood|staff.staff|staff.medium" = 20_000
|
||||||
|
|
||||||
|
"eldwood|staff.brand|staff.light" = 20_000
|
||||||
|
"eldwood|staff.grandstaff|staff.light" = 20_000
|
||||||
|
"eldwood|staff.longpole|staff.light" = 20_000
|
||||||
|
"eldwood|staff.ornate|staff.light" = 20_000
|
||||||
|
"eldwood|staff.pole|staff.light" = 20_000
|
||||||
|
"eldwood|staff.rod|staff.light" = 20_000
|
||||||
|
"eldwood|staff.staff|staff.light" = 20_000
|
||||||
|
|
||||||
|
## Sceptres
|
||||||
|
"eldwood|sceptre.arbor|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.cane|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.crook|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.crozier|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.grandsceptre|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.ornate|sceptre.heavy" = 20_000
|
||||||
|
"eldwood|sceptre.sceptre|sceptre.heavy" = 20_000
|
||||||
|
|
||||||
|
"eldwood|sceptre.arbor|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.cane|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.crook|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.crozier|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.grandsceptre|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.ornate|sceptre.medium" = 20_000
|
||||||
|
"eldwood|sceptre.sceptre|sceptre.medium" = 20_000
|
||||||
|
|
||||||
|
"eldwood|sceptre.arbor|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.cane|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.crook|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.crozier|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.grandsceptre|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.ornate|sceptre.light" = 20_000
|
||||||
|
"eldwood|sceptre.sceptre|sceptre.light" = 20_000
|
||||||
|
141
src/bot.rs
141
src/bot.rs
@ -7,6 +7,7 @@ use std::{
|
|||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use vek::{Quaternion, Vec3};
|
use vek::{Quaternion, Vec3};
|
||||||
use veloren_client::{addr::ConnectionArgs, Client, Event as VelorenEvent, SiteInfoRich, WorldExt};
|
use veloren_client::{addr::ConnectionArgs, Client, Event as VelorenEvent, SiteInfoRich, WorldExt};
|
||||||
@ -33,6 +34,13 @@ use crate::config::PriceList;
|
|||||||
const COINS: ItemDefinitionId =
|
const COINS: ItemDefinitionId =
|
||||||
ItemDefinitionId::Simple(Cow::Borrowed("common.items.utility.coins"));
|
ItemDefinitionId::Simple(Cow::Borrowed("common.items.utility.coins"));
|
||||||
|
|
||||||
|
/// TODO: Implement Display
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Reciept {
|
||||||
|
pub my_items: HashMap<String, u32>,
|
||||||
|
pub their_items: HashMap<String, u32>,
|
||||||
|
}
|
||||||
|
|
||||||
/// An active connection to the Veloren server that will attempt to run every time the `tick`
|
/// An active connection to the Veloren server that will attempt to run every time the `tick`
|
||||||
/// function is called.
|
/// function is called.
|
||||||
///
|
///
|
||||||
@ -56,6 +64,7 @@ pub struct Bot {
|
|||||||
trade_mode: TradeMode,
|
trade_mode: TradeMode,
|
||||||
|
|
||||||
previous_trade: Option<PendingTrade>,
|
previous_trade: Option<PendingTrade>,
|
||||||
|
previous_trade_receipt: Option<Reciept>,
|
||||||
last_trade_action: Instant,
|
last_trade_action: Instant,
|
||||||
last_announcement: Instant,
|
last_announcement: Instant,
|
||||||
last_ouch: Instant,
|
last_ouch: Instant,
|
||||||
@ -152,6 +161,7 @@ impl Bot {
|
|||||||
sell_prices,
|
sell_prices,
|
||||||
trade_mode: TradeMode::Trade,
|
trade_mode: TradeMode::Trade,
|
||||||
previous_trade: None,
|
previous_trade: None,
|
||||||
|
previous_trade_receipt: None,
|
||||||
last_trade_action: now,
|
last_trade_action: now,
|
||||||
last_announcement: now,
|
last_announcement: now,
|
||||||
last_ouch: now,
|
last_ouch: now,
|
||||||
@ -400,8 +410,8 @@ impl Bot {
|
|||||||
|
|
||||||
match result {
|
match result {
|
||||||
TradeResult::Completed => {
|
TradeResult::Completed => {
|
||||||
if let Some(trade) = &self.previous_trade {
|
if let Some(reciept) = &self.previous_trade_receipt {
|
||||||
log::info!("Trade with {their_name}: {:?}", trade.offers);
|
log::info!("Trade with {their_name}: {:?}", reciept);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.client.send_command(
|
self.client.send_command(
|
||||||
@ -528,13 +538,6 @@ impl Bot {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the trade hasn't changed, do nothing to avoid spamming the server.
|
|
||||||
if let Some(previous) = &self.previous_trade {
|
|
||||||
if previous == &trade {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let inventories = self.client.inventories();
|
let inventories = self.client.inventories();
|
||||||
let me = self.client.entity();
|
let me = self.client.entity();
|
||||||
let them = self
|
let them = self
|
||||||
@ -551,6 +554,10 @@ impl Bot {
|
|||||||
let coins_owned = COINS.to_owned();
|
let coins_owned = COINS.to_owned();
|
||||||
let get_my_coins = my_inventory.get_slot_of_item_by_def_id(&coins_owned);
|
let get_my_coins = my_inventory.get_slot_of_item_by_def_id(&coins_owned);
|
||||||
let get_their_coins = their_inventory.get_slot_of_item_by_def_id(&coins_owned);
|
let get_their_coins = their_inventory.get_slot_of_item_by_def_id(&coins_owned);
|
||||||
|
let mut receipt = Reciept {
|
||||||
|
my_items: HashMap::new(),
|
||||||
|
their_items: HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let (mut my_offered_coin_amount, mut their_offered_coin_amount) = (0, 0);
|
let (mut my_offered_coin_amount, mut their_offered_coin_amount) = (0, 0);
|
||||||
let my_offered_items_value =
|
let my_offered_items_value =
|
||||||
@ -578,6 +585,9 @@ impl Bot {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let item_name = self.get_item_name(item_id);
|
||||||
|
|
||||||
|
receipt.my_items.insert(item_name, *quantity);
|
||||||
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
|
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
|
||||||
} else {
|
} else {
|
||||||
acc
|
acc
|
||||||
@ -608,6 +618,9 @@ impl Bot {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let item_name = self.get_item_name(item_id);
|
||||||
|
|
||||||
|
receipt.their_items.insert(item_name, *quantity);
|
||||||
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
|
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
|
||||||
} else {
|
} else {
|
||||||
acc
|
acc
|
||||||
@ -648,8 +661,15 @@ impl Bot {
|
|||||||
|
|
||||||
let phase = trade.phase;
|
let phase = trade.phase;
|
||||||
|
|
||||||
// Up until now there may have been an error, so we only update the previous offer now.
|
// If the trade hasn't changed, do nothing to avoid spamming the server.
|
||||||
// The trade action is infallible from here.
|
if let Some(previous) = &self.previous_trade {
|
||||||
|
if previous == &trade {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Up until now there may have been an error, so we only update and check the previous
|
||||||
|
// offer now. The trade action is infallible from here.
|
||||||
self.previous_trade = Some(trade);
|
self.previous_trade = Some(trade);
|
||||||
|
|
||||||
// Before running any actual trade logic, remove items that are not for sale or not being
|
// Before running any actual trade logic, remove items that are not for sale or not being
|
||||||
@ -684,6 +704,8 @@ impl Bot {
|
|||||||
|
|
||||||
// If the trade is balanced
|
// If the trade is balanced
|
||||||
if difference == 0 {
|
if difference == 0 {
|
||||||
|
self.previous_trade_receipt = Some(receipt);
|
||||||
|
|
||||||
// Accept
|
// Accept
|
||||||
self.client.perform_trade_action(TradeAction::Accept(phase));
|
self.client.perform_trade_action(TradeAction::Accept(phase));
|
||||||
// If they are offering more
|
// If they are offering more
|
||||||
@ -745,40 +767,21 @@ impl Bot {
|
|||||||
.find_player_alias(target)
|
.find_player_alias(target)
|
||||||
.ok_or("Failed to find player name")?
|
.ok_or("Failed to find player name")?
|
||||||
.to_string();
|
.to_string();
|
||||||
let mut found = false;
|
let mut buying = Vec::new();
|
||||||
|
let mut selling = Vec::new();
|
||||||
|
|
||||||
for (item_id, price) in &self.buy_prices.0 {
|
for (item_id, price) in &self.buy_prices.0 {
|
||||||
let item_name = self.get_item_name(item_id.as_ref());
|
let item_name = self.get_item_name(item_id.as_ref());
|
||||||
|
|
||||||
if item_name.to_lowercase().contains(&search_term) {
|
if item_name.to_lowercase().contains(&search_term) {
|
||||||
log::info!("Sending price info on {item_name} to {player_name}");
|
buying.push((item_name, price));
|
||||||
|
|
||||||
self.client.send_command(
|
|
||||||
"tell".to_string(),
|
|
||||||
vec![
|
|
||||||
player_name.clone(),
|
|
||||||
format!("Buying {item_name} for {price} coins."),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(item_id_string) = item_id.as_ref().itemdef_id() {
|
if let Some(item_id_string) = item_id.as_ref().itemdef_id() {
|
||||||
if item_id_string.to_lowercase().contains(&search_term) {
|
if item_id_string.to_lowercase().contains(&search_term) {
|
||||||
log::info!("Sending price info on {item_id_string} to {player_name}");
|
buying.push((item_name, price));
|
||||||
|
|
||||||
self.client.send_command(
|
|
||||||
"tell".to_string(),
|
|
||||||
vec![
|
|
||||||
player_name.clone(),
|
|
||||||
format!("Buying {item_id_string} for {price} coins."),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,39 +790,21 @@ impl Bot {
|
|||||||
let item_name = self.get_item_name(item_id.as_ref());
|
let item_name = self.get_item_name(item_id.as_ref());
|
||||||
|
|
||||||
if item_name.to_lowercase().contains(&search_term) {
|
if item_name.to_lowercase().contains(&search_term) {
|
||||||
log::info!("Sending price info on {item_name} to {player_name}");
|
selling.push((item_name, price));
|
||||||
|
|
||||||
self.client.send_command(
|
|
||||||
"tell".to_string(),
|
|
||||||
vec![
|
|
||||||
player_name.clone(),
|
|
||||||
format!("Selling {item_name} for {price} coins."),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(item_id_string) = item_id.as_ref().itemdef_id() {
|
if let Some(item_id_string) = item_id.as_ref().itemdef_id() {
|
||||||
if item_id_string.to_lowercase().contains(&search_term) {
|
if item_id_string.to_lowercase().contains(&search_term) {
|
||||||
log::info!("Sending price info on {item_id_string} to {player_name}");
|
selling.push((item_name, price));
|
||||||
|
|
||||||
self.client.send_command(
|
|
||||||
"tell".to_string(),
|
|
||||||
vec![
|
|
||||||
player_name.clone(),
|
|
||||||
format!("Selling {item_id_string} for {price} coins."),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
let total_found = buying.len() + selling.len();
|
||||||
|
|
||||||
|
if total_found == 0 {
|
||||||
log::info!("Found no price for \"{original_search_term}\" for {player_name}");
|
log::info!("Found no price for \"{original_search_term}\" for {player_name}");
|
||||||
|
|
||||||
self.client.send_command(
|
self.client.send_command(
|
||||||
@ -829,6 +814,48 @@ impl Bot {
|
|||||||
format!("I don't have a price for {original_search_term}."),
|
format!("I don't have a price for {original_search_term}."),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if total_found > 10 {
|
||||||
|
log::info!(
|
||||||
|
"Found {total_found} prices for \"{original_search_term}\" for {player_name}, not sending."
|
||||||
|
);
|
||||||
|
|
||||||
|
self.client.send_command(
|
||||||
|
"tell".to_string(),
|
||||||
|
vec![
|
||||||
|
player_name,
|
||||||
|
format!(
|
||||||
|
"I found {total_found} prices for {original_search_term}. Please be more specific."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!("Found {total_found} prices for \"{original_search_term}\" for {player_name}, sending prices.");
|
||||||
|
|
||||||
|
for (item_name, price) in buying {
|
||||||
|
self.client.send_command(
|
||||||
|
"tell".to_string(),
|
||||||
|
vec![
|
||||||
|
player_name.clone(),
|
||||||
|
format!("Buying {item_name} for {price} coins."),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item_name, price) in selling {
|
||||||
|
self.client.send_command(
|
||||||
|
"tell".to_string(),
|
||||||
|
vec![
|
||||||
|
player_name.clone(),
|
||||||
|
format!("Selling {item_name} for {price} coins."),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -77,24 +77,17 @@ impl<'de> Visitor<'de> for PriceListVisitor {
|
|||||||
primary.insert_str(0, "common.items.modular.weapon.primary.");
|
primary.insert_str(0, "common.items.modular.weapon.primary.");
|
||||||
secondary.insert_str(0, "common.items.modular.weapon.secondary.");
|
secondary.insert_str(0, "common.items.modular.weapon.secondary.");
|
||||||
|
|
||||||
let material = ItemDefinitionIdOwned::Simple(
|
|
||||||
material
|
|
||||||
.asset_identifier()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
de::Error::custom(format!(
|
|
||||||
"{:?} is not a valid material for modular crafted items",
|
|
||||||
material
|
|
||||||
))
|
|
||||||
})?
|
|
||||||
.to_string(),
|
|
||||||
);
|
|
||||||
|
|
||||||
ItemDefinitionIdOwned::Modular {
|
ItemDefinitionIdOwned::Modular {
|
||||||
pseudo_base: "veloren.core.pseudo_items.modular.tool".to_string(),
|
pseudo_base: "veloren.core.pseudo_items.modular.tool".to_string(),
|
||||||
components: vec![ItemDefinitionIdOwned::Compound {
|
components: vec![
|
||||||
simple_base: primary,
|
ItemDefinitionIdOwned::Compound {
|
||||||
components: vec![ItemDefinitionIdOwned::Simple(secondary), material],
|
simple_base: primary,
|
||||||
}],
|
components: vec![ItemDefinitionIdOwned::Simple(
|
||||||
|
material.asset_identifier().unwrap().to_string(),
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
ItemDefinitionIdOwned::Simple(secondary),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[simple] => {
|
[simple] => {
|
||||||
|
Loading…
Reference in New Issue
Block a user