diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 4e940ea2e8..2f6bb986fc 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -179,7 +179,7 @@ impl<'a> From<&'a Body> for Psyche { pub enum AgentEvent { /// Engage in conversation with entity with Uid Talk(Uid), - TradeInvite(Uid), + TradeInvite(Uid, Box>>), FinishedTrade(TradeResult), UpdatePendingTrade( // this data structure is large so box it to keep AgentEvent small diff --git a/server/src/events/invite.rs b/server/src/events/invite.rs index b67a3b0d89..8de2d8d074 100644 --- a/server/src/events/invite.rs +++ b/server/src/events/invite.rs @@ -15,9 +15,10 @@ use common_net::{ msg::{InviteAnswer, ServerGeneral}, sync::WorldSyncExt, }; -use specs::world::WorldExt; +use specs::{world::WorldExt, Join}; use std::time::{Duration, Instant}; use tracing::{error, warn}; +use vek::Vec3; /// Time before invite times out const INVITE_TIMEOUT_DUR: Duration = Duration::from_secs(31); @@ -73,7 +74,6 @@ pub fn handle_invite( } } - let mut agents = state.ecs().write_storage::(); let mut invites = state.ecs().write_storage::(); if invites.contains(invitee) { @@ -120,6 +120,16 @@ pub fn handle_invite( } }; + let trader_positions: Vec> = { + let positions = state.ecs().write_storage::(); + let agents = state.ecs().read_storage::(); + (&agents, &positions) + .join() + .filter_map(|(a, p)| a.trade_for_site.map(|_| p.0.clone())) + .collect() + }; + let mut agents = state.ecs().write_storage::(); + // If client comp if let (Some(client), Some(inviter)) = (clients.get(invitee), uids.get(inviter).copied()) { if send_invite() { @@ -132,7 +142,10 @@ pub fn handle_invite( } else if let Some(agent) = agents.get_mut(invitee) { if send_invite() { if let Some(inviter) = uids.get(inviter) { - agent.inbox.push_front(AgentEvent::TradeInvite(*inviter)); + agent.inbox.push_front(AgentEvent::TradeInvite( + *inviter, + Box::new(trader_positions), + )); invite_sent = true; } } diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index a2c3e2952f..afc09cffab 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -899,7 +899,7 @@ impl<'a> AgentData<'a> { } } }, - Some(AgentEvent::TradeInvite(with)) => { + Some(AgentEvent::TradeInvite(with, pos)) => { if agent.trade_for_site.is_some() && !agent.trading { // stand still and looking towards the trading player controller.actions.push(ControlAction::Talk); @@ -917,7 +917,28 @@ impl<'a> AgentData<'a> { .push(ControlEvent::InviteResponse(InviteResponse::Accept)); agent.trading = true; } else { - // TODO: Provide a hint where to find the closest merchant? + // Provide a hint where to find the closest merchant? + let mypos = self.pos.0; + let mut closest = std::f32::INFINITY; + let mut closest_diff = None; + for p in pos.iter() { + let diff = (p.x - mypos.x, p.y - mypos.y); + let dist = diff.0.powi(2) + diff.1.powi(2); + if dist < closest { + closest = dist; + closest_diff = Some(diff); + } + } + if let Some(closest_diff) = closest_diff { + event_emitter.emit(ServerEvent::Chat(UnresolvedChatMsg::npc( + *self.uid, + format!( + "The next merchant is at {},{}", + closest_diff.0, closest_diff.1 + ), + ))) + } + controller .events .push(ControlEvent::InviteResponse(InviteResponse::Decline));