diff options
author | Shauren <shauren.trinity@gmail.com> | 2015-05-19 17:13:27 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2015-05-19 17:13:27 +0200 |
commit | dd4549cec9f011fd7be3a1c15de0a58ef65892f1 (patch) | |
tree | 0894fe122595653ea2f933e9a2879b04c99dc71c /src/server | |
parent | 7382c7d5d3ecfce7ae8d59390ba3ffa17eea81a9 (diff) |
Core/Garrisons: Improved follower ability selection to include exclusive trait flag
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Garrison/Garrison.h | 3 | ||||
-rw-r--r-- | src/server/game/Garrison/GarrisonMgr.cpp | 68 | ||||
-rw-r--r-- | src/server/game/Garrison/GarrisonMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Server/Packets/GarrisonPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/GarrisonPackets.h | 2 |
5 files changed, 60 insertions, 19 deletions
diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h index 348998b276c..be92b9e14f3 100644 --- a/src/server/game/Garrison/Garrison.h +++ b/src/server/game/Garrison/Garrison.h @@ -43,7 +43,8 @@ enum GarrisonAbilityFlags GARRISON_ABILITY_CANNOT_ROLL = 0x02, GARRISON_ABILITY_HORDE_ONLY = 0x04, GARRISON_ABILITY_ALLIANCE_ONLY = 0x08, - GARRISON_ABILITY_FLAG_CANNOT_REMOVE = 0x10 + GARRISON_ABILITY_FLAG_CANNOT_REMOVE = 0x10, + GARRISON_ABILITY_FLAG_EXCLUSIVE = 0x20 }; enum GarrisonError diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp index 3229ee7d02a..75f4289c385 100644 --- a/src/server/game/Garrison/GarrisonMgr.cpp +++ b/src/server/game/Garrison/GarrisonMgr.cpp @@ -139,11 +139,12 @@ uint32 const AbilitiesForQuality[][2] = { 2, 3 } // Legendary }; -std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const +std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const { ASSERT(faction < 2); - std::list<uint32> result; + bool hasForcedExclusiveTrait = false; + std::list<GarrAbilityEntry const*> result; int32 slots[2] = { AbilitiesForQuality[quality][0], AbilitiesForQuality[quality][1] }; GarrAbilities const* abilities = nullptr; @@ -151,7 +152,7 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo if (itr != _garrisonFollowerAbilities[faction].end()) abilities = &itr->second; - std::list<uint32> abilityList, forcedAbilities, traitList, forcedTraits; + std::list<GarrAbilityEntry const*> abilityList, forcedAbilities, traitList, forcedTraits; if (abilities) { for (GarrAbilityEntry const* ability : abilities->Counters) @@ -162,9 +163,9 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo continue; if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) - forcedAbilities.push_back(ability->ID); + forcedAbilities.push_back(ability); else - abilityList.push_back(ability->ID); + abilityList.push_back(ability); } for (GarrAbilityEntry const* ability : abilities->Traits) @@ -175,9 +176,9 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo continue; if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) - forcedTraits.push_back(ability->ID); + forcedTraits.push_back(ability); else - traitList.push_back(ability->ID); + traitList.push_back(ability); } } @@ -191,9 +192,19 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo forcedTraits.splice(forcedTraits.end(), traitList); } + // check if we have a trait from exclusive category + for (GarrAbilityEntry const* ability : forcedTraits) + { + if (ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + { + hasForcedExclusiveTrait = true; + break; + } + } + if (slots[0] > forcedAbilities.size() + abilityList.size()) { - std::list<uint32> classSpecAbilities; // = GetDefaultClassSpecAbilities(follower, faction) + std::list<GarrAbilityEntry const*> classSpecAbilities; // = GetDefaultClassSpecAbilities(follower, faction) abilityList.splice(abilityList.end(), classSpecAbilities); abilityList.sort(); @@ -204,7 +215,7 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo if (slots[1] > forcedTraits.size() + traitList.size()) { - std::list<uint32> genericTraits; + std::list<GarrAbilityEntry const*> genericTraits; for (GarrAbilityEntry const* ability : _garrisonFollowerRandomTraits) { if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) @@ -212,14 +223,43 @@ std::list<uint32> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* fo else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) continue; - genericTraits.push_back(ability->ID); + // forced exclusive trait exists, skip other ones entirely + if (hasForcedExclusiveTrait && ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + continue; + + genericTraits.push_back(ability); } - traitList.splice(traitList.end(), genericTraits); - traitList.sort(); - traitList.unique(); + genericTraits.splice(genericTraits.begin(), traitList); + // "split" the list into two parts [nonexclusive, exclusive] to make selection later easier + genericTraits.sort([](GarrAbilityEntry const* a1, GarrAbilityEntry const* a2) + { + uint32 e1 = a1->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE; + uint32 e2 = a2->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE; + if (e1 != e2) + return e1 < e2; + + return a1->ID < a2->ID; + }); + genericTraits.unique(); - Trinity::Containers::RandomResizeList(traitList, std::max<int32>(0, slots[1] - forcedTraits.size())); + std::size_t firstExclusive = 0, total = genericTraits.size(); + for (auto itr = genericTraits.begin(); itr != genericTraits.end(); ++itr, ++firstExclusive) + if ((*itr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + break; + + while (traitList.size() < std::max<int32>(0, slots[1] - forcedTraits.size()) && !genericTraits.empty()) + { + auto itr = genericTraits.begin(); + std::advance(itr, urand(0, total-- - 1)); + if ((*itr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + total = firstExclusive; // selected exclusive trait - no other can be selected now + else + --firstExclusive; + + traitList.push_back(*itr); + genericTraits.erase(itr); + } } result.splice(result.end(), forcedAbilities); diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h index f037c0867a0..a54606dd9b1 100644 --- a/src/server/game/Garrison/GarrisonMgr.h +++ b/src/server/game/Garrison/GarrisonMgr.h @@ -45,7 +45,7 @@ public: uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const; GarrBuildingEntry const* GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const; uint64 GenerateFollowerDbId(); - std::list<uint32> RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; + std::list<GarrAbilityEntry const*> RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; private: std::unordered_map<uint32 /*garrSiteId*/, std::vector<GarrSiteLevelPlotInstEntry const*>> _garrisonPlotInstBySiteLevel; diff --git a/src/server/game/Server/Packets/GarrisonPackets.cpp b/src/server/game/Server/Packets/GarrisonPackets.cpp index 456149bbdbb..88374e7ce62 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.cpp +++ b/src/server/game/Server/Packets/GarrisonPackets.cpp @@ -60,8 +60,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonFollowe data << uint32(follower.CurrentMissionID); data << uint32(follower.AbilityID.size()); data << uint32(follower.FollowerStatus); - for (uint32 abilityId : follower.AbilityID) - data << uint32(abilityId); + for (GarrAbilityEntry const* ability : follower.AbilityID) + data << uint32(ability->ID); return data; } diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h index 5fc386ab72b..5c7af650e29 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.h +++ b/src/server/game/Server/Packets/GarrisonPackets.h @@ -74,7 +74,7 @@ namespace WorldPackets uint32 Xp = 0; uint32 CurrentBuildingID = 0; uint32 CurrentMissionID = 0; - std::list<uint32> AbilityID; + std::list<GarrAbilityEntry const*> AbilityID; uint32 FollowerStatus; }; |