mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Client-side trade improvements.
- Add item tooltips in trade. - More localization support. - Fix bindings (R for trade, B for bag).
This commit is contained in:
parent
b4adc5369a
commit
559ad7b7f5
@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Adjusted Stonework Defender loot table to remove mindflayer drops (bag, staff, glider).
|
- Adjusted Stonework Defender loot table to remove mindflayer drops (bag, staff, glider).
|
||||||
- Changed default controller key bindings
|
- Changed default controller key bindings
|
||||||
- Improved network efficiency by ≈ factor 10 by using tokio.
|
- Improved network efficiency by ≈ factor 10 by using tokio.
|
||||||
|
- Added item tooltips to trade window.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
"hud.trade.has_accepted": "{playername}\nhas accepted",
|
"hud.trade.has_accepted": "{playername}\nhas accepted",
|
||||||
"hud.trade.accept": "Accept",
|
"hud.trade.accept": "Accept",
|
||||||
"hud.trade.decline": "Decline",
|
"hud.trade.decline": "Decline",
|
||||||
|
"hud.trade.invite_sent": "Trade request sent to {playername}.",
|
||||||
|
"hud.trade.result.completed": "Trade completed successfully.",
|
||||||
|
"hud.trade.result.declined": "Trade declined.",
|
||||||
|
"hud.trade.result.nospace": "Not enough space to complete the trade.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ impl Inventory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slot(&self, inv_slot_id: InvSlotId) -> Option<&InvSlot> {
|
pub fn slot(&self, inv_slot_id: InvSlotId) -> Option<&InvSlot> {
|
||||||
match SlotId::from(inv_slot_id) {
|
match SlotId::from(inv_slot_id) {
|
||||||
SlotId::Inventory(slot_idx) => self.slots.get(slot_idx),
|
SlotId::Inventory(slot_idx) => self.slots.get(slot_idx),
|
||||||
SlotId::Loadout(loadout_slot_id) => self.loadout.inv_slot(loadout_slot_id),
|
SlotId::Loadout(loadout_slot_id) => self.loadout.inv_slot(loadout_slot_id),
|
||||||
|
@ -2131,6 +2131,7 @@ impl Hud {
|
|||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.item_imgs,
|
&self.item_imgs,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
|
&self.rot_imgs,
|
||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
&mut self.slot_manager,
|
&mut self.slot_manager,
|
||||||
i18n,
|
i18n,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::Imgs,
|
get_quality_col,
|
||||||
|
img_ids::{Imgs, ImgsRot},
|
||||||
item_imgs::ItemImgs,
|
item_imgs::ItemImgs,
|
||||||
slots::{SlotManager, TradeSlot},
|
slots::{SlotManager, TradeSlot},
|
||||||
TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
|
||||||
@ -9,12 +10,12 @@ use crate::{
|
|||||||
ui::{
|
ui::{
|
||||||
fonts::Fonts,
|
fonts::Fonts,
|
||||||
slot::{ContentSize, SlotMaker},
|
slot::{ContentSize, SlotMaker},
|
||||||
TooltipManager,
|
ImageFrame, Tooltip, TooltipManager, Tooltipable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
comp::Inventory,
|
comp::{inventory::item::Quality, Inventory},
|
||||||
trade::{PendingTrade, TradeAction, TradePhase},
|
trade::{PendingTrade, TradeAction, TradePhase},
|
||||||
};
|
};
|
||||||
use common_net::sync::WorldSyncExt;
|
use common_net::sync::WorldSyncExt;
|
||||||
@ -54,9 +55,10 @@ pub struct Trade<'a> {
|
|||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
item_imgs: &'a ItemImgs,
|
item_imgs: &'a ItemImgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
|
rot_imgs: &'a ImgsRot,
|
||||||
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
common: widget::CommonBuilder,
|
common: widget::CommonBuilder,
|
||||||
//tooltip_manager: &'a mut TooltipManager,
|
|
||||||
slot_manager: &'a mut SlotManager,
|
slot_manager: &'a mut SlotManager,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
@ -68,7 +70,8 @@ impl<'a> Trade<'a> {
|
|||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
item_imgs: &'a ItemImgs,
|
item_imgs: &'a ItemImgs,
|
||||||
fonts: &'a Fonts,
|
fonts: &'a Fonts,
|
||||||
_tooltip_manager: &'a mut TooltipManager,
|
rot_imgs: &'a ImgsRot,
|
||||||
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
slot_manager: &'a mut SlotManager,
|
slot_manager: &'a mut SlotManager,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
@ -78,6 +81,8 @@ impl<'a> Trade<'a> {
|
|||||||
imgs,
|
imgs,
|
||||||
item_imgs,
|
item_imgs,
|
||||||
fonts,
|
fonts,
|
||||||
|
rot_imgs,
|
||||||
|
tooltip_manager,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
//tooltip_manager,
|
//tooltip_manager,
|
||||||
slot_manager,
|
slot_manager,
|
||||||
@ -225,6 +230,24 @@ impl<'a> Trade<'a> {
|
|||||||
who: usize,
|
who: usize,
|
||||||
tradeslots: &[TradeSlot],
|
tradeslots: &[TradeSlot],
|
||||||
) {
|
) {
|
||||||
|
let item_tooltip = Tooltip::new({
|
||||||
|
// Edge images [t, b, r, l]
|
||||||
|
// Corner images [tr, tl, br, bl]
|
||||||
|
let edge = &self.rot_imgs.tt_side;
|
||||||
|
let corner = &self.rot_imgs.tt_corner;
|
||||||
|
ImageFrame::new(
|
||||||
|
[edge.cw180, edge.none, edge.cw270, edge.cw90],
|
||||||
|
[corner.none, corner.cw270, corner.cw90, corner.cw180],
|
||||||
|
Color::Rgba(0.08, 0.07, 0.04, 1.0),
|
||||||
|
5.0,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.title_font_size(self.fonts.cyri.scale(15))
|
||||||
|
.parent(ui.window)
|
||||||
|
.desc_font_size(self.fonts.cyri.scale(12))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.desc_text_color(TEXT_COLOR);
|
||||||
|
|
||||||
let mut slot_maker = SlotMaker {
|
let mut slot_maker = SlotMaker {
|
||||||
empty_slot: self.imgs.inv_slot,
|
empty_slot: self.imgs.inv_slot,
|
||||||
filled_slot: self.imgs.inv_slot,
|
filled_slot: self.imgs.inv_slot,
|
||||||
@ -270,7 +293,33 @@ impl<'a> Trade<'a> {
|
|||||||
0.0 + y as f64 * (40.0),
|
0.0 + y as f64 * (40.0),
|
||||||
0.0 + x as f64 * (40.0),
|
0.0 + x as f64 * (40.0),
|
||||||
);
|
);
|
||||||
slot_widget.set(state.ids.inv_slots[i + who * MAX_TRADE_SLOTS], ui);
|
let slot_id = state.ids.inv_slots[i + who * MAX_TRADE_SLOTS];
|
||||||
|
if let Some(Some(item)) = slot.invslot.and_then(|slotid| inventory.slot(slotid)) {
|
||||||
|
let (title, desc) = super::util::item_text(item);
|
||||||
|
let quality_col = get_quality_col(item);
|
||||||
|
let quality_col_img = match item.quality() {
|
||||||
|
Quality::Low => self.imgs.inv_slot_grey,
|
||||||
|
Quality::Common => self.imgs.inv_slot,
|
||||||
|
Quality::Moderate => self.imgs.inv_slot_green,
|
||||||
|
Quality::High => self.imgs.inv_slot_blue,
|
||||||
|
Quality::Epic => self.imgs.inv_slot_purple,
|
||||||
|
Quality::Legendary => self.imgs.inv_slot_gold,
|
||||||
|
Quality::Artifact => self.imgs.inv_slot_orange,
|
||||||
|
_ => self.imgs.inv_slot_red,
|
||||||
|
};
|
||||||
|
slot_widget
|
||||||
|
.filled_slot(quality_col_img)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
title,
|
||||||
|
&*desc,
|
||||||
|
&item_tooltip,
|
||||||
|
quality_col,
|
||||||
|
)
|
||||||
|
.set(slot_id, ui);
|
||||||
|
} else {
|
||||||
|
slot_widget.set(slot_id, ui);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,25 +465,6 @@ impl<'a> Widget for Trade<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: item tooltips in trade preview
|
|
||||||
/*let trade_tooltip = Tooltip::new({
|
|
||||||
// Edge images [t, b, r, l]
|
|
||||||
// Corner images [tr, tl, br, bl]
|
|
||||||
let edge = &self.rot_imgs.tt_side;
|
|
||||||
let corner = &self.rot_imgs.tt_corner;
|
|
||||||
ImageFrame::new(
|
|
||||||
[edge.cw180, edge.none, edge.cw270, edge.cw90],
|
|
||||||
[corner.none, corner.cw270, corner.cw90, corner.cw180],
|
|
||||||
Color::Rgba(0.08, 0.07, 0.04, 1.0),
|
|
||||||
5.0,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.title_font_size(self.fonts.cyri.scale(15))
|
|
||||||
.parent(ui.window)
|
|
||||||
.desc_font_size(self.fonts.cyri.scale(12))
|
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
|
||||||
.desc_text_color(TEXT_COLOR);*/
|
|
||||||
|
|
||||||
self.background(&mut state, ui);
|
self.background(&mut state, ui);
|
||||||
self.title(&mut state, ui);
|
self.title(&mut state, ui);
|
||||||
self.phase_indicator(&mut state, ui, &trade);
|
self.phase_indicator(&mut state, ui, &trade);
|
||||||
|
@ -133,14 +133,15 @@ impl SessionState {
|
|||||||
answer,
|
answer,
|
||||||
kind,
|
kind,
|
||||||
} => {
|
} => {
|
||||||
// TODO: i18n
|
// TODO: i18n (complicated since substituting phrases at this granularity may
|
||||||
|
// not be grammatical in some languages)
|
||||||
let kind_str = match kind {
|
let kind_str = match kind {
|
||||||
InviteKind::Group => "Group",
|
InviteKind::Group => "Group",
|
||||||
InviteKind::Trade => "Trade",
|
InviteKind::Trade => "Trade",
|
||||||
};
|
};
|
||||||
let target_name = match client.player_list().get(&target) {
|
let target_name = match client.player_list().get(&target) {
|
||||||
Some(info) => info.player_alias.clone(),
|
Some(info) => info.player_alias.clone(),
|
||||||
None => "<unknown>".to_string(),
|
None => format!("<entity {}>", target),
|
||||||
};
|
};
|
||||||
let answer_str = match answer {
|
let answer_str = match answer {
|
||||||
InviteAnswer::Accepted => "accepted",
|
InviteAnswer::Accepted => "accepted",
|
||||||
@ -151,11 +152,11 @@ impl SessionState {
|
|||||||
self.hud.new_message(ChatType::Meta.chat_msg(msg));
|
self.hud.new_message(ChatType::Meta.chat_msg(msg));
|
||||||
},
|
},
|
||||||
client::Event::TradeComplete { result, trade: _ } => {
|
client::Event::TradeComplete { result, trade: _ } => {
|
||||||
// TODO: i18n, entity names
|
let i18n = global_state.i18n.read();
|
||||||
let msg = match result {
|
let msg = match result {
|
||||||
TradeResult::Completed => "Trade completed successfully.",
|
TradeResult::Completed => i18n.get("hud.trade.result.completed"),
|
||||||
TradeResult::Declined => "Trade declined.",
|
TradeResult::Declined => i18n.get("hud.trade.result.declined"),
|
||||||
TradeResult::NotEnoughSpace => "Not enough space to complete the trade.",
|
TradeResult::NotEnoughSpace => i18n.get("hud.trade.result.nospace"),
|
||||||
};
|
};
|
||||||
self.hud.new_message(ChatType::Meta.chat_msg(msg));
|
self.hud.new_message(ChatType::Meta.chat_msg(msg));
|
||||||
},
|
},
|
||||||
@ -573,11 +574,22 @@ impl PlayState for SessionState {
|
|||||||
match interactable {
|
match interactable {
|
||||||
Interactable::Block(_, _) => {},
|
Interactable::Block(_, _) => {},
|
||||||
Interactable::Entity(entity) => {
|
Interactable::Entity(entity) => {
|
||||||
client
|
if let Some(uid) =
|
||||||
.state()
|
client.state().ecs().uid_from_entity(entity)
|
||||||
.ecs()
|
{
|
||||||
.uid_from_entity(entity)
|
let name = client
|
||||||
.map(|uid| client.send_invite(uid, InviteKind::Trade));
|
.player_list()
|
||||||
|
.get(&uid)
|
||||||
|
.map(|info| info.player_alias.clone())
|
||||||
|
.unwrap_or_else(|| format!("<entity {:?}>", uid));
|
||||||
|
let msg = global_state
|
||||||
|
.i18n
|
||||||
|
.read()
|
||||||
|
.get("hud.trade.invite_sent")
|
||||||
|
.replace("{playername}", &name);
|
||||||
|
self.hud.new_message(ChatType::Meta.chat_msg(msg));
|
||||||
|
client.send_invite(uid, InviteKind::Trade)
|
||||||
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,8 @@ impl ControlSettings {
|
|||||||
GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G),
|
GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G),
|
||||||
GameInput::Mount => KeyMouse::Key(VirtualKeyCode::F),
|
GameInput::Mount => KeyMouse::Key(VirtualKeyCode::F),
|
||||||
GameInput::Map => KeyMouse::Key(VirtualKeyCode::M),
|
GameInput::Map => KeyMouse::Key(VirtualKeyCode::M),
|
||||||
GameInput::Bag => KeyMouse::Key(VirtualKeyCode::R),
|
GameInput::Bag => KeyMouse::Key(VirtualKeyCode::B),
|
||||||
GameInput::Trade => KeyMouse::Key(VirtualKeyCode::B),
|
GameInput::Trade => KeyMouse::Key(VirtualKeyCode::R),
|
||||||
GameInput::Social => KeyMouse::Key(VirtualKeyCode::O),
|
GameInput::Social => KeyMouse::Key(VirtualKeyCode::O),
|
||||||
GameInput::Crafting => KeyMouse::Key(VirtualKeyCode::C),
|
GameInput::Crafting => KeyMouse::Key(VirtualKeyCode::C),
|
||||||
GameInput::Spellbook => KeyMouse::Key(VirtualKeyCode::P),
|
GameInput::Spellbook => KeyMouse::Key(VirtualKeyCode::P),
|
||||||
|
Loading…
Reference in New Issue
Block a user