fix(Core/Handlers): Faction Change service properly reset and give ne… (#9729)

Fixes #7981
Fixes #8732
This commit is contained in:
UltraNix
2022-03-25 11:45:07 +01:00
committed by GitHub
parent 3890f5f000
commit f0eb6d36a3
6 changed files with 107 additions and 33 deletions
+16 -2
View File
@@ -20,6 +20,7 @@
#include "DBCFileLoader.h" #include "DBCFileLoader.h"
#include "DBCfmt.h" #include "DBCfmt.h"
#include "Errors.h" #include "Errors.h"
#include "LFGMgr.h"
#include "Log.h" #include "Log.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "SpellMgr.h" #include "SpellMgr.h"
@@ -510,7 +511,7 @@ void LoadDBCStores(const std::string& dataPath)
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); sTaxiPathSetBySource[entry->from][entry->to] = entry;
// Calculate path nodes count // Calculate path nodes count
uint32 pathCount = sTaxiPathStore.GetNumRows(); uint32 pathCount = sTaxiPathStore.GetNumRows();
@@ -559,7 +560,7 @@ void LoadDBCStores(const std::string& dataPath)
for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i)
{ {
// not spell path // not spell path
if (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end()) if (dest_i->second->price || spellPaths.find(dest_i->second->ID) == spellPaths.end())
{ {
ok = true; ok = true;
break; break;
@@ -840,6 +841,19 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
return nullptr; return nullptr;
} }
LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale)
{
for (LFGDungeonEntry const* dungeon : sLFGDungeonStore)
{
if (dungeon->type == lfg::LFG_TYPE_ZONE && zoneName.find(dungeon->name[locale]) != std::string::npos)
{
return dungeon;
}
}
return nullptr;
}
uint32 GetDefaultMapLight(uint32 mapId) uint32 GetDefaultMapLight(uint32 mapId)
{ {
for (int32 i = sLightStore.GetNumRows(); i >= 0; --i) for (int32 i = sLightStore.GetNumRows(); i >= 0; --i)
+2
View File
@@ -64,6 +64,8 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB
CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender); CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale);
uint32 GetDefaultMapLight(uint32 mapId); uint32 GetDefaultMapLight(uint32 mapId);
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap; typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
+1
View File
@@ -69,6 +69,7 @@ namespace lfg
LFG_TYPE_NONE = 0, LFG_TYPE_NONE = 0,
LFG_TYPE_DUNGEON = 1, LFG_TYPE_DUNGEON = 1,
LFG_TYPE_RAID = 2, LFG_TYPE_RAID = 2,
LFG_TYPE_ZONE = 4,
LFG_TYPE_HEROIC = 5, LFG_TYPE_HEROIC = 5,
LFG_TYPE_RANDOM = 6 LFG_TYPE_RANDOM = 6
}; };
+2 -2
View File
@@ -6435,8 +6435,8 @@ void ObjectMgr::GetTaxiPath(uint32 source, uint32 destination, uint32& path, uin
return; return;
} }
cost = dest_i->second.price; cost = dest_i->second->price;
path = dest_i->second.ID; path = dest_i->second->ID;
} }
uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, TeamId teamId, bool allowed_alt_team /* = false */) uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, TeamId teamId, bool allowed_alt_team /* = false */)
+85 -20
View File
@@ -33,6 +33,7 @@
#include "InstanceSaveMgr.h" #include "InstanceSaveMgr.h"
#include "Language.h" #include "Language.h"
#include "Log.h" #include "Log.h"
#include "MapMgr.h"
#include "Metric.h" #include "Metric.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
@@ -2174,33 +2175,97 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
if (factionChangeInfo->FactionChange) if (factionChangeInfo->FactionChange)
{ {
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
stmt->SetData(0, lowGuid);
trans->Append(stmt);
if (level > 7)
{ {
// Update Taxi path // Delete all Flypaths
// this doesn't seem to be 100% blizzlike... but it can't really be helped. stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
std::ostringstream taximaskstream; stmt->SetData(0, lowGuid);
uint32 numFullTaximasks = level / 7; trans->Append(stmt);
if (numFullTaximasks > 11) // Update Taxi path
numFullTaximasks = 11; TaxiMask newTaxiMask;
memset(newTaxiMask, 0, sizeof(newTaxiMask));
TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask; TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
for (uint8 i = 0; i < numFullTaximasks; ++i) for (auto const& itr : sTaxiPathSetBySource)
{ {
uint8 deathKnightExtraNode = (playerClass == CLASS_DEATH_KNIGHT) ? sDeathKnightTaxiNodesMask[i] : 0; auto FillTaxiMask = [&](uint8 field, uint32 mask)
taximaskstream << uint32(factionMask[i] | deathKnightExtraNode) << ' '; {
if (playerClass == CLASS_DEATH_KNIGHT)
{
newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
}
else
{
newTaxiMask[field] |= mask;
}
};
uint32 nodeId = itr.first;
uint8 field = (uint8)((nodeId - 1) / 32);
uint32 submask = 1 << ((nodeId - 1) % 32);
if ((factionMask[field] & submask) == 0)
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathSetForSource const& taxiPaths = itr.second;
if (taxiPaths.empty())
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathEntry const* taxiPath = taxiPaths.begin()->second;
if (!taxiPath)
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID];
if (taxiNodePaths.empty())
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathNodeEntry const* pathNode = taxiNodePaths.front();
if (!pathNode)
{
FillTaxiMask(field, 0);
continue;
}
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z));
if (!zone)
{
FillTaxiMask(field, 0);
continue;
}
LFGDungeonEntry const* lfgDungeon = GetZoneLFGDungeonEntry(zone->area_name[GetSessionDbLocaleIndex()], GetSessionDbLocaleIndex());
if (!lfgDungeon)
{
FillTaxiMask(field, 0);
continue;
}
// Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid
// If area level is too big, do not add new taxi
if (lfgDungeon->minlevel > level)
{
FillTaxiMask(field, 0);
continue;
}
FillTaxiMask(field, submask);
} }
uint32 numEmptyTaximasks = 11 - numFullTaximasks; std::ostringstream taximaskstream;
for (uint8 i = 0; i < numEmptyTaximasks; ++i) for (uint8 i = 0; i < TaxiMaskSize; ++i)
taximaskstream << "0 "; taximaskstream << uint32(newTaxiMask[i]) << ' ';
taximaskstream << '0';
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK); stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
stmt->SetData(0, taximaskstream.str()); stmt->SetData(0, taximaskstream.str());
+1 -9
View File
@@ -2159,15 +2159,7 @@ struct TalentSpellPos
typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap; typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap;
struct TaxiPathBySourceAndDestination typedef std::map<uint32, TaxiPathEntry const*> TaxiPathSetForSource;
{
TaxiPathBySourceAndDestination() = default;
TaxiPathBySourceAndDestination(uint32 _id, uint32 _price) : ID(_id), price(_price) {}
uint32 ID{0};
uint32 price{0};
};
typedef std::map<uint32, TaxiPathBySourceAndDestination> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource; typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource;
typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList; typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList;