Set buy prices according to SitePrices

This commit is contained in:
Jeff 2024-11-16 18:27:49 -05:00
parent c7d87d0638
commit 3b82067a50

View File

@ -18,18 +18,20 @@ use veloren_client_i18n::LocalizationHandle;
use veloren_common::{ use veloren_common::{
clock::Clock, clock::Clock,
comp::{ comp::{
inventory::trade_pricing::TradePricing,
invite::InviteKind, invite::InviteKind,
item::{ItemDefinitionId, ItemDesc, ItemI18n, MaterialStatManifest}, item::{ItemDefinitionId, ItemDesc, ItemI18n, MaterialStatManifest},
tool::AbilityMap, tool::AbilityMap,
ChatType, ControllerInputs, Item, Ori, Pos, ChatType, ControllerInputs, Item, Ori, Pos,
}, },
time::DayPeriod, time::DayPeriod,
trade::{PendingTrade, TradeAction, TradeResult}, trade::{PendingTrade, SitePrices, TradeAction, TradeResult},
uid::Uid, uid::Uid,
uuid::Uuid, uuid::Uuid,
ViewDistances, ViewDistances,
}; };
use veloren_common_net::sync::WorldSyncExt; use veloren_common_net::sync::WorldSyncExt;
use veloren_world::site::Economy;
use crate::config::PriceList; use crate::config::PriceList;
@ -53,6 +55,7 @@ pub struct Bot {
material_manifest: MaterialStatManifest, material_manifest: MaterialStatManifest,
item_i18n: ItemI18n, item_i18n: ItemI18n,
localization: LocalizationHandle, localization: LocalizationHandle,
site_prices: SitePrices,
buy_prices: PriceList, buy_prices: PriceList,
sell_prices: PriceList, sell_prices: PriceList,
@ -135,6 +138,9 @@ impl Bot {
} else { } else {
client.current::<Ori>().ok_or("Failed to get orientation")? client.current::<Ori>().ok_or("Failed to get orientation")?
}; };
let economy = Economy::default();
let site_prices = economy.get_site_prices();
let now = Instant::now(); let now = Instant::now();
Ok(Bot { Ok(Bot {
@ -147,6 +153,7 @@ impl Bot {
material_manifest: MaterialStatManifest::load().read().clone(), material_manifest: MaterialStatManifest::load().read().clone(),
item_i18n: ItemI18n::new_expect(), item_i18n: ItemI18n::new_expect(),
localization: LocalizationHandle::load_expect("en"), localization: LocalizationHandle::load_expect("en"),
site_prices,
buy_prices, buy_prices,
sell_prices, sell_prices,
trade_mode: TradeMode::Trade, trade_mode: TradeMode::Trade,
@ -550,43 +557,38 @@ impl Bot {
}; };
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 mut my_item_to_remove = None;
my_offer let my_offered_items_value = my_offer.into_iter().try_fold(
.into_iter() 0,
.fold(0, |acc: i32, (slot_id, quantity)| { |acc: i32, (slot_id, quantity)| -> Result<i32, String> {
if let Some(item) = my_inventory.get(*slot_id) { if let Some(item) = my_inventory.get(*slot_id) {
let item_id = item.item_definition_id(); let item_id = item.item_definition_id();
let item_value = if item_id == COINS { let item_value: i32 = if item_id == COINS {
my_offered_coin_amount = *quantity as i32; my_offered_coin_amount = *quantity as i32;
1 1
} else { } else {
self.sell_prices my_item_to_remove = Some((*slot_id, *quantity));
.0
.get(&item_id) 0
.map(|int| *int as i32)
.unwrap_or_else(|| {
self.buy_prices
.0
.get(&item_id)
.map(|int| 0 - *int as i32)
.unwrap_or(i32::MIN)
})
}; };
let item_name = self.get_item_name(item_id); let item_name = self.get_item_name(item_id);
receipt.my_items.insert(item_name, *quantity); receipt.my_items.insert(item_name, *quantity);
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
let acc = acc.saturating_add(item_value.saturating_mul(*quantity as i32));
Ok(acc)
} else { } else {
acc Ok(acc)
} }
}); },
let their_offered_items_value = )?;
their_offer let their_offered_items_value = their_offer.into_iter().try_fold(
.into_iter() 0,
.fold(0, |acc: i32, (slot_id, quantity)| { |acc: i32, (slot_id, quantity)| -> Result<i32, String> {
if let Some(item) = their_inventory.get(*slot_id) { if let Some(item) = their_inventory.get(*slot_id) {
let item_id = item.item_definition_id(); let item_id = item.item_definition_id();
@ -595,57 +597,21 @@ impl Bot {
1 1
} else { } else {
self.buy_prices self.get_npc_price(item_id.clone())? as i32 * *quantity as i32
.0
.get(&item_id)
.map(|int| *int as i32)
.unwrap_or_else(|| {
self.sell_prices
.0
.get(&item_id)
.map(|int| 0 - *int as i32)
.unwrap_or(0)
})
}; };
let item_name = self.get_item_name(item_id); let item_name = self.get_item_name(item_id);
receipt.their_items.insert(item_name, *quantity); receipt.their_items.insert(item_name, *quantity);
acc.saturating_add(item_value.saturating_mul(*quantity as i32))
let acc = acc.saturating_add(item_value.saturating_mul(*quantity as i32));
Ok(acc)
} else { } else {
acc Ok(acc)
}
});
let mut my_item_to_remove = None;
for (slot_id, amount) in my_offer {
let item = my_inventory.get(*slot_id).ok_or("Failed to get item")?;
let item_id = item.item_definition_id();
if item_id == COINS {
continue;
}
if !self.sell_prices.0.contains_key(&item_id) {
my_item_to_remove = Some((*slot_id, *amount));
}
}
let mut their_item_to_remove = None;
for (slot_id, amount) in their_offer {
let item = their_inventory.get(*slot_id).ok_or("Failed to get item")?;
let item_id = item.item_definition_id();
if item_id == COINS {
continue;
}
if !self.buy_prices.0.contains_key(&item_id) {
their_item_to_remove = Some((*slot_id, *amount));
}
} }
},
)?;
drop(inventories); drop(inventories);
@ -675,16 +641,6 @@ impl Bot {
return Ok(()); return Ok(());
} }
if let Some((slot_id, quantity)) = their_item_to_remove {
self.client.perform_trade_action(TradeAction::RemoveItem {
item: slot_id,
quantity,
ours: false,
});
return Ok(());
}
let difference = their_offered_items_value - my_offered_items_value; let difference = their_offered_items_value - my_offered_items_value;
// The if/else statements below implement the bot's main feature: buying, selling and // The if/else statements below implement the bot's main feature: buying, selling and
@ -1000,6 +956,26 @@ impl Bot {
} }
}) })
} }
pub fn get_npc_price(&self, item_definition_id: ItemDefinitionId<'_>) -> Result<f32, String> {
let materials = TradePricing::get_materials(&item_definition_id)
.ok_or("Failed to get NPC price for item.")?;
let buy_price: f32 = materials
.iter()
.map(|(value, good)| {
self.site_prices
.values
.get(good)
.cloned()
.unwrap_or_default()
* value
* good.trade_margin()
* 5.0
})
.sum();
Ok(buy_price)
}
} }
#[derive(Debug)] #[derive(Debug)]