Merge branch 'master' into Playerbot

# Conflicts:
#	apps/ci/ci-install-modules.sh
#	src/common/Collision/Management/MMapMgr.cpp
#	src/common/Debugging/Errors.h
#	src/server/game/AI/SmartScripts/SmartScript.cpp
#	src/server/game/Battlegrounds/Arena.cpp
#	src/server/game/Battlegrounds/ArenaScore.h
#	src/server/game/Battlegrounds/Battleground.cpp
#	src/server/game/Battlegrounds/BattlegroundMgr.cpp
#	src/server/game/Battlegrounds/BattlegroundMgr.h
#	src/server/game/Battlegrounds/BattlegroundQueue.cpp
#	src/server/game/Battlegrounds/BattlegroundQueue.h
#	src/server/game/Battlegrounds/Zones/BattlegroundAB.h
#	src/server/game/Battlegrounds/Zones/BattlegroundEY.h
#	src/server/game/Battlegrounds/Zones/BattlegroundIC.h
#	src/server/game/Conditions/ConditionMgr.cpp
#	src/server/game/DataStores/M2Stores.cpp
#	src/server/game/DungeonFinding/LFGMgr.cpp
#	src/server/game/Entities/Creature/Creature.cpp
#	src/server/game/Entities/Creature/CreatureData.h
#	src/server/game/Entities/GameObject/GameObject.cpp
#	src/server/game/Entities/GameObject/GameObject.h
#	src/server/game/Entities/Player/Player.cpp
#	src/server/game/Entities/Player/Player.h
#	src/server/game/Entities/Player/PlayerStorage.cpp
#	src/server/game/Entities/Unit/Unit.cpp
#	src/server/game/Entities/Unit/Unit.h
#	src/server/game/Globals/ObjectMgr.cpp
#	src/server/game/Groups/Group.cpp
#	src/server/game/Groups/Group.h
#	src/server/game/Guilds/Guild.cpp
#	src/server/game/Guilds/Guild.h
#	src/server/game/Handlers/BattleGroundHandler.cpp
#	src/server/game/Handlers/CharacterHandler.cpp
#	src/server/game/Scripting/ScriptDefines/BGScript.cpp
#	src/server/game/Scripting/ScriptDefines/DatabaseScript.cpp
#	src/server/game/Scripting/ScriptDefines/PlayerScript.cpp
#	src/server/game/Scripting/ScriptDefines/ServerScript.cpp
#	src/server/game/Scripting/ScriptMgr.cpp
#	src/server/game/Scripting/ScriptMgrMacros.h
#	src/server/game/Server/Packets/MiscPackets.cpp
#	src/server/game/Server/Packets/MiscPackets.h
#	src/server/game/Server/WorldSession.cpp
#	src/server/game/Spells/SpellEffects.cpp
#	src/server/game/World/IWorld.h
#	src/server/game/World/World.cpp
#	src/server/game/World/World.h
#	src/server/scripts/Commands/cs_npc.cpp
#	src/server/scripts/Commands/cs_server.cpp
#	src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
#	src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
#	src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
#	src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp
#	src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp
#	src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.h
#	src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
This commit is contained in:
郑佩茹
2022-03-21 13:57:37 -06:00
150 changed files with 9687 additions and 2113 deletions

View File

