diff options
Diffstat (limited to 'src/server/game/Garrison/GarrisonMgr.cpp')
-rw-r--r-- | src/server/game/Garrison/GarrisonMgr.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp index f81baa6ddf1..bb2d44d7141 100644 --- a/src/server/game/Garrison/GarrisonMgr.cpp +++ b/src/server/game/Garrison/GarrisonMgr.cpp @@ -16,7 +16,10 @@ */ #include "GarrisonMgr.h" +#include "Containers.h" +#include "Garrison.h" #include "ObjectDefines.h" +#include "World.h" void GarrisonMgr::Initialize() { @@ -35,6 +38,23 @@ void GarrisonMgr::Initialize() for (GarrBuildingEntry const* building : sGarrBuildingStore) _garrisonBuildingsByType[building->Type].push_back(building); + + for (GarrFollowerXAbilityEntry const* followerAbility : sGarrFollowerXAbilityStore) + { + if (GarrAbilityEntry const* ability = sGarrAbilityStore.LookupEntry(followerAbility->GarrAbilityID)) + { + if (!(ability->Flags & GARRISON_ABILITY_CANNOT_ROLL) && ability->Flags & GARRISON_ABILITY_FLAG_TRAIT) + _garrisonFollowerRandomTraits.insert(ability); + + if (followerAbility->FactionIndex < 2) + { + if (ability->Flags & GARRISON_ABILITY_FLAG_TRAIT) + _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Traits.insert(ability); + else + _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Counters.insert(ability); + } + } + } } GarrSiteLevelEntry const* GarrisonMgr::GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const @@ -96,3 +116,116 @@ GarrBuildingEntry const* GarrisonMgr::GetPreviousLevelBuilding(uint32 buildingTy return nullptr; } + +uint64 GarrisonMgr::GenerateFollowerDbId() +{ + if (_followerDbIdGenerator >= std::numeric_limits<uint64>::max()) + { + TC_LOG_ERROR("misc", "Garrison follower db id oberflow! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + + return _followerDbIdGenerator++; +} + +uint32 const AbilitiesForQuality[][2] = +{ + // Counters, Traits + { 0, 0 }, + { 1, 0 }, + { 1, 1 }, // Uncommon + { 1, 2 }, // Rare + { 2, 3 }, // Epic + { 2, 3 } // Legendary +}; + +std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const +{ + ASSERT(faction < 2); + + std::list<uint32> result; + int32 slots[2] = { AbilitiesForQuality[quality][0], AbilitiesForQuality[quality][1] }; + + GarrAbilities const* abilities = nullptr; + auto itr = _garrisonFollowerAbilities[faction].find(follower->ID); + if (itr != _garrisonFollowerAbilities[faction].end()) + abilities = &itr->second; + + std::list<uint32> abilityList, forcedAbilities, traitList, forcedTraits; + if (abilities) + { + for (GarrAbilityEntry const* ability : abilities->Counters) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) + forcedAbilities.push_back(ability->ID); + else + abilityList.push_back(ability->ID); + } + + for (GarrAbilityEntry const* ability : abilities->Traits) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) + forcedTraits.push_back(ability->ID); + else + traitList.push_back(ability->ID); + } + } + + Trinity::Containers::RandomResizeList(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size())); + Trinity::Containers::RandomResizeList(traitList, std::max<int32>(0, slots[1] - forcedTraits.size())); + + // Add counters specified in GarrFollowerXAbility.db2 before generic classspec ones on follower creation + if (initial) + { + forcedAbilities.splice(forcedAbilities.end(), abilityList); + forcedTraits.splice(forcedTraits.end(), traitList); + } + + if (slots[0] > forcedAbilities.size() + abilityList.size()) + { + std::list<uint32> classSpecAbilities; // = GetDefaultClassSpecAbilities(follower, faction) + + abilityList.splice(abilityList.end(), classSpecAbilities); + abilityList.sort(); + abilityList.unique(); + + Trinity::Containers::RandomResizeList(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size())); + } + + if (slots[1] > forcedTraits.size() + traitList.size()) + { + std::list<uint32> genericTraits; + for (GarrAbilityEntry const* ability : _garrisonFollowerRandomTraits) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + genericTraits.push_back(ability->ID); + } + + traitList.splice(traitList.end(), genericTraits); + traitList.sort(); + traitList.unique(); + + Trinity::Containers::RandomResizeList(traitList, std::max<int32>(0, slots[1] - forcedTraits.size())); + } + + result.splice(result.end(), forcedAbilities); + result.splice(result.end(), abilityList); + result.splice(result.end(), forcedTraits); + result.splice(result.end(), traitList); + + return result; +} |