Merge branch 'vfoulon80/cmd-item-kits' into 'master'

New Command: "kit" + Removed Command: "debug"

See merge request veloren/veloren!2115
This commit is contained in:
Samuel Keiffer 2021-04-12 19:36:08 +00:00
commit c4f3522138
5 changed files with 117 additions and 35 deletions

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Stun resilience stat display
- Villagers and guards now spawn with potions, and know how to use them.
- Combat music in dungeons when within range of enemies.
- New Command: "kit", place a set of items into your inventory
### Changed
@ -51,6 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
- Removed command: "debug", use "/kit debug" instead
### Fixed
- Server kicks old client when a user is trying to log in again (often the case when a user's original connection gets dropped)

View File

@ -10,7 +10,7 @@ ItemDef(
),
)
),
quality: Artifact,
quality: Debug,
tags: [],
slots: 900,
)

View File

@ -0,0 +1,35 @@
({
"debug": [
("common.items.debug.admin_back",1),
("common.items.debug.admin_black_hole",1),
("common.items.debug.admin_stick",1),
("common.items.debug.admin_sword",1),
("common.items.debug.admin",1),
("common.items.debug.cultist_belt",1),
("common.items.debug.cultist_boots",1),
("common.items.debug.cultist_chest_blue",1),
("common.items.debug.cultist_hands_blue",1),
("common.items.debug.cultist_legs_blue",1),
("common.items.debug.cultist_shoulder_blue",1),
("common.items.debug.dungeon_purple",1),
],
"cultist": [
("common.items.armor.cultist.chest",1),
("common.items.armor.cultist.pants",1),
("common.items.armor.cultist.hand",1),
("common.items.armor.cultist.foot",1),
("common.items.armor.cultist.shoulder",1),
("common.items.armor.cultist.belt",1),
("common.items.weapons.hammer.cultist_purp_2h-0",1),
("common.items.weapons.staff.cultist_staff",1),
("common.items.weapons.sword.cultist",1),
("common.items.weapons.bow.velorite",1),
("common.items.weapons.axe.malachite_axe-0",1),
("common.items.weapons.sceptre.sceptre_velorite_0",1),
],
"potions": [
("common.items.consumable.potion_minor", 100),
("common.items.consumable.potion_med", 100),
("common.items.consumable.potion_big", 100),
]
})

View File

