Merchants no longer buy/sell things they don't know the price of

This commit is contained in:
Joshua Barretto 2023-04-01 01:25:35 +01:00
parent ea007ff702
commit 8ba68e30f3
2 changed files with 86 additions and 58 deletions

View File

@ -381,15 +381,16 @@ impl SitePrices {
inventories: &[Option<ReducedInventory>; 2], inventories: &[Option<ReducedInventory>; 2],
who: usize, who: usize,
reduce: bool, reduce: bool,
) -> f32 { ) -> Option<f32> {
offers[who] offers[who]
.iter() .iter()
.map(|(slot, amount)| { .map(|(slot, amount)| {
inventories[who] inventories[who]
.as_ref() .as_ref()
.and_then(|ri| { .map(|ri| {
ri.inventory.get(slot).map(|item| { let item = ri.inventory.get(slot)?;
if let Some(vec) = TradePricing::get_materials(&item.name.as_ref()) { if let Some(vec) = TradePricing::get_materials(&item.name.as_ref()) {
Some(
vec.iter() vec.iter()
.map(|(amount2, material)| { .map(|(amount2, material)| {
self.values.get(material).copied().unwrap_or_default() self.values.get(material).copied().unwrap_or_default()
@ -397,15 +398,15 @@ impl SitePrices {
* (if reduce { material.trade_margin() } else { 1.0 }) * (if reduce { material.trade_margin() } else { 1.0 })
}) })
.sum::<f32>() .sum::<f32>()
* (*amount as f32) * (*amount as f32),
} else { )
0.0 } else {
} None
}) }
}) })
.unwrap_or_default() .unwrap_or(Some(0.0))
}) })
.sum() .try_fold(0.0, |a, p| Some(a + p?))
} }
} }

View File

@ -524,57 +524,84 @@ pub fn handle_inbox_update_pending_trade(bdata: &mut BehaviorData) -> bool {
let who = usize::from(!agent.behavior.is(BehaviorState::TRADING_ISSUER)); let who = usize::from(!agent.behavior.is(BehaviorState::TRADING_ISSUER));
match agent.behavior.trading_behavior { match agent.behavior.trading_behavior {
TradingBehavior::RequireBalanced { .. } => { TradingBehavior::RequireBalanced { .. } => {
let balance0: f32 = let balance0 = prices.balance(&pending.offers, &inventories, 1 - who, true);
prices.balance(&pending.offers, &inventories, 1 - who, true); let balance1 = prices.balance(&pending.offers, &inventories, who, false);
let balance1: f32 = prices.balance(&pending.offers, &inventories, who, false); match (balance0, balance1) {
if balance0 >= balance1 { (_, None) => {
// If the trade is favourable to us, only send an accept message if we're event_emitter.emit(ServerEvent::Chat(UnresolvedChatMsg::npc_say(
// not already accepting (since otherwise, spam-clicking the accept button *agent_data.uid,
// results in lagging and moving to the review phase of an unfavorable trade format!("I'm not willing to sell that item"),
// (although since the phase is included in the message, this shouldn't )))
// result in fully accepting an unfavourable trade)) },
if !pending.accept_flags[who] && !pending.is_empty_trade() { (None, _) => {
event_emitter.emit(ServerEvent::ProcessTradeAction( event_emitter.emit(ServerEvent::Chat(UnresolvedChatMsg::npc_say(
*agent_data.entity, *agent_data.uid,
tradeid, format!("I'm not willing to buy that item"),
TradeAction::Accept(pending.phase), )))
)); },
tracing::trace!(?tradeid, ?balance0, ?balance1, "Accept Pending Trade"); (Some(balance0), Some(balance1)) => {
} if balance0 >= balance1 {
} else { // If the trade is favourable to us, only send an accept message if
if balance1 > 0.0 { // we're not already accepting
let msg = format!( // (since otherwise, spam-clicking the accept button
"That only covers {:.0}% of my costs!", // results in lagging and moving to the review phase of an
(balance0 / balance1 * 100.0).floor() // unfavorable trade (although since
); // the phase is included in the message, this shouldn't
if let Some(tgt_data) = &agent.target { // result in fully accepting an unfavourable trade))
// If talking with someone in particular, "tell" it only to them if !pending.accept_flags[who] && !pending.is_empty_trade() {
if let Some(with) = read_data.uids.get(tgt_data.target) { event_emitter.emit(ServerEvent::ProcessTradeAction(
event_emitter.emit(ServerEvent::Chat( *agent_data.entity,
UnresolvedChatMsg::npc_tell(*agent_data.uid, *with, msg), tradeid,
)); TradeAction::Accept(pending.phase),
} else {
event_emitter.emit(ServerEvent::Chat(
UnresolvedChatMsg::npc_say(*agent_data.uid, msg),
)); ));
tracing::trace!(
?tradeid,
?balance0,
?balance1,
"Accept Pending Trade"
);
} }
} else { } else {
event_emitter.emit(ServerEvent::Chat(UnresolvedChatMsg::npc_say( if balance1 > 0.0 {
*agent_data.uid, let msg = format!(
msg, "That only covers {:.0}% of my costs!",
))); (balance0 / balance1 * 100.0).floor()
);
if let Some(tgt_data) = &agent.target {
// If talking with someone in particular, "tell" it only to
// them
if let Some(with) = read_data.uids.get(tgt_data.target) {
event_emitter.emit(ServerEvent::Chat(
UnresolvedChatMsg::npc_tell(
*agent_data.uid,
*with,
msg,
),
));
} else {
event_emitter.emit(ServerEvent::Chat(
UnresolvedChatMsg::npc_say(*agent_data.uid, msg),
));
}
} else {
event_emitter.emit(ServerEvent::Chat(
UnresolvedChatMsg::npc_say(*agent_data.uid, msg),
));
}
}
if pending.phase != TradePhase::Mutate {
// we got into the review phase but without balanced goods,
// decline
agent.behavior.unset(BehaviorState::TRADING);
agent.target = None;
event_emitter.emit(ServerEvent::ProcessTradeAction(
*agent_data.entity,
tradeid,
TradeAction::Decline,
));
}
} }
} },
if pending.phase != TradePhase::Mutate {
// we got into the review phase but without balanced goods, decline
agent.behavior.unset(BehaviorState::TRADING);
agent.target = None;
event_emitter.emit(ServerEvent::ProcessTradeAction(
*agent_data.entity,
tradeid,
TradeAction::Decline,
));
}
} }
}, },
TradingBehavior::AcceptFood => { TradingBehavior::AcceptFood => {