This commit is contained in:
Jeff 2024-07-08 10:39:19 -04:00
parent b86221e58f
commit 3ea0475ba7
4 changed files with 72 additions and 19 deletions

1
Cargo.lock generated
View File

@ -2795,6 +2795,7 @@ dependencies = [
"serde", "serde",
"tokio", "tokio",
"toml", "toml",
"vek",
"veloren-client", "veloren-client",
"veloren-common", "veloren-common",
"veloren-common-net", "veloren-common-net",

View File

@ -13,6 +13,7 @@ toml = "0.8.14"
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.203", features = ["derive"] }
log = "0.4.22" log = "0.4.22"
env_logger = "0.11.3" env_logger = "0.11.3"
vek = "0.17.0"
[patch.crates-io] [patch.crates-io]
specs = { git = "https://github.com/amethyst/specs.git", rev = "4e2da1df29ee840baa9b936593c45592b7c9ae27" } specs = { git = "https://github.com/amethyst/specs.git", rev = "4e2da1df29ee840baa9b936593c45592b7c9ae27" }

View File

@ -5,10 +5,11 @@ use std::{
}; };
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use vek::{num_traits::Float, Quaternion};
use veloren_client::{addr::ConnectionArgs, Client, Event as VelorenEvent, WorldExt}; use veloren_client::{addr::ConnectionArgs, Client, Event as VelorenEvent, WorldExt};
use veloren_common::{ use veloren_common::{
clock::Clock, clock::Clock,
comp::{invite::InviteKind, item::ItemDefinitionIdOwned, ChatType, ControllerInputs, Pos}, comp::{invite::InviteKind, item::ItemDefinitionIdOwned, ChatType, ControllerInputs, Ori, Pos},
outcome::Outcome, outcome::Outcome,
trade::{PendingTrade, TradeAction}, trade::{PendingTrade, TradeAction},
uid::Uid, uid::Uid,
@ -25,6 +26,7 @@ enum TradeMode {
pub struct Bot { pub struct Bot {
position: [f32; 3], position: [f32; 3],
orientation: String,
client: Client, client: Client,
clock: Clock, clock: Clock,
buy_prices: HashMap<String, u32>, buy_prices: HashMap<String, u32>,
@ -42,6 +44,7 @@ impl Bot {
buy_prices: HashMap<String, u32>, buy_prices: HashMap<String, u32>,
sell_prices: HashMap<String, u32>, sell_prices: HashMap<String, u32>,
position: [f32; 3], position: [f32; 3],
orientation: String,
) -> Result<Self, String> { ) -> Result<Self, String> {
log::info!("Connecting to veloren"); log::info!("Connecting to veloren");
@ -50,6 +53,7 @@ impl Bot {
Ok(Bot { Ok(Bot {
position, position,
orientation,
client, client,
clock, clock,
buy_prices, buy_prices,
@ -90,7 +94,6 @@ impl Bot {
entity: 4, entity: 4,
}, },
); );
self.client.sort_inventory();
Ok(()) Ok(())
} }
@ -114,26 +117,14 @@ impl Bot {
self.client.enable_lantern(); self.client.enable_lantern();
} }
if let Some(position) = self.client.position() { self.handle_position_and_orientation()?;
if position != self.position.into() {
let entity = self.client.entity().clone();
let mut position_state = self.client.state_mut().ecs().write_storage::<Pos>();
position_state
.insert(entity, Pos(self.position.into()))
.map_err(|error| error.to_string())?;
}
}
if let Some((_, trade, _)) = self.client.pending_trade() { if let Some((_, trade, _)) = self.client.pending_trade() {
match self.trade_mode { match self.trade_mode {
TradeMode::Trade => self.handle_trade(trade.clone())?, TradeMode::Trade => self.handle_trade(trade.clone())?,
TradeMode::Take => self.handle_take(trade.clone()), TradeMode::Take => self.handle_take(trade.clone())?,
} }
} } else if self.client.pending_invites().is_empty() {
if !self.client.is_trading() {
self.trade_mode = TradeMode::Trade;
self.is_player_notified = false; self.is_player_notified = false;
self.client.accept_invite(); self.client.accept_invite();
@ -189,6 +180,13 @@ impl Bot {
} }
} }
} }
VelorenEvent::TradeComplete { result, .. } => {
log::info!("Completed trade: {result:?}");
if let TradeMode::Take = self.trade_mode {
self.trade_mode = TradeMode::Trade
}
}
_ => (), _ => (),
} }
@ -419,11 +417,24 @@ impl Bot {
Ok(()) Ok(())
} }
fn handle_take(&mut self, trade: PendingTrade) { fn handle_take(&mut self, trade: PendingTrade) -> Result<(), String> {
if trade.offers[0].is_empty() && !trade.offers[1].is_empty() { let my_offer_index = trade
.which_party(self.client.uid().ok_or("Failed to get uid")?)
.ok_or("Failed to get offer index")?;
let their_offer_index = if my_offer_index == 0 { 1 } else { 0 };
let (my_offer, their_offer) = {
(
&trade.offers[my_offer_index],
&trade.offers[their_offer_index],
)
};
if my_offer.is_empty() && !their_offer.is_empty() {
self.client self.client
.perform_trade_action(TradeAction::Accept(trade.phase)); .perform_trade_action(TradeAction::Accept(trade.phase));
} }
Ok(())
} }
fn send_price_info(&mut self, target: &Uid) -> Result<(), String> { fn send_price_info(&mut self, target: &Uid) -> Result<(), String> {
@ -477,6 +488,44 @@ impl Bot {
} }
}) })
} }
fn handle_position_and_orientation(&mut self) -> Result<(), String> {
let current_position = self.client.position();
if current_position == Some(self.position.into()) {
return Ok(());
}
let entity = self.client.entity().clone();
let ecs = self.client.state_mut().ecs();
let mut position_state = ecs.write_storage::<Pos>();
let mut orientation_state = ecs.write_storage::<Ori>();
let orientation = match self.orientation.to_lowercase().as_str() {
"west" => Ori::default()
.uprighted()
.rotated(Quaternion::rotation_z(90.0.to_radians())),
"south" => Ori::default()
.uprighted()
.rotated(Quaternion::rotation_z(180.0.to_radians())),
"east" => Ori::default()
.uprighted()
.rotated(Quaternion::rotation_z(270.0.to_radians())),
"north" => Ori::default(),
_ => {
return Err("Orientation must north, east, south or west".to_string());
}
};
orientation_state
.insert(entity, orientation)
.map_err(|error| error.to_string())?;
position_state
.insert(entity, Pos(self.position.into()))
.map_err(|error| error.to_string())?;
Ok(())
}
} }
fn connect_to_veloren(username: &str, password: &str) -> Result<Client, String> { fn connect_to_veloren(username: &str, password: &str) -> Result<Client, String> {

View File

@ -16,6 +16,7 @@ struct Config {
pub buy_prices: HashMap<String, u32>, pub buy_prices: HashMap<String, u32>,
pub sell_prices: HashMap<String, u32>, pub sell_prices: HashMap<String, u32>,
pub position: [f32; 3], pub position: [f32; 3],
pub orientation: String,
} }
impl Config { impl Config {
@ -44,6 +45,7 @@ fn main() {
config.buy_prices, config.buy_prices,
config.sell_prices, config.sell_prices,
config.position, config.position,
config.orientation,
) )
.expect("Failed to create bot"); .expect("Failed to create bot");