@ -1,6 +1,8 @@
use crate::{assets, comp, npc, terrain};
use assets::AssetExt;
use hashbrown::HashMap;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display},
path::Path,
@ -44,7 +46,6 @@ pub enum ChatCommand {
BuildAreaList,
BuildAreaRemove,
Campfire,
Debug,
DebugColumn,
DropAll,
Dummy,
@ -65,6 +66,7 @@ pub enum ChatCommand {
Kick,
Kill,
KillNpcs,
Kit,
Lantern,
Light,
MakeBlock,
@ -105,7 +107,6 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::BuildAreaList,
ChatCommand::BuildAreaRemove,
ChatCommand::Campfire,
ChatCommand::Debug,
ChatCommand::DebugColumn,
ChatCommand::DropAll,
ChatCommand::Dummy,
@ -126,6 +127,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::Kick,
ChatCommand::Kill,
ChatCommand::KillNpcs,
ChatCommand::Kit,
ChatCommand::Lantern,
ChatCommand::Light,
ChatCommand::MakeBlock,
@ -155,6 +157,14 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::World,
];
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct KitManifest(pub HashMap<String, Vec<(String, u32)>>);
impl assets::Asset for KitManifest {
type Loader = assets::RonLoader;
const EXTENSION: &'static str = "ron";
}
lazy_static! {
pub static ref CHAT_SHORTCUTS: HashMap<char, ChatCommand> = [
('f', ChatCommand::Faction),
@ -224,6 +234,14 @@ lazy_static! {
items.sort();
items
};
static ref KITS: Vec<String> = {
if let Ok(kits) = KitManifest::load("server.manifests.kits") {
kits.read().0.keys().cloned().collect()
} else {
Vec::new()
}
};
}
impl ChatCommand {
@ -270,7 +288,6 @@ impl ChatCommand {
Admin,
),
ChatCommand::Campfire => cmd(vec![], "Spawns a campfire", Admin),
ChatCommand::Debug => cmd(vec![], "Place all debug items into your pack.", Admin),
ChatCommand::DebugColumn => cmd(
vec![Integer("x", 15000, Required), Integer("y", 15000, Required)],
"Prints some debug information about a column",
@ -358,6 +375,11 @@ impl ChatCommand {
),
ChatCommand::Kill => cmd(vec![], "Kill yourself", NoAdmin),
ChatCommand::KillNpcs => cmd(vec![], "Kill the NPCs", Admin),
ChatCommand::Kit => cmd(
vec![Enum("kit_name", KITS.to_vec(), Required)],
"Place a set of items into your inventory.",
Admin,
),
ChatCommand::Lantern => cmd(
vec![
Float("strength", 5.0, Required),
@ -515,7 +537,6 @@ impl ChatCommand {
ChatCommand::BuildAreaList => "build_area_list",
ChatCommand::BuildAreaRemove => "build_area_remove",
ChatCommand::Campfire => "campfire",
ChatCommand::Debug => "debug",
ChatCommand::DebugColumn => "debug_column",
ChatCommand::DropAll => "dropall",
ChatCommand::Dummy => "dummy",
@ -535,6 +556,7 @@ impl ChatCommand {
ChatCommand::Jump => "jump",
ChatCommand::Kick => "kick",
ChatCommand::Kill => "kill",
ChatCommand::Kit => "kit",
ChatCommand::KillNpcs => "kill_npcs",
ChatCommand::Lantern => "lantern",
ChatCommand::Light => "light",

View File

@ -6,9 +6,11 @@ use crate::{
settings::{BanRecord, EditableSetting},
Server, SpawnPoint, StateExt,
};
use assets::AssetExt;
use authc::Uuid;
use chrono::{NaiveTime, Timelike};
use common::{
assets,
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
comp::{
self,
@ -37,6 +39,7 @@ use core::{convert::TryFrom, ops::Not, time::Duration};
use hashbrown::HashSet;
use rand::Rng;
use specs::{Builder, Entity as EcsEntity, Join, WorldExt};
use vek::*;
use world::util::Sampler;
@ -98,7 +101,6 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
ChatCommand::BuildAreaList => handle_build_area_list,
ChatCommand::BuildAreaRemove => handle_build_area_remove,
ChatCommand::Campfire => handle_spawn_campfire,
ChatCommand::Debug => handle_debug,
ChatCommand::DebugColumn => handle_debug_column,
ChatCommand::DropAll => handle_drop_all,
ChatCommand::Dummy => handle_spawn_training_dummy,
@ -119,6 +121,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
ChatCommand::Kick => handle_kick,
ChatCommand::Kill => handle_kill,
ChatCommand::KillNpcs => handle_kill_npcs,
ChatCommand::Kit => handle_kit,
ChatCommand::Lantern => handle_lantern,
ChatCommand::Light => handle_light,
ChatCommand::MakeBlock => handle_make_block,
@ -1397,9 +1400,57 @@ fn handle_kill_npcs(
client,
ServerGeneral::server_msg(ChatType::CommandInfo, text),
);
Ok(())
}
fn handle_kit(
server: &mut Server,
_client: EcsEntity,
target: EcsEntity,
args: String,
action: &ChatCommand,
) -> CmdResult<()> {
let kit_name = scan_fmt!(&args, &action.arg_fmt(), String);
if let Ok(name) = kit_name {
if let Ok(kits) = common::cmd::KitManifest::load("server.manifests.kits") {
let kits = kits.read();
if let Some(kit) = kits.0.get(&name) {
if let (Some(mut target_inventory), mut target_inv_update) = (
server
.state()
.ecs()
.write_storage::<comp::Inventory>()
.get_mut(target),
server.state.ecs().write_storage::<comp::InventoryUpdate>(),
) {
for (item_id, quantity) in kit.iter() {
if let Ok(mut item) = comp::Item::new_from_asset(item_id) {
let _ = item.set_amount(*quantity);
let (_, _) = (
target_inventory.push(item),
target_inv_update.insert(
target,
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
),
);
}
}
Ok(())
} else {
Err("Could not get inventory".to_string())
}
} else {
Err(format!("Kit '{}' not found", name))
}
} else {
Err("Could not load manifest file 'server.manifests.kits'".to_string())
}
} else {
Err(action.help_string())
}
}
#[allow(clippy::float_cmp)] // TODO: Pending review in #587
#[allow(clippy::needless_return)] // TODO: Pending review in #587
#[allow(clippy::useless_format)] // TODO: Pending review in #587
@ -2112,35 +2163,6 @@ fn parse_skill_tree(skill_tree: &str) -> CmdResult<comp::skills::SkillGroupKind>
}
}
fn handle_debug(
server: &mut Server,
_client: EcsEntity,
target: EcsEntity,
_args: String,
_action: &ChatCommand,
) -> CmdResult<()> {
if let Ok(items) = comp::Item::new_from_asset_glob("common.items.debug.*") {
server
.state()
.ecs()
.write_storage::<comp::Inventory>()
.get_mut(target)
.ok_or("Cannot get inventory for target")?
.push_all_unique(items.into_iter())
// Deliberately swallow the error if not enough debug items could be added--though it
// might be nice to let the admin know, it's better than dropping them on the ground.
.ok();
insert_or_replace_component(
server,
target,
comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Debug),
"target",
)
} else {
Err("Debug items not found? Something is very broken.".into())
}
}
fn handle_remove_lights(
server: &mut Server,
client: EcsEntity,