aboutsummaryrefslogtreecommitdiff
path: root/src
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
parentee835671b4f572f92f79c9b302764ee591c6de11 (diff)
Core/GameObjects: Implemented GAMEOBJECT_TYPE_CAPTURE_POINT (#27034)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h13
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp215
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h20
-rw-r--r--src/server/game/Entities/Object/Updates/ViewerDependentValues.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.cpp27
-rw-r--r--src/server/game/Server/Packets/BattlegroundPackets.h39
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp6
-rw-r--r--src/server/game/Spells/SpellEffects.cpp5
10 files changed, 331 insertions, 4 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index e7eb63e3a02..c047ecd88f8 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -32,6 +32,14 @@ class Unit;
class WorldObject;
enum class QuestGiverStatus : uint32;
+namespace WorldPackets
+{
+ namespace Battleground
+ {
+ enum class BattlegroundCapturePointState : uint8;
+ }
+}
+
class TC_GAME_API GameObjectAI
{
private:
@@ -107,6 +115,11 @@ class TC_GAME_API GameObjectAI
virtual void SummonedCreatureDespawn(Creature* /*summon*/) { }
virtual void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) { }
+
+ // Called when the capture point gets assaulted by a player. Return true to disable default behaviour.
+ virtual bool OnCapturePointAssaulted(Player* /*player*/) { return false; }
+ // Called when the capture point state gets updated. Return true to disable default behaviour.
+ virtual bool OnCapturePointUpdated(WorldPackets::Battleground::BattlegroundCapturePointState /*state*/) { return false; }
};
class TC_GAME_API NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 8b2e9e414d9..29fcc2c7719 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -340,6 +340,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundQueueTypeId que
bg = new BattlegroundWS(*(BattlegroundWS*)bg_template);
break;
case BATTLEGROUND_AB:
+ case BATTLEGROUND_DOM_AB:
bg = new BattlegroundAB(*(BattlegroundAB*)bg_template);
break;
case BATTLEGROUND_NA:
@@ -411,6 +412,7 @@ bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate)
bg = new BattlegroundWS(bgTemplate);
break;
case BATTLEGROUND_AB:
+ case BATTLEGROUND_DOM_AB:
bg = new BattlegroundAB(bgTemplate);
break;
case BATTLEGROUND_NA:
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:
diff --git a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h
index 2f6db818a38..8b3ac1695c6 100644
--- a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h
+++ b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h
@@ -94,6 +94,12 @@ public:
}
break;
}
+ case GAMEOBJECT_TYPE_CAPTURE_POINT:
+ if (!gameObject->CanInteractWithCapturePoint(receiver))
+ dynFlags |= GO_DYNFLAG_LO_NO_INTERACT;
+ else
+ dynFlags &= ~GO_DYNFLAG_LO_NO_INTERACT;
+ break;
default:
break;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 52713e1fe90..c1ac6f3f357 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -9333,7 +9333,7 @@ void Player::SendInitWorldStates(uint32 zoneId, uint32 areaId)
}
break;
case 3358: // Arathi Basin
- if (battleground && battleground->GetTypeID(true) == BATTLEGROUND_AB)
+ if (battleground && (battleground->GetTypeID(true) == BATTLEGROUND_AB || battleground->GetTypeID(true) == BATTLEGROUND_DOM_AB))
battleground->FillInitialWorldStates(packet);
else
{
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp
index 08ac3bd490d..1c8abe81261 100644
--- a/src/server/game/Server/Packets/BattlegroundPackets.cpp
+++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp
@@ -373,3 +373,30 @@ WorldPacket const* WorldPackets::Battleground::PVPMatchComplete::Write()
return &_worldPacket;
}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::BattlegroundCapturePointInfo const& battlegroundCapturePointInfo)
+{
+ data << battlegroundCapturePointInfo.Guid;
+ data << battlegroundCapturePointInfo.Pos;
+ data << int8(battlegroundCapturePointInfo.State);
+
+ if (battlegroundCapturePointInfo.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedHorde || battlegroundCapturePointInfo.State == WorldPackets::Battleground::BattlegroundCapturePointState::ContestedAlliance)
+ {
+ data << battlegroundCapturePointInfo.CaptureTime;
+ data << battlegroundCapturePointInfo.CaptureTotalDuration;
+ }
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Battleground::UpdateCapturePoint::Write()
+{
+ _worldPacket << CapturePointInfo;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battleground::CapturePointRemoved::Write()
+{
+ _worldPacket << CapturePointGUID;
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h
index f5af61fe805..fcc98786fa6 100644
--- a/src/server/game/Server/Packets/BattlegroundPackets.h
+++ b/src/server/game/Server/Packets/BattlegroundPackets.h
@@ -498,6 +498,45 @@ namespace WorldPackets
Optional<PVPMatchStatistics> LogData;
uint32 SoloShuffleStatus = 0;
};
+
+ enum class BattlegroundCapturePointState : uint8
+ {
+ Neutral = 1,
+ ContestedHorde = 2,
+ ContestedAlliance = 3,
+ HordeCaptured = 4,
+ AllianceCaptured = 5
+ };
+
+ struct BattlegroundCapturePointInfo
+ {
+ ObjectGuid Guid;
+ TaggedPosition<Position::XY> Pos;
+ BattlegroundCapturePointState State = BattlegroundCapturePointState::Neutral;
+ Timestamp<> CaptureTime;
+ Duration<Milliseconds, uint32> CaptureTotalDuration;
+ };
+
+ class UpdateCapturePoint final : public ServerPacket
+ {
+ public:
+ UpdateCapturePoint() : ServerPacket(SMSG_UPDATE_CAPTURE_POINT) { }
+
+ WorldPacket const* Write() override;
+
+ BattlegroundCapturePointInfo CapturePointInfo;
+ };
+
+ class CapturePointRemoved final : public ServerPacket
+ {
+ public:
+ CapturePointRemoved() : ServerPacket(SMSG_CAPTURE_POINT_REMOVED) { }
+ CapturePointRemoved(ObjectGuid capturePointGUID) : ServerPacket(SMSG_CAPTURE_POINT_REMOVED), CapturePointGUID(capturePointGUID) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid CapturePointGUID;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 939309c5bfc..5f932030f3f 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1107,7 +1107,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_SPELL_VISUAL_KIT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAN_DUEL_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAN_REDEEM_TOKEN_FOR_BALANCE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAPTURE_POINT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAPTURE_POINT_REMOVED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CATEGORY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAIN_MISSILE_BOUNCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1272,7 +1272,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_BASE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_CUSTOM_ANIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_DESPAWN, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_RESET_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_SET_STATE_LOCAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -2004,7 +2004,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACTION_BUTTONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_BNET_SESSION_KEY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CAPTURE_POINT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CAPTURE_POINT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CELESTIAL_BODY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARACTER_FLAGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARGE_CATEGORY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 91b23ccd141..6acaac3c567 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1605,6 +1605,11 @@ void Spell::EffectOpenLock()
return;
}
}
+ else if (goInfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT)
+ {
+ gameObjTarget->AssaultCapturePoint(player);
+ return;
+ }
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
{
//CanUseBattlegroundObject() already called in CheckCast()