Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 14 additions & 61 deletions src/CFBG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,12 @@ void CFBG::ClearFakePlayer(Player* player)
return;

player->setRace(_fakePlayerStore[player].RealRace);
player->SetDisplayId(_fakePlayerStore[player].RealMorph);
// Restore via the aura-resolution path, not the entry-time snapshot: a
// player who dropped a shapeshift/transform mid-BG must get the real model
// back, one still in the form keeps the form model. RestoreDisplayId's
// no-aura fallback is the native display, so set that first.
player->SetNativeDisplayId(_fakePlayerStore[player].RealNativeMorph);
player->RestoreDisplayId();
SetFactionForRace(player, _fakePlayerStore[player].RealRace, _fakePlayerStore[player].RealTeamID);

// Clear forced faction reactions. Rank doesn't matter here, not used when they are removed.
Expand Down Expand Up @@ -622,38 +626,18 @@ TeamId CFBG::ResolveWGWarTeam(Player* player, uint32 nativeAllianceInvited, uint
return (_wgMajorityTeam == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
}

void CFBG::DoForgetPlayersInList(Player* player)
{
// m_FakePlayers is filled from a vector within the battleground
// they were in previously so all players that have been in that BG will be invalidated.
for (auto const& itr : _fakeNamePlayersStore)
{
WorldPacket data(SMSG_INVALIDATE_PLAYER, 8);
data << itr.second;
player->GetSession()->SendPacket(&data);

if (Player* _player = ObjectAccessor::FindPlayer(itr.second))
player->GetSession()->SendNameQueryOpcode(_player->GetGUID());
}

_fakeNamePlayersStore.erase(player);
}

void CFBG::FitPlayerInTeam(Player* player, bool action, Battleground* bg)
void CFBG::FitPlayerInTeam(Player* player, Battleground* bg)
{
if (!_IsEnableSystem)
return;

if (!bg)
bg = player->GetBattleground();

if ((!bg || bg->isArena()) && action)
if (!bg || bg->isArena())
return;

if (action)
SetForgetBGPlayers(player, true);
else
SetForgetInListPlayers(player, true);
SetForgetBGPlayers(player, true);
}

void CFBG::SetForgetBGPlayers(Player* player, bool value)
Expand All @@ -666,14 +650,10 @@ bool CFBG::ShouldForgetBGPlayers(Player* player)
return _forgetBGPlayersStore[player];
}

void CFBG::SetForgetInListPlayers(Player* player, bool value)
{
_forgetInListPlayersStore[player] = value;
}

bool CFBG::ShouldForgetInListPlayers(Player* player)
bool CFBG::HasPendingForget(Player* player) const
{
return _forgetInListPlayersStore.find(player) != _forgetInListPlayersStore.end() && _forgetInListPlayersStore[player];
auto const itr = _forgetBGPlayersStore.find(player);
return itr != _forgetBGPlayersStore.end() && itr->second;
}

void CFBG::DoForgetPlayersInBG(Player* player, Battleground* bg)
Expand All @@ -698,25 +678,6 @@ void CFBG::DoForgetPlayersInBG(Player* player, Battleground* bg)
}
}

bool CFBG::SendRealNameQuery(Player* player)
{
if (IsPlayingNative(player))
return false;

WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
data << player->GetGUID().WriteAsPacked(); // player guid
data << uint8(0); // added in 3.1; if > 1, then end of packet
data << player->GetName(); // played name
data << uint8(0); // realm name for cross realm BG usage
data << uint8(player->getRace(true));
data << uint8(player->getGender());
data << uint8(player->getClass());
data << uint8(0); // is not declined
player->GetSession()->SendPacket(&data);

return true;
}

