TrinityCore
Loading...
Searching...
No Matches
GarrisonMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "GarrisonMgr.h"
19#include "Containers.h"
20#include "DatabaseEnv.h"
21#include "DB2Stores.h"
22#include "Garrison.h"
23#include "Log.h"
24#include "ObjectMgr.h"
25#include "Random.h"
26#include "Timer.h"
27#include "World.h"
28
29GarrisonMgr::GarrisonMgr() = default;
31
33{
34 static GarrisonMgr instance;
35 return instance;
36}
37
39{
40 for (GarrSiteLevelPlotInstEntry const* siteLevelPlotInst : sGarrSiteLevelPlotInstStore)
41 _garrisonPlotInstBySiteLevel[siteLevelPlotInst->GarrSiteLevelID].push_back(siteLevelPlotInst);
42
43 for (GameObjectsEntry const* gameObject : sGameObjectsStore)
44 if (gameObject->TypeID == GAMEOBJECT_TYPE_GARRISON_PLOT)
45 _garrisonPlots[gameObject->OwnerID][gameObject->PropValue[0]] = gameObject;
46
47 for (GarrPlotBuildingEntry const* plotBuilding : sGarrPlotBuildingStore)
48 _garrisonBuildingsByPlot[plotBuilding->GarrPlotID].insert(plotBuilding->GarrBuildingID);
49
50 for (GarrBuildingPlotInstEntry const* buildingPlotInst : sGarrBuildingPlotInstStore)
51 _garrisonBuildingPlotInstances[std::make_pair(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID;
52
53 for (GarrBuildingEntry const* building : sGarrBuildingStore)
54 _garrisonBuildingsByType[building->BuildingType].push_back(building->ID);
55
56 for (GarrFollowerXAbilityEntry const* followerAbility : sGarrFollowerXAbilityStore)
57 {
58 if (GarrAbilityEntry const* ability = sGarrAbilityStore.LookupEntry(followerAbility->GarrAbilityID))
59 {
60 if (ability->GarrFollowerTypeID != FOLLOWER_TYPE_GARRISON)
61 continue;
62
63 if (!(ability->Flags & GARRISON_ABILITY_CANNOT_ROLL) && ability->Flags & GARRISON_ABILITY_FLAG_TRAIT)
64 _garrisonFollowerRandomTraits.insert(ability);
65
66 if (followerAbility->FactionIndex < 2)
67 {
68 if (ability->Flags & GARRISON_ABILITY_FLAG_TRAIT)
69 _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Traits.insert(ability);
70 else
71 _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Counters.insert(ability);
72 }
73 }
74 }
75
79}
80
82{
83 for (GarrSiteLevelEntry const* siteLevel : sGarrSiteLevelStore)
84 if (siteLevel->GarrSiteID == garrSiteId && siteLevel->GarrLevel == level)
85 return siteLevel;
86
87 return nullptr;
88}
89
90std::vector<GarrSiteLevelPlotInstEntry const*> const* GarrisonMgr::GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const
91{
92 auto itr = _garrisonPlotInstBySiteLevel.find(garrSiteLevelId);
93 if (itr != _garrisonPlotInstBySiteLevel.end())
94 return &itr->second;
95
96 return nullptr;
97}
98
99GameObjectsEntry const* GarrisonMgr::GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const
100{
101 auto mapItr = _garrisonPlots.find(mapId);
102 if (mapItr != _garrisonPlots.end())
103 {
104 auto plotItr = mapItr->second.find(garrPlotInstanceId);
105 if (plotItr != mapItr->second.end())
106 return plotItr->second;
107 }
108
109 return nullptr;
110}
111
112bool GarrisonMgr::IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const
113{
114 auto plotItr = _garrisonBuildingsByPlot.find(garrPlotId);
115 if (plotItr != _garrisonBuildingsByPlot.end())
116 return plotItr->second.count(garrBuildingId) > 0;
117
118 return false;
119}
120
121uint32 GarrisonMgr::GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const
122{
123 auto itr = _garrisonBuildingPlotInstances.find(std::make_pair(garrBuildingId, garrSiteLevelPlotInstId));
124 if (itr != _garrisonBuildingPlotInstances.end())
125 return itr->second;
126
127 return 0;
128}
129
131{
132 auto itr = _garrisonBuildingsByType.find(buildingType);
133 if (itr != _garrisonBuildingsByType.end())
134 for (uint32 buildingId : itr->second)
135 if (sGarrBuildingStore.AssertEntry(buildingId)->UpgradeLevel == currentLevel - 1)
136 return buildingId;
137
138 return 0;
139}
140
142{
143 auto itr = _finalizePlotGOInfo.find(garrPlotInstanceID);
144 if (itr != _finalizePlotGOInfo.end())
145 return &itr->second;
146
147 return nullptr;
148}
149
151{
152 if (_followerDbIdGenerator >= std::numeric_limits<uint64>::max())
153 {
154 TC_LOG_ERROR("misc", "Garrison follower db id overflow! Can't continue, shutting down server. ");
156 }
157
158 return _followerDbIdGenerator++;
159}
160
162{
163 // Counters, Traits
164 { 0, 0 },
165 { 1, 0 },
166 { 1, 1 }, // Uncommon
167 { 1, 2 }, // Rare
168 { 2, 3 }, // Epic
169 { 2, 3 } // Legendary
170};
171
172std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(uint32 garrFollowerId, GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const
173{
174 ASSERT(faction < 2);
175
176 bool hasForcedExclusiveTrait = false;
177 std::list<GarrAbilityEntry const*> result;
178 uint32 slots[2] = { AbilitiesForQuality[quality][0], AbilitiesForQuality[quality][1] };
179
180 GarrAbilities const* abilities = nullptr;
181 auto itr = _garrisonFollowerAbilities[faction].find(garrFollowerId);
182 if (itr != _garrisonFollowerAbilities[faction].end())
183 abilities = &itr->second;
184
185 std::list<GarrAbilityEntry const*> abilityList, forcedAbilities, traitList, forcedTraits;
186 if (abilities)
187 {
188 for (GarrAbilityEntry const* ability : abilities->Counters)
189 {
190 if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE)
191 continue;
192 else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE)
193 continue;
194
195 if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE)
196 forcedAbilities.push_back(ability);
197 else
198 abilityList.push_back(ability);
199 }
200
201 for (GarrAbilityEntry const* ability : abilities->Traits)
202 {
203 if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE)
204 continue;
205 else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE)
206 continue;
207
208 if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE)
209 forcedTraits.push_back(ability);
210 else
211 traitList.push_back(ability);
212 }
213 }
214
215 Trinity::Containers::RandomResize(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size()));
216 Trinity::Containers::RandomResize(traitList, std::max<int32>(0, slots[1] - forcedTraits.size()));
217
218 // Add abilities specified in GarrFollowerXAbility.db2 before generic classspec ones on follower creation
219 if (initial)
220 {
221 forcedAbilities.splice(forcedAbilities.end(), abilityList);
222 forcedTraits.splice(forcedTraits.end(), traitList);
223 }
224
225 forcedAbilities.sort();
226 abilityList.sort();
227 forcedTraits.sort();
228 traitList.sort();
229
230 // check if we have a trait from exclusive category
231 for (GarrAbilityEntry const* ability : forcedTraits)
232 {
233 if (ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE)
234 {
235 hasForcedExclusiveTrait = true;
236 break;
237 }
238 }
239
240 if (slots[0] > forcedAbilities.size() + abilityList.size())
241 {
242 std::list<GarrAbilityEntry const*> classSpecAbilities = GetClassSpecAbilities(follower, faction);
243 std::list<GarrAbilityEntry const*> classSpecAbilitiesTemp, classSpecAbilitiesTemp2;
244 classSpecAbilitiesTemp2.swap(abilityList);
245 std::set_difference(classSpecAbilities.begin(), classSpecAbilities.end(), forcedAbilities.begin(), forcedAbilities.end(), std::back_inserter(classSpecAbilitiesTemp));
246 std::set_union(classSpecAbilitiesTemp.begin(), classSpecAbilitiesTemp.end(), classSpecAbilitiesTemp2.begin(), classSpecAbilitiesTemp2.end(), std::back_inserter(abilityList));
247
248 Trinity::Containers::RandomResize(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size()));
249 }
250
251 if (slots[1] > forcedTraits.size() + traitList.size())
252 {
253 std::list<GarrAbilityEntry const*> genericTraits, genericTraitsTemp;
255 {
256 if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE)
257 continue;
258 else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE)
259 continue;
260
261 // forced exclusive trait exists, skip other ones entirely
262 if (hasForcedExclusiveTrait && ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE)
263 continue;
264
265 genericTraitsTemp.push_back(ability);
266 }
267
268 std::set_difference(genericTraitsTemp.begin(), genericTraitsTemp.end(), forcedTraits.begin(), forcedTraits.end(), std::back_inserter(genericTraits));
269 genericTraits.splice(genericTraits.begin(), traitList);
270 // "split" the list into two parts [nonexclusive, exclusive] to make selection later easier
271 genericTraits.sort([](GarrAbilityEntry const* a1, GarrAbilityEntry const* a2)
272 {
275 if (e1 != e2)
276 return e1 < e2;
277
278 return a1->ID < a2->ID;
279 });
280 genericTraits.unique();
281
282 std::size_t firstExclusive = 0, total = genericTraits.size();
283 for (auto genericTraitItr = genericTraits.begin(); genericTraitItr != genericTraits.end(); ++genericTraitItr, ++firstExclusive)
284 if ((*genericTraitItr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE)
285 break;
286
287 while (traitList.size() < size_t(std::max<int32>(0, slots[1] - forcedTraits.size())) && total)
288 {
289 auto genericTraitItr = genericTraits.begin();
290 std::advance(genericTraitItr, urand(0, total-- - 1));
291 if ((*genericTraitItr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE)
292 total = firstExclusive; // selected exclusive trait - no other can be selected now
293 else
294 --firstExclusive;
295
296 traitList.push_back(*genericTraitItr);
297 genericTraits.erase(genericTraitItr);
298 }
299 }
300
301 result.splice(result.end(), forcedAbilities);
302 result.splice(result.end(), abilityList);
303 result.splice(result.end(), forcedTraits);
304 result.splice(result.end(), traitList);
305
306 return result;
307}
308
309std::list<GarrAbilityEntry const*> GarrisonMgr::GetClassSpecAbilities(GarrFollowerEntry const* follower, uint32 faction) const
310{
311 std::list<GarrAbilityEntry const*> abilities;
312 uint32 classSpecId;
313 switch (faction)
314 {
316 classSpecId = follower->HordeGarrClassSpecID;
317 break;
319 classSpecId = follower->AllianceGarrClassSpecID;
320 break;
321 default:
322 return abilities;
323 }
324
325 if (!sGarrClassSpecStore.LookupEntry(classSpecId))
326 return abilities;
327
328 auto itr = _garrisonFollowerClassSpecAbilities.find(classSpecId);
330 abilities = itr->second;
331
332 return abilities;
333}
334
336{
337 if (QueryResult result = CharacterDatabase.Query("SELECT MAX(dbId) FROM character_garrison_followers"))
338 _followerDbIdGenerator = (*result)[0].GetUInt64() + 1;
339}
340
342{
343 // 0 1 2 3 4 5 6
344 QueryResult result = WorldDatabase.Query("SELECT garrPlotInstanceId, hordeGameObjectId, hordeX, hordeY, hordeZ, hordeO, hordeAnimKitId, "
345 // 7 8 9 10 11 12
346 "allianceGameObjectId, allianceX, allianceY, allianceZ, allianceO, allianceAnimKitId FROM garrison_plot_finalize_info");
347 if (!result)
348 {
349 TC_LOG_INFO("server.loading", ">> Loaded 0 garrison follower class spec abilities. DB table `garrison_plot_finalize_info` is empty.");
350 return;
351 }
352
353 uint32 msTime = getMSTime();
354 do
355 {
356 Field* fields = result->Fetch();
357 uint32 garrPlotInstanceId = fields[0].GetUInt32();
358 uint32 hordeGameObjectId = fields[1].GetUInt32();
359 uint32 allianceGameObjectId = fields[7].GetUInt32();
360 uint16 hordeAnimKitId = fields[6].GetUInt16();
361 uint16 allianceAnimKitId = fields[12].GetUInt16();
362
363 if (!sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId))
364 {
365 TC_LOG_ERROR("sql.sql", "Non-existing GarrPlotInstance.db2 entry {} was referenced in `garrison_plot_finalize_info`.", garrPlotInstanceId);
366 continue;
367 }
368
369 GameObjectTemplate const* goTemplate = sObjectMgr->GetGameObjectTemplate(hordeGameObjectId);
370 if (!goTemplate)
371 {
372 TC_LOG_ERROR("sql.sql", "Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId {}.",
373 hordeGameObjectId, garrPlotInstanceId);
374 continue;
375 }
376
377 if (goTemplate->type != GAMEOBJECT_TYPE_GOOBER)
378 {
379 TC_LOG_ERROR("sql.sql", "Invalid gameobject type {} (entry {}) was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId {}.",
380 goTemplate->type, hordeGameObjectId, garrPlotInstanceId);
381 continue;
382 }
383
384 goTemplate = sObjectMgr->GetGameObjectTemplate(allianceGameObjectId);
385 if (!goTemplate)
386 {
387 TC_LOG_ERROR("sql.sql", "Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId {}.",
388 allianceGameObjectId, garrPlotInstanceId);
389 continue;
390 }
391
392 if (goTemplate->type != GAMEOBJECT_TYPE_GOOBER)
393 {
394 TC_LOG_ERROR("sql.sql", "Invalid gameobject type {} (entry {}) was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId {}.",
395 goTemplate->type, allianceGameObjectId, garrPlotInstanceId);
396 continue;
397 }
398
399 if (hordeAnimKitId && !sAnimKitStore.LookupEntry(hordeAnimKitId))
400 {
401 TC_LOG_ERROR("sql.sql", "Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`hordeAnimKitId` for garrPlotInstanceId {}.",
402 hordeAnimKitId, garrPlotInstanceId);
403 continue;
404 }
405
406 if (allianceAnimKitId && !sAnimKitStore.LookupEntry(allianceAnimKitId))
407 {
408 TC_LOG_ERROR("sql.sql", "Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`allianceAnimKitId` for garrPlotInstanceId {}.",
409 allianceAnimKitId, garrPlotInstanceId);
410 continue;
411 }
412
413 FinalizeGarrisonPlotGOInfo& info = _finalizePlotGOInfo[garrPlotInstanceId];
414 info.FactionInfo[GARRISON_FACTION_INDEX_HORDE].GameObjectId = hordeGameObjectId;
415 info.FactionInfo[GARRISON_FACTION_INDEX_HORDE].Pos.Relocate(fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat());
417
418 info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].GameObjectId = allianceGameObjectId;
419 info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].Pos.Relocate(fields[8].GetFloat(), fields[9].GetFloat(), fields[10].GetFloat(), fields[11].GetFloat());
420 info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].AnimKitId = allianceAnimKitId;
421
422 } while (result->NextRow());
423
424 TC_LOG_INFO("server.loading", ">> Loaded {} garrison plot finalize entries in {}.", uint32(_finalizePlotGOInfo.size()), GetMSTimeDiffToNow(msTime));
425}
426
428{
429 QueryResult result = WorldDatabase.Query("SELECT classSpecId, abilityId FROM garrison_follower_class_spec_abilities");
430 if (!result)
431 {
432 TC_LOG_INFO("server.loading", ">> Loaded 0 garrison follower class spec abilities. DB table `garrison_follower_class_spec_abilities` is empty.");
433 return;
434 }
435
436 uint32 msTime = getMSTime();
437 uint32 count = 0;
438 do
439 {
440 Field* fields = result->Fetch();
441 uint32 classSpecId = fields[0].GetUInt32();
442 uint32 abilityId = fields[1].GetUInt32();
443
444 if (!sGarrClassSpecStore.LookupEntry(classSpecId))
445 {
446 TC_LOG_ERROR("sql.sql", "Non-existing GarrClassSpec.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", classSpecId, classSpecId, abilityId);
447 continue;
448 }
449
450 GarrAbilityEntry const* ability = sGarrAbilityStore.LookupEntry(abilityId);
451 if (!ability)
452 {
453 TC_LOG_ERROR("sql.sql", "Non-existing GarrAbility.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", abilityId, classSpecId, abilityId);
454 continue;
455 }
456
457 _garrisonFollowerClassSpecAbilities[classSpecId].push_back(ability);
458 ++count;
459
460 } while (result->NextRow());
461
462 for (auto& pair : _garrisonFollowerClassSpecAbilities)
463 pair.second.sort();
464
465 TC_LOG_INFO("server.loading", ">> Loaded {} garrison follower class spec abilities in {}.", count, GetMSTimeDiffToNow(msTime));
466}
DB2Storage< GameObjectsEntry > sGameObjectsStore("GameObjects.db2", &GameobjectsLoadInfo::Instance)
DB2Storage< AnimKitEntry > sAnimKitStore("AnimKit.db2", &AnimKitLoadInfo::Instance)
DB2Storage< GarrBuildingPlotInstEntry > sGarrBuildingPlotInstStore("GarrBuildingPlotInst.db2", &GarrBuildingPlotInstLoadInfo::Instance)
DB2Storage< GarrBuildingEntry > sGarrBuildingStore("GarrBuilding.db2", &GarrBuildingLoadInfo::Instance)
DB2Storage< GarrFollowerXAbilityEntry > sGarrFollowerXAbilityStore("GarrFollowerXAbility.db2", &GarrFollowerXAbilityLoadInfo::Instance)
DB2Storage< GarrSiteLevelPlotInstEntry > sGarrSiteLevelPlotInstStore("GarrSiteLevelPlotInst.db2", &GarrSiteLevelPlotInstLoadInfo::Instance)
DB2Storage< GarrPlotInstanceEntry > sGarrPlotInstanceStore("GarrPlotInstance.db2", &GarrPlotInstanceLoadInfo::Instance)
DB2Storage< GarrPlotBuildingEntry > sGarrPlotBuildingStore("GarrPlotBuilding.db2", &GarrPlotBuildingLoadInfo::Instance)
DB2Storage< GarrSiteLevelEntry > sGarrSiteLevelStore("GarrSiteLevel.db2", &GarrSiteLevelLoadInfo::Instance)
DB2Storage< GarrClassSpecEntry > sGarrClassSpecStore("GarrClassSpec.db2", &GarrClassSpecLoadInfo::Instance)
DB2Storage< GarrAbilityEntry > sGarrAbilityStore("GarrAbility.db2", &GarrAbilityLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
uint64_t uint64
Definition Define.h:153
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define ASSERT
Definition Errors.h:80
uint32 const AbilitiesForQuality[][2]
@ GARRISON_FACTION_INDEX_HORDE
Definition Garrison.h:44
@ GARRISON_FACTION_INDEX_ALLIANCE
Definition Garrison.h:45
@ GARRISON_ABILITY_FLAG_EXCLUSIVE
Definition Garrison.h:74
@ GARRISON_ABILITY_FLAG_CANNOT_REMOVE
Definition Garrison.h:73
@ GARRISON_ABILITY_FLAG_TRAIT
Definition Garrison.h:69
@ GARRISON_ABILITY_ALLIANCE_ONLY
Definition Garrison.h:72
@ GARRISON_ABILITY_CANNOT_ROLL
Definition Garrison.h:70
@ GARRISON_ABILITY_HORDE_ONLY
Definition Garrison.h:71
@ FOLLOWER_TYPE_GARRISON
Definition Garrison.h:60
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
#define sObjectMgr
Definition ObjectMgr.h:1885
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
@ GAMEOBJECT_TYPE_GARRISON_PLOT
@ GAMEOBJECT_TYPE_GOOBER
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
Class used to access individual fields of database query result.
Definition Field.h:94
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
uint16 GetUInt16() const noexcept
Definition Field.cpp:43
FinalizeGarrisonPlotGOInfo const * GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const
GarrSiteLevelEntry const * GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const
std::unordered_map< uint32, GarrAbilities > _garrisonFollowerAbilities[2]
Definition GarrisonMgr.h:88
void Initialize()
std::unordered_map< uint32, std::vector< uint32 > > _garrisonBuildingsByType
Definition GarrisonMgr.h:86
static GarrisonMgr & Instance()
std::set< GarrAbilityEntry const * > _garrisonFollowerRandomTraits
Definition GarrisonMgr.h:90
uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const
std::vector< GarrSiteLevelPlotInstEntry const * > const * GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const
std::unordered_map< uint32, FinalizeGarrisonPlotGOInfo > _finalizePlotGOInfo
Definition GarrisonMgr.h:87
std::list< GarrAbilityEntry const * > RollFollowerAbilities(uint32 garrFollowerId, GarrFollowerEntry const *follower, uint32 quality, uint32 faction, bool initial) const
void LoadPlotFinalizeGOInfo()
std::unordered_map< uint32, std::unordered_map< uint32, GameObjectsEntry const * > > _garrisonPlots
Definition GarrisonMgr.h:83
GameObjectsEntry const * GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const
bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const
std::unordered_map< uint32, std::list< GarrAbilityEntry const * > > _garrisonFollowerClassSpecAbilities
Definition GarrisonMgr.h:89
std::unordered_map< uint32, std::unordered_set< uint32 > > _garrisonBuildingsByPlot
Definition GarrisonMgr.h:84
std::list< GarrAbilityEntry const * > GetClassSpecAbilities(GarrFollowerEntry const *follower, uint32 faction) const
void InitializeDbIdSequences()
std::unordered_map< uint32, std::vector< GarrSiteLevelPlotInstEntry const * > > _garrisonPlotInstBySiteLevel
Definition GarrisonMgr.h:82
std::unordered_map< std::pair< uint32, uint32 >, uint32 > _garrisonBuildingPlotInstances
Definition GarrisonMgr.h:85
uint32 GetPreviousLevelBuildingId(uint32 buildingType, uint32 currentLevel) const
uint64 _followerDbIdGenerator
Definition GarrisonMgr.h:92
void LoadFollowerClassSpecAbilities()
uint64 GenerateFollowerDbId()
static void StopNow(uint8 exitcode)
Definition World.h:667
@ ERROR_EXIT_CODE
Definition World.h:76
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:67
struct FinalizeGarrisonPlotGOInfo::@269 FactionInfo[2]
std::unordered_set< GarrAbilityEntry const * > Traits
Definition GarrisonMgr.h:49
std::unordered_set< GarrAbilityEntry const * > Counters
Definition GarrisonMgr.h:48
constexpr void Relocate(float x, float y)
Definition Position.h:74