[Charm] Fix to update target windows on charm on/off (#3549)

* [Charm] Fix to update target windows on charm on/off

* Removed accidental change

* Removed magic #

* reformated brace style in function that was modified

* Use better names for clear variables

* Forgot header with name change

* More header name changes
This commit is contained in:
Paul Coene 2023-08-20 16:43:10 -04:00 committed by GitHub
parent 9cbe25f712
commit 4357b8c731
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 32 deletions

View File

@ -1595,7 +1595,7 @@ void EntityList::RefreshClientXTargets(Client *c)
} }
void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *app, void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *app,
bool iSendToSender, Mob *SkipThisMob, bool ackreq, bool HoTT, uint32 ClientVersionBits, bool inspect_buffs) bool iSendToSender, Mob *SkipThisMob, bool ackreq, bool HoTT, uint32 ClientVersionBits, bool inspect_buffs, bool clear_target_window)
{ {
auto it = client_list.begin(); auto it = client_list.begin();
while (it != client_list.end()) { while (it != client_list.end()) {
@ -1611,7 +1611,7 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
TargetsTarget = Target->GetTarget(); TargetsTarget = Target->GetTarget();
bool Send = false; bool Send = clear_target_window;
if (c == SkipThisMob) if (c == SkipThisMob)
continue; continue;
@ -1624,22 +1624,23 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
if (Target == sender) { if (Target == sender) {
if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA
if (c->GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs)) { if (c->GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs)) {
Send = true; Send = !clear_target_window;
} else if (c->IsRaidGrouped()) { } else if (c->IsRaidGrouped()) {
Raid *raid = c->GetRaid(); Raid *raid = c->GetRaid();
if (!raid) if (raid) {
continue;
uint32 gid = raid->GetGroup(c); uint32 gid = raid->GetGroup(c);
if (gid > 11 || raid->GroupCount(gid) < 3) if (gid < MAX_RAID_GROUPS && raid->GroupCount(gid) >= 3) {
continue;
if (raid->GetLeadershipAA(groupAAInspectBuffs, gid)) if (raid->GetLeadershipAA(groupAAInspectBuffs, gid))
Send = true; Send = !clear_target_window;
}
}
} else { } else {
Group *group = c->GetGroup(); Group *group = c->GetGroup();
if (!group || group->GroupCount() < 3) if (group && group->GroupCount() >= 3) {
continue; if (group->GetLeadershipAA(groupAAInspectBuffs)) {
if (group->GetLeadershipAA(groupAAInspectBuffs)) Send = !clear_target_window;
Send = true; }
}
} }
} else { } else {
Send = true; Send = true;
@ -1649,9 +1650,10 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
} }
} }
if (Send && (c->ClientVersionBit() & ClientVersionBits)) if (Send && (c->ClientVersionBit() & ClientVersionBits)) {
c->QueuePacket(app, ackreq); c->QueuePacket(app, ackreq);
} }
}
} }
void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender, EQ::versions::ClientVersionBitmask client_version_bits) void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender, EQ::versions::ClientVersionBitmask client_version_bits)

View File

@ -413,8 +413,7 @@ public:
void QueueClientsStatus(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint8 minstatus = AccountStatus::Player, uint8 maxstatus = AccountStatus::Player); void QueueClientsStatus(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint8 minstatus = AccountStatus::Player, uint8 maxstatus = AccountStatus::Player);
void QueueClientsGuild(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint32 guildeqid = 0); void QueueClientsGuild(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint32 guildeqid = 0);
void QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struct *gbius, uint32 GuildID); void QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struct *gbius, uint32 GuildID);
void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true, void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true, bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false, bool clear_target_window = false);
bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false);
void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQ::versions::ClientVersionBitmask client_version_bits = EQ::versions::ClientVersionBitmask::maskAllClients); void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQ::versions::ClientVersionBitmask client_version_bits = EQ::versions::ClientVersionBitmask::maskAllClients);
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app); void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);

View File

