Merge branch 'coffee-compiler/add_clear_command' into 'master'

Add clear command

See merge request veloren/veloren!4542
This commit is contained in:
Imbris 2024-08-07 19:48:46 +00:00
commit 2365209c12
5 changed files with 82 additions and 41 deletions

View File

@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Unlockable recipes - Unlockable recipes
- Localization support for prompt dialogs, diary sections, trade and group invitations. - Localization support for prompt dialogs, diary sections, trade and group invitations.
- Added Freezing Potion - Added Freezing Potion
- Clear command to delete chat messages.
### Changed ### Changed
@ -41,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Broad entity and loot updates to Gnarling Fortifications - Broad entity and loot updates to Gnarling Fortifications
- Reworked spacing and labels in crafting menu. - Reworked spacing and labels in crafting menu.
- Reworked design of repair equipment interface in crafting menu. - Reworked design of repair equipment interface in crafting menu.
- Help command can be used on client commands too.
### Removed ### Removed

View File

@ -25,6 +25,7 @@ use strum::{EnumIter, IntoEnumIterator};
// Please keep this sorted alphabetically, same as with server commands :-) // Please keep this sorted alphabetically, same as with server commands :-)
#[derive(Clone, Copy, strum::EnumIter)] #[derive(Clone, Copy, strum::EnumIter)]
pub enum ClientChatCommand { pub enum ClientChatCommand {
Clear,
ExperimentalShader, ExperimentalShader,
Help, Help,
Mute, Mute,
@ -37,6 +38,11 @@ impl ClientChatCommand {
use Requirement::*; use Requirement::*;
let cmd = ChatCommandData::new; let cmd = ChatCommandData::new;
match self { match self {
ClientChatCommand::Clear => cmd(
Vec::new(),
"Clears all messages in chat. Affects all chat tabs.",
None,
),
ClientChatCommand::ExperimentalShader => cmd( ClientChatCommand::ExperimentalShader => cmd(
vec![Enum( vec![Enum(
"Shader", "Shader",
@ -68,6 +74,7 @@ impl ClientChatCommand {
pub fn keyword(&self) -> &'static str { pub fn keyword(&self) -> &'static str {
match self { match self {
ClientChatCommand::Clear => "clear",
ClientChatCommand::ExperimentalShader => "experimental_shader", ClientChatCommand::ExperimentalShader => "experimental_shader",
ClientChatCommand::Help => "help", ClientChatCommand::Help => "help",
ClientChatCommand::Mute => "mute", ClientChatCommand::Mute => "mute",
@ -301,16 +308,15 @@ pub fn run_command(
preproccess_command(session_state, &command, &mut args)?; preproccess_command(session_state, &command, &mut args)?;
let client = &mut session_state.client.borrow_mut();
match command { match command {
ChatCommandKind::Server(cmd) => { ChatCommandKind::Server(cmd) => {
client.send_command(cmd.keyword().into(), args); session_state
.client
.borrow_mut()
.send_command(cmd.keyword().into(), args);
Ok(None) // The server will provide a response when the command is run Ok(None) // The server will provide a response when the command is run
}, },
ChatCommandKind::Client(cmd) => { ChatCommandKind::Client(cmd) => run_client_command(session_state, global_state, cmd, args),
Ok(Some(run_client_command(client, global_state, cmd, args)?))
},
} }
} }
@ -344,29 +350,43 @@ fn invalid_command_message(client: &Client, user_entered_invalid_command: String
} }
fn run_client_command( fn run_client_command(
client: &mut Client, session_state: &mut SessionState,
global_state: &mut GlobalState, global_state: &mut GlobalState,
command: ClientChatCommand, command: ClientChatCommand,
args: Vec<String>, args: Vec<String>,
) -> Result<String, String> { ) -> CommandResult {
let command = match command { let command = match command {
ClientChatCommand::Clear => handle_clear,
ClientChatCommand::ExperimentalShader => handle_experimental_shader, ClientChatCommand::ExperimentalShader => handle_experimental_shader,
ClientChatCommand::Help => handle_help, ClientChatCommand::Help => handle_help,
ClientChatCommand::Mute => handle_mute, ClientChatCommand::Mute => handle_mute,
ClientChatCommand::Unmute => handle_unmute, ClientChatCommand::Unmute => handle_unmute,
}; };
command(client, global_state, args) command(session_state, global_state, args)
}
fn handle_clear(
session_state: &mut SessionState,
_global_state: &mut GlobalState,
_args: Vec<String>,
) -> CommandResult {
session_state.hud.clear_chat();
Ok(None)
} }
fn handle_help( fn handle_help(
client: &Client, session_state: &mut SessionState,
_global_state: &mut GlobalState, _global_state: &mut GlobalState,
args: Vec<String>, args: Vec<String>,
) -> Result<String, String> { ) -> CommandResult {
if let Some(cmd) = parse_cmd_args!(args, ServerChatCommand) { if let Some(cmd) = parse_cmd_args!(&args, ServerChatCommand) {
Ok(cmd.help_string()) Ok(Some(cmd.help_string()))
} else if let Some(cmd) = parse_cmd_args!(&args, ClientChatCommand) {
Ok(Some(cmd.help_string()))
} else { } else {
let client = &mut session_state.client.borrow_mut();
let mut message = String::new(); let mut message = String::new();
let entity_role = client let entity_role = client
.state() .state()
@ -392,16 +412,18 @@ fn handle_help(
.for_each(|(k, cmd)| { .for_each(|(k, cmd)| {
message += &format!(" /{} => /{}", k, cmd.keyword()); message += &format!(" /{} => /{}", k, cmd.keyword());
}); });
Ok(message) Ok(Some(message))
} }
} }
fn handle_mute( fn handle_mute(
client: &Client, session_state: &mut SessionState,
global_state: &mut GlobalState, global_state: &mut GlobalState,
args: Vec<String>, args: Vec<String>,
) -> Result<String, String> { ) -> CommandResult {
if let Some(alias) = parse_cmd_args!(args, String) { if let Some(alias) = parse_cmd_args!(args, String) {
let client = &mut session_state.client.borrow_mut();
let target = client let target = client
.player_list() .player_list()
.values() .values()
@ -420,7 +442,7 @@ fn handle_mute(
.insert(target.uuid, alias.clone()) .insert(target.uuid, alias.clone())
.is_none() .is_none()
{ {
Ok(format!("Successfully muted player {}.", alias)) Ok(Some(format!("Successfully muted player {}.", alias)))
} else { } else {
Err(format!("{} is already muted.", alias)) Err(format!("{} is already muted.", alias))
} }
@ -430,10 +452,10 @@ fn handle_mute(
} }
fn handle_unmute( fn handle_unmute(
client: &Client, session_state: &mut SessionState,
global_state: &mut GlobalState, global_state: &mut GlobalState,
args: Vec<String>, args: Vec<String>,
) -> Result<String, String> { ) -> CommandResult {
// Note that we don't care if this is a real player, so that it's possible // Note that we don't care if this is a real player, so that it's possible
// to unmute someone when they're offline // to unmute someone when they're offline
if let Some(alias) = parse_cmd_args!(args, String) { if let Some(alias) = parse_cmd_args!(args, String) {
@ -444,6 +466,8 @@ fn handle_unmute(
.find(|(_, v)| **v == alias) .find(|(_, v)| **v == alias)
.map(|(k, _)| *k) .map(|(k, _)| *k)
{ {
let client = &mut session_state.client.borrow_mut();
if let Some(me) = client.uid().and_then(|uid| client.player_list().get(&uid)) { if let Some(me) = client.uid().and_then(|uid| client.player_list().get(&uid)) {
if uuid == me.uuid { if uuid == me.uuid {
return Err("You cannot unmute yourself.".to_string()); return Err("You cannot unmute yourself.".to_string());
@ -451,7 +475,7 @@ fn handle_unmute(
} }
global_state.profile.mutelist.remove(&uuid); global_state.profile.mutelist.remove(&uuid);
Ok(format!("Successfully unmuted player {}.", alias)) Ok(Some(format!("Successfully unmuted player {}.", alias)))
} else { } else {
Err(format!("Could not find a muted player named {}.", alias)) Err(format!("Could not find a muted player named {}.", alias))
} }
@ -461,11 +485,12 @@ fn handle_unmute(
} }
fn handle_experimental_shader( fn handle_experimental_shader(
_client: &Client, _session_state: &mut SessionState,
global_state: &mut GlobalState, global_state: &mut GlobalState,
args: Vec<String>, args: Vec<String>,
) -> Result<String, String> { ) -> CommandResult {
if args.is_empty() { if args.is_empty() {
Ok(Some(
ExperimentalShader::iter() ExperimentalShader::iter()
.map(|s| { .map(|s| {
let is_active = global_state let is_active = global_state
@ -481,15 +506,16 @@ fn handle_experimental_shader(
a.push_str(&b); a.push_str(&b);
a a
}) })
.ok_or("There are no experimental shaders.".to_string()) .ok_or("There are no experimental shaders.".to_string())?,
))
} else if let Some(item) = parse_cmd_args!(args, String) { } else if let Some(item) = parse_cmd_args!(args, String) {
if let Ok(shader) = ExperimentalShader::from_str(&item) { if let Ok(shader) = ExperimentalShader::from_str(&item) {
let mut new_render_mode = global_state.settings.graphics.render_mode.clone(); let mut new_render_mode = global_state.settings.graphics.render_mode.clone();
let res = if new_render_mode.experimental_shaders.remove(&shader) { let res = if new_render_mode.experimental_shaders.remove(&shader) {
Ok(format!("Disabled {item}.")) Ok(Some(format!("Disabled {item}.")))
} else { } else {
new_render_mode.experimental_shaders.insert(shader); new_render_mode.experimental_shaders.insert(shader);
Ok(format!("Enabled {item}.")) Ok(Some(format!("Enabled {item}.")))
}; };
change_render_mode( change_render_mode(

View File

@ -87,6 +87,7 @@ pub struct Chat<'a> {
scale: Scale, scale: Scale,
localized_strings: &'a Localization, localized_strings: &'a Localization,
clear_messages: bool,
} }
impl<'a> Chat<'a> { impl<'a> Chat<'a> {
@ -99,6 +100,7 @@ impl<'a> Chat<'a> {
fonts: &'a Fonts, fonts: &'a Fonts,
localized_strings: &'a Localization, localized_strings: &'a Localization,
scale: Scale, scale: Scale,
clear_messages: bool,
) -> Self { ) -> Self {
Self { Self {
pulse, pulse,
@ -114,6 +116,7 @@ impl<'a> Chat<'a> {
history_max: 32, history_max: 32,
localized_strings, localized_strings,
scale, scale,
clear_messages,
} }
} }
@ -240,6 +243,10 @@ impl<'a> Widget for Chat<'a> {
let chat_pos = Vec2::new(chat_settings.chat_pos_x, chat_settings.chat_pos_y); let chat_pos = Vec2::new(chat_settings.chat_pos_x, chat_settings.chat_pos_y);
let chat_box_input_width = chat_size.x - CHAT_ICON_WIDTH - 12.0; let chat_box_input_width = chat_size.x - CHAT_ICON_WIDTH - 12.0;
if self.clear_messages {
state.update(|s| s.messages.clear());
}
// Empty old messages // Empty old messages
state.update(|s| { state.update(|s| {
while s.messages.len() > MAX_MESSAGES { while s.messages.len() > MAX_MESSAGES {

View File

@ -1298,6 +1298,7 @@ pub struct Hud {
voxel_minimap: VoxelMinimap, voxel_minimap: VoxelMinimap,
map_drag: Vec2<f64>, map_drag: Vec2<f64>,
force_chat: bool, force_chat: bool,
clear_chat: bool,
} }
impl Hud { impl Hud {
@ -1435,9 +1436,12 @@ impl Hud {
}, },
map_drag: Vec2::zero(), map_drag: Vec2::zero(),
force_chat: false, force_chat: false,
clear_chat: false,
} }
} }
pub fn clear_chat(&mut self) { self.clear_chat = true; }
pub fn set_prompt_dialog(&mut self, prompt_dialog: PromptDialogSettings) { pub fn set_prompt_dialog(&mut self, prompt_dialog: PromptDialogSettings) {
self.show.prompt_dialog = Some(prompt_dialog); self.show.prompt_dialog = Some(prompt_dialog);
} }
@ -3524,6 +3528,7 @@ impl Hud {
&self.fonts, &self.fonts,
i18n, i18n,
scale, scale,
self.clear_chat,
) )
.and_then(self.force_chat_input.take(), |c, input| c.input(input)) .and_then(self.force_chat_input.take(), |c, input| c.input(input))
.and_then(self.tab_complete.take(), |c, input| { .and_then(self.tab_complete.take(), |c, input| {
@ -3575,6 +3580,7 @@ impl Hud {
self.new_messages.clear(); self.new_messages.clear();
self.new_notifications.clear(); self.new_notifications.clear();
self.clear_chat = false;
// Windows // Windows

View File

@ -102,7 +102,7 @@ pub struct SessionState {
scene: Scene, scene: Scene,
pub(crate) client: Rc<RefCell<Client>>, pub(crate) client: Rc<RefCell<Client>>,
metadata: UpdateCharacterMetadata, metadata: UpdateCharacterMetadata,
hud: Hud, pub(crate) hud: Hud,
key_state: KeyState, key_state: KeyState,
inputs: comp::ControllerInputs, inputs: comp::ControllerInputs,
inputs_state: HashSet<GameInput>, inputs_state: HashSet<GameInput>,