PageRenderTime 26ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/server/game/Conditions/DisableMgr.cpp

https://github.com/DarkmoonCore/DarkmoonCore
C++ | 347 lines | 293 code | 33 blank | 21 comment | 79 complexity | c3469282a59a5e6b326bb589dabfa335 MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
  3. * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "ObjectMgr.h"
  19. #include "OutdoorPvP.h"
  20. #include "SpellMgr.h"
  21. #include "VMapManager2.h"
  22. #include "DisableMgr.h"
  23. DisableMgr::DisableMgr()
  24. {
  25. }
  26. DisableMgr::~DisableMgr()
  27. {
  28. for (DisableMap::iterator itr = m_DisableMap.begin(); itr != m_DisableMap.end(); ++itr)
  29. itr->second.clear();
  30. m_DisableMap.clear();
  31. }
  32. void DisableMgr::LoadDisables()
  33. {
  34. uint32 oldMSTime = getMSTime();
  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. QueryResult result = WorldDatabase.Query("SELECT sourceType, entry, flags, params_0, params_1 FROM disables");
  40. uint32 total_count = 0;
  41. if (!result)
  42. {
  43. sLog->outString(">> Loaded 0 disables. DB table `disables` is empty!");
  44. sLog->outString();
  45. return;
  46. }
  47. Field* fields;
  48. do
  49. {
  50. fields = result->Fetch();
  51. DisableType type = DisableType(fields[0].GetUInt32());
  52. if (type >= MAX_DISABLE_TYPES)
  53. {
  54. sLog->outErrorDb("Invalid type %u specified in `disables` table, skipped.", type);
  55. continue;
  56. }
  57. uint32 entry = fields[1].GetUInt32();
  58. uint8 flags = fields[2].GetUInt8();
  59. std::string params_0 = fields[3].GetString();
  60. std::string params_1 = fields[4].GetString();
  61. DisableData data;
  62. data.flags = flags;
  63. switch (type)
  64. {
  65. case DISABLE_TYPE_SPELL:
  66. if (!(sSpellMgr->GetSpellInfo(entry) || flags & SPELL_DISABLE_DEPRECATED_SPELL))
  67. {
  68. sLog->outErrorDb("Spell entry %u from `disables` doesn't exist in dbc, skipped.", entry);
  69. continue;
  70. }
  71. if (!flags || flags > MAX_SPELL_DISABLE_TYPE)
  72. {
  73. sLog->outErrorDb("Disable flags for spell %u are invalid, skipped.", entry);
  74. continue;
  75. }
  76. if (flags & SPELL_DISABLE_MAP)
  77. {
  78. Tokens tokens(params_0, ',');
  79. for (uint8 i = 0; i < tokens.size(); )
  80. data.params[0].insert(atoi(tokens[i++]));
  81. }
  82. if (flags & SPELL_DISABLE_AREA)
  83. {
  84. Tokens tokens(params_1, ',');
  85. for (uint8 i = 0; i < tokens.size(); )
  86. data.params[1].insert(atoi(tokens[i++]));
  87. }
  88. break;
  89. // checked later
  90. case DISABLE_TYPE_QUEST:
  91. break;
  92. case DISABLE_TYPE_MAP:
  93. {
  94. MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
  95. if (!mapEntry)
  96. {
  97. sLog->outErrorDb("Map entry %u from `disables` doesn't exist in dbc, skipped.", entry);
  98. continue;
  99. }
  100. bool isFlagInvalid = false;
  101. switch (mapEntry->map_type)
  102. {
  103. case MAP_COMMON:
  104. if (flags)
  105. isFlagInvalid = true;
  106. break;
  107. case MAP_INSTANCE:
  108. case MAP_RAID:
  109. if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DUNGEON_DIFFICULTY_HEROIC))
  110. isFlagInvalid = true;
  111. else if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_10MAN_HEROIC))
  112. isFlagInvalid = true;
  113. else if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_25MAN_HEROIC))
  114. isFlagInvalid = true;
  115. break;
  116. case MAP_BATTLEGROUND:
  117. case MAP_ARENA:
  118. sLog->outErrorDb("Battleground map %u specified to be disabled in map case, skipped.", entry);
  119. continue;
  120. }
  121. if (isFlagInvalid)
  122. {
  123. sLog->outErrorDb("Disable flags for map %u are invalid, skipped.", entry);
  124. continue;
  125. }
  126. break;
  127. }
  128. case DISABLE_TYPE_BATTLEGROUND:
  129. if (!sBattlemasterListStore.LookupEntry(entry))
  130. {
  131. sLog->outErrorDb("Battleground entry %u from `disables` doesn't exist in dbc, skipped.", entry);
  132. continue;
  133. }
  134. if (flags)
  135. sLog->outErrorDb("Disable flags specified for battleground %u, useless data.", entry);
  136. break;
  137. case DISABLE_TYPE_OUTDOORPVP:
  138. if (entry > MAX_OUTDOORPVP_TYPES)
  139. {
  140. sLog->outErrorDb("OutdoorPvPTypes value %u from `disables` is invalid, skipped.", entry);
  141. continue;
  142. }
  143. if (flags)
  144. sLog->outErrorDb("Disable flags specified for outdoor PvP %u, useless data.", entry);
  145. break;
  146. case DISABLE_TYPE_ACHIEVEMENT_CRITERIA:
  147. if (!sAchievementCriteriaStore.LookupEntry(entry))
  148. {
  149. sLog->outErrorDb("Achievement Criteria entry %u from `disables` doesn't exist in dbc, skipped.", entry);
  150. continue;
  151. }
  152. if (flags)
  153. sLog->outErrorDb("Disable flags specified for Achievement Criteria %u, useless data.", entry);
  154. break;
  155. case DISABLE_TYPE_VMAP:
  156. {
  157. MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
  158. if (!mapEntry)
  159. {
  160. sLog->outErrorDb("Map entry %u from `disables` doesn't exist in dbc, skipped.", entry);
  161. continue;
  162. }
  163. switch (mapEntry->map_type)
  164. {
  165. case MAP_COMMON:
  166. if (flags & VMAP_DISABLE_AREAFLAG)
  167. sLog->outString("Areaflag disabled for world map %u.", entry);
  168. if (flags & VMAP_DISABLE_LIQUIDSTATUS)
  169. sLog->outString("Liquid status disabled for world map %u.", entry);
  170. break;
  171. case MAP_INSTANCE:
  172. case MAP_RAID:
  173. if (flags & VMAP_DISABLE_HEIGHT)
  174. sLog->outString("Height disabled for instance map %u.", entry);
  175. if (flags & VMAP_DISABLE_LOS)
  176. sLog->outString("LoS disabled for instance map %u.", entry);
  177. break;
  178. case MAP_BATTLEGROUND:
  179. if (flags & VMAP_DISABLE_HEIGHT)
  180. sLog->outString("Height disabled for battleground map %u.", entry);
  181. if (flags & VMAP_DISABLE_LOS)
  182. sLog->outString("LoS disabled for battleground map %u.", entry);
  183. break;
  184. case MAP_ARENA:
  185. if (flags & VMAP_DISABLE_HEIGHT)
  186. sLog->outString("Height disabled for arena map %u.", entry);
  187. if (flags & VMAP_DISABLE_LOS)
  188. sLog->outString("LoS disabled for arena map %u.", entry);
  189. break;
  190. default:
  191. break;
  192. }
  193. break;
  194. }
  195. default:
  196. break;
  197. }
  198. m_DisableMap[type].insert(DisableTypeMap::value_type(entry, data));
  199. ++total_count;
  200. }
  201. while (result->NextRow());
  202. sLog->outString(">> Loaded %u disables in %u ms", total_count, GetMSTimeDiffToNow(oldMSTime));
  203. sLog->outString();
  204. }
  205. void DisableMgr::CheckQuestDisables()
  206. {
  207. uint32 oldMSTime = getMSTime();
  208. uint32 count = m_DisableMap[DISABLE_TYPE_QUEST].size();
  209. if (!count)
  210. {
  211. sLog->outString(">> Checked 0 quest disables.");
  212. sLog->outString();
  213. return;
  214. }
  215. // check only quests, rest already done at startup
  216. for (DisableTypeMap::iterator itr = m_DisableMap[DISABLE_TYPE_QUEST].begin(); itr != m_DisableMap[DISABLE_TYPE_QUEST].end();)
  217. {
  218. const uint32 entry = itr->first;
  219. if (!sObjectMgr->GetQuestTemplate(entry))
  220. {
  221. sLog->outErrorDb("Quest entry %u from `disables` doesn't exist, skipped.", entry);
  222. m_DisableMap[DISABLE_TYPE_QUEST].erase(itr++);
  223. continue;
  224. }
  225. if (itr->second.flags)
  226. sLog->outErrorDb("Disable flags specified for quest %u, useless data.", entry);
  227. ++itr;
  228. }
  229. sLog->outString(">> Checked %u quest disables in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
  230. sLog->outString();
  231. }
  232. bool DisableMgr::IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags)
  233. {
  234. ASSERT(type < MAX_DISABLE_TYPES);
  235. if (m_DisableMap[type].empty())
  236. return false;
  237. DisableTypeMap::iterator itr = m_DisableMap[type].find(entry);
  238. if (itr == m_DisableMap[type].end()) // not disabled
  239. return false;
  240. switch (type)
  241. {
  242. case DISABLE_TYPE_SPELL:
  243. {
  244. uint8 flags = itr->second.flags;
  245. if (unit)
  246. {
  247. if ((flags & SPELL_DISABLE_PLAYER && unit->GetTypeId() == TYPEID_PLAYER) ||
  248. (unit->GetTypeId() == TYPEID_UNIT && ((unit->ToCreature()->isPet() && flags & SPELL_DISABLE_PET) || flags & SPELL_DISABLE_CREATURE)))
  249. {
  250. if (flags & SPELL_DISABLE_MAP)
  251. {
  252. std::set<uint32> const& mapIds = itr->second.params[0];
  253. if (mapIds.find(unit->GetMapId()) != mapIds.end())
  254. return true; // Spell is disabled on current map
  255. if (!(flags & SPELL_DISABLE_AREA))
  256. return false; // Spell is disabled on another map, but not this one, return false
  257. // Spell is disabled in an area, but not explicitly our current mapId. Continue processing.
  258. }
  259. if (flags & SPELL_DISABLE_AREA)
  260. {
  261. std::set<uint32> const& areaIds = itr->second.params[1];
  262. if (areaIds.find(unit->GetAreaId()) != areaIds.end())
  263. return true; // Spell is disabled in this area
  264. return false; // Spell is disabled in another area, but not this one, return false
  265. }
  266. else
  267. return true; // Spell disabled for all maps
  268. }
  269. return false;
  270. }
  271. else if (flags & SPELL_DISABLE_DEPRECATED_SPELL) // call not from spellcast
  272. return true;
  273. }
  274. case DISABLE_TYPE_MAP:
  275. if (Player const* player = unit->ToPlayer())
  276. {
  277. MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
  278. if (mapEntry->IsDungeon())
  279. {
  280. uint8 disabledModes = itr->second.flags;
  281. Difficulty targetDifficulty = player->GetDifficulty(mapEntry->IsRaid());
  282. GetDownscaledMapDifficultyData(entry, targetDifficulty);
  283. switch (targetDifficulty)
  284. {
  285. case DUNGEON_DIFFICULTY_NORMAL:
  286. return disabledModes & DUNGEON_STATUSFLAG_NORMAL;
  287. case DUNGEON_DIFFICULTY_HEROIC:
  288. return disabledModes & DUNGEON_STATUSFLAG_HEROIC;
  289. case RAID_DIFFICULTY_10MAN_HEROIC:
  290. return disabledModes & RAID_STATUSFLAG_10MAN_HEROIC;
  291. case RAID_DIFFICULTY_25MAN_HEROIC:
  292. return disabledModes & RAID_STATUSFLAG_25MAN_HEROIC;
  293. }
  294. }
  295. else if (mapEntry->map_type == MAP_COMMON)
  296. return true;
  297. }
  298. return false;
  299. case DISABLE_TYPE_QUEST:
  300. if (!unit)
  301. return true;
  302. if (Player const* player = unit->ToPlayer())
  303. if (player->isGameMaster())
  304. return false;
  305. return true;
  306. case DISABLE_TYPE_BATTLEGROUND:
  307. case DISABLE_TYPE_OUTDOORPVP:
  308. case DISABLE_TYPE_ACHIEVEMENT_CRITERIA:
  309. return true;
  310. case DISABLE_TYPE_VMAP:
  311. return flags & itr->second.flags;
  312. }
  313. return false;
  314. }