From b81981f8052a86396b116243e8755fb39cc7f207 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Mon, 3 May 2021 00:42:54 +0300 Subject: [PATCH] Draft implementation --- common/src/cmd.rs | 28 +++++++++++++++++++++ server/src/cmd.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/common/src/cmd.rs b/common/src/cmd.rs index 67bb0b4218..008bf3f89d 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -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 = 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 = 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", diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 48a663ca13..a032922132 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -15,8 +15,9 @@ 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 +98,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 +2608,62 @@ fn handle_server_physics( Err(action.help_string()) } } + +fn handle_apply_buff( + server: &mut Server, + _client: EcsEntity, + target: EcsEntity, + args: String, + action: &ChatCommand, +) -> CmdResult<()> { + 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 { + //TODO: implement Demon's Hangover + Ok(()) + } + } else { + Err(action.help_string()) + } +} + +fn cast_buff( + kind: &str, + data: BuffData, + server: &mut Server, + target: EcsEntity, +) -> Result<(), String> { + if let Some(buffkind) = parse_buffkind(kind) { + let ecs = &server.state.ecs(); + let mut buffs_all = ecs.write_storage::(); + 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 { + 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, + } +}