aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorJeremy <Golrag@users.noreply.github.com>2022-02-26 19:01:00 +0100
committerGitHub <noreply@github.com>2022-02-26 19:01:00 +0100
commit19f64e66e58d3d7ebed6437a474a134e7c673ed6 (patch)
tree26c5dac813d3400ea4a52e24b1b863db8ebed8a0 /src/server/game/Entities/GameObject
parentee835671b4f572f92f79c9b302764ee591c6de11 (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.cpp215
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h20
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: