45 _garrisonPlots[gameObject->OwnerID][gameObject->PropValue[0]] = gameObject;
51 _garrisonBuildingPlotInstances[std::make_pair(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID;
66 if (followerAbility->FactionIndex < 2)
84 if (siteLevel->GarrSiteID == garrSiteId && siteLevel->GarrLevel == level)
104 auto plotItr = mapItr->second.find(garrPlotInstanceId);
105 if (plotItr != mapItr->second.end())
106 return plotItr->second;
116 return plotItr->second.count(garrBuildingId) > 0;
134 for (
uint32 buildingId : itr->second)
154 TC_LOG_ERROR(
"misc",
"Garrison follower db id overflow! Can't continue, shutting down server. ");
176 bool hasForcedExclusiveTrait =
false;
177 std::list<GarrAbilityEntry const*> result;
183 abilities = &itr->second;
185 std::list<GarrAbilityEntry const*> abilityList, forcedAbilities, traitList, forcedTraits;
196 forcedAbilities.push_back(ability);
198 abilityList.push_back(ability);
209 forcedTraits.push_back(ability);
211 traitList.push_back(ability);
221 forcedAbilities.splice(forcedAbilities.end(), abilityList);
222 forcedTraits.splice(forcedTraits.end(), traitList);
225 forcedAbilities.sort();
235 hasForcedExclusiveTrait =
true;
240 if (slots[0] > forcedAbilities.size() + abilityList.size())
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));
251 if (slots[1] > forcedTraits.size() + traitList.size())
253 std::list<GarrAbilityEntry const*> genericTraits, genericTraitsTemp;
265 genericTraitsTemp.push_back(ability);
268 std::set_difference(genericTraitsTemp.begin(), genericTraitsTemp.end(), forcedTraits.begin(), forcedTraits.end(), std::back_inserter(genericTraits));
269 genericTraits.splice(genericTraits.begin(), traitList);
278 return a1->
ID < a2->
ID;
280 genericTraits.unique();
282 std::size_t firstExclusive = 0, total = genericTraits.size();
283 for (
auto genericTraitItr = genericTraits.begin(); genericTraitItr != genericTraits.end(); ++genericTraitItr, ++firstExclusive)
287 while (traitList.size() < size_t(std::max<int32>(0, slots[1] - forcedTraits.size())) && total)
289 auto genericTraitItr = genericTraits.begin();
290 std::advance(genericTraitItr,
urand(0, total-- - 1));
292 total = firstExclusive;
296 traitList.push_back(*genericTraitItr);
297 genericTraits.erase(genericTraitItr);
301 result.splice(result.end(), forcedAbilities);
302 result.splice(result.end(), abilityList);
303 result.splice(result.end(), forcedTraits);
304 result.splice(result.end(), traitList);
311 std::list<GarrAbilityEntry const*> abilities;
330 abilities = itr->second;
344 QueryResult result =
WorldDatabase.Query(
"SELECT garrPlotInstanceId, hordeGameObjectId, hordeX, hordeY, hordeZ, hordeO, hordeAnimKitId, "
346 "allianceGameObjectId, allianceX, allianceY, allianceZ, allianceO, allianceAnimKitId FROM garrison_plot_finalize_info");
349 TC_LOG_INFO(
"server.loading",
">> Loaded 0 garrison follower class spec abilities. DB table `garrison_plot_finalize_info` is empty.");
356 Field* fields = result->Fetch();
365 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrPlotInstance.db2 entry {} was referenced in `garrison_plot_finalize_info`.", garrPlotInstanceId);
372 TC_LOG_ERROR(
"sql.sql",
"Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId {}.",
373 hordeGameObjectId, garrPlotInstanceId);
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);
384 goTemplate =
sObjectMgr->GetGameObjectTemplate(allianceGameObjectId);
387 TC_LOG_ERROR(
"sql.sql",
"Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId {}.",
388 allianceGameObjectId, garrPlotInstanceId);
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);
399 if (hordeAnimKitId && !
sAnimKitStore.LookupEntry(hordeAnimKitId))
401 TC_LOG_ERROR(
"sql.sql",
"Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`hordeAnimKitId` for garrPlotInstanceId {}.",
402 hordeAnimKitId, garrPlotInstanceId);
406 if (allianceAnimKitId && !
sAnimKitStore.LookupEntry(allianceAnimKitId))
408 TC_LOG_ERROR(
"sql.sql",
"Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`allianceAnimKitId` for garrPlotInstanceId {}.",
409 allianceAnimKitId, garrPlotInstanceId);
422 }
while (result->NextRow());
429 QueryResult result =
WorldDatabase.Query(
"SELECT classSpecId, abilityId FROM garrison_follower_class_spec_abilities");
432 TC_LOG_INFO(
"server.loading",
">> Loaded 0 garrison follower class spec abilities. DB table `garrison_follower_class_spec_abilities` is empty.");
440 Field* fields = result->Fetch();
446 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrClassSpec.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", classSpecId, classSpecId, abilityId);
453 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrAbility.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", abilityId, classSpecId, abilityId);
460 }
while (result->NextRow());
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.
uint32 const AbilitiesForQuality[][2]
@ GARRISON_FACTION_INDEX_HORDE
@ GARRISON_FACTION_INDEX_ALLIANCE
@ GARRISON_ABILITY_FLAG_EXCLUSIVE
@ GARRISON_ABILITY_FLAG_CANNOT_REMOVE
@ GARRISON_ABILITY_FLAG_TRAIT
@ GARRISON_ABILITY_ALLIANCE_ONLY
@ GARRISON_ABILITY_CANNOT_ROLL
@ GARRISON_ABILITY_HORDE_ONLY
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
uint32 urand(uint32 min, uint32 max)
@ GAMEOBJECT_TYPE_GARRISON_PLOT
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Class used to access individual fields of database query result.
uint32 GetUInt32() const noexcept
uint16 GetUInt16() const noexcept
FinalizeGarrisonPlotGOInfo const * GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const
GarrSiteLevelEntry const * GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const
std::unordered_map< uint32, GarrAbilities > _garrisonFollowerAbilities[2]
std::unordered_map< uint32, std::vector< uint32 > > _garrisonBuildingsByType
static GarrisonMgr & Instance()
std::set< GarrAbilityEntry const * > _garrisonFollowerRandomTraits
uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const
std::vector< GarrSiteLevelPlotInstEntry const * > const * GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const
std::unordered_map< uint32, FinalizeGarrisonPlotGOInfo > _finalizePlotGOInfo
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
GameObjectsEntry const * GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const
bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const
std::unordered_map< uint32, std::list< GarrAbilityEntry const * > > _garrisonFollowerClassSpecAbilities
std::unordered_map< uint32, std::unordered_set< uint32 > > _garrisonBuildingsByPlot
std::list< GarrAbilityEntry const * > GetClassSpecAbilities(GarrFollowerEntry const *follower, uint32 faction) const
void InitializeDbIdSequences()
std::unordered_map< uint32, std::vector< GarrSiteLevelPlotInstEntry const * > > _garrisonPlotInstBySiteLevel
std::unordered_map< std::pair< uint32, uint32 >, uint32 > _garrisonBuildingPlotInstances
uint32 GetPreviousLevelBuildingId(uint32 buildingType, uint32 currentLevel) const
uint64 _followerDbIdGenerator
void LoadFollowerClassSpecAbilities()
uint64 GenerateFollowerDbId()
static void StopNow(uint8 exitcode)
void RandomResize(C &container, std::size_t requestedSize)
struct FinalizeGarrisonPlotGOInfo::@269 FactionInfo[2]
std::unordered_set< GarrAbilityEntry const * > Traits
std::unordered_set< GarrAbilityEntry const * > Counters
int32 HordeGarrClassSpecID
int32 AllianceGarrClassSpecID
constexpr void Relocate(float x, float y)