OregonCore  revision fb2a440-git
Your Favourite TBC server
DisableMgr.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 "SpellMgr.h"
19 #include "ObjectMgr.h"
20 #include "DisableMgr.h"
21 
23 {
24 }
25 
27 {
28  for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr)
29  itr->second.clear();
30  m_DisableMap.clear();
31 }
32 
34 {
35  // reload case
36  for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr)
37  itr->second.clear();
38  m_DisableMap.clear();
39 
40  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT sourceType,entry,flags,params_0,params_1 FROM disables");
41 
42  uint32 total_count = 0;
43 
44  if (!result)
45  {
46  sLog.outString(">> Loaded %u disables", total_count);
47  return;
48  }
49 
50  Field* fields;
51  do
52  {
53  fields = result->Fetch();
54  DisableType type = DisableType(fields[0].GetUInt32());
55  if (uint32(type) >= MAX_DISABLE_TYPES)
56  {
57  sLog.outErrorDb("Invalid type %u specified in `disables` table, skipped.", type);
58  continue;
59  }
60  uint32 entry = fields[1].GetUInt32();
61  uint8 flags = fields[2].GetUInt8();
62  std::string params_0 = fields[3].GetString();
63  std::string params_1 = fields[4].GetString();
64 
65  DisableData data;
66  data.flags = flags;
67 
68  switch (type)
69  {
70  case DISABLE_TYPE_SPELL:
71  {
72  if (!(sSpellStore.LookupEntry(entry) || flags & SPELL_DISABLE_DEPRECATED_SPELL))
73  {
74  sLog.outErrorDb("Spell entry %u from `disables` doesn't exist in dbc, skipped.", entry);
75  continue;
76  }
77 
78  if (!flags || flags > MAX_SPELL_DISABLE_TYPE)
79  {
80  sLog.outErrorDb("Disable flags for spell %u are invalid, skipped.", entry);
81  continue;
82  }
83 
84  if (flags & SPELL_DISABLE_MAP)
85  {
86 
87  Tokens tokens = StrSplit(params_0, ",");
88  for (uint8 i = 0; i < tokens.size(); )
89  data.params[0].insert(atoi(tokens[i++].c_str()));
90  }
91 
92  if (flags & SPELL_DISABLE_AREA)
93  {
94  Tokens tokens = StrSplit(params_1, ",");
95  for (uint8 i = 0; i < tokens.size(); )
96  data.params[1].insert(atoi(tokens[i++].c_str()));
97  }
98 
99  }
100  break;
101  // checked later
102  case DISABLE_TYPE_QUEST:
103  break;
104  case DISABLE_TYPE_MAP:
105  {
106  MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
107  if (!mapEntry)
108  {
109  sLog.outErrorDb("Map entry %u from `disables` doesn't exist in dbc, skipped.", entry);
110  continue;
111  }
112  bool isFlagInvalid = false;
113  switch (mapEntry->map_type)
114  {
115  case MAP_COMMON:
116  if (flags)
117  isFlagInvalid = true;
118  break;
119  case MAP_INSTANCE:
120  case MAP_RAID:
121  if (flags & DUNGEON_STATUSFLAG_NORMAL && !mapEntry->IsDungeon())
122  isFlagInvalid = true;
123  if (flags & DUNGEON_STATUSFLAG_HEROIC && !mapEntry->SupportsHeroicMode())
124  isFlagInvalid = true;
125  else if (flags & RAID_STATUSFLAG_10MAN && !mapEntry->IsRaid())
126  isFlagInvalid = true;
127  else if (flags & RAID_STATUSFLAG_25MAN && !mapEntry->IsRaid())
128  isFlagInvalid = true;
129  break;
130  case MAP_BATTLEGROUND:
131  case MAP_ARENA:
132  sLog.outErrorDb("Battleground map %u specified to be disabled in map case, skipped.", entry);
133  continue;
134  }
135  if (isFlagInvalid)
136  {
137  sLog.outErrorDb("Disable flags for map %u are invalid, skipped.", entry);
138  continue;
139  }
140  break;
141  }
143  if (!sBattlemasterListStore.LookupEntry(entry))
144  {
145  sLog.outErrorDb("Battleground entry %u from `disables` doesn't exist in dbc, skipped.", entry);
146  continue;
147  }
148  if (flags)
149  sLog.outErrorDb("Disable flags specified for battleground %u, useless data.", entry);
150  break;
151  }
152 
153  m_DisableMap[type].insert(DisableTypeMap::value_type(entry, data));
154  ++total_count;
155  }
156  while (result->NextRow());
157 
158  sLog.outString(">> Loaded %u disables.", total_count);
159 }
160 
162 {
163  uint32 count = m_DisableMap[DISABLE_TYPE_QUEST].size();
164  if (!count)
165  return;
166 
167  // check only quests, rest already done at startup
168  for (DisableTypeMap::iterator itr = m_DisableMap[DISABLE_TYPE_QUEST].begin(); itr != m_DisableMap[DISABLE_TYPE_QUEST].end();)
169  {
170  const uint32 entry = itr->first;
171  if (!sObjectMgr.GetQuestTemplate(entry))
172  {
173  sLog.outErrorDb("Quest entry %u from `disables` doesn't exist, skipped.", entry);
174  m_DisableMap[DISABLE_TYPE_QUEST].erase(itr++);
175  continue;
176  }
177  if (itr->second.flags)
178  sLog.outErrorDb("Disable flags specified for quest %u, useless data.", entry);
179  ++itr;
180  }
181 }
182 
183 bool DisableMgr::IsDisabledFor(DisableType type, uint32 entry, Unit* pUnit, uint8 flags)
184 {
185  assert(uint32(type) < MAX_DISABLE_TYPES);
186  if (m_DisableMap[type].empty())
187  return false;
188 
189  DisableTypeMap::iterator itr = m_DisableMap[type].find(entry);
190  if (itr == m_DisableMap[type].end()) // not disabled
191  return false;
192 
193  switch (type)
194  {
195  case DISABLE_TYPE_SPELL:
196  {
197  uint8 spellFlags = itr->second.flags;
198  if (pUnit)
199  {
200  if ((spellFlags & SPELL_DISABLE_PLAYER && pUnit->GetTypeId() == TYPEID_PLAYER) ||
201  (pUnit->GetTypeId() == TYPEID_UNIT && (pUnit->IsPet() && spellFlags & (SPELL_DISABLE_PET | SPELL_DISABLE_CREATURE))))
202  {
203  if (spellFlags & SPELL_DISABLE_MAP)
204  {
205  std::set<uint32> const& mapIds = itr->second.params[0];
206  if (mapIds.find(pUnit->GetMapId()) != mapIds.end())
207  return true; // Spell is disabled on current map
208 
209  if (!(flags & SPELL_DISABLE_AREA))
210  return false; // Spell is disabled on another map, but not this one, return false
211 
212  // Spell is disabled in an area, but not explicitly our current mapId. Continue processing.
213  }
214 
215  if (spellFlags & SPELL_DISABLE_AREA)
216  {
217  std::set<uint32> const& areaIds = itr->second.params[1];
218  if (areaIds.find(pUnit->GetAreaId()) != areaIds.end())
219  return true; // Spell is disabled in this area
220  return false; // Spell is disabled in another area, but not this one, return false
221  }
222  else
223  return true; // Spell disabled for all maps
224  }
225  return false;
226  }
227  else if (spellFlags & SPELL_DISABLE_DEPRECATED_SPELL) // call not from spellcast
228  return true;
229  else if (flags & SPELL_DISABLE_LOS)
230  return spellFlags & SPELL_DISABLE_LOS;
231  }
232  case DISABLE_TYPE_MAP:
233  if (Player* pPlayer = pUnit->ToPlayer())
234  {
235  MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
236  if (mapEntry->IsDungeon())
237  {
238  uint8 disabledModes = itr->second.flags;
239  uint32 targetDifficulty = pPlayer->GetDifficulty();
240  switch (targetDifficulty)
241  {
242  case DIFFICULTY_NORMAL:
243  return disabledModes & DUNGEON_STATUSFLAG_NORMAL;
244  case DIFFICULTY_HEROIC:
245  return disabledModes & DUNGEON_STATUSFLAG_HEROIC;
246  }
247  }
248  else if (mapEntry->map_type == MAP_COMMON)
249  return true;
250  }
251  return false;
252  case DISABLE_TYPE_QUEST:
253  if (!pUnit)
254  return true;
255  if (Player const* pPlayer = pUnit->ToPlayer())
256  if (pPlayer->IsGameMaster())
257  return false;
258  return true;
260  return true;
261  }
262 
263  return false;
264 }
std::vector< std::string > Tokens
Definition: Util.h:26
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
std::set< uint32 > params[2]
Definition: DisableMgr.h:51
Definition: Field.h:24
bool IsDisabledFor(DisableType type, uint32 entry, Unit *pUnit, uint8 flags=0)
Definition: DisableMgr.cpp:183
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
DisableType
Definition: DisableMgr.h:24
#define sLog
Log class singleton.
Definition: Log.h:187
Tokens StrSplit(const std::string &src, const std::string &sep)
Definition: Util.cpp:58
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
#define MAX_DISABLE_TYPES
Definition: DisableMgr.h:46
#define sObjectMgr
Definition: ObjectMgr.h:1285
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
const char * GetString() const
Definition: Field.h:41
Player * ToPlayer()
Definition: Object.h:392
uint8 GetTypeId() const
Definition: Object.h:210
ACE_UINT8 uint8
Definition: Define.h:73
uint8 flags
Definition: DisableMgr.h:50
bool IsDungeon() const
Definition: DBCStructure.h:550
uint32 GetMapId() const
Definition: Object.h:591
uint32 GetAreaId() const
Definition: Object.cpp:1184
bool IsRaid() const
Definition: DBCStructure.h:558
DisableMap m_DisableMap
Definition: DisableMgr.h:70
bool IsPet() const
Definition: Unit.h:1048
uint32 map_type
Definition: DBCStructure.h:516
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
void CheckQuestDisables()
Definition: DisableMgr.cpp:161
ACE_UINT32 uint32
Definition: Define.h:71
bool SupportsHeroicMode() const
Definition: DBCStructure.h:574
Definition: Unit.h:908
Definition: Player.h:922
void LoadDisables()
Definition: DisableMgr.cpp:33