mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Commands] Cleanup #ai Command. (#1980)
- Cleanup messages and logic. - Remove #ai start/#ai stop as they can crash zones and are mostly useless. - Add EQ::constants::GetConsiderLevelMap() and EQ::constants::GetConsiderLevelName(). - Add quest::getconsiderlevelname(consider_level) to Perl. - Add eq.get_consider_level_name(consider_level) to Lua.
This commit is contained in:
parent
99793cab8b
commit
d2d7b8108d
@ -338,6 +338,31 @@ std::string EQ::constants::GetAccountStatusName(uint8 account_status)
|
||||
return status_name;
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> consider_level_map = {
|
||||
{ ConsiderLevel::Ally, "Ally" },
|
||||
{ ConsiderLevel::Warmly, "Warmly" },
|
||||
{ ConsiderLevel::Kindly, "Kindly" },
|
||||
{ ConsiderLevel::Amiably, "Amiably" },
|
||||
{ ConsiderLevel::Indifferently, "Indifferently" },
|
||||
{ ConsiderLevel::Apprehensively, "Apprehensively" },
|
||||
{ ConsiderLevel::Dubiously, "Dubiously" },
|
||||
{ ConsiderLevel::Threateningly, "Threateningly" },
|
||||
{ ConsiderLevel::Scowls, "Scowls" }
|
||||
};
|
||||
return consider_level_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
||||
{
|
||||
auto consider_levels = EQ::constants::GetConsiderLevelMap();
|
||||
if (!consider_levels[faction_consider_level].empty()) {
|
||||
return consider_levels[faction_consider_level];
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> damage_type_map = {
|
||||
|
||||
@ -255,6 +255,9 @@ namespace EQ
|
||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
||||
std::string GetAccountStatusName(uint8 account_status);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||
std::string GetConsiderLevelName(uint8 consider_level);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEnvironmentalDamageMap();
|
||||
std::string GetEnvironmentalDamageName(uint8 damage_type);
|
||||
|
||||
@ -401,4 +404,16 @@ enum AugmentActions : int {
|
||||
Destroy
|
||||
};
|
||||
|
||||
enum ConsiderLevel : uint8 {
|
||||
Ally = 1,
|
||||
Warmly,
|
||||
Kindly,
|
||||
Amiably,
|
||||
Indifferently,
|
||||
Apprehensively,
|
||||
Dubiously,
|
||||
Threateningly,
|
||||
Scowls
|
||||
};
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
@ -8092,6 +8092,23 @@ XS(XS__getbodytypename) {
|
||||
}
|
||||
}
|
||||
|
||||
XS(XS__getconsiderlevelname);
|
||||
XS(XS__getconsiderlevelname) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::getconsiderlevelname(uint8 consider_level)");
|
||||
{
|
||||
dXSTARG;
|
||||
uint8 consider_level = (uint8) SvUV(ST(0));
|
||||
std::string consider_level_name = quest_manager.getconsiderlevelname(consider_level);
|
||||
|
||||
sv_setpv(TARG, consider_level_name.c_str());
|
||||
XSprePUSH;
|
||||
PUSHTARG;
|
||||
XSRETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
XS(XS__getenvironmentaldamagename);
|
||||
XS(XS__getenvironmentaldamagename) {
|
||||
dXSARGS;
|
||||
@ -8392,6 +8409,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "getcharidbyname"), XS__getcharidbyname, file);
|
||||
newXS(strcpy(buf, "getclassname"), XS__getclassname, file);
|
||||
newXS(strcpy(buf, "getcleannpcnamebyid"), XS__getcleannpcnamebyid, file);
|
||||
newXS(strcpy(buf, "getconsiderlevelname"), XS__getconsiderlevelname, file);
|
||||
newXS(strcpy(buf, "gethexcolorcode"), XS__gethexcolorcode, file);
|
||||
newXS(strcpy(buf, "getcurrencyid"), XS__getcurrencyid, file);
|
||||
newXS(strcpy(buf, "getexpmodifierbycharid"), XS__getexpmodifierbycharid, file);
|
||||
|
||||
@ -2,138 +2,262 @@
|
||||
|
||||
void command_ai(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
int arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(Chat::White, "Usage: #ai consider [Mob Name] - Show how an NPC considers to a mob");
|
||||
c->Message(Chat::White, "Usage: #ai faction [Faction ID] - Set an NPC's Faction ID");
|
||||
c->Message(Chat::White, "Usage: #ai guard - Save an NPC's guard spot to their current location");
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Min X] [Max X] [Min Y] [Max Y] [Delay] [Minimum Delay] - Set an NPC's roambox using X and Y coordinates");
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Roam Distance] [Delay] [Minimum Delay] - Set an NPC's roambox using roam distance");
|
||||
c->Message(Chat::White, "Usage: #ai spells [Spell List ID] - Set an NPC's Spell List ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(sep->arg[1], "factionid") == 0) {
|
||||
if (target && sep->IsNumber(2)) {
|
||||
if (target->IsNPC()) {
|
||||
target->CastToNPC()->SetNPCFactionID(atoi(sep->arg[2]));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s is not an NPC.", target->GetName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai factionid [factionid]");
|
||||
}
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "spellslist") == 0) {
|
||||
if (target && sep->IsNumber(2) && atoi(sep->arg[2]) >= 0) {
|
||||
if (target->IsNPC()) {
|
||||
target->CastToNPC()->AI_AddNPCSpells(atoi(sep->arg[2]));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s is not an NPC.", target->GetName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai spellslist [npc_spells_id]");
|
||||
}
|
||||
|
||||
auto target = c->GetTarget()->CastToNPC();
|
||||
|
||||
bool is_consider = !strcasecmp(sep->arg[1], "consider");
|
||||
bool is_faction = !strcasecmp(sep->arg[1], "faction");
|
||||
bool is_guard = !strcasecmp(sep->arg[1], "guard");
|
||||
bool is_roambox = !strcasecmp(sep->arg[1], "roambox");
|
||||
bool is_spells = !strcasecmp(sep->arg[1], "spells");
|
||||
|
||||
if (
|
||||
!is_consider &&
|
||||
!is_faction &&
|
||||
!is_guard &&
|
||||
!is_roambox &&
|
||||
!is_spells
|
||||
) {
|
||||
c->Message(Chat::White, "Usage: #ai consider [Mob Name] - Show how an NPC considers to a mob");
|
||||
c->Message(Chat::White, "Usage: #ai faction [Faction ID] - Set an NPC's Faction ID");
|
||||
c->Message(Chat::White, "Usage: #ai guard - Save an NPC's guard spot to their current location");
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Min X] [Max X] [Min Y] [Max Y] [Delay] [Minimum Delay] - Set an NPC's roambox using X and Y coordinates");
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Roam Distance] [Delay] [Minimum Delay] - Set an NPC's roambox using roam distance");
|
||||
c->Message(Chat::White, "Usage: #ai spells [Spell List ID] - Set an NPC's Spell List ID");
|
||||
return;
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "con") == 0) {
|
||||
if (target && sep->arg[2][0] != 0) {
|
||||
Mob *tar2 = entity_list.GetMob(sep->arg[2]);
|
||||
if (tar2) {
|
||||
|
||||
if (is_consider) {
|
||||
if (arguments == 2) {
|
||||
auto mob_name = sep->arg[2];
|
||||
auto mob_to_consider = entity_list.GetMob(mob_name);
|
||||
if (mob_to_consider) {
|
||||
auto consider_level = static_cast<uint8>(mob_to_consider->GetReverseFactionCon(target));
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"%s considering %s: %i",
|
||||
target->GetName(),
|
||||
tar2->GetName(),
|
||||
tar2->GetReverseFactionCon(target));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: %s not found.", sep->arg[2]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai con [mob name]");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "guard") == 0) {
|
||||
if (target && target->IsNPC()) {
|
||||
target->CastToNPC()->SaveGuardSpot(target->GetPosition());
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: (targeted) #ai guard - sets npc to guard the current location (use #summon to move)"
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "roambox") == 0) {
|
||||
if (target && target->IsAIControlled() && target->IsNPC()) {
|
||||
if ((sep->argnum == 6 || sep->argnum == 7 || sep->argnum == 8) && sep->IsNumber(2) && sep->IsNumber(3) &&
|
||||
sep->IsNumber(4) && sep->IsNumber(5) && sep->IsNumber(6)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
if (sep->IsNumber(7)) {
|
||||
tmp = atoi(sep->arg[7]);
|
||||
}
|
||||
if (sep->IsNumber(8)) {
|
||||
tmp2 = atoi(sep->arg[8]);
|
||||
}
|
||||
target->CastToNPC()->AI_SetRoambox(
|
||||
atof(sep->arg[2]),
|
||||
atof(sep->arg[3]),
|
||||
atof(sep->arg[4]),
|
||||
atof(sep->arg[5]),
|
||||
atof(sep->arg[6]),
|
||||
tmp,
|
||||
tmp2
|
||||
fmt::format(
|
||||
"{} ({}) considers {} ({}) as {} ({}).",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
mob_to_consider->GetCleanName(),
|
||||
mob_to_consider->GetID(),
|
||||
EQ::constants::GetConsiderLevelName(consider_level),
|
||||
consider_level
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else if ((sep->argnum == 3 || sep->argnum == 4) && sep->IsNumber(2) && sep->IsNumber(3)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
} else {
|
||||
c->Message(Chat::White, "Usage: #ai consider [Mob Name] - Show how an NPC considers a mob");
|
||||
}
|
||||
} else if (is_faction) {
|
||||
if (sep->IsNumber(2)) {
|
||||
auto faction_id = std::stoi(sep->arg[2]);
|
||||
auto faction_name = content_db.GetFactionName(faction_id);
|
||||
target->SetNPCFactionID(faction_id);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) is now on Faction {}.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
(
|
||||
faction_name.empty() ?
|
||||
std::to_string(faction_id) :
|
||||
fmt::format(
|
||||
"{} ({})",
|
||||
faction_name,
|
||||
faction_id
|
||||
)
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
c->Message(Chat::White, "Usage: #ai faction [Faction ID] - Set an NPC's Faction ID");
|
||||
}
|
||||
} else if (is_guard) {
|
||||
auto target_position = target->GetPosition();
|
||||
|
||||
target->SaveGuardSpot(target_position);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) now has a guard spot of {:.2f}, {:.2f}, {:.2f} with a heading of {:.2f}.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
target_position.x,
|
||||
target_position.y,
|
||||
target_position.z,
|
||||
target_position.w
|
||||
).c_str()
|
||||
);
|
||||
} else if (is_roambox) {
|
||||
if (target->IsAIControlled()) {
|
||||
if (
|
||||
arguments >= 6 &&
|
||||
arguments <= 8 &&
|
||||
sep->IsNumber(2) &&
|
||||
sep->IsNumber(3) &&
|
||||
sep->IsNumber(4) &&
|
||||
sep->IsNumber(5) &&
|
||||
sep->IsNumber(6)
|
||||
) {
|
||||
auto distance = std::stof(sep->arg[2]);
|
||||
auto min_x = std::stof(sep->arg[3]);
|
||||
auto max_x = std::stof(sep->arg[4]);
|
||||
auto min_y = std::stof(sep->arg[5]);
|
||||
auto max_y = std::stof(sep->arg[6]);
|
||||
|
||||
uint32 delay = 2500;
|
||||
uint32 minimum_delay = 2500;
|
||||
|
||||
if (sep->IsNumber(7)) {
|
||||
delay = std::stoul(sep->arg[7]);
|
||||
}
|
||||
|
||||
if (sep->IsNumber(8)) {
|
||||
minimum_delay = std::stoul(sep->arg[8]);
|
||||
}
|
||||
|
||||
target->CastToNPC()->AI_SetRoambox(
|
||||
distance,
|
||||
max_x,
|
||||
min_x,
|
||||
max_y,
|
||||
min_y,
|
||||
delay,
|
||||
minimum_delay
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) now has a roambox from {}, {} to {}, {} with {} and {} and a distance of {}.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
min_x,
|
||||
min_y,
|
||||
max_x,
|
||||
max_y,
|
||||
(
|
||||
delay ?
|
||||
fmt::format(
|
||||
"a delay of {} ({})",
|
||||
ConvertMillisecondsToTime(delay),
|
||||
delay
|
||||
):
|
||||
"no delay"
|
||||
),
|
||||
(
|
||||
minimum_delay ?
|
||||
fmt::format(
|
||||
"a minimum delay of {} ({})",
|
||||
ConvertMillisecondsToTime(minimum_delay),
|
||||
minimum_delay
|
||||
):
|
||||
"no minimum delay"
|
||||
),
|
||||
distance
|
||||
).c_str()
|
||||
);
|
||||
} else if (
|
||||
arguments >= 3 &&
|
||||
arguments <= 4 &&
|
||||
sep->IsNumber(2) &&
|
||||
sep->IsNumber(3)
|
||||
) {
|
||||
auto max_distance = std::stof(sep->arg[2]);
|
||||
auto roam_distance_variance = std::stof(sep->arg[3]);
|
||||
|
||||
uint32 delay = 2500;
|
||||
uint32 minimum_delay = 2500;
|
||||
|
||||
if (sep->IsNumber(4)) {
|
||||
tmp = atoi(sep->arg[4]);
|
||||
delay = std::stoul(sep->arg[4]);
|
||||
}
|
||||
|
||||
if (sep->IsNumber(5)) {
|
||||
tmp2 = atoi(sep->arg[5]);
|
||||
minimum_delay = std::stoul(sep->arg[5]);
|
||||
}
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), tmp, tmp2);
|
||||
|
||||
target->CastToNPC()->AI_SetRoambox(
|
||||
max_distance,
|
||||
roam_distance_variance,
|
||||
delay,
|
||||
minimum_delay
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) now has a roambox with a max distance of {} and a roam distance variance of {} with {} and {}.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
max_distance,
|
||||
roam_distance_variance,
|
||||
(
|
||||
delay ?
|
||||
fmt::format(
|
||||
"a delay of {} ({})",
|
||||
delay,
|
||||
ConvertMillisecondsToTime(delay)
|
||||
):
|
||||
"no delay"
|
||||
),
|
||||
(
|
||||
minimum_delay ?
|
||||
fmt::format(
|
||||
"a minimum delay of {} ({})",
|
||||
minimum_delay,
|
||||
ConvertMillisecondsToTime(delay)
|
||||
):
|
||||
"no minimum delay"
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Min X] [Max X] [Min Y] [Max Y] [Delay] [Minimum Delay] - Set an NPC's roambox using X and Y coordinates");
|
||||
c->Message(Chat::White, "Usage: #ai roambox [Distance] [Roam Distance] [Delay] [Minimum Delay] - Set an NPC's roambox using roam distance");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #ai roambox dist max_x min_x max_y min_y [delay] [mindelay]");
|
||||
c->Message(Chat::White, "Usage: #ai roambox dist roamdist [delay] [mindelay]");
|
||||
} else {
|
||||
c->Message(Chat::White, "You must target an NPC with AI.");
|
||||
}
|
||||
} else if (is_spells) {
|
||||
if (sep->IsNumber(2)) {
|
||||
auto spell_list_id = std::stoul(sep->arg[2]);
|
||||
if (spell_list_id >= 0) {
|
||||
target->CastToNPC()->AI_AddNPCSpells(spell_list_id);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) is now using Spell List {}.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
spell_list_id
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
c->Message(Chat::White, "Spell List ID must be greater than or equal to 0.");
|
||||
}
|
||||
} else {
|
||||
c->Message(Chat::White, "Usage: #ai spells [Spell List ID] - Set an NPC's Spell List ID");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You need a AI NPC targeted");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "stop") == 0 && c->Admin() >= commandToggleAI) {
|
||||
if (target) {
|
||||
if (target->IsAIControlled()) {
|
||||
target->AI_Stop();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: Target is not AI controlled");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: Target a Mob with AI enabled and use this to turn off their AI.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "start") == 0 && c->Admin() >= commandToggleAI) {
|
||||
if (target) {
|
||||
if (!target->IsAIControlled()) {
|
||||
target->AI_Start();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: Target is already AI controlled");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: Target a Mob with AI disabled and use this to turn on their AI.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "#AI Sub-commands");
|
||||
c->Message(Chat::White, " factionid");
|
||||
c->Message(Chat::White, " spellslist");
|
||||
c->Message(Chat::White, " con");
|
||||
c->Message(Chat::White, " guard");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3367,6 +3367,10 @@ std::string lua_get_body_type_name(uint32 bodytype_id) {
|
||||
return quest_manager.getbodytypename(bodytype_id);
|
||||
}
|
||||
|
||||
std::string lua_get_consider_level_name(uint8 consider_level) {
|
||||
return quest_manager.getconsiderlevelname(consider_level);
|
||||
}
|
||||
|
||||
std::string lua_get_environmental_damage_name(uint8 damage_type) {
|
||||
return quest_manager.getenvironmentaldamagename(damage_type);
|
||||
}
|
||||
@ -3818,6 +3822,7 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("get_faction_name", &lua_get_faction_name),
|
||||
luabind::def("get_language_name", &lua_get_language_name),
|
||||
luabind::def("get_body_type_name", &lua_get_body_type_name),
|
||||
luabind::def("get_consider_level_name", &lua_get_consider_level_name),
|
||||
luabind::def("get_environmental_damage_name", &lua_get_environmental_damage_name),
|
||||
|
||||
/*
|
||||
|
||||
@ -1052,6 +1052,10 @@ std::string QuestManager::getbodytypename(uint32 bodytype_id) {
|
||||
return EQ::constants::GetBodyTypeName(static_cast<bodyType>(bodytype_id));
|
||||
}
|
||||
|
||||
std::string QuestManager::getconsiderlevelname(uint8 consider_level) {
|
||||
return EQ::constants::GetConsiderLevelName(consider_level);
|
||||
}
|
||||
|
||||
void QuestManager::safemove() {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (initiator && initiator->IsClient())
|
||||
|
||||
@ -119,6 +119,7 @@ public:
|
||||
std::string getfactionname(int faction_id);
|
||||
std::string getlanguagename(int language_id);
|
||||
std::string getbodytypename(uint32 bodytype_id);
|
||||
std::string getconsiderlevelname(uint8 consider_level);
|
||||
void safemove();
|
||||
void rain(int weather);
|
||||
void snow(int weather);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user