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
- Localization support for prompt dialogs, diary sections, trade and group invitations.
- Added Freezing Potion
- Clear command to delete chat messages.
### 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
- Reworked spacing and labels in crafting menu.
- Reworked design of repair equipment interface in crafting menu.
- Help command can be used on client commands too.
### Removed

View File

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

View File

@ -87,6 +87,7 @@ pub struct Chat<'a> {
scale: Scale,
localized_strings: &'a Localization,
clear_messages: bool,
}
impl<'a> Chat<'a> {
@ -99,6 +100,7 @@ impl<'a> Chat<'a> {
fonts: &'a Fonts,
localized_strings: &'a Localization,
scale: Scale,
clear_messages: bool,
) -> Self {
Self {
pulse,
@ -114,6 +116,7 @@ impl<'a> Chat<'a> {
history_max: 32,
localized_strings,
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_box_input_width = chat_size.x - CHAT_ICON_WIDTH - 12.0;
if self.clear_messages {
state.update(|s| s.messages.clear());
}
// Empty old messages
state.update(|s| {
while s.messages.len() > MAX_MESSAGES {

View File

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

View File

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