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 "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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 */)
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user