bool CFBG::IsPlayingNative(Player* player)
{
return player->GetTeamId(true) == player->GetBGData().bgTeamId;
Expand Down Expand Up @@ -947,18 +908,10 @@ bool CFBG::isClassJoining(uint8 _class, Player* player, uint32 minLevel)
void CFBG::UpdateForget(Player* player)
{
Battleground* bg = player->GetBattleground();
if (bg)
{
if (ShouldForgetBGPlayers(player) && bg)
{
DoForgetPlayersInBG(player, bg);
SetForgetBGPlayers(player, false);
}
}
else if (ShouldForgetInListPlayers(player))
if (bg && ShouldForgetBGPlayers(player))
{
DoForgetPlayersInList(player);
SetForgetInListPlayers(player, false);
DoForgetPlayersInBG(player, bg);
SetForgetBGPlayers(player, false);
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/CFBG.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ class CFBG

TeamId ResolveBalancedTeam(TeamBalanceContext const& ctx);

bool SendRealNameQuery(Player* player);
bool IsPlayerFake(Player* player);
FakePlayer const* GetFakePlayer(Player* player) const;

Expand All @@ -158,7 +157,6 @@ class CFBG
// of a war, reset in ClearWGWarAssignments.
TeamId ResolveWGWarTeam(Player* player, uint32 nativeAllianceInvited, uint32 nativeHordeInvited);

bool ShouldForgetInListPlayers(Player* player);
bool IsPlayingNative(Player* player);

void ValidatePlayerForBG(Battleground* bg, Player* player);
Expand All @@ -170,12 +168,14 @@ class CFBG
void SetFactionForRace(Player* player, uint8 Race, TeamId teamId);
void ClearFakePlayer(Player* player);
void ReapplyFakePlayer(Player* player);
void DoForgetPlayersInList(Player* player);
void FitPlayerInTeam(Player* player, bool action, Battleground* bg);
void FitPlayerInTeam(Player* player, Battleground* bg);
void DoForgetPlayersInBG(Player* player, Battleground* bg);
void SetForgetBGPlayers(Player* player, bool value);
bool ShouldForgetBGPlayers(Player* player);
void SetForgetInListPlayers(Player* player, bool value);
// Const, non-inserting flag probe for the per-tick update hook
// (ShouldForgetBGPlayers' operator[] would default-insert an entry for
// every online player every tick).
bool HasPendingForget(Player* player) const;
void UpdateForget(Player* player);
void SendMessageQueue(BattlegroundQueue* bgQueue, Battleground* bg, PvPDifficultyEntry const* bracketEntry, Player* leader);

Expand Down Expand Up @@ -219,9 +219,7 @@ class CFBG
TeamId _wgMajorityTeam = TEAM_ALLIANCE;
uint32 _wgMajorityFairShare = 0;
uint32 _wgMajorityNativeKept = 0;
std::unordered_map<Player*, ObjectGuid> _fakeNamePlayersStore;
std::unordered_map<Player*, bool> _forgetBGPlayersStore;
std::unordered_map<Player*, bool> _forgetInListPlayersStore;

std::array<RaceData, 12> _raceData{};
std::array<CFBGRaceInfo, 9> _raceInfo{};
Expand Down
41 changes: 25 additions & 16 deletions src/CFBG_SC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "CFBG.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Chat.h"
#include "Group.h"
#include "ObjectAccessor.h"
#include "Player.h"
Expand Down Expand Up @@ -35,7 +36,7 @@ class CFBG_BG : public BGScript

void OnBattlegroundAddPlayer(Battleground* bg, Player* player) override
{
sCFBG->FitPlayerInTeam(player, true, bg);
sCFBG->FitPlayerInTeam(player, bg);

if (sCFBG->IsEnableResetCooldowns())
player->RemoveArenaSpellCooldowns(true);
Expand All @@ -55,8 +56,6 @@ class CFBG_BG : public BGScript
if (!sCFBG->IsEnableSystem() || bg->isArena())
return;

sCFBG->FitPlayerInTeam(player, false, bg);

if (sCFBG->IsPlayerFake(player))
sCFBG->ClearFakePlayer(player);
}
Expand Down Expand Up @@ -118,7 +117,7 @@ class CFBG_Player : public PlayerScript
return;

if (player->GetTeamId(true) != player->GetBgTeamId())
sCFBG->FitPlayerInTeam(player, player->GetBattleground() && !player->GetBattleground()->isArena(), player->GetBattleground());
sCFBG->FitPlayerInTeam(player, player->GetBattleground());
}

void OnPlayerLogout(Player* player) override
Expand Down Expand Up @@ -175,23 +174,25 @@ class CFBG_Player : public PlayerScript
return true;

if (group->isRaidGroup() || group->GetMembersCount() > sCFBG->GetMaxPlayersCountInGroup())
{
// The client shows only a generic "Join as a group failed.";
// name the actual limit so the leader knows what to change.
ChatHandler(player->GetSession()).PSendSysMessage("Battleground groups are limited to {} players.", sCFBG->GetMaxPlayersCountInGroup());
err = ERR_BATTLEGROUND_JOIN_FAILED;
}

return false;
}

return true;
}

