From 2dbbdd5bf369f1264ffb3c4fb8a2bef188c76f7b Mon Sep 17 00:00:00 2001 From: ReyDonovan Date: Thu, 23 May 2024 11:16:55 +0300 Subject: [PATCH] Core: mercenary system --- .../game/Battlegrounds/Battleground.cpp | 26 +++++++++++++++++++ src/server/game/Battlegrounds/Battleground.h | 5 ++++ .../game/Battlegrounds/BattlegroundQueue.cpp | 12 +++++++-- src/server/game/Entities/Player/Player.cpp | 19 ++++++++++++++ src/server/game/Entities/Player/Player.h | 8 ++++++ src/server/game/Handlers/SpellHandler.cpp | 4 +++ src/server/game/Miscellaneous/SharedDefines.h | 6 +++++ .../game/Spells/Auras/SpellAuraEffects.cpp | 14 +++++++++- .../game/Spells/Auras/SpellAuraEffects.h | 1 + src/server/game/Spells/SpellMgr.cpp | 8 ++++++ 10 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 38ffa97a..4850359f 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -590,9 +590,21 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID) void Battleground::RewardReputationToTeam(uint32 factionIDAlliance, uint32 factionIDHorde, uint32 reputation, uint32 teamID) { if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(teamID == ALLIANCE ? factionIDAlliance : factionIDHorde)) + { for (auto const& itr : GetPlayers()) + { if (Player* player = GetPlayerForTeam(teamID, itr, "RewardReputationToTeam")) + { + if (!player) + continue; + + if (player->GetNativeTeam() != teamID) + continue; + player->GetReputationMgr().ModifyReputation(factionEntry, reputation); + } + } + } } void Battleground::UpdateWorldState(uint32 variableID, uint32 value, bool hidden /*= false*/) @@ -1210,6 +1222,9 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); + player->RemoveAurasByType(SPELL_AURA_SWITCH_TEAM); + player->RemoveAurasByType(SPELL_AURA_MOD_FACTION); + if (!player->isAlive()) { player->ResurrectPlayer(1.0f); @@ -1416,6 +1431,17 @@ void Battleground::AddPlayer(Player* player) { player->RemoveArenaSpellCooldowns(true); } + + if (player->HasAura(SPELL_MERCENARY_CONTRACT_HORDE)) + { + player->CastSpell(player, SPELL_MERCENARY_HORDE_1, true); + player->CastSpell(player, SPELL_MERCENARY_HORDE_2, true); + } + else if (player->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE)) + { + player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_1, true); + player->CastSpell(player, SPELL_MERCENARY_ALLIANCE_2, true); + } } PlayerAddedToBGCheckIfBGIsRunning(player); diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 8127795a..8323e79c 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -164,6 +164,11 @@ enum BattlegroundSpells SPELL_BG_DESERTER = 26013, // Battleground Deserter Spell SPELL_BG_CRAVEN = 158263, // Arena Deserter Spell SPELL_BG_LEVEL_OF_CRAVEN = 158950, // Hidden spell for apply diminishing to arena deserter duration + + SPELL_MERCENARY_HORDE_1 = 193864, + SPELL_MERCENARY_HORDE_2 = 195838, + SPELL_MERCENARY_ALLIANCE_1 = 193863, + SPELL_MERCENARY_ALLIANCE_2 = 195843, }; static Milliseconds const PositionBroadcastUpdate = Seconds(5); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index a929043f..8b85cdcc 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -191,14 +191,14 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, uint16 B else if ((sWorld->getBoolConfig(CONFIG_CROSSFACTIONBG) && JoinType == MS::Battlegrounds::JoinType::None) || BgTypeId == MS::Battlegrounds::BattlegroundTypeId::BattlegroundDeathMatch) { if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() == m_SelectionPools[TEAM_HORDE].GetPlayerCount()) - ginfo->Team = leader->GetBGTeam(); + ginfo->Team = leader->GetBgQueueTeam(); else if (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() > m_SelectionPools[TEAM_HORDE].GetPlayerCount()) ginfo->Team = HORDE; else ginfo->Team = ALLIANCE; } else - ginfo->Team = leader->GetBGTeam(); + ginfo->Team = leader->GetBgQueueTeam(); ginfo->MatchmakerRating = mmr; ginfo->OpponentsMatchmakerRating = 0; @@ -231,6 +231,14 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, uint16 B info.LastOnlineTime = lastOnlineTime; info.GroupInfo = ginfo; ginfo->Players[member->GetGUID()] = &info; + + if (ginfo->Team != member->GetTeam()) + { + if (member->GetTeam() == ALLIANCE) + member->CastSpell(member, SPELL_MERCENARY_CONTRACT_HORDE); + else + member->CastSpell(member, SPELL_MERCENARY_CONTRACT_ALLIANCE); + } } } else diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 146e8ea3..a16c3f3b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8760,6 +8760,25 @@ uint32 Player::TeamForRace(uint8 race) return ALLIANCE; } +void Player::SwitchToOppositeTeam(bool apply) +{ + m_team = GetNativeTeam(); + + if (apply) + m_team = (m_team == ALLIANCE) ? HORDE : ALLIANCE; +} + +uint32 Player::GetBgQueueTeam() const +{ + if (HasAura(SPELL_MERCENARY_CONTRACT_HORDE)) + return HORDE; + + if (HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE)) + return ALLIANCE; + + return GetTeam(); +} + void Player::setFactionForRace(uint8 race) { m_team = TeamForRace(race); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7b84e084..5d0c4a51 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2602,10 +2602,18 @@ class Player : public Unit, public GridObject void CheckAreaExploreAndOutdoor(); static uint32 TeamForRace(uint8 race); + static TeamId TeamIdForRace(uint8 race); uint32 GetTeam() const { return m_team; } + void SwitchToOppositeTeam(bool apply); + uint32 GetBgQueueTeam() const; + bool IsInAlliance() const { return m_team == ALLIANCE; } + bool IsInHorde() const { return m_team == HORDE; } TeamId GetTeamId() const { if (m_team == ALLIANCE) return TEAM_ALLIANCE; if (m_team == HORDE) return TEAM_HORDE; return TEAM_NEUTRAL; } void setFactionForRace(uint8 race); + uint32 GetNativeTeam() const { return TeamForRace(getRace()); } + TeamId GetNativeTeamId() const { return TeamIdForRace(getRace()); } + void InitDisplayIds(); bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const; diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 9c86d253..d74fbad1 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -450,6 +450,10 @@ void WorldSession::HandleCancelAura(WorldPackets::Spells::CancelAura& packet) if (!spellInfo->IsPositive() || spellInfo->IsPassive()) return; + if (spellInfo->Id == SPELL_MERCENARY_CONTRACT_HORDE || spellInfo->Id == SPELL_MERCENARY_CONTRACT_ALLIANCE) + if (_player->InBattlegroundQueue()) + return; + player->RemoveOwnedAura(packet.SpellID, packet.CasterGUID, 0, AURA_REMOVE_BY_CANCEL); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index a915823b..f2abe505 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -6342,4 +6342,10 @@ constexpr auto AFFIXES_ALL = static const int32 Reputation_Cap = 42000; static const int32 Reputation_Bottom = -42000; +enum SpecialSpells : uint32 +{ + SPELL_MERCENARY_CONTRACT_HORDE = 193472, + SPELL_MERCENARY_CONTRACT_ALLIANCE = 193475, +}; + #endif diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b73c2548..0a794e00 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -551,7 +551,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNULL, //487 SPELL_AURA_487 &AuraEffect::HandleDisableGravity, //488 SPELL_AURA_DISABLE_GRAVITY &AuraEffect::HandleNULL, //489 SPELL_AURA_FORGET_LANGUAGE - &AuraEffect::HandleNULL, //490 SPELL_AURA_SWITCH_TEAM + &AuraEffect::HandleSwitchTeam, //490 SPELL_AURA_SWITCH_TEAM &AuraEffect::HandleNoImmediateEffect, //491 SPELL_AURA_SPELL_AURA_MOD_HONOR_POINTS_GAIN &AuraEffect::HandleNULL, //492 SPELL_AURA_492 }; @@ -9739,3 +9739,15 @@ void AuraEffect::HandleModVisibilityRange(AuraApplication const* auraApp, uint8 else target->SetRWVisibilityRange(0.0f); } + +void AuraEffect::HandleSwitchTeam(AuraApplication const* aurApp, uint8 mode, bool apply) const +{ + if (!(mode & AURA_EFFECT_HANDLE_REAL)) + return; + + Unit* target = aurApp->GetTarget(); + + if (Player* player = target->ToPlayer()) + player->SwitchToOppositeTeam(apply); +} + diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index b2dc6bbc..c835f226 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -364,6 +364,7 @@ class AuraEffect void HandleAuraProcOnHpBelow(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleExpedite(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleModVisibilityRange(AuraApplication const* aurApp, uint8 mode, bool apply) const; + void HandleSwitchTeam(AuraApplication const* aurApp, uint8 mode, bool apply) const; }; #endif diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 902a5233..0c81626d 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -8053,6 +8053,14 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->Effects[EFFECT_2]->Effect = 0; }); + // Horde / Alliance + ApplySpellFix({ 195838, 195843 }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0]->Effect = SPELL_EFFECT_APPLY_AURA; + spellInfo->Effects[EFFECT_1]->Effect = SPELL_EFFECT_APPLY_AURA; + spellInfo->Effects[EFFECT_2]->Effect = SPELL_EFFECT_APPLY_AURA; + }); + ApplySpellFix({ 232661 }, [](SpellInfo* spellInfo) { spellInfo->Misc.Duration.Duration = 3000;