mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Core/Player): remove vendor icon if there is no gossip vendor option (#23026)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
--
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=23 AND `SourceEntry`=0 AND `SourceId`=0 AND `SourceGroup` IN (3443, 12919, 15471);
|
||||
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 9087) AND (`SourceEntry` = 0) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 12) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 109) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 9087, 0, 0, 0, 12, 0, 109, 0, 0, 0, 0, 0, '', 'event \'Sun\'s Reach Reclamation Phase Anvil\' must be active');
|
||||
@@ -90,6 +90,7 @@
|
||||
#include "WorldStateDefines.h"
|
||||
#include "WorldStatePackets.h"
|
||||
#include <cmath>
|
||||
#include <queue>
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -14364,6 +14365,67 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if any vendor option is available in the gossip menu tree for a given creature.
|
||||
*
|
||||
* @param menuId The starting gossip menu ID to check.
|
||||
* @param creature Pointer to the creature whose gossip menus are being checked.
|
||||
* @return true if a vendor option is available in any accessible menu; false otherwise.
|
||||
*/
|
||||
bool Player::AnyVendorOptionAvailable(uint32 menuId, Creature const* creature) const
|
||||
{
|
||||
std::set<uint32> visitedMenus;
|
||||
std::queue<uint32> menusToCheck;
|
||||
menusToCheck.push(menuId);
|
||||
|
||||
while (!menusToCheck.empty())
|
||||
{
|
||||
uint32 const currentMenuId = menusToCheck.front();
|
||||
menusToCheck.pop();
|
||||
|
||||
if (visitedMenus.find(currentMenuId) != visitedMenus.end())
|
||||
continue;
|
||||
|
||||
visitedMenus.insert(currentMenuId);
|
||||
|
||||
GossipMenuItemsMapBounds menuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(currentMenuId);
|
||||
|
||||
if (menuItemBounds.first == menuItemBounds.second && currentMenuId != 0)
|
||||
continue;
|
||||
|
||||
for (auto itr = menuItemBounds.first; itr != menuItemBounds.second; ++itr)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(this), const_cast<Creature*>(creature), itr->second.Conditions))
|
||||
continue;
|
||||
|
||||
if (itr->second.OptionType == GOSSIP_OPTION_VENDOR)
|
||||
return true;
|
||||
else if (itr->second.ActionMenuID)
|
||||
{
|
||||
GossipMenusMapBounds menuBounds = sObjectMgr->GetGossipMenusMapBounds(itr->second.ActionMenuID);
|
||||
bool menuAccessible = false;
|
||||
|
||||
if (menuBounds.first == menuBounds.second)
|
||||
menuAccessible = true;
|
||||
else
|
||||
{
|
||||
for (auto menuItr = menuBounds.first; menuItr != menuBounds.second; ++menuItr)
|
||||
if (sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(this), const_cast<Creature*>(creature), menuItr->second.Conditions))
|
||||
{
|
||||
menuAccessible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (menuAccessible)
|
||||
menusToCheck.push(itr->second.ActionMenuID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Player::CanSeeVendor(Creature const* creature) const
|
||||
{
|
||||
if (!creature->HasNpcFlag(UNIT_NPC_FLAG_VENDOR))
|
||||
@@ -14371,9 +14433,11 @@ bool Player::CanSeeVendor(Creature const* creature) const
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(creature->GetEntry(), 0);
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(this), const_cast<Creature*>(creature), conditions))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 const menuId = creature->GetCreatureTemplate()->GossipMenuId;
|
||||
if (!AnyVendorOptionAvailable(menuId, creature))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "TradeData.h"
|
||||
#include "Unit.h"
|
||||
#include "WorldSession.h"
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -2548,7 +2549,9 @@ public:
|
||||
//bool isActiveObject() const { return true; }
|
||||
bool CanSeeSpellClickOn(Creature const* creature) const;
|
||||
[[nodiscard]] bool CanSeeVendor(Creature const* creature) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool AnyVendorOptionAvailable(uint32 menuId, Creature const* creature) const;
|
||||
public:
|
||||
[[nodiscard]] uint32 GetChampioningFaction() const { return m_ChampioningFaction; }
|
||||
void SetChampioningFaction(uint32 faction) { m_ChampioningFaction = faction; }
|
||||
Spell* m_spellModTakingSpell;
|
||||
|
||||
@@ -20791,7 +20791,10 @@ void Unit::PatchValuesUpdate(ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPoi
|
||||
appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
|
||||
|
||||
if (!target->CanSeeVendor(creature))
|
||||
{
|
||||
appendValue &= ~UNIT_NPC_FLAG_REPAIR;
|
||||
appendValue &= ~UNIT_NPC_FLAG_VENDOR_MASK;
|
||||
}
|
||||
|
||||
if (!creature->IsValidTrainerForPlayer(target, &appendValue))
|
||||
appendValue &= ~UNIT_NPC_FLAG_TRAINER;
|
||||
|
||||
Reference in New Issue
Block a user