[Commands] Add #clearxtargets Command (#3833)

# Perl
- Add `$client->ClearXTargets()`.

# Lua
- Add `client:ClearXTargets()`.

# Notes
- Add `#clearxtargets` command for players.
- Allows operators/players to clear their XTargets if something get stuck on it.
This commit is contained in:
Alex King 2024-01-06 23:18:21 -05:00 committed by GitHub
parent 122fe398b4
commit 99d2e3a8b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 95 additions and 2 deletions

View File

@ -44,9 +44,10 @@ enum : int { //values for pTimerType
pTimerBeggingPickPocket = 27,
pTimerLinkedSpellReuseStart = 28,
pTimerLinkedSpellReuseEnd = 48,
pTimerClearXTarget = 50,
pTimerShieldAbility = 86,
pTimerShieldAbility = 86,
pTimerLayHands = 87, //these IDs are used by client too
pTimerHarmTouch = 89, //so dont change them

View File

@ -216,6 +216,7 @@ RULE_BOOL(Character, EnableRaidMemberEXPModifier, true, "Enable or disable the r
RULE_BOOL(Character, LeaveCursorMoneyOnCorpse, false, "Enable or disable leaving cursor money on player corpses")
RULE_BOOL(Character, ItemExtraSkillDamageCalcAsPercent, false, "If enabled, apply Item Extra Skill Damage as Percentage-based modifiers")
RULE_BOOL(Character, UseForageCommonFood, true, "If enabled, use the common foods specified in the code.")
RULE_INT(Character, ClearXTargetDelay, 10, "Seconds between uses of the #clearxtargets command (Set to 0 to disable)")
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)

View File

@ -11981,3 +11981,26 @@ std::string GetZoneModeString(ZoneMode mode)
return "Unknown";
}
}
void Client::ClearXTargets()
{
if (!XTargettingAvailable()) {
return;
}
for (int i = 0; i < GetMaxXTargets(); ++i) {
if (XTargets[i].ID) {
Mob* m = entity_list.GetMob(XTargets[i].ID);
if (m) {
RemoveXTarget(m, false);
}
XTargets[i].ID = 0;
XTargets[i].Name[0] = 0;
XTargets[i].dirty = false;
SendXTargetPacket(i, nullptr);
}
}
}

View File

@ -1528,6 +1528,7 @@ public:
void JoinGroupXTargets(Group *g);
void LeaveGroupXTargets(Group *g);
void LeaveRaidXTargets(Raid *r);
void ClearXTargets();
bool GroupFollow(Client* inviter);
inline bool GetRunMode() const { return runmode; }

View File

@ -100,6 +100,7 @@ int command_init(void)
command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) ||
command_add("castspell", "[Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)] - Cast a spell", AccountStatus::Guide, command_castspell) ||
command_add("chat", "[Channel ID] [Message] - Send a channel message to all zones", AccountStatus::GMMgmt, command_chat) ||
command_add("clearxtargets", "Clears XTargets", AccountStatus::Player, command_clearxtargets) ||
command_add("copycharacter", "[source_char_name] [dest_char_name] [dest_account_name] - Copies character to destination account", AccountStatus::GMImpossible, command_copycharacter) ||
command_add("corpse", "Manipulate corpses, use with no arguments for help", AccountStatus::Guide, command_corpse) ||
command_add("corpsefix", "Attempts to bring corpses from underneath the ground within close proximity of the player", AccountStatus::Player, command_corpsefix) ||
@ -792,6 +793,7 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/camerashake.cpp"
#include "gm_commands/castspell.cpp"
#include "gm_commands/chat.cpp"
#include "gm_commands/clearxtargets.cpp"
#include "gm_commands/copycharacter.cpp"
#include "gm_commands/corpse.cpp"
#include "gm_commands/corpsefix.cpp"

View File

