42 _garrisonPlots[gameObject->OwnerID][gameObject->PropValue[0]] = gameObject;
48 _garrisonBuildingPlotInstances[std::make_pair(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID;
63 if (followerAbility->FactionIndex < 2)
81 if (siteLevel->GarrSiteID == garrSiteId && siteLevel->GarrLevel == level)
101 auto plotItr = mapItr->second.find(garrPlotInstanceId);
102 if (plotItr != mapItr->second.end())
103 return plotItr->second;
113 return plotItr->second.count(garrBuildingId) > 0;
131 for (
uint32 buildingId : itr->second)
151 TC_LOG_ERROR(
"misc",
"Garrison follower db id overflow! Can't continue, shutting down server. ");
173 bool hasForcedExclusiveTrait =
false;
174 std::list<GarrAbilityEntry const*> result;
180 abilities = &itr->second;
182 std::list<GarrAbilityEntry const*> abilityList, forcedAbilities, traitList, forcedTraits;
193 forcedAbilities.push_back(ability);
195 abilityList.push_back(ability);
206 forcedTraits.push_back(ability);
208 traitList.push_back(ability);
218 forcedAbilities.splice(forcedAbilities.end(), abilityList);
219 forcedTraits.splice(forcedTraits.end(), traitList);
222 forcedAbilities.sort();
232 hasForcedExclusiveTrait =
true;
237 if (slots[0] > forcedAbilities.size() + abilityList.size())
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));
248 if (slots[1] > forcedTraits.size() + traitList.size())
250 std::list<GarrAbilityEntry const*> genericTraits, genericTraitsTemp;
262 genericTraitsTemp.push_back(ability);
265 std::set_difference(genericTraitsTemp.begin(), genericTraitsTemp.end(), forcedTraits.begin(), forcedTraits.end(), std::back_inserter(genericTraits));
266 genericTraits.splice(genericTraits.begin(), traitList);
275 return a1->
ID < a2->
ID;
277 genericTraits.unique();
279 std::size_t firstExclusive = 0, total = genericTraits.size();
280 for (
auto genericTraitItr = genericTraits.begin(); genericTraitItr != genericTraits.end(); ++genericTraitItr, ++firstExclusive)
284 while (traitList.size() <
size_t(std::max<int32>(0, slots[1] - forcedTraits.size())) && total)
286 auto genericTraitItr = genericTraits.begin();
287 std::advance(genericTraitItr,
urand(0, total-- - 1));
289 total = firstExclusive;
293 traitList.push_back(*genericTraitItr);
294 genericTraits.erase(genericTraitItr);
298 result.splice(result.end(), forcedAbilities);
299 result.splice(result.end(), abilityList);
300 result.splice(result.end(), forcedTraits);
301 result.splice(result.end(), traitList);
308 std::list<GarrAbilityEntry const*> abilities;
327 abilities = itr->second;
341 QueryResult result =
WorldDatabase.Query(
"SELECT garrPlotInstanceId, hordeGameObjectId, hordeX, hordeY, hordeZ, hordeO, hordeAnimKitId, "
343 "allianceGameObjectId, allianceX, allianceY, allianceZ, allianceO, allianceAnimKitId FROM garrison_plot_finalize_info");
346 TC_LOG_INFO(
"server.loading",
">> Loaded 0 garrison follower class spec abilities. DB table `garrison_plot_finalize_info` is empty.");
353 Field* fields = result->Fetch();
362 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrPlotInstance.db2 entry {} was referenced in `garrison_plot_finalize_info`.", garrPlotInstanceId);
369 TC_LOG_ERROR(
"sql.sql",
"Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId {}.",
370 hordeGameObjectId, garrPlotInstanceId);
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);
381 goTemplate =
sObjectMgr->GetGameObjectTemplate(allianceGameObjectId);
384 TC_LOG_ERROR(
"sql.sql",
"Non-existing gameobject_template entry {} was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId {}.",
385 allianceGameObjectId, garrPlotInstanceId);
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);
396 if (hordeAnimKitId && !
sAnimKitStore.LookupEntry(hordeAnimKitId))
398 TC_LOG_ERROR(
"sql.sql",
"Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`hordeAnimKitId` for garrPlotInstanceId {}.",
399 hordeAnimKitId, garrPlotInstanceId);
403 if (allianceAnimKitId && !
sAnimKitStore.LookupEntry(allianceAnimKitId))
405 TC_LOG_ERROR(
"sql.sql",
"Non-existing AnimKit.dbc entry {} was referenced in `garrison_plot_finalize_info`.`allianceAnimKitId` for garrPlotInstanceId {}.",
406 allianceAnimKitId, garrPlotInstanceId);
419 }
while (result->NextRow());
426 QueryResult result =
WorldDatabase.Query(
"SELECT classSpecId, abilityId FROM garrison_follower_class_spec_abilities");
429 TC_LOG_INFO(
"server.loading",
">> Loaded 0 garrison follower class spec abilities. DB table `garrison_follower_class_spec_abilities` is empty.");
437 Field* fields = result->Fetch();
443 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrClassSpec.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", classSpecId, classSpecId, abilityId);
450 TC_LOG_ERROR(
"sql.sql",
"Non-existing GarrAbility.db2 entry {} was referenced in `garrison_follower_class_spec_abilities` by row ({}, {}).", abilityId, classSpecId, abilityId);
457 }
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__,...)
#define TC_LOG_INFO(filterType__,...)
uint32 urand(uint32 min, uint32 max)
@ GAMEOBJECT_TYPE_GARRISON_PLOT
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Class used to access individual fields of database query result.
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::@283 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)