TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ConditionMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ConditionMgr.h"
19#include "AchievementMgr.h"
20#include "DBCStores.h"
21#include "DatabaseEnv.h"
22#include "GameEventMgr.h"
23#include "GameObject.h"
24#include "InstanceScript.h"
25#include "Log.h"
26#include "LootMgr.h"
27#include "Map.h"
28#include "ObjectMgr.h"
29#include "Player.h"
30#include "Pet.h"
31#include "ReputationMgr.h"
32#include "ScriptMgr.h"
33#include "SpellAuras.h"
34#include "SpellMgr.h"
35#include "World.h"
36
38{
39 "None",
40 "Creature Loot",
41 "Disenchant Loot",
42 "Fishing Loot",
43 "GameObject Loot",
44 "Item Loot",
45 "Mail Loot",
46 "Milling Loot",
47 "Pickpocketing Loot",
48 "Prospecting Loot",
49 "Reference Loot",
50 "Skinning Loot",
51 "Spell Loot",
52 "Spell Impl. Target",
53 "Gossip Menu",
54 "Gossip Menu Option",
55 "Creature Vehicle",
56 "Spell Expl. Target",
57 "Spell Click Event",
58 "Quest Accept",
59 "Quest Show Mark",
60 "Vehicle Spell",
61 "SmartScript",
62 "Npc Vendor",
63 "Spell Proc",
64 "Terrain Swap",
65 "Phase"
66};
67
69{
70 { "None", false, false, false },
71 { "Aura", true, true, true },
72 { "Item Stored", true, true, true },
73 { "Item Equipped", true, false, false },
74 { "Zone", true, false, false },
75 { "Reputation", true, true, false },
76 { "Team", true, false, false },
77 { "Skill", true, true, false },
78 { "Quest Rewarded", true, false, false },
79 { "Quest Taken", true, false, false },
80 { "Drunken", true, false, false },
81 { "WorldState", true, true, false },
82 { "Active Event", true, false, false },
83 { "Instance Info", true, true, true },
84 { "Quest None", true, false, false },
85 { "Class", true, false, false },
86 { "Race", true, false, false },
87 { "Achievement", true, false, false },
88 { "Title", true, false, false },
89 { "SpawnMask", true, false, false },
90 { "Gender", true, false, false },
91 { "Unit State", true, false, false },
92 { "Map", true, false, false },
93 { "Area", true, false, false },
94 { "CreatureType", true, false, false },
95 { "Spell Known", true, false, false },
96 { "PhaseMask", true, false, false },
97 { "Level", true, true, false },
98 { "Quest Completed", true, false, false },
99 { "Near Creature", true, true, true },
100 { "Near GameObject", true, true, false },
101 { "Object Entry or Guid", true, true, true },
102 { "Object TypeMask", true, false, false },
103 { "Relation", true, true, false },
104 { "Reaction", true, true, false },
105 { "Distance", true, true, true },
106 { "Alive", false, false, false },
107 { "Health Value", true, true, false },
108 { "Health Pct", true, true, false },
109 { "Realm Achievement", true, false, false },
110 { "In Water", false, false, false },
111 { "Terrain Swap", false, false, false },
112 { "Sit/stand state", true, true, false },
113 { "Daily Quest Completed", true, false, false },
114 { "Charmed", false, false, false },
115 { "Pet type", true, false, false },
116 { "On Taxi", false, false, false },
117 { "Quest state mask", true, true, false },
118 { "Quest objective progress", true, true, true },
119 { "Map difficulty", true, false, false },
120 { "Is Gamemaster", true, false, false },
121 { "Object Entry or Guid", true, true, true },
122 { "Object TypeMask", true, false, false }
123};
124
125// Checks if object meets the condition
126// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
128{
130 WorldObject* object = sourceInfo.mConditionTargets[ConditionTarget];
131 // object not present, return false
132 if (!object)
133 {
134 TC_LOG_DEBUG("condition", "Condition object not found for {}", ToString());
135 return false;
136 }
137 bool condMeets = false;
138 switch (ConditionType)
139 {
140 case CONDITION_NONE:
141 condMeets = true; // empty condition, always met
142 break;
143 case CONDITION_AURA:
144 {
145 if (Unit* unit = object->ToUnit())
146 condMeets = unit->HasAuraEffect(ConditionValue1, ConditionValue2);
147 break;
148 }
149 case CONDITION_ITEM:
150 {
151 if (Player* player = object->ToPlayer())
152 {
153 // don't allow 0 items (it's checked during table load)
155 bool checkBank = ConditionValue3 ? true : false;
156 condMeets = player->HasItemCount(ConditionValue1, ConditionValue2, checkBank);
157 }
158 break;
159 }
161 {
162 if (Player* player = object->ToPlayer())
163 condMeets = player->HasItemOrGemWithIdEquipped(ConditionValue1, 1);
164 break;
165 }
166 case CONDITION_ZONEID:
167 condMeets = object->GetZoneId() == ConditionValue1;
168 break;
170 {
171 if (Player* player = object->ToPlayer())
172 {
173 if (FactionEntry const* faction = sFactionStore.LookupEntry(ConditionValue1))
174 condMeets = (ConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction))) != 0;
175 }
176 break;
177 }
179 {
180 if (Player* player = object->ToPlayer())
181 condMeets = player->HasAchieved(ConditionValue1);
182 break;
183 }
184 case CONDITION_TEAM:
185 {
186 if (Player* player = object->ToPlayer())
187 condMeets = player->GetTeam() == ConditionValue1;
188 break;
189 }
190 case CONDITION_CLASS:
191 {
192 if (Unit* unit = object->ToUnit())
193 condMeets = (unit->GetClassMask() & ConditionValue1) != 0;
194 break;
195 }
196 case CONDITION_RACE:
197 {
198 if (Unit* unit = object->ToUnit())
199 condMeets = (unit->GetRaceMask() & ConditionValue1) != 0;
200 break;
201 }
202 case CONDITION_GENDER:
203 {
204 if (Player* player = object->ToPlayer())
205 condMeets = player->GetNativeGender() == Gender(ConditionValue1);
206 break;
207 }
208 case CONDITION_SKILL:
209 {
210 if (Player* player = object->ToPlayer())
211 condMeets = player->HasSkill(ConditionValue1) && player->GetBaseSkillValue(ConditionValue1) >= ConditionValue2;
212 break;
213 }
215 {
216 if (Player* player = object->ToPlayer())
217 condMeets = player->GetQuestRewardStatus(ConditionValue1);
218 break;
219 }
221 {
222 if (Player* player = object->ToPlayer())
223 {
224 QuestStatus status = player->GetQuestStatus(ConditionValue1);
225 condMeets = (status == QUEST_STATUS_INCOMPLETE);
226 }
227 break;
228 }
230 {
231 if (Player* player = object->ToPlayer())
232 {
233 QuestStatus status = player->GetQuestStatus(ConditionValue1);
234 condMeets = (status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(ConditionValue1));
235 }
236 break;
237 }
239 {
240 if (Player* player = object->ToPlayer())
241 {
242 QuestStatus status = player->GetQuestStatus(ConditionValue1);
243 condMeets = (status == QUEST_STATUS_NONE);
244 }
245 break;
246 }
248 condMeets = sGameEventMgr->IsActiveEvent(ConditionValue1);
249 break;
251 {
252 Map* map = object->GetMap();
253 if (map->IsDungeon())
254 {
255 if (InstanceScript const* instance = ((InstanceMap*)map)->GetInstanceScript())
256 {
257 switch (ConditionValue3)
258 {
260 condMeets = instance->GetData(ConditionValue1) == ConditionValue2;
261 break;
263 condMeets = instance->GetGuidData(ConditionValue1) == ObjectGuid(uint64(ConditionValue2));
264 break;
266 condMeets = instance->GetBossState(ConditionValue1) == EncounterState(ConditionValue2);
267 break;
269 condMeets = instance->GetData64(ConditionValue1) == ConditionValue2;
270 break;
271 }
272 }
273 }
274 break;
275 }
276 case CONDITION_MAPID:
277 condMeets = object->GetMapId() == ConditionValue1;
278 break;
279 case CONDITION_AREAID:
280 condMeets = object->GetAreaId() == ConditionValue1;
281 break;
282 case CONDITION_SPELL:
283 {
284 if (Player* player = object->ToPlayer())
285 condMeets = player->HasSpell(ConditionValue1);
286 break;
287 }
288 case CONDITION_LEVEL:
289 {
290 if (Unit* unit = object->ToUnit())
291 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), static_cast<uint32>(unit->GetLevel()), ConditionValue1);
292 break;
293 }
295 {
296 if (Player* player = object->ToPlayer())
297 condMeets = (uint32)Player::GetDrunkenstateByValue(player->GetDrunkValue()) >= ConditionValue1;
298 break;
299 }
301 {
302 condMeets = object->FindNearestCreature(ConditionValue1, (float)ConditionValue2, bool(!ConditionValue3)) != nullptr;
303 break;
304 }
306 {
307 condMeets = object->FindNearestGameObject(ConditionValue1, (float)ConditionValue2) != nullptr;
308 break;
309 }
311 {
312 if (uint32(object->GetTypeId()) == ConditionValue1)
313 {
314 condMeets = !ConditionValue2 || (object->GetEntry() == ConditionValue2);
315
316 if (ConditionValue3)
317 {
318 switch (object->GetTypeId())
319 {
320 case TYPEID_UNIT:
321 condMeets &= object->ToCreature()->GetSpawnId() == ConditionValue3;
322 break;
324 condMeets &= object->ToGameObject()->GetSpawnId() == ConditionValue3;
325 break;
326 default:
327 break;
328 }
329 }
330 }
331 break;
332 }
334 {
335 condMeets = object->isType(ConditionValue1);
336 break;
337 }
339 {
340 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
341 {
342 Unit* toUnit = toObject->ToUnit();
343 Unit* unit = object->ToUnit();
344 if (toUnit && unit)
345 {
346 switch (static_cast<RelationType>(ConditionValue2))
347 {
348 case RELATION_SELF:
349 condMeets = unit == toUnit;
350 break;
352 condMeets = unit->IsInPartyWith(toUnit);
353 break;
355 condMeets = unit->IsInRaidWith(toUnit);
356 break;
358 condMeets = unit->GetOwnerGUID() == toUnit->GetGUID();
359 break;
361 condMeets = unit->IsOnVehicle(toUnit);
362 break;
364 condMeets = unit->GetCreatorGUID() == toUnit->GetGUID();
365 break;
366 default:
367 break;
368 }
369 }
370 }
371 break;
372 }
374 {
375 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
376 {
377 Unit* toUnit = toObject->ToUnit();
378 Unit* unit = object->ToUnit();
379 if (toUnit && unit)
380 condMeets = ((1 << unit->GetReactionTo(toUnit)) & ConditionValue2) != 0;
381 }
382 break;
383 }
385 {
386 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
387 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue3), object->GetDistance(toObject), static_cast<float>(ConditionValue2));
388 break;
389 }
390 case CONDITION_ALIVE:
391 {
392 if (Unit* unit = object->ToUnit())
393 condMeets = unit->IsAlive();
394 break;
395 }
396 case CONDITION_HP_VAL:
397 {
398 if (Unit* unit = object->ToUnit())
399 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), unit->GetHealth(), static_cast<uint32>(ConditionValue1));
400 break;
401 }
402 case CONDITION_HP_PCT:
403 {
404 if (Unit* unit = object->ToUnit())
405 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), unit->GetHealthPct(), static_cast<float>(ConditionValue1));
406 break;
407 }
409 {
410 condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1);
411 break;
412 }
414 {
415 condMeets = (object->GetPhaseMask() & ConditionValue1) != 0;
416 break;
417 }
418 case CONDITION_TITLE:
419 {
420 if (Player* player = object->ToPlayer())
421 condMeets = player->HasTitle(ConditionValue1);
422 break;
423 }
425 {
426 condMeets = ((1 << object->GetMap()->GetSpawnMode()) & ConditionValue1) != 0;
427 break;
428 }
430 {
431 if (Unit* unit = object->ToUnit())
432 condMeets = unit->HasUnitState(ConditionValue1);
433 break;
434 }
436 {
437 if (Creature* creature = object->ToCreature())
438 condMeets = creature->GetCreatureTemplate()->type == ConditionValue1;
439 break;
440 }
442 {
443 AchievementEntry const* achievement = sAchievementStore.LookupEntry(ConditionValue1);
444 if (achievement && sAchievementMgr->IsRealmCompleted(achievement))
445 condMeets = true;
446 break;
447 }
449 {
450 if (Unit* unit = object->ToUnit())
451 condMeets = unit->IsInWater();
452 break;
453 }
455 {
456 if (Unit* unit = object->ToUnit())
457 {
458 if (ConditionValue1 == 0)
459 condMeets = (unit->GetStandState() == ConditionValue2);
460 else if (ConditionValue2 == 0)
461 condMeets = unit->IsStandState();
462 else if (ConditionValue2 == 1)
463 condMeets = unit->IsSitState();
464 }
465 break;
466 }
468 {
469 if (Player* player = object->ToPlayer())
470 condMeets = player->IsDailyQuestDone(ConditionValue1);
471 break;
472 }
474 {
475 if (Unit* unit = object->ToUnit())
476 condMeets = unit->IsCharmed();
477 break;
478 }
480 {
481 if (Player* player = object->ToPlayer())
482 if (Pet* pet = player->GetPet())
483 condMeets = (((1 << pet->getPetType()) & ConditionValue1) != 0);
484 break;
485 }
486 case CONDITION_TAXI:
487 {
488 if (Player* player = object->ToPlayer())
489 condMeets = player->IsInFlight();
490 break;
491 }
493 {
494 if (Player* player = object->ToPlayer())
495 {
496 if (
497 ((ConditionValue2 & (1 << QUEST_STATUS_NONE)) && (player->GetQuestStatus(ConditionValue1) == QUEST_STATUS_NONE)) ||
498 ((ConditionValue2 & (1 << QUEST_STATUS_COMPLETE)) && (player->GetQuestStatus(ConditionValue1) == QUEST_STATUS_COMPLETE)) ||
499 ((ConditionValue2 & (1 << QUEST_STATUS_INCOMPLETE)) && (player->GetQuestStatus(ConditionValue1) == QUEST_STATUS_INCOMPLETE)) ||
500 ((ConditionValue2 & (1 << QUEST_STATUS_FAILED)) && (player->GetQuestStatus(ConditionValue1) == QUEST_STATUS_FAILED)) ||
501 ((ConditionValue2 & (1 << QUEST_STATUS_REWARDED)) && player->GetQuestRewardStatus(ConditionValue1))
502 )
503 condMeets = true;
504 }
505 break;
506 }
508 {
509 if (Player* player = object->ToPlayer())
510 {
511 const Quest* quest = ASSERT_NOTNULL(sObjectMgr->GetQuestTemplate(ConditionValue1));
512 uint16 log_slot = player->FindQuestSlot(quest->GetQuestId());
513 if (log_slot >= MAX_QUEST_LOG_SIZE)
514 break;
515 if (player->GetQuestSlotCounter(log_slot, ConditionValue2) == ConditionValue3)
516 condMeets = true;
517 }
518 break;
519 }
521 {
522 condMeets = object->GetMap()->GetDifficulty() == ConditionValue1;
523 break;
524 }
526 {
527 if (Player* player = object->ToPlayer())
528 {
529 if (ConditionValue1 == 1)
530 condMeets = player->CanBeGameMaster();
531 else
532 condMeets = player->IsGameMaster();
533 }
534 break;
535 }
536 default:
537 condMeets = false;
538 break;
539 }
540
542 condMeets = !condMeets;
543
544 if (!condMeets)
545 sourceInfo.mLastFailedCondition = this;
546
547 return condMeets && sScriptMgr->OnConditionCheck(this, sourceInfo); // Returns true by default.;
548}
549
551{
552 // build mask of types for which condition can return true
553 // this is used for speeding up gridsearches
555 return (GRID_MAP_TYPE_MASK_ALL);
556 uint32 mask = 0;
557 switch (ConditionType)
558 {
559 case CONDITION_NONE:
561 break;
562 case CONDITION_AURA:
564 break;
565 case CONDITION_ITEM:
567 break;
570 break;
571 case CONDITION_ZONEID:
573 break;
576 break;
579 break;
580 case CONDITION_TEAM:
582 break;
583 case CONDITION_CLASS:
585 break;
586 case CONDITION_RACE:
588 break;
589 case CONDITION_SKILL:
591 break;
594 break;
597 break;
600 break;
603 break;
606 break;
609 break;
610 case CONDITION_MAPID:
612 break;
613 case CONDITION_AREAID:
615 break;
616 case CONDITION_SPELL:
618 break;
619 case CONDITION_LEVEL:
621 break;
624 break;
627 break;
630 break;
632 switch (ConditionValue1)
633 {
634 case TYPEID_UNIT:
636 break;
637 case TYPEID_PLAYER:
639 break;
642 break;
643 case TYPEID_CORPSE:
645 break;
646 default:
647 break;
648 }
649 break;
659 break;
662 break;
665 break;
668 break;
669 case CONDITION_ALIVE:
671 break;
672 case CONDITION_HP_VAL:
674 break;
675 case CONDITION_HP_PCT:
677 break;
680 break;
683 break;
684 case CONDITION_TITLE:
686 break;
689 break;
690 case CONDITION_GENDER:
692 break;
695 break;
698 break;
701 break;
704 break;
707 break;
710 break;
713 break;
716 break;
717 case CONDITION_TAXI:
719 break;
722 break;
725 break;
728 break;
731 break;
732 default:
733 ABORT_MSG("Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
734 break;
735 }
736 return mask;
737}
738
740{
741 // returns number of targets which are available for given source type
742 switch (SourceType)
743 {
754 return 2;
755 default:
756 return 1;
757 }
758}
759
760std::string Condition::ToString(bool ext /*= false*/) const
761{
762 std::ostringstream ss;
763 ss << "[Condition ";
764 ss << "SourceType: " << SourceType;
767 else
768 ss << " (Unknown)";
770 ss << ", SourceGroup: " << SourceGroup;
771 ss << ", SourceEntry: " << SourceEntry;
773 ss << ", SourceId: " << SourceId;
774
775 if (ext)
776 {
777 ss << ", ConditionType: " << ConditionType;
780 else
781 ss << " (Unknown)";
782 }
783
784 ss << "]";
785 return ss.str();
786}
787
789
791{
792 Clean();
793}
794
796{
797 if (conditions.empty())
799 // groupId, typeMask
800 std::map<uint32, uint32> elseGroupSearcherTypeMasks;
801 for (ConditionContainer::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
802 {
803 // no point of having not loaded conditions in list
804 ASSERT((*i)->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
805 std::map<uint32, uint32>::const_iterator itr = elseGroupSearcherTypeMasks.find((*i)->ElseGroup);
806 // group not filled yet, fill with widest mask possible
807 if (itr == elseGroupSearcherTypeMasks.end())
808 elseGroupSearcherTypeMasks[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
809 // no point of checking anymore, empty mask
810 else if (!itr->second)
811 continue;
812
813 if ((*i)->ReferenceId) // handle reference
814 {
815 ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
816 ASSERT(ref != ConditionReferenceStore.end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
817 elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
818 }
819 else // handle normal condition
820 {
821 // object will match conditions in one ElseGroupStore only when it matches all of them
822 // so, let's find a smallest possible mask which satisfies all conditions
823 elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
824 }
825 }
826 // object will match condition when one of the checks in ElseGroupStore is matching
827 // so, let's include all possible masks
828 uint32 mask = 0;
829 for (std::map<uint32, uint32>::const_iterator i = elseGroupSearcherTypeMasks.begin(); i != elseGroupSearcherTypeMasks.end(); ++i)
830 mask |= i->second;
831
832 return mask;
833}
834
836{
837 // groupId, groupCheckPassed
838 std::map<uint32, bool> elseGroupStore;
839 for (Condition const* condition : conditions)
840 {
841 TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList {} val1: {}", condition->ToString(), condition->ConditionValue1);
842 if (condition->isLoaded())
843 {
845 std::map<uint32, bool>::const_iterator itr = elseGroupStore.find(condition->ElseGroup);
847 if (itr == elseGroupStore.end())
848 elseGroupStore[condition->ElseGroup] = true;
849 else if (!(*itr).second)
850 continue;
851
852 if (condition->ReferenceId)//handle reference
853 {
854 ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(condition->ReferenceId);
855 if (ref != ConditionReferenceStore.end())
856 {
857 if (!IsObjectMeetToConditionList(sourceInfo, ref->second))
858 elseGroupStore[condition->ElseGroup] = false;
859 }
860 else
861 {
862 TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList {} Reference template -{} not found",
863 condition->ToString(), condition->ReferenceId); // checked at loading, should never happen
864 }
865
866 }
867 else //handle normal condition
868 {
869 if (!condition->Meets(sourceInfo))
870 elseGroupStore[condition->ElseGroup] = false;
871 }
872 }
873 }
874 for (std::map<uint32, bool>::const_iterator i = elseGroupStore.begin(); i != elseGroupStore.end(); ++i)
875 if (i->second)
876 return true;
877
878 return false;
879}
880
882{
884 return IsObjectMeetToConditions(srcInfo, conditions);
885}
886
888{
889 ConditionSourceInfo srcInfo = ConditionSourceInfo(object1, object2);
890 return IsObjectMeetToConditions(srcInfo, conditions);
891}
892
894{
895 if (conditions.empty())
896 return true;
897
898 TC_LOG_DEBUG("condition", "ConditionMgr::IsObjectMeetToConditions");
899 return IsObjectMeetToConditionList(sourceInfo, conditions);
900}
901
903{
904 return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
916 sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
921 sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
923}
924
926{
927 return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
928}
929
931{
932 if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
933 {
934 ConditionsByEntryMap::const_iterator i = ConditionStore[sourceType].find(entry);
935 if (i != ConditionStore[sourceType].end())
936 {
937 TC_LOG_DEBUG("condition", "GetConditionsForNotGroupedEntry: found conditions for type {} and entry {}", uint32(sourceType), entry);
938 return IsObjectMeetToConditions(sourceInfo, i->second);
939 }
940 }
941
942 return true;
943}
944
945bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, WorldObject* target0, WorldObject* target1 /*= nullptr*/, WorldObject* target2 /*= nullptr*/) const
946{
947 ConditionSourceInfo conditionSource(target0, target1, target2);
948 return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource);
949}
950
952{
953 if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
954 if (ConditionStore[sourceType].find(entry) != ConditionStore[sourceType].end())
955 return true;
956
957 return false;
958}
959
961{
962 ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
963 if (itr != SpellClickEventConditionStore.end())
964 {
965 ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
966 if (i != itr->second.end())
967 {
968 TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
969 ConditionSourceInfo sourceInfo(clicker, target);
970 return IsObjectMeetToConditions(sourceInfo, i->second);
971 }
972 }
973 return true;
974}
975
977{
978 ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
979 if (itr != SpellClickEventConditionStore.end())
980 {
981 ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
982 if (i != itr->second.end())
983 {
984 TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
985 return &i->second;
986 }
987 }
988 return nullptr;
989}
990
991bool ConditionMgr::IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player* player, Unit* vehicle) const
992{
993 ConditionEntriesByCreatureIdMap::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
994 if (itr != VehicleSpellConditionStore.end())
995 {
996 ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
997 if (i != itr->second.end())
998 {
999 TC_LOG_DEBUG("condition", "GetConditionsForVehicleSpell: found conditions for Vehicle entry {} spell {}", creatureId, spellId);
1000 ConditionSourceInfo sourceInfo(player, vehicle);
1001 return IsObjectMeetToConditions(sourceInfo, i->second);
1002 }
1003 }
1004 return true;
1005}
1006
1007bool ConditionMgr::IsObjectMeetingSmartEventConditions(int32 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const
1008{
1009 SmartEventConditionContainer::const_iterator itr = SmartEventConditionStore.find(std::make_pair(entryOrGuid, sourceType));
1010 if (itr != SmartEventConditionStore.end())
1011 {
1012 ConditionsByEntryMap::const_iterator i = itr->second.find(eventId + 1);
1013 if (i != itr->second.end())
1014 {
1015 TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid {} eventId {}", entryOrGuid, eventId);
1016 ConditionSourceInfo sourceInfo(unit, baseObject);
1017 return IsObjectMeetToConditions(sourceInfo, i->second);
1018 }
1019 }
1020 return true;
1021}
1022
1024{
1025 ConditionEntriesByCreatureIdMap::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId);
1026 if (itr != NpcVendorConditionContainerStore.end())
1027 {
1028 ConditionsByEntryMap::const_iterator i = (*itr).second.find(itemId);
1029 if (i != (*itr).second.end())
1030 {
1031 TC_LOG_DEBUG("condition", "GetConditionsForNpcVendorEvent: found conditions for creature entry {} item {}", creatureId, itemId);
1032 ConditionSourceInfo sourceInfo(player, vendor);
1033 return IsObjectMeetToConditions(sourceInfo, i->second);
1034 }
1035 }
1036 return true;
1037}
1038
1040{
1042}
1043
1045{
1046 static ConditionMgr instance;
1047 return &instance;
1048}
1049
1051{
1052 uint32 oldMSTime = getMSTime();
1053
1054 Clean();
1055
1056 //must clear all custom handled cases (groupped types) before reload
1057 if (isReload)
1058 {
1059 TC_LOG_INFO("misc", "Reseting Loot Conditions...");
1072
1073 TC_LOG_INFO("misc", "Re-Loading `gossip_menu` Table for Conditions!");
1074 sObjectMgr->LoadGossipMenu();
1075
1076 TC_LOG_INFO("misc", "Re-Loading `gossip_menu_option` Table for Conditions!");
1077 sObjectMgr->LoadGossipMenuItems();
1078 sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
1079 }
1080
1081 QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
1082 " ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName FROM conditions");
1083
1084 if (!result)
1085 {
1086 TC_LOG_INFO("server.loading", ">> Loaded 0 conditions. DB table `conditions` is empty!");
1087 return;
1088 }
1089
1090 uint32 count = 0;
1091
1092 do
1093 {
1094 Field* fields = result->Fetch();
1095
1096 Condition* cond = new Condition();
1097 int32 iSourceTypeOrReferenceId = fields[0].GetInt32();
1098 cond->SourceGroup = fields[1].GetUInt32();
1099 cond->SourceEntry = fields[2].GetInt32();
1100 cond->SourceId = fields[3].GetInt32();
1101 cond->ElseGroup = fields[4].GetUInt32();
1102 int32 iConditionTypeOrReference = fields[5].GetInt32();
1103 cond->ConditionTarget = fields[6].GetUInt8();
1104 cond->ConditionValue1 = fields[7].GetUInt32();
1105 cond->ConditionValue2 = fields[8].GetUInt32();
1106 cond->ConditionValue3 = fields[9].GetUInt32();
1107 cond->NegativeCondition = fields[10].GetBool();
1108 cond->ErrorType = fields[11].GetUInt32();
1109 cond->ErrorTextId = fields[12].GetUInt32();
1110 cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
1111
1112 if (iConditionTypeOrReference >= 0)
1113 cond->ConditionType = ConditionTypes(iConditionTypeOrReference);
1114
1115 if (iSourceTypeOrReferenceId >= 0)
1116 cond->SourceType = ConditionSourceType(iSourceTypeOrReferenceId);
1117
1118 if (iConditionTypeOrReference < 0)//it has a reference
1119 {
1120 if (iConditionTypeOrReference == iSourceTypeOrReferenceId)//self referencing, skip
1121 {
1122 TC_LOG_ERROR("sql.sql", "Condition reference {} is referencing self, skipped", iSourceTypeOrReferenceId);
1123 delete cond;
1124 continue;
1125 }
1126 cond->ReferenceId = uint32(abs(iConditionTypeOrReference));
1127
1128 char const* rowType = "reference template";
1129 if (iSourceTypeOrReferenceId >= 0)
1130 rowType = "reference";
1131 //check for useless data
1132 if (cond->ConditionTarget)
1133 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in ConditionTarget ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionTarget);
1134 if (cond->ConditionValue1)
1135 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value1 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue1);
1136 if (cond->ConditionValue2)
1137 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value2 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue2);
1138 if (cond->ConditionValue3)
1139 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value3 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue3);
1140 if (cond->NegativeCondition)
1141 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in NegativeCondition ({})!", rowType, iSourceTypeOrReferenceId, cond->NegativeCondition);
1142 if (cond->SourceGroup && iSourceTypeOrReferenceId < 0)
1143 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in SourceGroup ({})!", rowType, iSourceTypeOrReferenceId, cond->SourceGroup);
1144 if (cond->SourceEntry && iSourceTypeOrReferenceId < 0)
1145 TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in SourceEntry ({})!", rowType, iSourceTypeOrReferenceId, cond->SourceEntry);
1146 }
1147 else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType
1148 {
1149 delete cond;
1150 continue;
1151 }
1152
1153 if (iSourceTypeOrReferenceId < 0)//it is a reference template
1154 {
1155 ConditionReferenceStore[std::abs(iSourceTypeOrReferenceId)].push_back(cond);//add to reference storage
1156 ++count;
1157 continue;
1158 }//end of reference templates
1159
1160 //if not a reference and SourceType is invalid, skip
1161 if (iConditionTypeOrReference >= 0 && !isSourceTypeValid(cond))
1162 {
1163 delete cond;
1164 continue;
1165 }
1166
1167 //Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
1168 if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
1169 {
1170 TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceGroup = {}!", cond->ToString(), cond->SourceGroup);
1171 delete cond;
1172 continue;
1173 }
1174 if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
1175 {
1176 TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceId = {}!", cond->ToString(), cond->SourceId);
1177 delete cond;
1178 continue;
1179 }
1180
1181 if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL)
1182 {
1183 TC_LOG_ERROR("sql.sql", "{} can't have ErrorType ({}), set to 0!", cond->ToString(), cond->ErrorType);
1184 cond->ErrorType = 0;
1185 }
1186
1187 if (cond->ErrorTextId && !cond->ErrorType)
1188 {
1189 TC_LOG_ERROR("sql.sql", "{} has any ErrorType, ErrorTextId ({}) is set, set to 0!", cond->ToString(), cond->ErrorTextId);
1190 cond->ErrorTextId = 0;
1191 }
1192
1193 if (cond->SourceGroup)
1194 {
1195 bool valid = false;
1196 // handle grouped conditions
1197 switch (cond->SourceType)
1198 {
1201 break;
1204 break;
1207 break;
1210 break;
1213 break;
1216 break;
1219 break;
1222 break;
1225 break;
1228 break;
1231 break;
1234 break;
1236 valid = addToGossipMenus(cond);
1237 break;
1239 valid = addToGossipMenuItems(cond);
1240 break;
1242 {
1243 SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
1244 if (cond->ConditionType == CONDITION_AURA)
1246 valid = true;
1247 ++count;
1248 continue; // do not add to m_AllocatedMemory to avoid double deleting
1249 }
1252 break;
1254 {
1255 VehicleSpellConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
1256 valid = true;
1257 ++count;
1258 continue; // do not add to m_AllocatedMemory to avoid double deleting
1259 }
1261 {
1263 std::pair<int32, uint32> key = std::make_pair(cond->SourceEntry, cond->SourceId);
1264 SmartEventConditionStore[key][cond->SourceGroup].push_back(cond);
1265 valid = true;
1266 ++count;
1267 continue;
1268 }
1270 {
1271 NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
1272 valid = true;
1273 ++count;
1274 continue;
1275 }
1276 default:
1277 break;
1278 }
1279
1280 if (!valid)
1281 {
1282 TC_LOG_ERROR("sql.sql", "{} Not handled grouped condition.", cond->ToString());
1283 delete cond;
1284 }
1285 else
1286 {
1287 AllocatedMemoryStore.push_back(cond);
1288 ++count;
1289 }
1290 continue;
1291 }
1292
1293 //handle not grouped conditions
1294 //add new Condition to storage based on Type/Entry
1297 ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond);
1298 ++count;
1299 }
1300 while (result->NextRow());
1301
1302 TC_LOG_INFO("server.loading", ">> Loaded {} conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
1303}
1304
1306{
1307 if (!loot)
1308 {
1309 TC_LOG_ERROR("sql.sql", "{} LootTemplate {} not found.", cond->ToString(), cond->SourceGroup);
1310 return false;
1311 }
1312
1313 if (loot->addConditionItem(cond))
1314 return true;
1315
1316 TC_LOG_ERROR("sql.sql", "{} Item {} not found in LootTemplate {}.", cond->ToString(), cond->SourceEntry, cond->SourceGroup);
1317 return false;
1318}
1319
1321{
1322 GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr->GetGossipMenusMapBoundsNonConst(cond->SourceGroup);
1323
1324 if (pMenuBounds.first != pMenuBounds.second)
1325 {
1326 for (GossipMenusContainer::iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr)
1327 {
1328 if ((*itr).second.MenuID == cond->SourceGroup && (*itr).second.TextID == uint32(cond->SourceEntry))
1329 {
1330 (*itr).second.Conditions.push_back(cond);
1331 return true;
1332 }
1333 }
1334 }
1335
1336 TC_LOG_ERROR("sql.sql", "{} GossipMenu {} not found.", cond->ToString(), cond->SourceGroup);
1337 return false;
1338}
1339
1341{
1342 GossipMenuItemsMapBoundsNonConst pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBoundsNonConst(cond->SourceGroup);
1343 if (pMenuItemBounds.first != pMenuItemBounds.second)
1344 {
1345 for (GossipMenuItemsContainer::iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr)
1346 {
1347 if ((*itr).second.MenuID == cond->SourceGroup && (*itr).second.OptionID == uint32(cond->SourceEntry))
1348 {
1349 (*itr).second.Conditions.push_back(cond);
1350 return true;
1351 }
1352 }
1353 }
1354
1355 TC_LOG_ERROR("sql.sql", "{} GossipMenuId {} Item {} not found.", cond->ToString(), cond->SourceGroup, cond->SourceEntry);
1356 return false;
1357}
1358
1360{
1361 uint32 conditionEffMask = cond->SourceGroup;
1362 SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->AssertSpellInfo(cond->SourceEntry));
1363 std::list<uint32> sharedMasks;
1364 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1365 {
1366 // additional checks by condition type
1367 if (conditionEffMask & (1 << spellEffectInfo.EffectIndex))
1368 {
1369 switch (cond->ConditionType)
1370 {
1372 {
1373 uint32 implicitTargetMask = GetTargetFlagMask(spellEffectInfo.TargetA.GetObjectType()) | GetTargetFlagMask(spellEffectInfo.TargetB.GetObjectType());
1374 if ((implicitTargetMask & TARGET_FLAG_UNIT_MASK) && cond->ConditionValue1 != TYPEID_UNIT && cond->ConditionValue1 != TYPEID_PLAYER)
1375 {
1376 TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
1377 "target requires ConditionValue1 to be either TYPEID_UNIT ({}) or TYPEID_PLAYER ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_UNIT), uint32(TYPEID_PLAYER));
1378 return false;
1379 }
1380
1381 if ((implicitTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) && cond->ConditionValue1 != TYPEID_GAMEOBJECT)
1382 {
1383 TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
1384 "target requires ConditionValue1 to be TYPEID_GAMEOBJECT ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_GAMEOBJECT));
1385 return false;
1386 }
1387
1388 if ((implicitTargetMask & TARGET_FLAG_CORPSE_MASK) && cond->ConditionValue1 != TYPEID_CORPSE)
1389 {
1390 TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
1391 "target requires ConditionValue1 to be TYPEID_CORPSE ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_CORPSE));
1392 return false;
1393 }
1394 break;
1395 }
1396 default:
1397 break;
1398 }
1399 }
1400
1401 // check if effect is already a part of some shared mask
1402 auto itr = std::find_if(sharedMasks.begin(), sharedMasks.end(), [&](uint32 mask) { return !!(mask & (1 << spellEffectInfo.EffectIndex)); });
1403 if (itr != sharedMasks.end())
1404 continue;
1405
1406 // build new shared mask with found effect
1407 uint32 sharedMask = 1 << spellEffectInfo.EffectIndex;
1408 ConditionContainer* cmp = spellEffectInfo.ImplicitTargetConditions;
1409 for (size_t effIndex = spellEffectInfo.EffectIndex + 1; effIndex < spellInfo->GetEffects().size(); ++effIndex)
1410 if (spellInfo->GetEffect(SpellEffIndex(effIndex)).ImplicitTargetConditions == cmp)
1411 sharedMask |= 1 << effIndex;
1412
1413 sharedMasks.push_back(sharedMask);
1414 }
1415
1416 for (uint32 effectMask : sharedMasks)
1417 {
1418 // some effect indexes should have same data
1419 if (uint32 commonMask = effectMask & conditionEffMask)
1420 {
1421 size_t firstEffIndex = 0;
1422 for (; firstEffIndex < spellInfo->GetEffects().size(); ++firstEffIndex)
1423 if ((1 << firstEffIndex) & effectMask)
1424 break;
1425
1426 if (firstEffIndex >= spellInfo->GetEffects().size())
1427 return false;
1428
1429 // get shared data
1430 ConditionContainer* sharedList = spellInfo->GetEffect(SpellEffIndex(firstEffIndex)).ImplicitTargetConditions;
1431
1432 // there's already data entry for that sharedMask
1433 if (sharedList)
1434 {
1435 // we have overlapping masks in db
1436 if (conditionEffMask != effectMask)
1437 {
1438 TC_LOG_ERROR("sql.sql", "{} in `condition` table, has incorrect SourceGroup {} (spell effectMask) set - "
1439 "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString(), cond->SourceGroup);
1440 return false;
1441 }
1442 }
1443 // no data for shared mask, we can create new submask
1444 else
1445 {
1446 // add new list, create new shared mask
1447 sharedList = new ConditionContainer();
1448 bool assigned = false;
1449 for (size_t i = firstEffIndex; i < spellInfo->GetEffects().size(); ++i)
1450 {
1451 if ((1 << i) & commonMask)
1452 {
1453 const_cast<SpellEffectInfo&>(spellInfo->GetEffect(SpellEffIndex(i))).ImplicitTargetConditions = sharedList;
1454 assigned = true;
1455 }
1456 }
1457
1458 if (!assigned)
1459 {
1460 delete sharedList;
1461 return false;
1462 }
1463 }
1464 sharedList->push_back(cond);
1465 break;
1466 }
1467 }
1468 return true;
1469}
1470
1472{
1474 {
1475 TC_LOG_ERROR("sql.sql", "{} Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString());
1476 return false;
1477 }
1478
1479 switch (cond->SourceType)
1480 {
1482 {
1484 {
1485 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->ToString());
1486 return false;
1487 }
1488
1490 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1491 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1492 {
1493 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1494 return false;
1495 }
1496 break;
1497 }
1499 {
1501 {
1502 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->ToString());
1503 return false;
1504 }
1505
1507 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1508 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1509 {
1510 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1511 return false;
1512 }
1513 break;
1514 }
1516 {
1518 {
1519 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->ToString());
1520 return false;
1521 }
1522
1524 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1525 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1526 {
1527 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1528 return false;
1529 }
1530 break;
1531 }
1533 {
1535 {
1536 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->ToString());
1537 return false;
1538 }
1539
1541 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1542 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1543 {
1544 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1545 return false;
1546 }
1547 break;
1548 }
1550 {
1552 {
1553 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->ToString());
1554 return false;
1555 }
1556
1558 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1559 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1560 {
1561 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1562 return false;
1563 }
1564 break;
1565 }
1567 {
1569 {
1570 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->ToString());
1571 return false;
1572 }
1573
1575 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1576 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1577 {
1578 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1579 return false;
1580 }
1581 break;
1582 }
1584 {
1586 {
1587 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->ToString());
1588 return false;
1589 }
1590
1592 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1593 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1594 {
1595 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1596 return false;
1597 }
1598 break;
1599 }
1601 {
1603 {
1604 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->ToString());
1605 return false;
1606 }
1607
1609 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1610 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1611 {
1612 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1613 return false;
1614 }
1615 break;
1616 }
1618 {
1620 {
1621 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->ToString());
1622 return false;
1623 }
1624
1626 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1627 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1628 {
1629 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1630 return false;
1631 }
1632 break;
1633 }
1635 {
1637 {
1638 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->ToString());
1639 return false;
1640 }
1641
1643 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1644 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1645 {
1646 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1647 return false;
1648 }
1649 break;
1650 }
1652 {
1654 {
1655 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->ToString());
1656 return false;
1657 }
1658
1660 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1661 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1662 {
1663 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1664 return false;
1665 }
1666 break;
1667 }
1669 {
1671 {
1672 TC_LOG_ERROR("sql.sql", "{} SourceGroup in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->ToString());
1673 return false;
1674 }
1675
1677 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1678 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1679 {
1680 TC_LOG_ERROR("sql.sql", "{} SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1681 return false;
1682 }
1683 break;
1684 }
1686 {
1687 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry);
1688 if (!spellInfo)
1689 {
1690 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString());
1691 return false;
1692 }
1693
1694 if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup)
1695 {
1696 TC_LOG_ERROR("sql.sql", "{} in `condition` table, has incorrect SourceGroup (spell effectMask) set, ignoring.", cond->ToString());
1697 return false;
1698 }
1699
1700 uint32 origGroup = cond->SourceGroup;
1701
1702 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
1703 {
1704 if (!((1 << spellEffectInfo.EffectIndex) & cond->SourceGroup))
1705 continue;
1706
1707 if (spellEffectInfo.ChainTarget > 0)
1708 continue;
1709
1710 switch (spellEffectInfo.TargetA.GetSelectionCategory())
1711 {
1716 continue;
1717 default:
1718 break;
1719 }
1720
1721 switch (spellEffectInfo.TargetB.GetSelectionCategory())
1722 {
1727 continue;
1728 default:
1729 break;
1730 }
1731
1732 switch (spellEffectInfo.Effect)
1733 {
1741 continue;
1742 default:
1743 break;
1744 }
1745
1746 TC_LOG_ERROR("sql.sql", "SourceEntry {} SourceGroup {} in `condition` table - spell {} does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_, __CHAIN__ or is not SPELL_EFFECT_PERSISTENT_AREA_AURA or SPELL_EFFECT_APPLY_AREA_AURA_* for effect {}, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(spellEffectInfo.EffectIndex));
1747 cond->SourceGroup &= ~(1 << spellEffectInfo.EffectIndex);
1748 }
1749 // all effects were removed, no need to add the condition at all
1750 if (!cond->SourceGroup)
1751 return false;
1752 break;
1753 }
1755 {
1756 if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry))
1757 {
1758 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString());
1759 return false;
1760 }
1761 break;
1762 }
1765 {
1766 SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
1767 if (!spellProto)
1768 {
1769 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString());
1770 return false;
1771 }
1772 break;
1773 }
1775 if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
1776 {
1777 TC_LOG_ERROR("sql.sql", "{} SourceEntry specifies non-existing quest, skipped.", cond->ToString());
1778 return false;
1779 }
1780 break;
1782 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1783 {
1784 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString());
1785 return false;
1786 }
1787
1788 if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
1789 {
1790 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString());
1791 return false;
1792 }
1793 break;
1795 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1796 {
1797 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString());
1798 return false;
1799 }
1800
1801 if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
1802 {
1803 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table does not exist in `spell.dbc`, ignoring.", cond->ToString());
1804 return false;
1805 }
1806 break;
1808 {
1809 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1810 {
1811 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString());
1812 return false;
1813 }
1814 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1815 if (!itemTemplate)
1816 {
1817 TC_LOG_ERROR("sql.sql", "{} SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString());
1818 return false;
1819 }
1820 break;
1821 }
1823 {
1824 if (!sAreaTriggerStore.LookupEntry(cond->SourceEntry))
1825 {
1826 TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exists in AreaTrigger.dbc, ignoring.", cond->ToString().c_str());
1827 return false;
1828 }
1829 break;
1830 }
1832 {
1833 TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_TERRAIN_SWAP: is only for master branch, skipped");
1834 return false;
1835 }
1837 {
1838 TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_PHASE: is only for master branch, skipped");
1839 return false;
1840 }
1842 {
1843 TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_GRAVEYARD: is only for master branch, skipped");
1844 return false;
1845 }
1847 {
1848 TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_AREATRIGGER: is only for master branch, skipped");
1849 return false;
1850 }
1852 {
1853 TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_CONVERSATION_LINE: is only for master branch, skipped");
1854 return false;
1855 }
1860 default:
1861 break;
1862 }
1863
1864 return true;
1865}
1866
1868{
1870 {
1871 TC_LOG_ERROR("sql.sql", "{} Invalid ConditionType in `condition` table, ignoring.", cond->ToString(true));
1872 return false;
1873 }
1874
1876 {
1877 TC_LOG_ERROR("sql.sql", "{} in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->ToString(true));
1878 return false;
1879 }
1880
1881 switch (cond->ConditionType)
1882 {
1883 case CONDITION_AURA:
1884 {
1885 if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
1886 {
1887 TC_LOG_ERROR("sql.sql", "{} has non existing spell (Id: {}), skipped.", cond->ToString(true), cond->ConditionValue1);
1888 return false;
1889 }
1890
1891 if (cond->ConditionValue2 > EFFECT_2)
1892 {
1893 TC_LOG_ERROR("sql.sql", "{} has non existing effect index ({}) (must be 0..2), skipped.", cond->ToString(true), cond->ConditionValue2);
1894 return false;
1895 }
1896 break;
1897 }
1898 case CONDITION_ITEM:
1899 {
1900 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
1901 if (!proto)
1902 {
1903 TC_LOG_ERROR("sql.sql", "{} Item ({}) does not exist, skipped.", cond->ToString(true), cond->ConditionValue1);
1904 return false;
1905 }
1906
1907 if (!cond->ConditionValue2)
1908 {
1909 TC_LOG_ERROR("sql.sql", "{} Zero item count in ConditionValue2, skipped.", cond->ToString(true));
1910 return false;
1911 }
1912 break;
1913 }
1915 {
1916 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
1917 if (!proto)
1918 {
1919 TC_LOG_ERROR("sql.sql", "{} Item ({}) does not exist, skipped.", cond->ToString(true), cond->ConditionValue1);
1920 return false;
1921 }
1922 break;
1923 }
1924 case CONDITION_ZONEID:
1925 {
1926 AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(cond->ConditionValue1);
1927 if (!areaEntry)
1928 {
1929 TC_LOG_ERROR("sql.sql", "{} Area ({}) does not exist, skipped.", cond->ToString(true), cond->ConditionValue1);
1930 return false;
1931 }
1932
1933 if (areaEntry->ParentAreaID != 0)
1934 {
1935 TC_LOG_ERROR("sql.sql", "{} requires to be in area ({}) which is a subzone but zone expected, skipped.", cond->ToString(true), cond->ConditionValue1);
1936 return false;
1937 }
1938 break;
1939 }
1941 {
1942 FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1);
1943 if (!factionEntry)
1944 {
1945 TC_LOG_ERROR("sql.sql", "{} has non existing faction ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
1946 return false;
1947 }
1948 break;
1949 }
1950 case CONDITION_TEAM:
1951 {
1952 if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE)
1953 {
1954 TC_LOG_ERROR("sql.sql", "{} specifies unknown team ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
1955 return false;
1956 }
1957 break;
1958 }
1959 case CONDITION_SKILL:
1960 {
1961 SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1);
1962 if (!pSkill)
1963 {
1964 TC_LOG_ERROR("sql.sql", "{} specifies non-existing skill ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
1965 return false;
1966 }
1967
1968 if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue())
1969 {
1970 TC_LOG_ERROR("sql.sql", "{} specifies skill ({}) with invalid value ({}), skipped.", cond->ToString(true), cond->ConditionValue1, cond->ConditionValue2);
1971 return false;
1972 }
1973 break;
1974 }
1976 if (cond->ConditionValue2 >= (1 << MAX_QUEST_STATUS))
1977 {
1978 TC_LOG_ERROR("sql.sql", "{} has invalid state mask ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
1979 return false;
1980 }
1981 [[fallthrough]];
1987 {
1988 if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1))
1989 {
1990 TC_LOG_ERROR("sql.sql", "{} points to non-existing quest ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
1991 return false;
1992 }
1993 break;
1994 }
1996 {
1997 GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
1998 if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid())
1999 {
2000 TC_LOG_ERROR("sql.sql", "{} has non existing event id ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2001 return false;
2002 }
2003 break;
2004 }
2006 {
2007 AchievementEntry const* achievement = sAchievementStore.LookupEntry(cond->ConditionValue1);
2008 if (!achievement)
2009 {
2010 TC_LOG_ERROR("sql.sql", "{} has non existing achivement id ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2011 return false;
2012 }
2013 break;
2014 }
2015 case CONDITION_CLASS:
2016 {
2018 {
2019 TC_LOG_ERROR("sql.sql", "{} has non existing classmask ({}), skipped.", cond->ToString(true), cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
2020 return false;
2021 }
2022 break;
2023 }
2024 case CONDITION_RACE:
2025 {
2027 {
2028 TC_LOG_ERROR("sql.sql", "{} has non existing racemask ({}), skipped.", cond->ToString(true), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
2029 return false;
2030 }
2031 break;
2032 }
2033 case CONDITION_GENDER:
2034 {
2036 {
2037 TC_LOG_ERROR("sql.sql", "{} has invalid gender ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2038 return false;
2039 }
2040 break;
2041 }
2042 case CONDITION_MAPID:
2043 {
2044 MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1);
2045 if (!me)
2046 {
2047 TC_LOG_ERROR("sql.sql", "{} has non existing map ({}), skipped", cond->ToString(true), cond->ConditionValue1);
2048 return false;
2049 }
2050 break;
2051 }
2052 case CONDITION_SPELL:
2053 {
2054 if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
2055 {
2056 TC_LOG_ERROR("sql.sql", "{} has non existing spell (Id: {}), skipped", cond->ToString(true), cond->ConditionValue1);
2057 return false;
2058 }
2059 break;
2060 }
2061 case CONDITION_LEVEL:
2062 {
2063 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
2064 {
2065 TC_LOG_ERROR("sql.sql", "{} has invalid ComparisionType ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2066 return false;
2067 }
2068 break;
2069 }
2071 {
2072 if (cond->ConditionValue1 > DRUNKEN_SMASHED)
2073 {
2074 TC_LOG_ERROR("sql.sql", "{} has invalid state ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2075 return false;
2076 }
2077 break;
2078 }
2080 {
2081 if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1))
2082 {
2083 TC_LOG_ERROR("sql.sql", "{} has non existing creature template entry ({}), skipped", cond->ToString(true), cond->ConditionValue1);
2084 return false;
2085 }
2086 break;
2087 }
2089 {
2090 if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1))
2091 {
2092 TC_LOG_ERROR("sql.sql", "{} has non existing gameobject template entry ({}), skipped.", cond->ToString(), cond->ConditionValue1);
2093 return false;
2094 }
2095 break;
2096 }
2098 {
2099 switch (cond->ConditionValue1)
2100 {
2101 case TYPEID_UNIT:
2102 if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2))
2103 {
2104 TC_LOG_ERROR("sql.sql", "{} has non existing creature template entry ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2105 return false;
2106 }
2107 if (cond->ConditionValue3)
2108 {
2109 if (CreatureData const* creatureData = sObjectMgr->GetCreatureData(cond->ConditionValue3))
2110 {
2111 if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2)
2112 {
2113 TC_LOG_ERROR("sql.sql", "{} has guid {} set but does not match creature entry ({}), skipped.", cond->ToString(true), cond->ConditionValue3, cond->ConditionValue2);
2114 return false;
2115 }
2116 }
2117 else
2118 {
2119 TC_LOG_ERROR("sql.sql", "{} has non existing creature guid ({}), skipped.", cond->ToString(true), cond->ConditionValue3);
2120 return false;
2121 }
2122 }
2123 break;
2124 case TYPEID_GAMEOBJECT:
2125 if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2))
2126 {
2127 TC_LOG_ERROR("sql.sql", "{} has non existing gameobject template entry ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2128 return false;
2129 }
2130 if (cond->ConditionValue3)
2131 {
2132 if (GameObjectData const* goData = sObjectMgr->GetGameObjectData(cond->ConditionValue3))
2133 {
2134 if (cond->ConditionValue2 && goData->id != cond->ConditionValue2)
2135 {
2136 TC_LOG_ERROR("sql.sql", "{} has guid {} set but does not match gameobject entry ({}), skipped.", cond->ToString(true), cond->ConditionValue3, cond->ConditionValue2);
2137 return false;
2138 }
2139 }
2140 else
2141 {
2142 TC_LOG_ERROR("sql.sql", "{} has non existing gameobject guid ({}), skipped.", cond->ToString(true), cond->ConditionValue3);
2143 return false;
2144 }
2145 }
2146 break;
2147 case TYPEID_PLAYER:
2148 case TYPEID_CORPSE:
2149 if (cond->ConditionValue2)
2151 if (cond->ConditionValue3)
2153 break;
2154 default:
2155 TC_LOG_ERROR("sql.sql", "{} has wrong typeid set ({}), skipped", cond->ToString(true), cond->ConditionValue1);
2156 return false;
2157 }
2158 break;
2159 }
2161 {
2163 {
2164 TC_LOG_ERROR("sql.sql", "{} has invalid typemask set ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2165 return false;
2166 }
2167 break;
2168 }
2170 {
2172 {
2173 TC_LOG_ERROR("sql.sql", "{} has invalid ConditionValue1(ConditionTarget selection) ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2174 return false;
2175 }
2176 if (cond->ConditionValue1 == cond->ConditionTarget)
2177 {
2178 TC_LOG_ERROR("sql.sql", "{} has ConditionValue1(ConditionTarget selection) set to self ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2179 return false;
2180 }
2181 if (cond->ConditionValue2 >= RELATION_MAX)
2182 {
2183 TC_LOG_ERROR("sql.sql", "{} has invalid ConditionValue2(RelationType) ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2184 return false;
2185 }
2186 break;
2187 }
2189 {
2191 {
2192 TC_LOG_ERROR("sql.sql", "{} has invalid ConditionValue1(ConditionTarget selection) ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2193 return false;
2194 }
2195 if (cond->ConditionValue1 == cond->ConditionTarget)
2196 {
2197 TC_LOG_ERROR("sql.sql", "{} has ConditionValue1(ConditionTarget selection) set to self ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2198 return false;
2199 }
2200 if (!cond->ConditionValue2)
2201 {
2202 TC_LOG_ERROR("sql.sql", "{} has invalid ConditionValue2(rankMask) ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2203 return false;
2204 }
2205 break;
2206 }
2208 {
2210 {
2211 TC_LOG_ERROR("sql.sql", "{} has invalid ConditionValue1(ConditionTarget selection) ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2212 return false;
2213 }
2214 if (cond->ConditionValue1 == cond->ConditionTarget)
2215 {
2216 TC_LOG_ERROR("sql.sql", "{} has ConditionValue1(ConditionTarget selection) set to self ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2217 return false;
2218 }
2219 if (cond->ConditionValue3 >= COMP_TYPE_MAX)
2220 {
2221 TC_LOG_ERROR("sql.sql", "{} has invalid ComparisionType ({}), skipped.", cond->ToString(true), cond->ConditionValue3);
2222 return false;
2223 }
2224 break;
2225 }
2226 case CONDITION_HP_VAL:
2227 {
2228 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
2229 {
2230 TC_LOG_ERROR("sql.sql", "{} has invalid ComparisionType ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2231 return false;
2232 }
2233 if (cond->ConditionValue3)
2234 TC_LOG_ERROR("sql.sql", "{} has useless data in value3 ({})!", cond->ToString(true), cond->ConditionValue3);
2235 break;
2236 }
2237 case CONDITION_HP_PCT:
2238 {
2239 if (cond->ConditionValue1 > 100)
2240 {
2241 TC_LOG_ERROR("sql.sql", "{} has too big percent value ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2242 return false;
2243 }
2244 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
2245 {
2246 TC_LOG_ERROR("sql.sql", "{} has invalid ComparisionType ({}), skipped.", cond->ToString(true), cond->ConditionValue2);
2247 return false;
2248 }
2249 if (cond->ConditionValue3)
2250 TC_LOG_ERROR("sql.sql", "{} has useless data in value3 ({})!", cond->ToString(), cond->ConditionValue3);
2251 break;
2252 }
2254 {
2255 if (!sWorld->getWorldState(cond->ConditionValue1))
2256 {
2257 TC_LOG_ERROR("sql.sql", "{} has non existing world state in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2258 return false;
2259 }
2260 break;
2261 }
2262 case CONDITION_TITLE:
2263 {
2264 CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1);
2265 if (!titleEntry)
2266 {
2267 TC_LOG_ERROR("sql.sql", "{} has non existing title in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2268 return false;
2269 }
2270 break;
2271 }
2273 {
2275 {
2276 TC_LOG_ERROR("sql.sql", "{} has non existing SpawnMask in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2277 return false;
2278 }
2279 break;
2280 }
2282 {
2284 {
2285 TC_LOG_ERROR("sql.sql", "{} has non existing UnitState in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2286 return false;
2287 }
2288 break;
2289 }
2291 {
2293 {
2294 TC_LOG_ERROR("sql.sql", "{} has non existing CreatureType in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2295 return false;
2296 }
2297 break;
2298 }
2300 case CONDITION_AREAID:
2302 case CONDITION_ALIVE:
2303 break;
2305 {
2306 AchievementEntry const* achievement = sAchievementStore.LookupEntry(cond->ConditionValue1);
2307 if (!achievement)
2308 {
2309 TC_LOG_ERROR("sql.sql", "{} has non existing realm first achivement id ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2310 return false;
2311 }
2312 break;
2313 }
2315 TC_LOG_ERROR("sql.sql", "{} is not valid for this branch, skipped.", cond->ToString(true));
2316 return false;
2318 {
2319 bool valid = false;
2320 switch (cond->ConditionValue1)
2321 {
2322 case 0:
2324 break;
2325 case 1:
2326 valid = cond->ConditionValue2 <= 1;
2327 break;
2328 default:
2329 valid = false;
2330 break;
2331 }
2332 if (!valid)
2333 {
2334 TC_LOG_ERROR("sql.sql", "{} has non-existing stand state ({},{}), skipped.", cond->ToString(true), cond->ConditionValue1, cond->ConditionValue2);
2335 return false;
2336 }
2337 break;
2338 }
2339 case CONDITION_PET_TYPE:
2340 if (cond->ConditionValue1 >= (1 << MAX_PET_TYPE))
2341 {
2342 TC_LOG_ERROR("sql.sql", "{} has non-existing pet type {}, skipped.", cond->ToString(true), cond->ConditionValue1);
2343 return false;
2344 }
2345 break;
2347 {
2348 const Quest* quest = sObjectMgr->GetQuestTemplate(cond->ConditionValue1);
2349 if (!quest)
2350 {
2351 TC_LOG_ERROR("sql.sql", "{} points to non-existing quest ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2352 return false;
2353 }
2354
2355 if (cond->ConditionValue2 > 3)
2356 {
2357 TC_LOG_ERROR("sql.sql", "{} has out-of-range quest objective index specified ({}), it must be a number between 0 and 3. skipped.", cond->ToString(true), cond->ConditionValue2);
2358 return false;
2359 }
2360
2361 if (quest->RequiredNpcOrGo[cond->ConditionValue2] == 0)
2362 {
2363 TC_LOG_ERROR("sql.sql", "{} has quest objective {} for quest {}, but the field RequiredNPCOrGo{} is 0, skipped.", cond->ToString(true), cond->ConditionValue2, cond->ConditionValue1, cond->ConditionValue2);
2364 return false;
2365 }
2366
2367 if (cond->ConditionValue3 > quest->RequiredNpcOrGoCount[cond->ConditionValue2])
2368 {
2369 TC_LOG_ERROR("sql.sql", "{} has quest objective count {} in value3, but quest {} has a maximum objective count of {} in RequiredNPCOrGOCount{}, skipped.", cond->ToString(true), cond->ConditionValue3, cond->ConditionValue2, quest->RequiredNpcOrGoCount[cond->ConditionValue2], cond->ConditionValue2);
2370 return false;
2371 }
2372 break;
2373 }
2375 if (cond->ConditionValue1 >= MAX_DIFFICULTY)
2376 {
2377 TC_LOG_ERROR("sql.sql", "{} has non existing difficulty in value1 ({}), skipped.", cond->ToString(true), cond->ConditionValue1);
2378 return false;
2379 }
2380 break;
2381 case CONDITION_IN_WATER:
2382 case CONDITION_CHARMED:
2383 case CONDITION_TAXI:
2385 default:
2386 break;
2387 }
2388
2395
2396 return true;
2397}
2398
2400{
2401 TC_LOG_ERROR("sql.sql", "{} has useless data in ConditionValue{} ({})!", cond->ToString(true), index, value);
2402}
2403
2405{
2406 for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
2407 for (ConditionContainer::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2408 delete *it;
2409
2411
2412 for (uint32 i = 0; i < CONDITION_SOURCE_TYPE_MAX; ++i)
2413 {
2414 for (ConditionsByEntryMap::iterator it = ConditionStore[i].begin(); it != ConditionStore[i].end(); ++it)
2415 for (ConditionContainer::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
2416 delete *itr;
2417
2418 ConditionStore[i].clear();
2419 }
2420
2421 for (ConditionEntriesByCreatureIdMap::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
2422 for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2423 for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2424 delete *i;
2425
2427
2428 for (SmartEventConditionContainer::iterator itr = SmartEventConditionStore.begin(); itr != SmartEventConditionStore.end(); ++itr)
2429 for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2430 for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2431 delete *i;
2432
2434
2435 for (ConditionEntriesByCreatureIdMap::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
2436 for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2437 for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2438 delete *i;
2439
2442
2443 for (ConditionEntriesByCreatureIdMap::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
2444 for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2445 for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2446 delete *i;
2447
2449
2450 // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
2451 for (std::vector<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
2452 delete *itr;
2453
2454 AllocatedMemoryStore.clear();
2455}
#define sAchievementMgr
ConditionSourceType
Definition: ConditionMgr.h:126
@ CONDITION_SOURCE_TYPE_MAX
Definition: ConditionMgr.h:161
@ CONDITION_SOURCE_TYPE_CONVERSATION_LINE
Definition: ConditionMgr.h:156
@ CONDITION_SOURCE_TYPE_VEHICLE_SPELL
Definition: ConditionMgr.h:148
@ CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE
Definition: ConditionMgr.h:129
@ CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE
Definition: ConditionMgr.h:137
@ CONDITION_SOURCE_TYPE_TERRAIN_SWAP
Definition: ConditionMgr.h:152
@ CONDITION_SOURCE_TYPE_NPC_VENDOR
Definition: ConditionMgr.h:150
@ CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION
Definition: ConditionMgr.h:142
@ CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT
Definition: ConditionMgr.h:145
@ CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE
Definition: ConditionMgr.h:133
@ CONDITION_SOURCE_TYPE_PHASE
Definition: ConditionMgr.h:153
@ CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE
Definition: ConditionMgr.h:139
@ CONDITION_SOURCE_TYPE_SMART_EVENT
Definition: ConditionMgr.h:149
@ CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE
Definition: ConditionMgr.h:135
@ CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE
Definition: ConditionMgr.h:136
@ CONDITION_SOURCE_TYPE_AREATRIGGER_CLIENT_TRIGGERED
Definition: ConditionMgr.h:157
@ CONDITION_SOURCE_TYPE_AREATRIGGER
Definition: ConditionMgr.h:155
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:144
@ CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE
Definition: ConditionMgr.h:130
@ CONDITION_SOURCE_TYPE_GOSSIP_MENU
Definition: ConditionMgr.h:141
@ CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE
Definition: ConditionMgr.h:143
@ CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE
Definition: ConditionMgr.h:132
@ CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET
Definition: ConditionMgr.h:140
@ CONDITION_SOURCE_TYPE_GRAVEYARD
Definition: ConditionMgr.h:154
@ CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE
Definition: ConditionMgr.h:138
@ CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE
Definition: ConditionMgr.h:128
@ CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE
Definition: ConditionMgr.h:131
@ CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE
Definition: ConditionMgr.h:134
@ CONDITION_SOURCE_TYPE_SPELL_PROC
Definition: ConditionMgr.h:151
@ CONDITION_SOURCE_TYPE_QUEST_AVAILABLE
Definition: ConditionMgr.h:146
@ CONDITION_SOURCE_TYPE_NONE
Definition: ConditionMgr.h:127
@ INSTANCE_INFO_DATA64
Definition: ConditionMgr.h:180
@ INSTANCE_INFO_DATA
Definition: ConditionMgr.h:177
@ INSTANCE_INFO_BOSS_STATE
Definition: ConditionMgr.h:179
@ INSTANCE_INFO_GUID_DATA
Definition: ConditionMgr.h:178
@ MAX_CONDITION_TARGETS
Definition: ConditionMgr.h:185
ConditionTypes
Definition: ConditionMgr.h:37
@ CONDITION_TAXI
Definition: ConditionMgr.h:84
@ CONDITION_MAPID
Definition: ConditionMgr.h:60
@ CONDITION_SKILL
Definition: ConditionMgr.h:45
@ CONDITION_RACE
Definition: ConditionMgr.h:54
@ CONDITION_REACTION_TO
Definition: ConditionMgr.h:72
@ CONDITION_NEAR_GAMEOBJECT
Definition: ConditionMgr.h:68
@ CONDITION_QUESTREWARDED
Definition: ConditionMgr.h:46
@ CONDITION_REALM_ACHIEVEMENT
Definition: ConditionMgr.h:77
@ CONDITION_PHASEMASK
Definition: ConditionMgr.h:64
@ CONDITION_QUEST_OBJECTIVE_PROGRESS
Definition: ConditionMgr.h:86
@ CONDITION_DAILY_QUEST_DONE
Definition: ConditionMgr.h:81
@ CONDITION_ACTIVE_EVENT
Definition: ConditionMgr.h:50
@ CONDITION_INSTANCE_INFO
Definition: ConditionMgr.h:51
@ CONDITION_RELATION_TO
Definition: ConditionMgr.h:71
@ CONDITION_STAND_STATE
Definition: ConditionMgr.h:80
@ CONDITION_DRUNKENSTATE
Definition: ConditionMgr.h:48
@ CONDITION_AURA
Definition: ConditionMgr.h:39
@ CONDITION_ACHIEVEMENT
Definition: ConditionMgr.h:55
@ CONDITION_OBJECT_ENTRY_GUID
Definition: ConditionMgr.h:69
@ CONDITION_PET_TYPE
Definition: ConditionMgr.h:83
@ CONDITION_DIFFICULTY_ID
Definition: ConditionMgr.h:87
@ CONDITION_DISTANCE_TO
Definition: ConditionMgr.h:73
@ CONDITION_HP_VAL
Definition: ConditionMgr.h:75
@ CONDITION_GENDER
Definition: ConditionMgr.h:58
@ CONDITION_GAMEMASTER
Definition: ConditionMgr.h:88
@ CONDITION_TERRAIN_SWAP
Definition: ConditionMgr.h:79
@ CONDITION_REPUTATION_RANK
Definition: ConditionMgr.h:43
@ CONDITION_HP_PCT
Definition: ConditionMgr.h:76
@ CONDITION_QUEST_COMPLETE
Definition: ConditionMgr.h:66
@ CONDITION_MAX
Definition: ConditionMgr.h:95
@ CONDITION_SPELL
Definition: ConditionMgr.h:63
@ CONDITION_ZONEID
Definition: ConditionMgr.h:42
@ CONDITION_CHARMED
Definition: ConditionMgr.h:82
@ CONDITION_TYPE_MASK
Definition: ConditionMgr.h:70
@ CONDITION_AREAID
Definition: ConditionMgr.h:61
@ CONDITION_IN_WATER
Definition: ConditionMgr.h:78
@ CONDITION_ITEM
Definition: ConditionMgr.h:40
@ CONDITION_WORLD_STATE
Definition: ConditionMgr.h:49
@ CONDITION_SPAWNMASK
Definition: ConditionMgr.h:57
@ CONDITION_CLASS
Definition: ConditionMgr.h:53
@ CONDITION_TEAM
Definition: ConditionMgr.h:44
@ CONDITION_NONE
Definition: ConditionMgr.h:38
@ CONDITION_QUEST_NONE
Definition: ConditionMgr.h:52
@ CONDITION_QUESTSTATE
Definition: ConditionMgr.h:85
@ CONDITION_ITEM_EQUIPPED
Definition: ConditionMgr.h:41
@ CONDITION_LEVEL
Definition: ConditionMgr.h:65
@ CONDITION_QUESTTAKEN
Definition: ConditionMgr.h:47
@ CONDITION_NEAR_CREATURE
Definition: ConditionMgr.h:67
@ CONDITION_TITLE
Definition: ConditionMgr.h:56
@ CONDITION_ALIVE
Definition: ConditionMgr.h:74
@ CONDITION_CREATURE_TYPE
Definition: ConditionMgr.h:62
@ CONDITION_UNIT_STATE
Definition: ConditionMgr.h:59
std::vector< Condition * > ConditionContainer
Definition: ConditionMgr.h:246
RelationType
Definition: ConditionMgr.h:165
@ RELATION_IN_PARTY
Definition: ConditionMgr.h:167
@ RELATION_IN_RAID_OR_PARTY
Definition: ConditionMgr.h:168
@ RELATION_CREATED_BY
Definition: ConditionMgr.h:171
@ RELATION_MAX
Definition: ConditionMgr.h:172
@ RELATION_SELF
Definition: ConditionMgr.h:166
@ RELATION_PASSENGER_OF
Definition: ConditionMgr.h:170
@ RELATION_OWNED_BY
Definition: ConditionMgr.h:169
#define MAX_EFFECT_MASK
Definition: DBCEnums.h:389
#define MAX_DIFFICULTY
Definition: DBCEnums.h:296
@ SPAWNMASK_RAID_ALL
Definition: DBCEnums.h:314
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DBCStorage< AreaTriggerEntry > sAreaTriggerStore(AreaTriggerEntryfmt)
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint8_t uint8
Definition: Define.h:135
int32_t int32
Definition: Define.h:129
uint64_t uint64
Definition: Define.h:132
uint16_t uint16
Definition: Define.h:134
uint32_t uint32
Definition: Define.h:133
#define ABORT_MSG
Definition: Errors.h:75
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
#define ASSERT
Definition: Errors.h:68
#define sGameEventMgr
Definition: GameEventMgr.h:189
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:75
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:76
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:71
EncounterState
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true)
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
LootStore LootTemplates_Item("item_loot_template", "item entry", true)
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Reference("reference_loot_template", "reference id", false)
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true)
@ TYPEID_GAMEOBJECT
Definition: ObjectGuid.h:40
@ TYPEID_UNIT
Definition: ObjectGuid.h:38
@ TYPEID_CORPSE
Definition: ObjectGuid.h:42
@ TYPEID_PLAYER
Definition: ObjectGuid.h:39
@ TYPEMASK_UNIT
Definition: ObjectGuid.h:52
@ TYPEMASK_CORPSE
Definition: ObjectGuid.h:56
@ TYPEMASK_GAMEOBJECT
Definition: ObjectGuid.h:54
@ TYPEMASK_PLAYER
Definition: ObjectGuid.h:53
#define sObjectMgr
Definition: ObjectMgr.h:1723
std::pair< GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::iterator > GossipMenuItemsMapBoundsNonConst
Definition: ObjectMgr.h:803
std::pair< GossipMenusContainer::iterator, GossipMenusContainer::iterator > GossipMenusMapBoundsNonConst
Definition: ObjectMgr.h:800
@ MAX_PET_TYPE
Definition: PetDefines.h:33
@ DRUNKEN_SMASHED
Definition: Player.h:315
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:36
QuestStatus
Definition: QuestDef.h:103
@ QUEST_STATUS_REWARDED
Definition: QuestDef.h:110
@ QUEST_STATUS_FAILED
Definition: QuestDef.h:109
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:107
@ QUEST_STATUS_NONE
Definition: QuestDef.h:104
@ MAX_QUEST_STATUS
Definition: QuestDef.h:111
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:105
#define sScriptMgr
Definition: ScriptMgr.h:1169
SpellEffIndex
Definition: SharedDefines.h:30
@ EFFECT_2
Definition: SharedDefines.h:33
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
@ SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
@ SPELL_EFFECT_APPLY_AREA_AURA_PET
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
@ SPELL_EFFECT_PERSISTENT_AREA_AURA
@ SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
@ SPELL_EFFECT_APPLY_AREA_AURA_OWNER
Gender
Definition: SharedDefines.h:76
@ CREATURE_TYPE_GAS_CLOUD
@ ALLIANCE
@ HORDE
#define CLASSMASK_ALL_PLAYABLE
#define RACEMASK_ALL_PLAYABLE
@ TARGET_FLAG_UNIT_MASK
Definition: SpellDefines.h:200
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellDefines.h:203
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellDefines.h:202
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:35
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:50
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:51
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:49
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:52
#define sSpellMgr
Definition: SpellMgr.h:738
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:57
uint32 getMSTime()
Definition: Timer.h:33
@ UNIT_STAND_STATE_SUBMERGED
Definition: UnitDefines.h:43
@ UNIT_STATE_ALL_STATE_SUPPORTED
Definition: Unit.h:251
bool CompareValues(ComparisionType type, T val1, T val2)
Definition: Util.h:532
ComparisionType
Definition: Util.h:522
@ COMP_TYPE_MAX
Definition: Util.h:528
bool isConditionTypeValid(Condition *cond) const
bool IsSpellUsedInSpellClickConditions(uint32 spellId) const
ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore
Definition: ConditionMgr.h:309
std::unordered_set< uint32 > SpellsUsedInSpellClickConditions
Definition: ConditionMgr.h:312
bool addToSpellImplicitTargetConditions(Condition *cond) const
ConditionEntriesByCreatureIdMap VehicleSpellConditionStore
Definition: ConditionMgr.h:307
bool IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player *player, Unit *vehicle) const
std::vector< Condition * > AllocatedMemoryStore
Definition: ConditionMgr.h:303
ConditionContainer const * GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const
bool isSourceTypeValid(Condition *cond) const
bool addToGossipMenus(Condition *cond) const
uint32 GetSearcherTypeMaskForConditionList(ConditionContainer const &conditions) const
bool IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, ConditionSourceInfo &sourceInfo) const
static ConditionMgr * instance()
SmartEventConditionContainer SmartEventConditionStore
Definition: ConditionMgr.h:310
bool HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const
bool IsObjectMeetingSmartEventConditions(int32 entryOrGuid, uint32 eventId, uint32 sourceType, Unit *unit, WorldObject *baseObject) const
bool IsObjectMeetToConditionList(ConditionSourceInfo &sourceInfo, ConditionContainer const &conditions) const
bool IsObjectMeetingSpellClickConditions(uint32 creatureId, uint32 spellId, WorldObject *clicker, WorldObject *target) const
bool addToLootTemplate(Condition *cond, LootTemplate *loot) const
bool addToGossipMenuItems(Condition *cond) const
ConditionEntriesByTypeArray ConditionStore
Definition: ConditionMgr.h:305
static bool CanHaveSourceGroupSet(ConditionSourceType sourceType)
static void LogUselessConditionValue(Condition *cond, uint8 index, uint32 value)
ConditionEntriesByCreatureIdMap SpellClickEventConditionStore
Definition: ConditionMgr.h:308
ConditionReferenceContainer ConditionReferenceStore
Definition: ConditionMgr.h:306
static bool CanHaveSourceIdSet(ConditionSourceType sourceType)
bool IsObjectMeetToConditions(WorldObject *object, ConditionContainer const &conditions) const
static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX]
Definition: ConditionMgr.h:290
bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player *player, Creature *vendor) const
static char const *const StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]
Definition: ConditionMgr.h:289
void LoadConditions(bool isReload=false)
Class used to access individual fields of database query result.
Definition: Field.h:92
uint8 GetUInt8() const
Definition: Field.cpp:29
bool GetBool() const
Definition: Field.h:100
uint32 GetUInt32() const
Definition: Field.cpp:61
int32 GetInt32() const
Definition: Field.cpp:69
std::vector< GameEventData > GameEventDataMap
Definition: GameEventMgr.h:111
void ResetConditions()
Definition: LootMgr.cpp:218
LootTemplate * GetLootForConditionFill(uint32 loot_id)
Definition: LootMgr.cpp:237
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:78
bool isReference(uint32 id)
Definition: LootMgr.cpp:771
bool addConditionItem(Condition *cond)
Definition: LootMgr.cpp:713
Definition: Map.h:281
bool IsDungeon() const
Definition: Map.cpp:4234
static Creature * ToCreature(Object *o)
Definition: Object.h:185
static Unit * ToUnit(Object *o)
Definition: Object.h:191
TypeID GetTypeId() const
Definition: Object.h:92
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:77
static Player * ToPlayer(Object *o)
Definition: Object.h:179
Definition: Pet.h:40
Definition: Player.h:915
static bool IsValidGender(uint8 Gender)
Definition: Player.h:1371
static DrunkenState GetDrunkenstateByValue(uint8 value)
Definition: Player.cpp:919
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:308
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:309
uint32 GetQuestId() const
Definition: QuestDef.h:229
std::vector< Condition * > * ImplicitTargetConditions
Definition: SpellInfo.h:234
uint32 Id
Definition: SpellInfo.h:293
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:487
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition: SpellInfo.h:486
Definition: Unit.h:769
ObjectGuid GetCreatorGUID() const
Definition: Unit.h:1243
ObjectGuid GetOwnerGUID() const override
Definition: Unit.h:1241
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.cpp:11854
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:11925
bool IsInPartyWith(Unit const *unit) const
Definition: Unit.cpp:11906
ReputationRank GetReactionTo(WorldObject const *target) const
Definition: Object.cpp:2661
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1116
#define sWorld
Definition: World.h:893
ObjectData const creatureData[]
uint32 ParentAreaID
Definition: DBCStructure.h:180
Condition const * mLastFailedCondition
Definition: ConditionMgr.h:191
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:190
uint32 SourceGroup
Definition: ConditionMgr.h:204
ConditionTypes ConditionType
Definition: ConditionMgr.h:208
std::string ToString(bool ext=false) const
uint32 GetSearcherTypeMaskForCondition() const
uint32 ErrorType
Definition: ConditionMgr.h:212
uint32 SourceId
Definition: ConditionMgr.h:206
int32 SourceEntry
Definition: ConditionMgr.h:205
uint32 ElseGroup
Definition: ConditionMgr.h:207
uint32 ScriptId
Definition: ConditionMgr.h:215
bool NegativeCondition
Definition: ConditionMgr.h:217
ConditionSourceType SourceType
Definition: ConditionMgr.h:203
uint32 ConditionValue2
Definition: ConditionMgr.h:210
uint8 ConditionTarget
Definition: ConditionMgr.h:216
uint32 ReferenceId
Definition: ConditionMgr.h:214
uint32 ErrorTextId
Definition: ConditionMgr.h:213
uint32 ConditionValue3
Definition: ConditionMgr.h:211
uint32 GetMaxAvailableConditionTargets() const
uint32 ConditionValue1
Definition: ConditionMgr.h:209
bool Meets(ConditionSourceInfo &sourceInfo) const