@ -52,6 +52,7 @@ void command_bugs(Client *c, const Seperator *sep);
void command_camerashake(Client *c, const Seperator *sep);
void command_castspell(Client *c, const Seperator *sep);
void command_chat(Client *c, const Seperator *sep);
void command_clearxtargets(Client *c, const Seperator *sep);
void command_copycharacter(Client *c, const Seperator *sep);
void command_corpse(Client *c, const Seperator *sep);
void command_corpsefix(Client *c, const Seperator *sep);

View File

@ -0,0 +1,50 @@
#include "../client.h"
void command_clearxtargets(Client *c, const Seperator *sep)
{
const int reuse_timer = RuleI(Character, ClearXTargetDelay);
const int arguments = sep->argnum;
if (arguments) {
const bool is_help = !strcasecmp(sep->arg[1], "help");
if (is_help) {
c->Message(Chat::White, "Usage: #clearxtargets");
c->Message(
Chat::White,
"Note: Use this if your Extended Target window is bugged or has lingering targets that are invalid."
);
if (reuse_timer) {
c->Message(
Chat::White,
fmt::format(
"Note: This can only be used every {}.",
Strings::SecondsToTime(reuse_timer)
).c_str()
);
}
return;
}
}
if (reuse_timer) {
const uint32 time_left = c->GetPTimers().GetRemainingTime(pTimerClearXTarget);
if (!c->GetPTimers().Expired(&database, pTimerClearXTarget, false)) {
c->Message(
Chat::White,
fmt::format(
"You must wait {} before using this command again.",
Strings::SecondsToTime(time_left)
).c_str()
);
return;
}
}
c->ClearXTargets();
c->Message(Chat::White, "Extended Target window has been cleared.");
if (reuse_timer) {
c->GetPTimers().Start(pTimerClearXTarget, reuse_timer);
}
}

View File

@ -3252,6 +3252,12 @@ bool Lua_Client::HasItemOnCorpse(uint32 item_id)
return self->HasItemOnCorpse(item_id);
}
void Lua_Client::ClearXTargets()
{
Lua_Safe_Call_Void();
self->ClearXTargets();
}
luabind::scope lua_register_client() {
return luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>())
@ -3323,6 +3329,7 @@ luabind::scope lua_register_client() {
.def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark)
.def("ClearAccountFlag", (void(Lua_Client::*)(const std::string&))&Lua_Client::ClearAccountFlag)
.def("ClearPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearPEQZoneFlag)
.def("ClearXTargets", (void(Lua_Client::*)(void))&Lua_Client::ClearXTargets)
.def("ClearZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearZoneFlag)
.def("Connected", (bool(Lua_Client::*)(void))&Lua_Client::Connected)
.def("CountAugmentEquippedByID", (int(Lua_Client::*)(uint32))&Lua_Client::CountAugmentEquippedByID)

View File

@ -488,6 +488,7 @@ public:
void RemoveRadiantCrystals(uint32 amount);
void SummonItemIntoInventory(luabind::object item_table);
bool HasItemOnCorpse(uint32 item_id);
void ClearXTargets();
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);

View File

@ -3063,6 +3063,11 @@ bool Perl_Client_HasItemOnCorpse(Client* self, uint32 item_id)
return self->HasItemOnCorpse(item_id);
}
void Perl_Client_ClearXTargets(Client* self)
{
self->ClearXTargets();
}
void perl_register_client()
{
perl::interpreter perl(PERL_GET_THX);
@ -3137,6 +3142,7 @@ void perl_register_client()
package.add("ClearCompassMark", &Perl_Client_ClearCompassMark);
package.add("ClearAccountFlag", &Perl_Client_ClearAccountFlag);
package.add("ClearPEQZoneFlag", &Perl_Client_ClearPEQZoneFlag);
package.add("ClearXTargets", &Perl_Client_ClearXTargets);
package.add("ClearZoneFlag", &Perl_Client_ClearZoneFlag);
package.add("Connected", &Perl_Client_Connected);
package.add("CountAugmentEquippedByID", &Perl_Client_CountAugmentEquippedByID);