mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 03:15:41 +00:00
fix(Core/Handlers): Faction Change service properly reset and give ne… (#9729)
Fixes #7981 Fixes #8732
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 */)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user