diff options
| author | Jeremy <Golrag@users.noreply.github.com> | 2022-02-26 19:01:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-26 19:01:00 +0100 |
| commit | 19f64e66e58d3d7ebed6437a474a134e7c673ed6 (patch) | |
| tree | 26c5dac813d3400ea4a52e24b1b863db8ebed8a0 /src/server/game/Entities/GameObject | |
| parent | ee835671b4f572f92f79c9b302764ee591c6de11 (diff) | |
Core/GameObjects: Implemented GAMEOBJECT_TYPE_CAPTURE_POINT (#27034)
Diffstat (limited to 'src/server/game/Entities/GameObject')
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 215 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 20 |
2 files changed, 235 insertions, 0 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1fe707abe24..a5ddbc2f5a1 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -20,6 +20,7 @@ #include "AzeriteItem.h" #include "AzeritePackets.h" #include "Battleground.h" +#include "BattlegroundPackets.h" #include "CellImpl.h" #include "CreatureAISelector.h" #include "DatabaseEnv.h" @@ -442,6 +443,10 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD break; case GAMEOBJECT_TYPE_CAPTURE_POINT: SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::SpellVisualID), m_goInfo->capturePoint.SpellVisual1); + m_goValue.CapturePoint.AssaultTimer = 0; + m_goValue.CapturePoint.LastTeamCapture = TEAM_NEUTRAL; + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::Neutral; + UpdateCapturePoint(); break; default: SetGoAnimProgress(animProgress); @@ -791,6 +796,47 @@ void GameObject::Update(uint32 diff) SetLootState(GO_ACTIVATED, target); } + else if (goInfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT) + { + bool hordeCapturing = m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde; + bool allianceCapturing = m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance; + if (hordeCapturing || allianceCapturing) + { + if (m_goValue.CapturePoint.AssaultTimer <= diff) + { + m_goValue.CapturePoint.State = hordeCapturing ? WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured : WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured; + if (hordeCapturing) + { + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured; + if (BattlegroundMap* map = GetMap()->ToBattlegroundMap()) + { + if (Battleground* bg = map->GetBG()) + { + EventInform(GetGOInfo()->capturePoint.CaptureEventHorde); + bg->SendBroadcastText(GetGOInfo()->capturePoint.CaptureBroadcastHorde, CHAT_MSG_BG_SYSTEM_HORDE); + } + } + } + else + { + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured; + if (BattlegroundMap* map = GetMap()->ToBattlegroundMap()) + { + if (Battleground* bg = map->GetBG()) + { + EventInform(GetGOInfo()->capturePoint.CaptureEventAlliance); + bg->SendBroadcastText(GetGOInfo()->capturePoint.CaptureBroadcastAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE); + } + } + } + + m_goValue.CapturePoint.LastTeamCapture = hordeCapturing ? TEAM_HORDE : TEAM_ALLIANCE; + UpdateCapturePoint(); + } + else + m_goValue.CapturePoint.AssaultTimer -= diff; + } + } else if (uint32 max_charges = goInfo->GetCharges()) { if (m_usetimes >= max_charges) @@ -1038,6 +1084,12 @@ void GameObject::Delete() SetLootState(GO_NOT_READY); RemoveFromOwner(); + if (m_goInfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT) + { + WorldPackets::Battleground::CapturePointRemoved packet(GetGUID()); + SendMessageToSet(packet.Write(), true); + } + SendGameObjectDespawn(); SetGoState(GO_STATE_READY); @@ -2946,6 +2998,161 @@ void GameObject::SetSpellVisualId(int32 spellVisualId, ObjectGuid activatorGuid) SendMessageToSet(packet.Write(), true); } +void GameObject::AssaultCapturePoint(Player* player) +{ + if (!CanInteractWithCapturePoint(player)) + return; + + if (GameObjectAI* ai = AI()) + if (ai->OnCapturePointAssaulted(player)) + return; + + // only supported in battlegrounds + Battleground* battleground = nullptr; + if (BattlegroundMap* map = GetMap()->ToBattlegroundMap()) + if (Battleground* bg = map->GetBG()) + battleground = bg; + + if (!battleground) + return; + + // Cancel current timer + m_goValue.CapturePoint.AssaultTimer = 0; + + if (player->GetBGTeam() == HORDE) + { + if (m_goValue.CapturePoint.LastTeamCapture == TEAM_HORDE) + { + // defended. capture instantly. + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured; + battleground->SendBroadcastText(GetGOInfo()->capturePoint.DefendedBroadcastHorde, CHAT_MSG_BG_SYSTEM_HORDE, player); + UpdateCapturePoint(); + EventInform(GetGOInfo()->capturePoint.DefendedEventHorde, player); + return; + } + + switch (m_goValue.CapturePoint.State) + { + case WorldPackets::Battleground::BattlegroundCapturePointState::Neutral: + case WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured: + case WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance: + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde; + battleground->SendBroadcastText(GetGOInfo()->capturePoint.AssaultBroadcastHorde, CHAT_MSG_BG_SYSTEM_HORDE, player); + UpdateCapturePoint(); + EventInform(GetGOInfo()->capturePoint.AssaultBroadcastHorde, player); + m_goValue.CapturePoint.AssaultTimer = GetGOInfo()->capturePoint.CaptureTime; + break; + default: + break; + } + } + else + { + if (m_goValue.CapturePoint.LastTeamCapture == TEAM_ALLIANCE) + { + // defended. capture instantly. + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured; + battleground->SendBroadcastText(GetGOInfo()->capturePoint.DefendedBroadcastAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, player); + UpdateCapturePoint(); + EventInform(GetGOInfo()->capturePoint.DefendedEventAlliance, player); + return; + } + + switch (m_goValue.CapturePoint.State) + { + case WorldPackets::Battleground::BattlegroundCapturePointState::Neutral: + case WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured: + case WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde: + m_goValue.CapturePoint.State = WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance; + battleground->SendBroadcastText(GetGOInfo()->capturePoint.AssaultBroadcastAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, player); + UpdateCapturePoint(); + EventInform(GetGOInfo()->capturePoint.ContestedEventAlliance, player); + m_goValue.CapturePoint.AssaultTimer = GetGOInfo()->capturePoint.CaptureTime; + break; + default: + break; + } + } +} + +void GameObject::UpdateCapturePoint() +{ + if (GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT) + return; + + if (GameObjectAI* ai = AI()) + if (ai->OnCapturePointUpdated(m_goValue.CapturePoint.State)) + return; + + uint32 spellVisualId = 0; + uint32 customAnim = 0; + + switch (m_goValue.CapturePoint.State) + { + case WorldPackets::Battleground::BattlegroundCapturePointState::Neutral: + spellVisualId = GetGOInfo()->capturePoint.SpellVisual1; + break; + case WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde: + customAnim = 1; + spellVisualId = GetGOInfo()->capturePoint.SpellVisual2; + break; + case WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance: + customAnim = 2; + spellVisualId = GetGOInfo()->capturePoint.SpellVisual3; + break; + case WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured: + customAnim = 3; + spellVisualId = GetGOInfo()->capturePoint.SpellVisual4; + break; + case WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured: + customAnim = 4; + spellVisualId = GetGOInfo()->capturePoint.SpellVisual5; + break; + default: + break; + } + + if (customAnim != 0) + SendCustomAnim(customAnim); + + SetSpellVisualId(spellVisualId); + UpdateDynamicFlagsForNearbyPlayers(); + + if (BattlegroundMap* map = GetMap()->ToBattlegroundMap()) + { + if (Battleground* bg = map->GetBG()) + { + WorldPackets::Battleground::UpdateCapturePoint packet; + packet.CapturePointInfo.State = m_goValue.CapturePoint.State; + packet.CapturePointInfo.Pos = GetPosition(); + packet.CapturePointInfo.Guid = GetGUID(); + packet.CapturePointInfo.CaptureTotalDuration = Milliseconds(GetGOInfo()->capturePoint.CaptureTime); + packet.CapturePointInfo.CaptureTime = m_goValue.CapturePoint.AssaultTimer; + bg->SendPacketToAll(packet.Write()); + bg->UpdateWorldState(GetGOInfo()->capturePoint.worldState1, AsUnderlyingType(m_goValue.CapturePoint.State)); + } + } +} + +bool GameObject::CanInteractWithCapturePoint(Player const* target) const +{ + if (m_goInfo->type != GAMEOBJECT_TYPE_CAPTURE_POINT) + return false; + + if (m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::Neutral) + return true; + + if (target->GetBGTeam() == HORDE) + { + return m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance + || m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured; + } + + // For Alliance players + return m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde + || m_goValue.CapturePoint.State == WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured; +} + class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase { public: @@ -2965,6 +3172,14 @@ private: GameObject* _owner; }; +void GameObject::UpdateDynamicFlagsForNearbyPlayers() const +{ + ValuesUpdateForPlayerWithMaskSender sender(this); + sender.ObjectMask.MarkChanged(&UF::ObjectData::DynamicFlags); + Trinity::MessageDistDeliverer<ValuesUpdateForPlayerWithMaskSender> deliverer(this, sender, GetVisibilityRange()); + Cell::VisitWorldObjects(this, deliverer, GetVisibilityRange()); +} + void GameObject::CreateModel() { m_model = GameObjectModel::Create(std::make_unique<GameObjectModelOwnerImpl>(this), sWorld->GetDataPath()); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 964101df642..22b09a74b92 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -33,6 +33,14 @@ class Unit; struct TransportAnimation; enum TriggerCastFlags : uint32; +namespace WorldPackets +{ + namespace Battleground + { + enum class BattlegroundCapturePointState : uint8; + } +} + union GameObjectValue { //11 GAMEOBJECT_TYPE_TRANSPORT @@ -60,6 +68,13 @@ union GameObjectValue uint32 Health; uint32 MaxHealth; } Building; + //42 GAMEOBJECT_TYPE_CAPTURE_POINT + struct + { + TeamId LastTeamCapture; + WorldPackets::Battleground::BattlegroundCapturePointState State; + uint32 AssaultTimer; + } CapturePoint; }; // For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ... @@ -324,12 +339,17 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SetWorldEffectID(uint32 worldEffectID) { _worldEffectID = worldEffectID; } void SetSpellVisualId(int32 spellVisualId, ObjectGuid activatorGuid = ObjectGuid::Empty); + void AssaultCapturePoint(Player* player); + void UpdateCapturePoint(); + bool CanInteractWithCapturePoint(Player const* target) const; void AIM_Destroy(); bool AIM_Initialize(); std::string GetDebugInfo() const override; + void UpdateDynamicFlagsForNearbyPlayers() const; + UF::UpdateField<UF::GameObjectData, 0, TYPEID_GAMEOBJECT> m_gameObjectData; protected: |
