From d665ce329dd83e0f29cb180fc708f60be2e6a2be Mon Sep 17 00:00:00 2001 From: Ben Wallis Date: Sat, 21 Aug 2021 10:23:26 +0100 Subject: [PATCH] * Added new Admin Commands window to egui, including Give Items and Kits sections * Added widgets.rs to egui for reusable widgets * Added filterable_list egui widget * Reworked DebugShapeAction to be a more generic EguiAction which now allows for ChatCommands (used by admin tools) as well as DebugShape drawing requests. * Fixed egui event handling so that typing/clicking within egui windows now correctly doesn't pass these events onto the game itself * Removed /give_item limit for stackable items --- common/src/cmd.rs | 6 +- server/src/cmd.rs | 11 ++- voxygen/egui/Cargo.toml | 5 +- voxygen/egui/src/admin.rs | 94 +++++++++++++++++++ voxygen/egui/src/character_states.rs | 2 +- voxygen/egui/src/lib.rs | 131 ++++++++++++++++++--------- voxygen/egui/src/widgets.rs | 34 +++++++ voxygen/src/run.rs | 8 +- voxygen/src/session/mod.rs | 2 +- voxygen/src/ui/egui/mod.rs | 50 +++++----- 10 files changed, 267 insertions(+), 76 deletions(-) create mode 100644 voxygen/egui/src/admin.rs create mode 100644 voxygen/egui/src/widgets.rs diff --git a/common/src/cmd.rs b/common/src/cmd.rs index 614d86bb72..69398bf91f 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -255,9 +255,11 @@ lazy_static! { }) }; - static ref KITS: Vec = { + pub static ref KITS: Vec = { if let Ok(kits) = KitManifest::load(KIT_MANIFEST_PATH) { - kits.read().0.keys().cloned().collect() + let mut kits = kits.read().0.keys().cloned().collect::>(); + kits.sort(); + kits } else { Vec::new() } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 3554d12ac9..a214a4baf5 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -472,7 +472,16 @@ fn handle_give_item( if let Ok(item) = Item::new_from_asset(&item_name.replace('/', ".").replace("\\", ".")) { let mut item: Item = item; let mut res = Ok(()); - if let Ok(()) = item.set_amount(give_amount.min(2000)) { + + const MAX_GIVE_AMOUNT: u32 = 2000; + // Cap give_amount for non-stackable items + let give_amount = if item.is_stackable() { + give_amount + } else { + give_amount.min(MAX_GIVE_AMOUNT) + }; + + if let Ok(()) = item.set_amount(give_amount) { server .state .ecs() diff --git a/voxygen/egui/Cargo.toml b/voxygen/egui/Cargo.toml index 6c59194d8c..29b246f246 100644 --- a/voxygen/egui/Cargo.toml +++ b/voxygen/egui/Cargo.toml @@ -5,7 +5,7 @@ edition = "2018" version = "0.9.0" [features] -use-dyn-lib = ["lazy_static", "voxygen-dynlib"] +use-dyn-lib = ["voxygen-dynlib"] be-dyn-lib = [] [dependencies] @@ -13,8 +13,7 @@ client = {package = "veloren-client", path = "../../client"} common = {package = "veloren-common", path = "../../common"} egui = "0.12" egui_winit_platform = "0.8" +lazy_static = "1.4.0" voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "../dynlib", optional = true} -# Hot Reloading -lazy_static = {version = "1.4.0", optional = true} diff --git a/voxygen/egui/src/admin.rs b/voxygen/egui/src/admin.rs new file mode 100644 index 0000000000..73b365321b --- /dev/null +++ b/voxygen/egui/src/admin.rs @@ -0,0 +1,94 @@ +use crate::{AdminCommandState, EguiAction, EguiActions, EguiWindows}; +use common::cmd::ChatCommand; +use egui::{CollapsingHeader, CtxRef, Resize, Slider, Ui, Vec2, Window}; +use lazy_static::lazy_static; + +lazy_static! { + static ref ITEM_SPECS: Vec = { + let mut item_specs = common::cmd::ITEM_SPECS + .iter() + .map(|item_desc| item_desc.replace("common.items.", "")) + .collect::>(); + item_specs.sort(); + item_specs + }; +} + +pub fn draw_admin_commands_window( + ctx: &CtxRef, + state: &mut AdminCommandState, + windows: &mut EguiWindows, + egui_actions: &mut EguiActions, +) { + Window::new("Admin Commands") + .open(&mut windows.admin_commands) + .default_width(400.0) + .default_height(600.0) + .show(ctx, |ui| { + ui.spacing_mut().item_spacing = Vec2::new(10.0, 10.0); + ui.vertical(|ui| { + CollapsingHeader::new("Give Items") + .default_open(true) + .show(ui, |ui| { + draw_give_items(ui, state, egui_actions); + }); + CollapsingHeader::new("Kits") + .default_open(false) + .show(ui, |ui| { + draw_kits(ui, state, egui_actions); + }); + }); + }); +} + +fn draw_kits(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mut EguiActions) { + ui.vertical(|ui| { + if ui.button("Give Kit").clicked() { + egui_actions.actions.push(EguiAction::ChatCommand { + cmd: ChatCommand::Kit, + args: vec![common::cmd::KITS[state.kits_selected_idx].clone()], + }); + }; + crate::widgets::filterable_list(ui, &common::cmd::KITS, "", &mut state.kits_selected_idx) + }); +} + +fn draw_give_items(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mut EguiActions) { + ui.spacing_mut().window_padding = Vec2::new(10.0, 10.0); + Resize::default() + .default_size([400.0, 200.0]) + .show(ui, |ui| { + ui.horizontal(|ui| { + ui.add( + Slider::new(&mut state.give_item_qty, 1..=100000) + .logarithmic(true) + .clamp_to_range(true) + .text("Qty"), + ); + if ui.button("Give Items").clicked() { + egui_actions.actions.push(EguiAction::ChatCommand { + cmd: ChatCommand::GiveItem, + args: vec![ + format!( + "common.items.{}", + ITEM_SPECS[state.give_item_selected_idx].clone() + ), + format!("{}", state.give_item_qty), + ], + }); + }; + }); + ui.horizontal(|ui| { + ui.label("Filter:"); + + ui.text_edit_singleline(&mut state.give_item_search_text); + }); + + crate::widgets::filterable_list( + ui, + &ITEM_SPECS, + &state.give_item_search_text, + &mut state.give_item_selected_idx, + ); + }); +} diff --git a/voxygen/egui/src/character_states.rs b/voxygen/egui/src/character_states.rs index 39a8660119..d27a8975cc 100644 --- a/voxygen/egui/src/character_states.rs +++ b/voxygen/egui/src/character_states.rs @@ -1,4 +1,4 @@ -use crate::{two_col_row, SelectedEntityInfo}; +use crate::{widgets::two_col_row, SelectedEntityInfo}; use common::{ comp::CharacterState, states::{charged_melee, combo_melee, dash_melee, leap_melee}, diff --git a/voxygen/egui/src/lib.rs b/voxygen/egui/src/lib.rs index 7acf8a3f0b..74636be28e 100644 --- a/voxygen/egui/src/lib.rs +++ b/voxygen/egui/src/lib.rs @@ -3,7 +3,9 @@ #[cfg(all(feature = "be-dyn-lib", feature = "use-dyn-lib"))] compile_error!("Can't use both \"be-dyn-lib\" and \"use-dyn-lib\" features at once"); +mod admin; mod character_states; +mod widgets; use client::{Client, Join, World, WorldExt}; use common::{ @@ -14,17 +16,17 @@ use core::mem; use egui::{ plot::{Plot, Value}, widgets::plot::Curve, - CollapsingHeader, Color32, Grid, Label, Pos2, ScrollArea, Slider, Ui, Window, + CollapsingHeader, Color32, Grid, Pos2, ScrollArea, Slider, Ui, Window, }; -fn two_col_row(ui: &mut Ui, label: impl Into