Merge branch 'juliancoffee/cast_buff_cmd' into 'master'

Adding command for applying buff on player

See merge request veloren/veloren!2240
This commit is contained in:
Samuel Keiffer 2021-05-03 19:53:19 +00:00
commit 622d7c5033
3 changed files with 103 additions and 1 deletions

View File

@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fundamentals/prototype for wiring system
- Mountain peak and lake markers on the map
- There's now a checkbox in the graphics tab to opt-in to receiving lossily-compressed terrain colors.
- /buff command which allows you to cast a buff on player
### Changed

View File

@ -40,6 +40,7 @@ pub enum ChatCommand {
Adminify,
Airship,
Alias,
ApplyBuff,
Ban,
Build,
BuildAreaAdd,
@ -104,6 +105,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::Adminify,
ChatCommand::Airship,
ChatCommand::Alias,
ChatCommand::ApplyBuff,
ChatCommand::Ban,
ChatCommand::Build,
ChatCommand::BuildAreaAdd,
@ -208,6 +210,22 @@ lazy_static! {
.map(|s| s.to_string())
.collect();
static ref BUFFS: Vec<String> = vec![
// Debuffs
"burning", "bleeding", "curse",
// Heal
"regeneration", "saturation", "potion", "campfire_heal",
// Outmaxing stats
"increase_max_energy", "increase_max_health",
// Defensive buffs
"invulnerability", "protecting_ward",
// One command to rule them all
"all",
]
.iter()
.map(|b| b.to_string())
.collect();
static ref BLOCK_KINDS: Vec<String> = terrain::block::BLOCK_KINDS
.keys()
.cloned()
@ -268,6 +286,15 @@ impl ChatCommand {
Admin,
),
ChatCommand::Alias => cmd(vec![Any("name", Required)], "Change your alias", NoAdmin),
ChatCommand::ApplyBuff => cmd(
vec![
Enum("buff", BUFFS.clone(), Required),
Float("strength", 0.01, Optional),
Float("duration", 10.0, Optional),
],
"Cast a buff on player",
Admin,
),
ChatCommand::Ban => cmd(
vec![Any("username", Required), Message(Optional)],
"Ban a player with a given username",
@ -551,6 +578,7 @@ impl ChatCommand {
ChatCommand::Adminify => "adminify",
ChatCommand::Airship => "airship",
ChatCommand::Alias => "alias",
ChatCommand::ApplyBuff => "buff",
ChatCommand::Ban => "ban",
ChatCommand::Build => "build",
ChatCommand::BuildAreaAdd => "build_area_add",

View File

@ -15,7 +15,7 @@ use common::{
comp::{
self,
aura::{Aura, AuraKind, AuraTarget},
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
buff::{Buff, BuffCategory, BuffData, BuffKind, BuffSource},
inventory::item::{tool::AbilityMap, MaterialStatManifest},
invite::InviteKind,
ChatType, Inventory, Item, LightEmitter, WaypointArea,
@ -97,6 +97,7 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
ChatCommand::Adminify => handle_adminify,
ChatCommand::Airship => handle_spawn_airship,
ChatCommand::Alias => handle_alias,
ChatCommand::ApplyBuff => handle_apply_buff,
ChatCommand::Ban => handle_ban,
ChatCommand::Build => handle_build,
ChatCommand::BuildAreaAdd => handle_build_area_add,
@ -2606,3 +2607,75 @@ fn handle_server_physics(
Err(action.help_string())
}
}
fn handle_apply_buff(
server: &mut Server,
_client: EcsEntity,
target: EcsEntity,
args: String,
action: &ChatCommand,
) -> CmdResult<()> {
const BUFF_PACK: &[&str] = &[
// Debuffs
"burning",
"bleeding",
"curse",
// Healing
"regeneration",
"saturation",
"potion",
"campfire_heal",
// Outmaxing stats
"increase_max_energy",
"increase_max_health",
// Defensive buffs (invulnerability is skipped because it ruins all debuffs)
"protecting_ward",
];
if let (Some(buff), strength, duration) =
scan_fmt_some!(&args, &action.arg_fmt(), String, f32, f64)
{
let strength = strength.unwrap_or(0.01);
let duration = Duration::from_secs_f64(duration.unwrap_or(1.0));
let buffdata = BuffData::new(strength, Some(duration));
if buff != "all" {
cast_buff(&buff, buffdata, server, target)
} else {
for kind in BUFF_PACK {
cast_buff(kind, buffdata, server, target)?;
}
Ok(())
}
} else {
Err(action.help_string())
}
}
fn cast_buff(kind: &str, data: BuffData, server: &mut Server, target: EcsEntity) -> CmdResult<()> {
if let Some(buffkind) = parse_buffkind(kind) {
let ecs = &server.state.ecs();
let mut buffs_all = ecs.write_storage::<comp::Buffs>();
if let Some(mut buffs) = buffs_all.get_mut(target) {
buffs.insert(Buff::new(buffkind, data, vec![], BuffSource::Command));
}
Ok(())
} else {
Err(format!("unknown buff: {}", kind))
}
}
fn parse_buffkind(buff: &str) -> Option<BuffKind> {
match buff {
"burning" => Some(BuffKind::Burning),
"regeneration" => Some(BuffKind::Regeneration),
"saturation" => Some(BuffKind::Saturation),
"bleeding" => Some(BuffKind::Bleeding),
"curse" => Some(BuffKind::Cursed),
"potion" => Some(BuffKind::Potion),
"campfire_heal" => Some(BuffKind::CampfireHeal),
"increase_max_energy" => Some(BuffKind::IncreaseMaxEnergy),
"increase_max_health" => Some(BuffKind::IncreaseMaxHealth),
"invulnerability" => Some(BuffKind::Invulnerability),
"protecting_ward" => Some(BuffKind::ProtectingWard),
_ => None,
}
}