mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
Core/Conditions: allow spellclick conditions to properly work for aura apply/remove (#23527)
# Conflicts: # src/server/game/Entities/Player/Player.cpp
This commit is contained in:
@@ -1015,6 +1015,11 @@ bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsSpellUsedInSpellClickConditions(uint32 spellId) const
|
||||
{
|
||||
return SpellsUsedInSpellClickConditions.find(spellId) != SpellsUsedInSpellClickConditions.end();
|
||||
}
|
||||
|
||||
ConditionMgr* ConditionMgr::instance()
|
||||
{
|
||||
static ConditionMgr instance;
|
||||
@@ -1218,6 +1223,8 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
|
||||
{
|
||||
SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
|
||||
if (cond->ConditionType == CONDITION_AURA)
|
||||
SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1);
|
||||
valid = true;
|
||||
++count;
|
||||
continue; // do not add to m_AllocatedMemory to avoid double deleting
|
||||
@@ -1270,6 +1277,8 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
|
||||
//handle not grouped conditions
|
||||
//add new Condition to storage based on Type/Entry
|
||||
if (cond->SourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT && cond->ConditionType == CONDITION_AURA)
|
||||
SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1);
|
||||
ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond);
|
||||
++count;
|
||||
}
|
||||
@@ -2412,6 +2421,7 @@ void ConditionMgr::Clean()
|
||||
delete *i;
|
||||
|
||||
SpellClickEventConditionStore.clear();
|
||||
SpellsUsedInSpellClickConditions.clear();
|
||||
|
||||
for (ConditionEntriesByCreatureIdMap::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
|
||||
for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "Hash.h"
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
class Creature;
|
||||
@@ -261,6 +262,8 @@ class TC_GAME_API ConditionMgr
|
||||
bool IsObjectMeetingSmartEventConditions(int32 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const;
|
||||
bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const;
|
||||
|
||||
bool IsSpellUsedInSpellClickConditions(uint32 spellId) const;
|
||||
|
||||
struct ConditionTypeInfo
|
||||
{
|
||||
char const* Name;
|
||||
@@ -291,6 +294,8 @@ class TC_GAME_API ConditionMgr
|
||||
ConditionEntriesByCreatureIdMap SpellClickEventConditionStore;
|
||||
ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore;
|
||||
SmartEventConditionContainer SmartEventConditionStore;
|
||||
|
||||
std::unordered_set<uint32> SpellsUsedInSpellClickConditions;
|
||||
};
|
||||
|
||||
#define sConditionMgr ConditionMgr::instance()
|
||||
|
||||
@@ -16231,7 +16231,7 @@ void Player::SendQuestUpdate(uint32 questId)
|
||||
}
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
PhasingHandler::OnConditionChange(this);
|
||||
}
|
||||
|
||||
@@ -16525,17 +16525,13 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
|
||||
{
|
||||
q_status.ItemCount[j] = std::min<uint16>(q_status.ItemCount[j] + count, reqitemcount);
|
||||
m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE;
|
||||
|
||||
//SendQuestUpdateAddItem(qInfo, j, additemcount);
|
||||
// FIXME: verify if there's any packet sent updating item
|
||||
}
|
||||
if (CanCompleteQuest(questid))
|
||||
CompleteQuest(questid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
|
||||
@@ -16578,7 +16574,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
void Player::KilledMonster(CreatureTemplate const* cInfo, ObjectGuid guid)
|
||||
@@ -24680,7 +24676,7 @@ bool Player::HasQuestForGO(int32 GOId) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::UpdateForQuestWorldObjects()
|
||||
void Player::UpdateVisibleGameobjectsOrSpellClicks()
|
||||
{
|
||||
if (m_clientGUIDs.empty())
|
||||
return;
|
||||
@@ -24707,20 +24703,10 @@ void Player::UpdateForQuestWorldObjects()
|
||||
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(obj->GetEntry());
|
||||
for (SpellClickInfoContainer::const_iterator _itr = clickPair.first; _itr != clickPair.second; ++_itr)
|
||||
{
|
||||
//! This code doesn't look right, but it was logically converted to condition system to do the exact
|
||||
//! same thing it did before. It definitely needs to be overlooked for intended functionality.
|
||||
if (ConditionContainer const* conds = sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), _itr->second.spellId))
|
||||
{
|
||||
bool buildUpdateBlock = false;
|
||||
for (ConditionContainer::const_iterator jtr = conds->begin(); jtr != conds->end() && !buildUpdateBlock; ++jtr)
|
||||
if ((*jtr)->ConditionType == CONDITION_QUESTREWARDED || (*jtr)->ConditionType == CONDITION_QUESTTAKEN || (*jtr)->ConditionType == CONDITION_QUEST_COMPLETE)
|
||||
buildUpdateBlock = true;
|
||||
|
||||
if (buildUpdateBlock)
|
||||
{
|
||||
obj->BuildValuesUpdateBlockForPlayer(&udata, this);
|
||||
break;
|
||||
}
|
||||
obj->BuildValuesUpdateBlockForPlayer(&udata, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1437,7 +1437,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void ReputationChanged2(FactionEntry const* factionEntry);
|
||||
bool HasQuestForItem(uint32 itemId, uint32 excludeQuestId = 0, bool turnIn = false) const;
|
||||
bool HasQuestForGO(int32 goId) const;
|
||||
void UpdateForQuestWorldObjects();
|
||||
void UpdateVisibleGameobjectsOrSpellClicks();
|
||||
bool CanShareQuest(uint32 questId) const;
|
||||
|
||||
void SendQuestComplete(Quest const* quest) const;
|
||||
|
||||
@@ -3517,6 +3517,10 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
|
||||
if (effMask & 1 << i && (!aurApp->GetRemoveMode()))
|
||||
aurApp->_HandleEffect(i, true);
|
||||
}
|
||||
|
||||
if (Player* player = ToPlayer())
|
||||
if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId()))
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
// removes aura application from lists and unapplies effects
|
||||
@@ -3593,6 +3597,10 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
|
||||
|
||||
aura->HandleAuraSpecificMods(aurApp, caster, false, false);
|
||||
|
||||
if (Player* player = ToPlayer())
|
||||
if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId()))
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
// only way correctly remove all auras from list
|
||||
//if (removedAuras != m_removedAurasCount) new aura may be added
|
||||
i = m_appliedAuras.begin();
|
||||
|
||||
@@ -291,7 +291,7 @@ void Group::ConvertToRaid()
|
||||
// update quest related GO states (quest activity dependent from raid membership)
|
||||
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
|
||||
player->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
void Group::ConvertToGroup()
|
||||
@@ -489,7 +489,7 @@ bool Group::AddMember(Player* player)
|
||||
|
||||
// quest related GO state dependent from raid membership
|
||||
if (isRaidGroup())
|
||||
player->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
{
|
||||
// Broadcast new player group member fields to rest of the group
|
||||
@@ -585,7 +585,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
|
||||
player->SetGroup(nullptr);
|
||||
|
||||
// quest related GO state dependent from raid membership
|
||||
player->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
@@ -821,7 +821,7 @@ void Group::Disband(bool hideDestroy /* = false */)
|
||||
|
||||
// quest related GO state dependent from raid membership
|
||||
if (isRaidGroup())
|
||||
player->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
if (!player->GetSession())
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user