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

View File

@@ -20,6 +20,7 @@
#include "DBCFileLoader.h"
#include "DBCfmt.h"
#include "Errors.h"
#include "LFGMgr.h"
#include "Log.h"
#include "SharedDefines.h"
#include "SpellMgr.h"
@@ -510,7 +511,7 @@ void LoadDBCStores(const std::string& dataPath)
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++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
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)
{
// 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;
break;
@@ -840,6 +841,19 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
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)
{
for (int32 i = sLightStore.GetNumRows(); i >= 0; --i)

View File

@@ -64,6 +64,8 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB
CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale);
uint32 GetDefaultMapLight(uint32 mapId);
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;

View File

@@ -69,6 +69,7 @@ namespace lfg
LFG_TYPE_NONE = 0,
LFG_TYPE_DUNGEON = 1,
LFG_TYPE_RAID = 2,
LFG_TYPE_ZONE = 4,
LFG_TYPE_HEROIC = 5,
LFG_TYPE_RANDOM = 6
};

View File

@@ -6435,8 +6435,8 @@ void ObjectMgr::GetTaxiPath(uint32 source, uint32 destination, uint32& path, uin
return;
}
cost = dest_i->second.price;
path = dest_i->second.ID;
cost = dest_i->second->price;
path = dest_i->second->ID;
}
uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, TeamId teamId, bool allowed_alt_team /* = false */)

View File

@@ -33,6 +33,7 @@
#include "InstanceSaveMgr.h"
#include "Language.h"
#include "Log.h"
#include "MapMgr.h"
#include "Metric.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
@@ -2174,33 +2175,97 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
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
// this doesn't seem to be 100% blizzlike... but it can't really be helped.
std::ostringstream taximaskstream;
uint32 numFullTaximasks = level / 7;
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
stmt->SetData(0, lowGuid);
trans->Append(stmt);
if (numFullTaximasks > 11)
numFullTaximasks = 11;
// Update Taxi path
TaxiMask newTaxiMask;
memset(newTaxiMask, 0, sizeof(newTaxiMask));
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;
taximaskstream << uint32(factionMask[i] | deathKnightExtraNode) << ' ';
auto FillTaxiMask = [&](uint8 field, uint32 mask)
{
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;
for (uint8 i = 0; i < numEmptyTaximasks; ++i)
taximaskstream << "0 ";
taximaskstream << '0';
std::ostringstream taximaskstream;
for (uint8 i = 0; i < TaxiMaskSize; ++i)
taximaskstream << uint32(newTaxiMask[i]) << ' ';
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
stmt->SetData(0, taximaskstream.str());

View File

@@ -2159,15 +2159,7 @@ struct TalentSpellPos
typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap;
struct TaxiPathBySourceAndDestination
{
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, TaxiPathEntry const*> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource;
typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList;