[Commands] Cleanup #nukebuffs Command. (#1795)

* [Commands] Cleanup #nukebuffs Command.
- Cleanup messages and logic.
- #nukebuffs now allows you to nuke all, beneficial, or detrimental buffs, also added a help menu.
- Add BuffFadeBeneficial().
- Cleanup logic in some buff fade methods.
- Fix several spots where we were using CalcBonuses() when it was unnecessary, i.e when you fade no buffs you do not need to recalculate bonuses.

* Update spells.cpp
This commit is contained in:
Kinglykrab 2021-11-21 15:20:16 -05:00 committed by GitHub
parent 39c27c987d
commit d29993fafa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 220 additions and 124 deletions

View File

@ -266,7 +266,7 @@ int command_init(void)
command_add("npctype_cache", "[id] or all - Clears the npc type cache for either the id or all npcs.", AccountStatus::GMImpossible, command_npctype_cache) ||
command_add("npctypespawn", "[npctypeid] [factionid] - Spawn an NPC from the db", AccountStatus::Steward, command_npctypespawn) ||
command_add("nudge", "- Nudge your target's current position by specific values", AccountStatus::QuestTroupe, command_nudge) ||
command_add("nukebuffs", "- Strip all buffs on you or your target", AccountStatus::Guide, command_nukebuffs) ||
command_add("nukebuffs", "[Beneficial|Detrimental|Help] - Strip all buffs by type on you or your target (no argument to remove all buffs)", AccountStatus::Guide, command_nukebuffs) ||
command_add("nukeitem", "[Item ID] - Removes the specified Item ID from you or your player target's inventory", AccountStatus::GMLeadAdmin, command_nukeitem) ||
command_add("object", "List|Add|Edit|Move|Rotate|Copy|Save|Undo|Delete - Manipulate static and tradeskill objects within the zone", AccountStatus::GMAdmin, command_object) ||
command_add("oocmute", "[1/0] - Mutes OOC chat", AccountStatus::GMMgmt, command_oocmute) ||

View File

