Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
ConditionMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AchievementMgr.h"
7#include "ConditionMgr.h"
8#include "GameEventMgr.h"
9#include "InstanceScript.h"
10#include "ObjectMgr.h"
11#include "Player.h"
12#include "ReputationMgr.h"
13#include "ScriptedCreature.h"
14#include "ScriptMgr.h"
15#include "Spell.h"
16#include "SpellAuras.h"
17#include "SpellMgr.h"
18
19// Checks if object meets the condition
20// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
22{
24 WorldObject* object = sourceInfo.mConditionTargets[ConditionTarget];
25 // object not present, return false
26 if (!object)
27 {
28 SF_LOG_DEBUG("condition", "Condition object not found for condition (Entry: %u Type: %u Group: %u)", SourceEntry, SourceType, SourceGroup);
29 return false;
30 }
31 bool condMeets = false;
32 switch (ConditionType)
33 {
34 case CONDITION_NONE:
35 condMeets = true; // empty condition, always met
36 break;
37 case CONDITION_AURA:
38 {
39 if (Unit* unit = object->ToUnit())
40 condMeets = unit->HasAuraEffect(ConditionValue1, ConditionValue2);
41 break;
42 }
43 case CONDITION_ITEM:
44 {
45 if (Player* player = object->ToPlayer())
46 {
47 // don't allow 0 items (it's checked during table load)
49 bool checkBank = ConditionValue3 ? true : false;
50 condMeets = player->HasItemCount(ConditionValue1, ConditionValue2, checkBank);
51 }
52 break;
53 }
55 {
56 if (Player* player = object->ToPlayer())
57 condMeets = player->HasItemOrGemWithIdEquipped(ConditionValue1, 1);
58 break;
59 }
61 condMeets = object->GetZoneId() == ConditionValue1;
62 break;
64 {
65 if (Player* player = object->ToPlayer())
66 {
67 if (FactionEntry const* faction = sFactionStore.LookupEntry(ConditionValue1))
68 condMeets = (ConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction)));
69 }
70 break;
71 }
73 {
74 if (Player* player = object->ToPlayer())
75 condMeets = player->HasAchieved(ConditionValue1);
76 break;
77 }
78 case CONDITION_TEAM:
79 {
80 if (Player* player = object->ToPlayer())
81 condMeets = player->GetTeam() == ConditionValue1;
82 break;
83 }
84 case CONDITION_CLASS:
85 {
86 if (Unit* unit = object->ToUnit())
87 condMeets = unit->getClassMask() & ConditionValue1;
88 break;
89 }
90 case CONDITION_RACE:
91 {
92 if (Unit* unit = object->ToUnit())
93 condMeets = unit->getRaceMask() & ConditionValue1;
94 break;
95 }
97 {
98 if (Player* player = object->ToPlayer())
99 condMeets = player->getGender() == ConditionValue1;
100 break;
101 }
102 case CONDITION_SKILL:
103 {
104 if (Player* player = object->ToPlayer())
105 condMeets = player->HasSkill(ConditionValue1) && player->GetBaseSkillValue(ConditionValue1) >= ConditionValue2;
106 break;
107 }
109 {
110 if (Player* player = object->ToPlayer())
111 condMeets = player->GetQuestRewardStatus(ConditionValue1);
112 break;
113 }
115 {
116 if (Player* player = object->ToPlayer())
117 {
118 QuestStatus status = player->GetQuestStatus(ConditionValue1);
119 condMeets = (status == QUEST_STATUS_INCOMPLETE);
120 }
121 break;
122 }
124 {
125 if (Player* player = object->ToPlayer())
126 {
127 QuestStatus status = player->GetQuestStatus(ConditionValue1);
128 condMeets = (status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(ConditionValue1));
129 }
130 break;
131 }
133 {
134 if (Player* player = object->ToPlayer())
135 {
136 QuestStatus status = player->GetQuestStatus(ConditionValue1);
137 condMeets = (status == QUEST_STATUS_NONE);
138 }
139 break;
140 }
142 condMeets = sGameEventMgr->IsActiveEvent(ConditionValue1);
143 break;
145 {
146 Map* map = object->GetMap();
147 if (map && map->IsInstance())
148 {
149 if (InstanceScript const* instance = ((InstanceMap*)map)->GetInstanceScript())
150 {
151 switch (ConditionValue3)
152 {
154 condMeets = instance->GetData(ConditionValue1) == ConditionValue2;
155 break;
157 condMeets = instance->GetData64(ConditionValue1) == ConditionValue2;
158 break;
160 condMeets = instance->GetBossState(ConditionValue1) == EncounterState(ConditionValue2);
161 break;
162 }
163 }
164 }
165 break;
166 }
167 case CONDITION_MAPID:
168 condMeets = object->GetMapId() == ConditionValue1;
169 break;
170 case CONDITION_AREAID:
171 condMeets = object->GetAreaId() == ConditionValue1;
172 break;
173 case CONDITION_SPELL:
174 {
175 if (Player* player = object->ToPlayer())
176 condMeets = player->HasSpell(ConditionValue1);
177 break;
178 }
179 case CONDITION_LEVEL:
180 {
181 if (Unit* unit = object->ToUnit())
182 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), static_cast<uint32>(unit->getLevel()), ConditionValue1);
183 break;
184 }
186 {
187 if (Player* player = object->ToPlayer())
188 condMeets = (uint32)Player::GetDrunkenstateByValue(player->GetDrunkValue()) >= ConditionValue1;
189 break;
190 }
192 {
193 condMeets = GetClosestCreatureWithEntry(object, ConditionValue1, (float)ConditionValue2) ? true : false;
194 break;
195 }
197 {
198 condMeets = GetClosestGameObjectWithEntry(object, ConditionValue1, (float)ConditionValue2) ? true : false;
199 break;
200 }
202 {
203 if (uint32(object->GetTypeId()) == ConditionValue1)
204 condMeets = (!ConditionValue2) || (object->GetEntry() == ConditionValue2);
205 break;
206 }
208 {
209 condMeets = object->isType(ConditionValue1);
210 break;
211 }
213 {
214 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
215 {
216 Unit* toUnit = toObject->ToUnit();
217 Unit* unit = object->ToUnit();
218 if (toUnit && unit)
219 {
220 switch (ConditionValue2)
221 {
222 case RELATION_SELF:
223 condMeets = unit == toUnit;
224 break;
226 condMeets = unit->IsInPartyWith(toUnit);
227 break;
229 condMeets = unit->IsInRaidWith(toUnit);
230 break;
232 condMeets = unit->GetOwnerGUID() == toUnit->GetGUID();
233 break;
235 condMeets = unit->IsOnVehicle(toUnit);
236 break;
238 condMeets = unit->GetCreatorGUID() == toUnit->GetGUID();
239 break;
240 }
241 }
242 }
243 break;
244 }
246 {
247 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
248 {
249 Unit* toUnit = toObject->ToUnit();
250 Unit* unit = object->ToUnit();
251 if (toUnit && unit)
252 condMeets = (1 << unit->GetReactionTo(toUnit)) & ConditionValue2;
253 }
254 break;
255 }
257 {
258 if (WorldObject* toObject = sourceInfo.mConditionTargets[ConditionValue1])
259 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue3), object->GetDistance(toObject), static_cast<float>(ConditionValue2));
260 break;
261 }
262 case CONDITION_ALIVE:
263 {
264 if (Unit* unit = object->ToUnit())
265 condMeets = unit->IsAlive();
266 break;
267 }
268 case CONDITION_HP_VAL:
269 {
270 if (Unit* unit = object->ToUnit())
271 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), unit->GetHealth(), static_cast<uint32>(ConditionValue1));
272 break;
273 }
274 case CONDITION_HP_PCT:
275 {
276 if (Unit* unit = object->ToUnit())
277 condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), unit->GetHealthPct(), static_cast<float>(ConditionValue1));
278 break;
279 }
281 {
282 condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1);
283 break;
284 }
286 {
287 condMeets = object->IsPhased(ConditionValue1);
288 break;
289 }
290 case CONDITION_TITLE:
291 {
292 if (Player* player = object->ToPlayer())
293 condMeets = player->HasTitle(ConditionValue1);
294 break;
295 }
297 {
298 condMeets = ((1 << object->GetMap()->GetSpawnMode()) & ConditionValue1);
299 break;
300 }
302 {
303 if (Unit* unit = object->ToUnit())
304 condMeets = unit->HasUnitState(ConditionValue1);
305 break;
306 }
308 {
309 if (Creature* creature = object->ToCreature())
310 condMeets = creature->GetCreatureTemplate()->type == ConditionValue1;
311 break;
312 }
314 {
315 condMeets = object->IsTerrainSwaped(ConditionValue1);
316 break;
317 }
318 default:
319 condMeets = false;
320 break;
321 }
322
324 condMeets = !condMeets;
325
326 if (!condMeets)
327 sourceInfo.mLastFailedCondition = this;
328
329 bool script = sScriptMgr->OnConditionCheck(this, sourceInfo); // Returns true by default.
330 return condMeets && script;
331}
332
334{
335 // build mask of types for which condition can return true
336 // this is used for speeding up gridsearches
338 return (GRID_MAP_TYPE_MASK_ALL);
339 uint32 mask = 0;
340 switch (ConditionType)
341 {
342 case CONDITION_NONE:
344 break;
345 case CONDITION_AURA:
347 break;
348 case CONDITION_ITEM:
350 break;
353 break;
354 case CONDITION_ZONEID:
356 break;
359 break;
362 break;
363 case CONDITION_TEAM:
365 break;
366 case CONDITION_CLASS:
368 break;
369 case CONDITION_RACE:
371 break;
372 case CONDITION_SKILL:
374 break;
377 break;
380 break;
383 break;
386 break;
389 break;
392 break;
393 case CONDITION_MAPID:
395 break;
396 case CONDITION_AREAID:
398 break;
399 case CONDITION_SPELL:
401 break;
402 case CONDITION_LEVEL:
404 break;
407 break;
410 break;
413 break;
415 switch (ConditionValue1)
416 {
419 break;
422 break;
425 break;
428 break;
431 break;
432 default:
433 break;
434 }
435 break;
447 break;
450 break;
453 break;
456 break;
457 case CONDITION_ALIVE:
459 break;
460 case CONDITION_HP_VAL:
462 break;
463 case CONDITION_HP_PCT:
465 break;
468 break;
471 break;
472 case CONDITION_TITLE:
474 break;
477 break;
478 case CONDITION_GENDER:
480 break;
483 break;
486 break;
489 break;
490 default:
491 ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
492 break;
493 }
494 return mask;
495}
496
517
519
524
526{
527 ConditionList conditions;
528 ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(refId);
529 if (ref != ConditionReferenceStore.end())
530 conditions = (*ref).second;
531 return conditions;
532}
533
535{
536 if (conditions.empty())
538 // groupId, typeMask
539 std::map<uint32, uint32> ElseGroupStore;
540 for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
541 {
542 // no point of having not loaded conditions in list
543 ASSERT((*i)->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
544 std::map<uint32, uint32>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
545 // group not filled yet, fill with widest mask possible
546 if (itr == ElseGroupStore.end())
547 ElseGroupStore[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
548 // no point of checking anymore, empty mask
549 else if (!(*itr).second)
550 continue;
551
552 if ((*i)->ReferenceId) // handle reference
553 {
554 ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
555 ASSERT(ref != ConditionReferenceStore.end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
556 ElseGroupStore[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
557 }
558 else // handle normal condition
559 {
560 // object will match conditions in one ElseGroupStore only when it matches all of them
561 // so, let's find a smallest possible mask which satisfies all conditions
562 ElseGroupStore[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
563 }
564 }
565 // object will match condition when one of the checks in ElseGroupStore is matching
566 // so, let's include all possible masks
567 uint32 mask = 0;
568 for (std::map<uint32, uint32>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
569 mask |= i->second;
570
571 return mask;
572}
573
575{
576 // groupId, groupCheckPassed
577 std::map<uint32, bool> ElseGroupStore;
578 for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
579 {
580 SF_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1);
581 if ((*i)->isLoaded())
582 {
584 std::map<uint32, bool>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
586 if (itr == ElseGroupStore.end())
587 ElseGroupStore[(*i)->ElseGroup] = true;
588 else if (!(*itr).second)
589 continue;
590
591 if ((*i)->ReferenceId)//handle reference
592 {
593 ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
594 if (ref != ConditionReferenceStore.end())
595 {
596 if (!IsObjectMeetToConditionList(sourceInfo, (*ref).second))
597 ElseGroupStore[(*i)->ElseGroup] = false;
598 }
599 else
600 {
601 SF_LOG_DEBUG("condition", "IsPlayerMeetToConditionList: Reference template -%u not found",
602 (*i)->ReferenceId);//checked at loading, should never happen
603 }
604 }
605 else //handle normal condition
606 {
607 if (!(*i)->Meets(sourceInfo))
608 ElseGroupStore[(*i)->ElseGroup] = false;
609 }
610 }
611 }
612 for (std::map<uint32, bool>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
613 if (i->second)
614 return true;
615
616 return false;
617}
618
620{
622 return IsObjectMeetToConditions(srcInfo, conditions);
623}
624
626{
627 ConditionSourceInfo srcInfo = ConditionSourceInfo(object1, object2);
628 return IsObjectMeetToConditions(srcInfo, conditions);
629}
630
632{
633 if (conditions.empty())
634 return true;
635
636 SF_LOG_DEBUG("condition", "ConditionMgr::IsObjectMeetToConditions");
637 return IsObjectMeetToConditionList(sourceInfo, conditions);
638}
639
663
665{
666 return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
667}
668
670{
671 ConditionList spellCond;
672 if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
673 {
674 ConditionContainer::const_iterator itr = ConditionStore.find(sourceType);
675 if (itr != ConditionStore.end())
676 {
677 ConditionTypeContainer::const_iterator i = (*itr).second.find(entry);
678 if (i != (*itr).second.end())
679 {
680 spellCond = (*i).second;
681 SF_LOG_DEBUG("condition", "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u", uint32(sourceType), entry);
682 }
683 }
684 }
685 return spellCond;
686}
687
689{
690 ConditionList cond;
691 CreatureSpellConditionContainer::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
692 if (itr != SpellClickEventConditionStore.end())
693 {
694 ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
695 if (i != (*itr).second.end())
696 {
697 cond = (*i).second;
698 SF_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
699 }
700 }
701 return cond;
702}
703
705{
706 ConditionList cond;
707 CreatureSpellConditionContainer::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
708 if (itr != VehicleSpellConditionStore.end())
709 {
710 ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
711 if (i != (*itr).second.end())
712 {
713 cond = (*i).second;
714 SF_LOG_DEBUG("condition", "GetConditionsForVehicleSpell: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
715 }
716 }
717 return cond;
718}
719
721{
722 ConditionList cond;
723 SmartEventConditionContainer::const_iterator itr = SmartEventConditionStore.find(std::make_pair(entryOrGuid, sourceType));
724 if (itr != SmartEventConditionStore.end())
725 {
726 ConditionTypeContainer::const_iterator i = (*itr).second.find(eventId + 1);
727 if (i != (*itr).second.end())
728 {
729 cond = (*i).second;
730 SF_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d event_id %u", entryOrGuid, eventId);
731 }
732 }
733 return cond;
734}
735
737{
738 ConditionList cond;
739 NpcVendorConditionContainer::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId);
740 if (itr != NpcVendorConditionContainerStore.end())
741 {
742 ConditionTypeContainer::const_iterator i = (*itr).second.find(itemId);
743 if (i != (*itr).second.end())
744 {
745 cond = (*i).second;
746 SF_LOG_DEBUG("condition", "GetConditionsForNpcVendorEvent: found conditions for creature entry %u item %u", creatureId, itemId);
747 }
748 }
749 return cond;
750}
751
753{
754 uint32 oldMSTime = getMSTime();
755
756 Clean();
757
758 //must clear all custom handled cases (groupped types) before reload
759 if (isReload)
760 {
761 SF_LOG_INFO("misc", "Reseting Loot Conditions...");
762 LootTemplates_Creature.ResetConditions();
763 LootTemplates_Fishing.ResetConditions();
764 LootTemplates_Gameobject.ResetConditions();
765 LootTemplates_Item.ResetConditions();
766 LootTemplates_Mail.ResetConditions();
767 LootTemplates_Milling.ResetConditions();
768 LootTemplates_Pickpocketing.ResetConditions();
769 LootTemplates_Reference.ResetConditions();
770 LootTemplates_Skinning.ResetConditions();
771 LootTemplates_Disenchant.ResetConditions();
772 LootTemplates_Prospecting.ResetConditions();
773 LootTemplates_Spell.ResetConditions();
774
775 SF_LOG_INFO("misc", "Re-Loading `gossip_menu` Table for Conditions!");
776 sObjectMgr->LoadGossipMenu();
777
778 SF_LOG_INFO("misc", "Re-Loading `gossip_menu_option` Table for Conditions!");
779 sObjectMgr->LoadGossipMenuItems();
780 sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
781
782 SF_LOG_INFO("misc", "Re-Loading `terrain_phase_info` Table for Conditions!");
783 sObjectMgr->LoadTerrainPhaseInfo();
784
785 SF_LOG_INFO("misc", "Re-Loading `terrain_swap_defaults` Table for Conditions!");
786 sObjectMgr->LoadTerrainSwapDefaults();
787
788 SF_LOG_INFO("misc", "Re-Loading `terrain_worldmap` Table for Conditions!");
789 sObjectMgr->LoadTerrainWorldMaps();
790
791 SF_LOG_INFO("misc", "Re-Loading `phase_area` Table for Conditions!");
792 sObjectMgr->LoadAreaPhases();
793 }
794
795 QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
796 " ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName FROM conditions");
797
798 if (!result)
799 {
800 SF_LOG_ERROR("server.loading", ">> Loaded 0 conditions. DB table `conditions` is empty!");
801 return;
802 }
803
804 uint32 count = 0;
805
806 do
807 {
808 Field* fields = result->Fetch();
809
810 Condition* cond = new Condition();
811 int32 iSourceTypeOrReferenceId = fields[0].GetInt32();
812 cond->SourceGroup = fields[1].GetUInt32();
813 cond->SourceEntry = fields[2].GetInt32();
814 cond->SourceId = fields[3].GetInt32();
815 cond->ElseGroup = fields[4].GetUInt32();
816 int32 iConditionTypeOrReference = fields[5].GetInt32();
817 cond->ConditionTarget = fields[6].GetUInt8();
818 cond->ConditionValue1 = fields[7].GetUInt32();
819 cond->ConditionValue2 = fields[8].GetUInt32();
820 cond->ConditionValue3 = fields[9].GetUInt32();
821 cond->NegativeCondition = fields[10].GetUInt8();
822 cond->ErrorType = SpellCastResult(fields[11].GetUInt32());
823 cond->ErrorTextId = fields[12].GetUInt32();
824 cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetCString());
825
826 if (iConditionTypeOrReference >= 0)
827 cond->ConditionType = ConditionTypes(iConditionTypeOrReference);
828
829 if (iSourceTypeOrReferenceId >= 0)
830 cond->SourceType = ConditionSourceType(iSourceTypeOrReferenceId);
831
832 if (iConditionTypeOrReference < 0)//it has a reference
833 {
834 if (iConditionTypeOrReference == iSourceTypeOrReferenceId)//self referencing, skip
835 {
836 SF_LOG_ERROR("sql.sql", "Condition reference %i is referencing self, skipped", iSourceTypeOrReferenceId);
837 delete cond;
838 continue;
839 }
840 cond->ReferenceId = uint32(abs(iConditionTypeOrReference));
841
842 const char* rowType = "reference template";
843 if (iSourceTypeOrReferenceId >= 0)
844 rowType = "reference";
845 //check for useless data
846 if (cond->ConditionTarget)
847 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in ConditionTarget (%u)!", rowType, iSourceTypeOrReferenceId, cond->ConditionTarget);
848 if (cond->ConditionValue1)
849 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in value1 (%u)!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue1);
850 if (cond->ConditionValue2)
851 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in value2 (%u)!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue2);
852 if (cond->ConditionValue3)
853 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in value3 (%u)!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue3);
854 if (cond->NegativeCondition)
855 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in NegativeCondition (%u)!", rowType, iSourceTypeOrReferenceId, cond->NegativeCondition);
856 if (cond->SourceGroup && iSourceTypeOrReferenceId < 0)
857 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in SourceGroup (%u)!", rowType, iSourceTypeOrReferenceId, cond->SourceGroup);
858 if (cond->SourceEntry && iSourceTypeOrReferenceId < 0)
859 SF_LOG_ERROR("sql.sql", "Condition %s %i has useless data in SourceEntry (%u)!", rowType, iSourceTypeOrReferenceId, cond->SourceEntry);
860 }
861 else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType
862 {
863 delete cond;
864 continue;
865 }
866
867 if (iSourceTypeOrReferenceId < 0)//it is a reference template
868 {
869 uint32 uRefId = abs(iSourceTypeOrReferenceId);
870 if (ConditionReferenceStore.find(uRefId) == ConditionReferenceStore.end())//make sure we have a list for our conditions, based on reference id
871 {
872 ConditionList mCondList;
873 ConditionReferenceStore[uRefId] = mCondList;
874 }
875 ConditionReferenceStore[uRefId].push_back(cond);//add to reference storage
876 count++;
877 continue;
878 }//end of reference templates
879
880 //if not a reference and SourceType is invalid, skip
881 if (iConditionTypeOrReference >= 0 && !isSourceTypeValid(cond))
882 {
883 delete cond;
884 continue;
885 }
886
887 //Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
888 if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
889 {
890 SF_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup);
891 delete cond;
892 continue;
893 }
894 if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
895 {
896 SF_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId);
897 delete cond;
898 continue;
899 }
900
902 {
903 SF_LOG_ERROR("sql.sql", "Condition type %u entry %i can't have ErrorType (%u), set to 0!", uint32(cond->SourceType), cond->SourceEntry, uint32(cond->ErrorType));
905 }
906
908 {
909 SF_LOG_ERROR("sql.sql", "Condition type %u entry %i has any ErrorType, ErrorTextId (%u) is set, set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorTextId);
910 cond->ErrorTextId = 0;
911 }
912
913 if (cond->SourceGroup)
914 {
915 bool valid = false;
916 // handle grouped conditions
917 switch (cond->SourceType)
918 {
920 valid = addToLootTemplate(cond, LootTemplates_Creature.GetLootForConditionFill(cond->SourceGroup));
921 break;
923 valid = addToLootTemplate(cond, LootTemplates_Disenchant.GetLootForConditionFill(cond->SourceGroup));
924 break;
926 valid = addToLootTemplate(cond, LootTemplates_Fishing.GetLootForConditionFill(cond->SourceGroup));
927 break;
929 valid = addToLootTemplate(cond, LootTemplates_Gameobject.GetLootForConditionFill(cond->SourceGroup));
930 break;
932 valid = addToLootTemplate(cond, LootTemplates_Item.GetLootForConditionFill(cond->SourceGroup));
933 break;
935 valid = addToLootTemplate(cond, LootTemplates_Mail.GetLootForConditionFill(cond->SourceGroup));
936 break;
938 valid = addToLootTemplate(cond, LootTemplates_Milling.GetLootForConditionFill(cond->SourceGroup));
939 break;
941 valid = addToLootTemplate(cond, LootTemplates_Pickpocketing.GetLootForConditionFill(cond->SourceGroup));
942 break;
944 valid = addToLootTemplate(cond, LootTemplates_Prospecting.GetLootForConditionFill(cond->SourceGroup));
945 break;
947 valid = addToLootTemplate(cond, LootTemplates_Reference.GetLootForConditionFill(cond->SourceGroup));
948 break;
950 valid = addToLootTemplate(cond, LootTemplates_Skinning.GetLootForConditionFill(cond->SourceGroup));
951 break;
953 valid = addToLootTemplate(cond, LootTemplates_Spell.GetLootForConditionFill(cond->SourceGroup));
954 break;
956 valid = addToGossipMenus(cond);
957 break;
959 valid = addToGossipMenuItems(cond);
960 break;
962 {
963 SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
964 valid = true;
965 ++count;
966 continue; // do not add to m_AllocatedMemory to avoid double deleting
967 }
970 break;
972 {
973 VehicleSpellConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
974 valid = true;
975 ++count;
976 continue; // do not add to m_AllocatedMemory to avoid double deleting
977 }
979 {
981 std::pair<int32, uint32> key = std::make_pair(cond->SourceEntry, cond->SourceId);
982 SmartEventConditionStore[key][cond->SourceGroup].push_back(cond);
983 valid = true;
984 ++count;
985 continue;
986 }
988 {
989 NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
990 valid = true;
991 ++count;
992 continue;
993 }
995 {
996 valid = addToPhases(cond);
997 break;
998 }
999 default:
1000 break;
1001 }
1002
1003 if (!valid)
1004 {
1005 SF_LOG_ERROR("sql.sql", "Not handled grouped condition, SourceGroup %u", cond->SourceGroup);
1006 delete cond;
1007 }
1008 else
1009 {
1010 AllocatedMemoryStore.push_back(cond);
1011 ++count;
1012 }
1013 continue;
1014 }
1016 {
1017 if (!addToTerrainSwaps(cond))
1018 {
1019 delete cond;
1020 continue;
1021 }
1022
1023 ++count;
1024 continue;
1025 }
1026
1027 //handle not grouped conditions
1028 //make sure we have a storage list for our SourceType
1029 if (ConditionStore.find(cond->SourceType) == ConditionStore.end())
1030 {
1031 ConditionTypeContainer mTypeMap;
1032 ConditionStore[cond->SourceType] = mTypeMap;//add new empty list for SourceType
1033 }
1034
1035 //make sure we have a condition list for our SourceType's entry
1036 if (ConditionStore[cond->SourceType].find(cond->SourceEntry) == ConditionStore[cond->SourceType].end())
1037 {
1038 ConditionList mCondList;
1039 ConditionStore[cond->SourceType][cond->SourceEntry] = mCondList;
1040 }
1041
1042 //add new Condition to storage based on Type/Entry
1043 ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond);
1044 ++count;
1045 } while (result->NextRow());
1046
1047 SF_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
1048}
1049
1051{
1052 if (!loot)
1053 {
1054 SF_LOG_ERROR("sql.sql", "ConditionMgr: LootTemplate %u not found", cond->SourceGroup);
1055 return false;
1056 }
1057
1058 if (loot->addConditionItem(cond))
1059 return true;
1060
1061 SF_LOG_ERROR("sql.sql", "ConditionMgr: Item %u not found in LootTemplate %u", cond->SourceEntry, cond->SourceGroup);
1062 return false;
1063}
1064
1066{
1067 GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr->GetGossipMenusMapBoundsNonConst(cond->SourceGroup);
1068
1069 if (pMenuBounds.first != pMenuBounds.second)
1070 {
1071 for (GossipMenusContainer::iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr)
1072 {
1073 if ((*itr).second.entry == cond->SourceGroup && (*itr).second.text_id == uint32(cond->SourceEntry))
1074 {
1075 (*itr).second.conditions.push_back(cond);
1076 return true;
1077 }
1078 }
1079 }
1080
1081 SF_LOG_ERROR("sql.sql", "addToGossipMenus: GossipMenu %u not found", cond->SourceGroup);
1082 return false;
1083}
1084
1086{
1087 GossipMenuItemsMapBoundsNonConst pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBoundsNonConst(cond->SourceGroup);
1088 if (pMenuItemBounds.first != pMenuItemBounds.second)
1089 {
1090 for (GossipMenuItemsContainer::iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr)
1091 {
1092 if ((*itr).second.MenuID == cond->SourceGroup && (*itr).second.OptionID == uint32(cond->SourceEntry))
1093 {
1094 (*itr).second.Conditions.push_back(cond);
1095 return true;
1096 }
1097 }
1098 }
1099
1100 SF_LOG_ERROR("sql.sql", "addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->SourceGroup, cond->SourceEntry);
1101 return false;
1102}
1103
1105{
1106 uint32 conditionEffMask = cond->SourceGroup;
1107 SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->GetSpellInfo(cond->SourceEntry));
1108 ASSERT(spellInfo);
1109 std::list<uint32> sharedMasks;
1110 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1111 {
1112 // check if effect is already a part of some shared mask
1113 bool found = false;
1114 for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
1115 {
1116 if ((1 << i) & *itr)
1117 {
1118 found = true;
1119 break;
1120 }
1121 }
1122 if (found)
1123 continue;
1124
1125 // build new shared mask with found effect
1126 uint32 sharedMask = (1 << i);
1127 ConditionList* cmp = spellInfo->Effects[i].ImplicitTargetConditions;
1128 for (uint8 effIndex = i + 1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
1129 {
1130 if (spellInfo->Effects[effIndex].ImplicitTargetConditions == cmp)
1131 sharedMask |= 1 << effIndex;
1132 }
1133 sharedMasks.push_back(sharedMask);
1134 }
1135
1136 for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
1137 {
1138 // some effect indexes should have same data
1139 if (uint32 commonMask = *itr & conditionEffMask)
1140 {
1141 uint8 firstEffIndex = 0;
1142 for (; firstEffIndex < MAX_SPELL_EFFECTS; ++firstEffIndex)
1143 if ((1 << firstEffIndex) & *itr)
1144 break;
1145
1146 if (firstEffIndex >= MAX_SPELL_EFFECTS)
1147 return false;
1148
1149 // get shared data
1150 ConditionList* sharedList = spellInfo->Effects[firstEffIndex].ImplicitTargetConditions;
1151
1152 // there's already data entry for that sharedMask
1153 if (sharedList)
1154 {
1155 // we have overlapping masks in db
1156 if (conditionEffMask != *itr)
1157 {
1158 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
1159 "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup);
1160 return false;
1161 }
1162 }
1163 // no data for shared mask, we can create new submask
1164 else
1165 {
1166 // add new list, create new shared mask
1167 sharedList = new ConditionList();
1168 bool assigned = false;
1169 for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i)
1170 {
1171 if ((1 << i) & commonMask)
1172 {
1173 spellInfo->Effects[i].ImplicitTargetConditions = sharedList;
1174 assigned = true;
1175 }
1176 }
1177
1178 if (!assigned)
1179 delete sharedList;
1180 }
1181 sharedList->push_back(cond);
1182 break;
1183 }
1184 }
1185 return true;
1186}
1187
1189{
1190 bool added = false;
1191 for (auto itr = swaps.begin(); itr != swaps.end(); ++itr)
1192 for (auto it2 = itr->second.begin(); it2 != itr->second.end(); ++it2)
1193 if (it2->id == uint32(cond->SourceEntry))
1194 it2->Conditions.push_back(cond), added = true;
1195
1196 return added;
1197}
1198
1200{
1201 bool added = false;
1202 added = addToTerrainSwapStore(sObjectMgr->GetPhaseTerrainSwapStoreForLoading(), cond);
1203 added = addToTerrainSwapStore(sObjectMgr->GetDefaultTerrainSwapStoreForLoading(), cond) || added;
1204 if (added)
1205 return true;
1206
1207 SF_LOG_ERROR("sql.sql", "No terrain swap with map %u exists.", cond->SourceEntry);
1208 return false;
1209}
1210
1212{
1213 if (!cond->SourceEntry)
1214 {
1215 PhaseInfo& p = sObjectMgr->GetAreaPhasesForLoading();
1216 for (auto phaseItr = p.begin(); phaseItr != p.end(); ++phaseItr)
1217 {
1218 for (PhaseInfoStruct& phase : phaseItr->second)
1219 {
1220 if (phase.id == cond->SourceGroup)
1221 {
1222 phase.Conditions.push_back(cond);
1223 return true;
1224 }
1225 }
1226 }
1227 }
1228 else if (std::vector<PhaseInfoStruct>* phases = sObjectMgr->GetPhasesForAreaForLoading(cond->SourceEntry))
1229 {
1230 for (PhaseInfoStruct& phase : *phases)
1231 {
1232 if (phase.id == cond->SourceGroup)
1233 {
1234 phase.Conditions.push_back(cond);
1235 return true;
1236 }
1237 }
1238 }
1239
1240 SF_LOG_ERROR("sql.sql", "Phase %u does not have Area %u.", cond->SourceGroup, cond->SourceEntry);
1241 return false;
1242}
1243
1245{
1247 {
1248 SF_LOG_ERROR("sql.sql", "Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->SourceType));
1249 return false;
1250 }
1251
1252 switch (cond->SourceType)
1253 {
1255 {
1256 if (!LootTemplates_Creature.HaveLootFor(cond->SourceGroup))
1257 {
1258 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->SourceGroup);
1259 return false;
1260 }
1261
1262 LootTemplate* loot = LootTemplates_Creature.GetLootForConditionFill(cond->SourceGroup);
1263 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1264 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1265 {
1266 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1267 return false;
1268 }
1269 break;
1270 }
1272 {
1273 if (!LootTemplates_Disenchant.HaveLootFor(cond->SourceGroup))
1274 {
1275 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->SourceGroup);
1276 return false;
1277 }
1278
1279 LootTemplate* loot = LootTemplates_Disenchant.GetLootForConditionFill(cond->SourceGroup);
1280 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1281 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1282 {
1283 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1284 return false;
1285 }
1286 break;
1287 }
1289 {
1290 if (!LootTemplates_Fishing.HaveLootFor(cond->SourceGroup))
1291 {
1292 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->SourceGroup);
1293 return false;
1294 }
1295
1296 LootTemplate* loot = LootTemplates_Fishing.GetLootForConditionFill(cond->SourceGroup);
1297 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1298 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1299 {
1300 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1301 return false;
1302 }
1303 break;
1304 }
1306 {
1307 if (!LootTemplates_Gameobject.HaveLootFor(cond->SourceGroup))
1308 {
1309 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->SourceGroup);
1310 return false;
1311 }
1312
1313 LootTemplate* loot = LootTemplates_Gameobject.GetLootForConditionFill(cond->SourceGroup);
1314 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1315 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1316 {
1317 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1318 return false;
1319 }
1320 break;
1321 }
1323 {
1324 if (!LootTemplates_Item.HaveLootFor(cond->SourceGroup))
1325 {
1326 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->SourceGroup);
1327 return false;
1328 }
1329
1330 LootTemplate* loot = LootTemplates_Item.GetLootForConditionFill(cond->SourceGroup);
1331 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1332 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1333 {
1334 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1335 return false;
1336 }
1337 break;
1338 }
1340 {
1341 if (!LootTemplates_Mail.HaveLootFor(cond->SourceGroup))
1342 {
1343 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->SourceGroup);
1344 return false;
1345 }
1346
1347 LootTemplate* loot = LootTemplates_Mail.GetLootForConditionFill(cond->SourceGroup);
1348 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1349 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1350 {
1351 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1352 return false;
1353 }
1354 break;
1355 }
1357 {
1358 if (!LootTemplates_Milling.HaveLootFor(cond->SourceGroup))
1359 {
1360 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->SourceGroup);
1361 return false;
1362 }
1363
1364 LootTemplate* loot = LootTemplates_Milling.GetLootForConditionFill(cond->SourceGroup);
1365 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1366 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1367 {
1368 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1369 return false;
1370 }
1371 break;
1372 }
1374 {
1375 if (!LootTemplates_Pickpocketing.HaveLootFor(cond->SourceGroup))
1376 {
1377 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->SourceGroup);
1378 return false;
1379 }
1380
1381 LootTemplate* loot = LootTemplates_Pickpocketing.GetLootForConditionFill(cond->SourceGroup);
1382 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1383 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1384 {
1385 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1386 return false;
1387 }
1388 break;
1389 }
1391 {
1392 if (!LootTemplates_Prospecting.HaveLootFor(cond->SourceGroup))
1393 {
1394 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->SourceGroup);
1395 return false;
1396 }
1397
1398 LootTemplate* loot = LootTemplates_Prospecting.GetLootForConditionFill(cond->SourceGroup);
1399 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1400 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1401 {
1402 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1403 return false;
1404 }
1405 break;
1406 }
1408 {
1409 if (!LootTemplates_Reference.HaveLootFor(cond->SourceGroup))
1410 {
1411 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->SourceGroup);
1412 return false;
1413 }
1414
1415 LootTemplate* loot = LootTemplates_Reference.GetLootForConditionFill(cond->SourceGroup);
1416 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1417 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1418 {
1419 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1420 return false;
1421 }
1422 break;
1423 }
1425 {
1426 if (!LootTemplates_Skinning.HaveLootFor(cond->SourceGroup))
1427 {
1428 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->SourceGroup);
1429 return false;
1430 }
1431
1432 LootTemplate* loot = LootTemplates_Skinning.GetLootForConditionFill(cond->SourceGroup);
1433 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1434 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1435 {
1436 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1437 return false;
1438 }
1439 break;
1440 }
1442 {
1443 if (!LootTemplates_Spell.HaveLootFor(cond->SourceGroup))
1444 {
1445 SF_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->SourceGroup);
1446 return false;
1447 }
1448
1449 LootTemplate* loot = LootTemplates_Spell.GetLootForConditionFill(cond->SourceGroup);
1450 ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1451 if (!pItemProto && !loot->isReference(cond->SourceEntry))
1452 {
1453 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
1454 return false;
1455 }
1456 break;
1457 }
1459 {
1460 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry);
1461 if (!spellInfo)
1462 {
1463 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
1464 return false;
1465 }
1466
1467 if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup)
1468 {
1469 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set, ignoring.", cond->SourceEntry, cond->SourceGroup);
1470 return false;
1471 }
1472
1473 uint32 origGroup = cond->SourceGroup;
1474
1475 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1476 {
1477 if (!((1 << i) & cond->SourceGroup))
1478 continue;
1479
1480 switch (spellInfo->Effects[i].TargetA.GetSelectionCategory())
1481 {
1485 continue;
1486 default:
1487 break;
1488 }
1489
1490 switch (spellInfo->Effects[i].TargetB.GetSelectionCategory())
1491 {
1495 continue;
1496 default:
1497 break;
1498 }
1499
1500 SF_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
1501 cond->SourceGroup &= ~(1 << i);
1502 }
1503 // all effects were removed, no need to add the condition at all
1504 if (!cond->SourceGroup)
1505 return false;
1506 break;
1507 }
1509 {
1510 if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry))
1511 {
1512 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceEntry);
1513 return false;
1514 }
1515 break;
1516 }
1519 {
1520 SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
1521 if (!spellProto)
1522 {
1523 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
1524 return false;
1525 }
1526 break;
1527 }
1529 if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
1530 {
1531 SF_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->SourceEntry);
1532 return false;
1533 }
1534 break;
1536 if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
1537 {
1538 SF_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->SourceEntry);
1539 return false;
1540 }
1541 break;
1543 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1544 {
1545 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
1546 return false;
1547 }
1548
1549 if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
1550 {
1551 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
1552 return false;
1553 }
1554 break;
1556 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1557 {
1558 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
1559 return false;
1560 }
1561
1562 if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
1563 {
1564 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
1565 return false;
1566 }
1567 break;
1569 {
1570 if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
1571 {
1572 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
1573 return false;
1574 }
1575 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry);
1576 if (!itemTemplate)
1577 {
1578 SF_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry);
1579 return false;
1580 }
1581 break;
1582 }
1584 {
1585 if (!sMapStore.LookupEntry(cond->SourceEntry))
1586 {
1587 SF_LOG_ERROR("sql.sql", "%u SourceEntry in `condition` table, does not exist in Map.dbc, ignoring.", cond->SourceEntry);
1588 return false;
1589 }
1590 break;
1591 }
1593 {
1594 if (cond->SourceEntry && !GetAreaEntryByAreaID(cond->SourceEntry))
1595 {
1596 SF_LOG_ERROR("sql.sql", "%u SourceEntry in `condition` table, does not exist in AreaTable.dbc, ignoring.", cond->SourceEntry);
1597 return false;
1598 }
1599 break;
1600 }
1605 default:
1606 break;
1607 }
1608
1609 return true;
1610}
1611
1613{
1615 {
1616 SF_LOG_ERROR("sql.sql", "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->ConditionType), cond->SourceEntry);
1617 return false;
1618 }
1619
1621 {
1622 SF_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup);
1623 return false;
1624 }
1625
1626 switch (cond->ConditionType)
1627 {
1628 case CONDITION_AURA:
1629 {
1630 if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
1631 {
1632 SF_LOG_ERROR("sql.sql", "Aura condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
1633 return false;
1634 }
1635
1636 if (cond->ConditionValue2 > EFFECT_2)
1637 {
1638 SF_LOG_ERROR("sql.sql", "Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2);
1639 return false;
1640 }
1641 if (cond->ConditionValue3)
1642 SF_LOG_ERROR("sql.sql", "Aura condition has useless data in value3 (%u)!", cond->ConditionValue3);
1643 break;
1644 }
1645 case CONDITION_ITEM:
1646 {
1647 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
1648 if (!proto)
1649 {
1650 SF_LOG_ERROR("sql.sql", "Item condition has non existing item (%u), skipped", cond->ConditionValue1);
1651 return false;
1652 }
1653
1654 if (!cond->ConditionValue2)
1655 {
1656 SF_LOG_ERROR("sql.sql", "Item condition has 0 set for item count in value2 (%u), skipped", cond->ConditionValue2);
1657 return false;
1658 }
1659 break;
1660 }
1662 {
1663 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
1664 if (!proto)
1665 {
1666 SF_LOG_ERROR("sql.sql", "ItemEquipped condition has non existing item (%u), skipped", cond->ConditionValue1);
1667 return false;
1668 }
1669
1670 if (cond->ConditionValue2)
1671 SF_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value2 (%u)!", cond->ConditionValue2);
1672 if (cond->ConditionValue3)
1673 SF_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value3 (%u)!", cond->ConditionValue3);
1674 break;
1675 }
1676 case CONDITION_ZONEID:
1677 {
1678 AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1);
1679 if (!areaEntry)
1680 {
1681 SF_LOG_ERROR("sql.sql", "ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1);
1682 return false;
1683 }
1684
1685 if (areaEntry->m_ParentAreaID != 0)
1686 {
1687 SF_LOG_ERROR("sql.sql", "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->ConditionValue1);
1688 return false;
1689 }
1690
1691 if (cond->ConditionValue2)
1692 SF_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value2 (%u)!", cond->ConditionValue2);
1693 if (cond->ConditionValue3)
1694 SF_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value3 (%u)!", cond->ConditionValue3);
1695 break;
1696 }
1698 {
1699 FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1);
1700 if (!factionEntry)
1701 {
1702 SF_LOG_ERROR("sql.sql", "Reputation condition has non existing faction (%u), skipped", cond->ConditionValue1);
1703 return false;
1704 }
1705 if (cond->ConditionValue3)
1706 SF_LOG_ERROR("sql.sql", "Reputation condition has useless data in value3 (%u)!", cond->ConditionValue3);
1707 break;
1708 }
1709 case CONDITION_TEAM:
1710 {
1711 if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE)
1712 {
1713 SF_LOG_ERROR("sql.sql", "Team condition specifies unknown team (%u), skipped", cond->ConditionValue1);
1714 return false;
1715 }
1716
1717 if (cond->ConditionValue2)
1718 SF_LOG_ERROR("sql.sql", "Team condition has useless data in value2 (%u)!", cond->ConditionValue2);
1719 if (cond->ConditionValue3)
1720 SF_LOG_ERROR("sql.sql", "Team condition has useless data in value3 (%u)!", cond->ConditionValue3);
1721 break;
1722 }
1723 case CONDITION_SKILL:
1724 {
1725 SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1);
1726 if (!pSkill)
1727 {
1728 SF_LOG_ERROR("sql.sql", "Skill condition specifies non-existing skill (%u), skipped", cond->ConditionValue1);
1729 return false;
1730 }
1731
1732 if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue())
1733 {
1734 SF_LOG_ERROR("sql.sql", "Skill condition specifies skill (%u) with invalid value (%u), skipped", cond->ConditionValue1, cond->ConditionValue2);
1735 return false;
1736 }
1737 if (cond->ConditionValue3)
1738 SF_LOG_ERROR("sql.sql", "Skill condition has useless data in value3 (%u)!", cond->ConditionValue3);
1739 break;
1740 }
1745 {
1746 if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1))
1747 {
1748 SF_LOG_ERROR("sql.sql", "Quest condition (Type: %u) points to non-existing quest (%u) for Source Entry %u. SourceGroup: %u, SourceTypeOrReferenceId: %u",
1749 cond->ConditionType, cond->ConditionValue1, cond->SourceEntry, cond->SourceGroup, cond->SourceType);
1750 return false;
1751 }
1752
1753 if (cond->ConditionValue2 > 1)
1754 SF_LOG_ERROR("sql.sql", "Quest condition has useless data in value2 (%u)!", cond->ConditionValue2);
1755 if (cond->ConditionValue3)
1756 SF_LOG_ERROR("sql.sql", "Quest condition has useless data in value3 (%u)!", cond->ConditionValue3);
1757 break;
1758 }
1760 {
1761 GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
1762 if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid())
1763 {
1764 SF_LOG_ERROR("sql.sql", "ActiveEvent condition has non existing event id (%u), skipped", cond->ConditionValue1);
1765 return false;
1766 }
1767
1768 if (cond->ConditionValue2)
1769 SF_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value2 (%u)!", cond->ConditionValue2);
1770 if (cond->ConditionValue3)
1771 SF_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value3 (%u)!", cond->ConditionValue3);
1772 break;
1773 }
1775 {
1776 AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1);
1777 if (!achievement)
1778 {
1779 SF_LOG_ERROR("sql.sql", "Achivement condition has non existing achivement id (%u), skipped", cond->ConditionValue1);
1780 return false;
1781 }
1782
1783 if (cond->ConditionValue2)
1784 SF_LOG_ERROR("sql.sql", "Achivement condition has useless data in value2 (%u)!", cond->ConditionValue2);
1785 if (cond->ConditionValue3)
1786 SF_LOG_ERROR("sql.sql", "Achivement condition has useless data in value3 (%u)!", cond->ConditionValue3);
1787 break;
1788 }
1789 case CONDITION_CLASS:
1790 {
1792 {
1793 SF_LOG_ERROR("sql.sql", "Class condition has non existing classmask (%u), skipped", cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
1794 return false;
1795 }
1796
1797 if (cond->ConditionValue2)
1798 SF_LOG_ERROR("sql.sql", "Class condition has useless data in value2 (%u)!", cond->ConditionValue2);
1799 if (cond->ConditionValue3)
1800 SF_LOG_ERROR("sql.sql", "Class condition has useless data in value3 (%u)!", cond->ConditionValue3);
1801 break;
1802 }
1803 case CONDITION_RACE:
1804 {
1806 {
1807 SF_LOG_ERROR("sql.sql", "Race condition has non existing racemask (%u), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
1808 return false;
1809 }
1810
1811 if (cond->ConditionValue2)
1812 SF_LOG_ERROR("sql.sql", "Race condition has useless data in value2 (%u)!", cond->ConditionValue2);
1813 if (cond->ConditionValue3)
1814 SF_LOG_ERROR("sql.sql", "Race condition has useless data in value3 (%u)!", cond->ConditionValue3);
1815 break;
1816 }
1817 case CONDITION_GENDER:
1818 {
1820 {
1821 SF_LOG_ERROR("sql.sql", "Gender condition has invalid gender (%u), skipped", cond->ConditionValue1);
1822 return false;
1823 }
1824
1825 if (cond->ConditionValue2)
1826 SF_LOG_ERROR("sql.sql", "Gender condition has useless data in value2 (%u)!", cond->ConditionValue2);
1827 if (cond->ConditionValue3)
1828 SF_LOG_ERROR("sql.sql", "Gender condition has useless data in value3 (%u)!", cond->ConditionValue3);
1829 break;
1830 }
1831 case CONDITION_MAPID:
1832 {
1833 MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1);
1834 if (!me)
1835 {
1836 SF_LOG_ERROR("sql.sql", "Map condition has non existing map (%u), skipped", cond->ConditionValue1);
1837 return false;
1838 }
1839
1840 if (cond->ConditionValue2)
1841 SF_LOG_ERROR("sql.sql", "Map condition has useless data in value2 (%u)!", cond->ConditionValue2);
1842 if (cond->ConditionValue3)
1843 SF_LOG_ERROR("sql.sql", "Map condition has useless data in value3 (%u)!", cond->ConditionValue3);
1844 break;
1845 }
1846 case CONDITION_SPELL:
1847 {
1848 if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
1849 {
1850 SF_LOG_ERROR("sql.sql", "Spell condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
1851 return false;
1852 }
1853
1854 if (cond->ConditionValue2)
1855 SF_LOG_ERROR("sql.sql", "Spell condition has useless data in value2 (%u)!", cond->ConditionValue2);
1856 if (cond->ConditionValue3)
1857 SF_LOG_ERROR("sql.sql", "Spell condition has useless data in value3 (%u)!", cond->ConditionValue3);
1858 break;
1859 }
1860 case CONDITION_LEVEL:
1861 {
1862 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
1863 {
1864 SF_LOG_ERROR("sql.sql", "Level condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
1865 return false;
1866 }
1867 if (cond->ConditionValue3)
1868 SF_LOG_ERROR("sql.sql", "Level condition has useless data in value3 (%u)!", cond->ConditionValue3);
1869 break;
1870 }
1872 {
1873 if (cond->ConditionValue1 >= MAX_DRUNKEN)
1874 {
1875 SF_LOG_ERROR("sql.sql", "DrunkState condition has invalid state (%u), skipped", cond->ConditionValue1);
1876 return false;
1877 }
1878 if (cond->ConditionValue2)
1879 {
1880 SF_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value2 (%u)!", cond->ConditionValue2);
1881 return false;
1882 }
1883 if (cond->ConditionValue3)
1884 SF_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value3 (%u)!", cond->ConditionValue3);
1885 break;
1886 }
1888 {
1889 if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1))
1890 {
1891 SF_LOG_ERROR("sql.sql", "NearCreature condition has non existing creature template entry (%u), skipped", cond->ConditionValue1);
1892 return false;
1893 }
1894 if (cond->ConditionValue3)
1895 SF_LOG_ERROR("sql.sql", "NearCreature condition has useless data in value3 (%u)!", cond->ConditionValue3);
1896 break;
1897 }
1899 {
1900 if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1))
1901 {
1902 SF_LOG_ERROR("sql.sql", "NearGameObject condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue1);
1903 return false;
1904 }
1905 if (cond->ConditionValue3)
1906 SF_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3);
1907 break;
1908 }
1910 {
1911 switch (cond->ConditionValue1)
1912 {
1914 if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2))
1915 {
1916 SF_LOG_ERROR("sql.sql", "ObjectEntry condition has non existing creature template entry (%u), skipped", cond->ConditionValue2);
1917 return false;
1918 }
1919 break;
1921 if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2))
1922 {
1923 SF_LOG_ERROR("sql.sql", "ObjectEntry condition has non existing game object template entry (%u), skipped", cond->ConditionValue2);
1924 return false;
1925 }
1926 break;
1929 if (cond->ConditionValue2)
1930 SF_LOG_ERROR("sql.sql", "ObjectEntry condition has useless data in value2 (%u)!", cond->ConditionValue2);
1931 break;
1932 default:
1933 SF_LOG_ERROR("sql.sql", "ObjectEntry condition has wrong typeid set (%u), skipped", cond->ConditionValue1);
1934 return false;
1935 }
1936 if (cond->ConditionValue3)
1937 SF_LOG_ERROR("sql.sql", "ObjectEntry condition has useless data in value3 (%u)!", cond->ConditionValue3);
1938 break;
1939 }
1941 {
1943 {
1944 SF_LOG_ERROR("sql.sql", "TypeMask condition has invalid typemask set (%u), skipped", cond->ConditionValue2);
1945 return false;
1946 }
1947 if (cond->ConditionValue2)
1948 SF_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value2 (%u)!", cond->ConditionValue2);
1949 if (cond->ConditionValue3)
1950 SF_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value3 (%u)!", cond->ConditionValue3);
1951 break;
1952 }
1954 {
1956 {
1957 SF_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
1958 return false;
1959 }
1960 if (cond->ConditionValue1 == cond->ConditionTarget)
1961 {
1962 SF_LOG_ERROR("sql.sql", "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
1963 return false;
1964 }
1965 if (cond->ConditionValue2 >= RELATION_MAX)
1966 {
1967 SF_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->ConditionValue2);
1968 return false;
1969 }
1970 if (cond->ConditionValue3)
1971 SF_LOG_ERROR("sql.sql", "RelationTo condition has useless data in value3 (%u)!", cond->ConditionValue3);
1972 break;
1973 }
1975 {
1977 {
1978 SF_LOG_ERROR("sql.sql", "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
1979 return false;
1980 }
1981 if (cond->ConditionValue1 == cond->ConditionTarget)
1982 {
1983 SF_LOG_ERROR("sql.sql", "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
1984 return false;
1985 }
1986 if (!cond->ConditionValue2)
1987 {
1988 SF_LOG_ERROR("sql.sql", "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->ConditionValue2);
1989 return false;
1990 }
1991 break;
1992 }
1994 {
1996 {
1997 SF_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
1998 return false;
1999 }
2000 if (cond->ConditionValue1 == cond->ConditionTarget)
2001 {
2002 SF_LOG_ERROR("sql.sql", "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
2003 return false;
2004 }
2005 if (cond->ConditionValue3 >= COMP_TYPE_MAX)
2006 {
2007 SF_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ComparisionType (%u), skipped", cond->ConditionValue3);
2008 return false;
2009 }
2010 break;
2011 }
2012 case CONDITION_ALIVE:
2013 {
2014 if (cond->ConditionValue1)
2015 SF_LOG_ERROR("sql.sql", "Alive condition has useless data in value1 (%u)!", cond->ConditionValue1);
2016 if (cond->ConditionValue2)
2017 SF_LOG_ERROR("sql.sql", "Alive condition has useless data in value2 (%u)!", cond->ConditionValue2);
2018 if (cond->ConditionValue3)
2019 SF_LOG_ERROR("sql.sql", "Alive condition has useless data in value3 (%u)!", cond->ConditionValue3);
2020 break;
2021 }
2022 case CONDITION_HP_VAL:
2023 {
2024 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
2025 {
2026 SF_LOG_ERROR("sql.sql", "HpVal condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
2027 return false;
2028 }
2029 if (cond->ConditionValue3)
2030 SF_LOG_ERROR("sql.sql", "HpVal condition has useless data in value3 (%u)!", cond->ConditionValue3);
2031 break;
2032 }
2033 case CONDITION_HP_PCT:
2034 {
2035 if (cond->ConditionValue1 > 100)
2036 {
2037 SF_LOG_ERROR("sql.sql", "HpPct condition has too big percent value (%u), skipped", cond->ConditionValue1);
2038 return false;
2039 }
2040 if (cond->ConditionValue2 >= COMP_TYPE_MAX)
2041 {
2042 SF_LOG_ERROR("sql.sql", "HpPct condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
2043 return false;
2044 }
2045 if (cond->ConditionValue3)
2046 SF_LOG_ERROR("sql.sql", "HpPct condition has useless data in value3 (%u)!", cond->ConditionValue3);
2047 break;
2048 }
2049 case CONDITION_AREAID:
2051 break;
2053 {
2054 if (!sWorld->getWorldState(cond->ConditionValue1))
2055 {
2056 SF_LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 (%u), skipped", cond->ConditionValue1);
2057 return false;
2058 }
2059 if (cond->ConditionValue3)
2060 SF_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3);
2061 break;
2062 }
2063 case CONDITION_PHASEID:
2064 {
2065 if (!sPhaseStore.LookupEntry(cond->ConditionValue1))
2066 {
2067 SF_LOG_ERROR("sql.sql", "Phase condition has nonexistent phaseid in value1 (%u), skipped", cond->ConditionValue1);
2068 return false;
2069 }
2070 if (cond->ConditionValue2)
2071 SF_LOG_ERROR("sql.sql", "Phase condition has useless data in value2 (%u)!", cond->ConditionValue2);
2072 if (cond->ConditionValue3)
2073 SF_LOG_ERROR("sql.sql", "Phase condition has useless data in value3 (%u)!", cond->ConditionValue3);
2074 break;
2075 }
2077 {
2078 if (cond->ConditionValue2)
2079 SF_LOG_ERROR("sql.sql", "Terrain swap condition has useless data in value2 (%u)!", cond->ConditionValue2);
2080 if (cond->ConditionValue3)
2081 SF_LOG_ERROR("sql.sql", "Terrain swap condition has useless data in value3 (%u)!", cond->ConditionValue3);
2082 break;
2083 }
2084 case CONDITION_TITLE:
2085 {
2086 CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1);
2087 if (!titleEntry)
2088 {
2089 SF_LOG_ERROR("sql.sql", "Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1);
2090 return false;
2091 }
2092 break;
2093 }
2095 {
2097 {
2098 SF_LOG_ERROR("sql.sql", "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1);
2099 return false;
2100 }
2101 break;
2102 }
2104 {
2106 {
2107 SF_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1);
2108 return false;
2109 }
2110 break;
2111 }
2113 {
2115 {
2116 SF_LOG_ERROR("sql.sql", "CreatureType condition has non existing CreatureType in value1 (%u), skipped", cond->ConditionValue1);
2117 return false;
2118 }
2119 break;
2120 }
2121 default:
2122 break;
2123 }
2124 return true;
2125}
2126
2128{
2129 for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
2130 {
2131 for (ConditionList::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2132 delete* it;
2133 itr->second.clear();
2134 }
2135
2137
2138 for (ConditionContainer::iterator itr = ConditionStore.begin(); itr != ConditionStore.end(); ++itr)
2139 {
2140 for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2141 {
2142 for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2143 delete* i;
2144 it->second.clear();
2145 }
2146 itr->second.clear();
2147 }
2148
2149 ConditionStore.clear();
2150
2151 for (CreatureSpellConditionContainer::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
2152 {
2153 for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2154 {
2155 for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2156 delete* i;
2157 it->second.clear();
2158 }
2159 itr->second.clear();
2160 }
2161
2163
2164 for (SmartEventConditionContainer::iterator itr = SmartEventConditionStore.begin(); itr != SmartEventConditionStore.end(); ++itr)
2165 {
2166 for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2167 {
2168 for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2169 delete* i;
2170 it->second.clear();
2171 }
2172 itr->second.clear();
2173 }
2174
2176
2177 for (CreatureSpellConditionContainer::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
2178 {
2179 for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2180 {
2181 for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2182 delete* i;
2183 it->second.clear();
2184 }
2185 itr->second.clear();
2186 }
2187
2189
2190 for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
2191 {
2192 for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
2193 {
2194 for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
2195 delete* i;
2196 it->second.clear();
2197 }
2198 itr->second.clear();
2199 }
2200
2202
2203 // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
2204 for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
2205 delete* itr;
2206
2207 AllocatedMemoryStore.clear();
2208}
#define sAchievementMgr
static bool addToTerrainSwapStore(TerrainPhaseInfo &swaps, Condition *cond)
ConditionSourceType
@ CONDITION_SOURCE_TYPE_MAX
@ CONDITION_SOURCE_TYPE_VEHICLE_SPELL
@ CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_QUEST_ACCEPT
@ CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_TERRAIN_SWAP
@ CONDITION_SOURCE_TYPE_NPC_VENDOR
@ CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION
@ CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT
@ CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK
@ CONDITION_SOURCE_TYPE_PHASE
@ CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_SMART_EVENT
@ CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_SPELL
@ CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_GOSSIP_MENU
@ CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE
@ CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET
@ CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE
@ CONDITION_SOURCE_TYPE_SPELL_PROC
@ CONDITION_SOURCE_TYPE_NONE
@ INSTANCE_INFO_DATA64
@ INSTANCE_INFO_DATA
@ INSTANCE_INFO_BOSS_STATE
@ MAX_CONDITION_TARGETS
ConditionTypes
@ CONDITION_OBJECT_ENTRY
@ CONDITION_MAPID
@ CONDITION_SKILL
@ CONDITION_RACE
@ CONDITION_PHASEID
@ CONDITION_REACTION_TO
@ CONDITION_NEAR_GAMEOBJECT
@ CONDITION_QUESTREWARDED
@ CONDITION_ACTIVE_EVENT
@ CONDITION_INSTANCE_INFO
@ CONDITION_RELATION_TO
@ CONDITION_DRUNKENSTATE
@ CONDITION_AURA
@ CONDITION_ACHIEVEMENT
@ CONDITION_DISTANCE_TO
@ CONDITION_HP_VAL
@ CONDITION_GENDER
@ CONDITION_TERRAIN_SWAP
@ CONDITION_REPUTATION_RANK
@ CONDITION_HP_PCT
@ CONDITION_QUEST_COMPLETE
@ CONDITION_MAX
@ CONDITION_SPELL
@ CONDITION_ZONEID
@ CONDITION_TYPE_MASK
@ CONDITION_AREAID
@ CONDITION_ITEM
@ CONDITION_WORLD_STATE
@ CONDITION_SPAWNMASK
@ CONDITION_CLASS
@ CONDITION_TEAM
@ CONDITION_NONE
@ CONDITION_QUEST_NONE
@ CONDITION_ITEM_EQUIPPED
@ CONDITION_LEVEL
@ CONDITION_QUESTTAKEN
@ CONDITION_NEAR_CREATURE
@ CONDITION_TITLE
@ CONDITION_ALIVE
@ CONDITION_CREATURE_TYPE
@ CONDITION_UNIT_STATE
std::list< Condition * > ConditionList
std::map< uint32, ConditionList > ConditionTypeContainer
@ RELATION_IN_PARTY
@ RELATION_IN_RAID_OR_PARTY
@ RELATION_CREATED_BY
@ RELATION_MAX
@ RELATION_SELF
@ RELATION_PASSENGER_OF
@ RELATION_OWNED_BY
@ SPAWNMASK_RAID_ALL
Definition DBCEnums.h:364
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< PhaseEntry > sPhaseStore(PhaseEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
AreaTableEntry const * GetAreaEntryByAreaID(uint32 area_id)
#define MAX_EFFECT_MASK
#define MAX_SPELL_EFFECTS
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
#define sGameEventMgr
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:63
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:60
@ GRID_MAP_TYPE_MASK_ALL
Definition GridDefines.h:65
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition GridDefines.h:62
@ GRID_MAP_TYPE_MASK_CORPSE
Definition GridDefines.h:59
@ GRID_MAP_TYPE_MASK_AREATRIGGER
Definition GridDefines.h:64
EncounterState
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
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_PLAYER
Definition Object.h:55
@ TYPEID_GAMEOBJECT
Definition Object.h:56
@ TYPEID_UNIT
Definition Object.h:54
@ TYPEID_CORPSE
Definition Object.h:58
@ TYPEID_AREATRIGGER
Definition Object.h:59
@ TYPEMASK_UNIT
Definition Object.h:40
@ TYPEMASK_CORPSE
Definition Object.h:44
@ TYPEMASK_GAMEOBJECT
Definition Object.h:42
@ TYPEMASK_PLAYER
Definition Object.h:41
@ TYPEMASK_AREATRIGGER
Definition Object.h:45
UNORDERED_MAP< uint32, std::vector< PhaseInfoStruct > > PhaseInfo
Definition ObjectMgr.h:707
#define sObjectMgr
Definition ObjectMgr.h:1617
UNORDERED_MAP< uint32, std::vector< PhaseInfoStruct > > TerrainPhaseInfo
Definition ObjectMgr.h:705
std::pair< GossipMenuItemsContainer::iterator, GossipMenuItemsContainer::iterator > GossipMenuItemsMapBoundsNonConst
Definition ObjectMgr.h:556
std::pair< GossipMenusContainer::iterator, GossipMenusContainer::iterator > GossipMenusMapBoundsNonConst
Definition ObjectMgr.h:553
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
Definition QueryResult.h:48
QuestStatus
Definition QuestDef.h:85
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
@ QUEST_STATUS_NONE
Definition QuestDef.h:86
@ QUEST_STATUS_COMPLETE
Definition QuestDef.h:87
#define sScriptMgr
Definition ScriptMgr.h:764
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive)
GameObject * GetClosestGameObjectWithEntry(WorldObject *source, uint32 entry, float maxSearchRange)
@ EFFECT_2
@ CREATURE_TYPE_GAS_CLOUD
@ ALLIANCE
@ HORDE
#define MAX_DRUNKEN
#define CLASSMASK_ALL_PLAYABLE
#define RACEMASK_ALL_PLAYABLE
SpellCastResult
#define sSpellMgr
Definition SpellMgr.h:744
@ TARGET_SELECT_CATEGORY_CONE
@ TARGET_SELECT_CATEGORY_AREA
@ TARGET_SELECT_CATEGORY_NEARBY
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
@ UNIT_STATE_ALL_STATE
Definition Unit.h:550
bool CompareValues(ComparisionType type, T val1, T val2)
Definition Util.h:698
ComparisionType
Definition Util.h:688
@ COMP_TYPE_MAX
Definition Util.h:694
uint32 GetSearcherTypeMaskForConditionList(ConditionList const &conditions)
bool IsObjectMeetToConditionList(ConditionSourceInfo &sourceInfo, ConditionList const &conditions)
bool isConditionTypeValid(Condition *cond)
bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const
bool addToSpellImplicitTargetConditions(Condition *cond)
bool addToGossipMenus(Condition *cond)
SmartEventConditionContainer SmartEventConditionStore
bool addToGossipMenuItems(Condition *cond)
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry)
bool addToLootTemplate(Condition *cond, LootTemplate *loot)
CreatureSpellConditionContainer SpellClickEventConditionStore
ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId)
CreatureSpellConditionContainer VehicleSpellConditionStore
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId)
bool isSourceTypeValid(Condition *cond)
bool addToPhases(Condition *cond)
bool addToTerrainSwaps(Condition *cond)
NpcVendorConditionContainer NpcVendorConditionContainerStore
bool CanHaveSourceIdSet(ConditionSourceType sourceType) const
ConditionContainer ConditionStore
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType)
ConditionReferenceContainer ConditionReferenceStore
std::list< Condition * > AllocatedMemoryStore
ConditionList GetConditionReferences(uint32 refId)
bool IsObjectMeetToConditions(WorldObject *object, ConditionList const &conditions)
ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId)
void LoadConditions(bool isReload=false)
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
uint32 GetUInt32() const
Definition Field.h:105
int32 GetInt32() const
Definition Field.h:123
std::vector< GameEventData > GameEventDataMap
bool isReference(uint32 id)
Definition LootMgr.cpp:1597
bool addConditionItem(Condition *cond)
Definition LootMgr.cpp:1539
Definition Map.h:238
bool IsInstance() const
Definition Map.h:368
uint64 GetGUID() const
Definition Object.h:119
Player * ToPlayer()
Definition Object.h:204
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
Unit * ToUnit()
Definition Object.h:210
static bool IsValidGender(uint8 Gender)
Definition Player.h:1898
static DrunkenState GetDrunkenstateByValue(uint8 value)
Definition Player.cpp:1346
std::list< Condition * > * ImplicitTargetConditions
Definition SpellInfo.h:110
SpellImplicitTargetInfo TargetA
Definition SpellInfo.h:102
SpellImplicitTargetInfo TargetB
Definition SpellInfo.h:103
SpellTargetSelectionCategories GetSelectionCategory() const
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
Definition Unit.h:1367
ReputationRank GetReactionTo(Unit const *target) const
Definition Unit.cpp:2140
uint64 GetCreatorGUID() const
Definition Unit.h:2055
bool IsOnVehicle(const Unit *vehicle) const
Definition Unit.cpp:7198
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:7253
uint64 GetOwnerGUID() const
Definition Unit.h:2050
bool IsInPartyWith(Unit const *unit) const
Definition Unit.cpp:7234
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1666
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
#define sWorld
Definition World.h:910
uint32 m_ParentAreaID
uint32 GetSearcherTypeMaskForCondition()
uint32 SourceGroup
ConditionTypes ConditionType
bool Meets(ConditionSourceInfo &sourceInfo)
uint32 SourceId
int32 SourceEntry
uint32 ElseGroup
uint32 ScriptId
bool NegativeCondition
ConditionSourceType SourceType
SpellCastResult ErrorType
uint32 ConditionValue2
uint8 ConditionTarget
uint32 ReferenceId
uint32 ErrorTextId
uint32 ConditionValue3
uint32 ConditionValue1
uint32 GetMaxAvailableConditionTargets()
Condition * mLastFailedCondition
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
ConditionList Conditions
Definition ObjectMgr.h:702