@ -457,7 +457,7 @@ public:
virtual uint32 GetLastBuffSlot(bool disc, bool song); virtual uint32 GetLastBuffSlot(bool disc, bool song);
virtual void InitializeBuffSlots() { buffs = nullptr; } virtual void InitializeBuffSlots() { buffs = nullptr; }
virtual void UninitializeBuffSlots() { } virtual void UninitializeBuffSlots() { }
EQApplicationPacket *MakeBuffsPacket(bool for_target = true); EQApplicationPacket *MakeBuffsPacket(bool for_target = true, bool clear_buffs = false);
void SendBuffsToClient(Client *c); void SendBuffsToClient(Client *c);
inline Buffs_Struct* GetBuffs() { return buffs; } inline Buffs_Struct* GetBuffs() { return buffs; }
void DoGravityEffect(); void DoGravityEffect();

View File

@ -799,6 +799,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
SetPetType(petCharmed); SetPetType(petCharmed);
// This was done in AddBuff, but we were not a pet yet, so
// the target windows didn't get updated.
EQApplicationPacket *outapp = MakeBuffsPacket();
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQ::versions::maskSoDAndLater);
safe_delete(outapp);
if(caster->IsClient()){ if(caster->IsClient()){
auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct)); auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct));
Charm_Struct *ps = (Charm_Struct*)app->pBuffer; Charm_Struct *ps = (Charm_Struct*)app->pBuffer;
@ -4355,6 +4361,15 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
{ {
owner->SetPet(0); owner->SetPet(0);
} }
// Any client that has a previous charmed pet targetted shouldo
// no longer see the buffs on the old pet.
// QueueClientsByTarget preserves GM and leadership cases.
EQApplicationPacket *outapp = MakeBuffsPacket(true, true);
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQ::versions::maskSoDAndLater, true, true);
if (IsAIControlled()) if (IsAIControlled())
{ {
//Remove damage over time effects on charmed pet and those applied by charmed pet. //Remove damage over time effects on charmed pet and those applied by charmed pet.

View File

@ -6258,16 +6258,22 @@ void Mob::SendBuffsToClient(Client *c)
} }
} }
EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target) EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target, bool clear_buffs)
{ {
uint32 count = 0; uint32 count = 0;
uint32 buff_count;
// for self we want all buffs, for target, we want to skip song window buffs // for self we want all buffs, for target, we want to skip song window buffs
// since NPCs and pets don't have a song window, we still see it for them :P // since NPCs and pets don't have a song window, we still see it for them :P
uint32 buff_count = for_target ? GetMaxBuffSlots() : GetMaxTotalSlots(); if (for_target) {
for(int i = 0; i < buff_count; ++i) buff_count = (clear_buffs) ? 0 : GetMaxBuffSlots();
{ }
if (IsValidSpell(buffs[i].spellid)) else {
{ buff_count = GetMaxTotalSlots();
}
for(int i = 0; i < buff_count; ++i) {
if (IsValidSpell(buffs[i].spellid)) {
++count; ++count;
} }
} }
@ -6275,12 +6281,10 @@ EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target)
EQApplicationPacket* outapp = nullptr; EQApplicationPacket* outapp = nullptr;
//Create it for a targeting window, else create it for a create buff packet. //Create it for a targeting window, else create it for a create buff packet.
if(for_target) if(for_target) {
{
outapp = new EQApplicationPacket(OP_TargetBuffs, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct) * count); outapp = new EQApplicationPacket(OP_TargetBuffs, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct) * count);
} }
else else {
{
outapp = new EQApplicationPacket(OP_BuffCreate, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct) * count); outapp = new EQApplicationPacket(OP_BuffCreate, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct) * count);
} }
BuffIcon_Struct *buff = (BuffIcon_Struct*)outapp->pBuffer; BuffIcon_Struct *buff = (BuffIcon_Struct*)outapp->pBuffer;
@ -6297,10 +6301,8 @@ EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target)
buff->name_lengths = 0; // hacky shit buff->name_lengths = 0; // hacky shit
uint32 index = 0; uint32 index = 0;
for(int i = 0; i < buff_count; ++i) for(int i = 0; i < buff_count; ++i) {
{ if (IsValidSpell(buffs[i].spellid)) {
if (IsValidSpell(buffs[i].spellid))
{
buff->entries[index].buff_slot = i; buff->entries[index].buff_slot = i;
buff->entries[index].spell_id = buffs[i].spellid; buff->entries[index].spell_id = buffs[i].spellid;
buff->entries[index].tics_remaining = buffs[i].ticsremaining; buff->entries[index].tics_remaining = buffs[i].ticsremaining;