diff --git a/server/src/cmd.rs b/server/src/cmd.rs index f2fe307337..f41bfb8a0a 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1246,28 +1246,37 @@ fn handle_join_faction( .get(target) .map(|player| player.alias.clone()) { - if let Ok(faction) = scan_fmt!(&args, &action.arg_fmt(), String) { + let faction_leave = if let Ok(faction) = scan_fmt!(&args, &action.arg_fmt(), String) { let mode = comp::ChatMode::Faction(faction.clone()); let _ = server.state.ecs().write_storage().insert(client, mode); - let _ = server + let faction_leave = server .state .ecs() .write_storage() - .insert(client, comp::Faction(faction.clone())); + .insert(client, comp::Faction(faction.clone())) + .ok() + .flatten() + .map(|f| f.0); server.state.send_chat( ChatType::FactionMeta(faction.clone()) .chat_msg(format!("[{}] joined faction ({})", alias, faction)), ); + faction_leave } else { let mode = comp::ChatMode::default(); let _ = server.state.ecs().write_storage().insert(client, mode); - if let Some(comp::Faction(faction)) = server.state.ecs().write_storage().remove(client) - { - server.state.send_chat( - ChatType::FactionMeta(faction.clone()) - .chat_msg(format!("[{}] left faction ({})", alias, faction)), - ); - } + server + .state + .ecs() + .write_storage() + .remove(client) + .map(|comp::Faction(f)| f) + }; + if let Some(faction) = faction_leave { + server.state.send_chat( + ChatType::FactionMeta(faction.clone()) + .chat_msg(format!("[{}] left faction ({})", alias, faction)), + ); } } else { server.notify_client( @@ -1299,27 +1308,37 @@ fn handle_join_group( .get(target) .map(|player| player.alias.clone()) { - if let Ok(group) = scan_fmt!(&args, &action.arg_fmt(), String) { + let group_leave = if let Ok(group) = scan_fmt!(&args, &action.arg_fmt(), String) { let mode = comp::ChatMode::Group(group.clone()); let _ = server.state.ecs().write_storage().insert(client, mode); - let _ = server + let group_leave = server .state .ecs() .write_storage() - .insert(client, comp::Group(group.clone())); + .insert(client, comp::Group(group.clone())) + .ok() + .flatten() + .map(|f| f.0); server.state.send_chat( ChatType::GroupMeta(group.clone()) .chat_msg(format!("[{}] joined group ({})", alias, group)), ); + group_leave } else { let mode = comp::ChatMode::default(); let _ = server.state.ecs().write_storage().insert(client, mode); - if let Some(comp::Group(group)) = server.state.ecs().write_storage().remove(client) { - server.state.send_chat( - ChatType::GroupMeta(group.clone()) - .chat_msg(format!("[{}] left group ({})", alias, group)), - ); - } + server + .state + .ecs() + .write_storage() + .remove(client) + .map(|comp::Group(f)| f) + }; + if let Some(group) = group_leave { + server.state.send_chat( + ChatType::GroupMeta(group.clone()) + .chat_msg(format!("[{}] left group ({})", alias, group)), + ); } } else { server.notify_client( diff --git a/server/src/events/player.rs b/server/src/events/player.rs index 3c45b61366..32682c166b 100644 --- a/server/src/events/player.rs +++ b/server/src/events/player.rs @@ -64,7 +64,7 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event let mut accounts = state.ecs().write_resource::(); accounts.logout(player.uuid()); - let msg = comp::ChatType::Offline.server_msg(format!("{} went offline.", &player.alias)); + let msg = comp::ChatType::Offline.server_msg(format!("[{}] went offline.", &player.alias)); state.notify_registered_clients(msg); } diff --git a/voxygen/src/hud/overhead.rs b/voxygen/src/hud/overhead.rs index e4f09011da..58b4907973 100644 --- a/voxygen/src/hud/overhead.rs +++ b/voxygen/src/hud/overhead.rs @@ -14,11 +14,13 @@ use conrod_core::{ widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; +const MAX_BUBBLE_WIDTH: f64 = 250.0; + widget_ids! { struct Ids { // Speech bubble speech_bubble_text, - speech_bubble_text2, + speech_bubble_shadow, speech_bubble_top_left, speech_bubble_top, speech_bubble_top_right, @@ -105,10 +107,10 @@ impl<'a> Ingameable for Overhead<'a> { // - 1 for level: either Text or Image // - 4 for HP + mana + fg + bg // If there's a speech bubble - // - 1 Text::new for speech bubble + // - 2 Text::new for speech bubble // - 1 Image::new for icon // - 10 Image::new for speech bubble (9-slice + tail) - 7 + if self.bubble.is_some() { 12 } else { 0 } + 7 + if self.bubble.is_some() { 13 } else { 0 } } } @@ -153,8 +155,9 @@ impl<'a> Widget for Overhead<'a> { let localizer = |s: &str, i| -> String { self.voxygen_i18n.get_variation(&s, i).to_string() }; let bubble_contents: String = bubble.message(localizer); + let (text_color, shadow_color) = bubble_color(&bubble, dark_mode); let mut text = Text::new(&bubble_contents) - .color(bubble_color(&bubble, dark_mode)) + .color(text_color) .font_id(self.fonts.cyri.conrod_id) .font_size(18) .up_from(state.ids.name, 20.0) @@ -162,8 +165,8 @@ impl<'a> Widget for Overhead<'a> { .parent(id); if let Some(w) = text.get_w(ui) { - if w > 250.0 { - text = text.w(250.0); + if w > MAX_BUBBLE_WIDTH { + text = text.w(MAX_BUBBLE_WIDTH); } } Image::new(if dark_mode { @@ -251,18 +254,31 @@ impl<'a> Widget for Overhead<'a> { .bottom_right_with_margin_on(state.ids.speech_bubble_text, -20.0) .parent(id) .set(state.ids.speech_bubble_bottom_right, ui); - let tail = Image::new(if dark_mode { + Image::new(if dark_mode { self.imgs.dark_bubble_tail } else { self.imgs.speech_bubble_tail }) .w_h(22.0, 28.0) .mid_bottom_with_margin_on(state.ids.speech_bubble_text, -32.0) - .parent(id); + .parent(id) + .set(state.ids.speech_bubble_tail, ui); + let mut text_shadow = Text::new(&bubble_contents) + .color(shadow_color) + .font_id(self.fonts.cyri.conrod_id) + .font_size(18) + .x_relative_to(state.ids.speech_bubble_text, 1.0) + .y_relative_to(state.ids.speech_bubble_text, -1.0) + .parent(id); // Move text to front (conrod depth is lowest first; not a z-index) - tail.set(state.ids.speech_bubble_tail, ui); - text.depth(tail.get_depth() - 1.0) + text.depth(text_shadow.get_depth() - 1.0) .set(state.ids.speech_bubble_text, ui); + if let Some(w) = text_shadow.get_w(ui) { + if w > MAX_BUBBLE_WIDTH { + text_shadow = text_shadow.w(MAX_BUBBLE_WIDTH); + } + } + text_shadow.set(state.ids.speech_bubble_shadow, ui); Image::new(bubble_icon(&bubble, &self.imgs)) .w_h(16.0, 16.0) .top_left_with_margin_on(state.ids.speech_bubble_text, -16.0) @@ -367,8 +383,8 @@ impl<'a> Widget for Overhead<'a> { } } -fn bubble_color(bubble: &SpeechBubble, dark_mode: bool) -> Color { - match bubble.icon { +fn bubble_color(bubble: &SpeechBubble, dark_mode: bool) -> (Color, Color) { + let light_color = match bubble.icon { SpeechBubbleType::Tell => TELL_COLOR, SpeechBubbleType::Say => SAY_COLOR, SpeechBubbleType::Region => REGION_COLOR, @@ -377,13 +393,12 @@ fn bubble_color(bubble: &SpeechBubble, dark_mode: bool) -> Color { SpeechBubbleType::World | SpeechBubbleType::Quest | SpeechBubbleType::Trade - | SpeechBubbleType::None => { - if dark_mode { - TEXT_COLOR - } else { - TEXT_BG - } - }, + | SpeechBubbleType::None => TEXT_COLOR, + }; + if dark_mode { + (light_color, TEXT_BG) + } else { + (TEXT_BG, light_color) } }