mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-05 19:32:25 +00:00
- License was intended to be GPLv3 per earlier commit of GPLv3 LICENSE FILE - This is confirmed by the inclusion of libraries that are incompatible with GPLv2 - This is also confirmed by KLS and the agreement of KLS's predecessors - Added GPLv3 license headers to the compilable source files - Removed Folly licensing in strings.h since the string functions do not match the Folly functions and are standard functions - this must have been left over from previous implementations - Removed individual contributor license headers since the project has been under the "developer" mantle for many years - Removed comments on files that were previously automatically generated since they've been manually modified multiple times and there are no automatic scripts referencing them (removed in 2023)
1858 lines
63 KiB
C++
Executable File
1858 lines
63 KiB
C++
Executable File
/* EQEmu: EQEmulator
|
|
|
|
Copyright (C) 2001-2026 EQEmu Development Team
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "common/repositories/npc_types_repository.h"
|
|
#include "zone/client.h"
|
|
#include "zone/groups.h"
|
|
#include "zone/raids.h"
|
|
|
|
void SendNPCEditSubCommands(Client *c)
|
|
{
|
|
c->Message(Chat::White, "Usage: #npcedit name [Name] - Sets an NPC's Name");
|
|
c->Message(Chat::White, "Usage: #npcedit lastname [Last Name] - Sets an NPC's Last Name");
|
|
c->Message(Chat::White, "Usage: #npcedit level [Level] - Sets an NPC's Level");
|
|
c->Message(Chat::White, "Usage: #npcedit race [Race ID] - Sets an NPC's Race");
|
|
c->Message(Chat::White, "Usage: #npcedit class [Class ID] - Sets an NPC's Class");
|
|
c->Message(Chat::White, "Usage: #npcedit bodytype [Body Type ID] - Sets an NPC's Bodytype");
|
|
c->Message(Chat::White, "Usage: #npcedit hp [HP] - Sets an NPC's HP");
|
|
c->Message(Chat::White, "Usage: #npcedit mana [Mana] - Sets an NPC's Mana");
|
|
c->Message(Chat::White, "Usage: #npcedit gender [Gender ID] - Sets an NPC's Gender");
|
|
c->Message(Chat::White, "Usage: #npcedit texture [Texture] - Sets an NPC's Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit helmtexture [Helmet Texture] - Sets an NPC's Helmet Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit herosforgemodel [Model Number] - Sets an NPC's Hero's Forge Model");
|
|
c->Message(Chat::White, "Usage: #npcedit size [Size] - Sets an NPC's Size");
|
|
c->Message(Chat::White, "Usage: #npcedit hpregen [HP Regen] - Sets an NPC's HP Regen Rate Per Tick");
|
|
c->Message(Chat::White, "Usage: #npcedit hp_regen_per_second [HP Regen] - Sets an NPC's HP Regen Rate Per Second");
|
|
c->Message(Chat::White, "Usage: #npcedit manaregen [Mana Regen] - Sets an NPC's Mana Regen Rate Per Tick");
|
|
c->Message(Chat::White, "Usage: #npcedit loottable [Loottable ID] - Sets an NPC's Loottable ID");
|
|
c->Message(Chat::White, "Usage: #npcedit merchantid [Merchant ID] - Sets an NPC's Merchant ID");
|
|
c->Message(Chat::White, "Usage: #npcedit alt_currency_id [Alternate Currency ID] - Sets an NPC's Alternate Currency ID");
|
|
c->Message(Chat::White, "Usage: #npcedit spell [Spell List ID] - Sets an NPC's Spells List ID");
|
|
c->Message(Chat::White, "Usage: #npcedit npc_spells_effects_id [Spell Effects ID] - Sets an NPC's Spell Effects ID");
|
|
c->Message(Chat::White, "Usage: #npcedit faction [Faction ID] - Sets an NPC's Faction ID");
|
|
c->Message(Chat::White, "Usage: #npcedit adventure_template_id [Template ID] - Sets an NPC's Adventure Template ID");
|
|
c->Message(Chat::White, "Usage: #npcedit trap_template [Template ID] - Sets an NPC's Trap Template ID");
|
|
c->Message(Chat::White, "Usage: #npcedit damage [Minimum] [Maximum] - Sets an NPC's Damage");
|
|
c->Message(Chat::White, "Usage: #npcedit attackcount [Attack Count] - Sets an NPC's Attack Count");
|
|
c->Message(Chat::White, "Usage: #npcedit special_attacks [Special Attacks] - Sets an NPC's Special Attacks");
|
|
c->Message(Chat::White, "Usage: #npcedit special_abilities [Special Abilities] - Sets an NPC's Special Abilities");
|
|
c->Message(Chat::White, "Usage: #npcedit aggroradius [Radius] - Sets an NPC's Aggro Radius");
|
|
c->Message(Chat::White, "Usage: #npcedit assistradius [Radius] - Sets an NPC's Assist Radius");
|
|
c->Message(Chat::White, "Usage: #npcedit featuresave - Saves an NPC's current facial features to the database");
|
|
c->Message(Chat::White, "Usage: #npcedit armortint_id [Armor Tint ID] - Sets an NPC's Armor Tint ID");
|
|
c->Message(Chat::White, "Usage: #npcedit color [Red] [Green] [Blue] - Sets an NPC's Red, Green, and Blue armor tint");
|
|
c->Message(Chat::White, "Usage: #npcedit ammoidfile [ID File] - Sets an NPC's Ammo ID File");
|
|
c->Message(Chat::White, "Usage: #npcedit weapon [Primary Model] [Secondary Model] - Sets an NPC's Primary and Secondary Weapon Model");
|
|
c->Message(Chat::White, "Usage: #npcedit meleetype [Primary Type] [Secondary Type] - Sets an NPC's Melee Skill Types");
|
|
c->Message(Chat::White, "Usage: #npcedit rangedtype [Type] - Sets an NPC's Ranged Skill Type");
|
|
c->Message(Chat::White, "Usage: #npcedit runspeed [Run Speed] - Sets an NPC's Run Speed");
|
|
c->Message(Chat::White, "Usage: #npcedit mr [Resistance] - Sets an NPC's Magic Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit pr [Resistance] - Sets an NPC's Poison Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit dr [Resistance] - Sets an NPC's Disease Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit fr [Resistance] - Sets an NPC's Fire Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit cr [Resistance] - Sets an NPC's Cold Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit corrup [Resistance] - Sets an NPC's Corruption Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit phr [Resistance] - Sets and NPC's Physical Resistance");
|
|
c->Message(Chat::White, "Usage: #npcedit seeinvis [Flag] - Sets an NPC's See Invisible Flag [0 = Cannot See Invisible, 1 = Can See Invisible]");
|
|
c->Message(Chat::White, "Usage: #npcedit seeinvisundead [Flag] - Sets an NPC's See Invisible vs. Undead Flag [0 = Cannot See Invisible vs. Undead, 1 = Can See Invisible vs. Undead]");
|
|
c->Message(Chat::White, "Usage: #npcedit qglobal [Flag] - Sets an NPC's Quest Global Flag [0 = Quest Globals Off, 1 = Quest Globals On]");
|
|
c->Message(Chat::White, "Usage: #npcedit ac [Armor Class] - Sets an NPC's Armor Class");
|
|
c->Message(Chat::White, "Usage: #npcedit npcaggro [Flag] - Sets an NPC's NPC Aggro Flag [0 = Aggro NPCs Off, 1 = Aggro NPCs On]");
|
|
c->Message(Chat::White, "Usage: #npcedit spawn_limit [Limit] - Sets an NPC's Spawn Limit Counter");
|
|
c->Message(Chat::White, "Usage: #npcedit attackspeed [Attack Speed] - Sets an NPC's Attack Speed Modifier");
|
|
c->Message(Chat::White, "Usage: #npcedit attackdelay [Attack Delay] - Sets an NPC's Attack Delay");
|
|
c->Message(Chat::White, "Usage: #npcedit findable [Flag] - Sets an NPC's Findable Flag [0 = Not Findable, 1 = Findable]");
|
|
c->Message(Chat::White, "Usage: #npcedit str [Strength] - Sets an NPC's Strength");
|
|
c->Message(Chat::White, "Usage: #npcedit sta [Stamina] - Sets an NPC's Stamina");
|
|
c->Message(Chat::White, "Usage: #npcedit agi [Agility] - Sets an NPC's Agility");
|
|
c->Message(Chat::White, "Usage: #npcedit dex [Dexterity] - Sets an NPC's Dexterity");
|
|
c->Message(Chat::White, "Usage: #npcedit int [Intelligence] - Sets an NPC's Intelligence");
|
|
c->Message(Chat::White, "Usage: #npcedit wis [Wisdom] - Sets an NPC's Wisdom");
|
|
c->Message(Chat::White, "Usage: #npcedit cha [Charisma] - Sets an NPC's Charisma");
|
|
c->Message(Chat::White, "Usage: #npcedit seehide [Flag] - Sets an NPC's See Hide Flag [0 = Cannot See Hide, 1 = Can See Hide]");
|
|
c->Message(Chat::White, "Usage: #npcedit seeimprovedhide [Flag] - Sets an NPC's See Improved Hide Flag [0 = Cannot See Improved Hide, 1 = Can See Improved Hide]");
|
|
c->Message(Chat::White, "Usage: #npcedit trackable [Flag] - Sets an NPC's Trackable Flag [0 = Not Trackable, 1 = Trackable]");
|
|
c->Message(Chat::White, "Usage: #npcedit atk [Attack] - Sets an NPC's Attack");
|
|
c->Message(Chat::White, "Usage: #npcedit accuracy [Accuracy] - Sets an NPC's Accuracy");
|
|
c->Message(Chat::White, "Usage: #npcedit avoidance [Avoidance] - Sets an NPC's Avoidance");
|
|
c->Message(Chat::White, "Usage: #npcedit slow_mitigation [Slow Mitigation] - Sets an NPC's Slow Mitigation");
|
|
c->Message(Chat::White, "Usage: #npcedit version [Version] - Sets an NPC's Version");
|
|
c->Message(Chat::White, "Usage: #npcedit maxlevel [Max Level] - Sets an NPC's Maximum Level");
|
|
c->Message(Chat::White, "Usage: #npcedit scalerate [Scale Rate] - Sets an NPC's Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]");
|
|
c->Message(Chat::White, "Usage: #npcedit emoteid [Emote ID] - Sets an NPC's Emote ID");
|
|
c->Message(Chat::White, "Usage: #npcedit spellscale [Scale Rate] - Sets an NPC's Spell Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]");
|
|
c->Message(Chat::White, "Usage: #npcedit healscale [Scale Rate] - Sets an NPC's Heal Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]");
|
|
c->Message(Chat::White, "Usage: #npcedit no_target [Flag] - Sets an NPC's No Target Hotkey Flag [0 = Not Targetable with Target Hotkey, 1 = Targetable with Target Hotkey]");
|
|
c->Message(Chat::White, "Usage: #npcedit raidtarget [Flag] - Sets an NPC's Raid Target Flag [0 = Not a Raid Target, 1 = Raid Target]");
|
|
c->Message(Chat::White, "Usage: #npcedit armtexture [Texture] - Sets an NPC's Arm Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit bracertexture [Texture] - Sets an NPC's Bracer Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit handtexture [Texture] - Sets an NPC's Hand Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit legtexture [Texture] - Sets an NPC's Leg Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit feettexture [Texture] - Sets an NPC's Feet Texture");
|
|
c->Message(Chat::White, "Usage: #npcedit walkspeed [Walk Speed] - Sets an NPC's Walk Speed");
|
|
c->Message(Chat::White, "Usage: #npcedit show_name [Flag] - Sets an NPC's Show Name Flag [0 = Hidden, 1 = Shown]");
|
|
c->Message(Chat::White, "Usage: #npcedit untargetable [Flag] - Sets an NPC's Untargetable Flag [0 = Targetable, 1 = Untargetable]");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_ac [Armor Class] - Sets an NPC's Armor Class while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_min_dmg [Damage] - Sets an NPC's Minimum Damage while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_max_dmg [Damage] - Sets an NPC's Maximum Damage while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_attack_delay [Attack Delay] - Sets an NPC's Attack Delay while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_accuracy_rating [Accuracy] - Sets an NPC's Accuracy Rating while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_avoidance_rating [Avoidance] - Sets an NPC's Avoidance Rating while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit charm_atk [Attack] - Sets an NPC's Attack while Charmed");
|
|
c->Message(Chat::White, "Usage: #npcedit skip_global_loot [Flag] - Sets an NPC's Skip Global Loot Flag [0 = Don't Skip, 1 = Skip");
|
|
c->Message(Chat::White, "Usage: #npcedit rarespawn [Flag] - Sets an NPC's Rare Spawn Flag [0 = Not a Rare Spawn, 1 = Rare Spawn]");
|
|
c->Message(Chat::White, "Usage: #npcedit stuck_behavior [Stuck Behavior] - Sets an NPC's Stuck Behavior [0 = Run to Target, 1 = Warp to Target, 2 = Take No Action, 3 = Evade Combat]");
|
|
c->Message(Chat::White, "Usage: #npcedit model [Race ID] - Sets an NPC's Race Model");
|
|
c->Message(Chat::White, "Usage: #npcedit flymode [Fly Mode] - Sets an NPC's Fly Mode [0 = Ground, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating While Running]");
|
|
c->Message(Chat::White, "Usage: #npcedit always_aggro [Flag] - Sets an NPC's Always Aggro Flag [0 = Does not Always Aggro, 1 = Always Aggro]");
|
|
c->Message(Chat::White, "Usage: #npcedit exp_mod [Modifier] - Sets an NPC's Experience Modifier [50 = 50%, 100 = 100%, 200 = 200%]");
|
|
c->Message(Chat::White, "Usage: #npcedit heroic_strikethrough [Heroic Strikethrough] - Sets an NPC's Heroic Strikethrough");
|
|
c->Message(Chat::White, "Usage: #npcedit faction_amount [Faction Amount] - Sets an NPC's Faction Amount");
|
|
c->Message(Chat::White, "Usage: #npcedit keeps_sold_items [Flag] - Sets an NPC's Keeps Sold Items Flag [0 = False, 1 = True]");
|
|
c->Message(Chat::White, "Usage: #npcedit is_parcel_merchant [Flag] - Sets an NPC's Parcel Merchant Flag [0 = False, 1 = True]");
|
|
c->Message(Chat::White, "Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)");
|
|
c->Message(Chat::White, "Usage: #npcedit respawntime [Respawn Time] - Sets an NPC's Respawn Timer in Seconds (Stored in spawn2 table)");
|
|
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
|
c->Message(Chat::White, "Usage: #npcedit npc_tint_id [NPC Tint ID] - Sets an NPC's Tint ID (0 to 78 for RoF2)");
|
|
}
|
|
|
|
void command_npcedit(Client *c, const Seperator *sep)
|
|
{
|
|
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
|
c->Message(Chat::White, "You must target an NPC to use this command.");
|
|
return;
|
|
}
|
|
|
|
int arguments = sep->argnum;
|
|
|
|
bool is_help = (!arguments || !strcasecmp(sep->arg[1], "help"));
|
|
|
|
if (is_help) {
|
|
SendNPCEditSubCommands(c);
|
|
return;
|
|
}
|
|
|
|
std::string sub_command = sep->arg[1];
|
|
|
|
auto t = c->GetTarget()->CastToNPC();
|
|
auto npc_id = t->GetNPCTypeID();
|
|
auto npc_id_string = fmt::format(
|
|
"NPC ID {}",
|
|
npc_id
|
|
);
|
|
|
|
auto n = NpcTypesRepository::FindOne(content_db, npc_id);
|
|
if (!n.id) {
|
|
c->Message(Chat::White, "You must target a valid NPC to use this command.");
|
|
return;
|
|
}
|
|
|
|
std::string d;
|
|
|
|
if (!strcasecmp(sep->arg[1], "name")) {
|
|
std::string name = sep->argplus[2];
|
|
if (!name.empty()) {
|
|
n.name = name;
|
|
d = fmt::format(
|
|
"{} is now named '{}'.",
|
|
npc_id_string,
|
|
name
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit name [Name] - Sets an NPC's Name");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "lastname")) {
|
|
std::string last_name = sep->argplus[2];
|
|
n.lastname = last_name;
|
|
d = fmt::format(
|
|
"{} now has the lastname '{}'.",
|
|
npc_id_string,
|
|
last_name
|
|
);
|
|
} else if (!strcasecmp(sep->arg[1], "level")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto level = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.level = level;
|
|
d = fmt::format(
|
|
"{} is now level {}.",
|
|
npc_id_string,
|
|
level
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit level [Level] - Sets an NPC's Level");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "race")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto race_id = static_cast<uint16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.race = race_id;
|
|
d = fmt::format(
|
|
"{} is now a(n) {} ({}).",
|
|
npc_id_string,
|
|
GetRaceIDName(race_id),
|
|
race_id
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit race [Race ID] - Sets an NPC's Race");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "class")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto class_id = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.class_ = class_id;
|
|
d = fmt::format(
|
|
"{} is now a(n) {} ({}).",
|
|
npc_id_string,
|
|
GetClassIDName(class_id),
|
|
class_id
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit class [Class ID] - Sets an NPC's Class");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "bodytype")) {
|
|
if (sep->IsNumber(2)) {
|
|
const uint8 body_type_id = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
const std::string& body_type_name = BodyType::GetName(body_type_id);
|
|
if (Strings::EqualFold(body_type_name, "UNKNOWN BODY TYPE")) {
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"Body Type {} does not exist.",
|
|
body_type_id
|
|
).c_str()
|
|
);
|
|
return;
|
|
}
|
|
|
|
n.bodytype = body_type_id;
|
|
d = fmt::format(
|
|
"{} is now using Body Type {} ({}).",
|
|
npc_id_string,
|
|
body_type_name,
|
|
body_type_id
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit bodytype [Body Type ID] - Sets an NPC's Bodytype");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "hp")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto hp = Strings::ToBigInt(sep->arg[2]);
|
|
n.hp = hp;
|
|
d = fmt::format(
|
|
"{} now has {} Health.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit hp [HP] - Sets an NPC's HP");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "mana")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto mana = Strings::ToBigInt(sep->arg[2]);
|
|
n.mana = mana;
|
|
d = fmt::format(
|
|
"{} now has {} Mana.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit mana [Mana] - Sets an NPC's Mana");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "gender")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto gender_id = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.gender = gender_id;
|
|
d = fmt::format(
|
|
"{} is now a {} ({}).",
|
|
npc_id_string,
|
|
gender_id,
|
|
GetGenderName(gender_id)
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit gender [Gender ID] - Sets an NPC's Gender");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "texture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto texture = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.texture = texture;
|
|
d = fmt::format(
|
|
"{} is now using Texture {}.",
|
|
npc_id_string,
|
|
texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit texture [Texture] - Sets an NPC's Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "helmtexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto helmet_texture = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.helmtexture = helmet_texture;
|
|
d = fmt::format(
|
|
"{} is now using Helmet Texture {}.",
|
|
npc_id_string,
|
|
helmet_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit helmtexture [Helmet Texture] - Sets an NPC's Helmet Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "herosforgemodel")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto heros_forge_model = Strings::ToInt(sep->arg[2]);
|
|
n.herosforgemodel = heros_forge_model;
|
|
d = fmt::format(
|
|
"{} is now using Hero's Forge Model {}.",
|
|
npc_id_string,
|
|
heros_forge_model
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit herosforgemodel [Model Number] - Sets an NPC's Hero's Forge Model"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "size")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto size = Strings::ToFloat(sep->arg[2]);
|
|
n.size = size;
|
|
d = fmt::format(
|
|
"{} is now Size {:.2f}.",
|
|
npc_id_string,
|
|
size
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit size [Size] - Sets an NPC's Size");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "hpregen")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto hp_regen = Strings::ToBigInt(sep->arg[2]);
|
|
n.hp_regen_rate = hp_regen;
|
|
d = fmt::format(
|
|
"{} now regenerates {} Health per Tick.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit hpregen [HP Regen] - Sets an NPC's HP Regen Rate Per Tick");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "hp_regen_per_second")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto hp_regen_per_second = Strings::ToBigInt(sep->arg[2]);
|
|
n.hp_regen_per_second = hp_regen_per_second;
|
|
d = fmt::format(
|
|
"{} now regenerates {} HP per Second.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit hp_regen_per_second [HP Regen] - Sets an NPC's HP Regen Rate Per Second"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "manaregen")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto mana_regen = Strings::ToBigInt(sep->arg[2]);
|
|
n.mana_regen_rate = mana_regen;
|
|
d = fmt::format(
|
|
"{} now regenerates {} Mana per Tick.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit manaregen [Mana Regen] - Sets an NPC's Mana Regen Rate Per Tick");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "loottable")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto loottable_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.loottable_id = loottable_id;
|
|
d = fmt::format(
|
|
"{} is now using Loottable ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit loottable [Loottable ID] - Sets an NPC's Loottable ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "merchantid")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto merchant_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.merchant_id = merchant_id;
|
|
d = fmt::format(
|
|
"{} is now using Merchant ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit merchantid [Merchant ID] - Sets an NPC's Merchant ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "alt_currency_id")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto alternate_currency_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
auto alternate_currency_item_id = zone->GetCurrencyItemID(alternate_currency_id);
|
|
n.alt_currency_id = alternate_currency_id;
|
|
d = fmt::format(
|
|
"{} is now using Alternate Currency {}.",
|
|
npc_id_string,
|
|
(
|
|
alternate_currency_item_id ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
database.CreateItemLink(alternate_currency_item_id),
|
|
alternate_currency_id
|
|
) :
|
|
std::to_string(alternate_currency_id)
|
|
)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit alt_currency_id [Alternate Currency ID] - Sets an NPC's Alternate Currency ID"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "spell")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto spell_list_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.npc_spells_id = spell_list_id;
|
|
d = fmt::format(
|
|
"{} is now using Spell List ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit spell [Spell List ID] - Sets an NPC's Spells List ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "npc_spells_effects_id")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto spell_effects_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.npc_spells_effects_id = spell_effects_id;
|
|
d = fmt::format(
|
|
"{} is now using Spells Effects ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit npc_spells_effects_id [Spell Effects ID] - Sets an NPC's Spell Effects ID"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "faction")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto npc_faction_id = Strings::ToInt(sep->arg[2]);
|
|
const auto f = zone->GetNPCFaction(npc_faction_id);
|
|
if (f) {
|
|
auto faction_id = f->primaryfaction;
|
|
auto faction_name = content_db.GetFactionName(faction_id);
|
|
|
|
n.npc_faction_id = npc_faction_id;
|
|
d = fmt::format(
|
|
"{} is now using Faction {}.",
|
|
npc_id_string,
|
|
(
|
|
!faction_name.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
faction_name,
|
|
faction_id
|
|
) :
|
|
Strings::Commify(sep->arg[2])
|
|
)
|
|
);
|
|
}
|
|
else {
|
|
c->Message(Chat::White, "Need to provide a valid, existing, npc_faction_id");
|
|
return;
|
|
}
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit faction [npc_faction_id] - Sets an NPC's npc Faction ID (not primary faction) but lookup into table.");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "adventure_template_id")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto adventure_template_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.adventure_template_id = adventure_template_id;
|
|
d = fmt::format(
|
|
"{} is now using Adventure Template ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit adventure_template_id [Template ID] - Sets an NPC's Adventure Template ID"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "trap_template")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto trap_template = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.trap_template = trap_template;
|
|
d = fmt::format(
|
|
"{} is now using Trap Template ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit trap_template [Template ID] - Sets an NPC's Trap Template ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "damage")) {
|
|
if (sep->IsNumber(2) && sep->IsNumber(3)) {
|
|
auto minimum_damage = Strings::ToUnsignedInt(sep->arg[2]);
|
|
auto maximum_damage = Strings::ToUnsignedInt(sep->arg[3]);
|
|
n.mindmg = minimum_damage;
|
|
n.maxdmg = maximum_damage;
|
|
d = fmt::format(
|
|
"{} now hits from {} to {} damage.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2]),
|
|
Strings::Commify(sep->arg[3])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit damage [Minimum] [Maximum] - Sets an NPC's Damage");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "attackcount")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto attack_count = static_cast<int16>(Strings::ToInt(sep->arg[2]));
|
|
n.attack_count = attack_count;
|
|
d = fmt::format(
|
|
"{} now has an Attack Count of {}.",
|
|
npc_id_string,
|
|
attack_count
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit attackcount [Attack Count] - Sets an NPC's Attack Count");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "special_attacks")) {
|
|
std::string special_attacks = sep->argplus[2];
|
|
n.npcspecialattks = special_attacks;
|
|
d = fmt::format(
|
|
"{} is now using the following Special Attacks '{}'.",
|
|
npc_id_string,
|
|
special_attacks
|
|
);
|
|
} else if (!strcasecmp(sep->arg[1], "special_abilities")) {
|
|
std::string special_abilities = sep->argplus[2];
|
|
n.special_abilities = special_abilities;
|
|
d = fmt::format(
|
|
"{} is now using the following Special Abilities '{}'.",
|
|
npc_id_string,
|
|
special_abilities
|
|
);
|
|
} else if (!strcasecmp(sep->arg[1], "aggroradius")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto aggro_radius = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.aggroradius = aggro_radius;
|
|
d = fmt::format(
|
|
"{} now has an Aggro Radius of {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit aggroradius [Radius] - Sets an NPC's Aggro Radius");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "assistradius")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto assist_radius = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.assistradius = assist_radius;
|
|
d = fmt::format(
|
|
"{} now has an Assist Radius of {}",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit assistradius [Radius] - Sets an NPC's Assist Radius");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "featuresave")) {
|
|
d = fmt::format(
|
|
"{} saved with all current body and facial feature settings.",
|
|
npc_id
|
|
);
|
|
|
|
n.gender = t->GetGender();
|
|
n.texture = t->GetTexture();
|
|
n.helmtexture = t->GetHelmTexture();
|
|
n.size = t->GetSize();
|
|
n.face = t->GetLuclinFace();
|
|
n.luclin_hairstyle = t->GetHairStyle();
|
|
n.luclin_haircolor = t->GetHairColor();
|
|
n.luclin_eyecolor = t->GetEyeColor1();
|
|
n.luclin_eyecolor2 = t->GetEyeColor2();
|
|
n.luclin_beardcolor = t->GetBeardColor();
|
|
n.luclin_beard = t->GetBeard();
|
|
n.drakkin_heritage = t->GetDrakkinHeritage();
|
|
n.drakkin_tattoo = t->GetDrakkinTattoo();
|
|
n.drakkin_details = t->GetDrakkinDetails();
|
|
} else if (!strcasecmp(sep->arg[1], "armortint_id")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto armor_tint_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.armortint_id = armor_tint_id;
|
|
d = fmt::format(
|
|
"{} is now using Armor Tint ID {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit armortint_id [Armor Tint ID] - Sets an NPC's Armor Tint ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "color")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto red = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
uint8_t green = sep->IsNumber(3) ? static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[3])) : 0;
|
|
uint8_t blue = sep->IsNumber(4) ? static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[4])) : 0;
|
|
n.armortint_red = red;
|
|
n.armortint_green = green;
|
|
n.armortint_blue = blue;
|
|
d = fmt::format(
|
|
"{} now has {} Red, {} Green, and {} Blue tinting on their armor.",
|
|
npc_id_string,
|
|
red,
|
|
green,
|
|
blue
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit color [Red] [Green] [Blue] - Sets an NPC's Red, Green, and Blue armor tint"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "ammoidfile")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto ammo_id_file = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.ammo_idfile = ammo_id_file;
|
|
d = fmt::format(
|
|
"{} is now using Ammo ID File {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit ammoidfile [ID File] - Sets an NPC's Ammo ID File");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "weapon")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto primary_model = Strings::ToUnsignedInt(sep->arg[2]);
|
|
uint32_t secondary_model = sep->IsNumber(3) ? Strings::ToUnsignedInt(sep->arg[3]) : 0;
|
|
n.d_melee_texture1 = primary_model;
|
|
n.d_melee_texture2 = secondary_model;
|
|
d = fmt::format(
|
|
"{} will have Model {} set to their Primary and Model {} set to their Secondary on repop.",
|
|
npc_id_string,
|
|
Strings::Commify(primary_model),
|
|
Strings::Commify(secondary_model)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit weapon [Primary Model] [Secondary Model] - Sets an NPC's Primary and Secondary Weapon Model"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "meleetype")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto primary_type = Strings::ToUnsignedInt(sep->arg[2]);
|
|
uint32_t secondary_type = sep->IsNumber(3) ? Strings::ToUnsignedInt(sep->arg[3]) : EQ::skills::SkillHandtoHand;
|
|
|
|
auto primary_skill = EQ::skills::GetSkillName(static_cast<EQ::skills::SkillType>(primary_type));
|
|
auto secondary_skill = EQ::skills::GetSkillName(static_cast<EQ::skills::SkillType>(secondary_type));
|
|
|
|
n.prim_melee_type = primary_type;
|
|
n.sec_melee_type = secondary_type;
|
|
|
|
d = fmt::format(
|
|
"{} now has a Primary Melee Type of {} and a Secondary Melee Type of {}.",
|
|
npc_id_string,
|
|
(
|
|
!primary_skill.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
primary_skill,
|
|
primary_type
|
|
) :
|
|
std::to_string(primary_type)
|
|
),
|
|
(
|
|
!secondary_skill.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
secondary_skill,
|
|
secondary_type
|
|
) :
|
|
std::to_string(secondary_type)
|
|
)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit meleetype [Primary Type] [Secondary Type] - Sets an NPC's Melee Skill Types"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "rangedtype")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto ranged_type = Strings::ToUnsignedInt(sep->arg[2]);
|
|
|
|
auto ranged_skill = EQ::skills::GetSkillName(static_cast<EQ::skills::SkillType>(ranged_type));
|
|
|
|
n.ranged_type = ranged_type;
|
|
|
|
d = fmt::format(
|
|
"{} now has a Ranged Type of {}.",
|
|
npc_id_string,
|
|
(
|
|
!ranged_skill.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
ranged_skill,
|
|
ranged_type
|
|
) :
|
|
std::to_string(ranged_type)
|
|
)
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit rangedtype [Type] - Sets an NPC's Ranged Skill Type");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "runspeed")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto run_speed = Strings::ToFloat(sep->arg[2]);
|
|
n.runspeed = run_speed;
|
|
d = fmt::format(
|
|
"{} now runs at a Run Speed of {:.2f}.",
|
|
npc_id_string,
|
|
run_speed
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit runspeed [Run Speed] - Sets an NPC's Run Speed");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "mr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto magic_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.MR = magic_resist;
|
|
d = fmt::format(
|
|
"{} now has a Magic Resistance of {}.",
|
|
npc_id_string,
|
|
magic_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit mr [Resistance] - Sets an NPC's Magic Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "pr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto poison_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.PR = poison_resist;
|
|
d = fmt::format(
|
|
"{} now has a Poison Resistance of {}.",
|
|
npc_id_string,
|
|
poison_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit pr [Resistance] - Sets an NPC's Poison Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "dr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto disease_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.DR = disease_resist;
|
|
d = fmt::format(
|
|
"{} now has a Disease Resistance of {}.",
|
|
npc_id_string,
|
|
disease_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit dr [Resistance] - Sets an NPC's Disease Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "fr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto fire_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.FR = fire_resist;
|
|
d = fmt::format(
|
|
"{} now has a Fire Resistance of {}.",
|
|
npc_id_string,
|
|
fire_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit fr [Resistance] - Sets an NPC's Fire Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "cr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto cold_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.CR = cold_resist;
|
|
d = fmt::format(
|
|
"{} now has a Cold Resistance of {}.",
|
|
npc_id_string,
|
|
cold_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit cr [Resistance] - Sets an NPC's Cold Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "corrup")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto corruption_resist = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.Corrup = corruption_resist;
|
|
d = fmt::format(
|
|
"{} now has a Corruption Resistance of {}.",
|
|
npc_id_string,
|
|
corruption_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit corrup [Resistance] - Sets an NPC's Corruption Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "phr")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto physical_resist = static_cast<uint16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.PhR = physical_resist;
|
|
d = fmt::format(
|
|
"{} now has a Physical Resistance of {}.",
|
|
npc_id_string,
|
|
physical_resist
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit phr [Resistance] - Sets and NPC's Physical Resistance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "seeinvis")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto see_invisible = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.see_invis = see_invisible;
|
|
d = fmt::format(
|
|
"{} can {} See Invisible.",
|
|
npc_id_string,
|
|
see_invisible ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit seeinvis [Flag] - Sets an NPC's See Invisible Flag [0 = Cannot See Invisible, 1 = Can See Invisible]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "seeinvisundead")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto see_invisible_undead = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.see_invis_undead = see_invisible_undead;
|
|
d = fmt::format(
|
|
"{} can {} See Invisible vs. Undead.",
|
|
npc_id_string,
|
|
see_invisible_undead ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit seeinvisundead [Flag] - Sets an NPC's See Invisible vs. Undead Flag [0 = Cannot See Invisible vs. Undead, 1 = Can See Invisible vs. Undead]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "qglobal")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto use_qglobals = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.qglobal = use_qglobals;
|
|
d = fmt::format(
|
|
"{} can {} use Quest Globals.",
|
|
npc_id_string,
|
|
use_qglobals ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit qglobal [Flag] - Sets an NPC's Quest Global Flag [0 = Quest Globals Off, 1 = Quest Globals On]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "ac")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto armor_class = static_cast<int16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.AC = armor_class;
|
|
d = fmt::format(
|
|
"{} now has {} Armor Class.",
|
|
npc_id_string,
|
|
armor_class
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit ac [Armor Class] - Sets an NPC's Armor Class");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "npcaggro")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto aggro_npcs = static_cast<int8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.npc_aggro = aggro_npcs;
|
|
d = fmt::format(
|
|
"{} will {} aggro other NPCs that have a hostile faction.",
|
|
npc_id_string,
|
|
aggro_npcs ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit npcaggro [Flag] - Sets an NPC's NPC Aggro Flag [0 = Aggro NPCs Off, 1 = Aggro NPCs On]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "spawn_limit")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto spawn_limit = static_cast<int8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.spawn_limit = spawn_limit;
|
|
d = fmt::format(
|
|
"{} now has a Spawn Limit of {}.",
|
|
npc_id_string,
|
|
spawn_limit
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit spawn_limit [Limit] - Sets an NPC's Spawn Limit Counter");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "attackspeed")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto attack_speed = Strings::ToFloat(sep->arg[2]);
|
|
n.attack_speed = attack_speed;
|
|
d = fmt::format(
|
|
"{} now has an Attack Speed of {:.2f}.",
|
|
npc_id_string,
|
|
attack_speed
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit attackspeed [Attack Speed] - Sets an NPC's Attack Speed Modifier");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "attackdelay")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto attack_delay = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.attack_delay = attack_delay;
|
|
d = fmt::format(
|
|
"{} now has an Attack Delay of {}.",
|
|
npc_id_string,
|
|
attack_delay
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit attackdelay [Attack Delay] - Sets an NPC's Attack Delay");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "findable")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_findable = static_cast<int8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.findable = is_findable;
|
|
d = fmt::format(
|
|
"{} is {} Findable.",
|
|
npc_id_string,
|
|
is_findable ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit findable [Flag] - Sets an NPC's Findable Flag [0 = Not Findable, 1 = Findable]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "str")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto strength = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.STR = strength;
|
|
d = fmt::format(
|
|
"{} now has {} Strength.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit str [Strength] - Sets an NPC's Strength");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "sta")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto stamina = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.STA = stamina;
|
|
d = fmt::format(
|
|
"{} now has {} Stamina.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit sta [Stamina] - Sets an NPC's Stamina");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "agi")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto agility = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.AGI = agility;
|
|
d = fmt::format(
|
|
"{} now has {} Agility.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit agi [Agility] - Sets an NPC's Agility");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "dex")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto dexterity = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.DEX = dexterity;
|
|
d = fmt::format(
|
|
"{} now has {} Dexterity.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit dex [Dexterity] - Sets an NPC's Dexterity");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "int")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto intelligence = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n._INT = intelligence;
|
|
d = fmt::format(
|
|
"{} now has {} Intelligence.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit int [Intelligence] - Sets an NPC's Intelligence");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "wis")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto wisdom = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.WIS = wisdom;
|
|
d = fmt::format(
|
|
"{} now has {} Wisdom.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit wis [Wisdom] - Sets an NPC's Wisdom");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "cha")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charisma = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.CHA = charisma;
|
|
d = fmt::format(
|
|
"{} now has {} Charisma.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit cha [Charisma] - Sets an NPC's Charisma");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "seehide")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto see_hide = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.see_hide = see_hide;
|
|
d = fmt::format(
|
|
"{} can {} See Hide.",
|
|
npc_id_string,
|
|
see_hide ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit seehide [Flag] - Sets an NPC's See Hide Flag [0 = Cannot See Hide, 1 = Can See Hide]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "seeimprovedhide")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto see_improved_hide = static_cast<int8>(Strings::ToInt(sep->arg[2]));
|
|
n.see_improved_hide = see_improved_hide;
|
|
d = fmt::format(
|
|
"{} can {} See Improved Hide.",
|
|
npc_id_string,
|
|
see_improved_hide ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit seeimprovedhide [Flag] - Sets an NPC's See Improved Hide Flag [0 = Cannot See Improved Hide, 1 = Can See Improved Hide]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "trackable")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_trackable = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.trackable = is_trackable;
|
|
d = fmt::format(
|
|
"{} is {} Trackable.",
|
|
npc_id_string,
|
|
is_trackable ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit trackable [Flag] - Sets an NPC's Trackable Flag [0 = Not Trackable, 1 = Trackable]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "atk")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto attack = Strings::ToInt(sep->arg[2]);
|
|
n.ATK = attack;
|
|
d = fmt::format(
|
|
"{} now has {} Attack.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit atk [Attack] - Sets an NPC's Attack");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "accuracy")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto accuracy = Strings::ToInt(sep->arg[2]);
|
|
n.Accuracy = accuracy;
|
|
d = fmt::format(
|
|
"{} now has {} Accuracy.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit accuracy [Accuracy] - Sets an NPC's Accuracy");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "avoidance")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto avoidance = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.Avoidance = avoidance;
|
|
d = fmt::format(
|
|
"{} now has {} Avoidance.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit avoidance [Avoidance] - Sets an NPC's Avoidance");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "slow_mitigation")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto slow_mitigation = static_cast<int16_t>(Strings::ToInt(sep->arg[2]));
|
|
n.slow_mitigation = slow_mitigation;
|
|
d = fmt::format(
|
|
"{} now has {} Slow Mitigation.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit slow_mitigation [Slow Mitigation] - Sets an NPC's Slow Mitigation"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "version")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto version = static_cast<uint16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.version = version;
|
|
d = fmt::format(
|
|
"{} is now using Version {}.",
|
|
npc_id_string,
|
|
version
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit version [Version] - Sets an NPC's Version");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "maxlevel")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto max_level = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.maxlevel = max_level;
|
|
d = fmt::format(
|
|
"{} now has a Maximum Level of {}.",
|
|
npc_id_string,
|
|
max_level
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit maxlevel [Max Level] - Sets an NPC's Maximum Level");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "scalerate")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto scale_rate = Strings::ToInt(sep->arg[2]);
|
|
n.scalerate = scale_rate;
|
|
d = fmt::format(
|
|
"{} now has a Scaling Rate of {}%%.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit scalerate [Scale Rate] - Sets an NPC's Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "emoteid")) {
|
|
if (sep->IsNumber(2)) {
|
|
const uint32 emote_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.emoteid = emote_id;
|
|
d = fmt::format(
|
|
"{} now has an Emote ID of {}.",
|
|
npc_id_string,
|
|
Strings::Commify(emote_id)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit emoteid [Emote ID] - Sets an NPC's Emote ID"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "spellscale")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto spell_scale = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.spellscale = static_cast<float>(spell_scale);
|
|
d = fmt::format(
|
|
"{} now has a Spell Scaling Rate of {}%%.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit spellscale [Scale Rate] - Sets an NPC's Spell Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "healscale")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto heal_scale = Strings::ToUnsignedInt(sep->arg[2]);
|
|
n.healscale = static_cast<float>(heal_scale);
|
|
d = fmt::format(
|
|
"{} now has a Heal Scaling Rate of {}%%.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit healscale [Scale Rate] - Sets an NPC's Heal Scaling Rate [50 = 50%, 100 = 100%, 200 = 200%]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "no_target")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_no_target = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.no_target_hotkey = is_no_target;
|
|
d = fmt::format(
|
|
"{} is {} Targetable with Target Hotkey.",
|
|
npc_id_string,
|
|
is_no_target ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit no_target [Flag] - Sets an NPC's No Target Hotkey Flag [0 = Not Targetable with Target Hotkey, 1 = Targetable with Target Hotkey]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "raidtarget")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_raid_target = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.raid_target = is_raid_target;
|
|
d = fmt::format(
|
|
"{} is {} designated as a Raid Target.",
|
|
npc_id_string,
|
|
is_raid_target ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit raidtarget [Flag] - Sets an NPC's Raid Target Flag [0 = Not a Raid Target, 1 = Raid Target]"
|
|
);
|
|
}
|
|
return;
|
|
} else if (!strcasecmp(sep->arg[1], "armtexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto arm_texture = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.armtexture = arm_texture;
|
|
d = fmt::format(
|
|
"{} is now using Arm Texture {}.",
|
|
npc_id_string,
|
|
arm_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit armtexture [Texture] - Sets an NPC's Arm Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "bracertexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto bracer_texture = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.bracertexture = bracer_texture;
|
|
d = fmt::format(
|
|
"{} is now using Bracer Texture {}.",
|
|
npc_id_string,
|
|
bracer_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit bracertexture [Texture] - Sets an NPC's Bracer Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "handtexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto hand_texture = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.handtexture = hand_texture;
|
|
d = fmt::format(
|
|
"{} is now using Hand Texture {}.",
|
|
npc_id_string,
|
|
hand_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit handtexture [Texture] - Sets an NPC's Hand Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "legtexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto leg_texture = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.legtexture = leg_texture;
|
|
d = fmt::format(
|
|
"{} is now using Leg Texture {}.",
|
|
npc_id_string,
|
|
leg_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit legtexture [Texture] - Sets an NPC's Leg Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "feettexture")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto feet_texture = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.feettexture = feet_texture;
|
|
d = fmt::format(
|
|
"{} is now using Feet Texture {}.",
|
|
npc_id_string,
|
|
feet_texture
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit feettexture [Texture] - Sets an NPC's Feet Texture");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "walkspeed")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto walk_speed = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.walkspeed = walk_speed;
|
|
d = fmt::format(
|
|
"{} now walks at a Walk Speed of {}.",
|
|
npc_id_string,
|
|
walk_speed
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit walkspeed [Walk Speed] - Sets an NPC's Walk Speed");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "show_name")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto show_name = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.show_name = show_name;
|
|
d = fmt::format(
|
|
"{} will {} show their name.",
|
|
npc_id_string,
|
|
show_name ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit show_name [Flag] - Sets an NPC's Show Name Flag [0 = Hidden, 1 = Shown]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "untargetable")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_untargetable = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.untargetable = is_untargetable;
|
|
d = fmt::format(
|
|
"{} will {} be untargetable.",
|
|
npc_id_string,
|
|
is_untargetable ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit untargetable [Flag] - Sets an NPC's Untargetable Flag [0 = Targetable, 1 = Untargetable]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_ac")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_armor_class = static_cast<int16_t>(Strings::ToInt(sep->arg[2]));
|
|
n.charm_ac = charm_armor_class;
|
|
d = fmt::format(
|
|
"{} now has {} Armor Class while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit charm_ac [Armor Class] - Sets an NPC's Armor Class while Charmed");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_min_dmg")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_minimum_damage = Strings::ToInt(sep->arg[2]);
|
|
n.charm_min_dmg = charm_minimum_damage;
|
|
d = fmt::format(
|
|
"{} now does {} Minimum Damage while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit charm_min_dmg [Damage] - Sets an NPC's Minimum Damage while Charmed"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_max_dmg")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_maximum_damage = Strings::ToInt(sep->arg[2]);
|
|
n.charm_max_dmg = charm_maximum_damage;
|
|
d = fmt::format(
|
|
"{} now does {} Maximum Damage while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit charm_max_dmg [Damage] - Sets an NPC's Maximum Damage while Charmed"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_attack_delay")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_attack_delay = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.charm_attack_delay = charm_attack_delay;
|
|
d = fmt::format(
|
|
"{} now has {} Attack Delay while Charmed.",
|
|
npc_id_string,
|
|
charm_attack_delay
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit charm_attack_delay [Attack Delay] - Sets an NPC's Attack Delay while Charmed"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_accuracy_rating")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_accuracy_rating = Strings::ToInt(sep->arg[2]);
|
|
n.charm_accuracy_rating = charm_accuracy_rating;
|
|
d = fmt::format(
|
|
"{} now has {} Accuracy Rating while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit charm_accuracy_rating [Accuracy] - Sets an NPC's Accuracy Rating while Charmed"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_avoidance_rating")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_avoidance_rating = Strings::ToInt(sep->arg[2]);
|
|
n.charm_avoidance_rating = charm_avoidance_rating;
|
|
d = fmt::format(
|
|
"{} now has {} Avoidance Rating while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit charm_avoidance_rating [Avoidance] - Sets an NPC's Avoidance Rating while Charmed"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "charm_atk")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto charm_attack = Strings::ToInt(sep->arg[2]);
|
|
n.charm_atk = charm_attack;
|
|
d = fmt::format(
|
|
"{} now has {} Attack while Charmed.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit charm_atk [Attack] - Sets an NPC's Attack while Charmed");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "skip_global_loot")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto skip_global_loot = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.skip_global_loot = skip_global_loot;
|
|
d = fmt::format(
|
|
"{} will {} skip Global Loot.",
|
|
npc_id_string,
|
|
skip_global_loot ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit skip_global_loot [Flag] - Sets an NPC's Skip Global Loot Flag [0 = Don't Skip, 1 = Skip"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "rarespawn")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto is_rare_spawn = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.rare_spawn = is_rare_spawn;
|
|
d = fmt::format(
|
|
"{} is {} designated as a Rare Spawn.",
|
|
npc_id_string,
|
|
is_rare_spawn ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit rarespawn [Flag] - Sets an NPC's Rare Spawn Flag [0 = Not a Rare Spawn, 1 = Rare Spawn]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "stuck_behavior")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto behavior_id = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
if (behavior_id > EQ::constants::StuckBehavior::EvadeCombat) {
|
|
behavior_id = EQ::constants::StuckBehavior::EvadeCombat;
|
|
}
|
|
|
|
auto behavior_name = EQ::constants::GetStuckBehaviorName(behavior_id);
|
|
n.stuck_behavior = behavior_id;
|
|
d = fmt::format(
|
|
"{} is now using Stuck Behavior {}.",
|
|
npc_id_string,
|
|
(
|
|
!behavior_name.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
behavior_name,
|
|
behavior_id
|
|
) :
|
|
std::to_string(behavior_id)
|
|
)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit stuck_behavior [Stuck Behavior] - Sets an NPC's Stuck Behavior [0 = Run to Target, 1 = Warp to Target, 2 = Take No Action, 3 = Evade Combat]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "model")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto race_id = static_cast<uint16_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.model = race_id;
|
|
if (race_id) {
|
|
d = fmt::format(
|
|
"{} is now using a(n) {} ({}) as their race model.",
|
|
npc_id_string,
|
|
GetRaceIDName(race_id),
|
|
race_id
|
|
);
|
|
} else {
|
|
d = fmt::format(
|
|
"{} is no longer using a race model.",
|
|
npc_id_string
|
|
);
|
|
}
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit model [Race ID] - Sets an NPC's Race Model");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "flymode")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto flymode_id = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
if (flymode_id > GravityBehavior::LevitateWhileRunning) {
|
|
flymode_id = GravityBehavior::LevitateWhileRunning;
|
|
}
|
|
|
|
auto flymode_name = EQ::constants::GetFlyModeName(flymode_id);
|
|
n.flymode = flymode_id;
|
|
d = fmt::format(
|
|
"{} is now using Fly Mode {}.",
|
|
npc_id_string,
|
|
(
|
|
!flymode_name.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
flymode_name,
|
|
flymode_id
|
|
) :
|
|
std::to_string(flymode_id)
|
|
)
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit flymode [Fly Mode] - Sets an NPC's Fly Mode [0 = Ground, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating While Running]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "always_aggro")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto always_aggro = static_cast<int8_t>(Strings::ToInt(sep->arg[2]));
|
|
n.always_aggro = always_aggro;
|
|
d = fmt::format(
|
|
"{} will {} Always Aggro.",
|
|
npc_id_string,
|
|
always_aggro ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit always_aggro [Flag] - Sets an NPC's Always Aggro Flag [0 = Does not Always Aggro, 1 = Always Aggro]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "exp_mod")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto experience_modifier = Strings::ToInt(sep->arg[2]);
|
|
n.exp_mod = experience_modifier;
|
|
d = fmt::format(
|
|
"{} now has an Experience Modifier of {}%%.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit exp_mod [Modifier] - Sets an NPC's Experience Modifier [50 = 50%, 100 = 100%, 200 = 200%]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "heroic_strikethrough")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto heroic_strikethrough = Strings::ToInt(sep->arg[2]);
|
|
n.heroic_strikethrough = heroic_strikethrough;
|
|
d = fmt::format(
|
|
"{} now has {} Heroic Strikethrough.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit heroic_strikethrough [Heroic Strikethrough] - Sets an NPC's Heroic Strikethrough"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "faction_amount")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto faction_amount = Strings::ToInt(sep->arg[2]);
|
|
n.faction_amount = faction_amount;
|
|
d = fmt::format(
|
|
"{} now has a Faction Amount of {}.",
|
|
npc_id_string,
|
|
Strings::Commify(sep->arg[2])
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit faction_amount [Faction Amount] - Sets an NPC's Faction Amount"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "keeps_sold_items")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto keeps_sold_items = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
n.keeps_sold_items = keeps_sold_items;
|
|
d = fmt::format(
|
|
"{} will {} Keep Sold Items.",
|
|
npc_id_string,
|
|
keeps_sold_items ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit keeps_sold_items [Flag] - Sets an NPC's Keeps Sold Items Flag [0 = False, 1 = True]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "is_parcel_merchant")) {
|
|
if (sep->IsNumber(2)) {
|
|
const bool is_parcel_merchant = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
|
|
|
|
n.is_parcel_merchant = is_parcel_merchant;
|
|
|
|
d = fmt::format(
|
|
"{} will {} be a Parcel Merchant.",
|
|
npc_id_string,
|
|
is_parcel_merchant ? "now" : "no longer"
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit is_parcel_merchant [Flag] - Sets an NPC's Parcel Merchant Flag [0 = False, 1 = True]"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "setanimation")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto animation_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
if (animation_id > EQ::constants::SpawnAnimations::Looting) {
|
|
animation_id = EQ::constants::SpawnAnimations::Looting;
|
|
}
|
|
|
|
auto animation_name = EQ::constants::GetSpawnAnimationName(animation_id);
|
|
d = fmt::format(
|
|
"{} is now using Spawn Animation {} on Spawn Group ID {}.",
|
|
npc_id_string,
|
|
(
|
|
!animation_name.empty() ?
|
|
fmt::format(
|
|
"{} ({})",
|
|
animation_name,
|
|
animation_id
|
|
) :
|
|
std::to_string(animation_id)
|
|
),
|
|
Strings::Commify(std::to_string(c->GetTarget()->CastToNPC()->GetSpawnGroupId()))
|
|
);
|
|
auto query = fmt::format(
|
|
"UPDATE spawn2 SET animation = {} WHERE spawngroupID = {}",
|
|
animation_id,
|
|
c->GetTarget()->CastToNPC()->GetSpawnGroupId()
|
|
);
|
|
content_db.QueryDatabase(query);
|
|
|
|
c->GetTarget()->SetAppearance(EmuAppearance(animation_id));
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "respawntime")) {
|
|
if (sep->IsNumber(2)) {
|
|
auto respawn_time = Strings::ToUnsignedInt(sep->arg[2]);
|
|
if (respawn_time) {
|
|
d = fmt::format(
|
|
"{} now has a Respawn Timer of {} ({}) on Spawn Group ID {}.",
|
|
npc_id_string,
|
|
Strings::SecondsToTime(respawn_time),
|
|
respawn_time,
|
|
Strings::Commify(std::to_string(t->GetSpawnGroupId()))
|
|
);
|
|
auto query = fmt::format(
|
|
"UPDATE spawn2 SET respawntime = {} WHERE spawngroupID = {} AND version = {}",
|
|
respawn_time,
|
|
t->GetSpawnGroupId(),
|
|
zone->GetInstanceVersion()
|
|
);
|
|
content_db.QueryDatabase(query);
|
|
} else {
|
|
c->Message(Chat::White, "Respawn Timer must be greater than 0 seconds.");
|
|
return;
|
|
}
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit respawntime [Respawn Time] - Sets an NPC's Respawn Timer in Seconds (Stored in spawn2 table)"
|
|
);
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "set_grid")) {
|
|
if (sep->IsNumber(2)) {
|
|
const uint32 grid_id = Strings::ToUnsignedInt(sep->arg[2]);
|
|
if (grid_id >= 0) {
|
|
d = fmt::format(
|
|
"{} now has a Grid ID of {} on Spawn Group ID {}.",
|
|
npc_id_string,
|
|
grid_id,
|
|
Strings::Commify(std::to_string(t->GetSpawnGroupId()))
|
|
);
|
|
auto query = fmt::format(
|
|
"UPDATE spawn2 SET pathgrid = {} WHERE spawngroupID = {} AND version = {} AND zone = '{}'",
|
|
grid_id,
|
|
t->GetSpawnGroupId(),
|
|
zone->GetInstanceVersion(),
|
|
zone->GetShortName()
|
|
);
|
|
content_db.QueryDatabase(query);
|
|
} else {
|
|
c->Message(Chat::White, "Grid ID must be greater than or equal to 0.");
|
|
return;
|
|
}
|
|
} else {
|
|
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
|
return;
|
|
}
|
|
} else if (!strcasecmp(sep->arg[1], "npc_tint_id")) {
|
|
if (sep->IsNumber(2)) {
|
|
const uint32 npc_tint_id = (Strings::ToUnsignedInt(sep->arg[2]));
|
|
|
|
n.npc_tint_id = npc_tint_id;
|
|
|
|
d = fmt::format(
|
|
"Set NPCTintID {} for {}",
|
|
npc_tint_id,
|
|
npc_id_string
|
|
);
|
|
} else {
|
|
c->Message(
|
|
Chat::White,
|
|
"Usage: #npcedit npc_tint_id [id] - Sets an NPC's NPCTintID [0 - 78 for RoF2]"
|
|
);
|
|
return;
|
|
}
|
|
} else {
|
|
SendNPCEditSubCommands(c);
|
|
return;
|
|
}
|
|
|
|
if (!NpcTypesRepository::UpdateOne(content_db, n)) {
|
|
c->Message(
|
|
Chat::White,
|
|
fmt::format(
|
|
"Failed to update {}.",
|
|
npc_id_string
|
|
).c_str()
|
|
);
|
|
}
|
|
|
|
c->Message(Chat::White, d.c_str());
|
|
}
|