aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-05-19 17:13:27 +0200
committerShauren <shauren.trinity@gmail.com>2015-05-19 17:13:27 +0200
commitdd4549cec9f011fd7be3a1c15de0a58ef65892f1 (patch)
tree0894fe122595653ea2f933e9a2879b04c99dc71c /src/server
parent7382c7d5d3ecfce7ae8d59390ba3ffa17eea81a9 (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.h3
-rw-r--r--src/server/game/Garrison/GarrisonMgr.cpp68
-rw-r--r--src/server/game/Garrison/GarrisonMgr.h2
-rw-r--r--src/server/game/Server/Packets/GarrisonPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/GarrisonPackets.h2
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;
};