@@ -248,7 +248,10 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
m_swingErrorMsg = 0;
for (uint8 j = 0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; ++j)
m_bgBattlegroundQueueID[j] = BATTLEGROUND_QUEUE_NONE;
{
_BgBattlegroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
_BgBattlegroundQueueID[j].invitedToInstance = 0;
}
m_logintime = GameTime::GetGameTime().count();
m_Last_tick = m_logintime;
@@ -2423,23 +2426,23 @@ void Player::GiveLevel(uint8 level)
PlayerClassLevelInfo classInfo;
sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
// send levelup info to client
WorldPacket data(SMSG_LEVELUP_INFO, (4 + 4 + MAX_POWERS * 4 + MAX_STATS * 4));
data << uint32(level);
data << uint32(int32(classInfo.basehealth) - int32(GetCreateHealth()));
// for (int i = 0; i < MAX_POWERS; ++i) // Powers loop (0-6)
data << uint32(int32(classInfo.basemana) - int32(GetCreateMana()));
data << uint32(0);
data << uint32(0);
data << uint32(0);
data << uint32(0);
data << uint32(0);
data << uint32(0);
// end for
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4)
data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i)));
WorldPackets::Misc::LevelUpInfo packet;
packet.Level = level;
packet.HealthDelta = int32(classInfo.basehealth) - int32(GetCreateHealth());
GetSession()->SendPacket(&data);
/// @todo find some better solution
// for (int i = 0; i < MAX_POWERS; ++i)
packet.PowerDelta[0] = int32(classInfo.basemana) - int32(GetCreateMana());
packet.PowerDelta[1] = 0;
packet.PowerDelta[2] = 0;
packet.PowerDelta[3] = 0;
packet.PowerDelta[4] = 0;
packet.PowerDelta[5] = 0;
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
packet.StatDelta[i] = int32(info.stats[i]) - GetCreateStat(Stats(i));
SendDirectMessage(packet.Write());
SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(level));
@@ -6970,7 +6973,7 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change)
continue;
// Spells that should stay on the caster after removing the item.
constexpr std::array<int32, 1> spellExceptions = { /*Electromagnetic Gigaflux Reactivator*/ 11826 };
constexpr std::array<uint32, 1> spellExceptions = { /*Electromagnetic Gigaflux Reactivator*/ 11826 };
const auto found = std::find(std::begin(spellExceptions), std::end(spellExceptions), spellData.SpellId);
// wrong triggering type
@@ -9226,7 +9229,15 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/,
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT));
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE))
{
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
}
else
{
SendMessageToSetInRange_OwnTeam(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true);
}
}
void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/)
@@ -11027,6 +11038,8 @@ void Player::LeaveBattleground(Battleground* bg)
sScriptMgr->OnBattlegroundDesertion(this, BG_DESERTION_TYPE_LEAVE_BG);
}
bg->RemovePlayerAtLeave(this);
// xinef: reset corpse reclaim time
m_deathExpireTime = GameTime::GetGameTime().count();
@@ -11855,10 +11868,102 @@ Battleground* Player::GetBattleground(bool create) const
if (GetBattlegroundId() == 0)
return nullptr;
Battleground* bg = sBattlegroundMgr->GetBattleground(GetBattlegroundId());
Battleground* bg = sBattlegroundMgr->GetBattleground(GetBattlegroundId(), GetBattlegroundTypeId());
return (create || (bg && bg->FindBgMap()) ? bg : nullptr);
}
bool Player::InBattlegroundQueue(bool ignoreArena) const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_NONE &&
(!ignoreArena || (_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_2v2 &&
_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_3v3 &&
_BgBattlegroundQueueID[i].bgQueueTypeId != BATTLEGROUND_QUEUE_5v5)))
return true;
return false;
}
BattlegroundQueueTypeId Player::GetBattlegroundQueueTypeId(uint32 index) const
{
return _BgBattlegroundQueueID[index].bgQueueTypeId;
}
uint32 Player::GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
return i;
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
bool Player::IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
return _BgBattlegroundQueueID[i].invitedToInstance != 0;
return false;
}
bool Player::InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
{
return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
}
uint32 Player::AddBattlegroundQueueId(BattlegroundQueueTypeId val)
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
if (_BgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE || _BgBattlegroundQueueID[i].bgQueueTypeId == val)
{
_BgBattlegroundQueueID[i].bgQueueTypeId = val;
_BgBattlegroundQueueID[i].invitedToInstance = 0;
return i;
}
}
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
bool Player::HasFreeBattlegroundQueueId() const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
return true;
return false;
}
void Player::RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
{
if (_BgBattlegroundQueueID[i].bgQueueTypeId == val)
{
_BgBattlegroundQueueID[i].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
_BgBattlegroundQueueID[i].invitedToInstance = 0;
return;
}
}
}
void Player::SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId)
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].bgQueueTypeId == bgQueueTypeId)
_BgBattlegroundQueueID[i].invitedToInstance = instanceId;
}
bool Player::IsInvitedForBattlegroundInstance(uint32 instanceId) const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (_BgBattlegroundQueueID[i].invitedToInstance == instanceId)
return true;
return false;
}
bool Player::InArena() const
{
Battleground* bg = GetBattleground();
@@ -11870,16 +11975,6 @@ bool Player::InArena() const
void Player::SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
{
// if leaving current bg (and was invited) - decrease invited count for current one
if (m_bgData.bgInstanceID && m_bgData.isInvited)
if (Battleground* bg = sBattlegroundMgr->GetBattleground(m_bgData.bgInstanceID))
bg->DecreaseInvitedCount(m_bgData.bgTeamId);
// if entering new bg (and is invited) - increase invited count for new one
if (id && invited)
if (Battleground* bg = sBattlegroundMgr->GetBattleground(id))
bg->IncreaseInvitedCount(teamId);
m_bgData.bgInstanceID = id;
m_bgData.bgTypeID = bgTypeId;
m_bgData.bgQueueSlot = queueSlot;
@@ -11910,21 +12005,11 @@ bool Player::GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
float Player::GetReputationPriceDiscount(Creature const* creature) const
{
FactionTemplateEntry const* vendorFaction = creature->GetFactionTemplateEntry();
if (!vendorFaction)
{
return 1.0f;
}
return GetReputationPriceDiscount(vendorFaction);
}
float Player::GetReputationPriceDiscount(FactionTemplateEntry const* vendorFaction) const
{
if (!vendorFaction->faction)
FactionTemplateEntry const* vendor_faction = creature->GetFactionTemplateEntry();
if (!vendor_faction || !vendor_faction->faction)
return 1.0f;
ReputationRank rank = GetReputationRank(vendorFaction->faction);
ReputationRank rank = GetReputationRank(vendor_faction->faction);
if (rank <= REP_NEUTRAL)
return 1.0f;
@@ -15850,9 +15935,3 @@ uint32 Player::GetSpellCooldownDelay(uint32 spell_id) const
SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id);
return uint32(itr != m_spellCooldowns.end() && itr->second.end > getMSTime() ? itr->second.end - getMSTime() : 0);
}
void Player::ResetSpeakTimers()
{
m_speakTime = 0;
m_speakCount = 0;
}

View File

@@ -177,7 +177,7 @@ enum TalentTree // talent tabs
// Spell modifier (used for modify other spells)
struct SpellModifier
{
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {}
SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {}
SpellModOp op : 8;
SpellModType type : 8;
int16 charges : 16;
@@ -662,7 +662,7 @@ enum PlayerSlots
#define INVENTORY_SLOT_BAG_0 255
enum EquipmentSlots : uint32 // 19 slots
enum EquipmentSlots // 19 slots
{
EQUIPMENT_SLOT_START = 0,
EQUIPMENT_SLOT_HEAD = 0,
@@ -1323,7 +1323,6 @@ public:
bool _StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
float GetReputationPriceDiscount(Creature const* creature) const;
float GetReputationPriceDiscount(FactionTemplateEntry const* vendorFaction) const;
[[nodiscard]] Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : nullptr; }
[[nodiscard]] TradeData* GetTradeData() const { return m_trade; }
@@ -2189,59 +2188,20 @@ public:
void SetBGData(BGData& bgdata) { m_bgData = bgdata; }
[[nodiscard]] Battleground* GetBattleground(bool create = false) const;
[[nodiscard]] bool InBattlegroundQueue() const
{
for (auto i : m_bgBattlegroundQueueID)
if (i != BATTLEGROUND_QUEUE_NONE)
return true;
return false;
}
[[nodiscard]] bool InBattlegroundQueue(bool ignoreArena = false) const;
[[nodiscard]] bool IsDeserter() const { return HasAura(26013); }
[[nodiscard]] BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const { return m_bgBattlegroundQueueID[index]; }
[[nodiscard]] uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (m_bgBattlegroundQueueID[i] == bgQueueTypeId)
return i;
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
[[nodiscard]] bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
{
return GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
}
[[nodiscard]] BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const;
[[nodiscard]] uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const;
[[nodiscard]] bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const;
[[nodiscard]] bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const;
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId);
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
{
for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (m_bgBattlegroundQueueID[i] == BATTLEGROUND_QUEUE_NONE || m_bgBattlegroundQueueID[i] == val)
{
m_bgBattlegroundQueueID[i] = val;
return i;
}
return PLAYER_MAX_BATTLEGROUND_QUEUES;
}
bool HasFreeBattlegroundQueueId()
{
for (auto & i : m_bgBattlegroundQueueID)
if (i == BATTLEGROUND_QUEUE_NONE)
return true;
return false;
}
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
{
for (auto & i : m_bgBattlegroundQueueID)
if (i == val)
{
i = BATTLEGROUND_QUEUE_NONE;
return;
}
}
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val);
bool HasFreeBattlegroundQueueId() const;
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val);
void SetInviteForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId, uint32 instanceId);
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const;
[[nodiscard]] TeamId GetBgTeamId() const { return m_bgData.bgTeamId != TEAM_NEUTRAL ? m_bgData.bgTeamId : GetTeamId(); }
@@ -2578,9 +2538,7 @@ public:
[[nodiscard]] PlayerSetting GetPlayerSetting(std::string source, uint8 index);
void UpdatePlayerSetting(std::string source, uint8 index, uint32 value);
void ResetSpeakTimers();
protected:
protected:
// Gamemaster whisper whitelist
WhisperListContainer WhisperList;
@@ -2604,7 +2562,13 @@ protected:
/*** BATTLEGROUND SYSTEM ***/
/*********************************************************/
BattlegroundQueueTypeId m_bgBattlegroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
struct BgBattlegroundQueueID_Rec
{
BattlegroundQueueTypeId bgQueueTypeId;
uint32 invitedToInstance;
};
std::array<BgBattlegroundQueueID_Rec, PLAYER_MAX_BATTLEGROUND_QUEUES> _BgBattlegroundQueueID;
BGData m_bgData;
bool m_IsBGRandomWinner;

View File

@@ -6180,6 +6180,8 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint
void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mailItemsResult)
{
time_t cur_time = GameTime::GetGameTime().count();
m_mail.clear();
std::unordered_map<uint32, Mail*> mailById;
@@ -6205,6 +6207,12 @@ void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mail
m->stationery = fields[11].Get<uint8>();
m->mailTemplateId = fields[12].Get<int16>();
if (cur_time > m->expire_time)
{
LOG_DEBUG("entities.player", "Player::_LoadMail: Mail ({}) has expired - ignored.", m->messageID);
continue;
}
if (m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId))
{
LOG_ERROR("entities.player", "Player::_LoadMail: Mail ({}) has nonexistent MailTemplateId ({}), remove at load", m->messageID, m->mailTemplateId);
@@ -7304,9 +7312,7 @@ void Player::_SaveInventory(CharacterDatabaseTransaction trans)
// update enchantment durations
for (EnchantDurationList::iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end(); ++itr)
{
itr->item->SetEnchantmentDuration(itr->slot, itr->leftduration, this);
}
// if no changes
if (m_itemUpdateQueue.empty())