From 36887203d330ce5f36e8588a162b18c5b387b5b8 Mon Sep 17 00:00:00 2001 From: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 14 Nov 2022 16:38:05 -0500 Subject: [PATCH] [Commands] Cleanup #doanim Command. (#2540) * [Commands] Cleanup #doanim Command. - Cleanup messages and logic. - Allow you to use animation names or IDs, could possibly extend this to quest API in the future. * Update dialogue_window.h --- zone/command.cpp | 2 +- zone/dialogue_window.h | 69 +++++++++++++++++++++++++- zone/gm_commands/doanim.cpp | 96 +++++++++++++++++++++++++++++++++---- zone/mob.cpp | 16 ++----- zone/mob.h | 2 +- 5 files changed, 161 insertions(+), 24 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index af2be316c..6cdb116e3 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -127,7 +127,7 @@ int command_init(void) command_add("disarmtrap", "Analog for ldon disarm trap for the newer clients since we still don't have it working.", AccountStatus::QuestTroupe, command_disarmtrap) || command_add("distance", "Reports the distance between you and your target.", AccountStatus::QuestTroupe, command_distance) || command_add("door", "Door editing command", AccountStatus::QuestTroupe, command_door) || - command_add("doanim", "[animnum] [type] - Send an EmoteAnim for you or your target", AccountStatus::Guide, command_doanim) || + command_add("doanim", "[Animation ID|Animation Name] [Speed] - Send an animation by ID or name at the specified speed to you or your target (Speed is optional)", AccountStatus::Guide, command_doanim) || command_add("dye", "[slot|'help'] [red] [green] [blue] [use_tint] - Dyes the specified armor slot to Red, Green, and Blue provided, allows you to bypass darkness limits.", AccountStatus::ApprenticeGuide, command_dye) || command_add("dz", "Manage expeditions and dynamic zone instances", AccountStatus::QuestTroupe, command_dz) || command_add("dzkickplayers", "Removes all players from current expedition. (/kickplayers alternative for pre-RoF clients)", AccountStatus::Player, command_dzkickplayers) || diff --git a/zone/dialogue_window.h b/zone/dialogue_window.h index 177bfb58f..5787b818f 100644 --- a/zone/dialogue_window.h +++ b/zone/dialogue_window.h @@ -381,9 +381,74 @@ const std::map animations = { {"salute", 67}, {"shiver", 68}, {"tapfoot", 69}, - {"bowto", 70}, - }; + {"bowto", 70} +}; +const std::map animation_names_map = { + { 1, "Kick" }, + { 2, "1H Piercing" }, + { 3, "2H Slashing" }, + { 4, "2H Blunt" }, + { 4, "2H Piercing" }, + { 5, "Throw" }, + { 6, "Off Hand" }, + { 7, "Bash" }, + { 8, "Main Hand" }, + { 9, "Bow" }, + { 10, "Swim" }, + { 11, "Round Kick" }, + { 12, "Get Hit" }, + { 13, "Get Hit" }, + { 14, "Falling" }, + { 15, "Drowning" }, + { 16, "Death" }, + { 17, "Stand By" }, + { 18, "Stand By" }, + { 19, "Lunge" }, + { 20, "Jump" }, + { 21, "Falling" }, + { 22, "Crouched Walk" }, + { 23, "Ladder Climb" }, + { 24, "Crouch" }, + { 25, "Swim" }, + { 26, "Idle" }, + { 27, "Cheer" }, + { 28, "Disgusted" }, + { 29, "Wave" }, + { 30, "Rude" }, + { 31, "Yawn" }, + { 33, "Move To Side" }, + { 35, "Ice Slide" }, + { 36, "Kneel" }, + { 37, "Swim" }, + { 38, "Sit" }, + { 42, "Cast" }, + { 43, "Cast" }, + { 44, "Cast" }, + { 45, "Flying Kick" }, + { 46, "Tiger Claw" }, + { 47, "Eagle Strike" }, + { 48, "Nod Yes" }, + { 49, "Shake No" }, + { 50, "Plead" }, + { 51, "Clap" }, + { 52, "Blush" }, + { 54, "Chuckle" }, + { 57, "Head Tilt" }, + { 58, "Dance" }, + { 59, "Disagree" }, + { 60, "Glare" }, + { 61, "Peer" }, + { 62, "Kneel" }, + { 63, "Laugh" }, + { 64, "Point" }, + { 65, "Shrug" }, + { 66, "Hand Raise" }, + { 67, "Salute" }, + { 68, "Shiver" }, + { 69, "Tap Foot" }, + { 70, "Bow To" } +}; class DialogueWindow { public: diff --git a/zone/gm_commands/doanim.cpp b/zone/gm_commands/doanim.cpp index d48725a97..ec57650ff 100755 --- a/zone/gm_commands/doanim.cpp +++ b/zone/gm_commands/doanim.cpp @@ -1,20 +1,98 @@ #include "../client.h" +#include "../dialogue_window.h" void command_doanim(Client *c, const Seperator *sep) { - if (!sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #DoAnim [number]"); + auto arguments = sep->argnum; + if (!arguments) { + c->Message(Chat::White, "Usage: #doanim [Name|Number] [Speed]"); + return; } - else if (c->Admin() >= commandDoAnimOthers) { - if (c->GetTarget() == 0) { - c->Message(Chat::White, "Error: You need a target."); + + Mob* t = c; + if (c->GetTarget() && c->Admin() >= commandDoAnimOthers) { + t = c->GetTarget(); + } + + int animation_id = -1; + std::string animation_name; + auto animation_speed = 0; + + if (sep->IsNumber(1)) { + animation_id = std::stoi(sep->arg[1]); + + const auto& a = animation_names_map.find(animation_id); + if (a != animation_names_map.end()) { + animation_name = a->second; } - else { - c->GetTarget()->DoAnim(atoi(sep->arg[1]), atoi(sep->arg[2])); + + if (animation_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Animation ID {} does not exist or is invalid.", + animation_id + ).c_str() + ); + return; + } + } else { + const std::string search_criteria = sep->arg[1]; + + const auto& a = animations.find(Strings::ToLower(search_criteria)); + if (a != animations.end()) { + animation_id = a->second; + const auto& b = animation_names_map.find(animation_id); + if (b != animation_names_map.end()) { + animation_name = b->second; + } + } else { + for (const auto& b : animation_names_map) { + if (Strings::ToLower(b.second).find(Strings::ToLower(search_criteria)) != std::string::npos) { + animation_id = b.first; + animation_name = b.second; + break; + } + } + + if (animation_id == -1) { + c->Message( + Chat::White, + fmt::format( + "No Animation could be found matching '{}'.", + search_criteria + ).c_str() + ); + return; + } } } - else { - c->DoAnim(atoi(sep->arg[1]), atoi(sep->arg[2])); + + if (sep->IsNumber(2)) { + animation_speed = std::stoi(sep->arg[2]); } + + const auto speed_message = ( + animation_speed ? + fmt::format( + " at speed {}", + animation_speed + ) : + "" + ); + + c->Message( + Chat::White, + fmt::format( + "{} {} now performing the {} ({}) animation{}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "are" : "is", + animation_name, + animation_id, + speed_message + ).c_str() + ); + + t->DoAnim(animation_id, animation_speed); } diff --git a/zone/mob.cpp b/zone/mob.cpp index fd003e760..f65f2af18 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2320,24 +2320,18 @@ void Mob::ShowStats(Client* client) } } -void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter) +void Mob::DoAnim(const int animation_id, int animation_speed, bool ackreq, eqFilterType filter) { if (!attack_anim_timer.Check()) { return; } auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); - auto *anim = (Animation_Struct *) outapp->pBuffer; - anim->spawnid = GetID(); + auto *a = (Animation_Struct *) outapp->pBuffer; - if (type == 0) { - anim->action = animnum; - anim->speed = 10; - } - else { - anim->action = animnum; - anim->speed = type; - } + a->spawnid = GetID(); + a->action = animation_id; + a->speed = animation_speed ? animation_speed : 10; entity_list.QueueCloseClients( this, /* Sender */ diff --git a/zone/mob.h b/zone/mob.h index e92fa4936..9c68653d4 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -299,7 +299,7 @@ public: virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 hero_forge_model = 0); void ChangeSize(float in_size, bool bNoRestriction = false); - void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone); + void DoAnim(const int animation_id, int animation_speed = 0, bool ackreq = true, eqFilterType filter = FilterNone); void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0, float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, EQ::skills::SkillType skillInUse = EQ::skills::SkillArchery); void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Client *specific_target=nullptr, uint32 value1slot = 1, uint32 value1ground = 1, uint32 value2slot = 1, uint32 value2ground = 1, uint32 value3slot = 1, uint32 value3ground = 1, uint32 value4slot = 1, uint32 value4ground = 1, uint32 value5slot = 1, uint32 value5ground = 1);