@ -1,12 +1,47 @@
#include "../client.h"
void command_nukebuffs(Client *c, const Seperator *sep)
{
if (c->GetTarget() == 0) {
c->BuffFadeAll();
{
Mob* target = c;
if (c->GetTarget()) {
target = c->GetTarget();
}
else {
c->GetTarget()->BuffFadeAll();
std::string buff_identifier = str_tolower(sep->arg[1]);
std::string buff_type;
bool is_beneficial = buff_identifier.find("beneficial") != std::string::npos;
bool is_detrimental = buff_identifier.find("detrimental") != std::string::npos;
bool is_help = buff_identifier.find("help") != std::string::npos;
if (is_beneficial) {
target->BuffFadeBeneficial();
buff_type = " beneficial";
} else if (is_detrimental) {
target->BuffFadeDetrimental();
buff_type = " detrimental";
} else if (is_help) {
c->Message(Chat::White, "Usage: #nukebuffs");
c->Message(Chat::White, "Usage: #nukebuffs beneficial");
c->Message(Chat::White, "Usage: #nukebuffs detrimental");
return;
} else {
target->BuffFadeAll();
}
c->Message(
Chat::White,
fmt::format(
"Faded all{} buffs for {}.",
buff_type,
(
c == target ?
"yourself" :
fmt::format(
"{} ({})",
target->GetCleanName(),
target->GetID()
)
)
).c_str()
);
}

View File

@ -361,8 +361,9 @@ public:
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
void BuffFadeBySpellID(uint16 spell_id);
void BuffFadeBySpellIDAndCaster(uint16 spell_id, uint16 caster_id);
void BuffFadeByEffect(int effect_id, int skipslot = -1);
void BuffFadeByEffect(int effect_id, int slot_to_skip = -1);
void BuffFadeAll();
void BuffFadeBeneficial();
void BuffFadeNonPersistDeath();
void BuffFadeDetrimental();
void BuffFadeBySlot(int slot, bool iRecalcBonuses = true);
@ -393,7 +394,7 @@ public:
void DoGravityEffect();
void DamageShield(Mob* other, bool spell_ds = false);
int32 RuneAbsorb(int32 damage, uint16 type);
bool FindBuff(uint16 spellid);
bool FindBuff(uint16 spell_id);
uint16 FindBuffBySlot(int slot);
uint32 BuffCount();
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
@ -421,7 +422,7 @@ public:
inline float GetTargetRingZ() const { return m_TargetRing.z; }
inline bool HasEndurUpkeep() const { return endur_upkeep; }
inline void SetEndurUpkeep(bool val) { endur_upkeep = val; }
bool HasBuffWithSpellGroup(int spellgroup);
bool HasBuffWithSpellGroup(int spell_group);
//Basic Stats/Inventory
virtual void SetLevel(uint8 in_level, bool command = false) { level = in_level; }

View File

@ -4255,21 +4255,27 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster)
safe_delete(outapp);
}
bool Mob::FindBuff(uint16 spellid)
bool Mob::FindBuff(uint16 spell_id)
{
int i;
uint32 buff_count = GetMaxTotalSlots();
for(i = 0; i < buff_count; i++)
if(buffs[i].spellid == spellid)
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
current_spell_id == spell_id
) {
return true;
}
}
return false;
}
uint16 Mob::FindBuffBySlot(int slot) {
if (buffs[slot].spellid != SPELL_UNKNOWN)
return buffs[slot].spellid;
auto current_spell_id = buffs[slot].spellid;
if (IsValidSpell(current_spell_id)) {
return current_spell_id;
}
return 0;
}
@ -4277,167 +4283,221 @@ uint16 Mob::FindBuffBySlot(int slot) {
uint32 Mob::BuffCount() {
uint32 active_buff_count = 0;
int buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; i++)
if (buffs[i].spellid != SPELL_UNKNOWN)
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
if (IsValidSpell(buffs[buff_slot].spellid)) {
active_buff_count++;
}
}
return active_buff_count;
}
bool Mob::HasBuffWithSpellGroup(int spellgroup)
bool Mob::HasBuffWithSpellGroup(int spell_group)
{
for (int i = 0; i < GetMaxTotalSlots(); i++) {
if (IsValidSpell(buffs[i].spellid) && spells[buffs[i].spellid].spell_group == spellgroup) {
for (int buff_slot = 0; buff_slot < GetMaxTotalSlots(); buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
spells[current_spell_id].spell_group == spell_group
) {
return true;
}
}
return false;
}
// removes all buffs
void Mob::BuffFadeAll()
{
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int j = 0; j < buff_count; j++) {
if(buffs[j].spellid != SPELL_UNKNOWN)
BuffFadeBySlot(j, false);
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeNonPersistDeath()
{
int buff_count = GetMaxTotalSlots();
for (int j = 0; j < buff_count; j++) {
if (buffs[j].spellid != SPELL_UNKNOWN && !IsPersistDeathSpell(buffs[j].spellid))
BuffFadeBySlot(j, false);
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeDetrimental() {
int buff_count = GetMaxTotalSlots();
for (int j = 0; j < buff_count; j++) {
if(buffs[j].spellid != SPELL_UNKNOWN) {
if(IsDetrimentalSpell(buffs[j].spellid))
BuffFadeBySlot(j, false);
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeDetrimentalByCaster(Mob *caster)
{
if(!caster)
return;
int buff_count = GetMaxTotalSlots();
for (int j = 0; j < buff_count; j++) {
if(buffs[j].spellid != SPELL_UNKNOWN) {
if(IsDetrimentalSpell(buffs[j].spellid))
{
//this is a pretty terrible way to do this but
//there really isn't another way till I rewrite the basics
Mob * c = entity_list.GetMob(buffs[j].casterid);
if(c && c == caster)
BuffFadeBySlot(j, false);
}
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeBySitModifier()
{
bool r_bonus = false;
uint32 buff_count = GetMaxTotalSlots();
for(uint32 j = 0; j < buff_count; ++j)
{
if(buffs[j].spellid != SPELL_UNKNOWN)
{
if(spells[buffs[j].spellid].disallow_sit)
{
BuffFadeBySlot(j, false);
r_bonus = true;
}
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
if (IsValidSpell(buffs[buff_slot].spellid)) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if(r_bonus)
{
if (recalc_bonus) {
CalcBonuses();
}
}
// removes the buff matching spell_id
void Mob::BuffFadeBySpellID(uint16 spell_id)
void Mob::BuffFadeNonPersistDeath()
{
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int j = 0; j < buff_count; j++)
{
if (buffs[j].spellid == spell_id)
BuffFadeBySlot(j, false);
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
!IsPersistDeathSpell(current_spell_id)
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeBeneficial() {
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
IsBeneficialSpell(current_spell_id)
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeDetrimental() {
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
IsDetrimentalSpell(current_spell_id)
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeDetrimentalByCaster(Mob *caster)
{
if(!caster) {
return;
}
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
IsDetrimentalSpell(current_spell_id) &&
caster->GetID() == buffs[buff_slot].casterid
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeBySitModifier()
{
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
spells[current_spell_id].disallow_sit
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeBySpellID(uint16 spell_id)
{
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
if (buffs[buff_slot].spellid == spell_id) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus) {
CalcBonuses();
}
}
void Mob::BuffFadeBySpellIDAndCaster(uint16 spell_id, uint16 caster_id)
{
bool recalc_bonus = false;
auto buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; ++i) {
if (buffs[i].spellid == spell_id && buffs[i].casterid == caster_id) {
BuffFadeBySlot(i, false);
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
if (
buffs[buff_slot].spellid == spell_id &&
buffs[buff_slot].casterid == caster_id
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
if (recalc_bonus)
if (recalc_bonus) {
CalcBonuses();
}
}
// removes buffs containing effectid, skipping skipslot
void Mob::BuffFadeByEffect(int effect_id, int skipslot)
void Mob::BuffFadeByEffect(int effect_id, int slot_to_skip)
{
int i;
bool recalc_bonus = false;
int buff_count = GetMaxTotalSlots();
for(i = 0; i < buff_count; i++)
{
if(buffs[i].spellid == SPELL_UNKNOWN)
continue;
if(IsEffectInSpell(buffs[i].spellid, effect_id) && i != skipslot)
BuffFadeBySlot(i, false);
for(int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
IsEffectInSpell(current_spell_id, effect_id) &&
buff_slot != slot_to_skip
) {
BuffFadeBySlot(buff_slot, false);
recalc_bonus = true;
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
if (recalc_bonus) {
CalcBonuses();
}
}
bool Mob::IsAffectedByBuff(uint16 spell_id)
{
int buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; ++i)
if (buffs[i].spellid == spell_id)
return true;
return false;
return FindBuff(spell_id);
}
bool Mob::IsAffectedByBuffByGlobalGroup(GlobalGroup group)
{
int buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; ++i) {
if (buffs[i].spellid == SPELL_UNKNOWN)
continue;
if (spells[buffs[i].spellid].spell_category == static_cast<int>(group))
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
spells[current_spell_id].spell_category == static_cast<int>(group)
) {
return true;
}
}
return false;