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