diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.cpp | 56 | ||||
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 9 |
4 files changed, 67 insertions, 6 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index b0a466148fb..1dc6797ddbc 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -472,6 +472,7 @@ uint32 Condition::GetMaxAvailableConditionTargets() case CONDITION_SOURCE_TYPE_GOSSIP_MENU: case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: + case CONDITION_SOURCE_TYPE_NPC_VENDOR: return 2; default: return 1; @@ -622,7 +623,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL || sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET || sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || - sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT); + sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || + sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR); } bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const @@ -649,7 +651,6 @@ ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType return spellCond; } - ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) { ConditionList cond; @@ -698,6 +699,22 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32 return cond; } +ConditionList ConditionMgr::GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId) +{ + ConditionList cond; + CreatureSpellConditionContainer::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId); + if (itr != NpcVendorConditionContainerStore.end()) + { + ConditionTypeContainer::const_iterator i = (*itr).second.find(itemId); + if (i != (*itr).second.end()) + { + cond = (*i).second; + sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForNpcVendorEvent: found conditions for creature entry %u item %u", creatureId, itemId); + } + } + return cond; +} + void ConditionMgr::LoadConditions(bool isReload) { uint32 oldMSTime = getMSTime(); @@ -921,6 +938,13 @@ void ConditionMgr::LoadConditions(bool isReload) ++count; continue; } + case CONDITION_SOURCE_TYPE_NPC_VENDOR: + { + NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond); + valid = true; + ++count; + continue; + } default: break; } @@ -1412,6 +1436,21 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) return false; } break; + case CONDITION_SOURCE_TYPE_NPC_VENDOR: + { + if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) + { + sLog->outError(LOG_FILTER_SQL, "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + return false; + } + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry); + if (!itemTemplate) + { + sLog->outError(LOG_FILTER_SQL, "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry); + return false; + } + break; + } case CONDITION_SOURCE_TYPE_GOSSIP_MENU: case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: @@ -1975,6 +2014,19 @@ void ConditionMgr::Clean() SpellClickEventConditionStore.clear(); + for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr) + { + for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it) + { + for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i) + delete *i; + it->second.clear(); + } + itr->second.clear(); + } + + NpcVendorConditionContainerStore.clear(); + // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;) for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr) delete *itr; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 0adf44a2d5a..828a818a561 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -127,7 +127,8 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20, CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21, CONDITION_SOURCE_TYPE_SMART_EVENT = 22, - CONDITION_SOURCE_TYPE_MAX = 23 //MAX + CONDITION_SOURCE_TYPE_NPC_VENDOR = 23, + CONDITION_SOURCE_TYPE_MAX = 24 // MAX }; enum ComparisionType @@ -215,6 +216,7 @@ typedef std::list<Condition*> ConditionList; typedef std::map<uint32, ConditionList> ConditionTypeContainer; typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer; typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer; +typedef std::map<uint32, ConditionTypeContainer> NpcVendorConditionContainer; typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer; typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references @@ -242,6 +244,7 @@ class ConditionMgr ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType); ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId); + ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 spellId); private: bool isSourceTypeValid(Condition* cond); @@ -258,6 +261,7 @@ class ConditionMgr ConditionReferenceContainer ConditionReferenceStore; CreatureSpellConditionContainer VehicleSpellConditionStore; CreatureSpellConditionContainer SpellClickEventConditionStore; + NpcVendorConditionContainer NpcVendorConditionContainerStore; SmartEventConditionContainer SmartEventConditionStore; }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e6d264d46cf..3a562ca09b1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21016,7 +21016,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 if (count < 1) count = 1; // cheating attempt - if (slot > MAX_BAG_SIZE && slot !=NULL_SLOT) + if (slot > MAX_BAG_SIZE && slot != NULL_SLOT) return false; if (!isAlive()) diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 17d1e31c399..523a1b9453e 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -538,9 +538,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData) // special case at auto sell (sell all) if (count == 0) - { count = pItem->GetCount(); - } else { // prevent sell more items that exist in stack (possible only not from client) @@ -779,6 +777,13 @@ void WorldSession::SendListInventory(uint64 vendorGuid) if (!_player->isGameMaster() && !leftInStock) continue; + ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item); + if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions)) + { + sLog->outError(LOG_FILTER_CONDITIONSYS, "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), item->item); + continue; + } + ++count; // reputation discount |