void OnPlayerBeforeUpdate(Player* player, uint32 diff) override
void OnPlayerBeforeUpdate(Player* player, uint32 /*diff*/) override
{
if (timeCheck <= diff)
{
// The flag is set once per BG add (or login into a BG) and cleared
// after service, so serving it on the next tick self-rate-limits.
if (sCFBG->HasPendingForget(player))
sCFBG->UpdateForget(player);
timeCheck = 10000;
}
else
timeCheck -= diff;
}

void OnPlayerBeforeSendChatMessage(Player* player, uint32& type, uint32& lang, std::string& /*msg*/) override
Expand All @@ -212,6 +213,11 @@ class CFBG_Player : public PlayerScript
if (type == CHAT_MSG_ADDON || type == CHAT_MSG_SYSTEM)
return;

// keep proximity chat in the native language so enemies get
// the normal cross-faction scramble instead of readable text
if (type == CHAT_MSG_SAY || type == CHAT_MSG_YELL)
return;

// to gm lang
lang = LANG_UNIVERSAL;
}
Expand Down Expand Up @@ -246,22 +252,25 @@ class CFBG_Player : public PlayerScript

bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool /*incremental*/) override
{
uint32 repGain = player->GetReputation(factionID);
if (!sCFBG->IsEnableSystem())
return true;

TeamId teamId = player->GetTeamId(true);

if ((factionID == FACTION_FROSTWOLF_CLAN && teamId == TEAM_ALLIANCE) ||
(factionID == FACTION_STORMPIKE_GUARD && teamId == TEAM_HORDE))
{
uint32 diff = standing - repGain;
// Signed arithmetic: a reputation LOSS must arrive as a negative
// delta; an unsigned difference would wrap and slam the mirror
// faction to the reputation floor.
int32 current = player->GetReputationMgr().GetReputation(sFactionStore.LookupEntry(factionID));
int32 diff = standing - current;
player->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(teamId == TEAM_ALLIANCE ? FACTION_STORMPIKE_GUARD : FACTION_FROSTWOLF_CLAN), diff);
return false;
}

return true;
}

private:
uint32 timeCheck = 10000;
};

// WG constants duplicated here to avoid pulling in BattlefieldWG.h
Expand Down
2 changes: 0 additions & 2 deletions src/cs_cfbg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ class cfbg_commandscript : public CommandScript
bool const isFake = sCFBG->IsPlayerFake(target);
bool const native = sCFBG->IsPlayingNative(target);
bool const forgetBG = sCFBG->ShouldForgetBGPlayers(target);
bool const forgetList = sCFBG->ShouldForgetInListPlayers(target);
bool const inBG = target->InBattleground();
uint8 const preferredRace = target->GetPlayerSetting("mod-cfbg", SETTING_CFBG_RACE).value;
FakePlayer const* fake = sCFBG->GetFakePlayer(target);
Expand Down Expand Up @@ -161,7 +160,6 @@ class cfbg_commandscript : public CommandScript
uint32(target->getClass()), uint32(target->getGender()));
handler->PSendSysMessage(" Preferred race {}", uint32(preferredRace));
handler->PSendSysMessage(" Forget BG players {}", YesNo(forgetBG));
handler->PSendSysMessage(" Forget in list {}", YesNo(forgetList));

// === Fake record ===
if (fake)
Expand Down
Loading