aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy <Golrag@users.noreply.github.com>2023-08-29 08:38:10 +0200
committerGitHub <noreply@github.com>2023-08-29 08:38:10 +0200
commit72b9aace54e44d30c323bd1acda630125e8a574d (patch)
tree2a5f0b9a7b7f72ace97f46de3b3a6168ad19a26f
parent9b516978e7265294f3d3925318caa1cf9e7effd4 (diff)
Core/Battlegrounds: Implemented BfA Warsong Gulch (#29247)
-rw-r--r--sql/updates/world/master/2023_08_29_00_world.sql139
-rw-r--r--src/server/game/Battlegrounds/Battleground.h4
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp951
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.h165
-rw-r--r--src/server/game/Entities/Player/Player.cpp13
7 files changed, 548 insertions, 727 deletions
diff --git a/sql/updates/world/master/2023_08_29_00_world.sql b/sql/updates/world/master/2023_08_29_00_world.sql
new file mode 100644
index 00000000000..0ede78dbb10
--- /dev/null
+++ b/sql/updates/world/master/2023_08_29_00_world.sql
@@ -0,0 +1,139 @@
+SET @CGUID := 7000000;
+SET @OGUID := 7000000;
+
+SET @TRIGGER_ID_ALLIANCE := 30; -- Trigger ID for capture flag area trigger alliance
+SET @TRIGGER_ID_HORDE := 31; -- Trigger ID for capture flag area trigger horde
+SET @TRIGGER_SPAWN_ID := 35;
+
+-- new trigger capture flag
+DELETE FROM `areatrigger_template` WHERE `Id` IN (@TRIGGER_ID_ALLIANCE, @TRIGGER_ID_HORDE) AND `IsServerSide` = 1;
+INSERT INTO `areatrigger_template` (`Id`, `IsServerSide`, `Type`, `Data0`, `Data1`) VALUES
+(@TRIGGER_ID_ALLIANCE, 1, 0, 5.0, 5.0),
+(@TRIGGER_ID_HORDE, 1, 0, 5.0, 5.0);
+
+DELETE FROM `areatrigger` WHERE `SpawnId` BETWEEN @TRIGGER_SPAWN_ID+0 AND @TRIGGER_SPAWN_ID+2 AND `IsServerSide` = 1;
+INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerId`, `IsServerSide`, `MapId`, `PosX`, `PosY`, `PosZ`, `Orientation`, `ShapeData0`, `ShapeData1`, `ScriptName`, `Comment`) VALUES
+(@TRIGGER_SPAWN_ID+0, @TRIGGER_ID_ALLIANCE, 1, 2106, 1540.4461669921875, 1481.217041015625, 353.577301025390625, 3.089183330535888671, 5.0, 5.0, 'areatrigger_action_capture_flag', 'Warsong Gulch - Capture Flag - Alliance'),
+(@TRIGGER_SPAWN_ID+1, @TRIGGER_ID_HORDE, 1, 2106, 917.310791015625, 1434.0035400390625, 346.1337890625, 0.017452461645007133, 5.0, 5.0, 'areatrigger_action_capture_flag', 'Warsong Gulch - Capture Flag - Horde');
+
+-- Areatrigger Scripts for buffs
+DELETE FROM `areatrigger_scripts` WHERE `entry` IN (10500, 10501, 10502, 10503, 10504, 10505);
+INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
+(10500, 'at_battleground_buffs'),
+(10501, 'at_battleground_buffs'),
+(10502, 'at_battleground_buffs'),
+(10503, 'at_battleground_buffs'),
+(10504, 'at_battleground_buffs'),
+(10505, 'at_battleground_buffs');
+
+-- Graveyards
+DELETE FROM `graveyard_zone` WHERE `ID` IN (7052, 7053);
+INSERT INTO `graveyard_zone` (`ID`, `GhostZone`,`Comment`) VALUES
+(7053, 10218, 'Warsong Gulch - Horde Graveyard'),
+(7052, 10218, 'Warsong Gulch - Alliance Graveyard');
+
+-- Graveyard conditions
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 27 AND `SourceEntry` IN (7052, 7053);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `Comment`) VALUES
+(27, 7052, 10218, 0, 6, 469, 0, 'Graveyard - Warsong Gulch - Alliance Graveyard - Team Alliance'),
+(27, 7053, 10218, 0, 6, 67, 0, 'Graveyard - Warsong Gulch - Horde Graveyard - Team Horde');
+
+UPDATE `battleground_template` SET `comment` = 'Warsong Gulch - Classic' WHERE `ID` = 2;
+DELETE FROM `battleground_template` WHERE `ID`=1014;
+INSERT INTO `battleground_template` (`ID`, `AllianceStartLoc`, `HordeStartLoc`, `Weight`, `ScriptName`, `Comment`) VALUES
+(1014, 7051, 7050, 1, '', 'Warsong Gulch');
+
+DELETE FROM `gameobject_template_addon` WHERE `entry` IN (227744 /*Horde Flag*/, 227745 /*Alliance Flag*/, 352710 /*Horde Gate*/, 352709 /*Horde Gate*/, 227741 /*Alliance Flag*/, 227740 /*Horde Flag*/, 309883 /*Doodad_7NE_Blackrook_Portcullis002*/, 309705 /*Doodad_7NE_Blackrook_Portcullis009*/, 309704 /*Alliance Door*/);
+INSERT INTO `gameobject_template_addon` (`entry`, `faction`, `flags`, `WorldEffectID`, `AIAnimKitID`) VALUES
+(227744, 2058, 0, 0, 0), -- Horde Flag
+(227745, 1913, 0, 0, 0), -- Alliance Flag
+(352710, 1375, 32, 0, 0), -- Horde Gate
+(352709, 1375, 32, 0, 0), -- Horde Gate
+(227741, 1995, 32, 0, 0), -- Alliance Flag
+(227740, 1997, 32, 0, 0), -- Horde Flag
+(309883, 1375, 32, 0, 0), -- Doodad_7NE_Blackrook_Portcullis002
+(309705, 1375, 32, 0, 0), -- Doodad_7NE_Blackrook_Portcullis009
+(309704, 1375, 32, 0, 0); -- Alliance Door
+
+DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+27;
+INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `PhaseGroup`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `VerifiedBuild`) VALUES
+(@CGUID+0, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1402.9974365234375, 1345.5699462890625, 329.3948974609375, 2.346344232559204101, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+1, 147662, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1506.2882080078125, 1483.5694580078125, 364.8609619140625, 0.645661056041717529, 7200, 0, 0, 84689, 0, 0, 0, 0, 50000), -- Owl (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@CGUID+2, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1282.609375, 1521.671875, 314.936370849609375, 1.985947966575622558, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+3, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1052.4820556640625, 1375.9078369140625, 328.55780029296875, 3.76127481460571289, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+4, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1174.87109375, 1620.51611328125, 313.747344970703125, 5.750471115112304687, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+5, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1094.83447265625, 1494.9989013671875, 327.934967041015625, 2.633371829986572265, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+6, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 946.44940185546875, 1531.2198486328125, 358.988311767578125, 0.561181128025054931, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+7, 147695, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1471.9176025390625, 1487.6875, 374.7779541015625, 4.924968719482421875, 7200, 10, 0, 21508, 0, 1, 0, 0, 50000), -- Forest Moth (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+8, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1272.109375, 1335.9427490234375, 312.37847900390625, 2.319414615631103515, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+9, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1358.2359619140625, 1573.6336669921875, 319.684722900390625, 1.636260390281677246, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+10, 147662, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1506.59375, 1495.2760009765625, 364.965576171875, 5.427386760711669921, 7200, 0, 0, 84689, 0, 0, 0, 0, 50000), -- Owl (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@CGUID+11, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 939.52435302734375, 1462.2064208984375, 367.303619384765625, 2.263118505477905273, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+12, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1161.0198974609375, 1293.515625, 319.525360107421875, 4.396508216857910156, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+13, 147695, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1386.3555908203125, 1621.4478759765625, 324.60595703125, 1.856943249702453613, 7200, 10, 0, 21508, 0, 1, 0, 0, 50000), -- Forest Moth (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+14, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1294.1875, 1378.4305419921875, 311.818695068359375, 0, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+15, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1016.89788818359375, 1318.869140625, 337.970428466796875, 5.617191314697265625, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+16, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1019.16583251953125, 1397.8968505859375, 341.267486572265625, 4.985507011413574218, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+17, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1463.2850341796875, 1543.6378173828125, 344.3548583984375, 5.42351531982421875, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+18, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 942.4390869140625, 1431.4508056640625, 345.58868408203125, 5.040985107421875, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+19, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1089.4793701171875, 1593.7698974609375, 321.227325439453125, 6.239905357360839843, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+20, 147695, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1522.5980224609375, 1425.98046875, 373.12481689453125, 3.617821216583251953, 7200, 10, 0, 21508, 0, 1, 0, 0, 50000), -- Forest Moth (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+21, 61750, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1367.4722900390625, 1348.548583984375, 327.42950439453125, 0, 7200, 10, 0, 1, 0, 1, 0, 0, 50000), -- Deer (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+22, 147695, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1415.2279052734375, 1568.1527099609375, 330.19384765625, 2.975586175918579101, 7200, 10, 0, 21508, 0, 1, 0, 0, 50000), -- Forest Moth (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+23, 147693, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1133.1231689453125, 1470.9544677734375, 314.525146484375, 3.480478525161743164, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Coral Snake (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+24, 147694, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1106.4130859375, 1659.8427734375, 322.794708251953125, 5.533683300018310546, 7200, 10, 0, 1129, 0, 1, 0, 0, 50000), -- Rabbit (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+25, 147695, 2106, 10218, 12835, '0', '0', 0, 0, 0, 1318.541015625, 1526.775390625, 317.263580322265625, 3.778635025024414062, 7200, 10, 0, 21508, 0, 1, 0, 0, 50000), -- Forest Moth (Area: Warsong Flag Room - Difficulty: 0) CreateObject1 (possible waypoints or random movement)
+(@CGUID+26, 13116, 2106, 10218, 0, '0', '0', 0, 0, 1, 1395.6353759765625, 1560.8367919921875, 329.86895751953125, 6.114908695220947265, 7200, 0, 0, 1129190, 6310, 0, 0, 0, 50000), -- Alliance Spirit Guide (Area: 0 - Difficulty: 0) CreateObject1 (Auras: 9036 - Ghost, 9617 - Ghost Visual)
+(@CGUID+27, 13117, 2106, 10218, 0, '0', '0', 0, 0, 1, 1064.1788330078125, 1371.8975830078125, 328.837646484375, 2.728983640670776367, 7200, 0, 0, 1129190, 6310, 0, 0, 0, 50000); -- Horde Spirit Guide (Area: 0 - Difficulty: 0) CreateObject1 (Auras: 9036 - Ghost, 9617 - Ghost Visual)
+
+DELETE FROM `creature_addon` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+27;
+INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
+(@CGUID+1, 0, 0, 0, 3, 0, 1, 0, 0, 835, 0, 0, 0, ''), -- Owl
+(@CGUID+7, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- Forest Moth
+(@CGUID+10, 0, 0, 0, 3, 0, 1, 0, 0, 835, 0, 0, 0, ''), -- Owl
+(@CGUID+13, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- Forest Moth
+(@CGUID+20, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- Forest Moth
+(@CGUID+22, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- Forest Moth
+(@CGUID+25, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- Forest Moth
+(@CGUID+26, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, '9036 9617'), -- Alliance Spirit Guide - 9036 - Ghost, 9617 - Ghost Visual
+(@CGUID+27, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 5, '9036 9617'); -- Horde Spirit Guide - 9036 - Ghost, 9617 - Ghost Visual
+
+DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+13;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `PhaseGroup`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES
+(@OGUID+0, 179904, 2106, 10218, 12835, '0', '0', 0, 1317.0833740234375, 1551.6614990234375, 315.25006103515625, 5.758442401885986328, 0, 0, -0.25937175750732421, 0.965777516365051269, 90, 255, 1, 50000), -- Food Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+1, 179905, 2106, 10218, 12835, '0', '0', 0, 1319.6875, 1379.923583984375, 316.90704345703125, 1.080207586288452148, 0, 0, 0.514225006103515625, 0.857655286788940429, 90, 255, 1, 50000), -- Berserk Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+2, 179906, 2106, 10218, 12835, '0', '0', 0, 1104.73095703125, 1352.21533203125, 318.598541259765625, 5.946152687072753906, 0, 0, -0.16771984100341796, 0.985834717750549316, 90, 255, 1, 50000), -- Food Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+3, 179907, 2106, 10218, 12835, '0', '0', 0, 1144.795166015625, 1558.779541015625, 308.874053955078125, 3.608199357986450195, 0, 0, -0.97290802001953125, 0.231192529201507568, 90, 255, 1, 50000), -- Berserk Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+4, 179899, 2106, 10218, 12835, '0', '0', 0, 1005.4774169921875, 1448.092041015625, 335.867950439453125, 1.605701684951782226, 0, 0, 0.719339370727539062, 0.694658815860748291, 90, 255, 1, 50000), -- Speed Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+5, 309704, 2106, 10218, 12835, '0', '0', 0, 1503.0211181640625, 1492.2269287109375, 352.20233154296875, 6.257006168365478515, 0, 0, -0.01308917999267578, 0.999914348125457763, 7200, 255, 1, 50000), -- Alliance Door (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+6, 309705, 2106, 10218, 12835, '0', '0', 0, 1492.7191162109375, 1457.802490234375, 344.8914794921875, 6.257006168365478515, 0, 0, -0.01308917999267578, 0.999914348125457763, 7200, 255, 1, 50000), -- Doodad_7NE_Blackrook_Portcullis009 (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+7, 309883, 2106, 10218, 12835, '0', '0', 0, 1468.5399169921875, 1493.1424560546875, 352.219512939453125, 6.257006168365478515, 0, 0, -0.01308917999267578, 0.999914348125457763, 7200, 255, 1, 50000), -- Doodad_7NE_Blackrook_Portcullis002 (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+8, 179871, 2106, 10218, 12835, '0', '0', 0, 1449.65625, 1470.8367919921875, 343.069000244140625, 4.642575740814208984, 0, 0, -0.731353759765625, 0.681998312473297119, 90, 255, 1, 50000), -- Speed Buff (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+9, 227740, 2106, 10218, 12835, '0', '0', 0, 917.310791015625, 1434.0035400390625, 346.1337890625, 0.017452461645007133, 0, 0, 0.008726119995117187, 0.999961912631988525, 7200, 255, 1, 50000), -- Horde Flag (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+10, 227741, 2106, 10218, 12835, '0', '0', 0, 1540.4461669921875, 1481.217041015625, 353.577301025390625, 3.089183330535888671, 0, 0, 0.99965667724609375, 0.026201646775007247, 7200, 255, 1, 50000), -- Alliance Flag (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+11, 242273, 2106, 10218, 12835, '0', '0', 0, 1524.5, 1514.3663330078125, 358.001007080078125, 0, 0, 0, 0, 1, 7200, 255, 1, 50000), -- Collision PC Size (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+12, 352709, 2106, 10218, 12835, '0', '0', 0, 949.561279296875, 1422.976318359375, 345.614593505859375, 0, 0, 0, 0, 1, 7200, 255, 1, 50000), -- Horde Gate (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+(@OGUID+13, 352710, 2106, 10218, 12835, '0', '0', 0, 957.255859375, 1459.40087890625, 340.62237548828125, 0, 0, 0.130525588989257812, 0, 0.991444945335388183, 7200, 255, 1, 50000); -- Horde Gate (Area: Warsong Flag Room - Difficulty: 0) CreateObject1
+
+DELETE FROM `gameobject_addon` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+13;
+INSERT INTO `gameobject_addon` (`guid`, `parent_rotation0`, `parent_rotation1`, `parent_rotation2`, `parent_rotation3`, `WorldEffectID`, `AIAnimKitID`) VALUES
+(@OGUID+5, 0, 0, 0.697790503501892089, 0.716301918029785156, 0, 0), -- Alliance Door
+(@OGUID+6, 0, 0, 0.697790503501892089, 0.716301918029785156, 0, 0), -- Doodad_7NE_Blackrook_Portcullis009
+(@OGUID+7, 0, 0, 0.697790503501892089, 0.716301918029785156, 0, 0), -- Doodad_7NE_Blackrook_Portcullis002
+(@OGUID+12, 0, 0, -0.70710659027099609, 0.707106947898864746, 0, 0), -- Horde Gate
+(@OGUID+13, 0, 0, -0.70710659027099609, 0.707106947898864746, 0, 0); -- Horde Gate
+
+DELETE FROM `creature_template_addon` WHERE `entry` IN (147695 /*147695 (Forest Moth)*/, 147662 /*147662 (Owl)*/);
+INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
+(147695, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, ''), -- 147695 (Forest Moth)
+(147662, 0, 0, 0, 3, 0, 1, 0, 0, 835, 0, 0, 0, ''); -- 147662 (Owl)
+
+-- Quick Cap Server Side Spell
+-- Spell with dummy aura application
+DELETE FROM `serverside_spell` WHERE `id` = 183317;
+INSERT INTO `serverside_spell` (`Id`, `Attributes`, `AttributesEx2`, `AttributesEx6`, `RangeIndex`, `EquippedItemClass`, `SpellName`, `SchoolMask`, `AuraInterruptFlags1`) VALUES
+(183317, 134217984, 4, 1, 13, -1, 'CTF Tracking Aura', 1, 0x00080000 | 0x00020000 | 0x00100000); -- Removed when leaving world/mounting/stealth/invis
+
+DELETE FROM `serverside_spell_effect` WHERE `SpellID` = 183317;
+INSERT INTO `serverside_spell_effect` (`SpellID`, `EffectIndex`, `Effect`, `EffectAura`) VALUES
+(183317, 0, 6, 4);
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 2b8698860d1..2b5b204732f 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -106,7 +106,9 @@ enum BattlegroundSpells
SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct
SPELL_PREPARATION = 44521, // Preparation
SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal
- SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag
+ SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG = 42792, // makes Alliance flag unselectable
+ SPELL_RECENTLY_DROPPED_HORDE_FLAG = 50326, // makes Horde flag unselectable
+ SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG = 50327, // makes Neutral flag unselectable
SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive
SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2)
SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 5b4b958042a..c2c106c43b6 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -330,6 +330,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundQueueTypeId que
bg = new BattlegroundAV(bg_template);
break;
case BATTLEGROUND_WS:
+ case BATTLEGROUND_WG_CTF:
bg = new BattlegroundWS(bg_template);
break;
case BATTLEGROUND_AB:
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index e258b762f68..c842de57e3d 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -640,7 +640,7 @@ void BattlegroundEY::EventPlayerDroppedFlag(Player* player)
player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
- player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
+ player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
player->CastSpell(player, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
//this does not work correctly :((it should remove flag carrier name)
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index aa84185f559..6a64373e8ef 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -16,6 +16,7 @@
*/
#include "BattlegroundWS.h"
+#include "AreaTrigger.h"
#include "BattlegroundMgr.h"
#include "DB2Stores.h"
#include "GameObject.h"
@@ -26,6 +27,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "SpellAuras.h"
#include "SpellInfo.h"
// these variables aren't used outside of this file, so declare them only here
@@ -45,30 +47,25 @@ uint32 BG_WSG_Honor[2][BG_WSG_REWARD_NUM] =
BattlegroundWS::BattlegroundWS(BattlegroundTemplate const* battlegroundTemplate) : Battleground(battlegroundTemplate)
{
- BgObjects.resize(BG_WS_OBJECT_MAX);
- BgCreatures.resize(BG_CREATURES_MAX_WS);
+ BgObjects.resize(0);
+ BgCreatures.resize(0);
StartMessageIds[BG_STARTING_EVENT_SECOND] = BG_WS_TEXT_START_ONE_MINUTE;
StartMessageIds[BG_STARTING_EVENT_THIRD] = BG_WS_TEXT_START_HALF_MINUTE;
StartMessageIds[BG_STARTING_EVENT_FOURTH] = BG_WS_TEXT_BATTLE_HAS_BEGUN;
- _flagSpellForceTimer = 0;
_bothFlagsKept = false;
- _flagDebuffState = 0;
- m_FlagKeepers[TEAM_ALLIANCE].Clear();
- m_FlagKeepers[TEAM_HORDE].Clear();
- m_DroppedFlagGUID[TEAM_ALLIANCE].Clear();
- m_DroppedFlagGUID[TEAM_HORDE].Clear();
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagsTimer[TEAM_ALLIANCE] = 0;
- _flagsTimer[TEAM_HORDE] = 0;
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- _flagsDropTimer[TEAM_HORDE] = 0;
+
_lastFlagCaptureTeam = 0;
m_ReputationCapture = 0;
m_HonorWinKills = 0;
m_HonorEndKills = 0;
+
+ _flags = { };
+ _capturePointAreaTriggers = { };
+
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _assaultStackCount = 0;
}
BattlegroundWS::~BattlegroundWS() { }
@@ -77,17 +74,17 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
{
if (GetStatus() == STATUS_IN_PROGRESS)
{
- if (GetElapsedTime() >= 17*MINUTE*IN_MILLISECONDS)
+ if (GetElapsedTime() >= 17 * MINUTE * IN_MILLISECONDS)
{
if (GetTeamScore(TEAM_ALLIANCE) == 0)
{
- if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
+ if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
EndBattleground(0);
- else // Horde has more points and thus wins
+ else // Horde has more points and thus wins
EndBattleground(HORDE);
}
- else if (GetTeamScore(TEAM_HORDE) == 0)
- EndBattleground(ALLIANCE); // Alliance has > 0, Horde has 0, alliance wins
+ else if (GetTeamScore(TEAM_HORDE) == 0) // Alliance has > 0, Horde has 0, alliance wins
+ EndBattleground(ALLIANCE);
else if (GetTeamScore(TEAM_HORDE) == GetTeamScore(TEAM_ALLIANCE)) // Team score equal, winner is team that scored the last flag
EndBattleground(_lastFlagCaptureTeam);
else if (GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE)) // Last but not least, check who has the higher score
@@ -96,541 +93,155 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
EndBattleground(ALLIANCE);
}
- if (_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
- {
- _flagsTimer[TEAM_ALLIANCE] -= diff;
-
- if (_flagsTimer[TEAM_ALLIANCE] < 0)
- {
- _flagsTimer[TEAM_ALLIANCE] = 0;
- RespawnFlag(ALLIANCE, true);
- }
- }
-
- if (_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
- {
- _flagsDropTimer[TEAM_ALLIANCE] -= diff;
-
- if (_flagsDropTimer[TEAM_ALLIANCE] < 0)
- {
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- RespawnFlagAfterDrop(ALLIANCE);
- _bothFlagsKept = false;
- }
- }
-
- if (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
- {
- _flagsTimer[TEAM_HORDE] -= diff;
-
- if (_flagsTimer[TEAM_HORDE] < 0)
- {
- _flagsTimer[TEAM_HORDE] = 0;
- RespawnFlag(HORDE, true);
- }
- }
-
- if (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
- {
- _flagsDropTimer[TEAM_HORDE] -= diff;
-
- if (_flagsDropTimer[TEAM_HORDE] < 0)
- {
- _flagsDropTimer[TEAM_HORDE] = 0;
- RespawnFlagAfterDrop(HORDE);
- _bothFlagsKept = false;
- }
- }
-
if (_bothFlagsKept)
{
- _flagSpellForceTimer += diff;
- if (_flagDebuffState == 0 && _flagSpellForceTimer >= 10*MINUTE*IN_MILLISECONDS) //10 minutes
+ _flagAssaultTimer.Update(diff);
+ if (_flagAssaultTimer.Passed())
{
- // Apply Stage 1 (Focused Assault)
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- _flagDebuffState = 1;
- }
- else if (_flagDebuffState == 1 && _flagSpellForceTimer >= 15*MINUTE*IN_MILLISECONDS) //15 minutes
- {
- // Apply Stage 2 (Brutal Assault)
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- _flagDebuffState = 2;
- }
- }
- else if ((_flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_BASE || _flagState[TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) &&
- (_flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_ON_BASE || _flagState[TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN))
- {
- // Both flags are in base or awaiting respawn.
- // Remove assault debuffs, reset timers
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _assaultStackCount++;
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[0]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- }
- if (Player* player = ObjectAccessor::FindPlayer(m_FlagKeepers[1]))
- {
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
+ // update assault debuff stacks
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ ApplyAssaultDebuffToPlayer(player);
+ });
}
-
- _flagSpellForceTimer = 0; //reset timer.
- _flagDebuffState = 0;
}
}
}
-void BattlegroundWS::StartingEventCloseDoors()
+void BattlegroundWS::DoForFlagKeepers(std::function<void(Player*)> action) const
{
- for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
+ for (ObjectGuid flagGUID : _flags)
{
- DoorClose(i);
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
+ if (GameObject* flag = GetBgMap()->GetGameObject(flagGUID))
+ {
+ if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
+ action(carrier);
+ }
}
- for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
- SpawnBGObject(i, RESPAWN_ONE_DAY);
-}
-
-void BattlegroundWS::StartingEventOpenDoors()
-{
- for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_6; ++i)
- DoorOpen(i);
- for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
- DoorOpen(i);
-
- for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
- SpawnBGObject(i, RESPAWN_IMMEDIATELY);
-
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
- SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
-
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER, GameTime::GetGameTime() + 15 * MINUTE);
-
- // players joining later are not eligibles
- TriggerGameEvent(WS_EVENT_START_BATTLE);
}
-void BattlegroundWS::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
+void BattlegroundWS::ResetAssaultDebuff()
{
- bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
- Battleground::AddPlayer(player, queueId);
- if (!isInBattleground)
- PlayerScores[player->GetGUID()] = new BattlegroundWGScore(player->GetGUID(), player->GetBGTeam());
-}
-
-void BattlegroundWS::RespawnFlag(uint32 Team, bool captured)
-{
- if (Team == ALLIANCE)
- {
- TC_LOG_DEBUG("bg.battleground", "Respawn Alliance flag");
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- }
- else
- {
- TC_LOG_DEBUG("bg.battleground", "Respawn Horde flag");
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
- }
-
- if (captured)
- {
- //when map_update will be allowed for battlegrounds this code will be useless
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); // flag respawned sound...
- }
_bothFlagsKept = false;
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ DoForFlagKeepers([&](Player* player) -> void
+ {
+ RemoveAssaultDebuffFromPlayer(player);
+ });
}
-void BattlegroundWS::RespawnFlagAfterDrop(uint32 team)
+void BattlegroundWS::ApplyAssaultDebuffToPlayer(Player* player)
{
- if (GetStatus() != STATUS_IN_PROGRESS)
+ if (_assaultStackCount == 0)
return;
- RespawnFlag(team, false);
- if (team == ALLIANCE)
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- else
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
-
- SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
- PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
-
- if (GameObject* obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID(team)))
- obj->Delete();
- else
- TC_LOG_ERROR("bg.battleground", "unknown dropped flag ({})", GetDroppedFlagGUID(team).ToString());
-
- SetDroppedFlagGUID(ObjectGuid::Empty, GetTeamIndexByTeamId(team));
- _bothFlagsKept = false;
- // Check opposing flag if it is in capture zone; if so, capture it
- HandleFlagRoomCapturePoint(team == ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
-}
-
-void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
-{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- uint32 winner = 0;
-
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
- uint32 team = GetPlayerTeam(player->GetGUID());
- if (team == ALLIANCE)
- {
- if (!IsHordeFlagPickedup())
- return;
- SetHordeFlagPicker(ObjectGuid::Empty); // must be before aura remove to prevent 2 events (drop+capture) at the same time
- // horde flag in base (but not respawned yet)
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
- // Drop Horde Flag from Player
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
-
- if (GetTeamScore(TEAM_ALLIANCE) < BG_WS_MAX_TEAM_SCORE)
- AddPoint(ALLIANCE, 1);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
- RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
- }
- else
+ uint32 spellId = WS_SPELL_FOCUSED_ASSAULT;
+ if (_assaultStackCount >= FLAG_BRUTAL_ASSAULT_STACK_COUNT)
{
- if (!IsAllianceFlagPickedup())
- return;
- SetAllianceFlagPicker(ObjectGuid::Empty); // must be before aura remove to prevent 2 events (drop+capture) at the same time
- // alliance flag in base (but not respawned yet)
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_WAIT_RESPAWN;
- // Drop Alliance Flag from Player
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
-
- if (GetTeamScore(TEAM_HORDE) < BG_WS_MAX_TEAM_SCORE)
- AddPoint(HORDE, 1);
- PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
- RewardReputationToTeam(889, m_ReputationCapture, HORDE);
+ player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
+ spellId = WS_SPELL_BRUTAL_ASSAULT;
}
- //for flag capture is reward 2 honorable kills
- RewardHonorToTeam(GetBonusHonorFromKill(2), team);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
-
- if (team == ALLIANCE)
- SendBroadcastText(BG_WS_TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- else
- SendBroadcastText(BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
-
- UpdateFlagState(team, BG_WS_FLAG_STATE_WAIT_RESPAWN); // flag state none
- UpdateTeamScore(GetTeamIndexByTeamId(team));
- // only flag capture should be updated
- UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
-
- // update last flag capture to be used if teamscore is equal
- SetLastFlagCapture(team);
-
- if (GetTeamScore(TEAM_ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
- winner = ALLIANCE;
-
- if (GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE)
- winner = HORDE;
-
- if (winner)
+ Aura* aura = player->GetAura(spellId);
+ if (!aura)
{
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
- UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
-
- RewardHonorToTeam(BG_WSG_Honor[BattlegroundMgr::IsBGWeekend(BATTLEGROUND_WS) ? 1 : 0][BG_WSG_WIN], winner);
- EndBattleground(winner);
- }
- else
- {
- _flagsTimer[GetTeamIndexByTeamId(team) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME;
+ player->CastSpell(player, spellId, true);
+ aura = player->GetAura(spellId);
}
+
+ if (aura)
+ aura->SetStackAmount(_assaultStackCount);
}
-void BattlegroundWS::HandleFlagRoomCapturePoint(int32 team)
+
+void BattlegroundWS::RemoveAssaultDebuffFromPlayer(Player* player)
{
- Player* flagCarrier = ObjectAccessor::GetPlayer(GetBgMap(), GetFlagPickerGUID(team));
- uint32 areaTrigger = team == TEAM_ALLIANCE ? 3647 : 3646;
- if (flagCarrier && flagCarrier->IsInAreaTriggerRadius(sAreaTriggerStore.LookupEntry(areaTrigger)))
- EventPlayerCapturedFlag(flagCarrier);
+ player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
+ player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
}
-void BattlegroundWS::EventPlayerDroppedFlag(Player* player)
+void BattlegroundWS::StartingEventOpenDoors()
{
- uint32 team = GetPlayerTeam(player->GetGUID());
- if (GetStatus() != STATUS_IN_PROGRESS)
+ for (ObjectGuid door : _doors)
{
- // if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
- // just take off the aura
- if (team == ALLIANCE)
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(door))
{
- if (!IsHordeFlagPickedup())
- return;
-
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- {
- SetHordeFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- }
+ gameObject->UseDoorOrButton();
+ gameObject->DespawnOrUnsummon(3s);
}
- else
- {
- if (!IsAllianceFlagPickedup())
- return;
-
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- {
- SetAllianceFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- }
- }
- return;
}
- bool set = false;
-
- if (team == ALLIANCE)
- {
- if (!IsHordeFlagPickedup())
- return;
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- {
- SetHordeFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_GROUND;
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
- set = true;
- }
- }
- else
- {
- if (!IsAllianceFlagPickedup())
- return;
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- {
- SetAllianceFlagPicker(ObjectGuid::Empty);
- player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
- if (_flagDebuffState == 1)
- player->RemoveAurasDueToSpell(WS_SPELL_FOCUSED_ASSAULT);
- else if (_flagDebuffState == 2)
- player->RemoveAurasDueToSpell(WS_SPELL_BRUTAL_ASSAULT);
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_GROUND;
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
- set = true;
- }
- }
-
- if (set)
- {
- player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
- UpdateFlagState(team, BG_WS_FLAG_STATE_ON_GROUND);
-
- if (team == ALLIANCE)
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
- else
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
+ UpdateWorldState(BG_WS_STATE_TIMER, GameTime::GetGameTime() + 15 * MINUTE);
- _flagsDropTimer[GetTeamIndexByTeamId(team) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
- }
+ // players joining later are not eligibles
+ TriggerGameEvent(WS_EVENT_START_BATTLE);
}
-void BattlegroundWS::EventPlayerClickedOnFlag(Player* player, GameObject* target_obj)
+void BattlegroundWS::AddPlayer(Player* player, BattlegroundQueueTypeId queueId)
{
- if (GetStatus() != STATUS_IN_PROGRESS)
- return;
-
- uint32 team = GetPlayerTeam(player->GetGUID());
-
- //alliance flag picked up from base
- if (team == HORDE && GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
- && BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
- SetAllianceFlagPicker(player->GetGUID());
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
- //update world state to show correct flag carrier
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
- player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_SILVERWING_FLAG_PICKED);
- if (_flagState[1] == BG_WS_FLAG_STATE_ON_PLAYER)
- _bothFlagsKept = true;
-
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
+ bool const isInBattleground = IsPlayerInBattleground(player->GetGUID());
+ Battleground::AddPlayer(player, queueId);
+ if (!isInBattleground)
+ PlayerScores[player->GetGUID()] = new BattlegroundWGScore(player->GetGUID(), player->GetBGTeam());
+}
- //horde flag picked up from base
- if (team == ALLIANCE && GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
- && BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
- SetHordeFlagPicker(player->GetGUID());
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
- //update world state to show correct flag carrier
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
- player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_WARSONG_FLAG_PICKED);
- if (_flagState[0] == BG_WS_FLAG_STATE_ON_PLAYER)
- _bothFlagsKept = true;
-
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
+FlagState BattlegroundWS::GetFlagState(TeamId team) const
+{
+ if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
+ return gameObject->GetFlagState();
- //Alliance flag on ground(not in base) (returned or picked up again from ground!)
- if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(target_obj, 10)
- && target_obj->GetGOInfo()->entry == BG_OBJECT_A_FLAG_GROUND_WS_ENTRY)
- {
- if (team == ALLIANCE)
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
- RespawnFlag(ALLIANCE, false);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
- _bothFlagsKept = false;
- HandleFlagRoomCapturePoint(TEAM_HORDE); // Check Horde flag if it is in capture zone; if so, capture it
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
- PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
- SetAllianceFlagPicker(player->GetGUID());
- player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_PLAYER;
- UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- //called in HandleGameObjectUseOpcode:
- //target_obj->Delete();
- }
+ return FlagState(0);
+}
- //Horde flag on ground(not in base) (returned or picked up again)
- if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(target_obj, 10)
- && target_obj->GetGOInfo()->entry == BG_OBJECT_H_FLAG_GROUND_WS_ENTRY)
- {
- if (team == HORDE)
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_WAIT_RESPAWN);
- RespawnFlag(HORDE, false);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
- PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
- UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
- _bothFlagsKept = false;
- HandleFlagRoomCapturePoint(TEAM_ALLIANCE); // Check Alliance flag if it is in capture zone; if so, capture it
- }
- else
- {
- SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
- PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
- SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
- SetHordeFlagPicker(player->GetGUID());
- player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_PLAYER;
- UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
- if (_flagDebuffState == 1)
- player->CastSpell(player, WS_SPELL_FOCUSED_ASSAULT, true);
- else if (_flagDebuffState == 2)
- player->CastSpell(player, WS_SPELL_BRUTAL_ASSAULT, true);
- }
- //called in HandleGameObjectUseOpcode:
- //target_obj->Delete();
- }
+ObjectGuid const& BattlegroundWS::GetFlagCarrierGUID(TeamId team) const
+{
+ if (GameObject* gameObject = FindBgMap()->GetGameObject(_flags[team]))
+ return gameObject->GetFlagCarrierGUID();
- player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+ return ObjectGuid::Empty;
}
-void BattlegroundWS::RemovePlayer(Player* player, ObjectGuid guid, uint32 /*team*/)
+void BattlegroundWS::HandleFlagRoomCapturePoint()
{
- // sometimes flag aura not removed :(
- if (IsAllianceFlagPickedup() && m_FlagKeepers[TEAM_ALLIANCE] == guid)
- {
- if (!player)
- {
- TC_LOG_ERROR("bg.battleground", "BattlegroundWS: Removing offline player who has the FLAG!!");
- SetAllianceFlagPicker(ObjectGuid::Empty);
- RespawnFlag(ALLIANCE, false);
- }
- else
- EventPlayerDroppedFlag(player);
- }
- if (IsHordeFlagPickedup() && m_FlagKeepers[TEAM_HORDE] == guid)
+ DoForFlagKeepers([&](Player* player) -> void
{
- if (!player)
- {
- TC_LOG_ERROR("bg.battleground", "BattlegroundWS: Removing offline player who has the FLAG!!");
- SetHordeFlagPicker(ObjectGuid::Empty);
- RespawnFlag(HORDE, false);
- }
- else
- EventPlayerDroppedFlag(player);
- }
+ TeamId team = GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()));
+ if (AreaTrigger* trigger = GetBgMap()->GetAreaTrigger(_capturePointAreaTriggers[team]))
+ if (trigger->GetInsideUnits().contains(player->GetGUID()))
+ if (CanCaptureFlag(trigger, player))
+ OnCaptureFlag(trigger, player);
+ });
}
-void BattlegroundWS::UpdateFlagState(uint32 team, uint32 value)
+void BattlegroundWS::UpdateFlagState(uint32 team, FlagState value)
{
- auto transformValueToOtherTeamControlWorldState = [](uint32 value)
+ auto transformValueToOtherTeamControlWorldState = [](FlagState value)
{
switch (value)
{
- case BG_WS_FLAG_STATE_ON_BASE:
- case BG_WS_FLAG_STATE_ON_GROUND:
- case BG_WS_FLAG_STATE_WAIT_RESPAWN:
+ case FlagState::InBase:
+ case FlagState::Dropped:
+ case FlagState::Respawning:
return 1;
- case BG_WS_FLAG_STATE_ON_PLAYER:
+ case FlagState::Taken:
return 2;
default:
return 0;
}
};
- if (team == HORDE)
+
+ if (team == ALLIANCE)
{
- UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, value);
+ UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, AsUnderlyingType(value));
UpdateWorldState(BG_WS_FLAG_CONTROL_HORDE, transformValueToOtherTeamControlWorldState(value));
}
else
{
- UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
+ UpdateWorldState(BG_WS_FLAG_STATE_HORDE, AsUnderlyingType(value));
UpdateWorldState(BG_WS_FLAG_CONTROL_ALLIANCE, transformValueToOtherTeamControlWorldState(value));
}
}
@@ -643,105 +254,8 @@ void BattlegroundWS::UpdateTeamScore(uint32 team)
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
}
-void BattlegroundWS::HandleAreaTrigger(Player* player, uint32 trigger, bool entered)
-{
- //uint32 SpellId = 0;
- //uint64 buff_guid = 0;
- switch (trigger)
- {
- case 8965: // Horde Start
- case 8966: // Alliance Start
- if (GetStatus() == STATUS_WAIT_JOIN && !entered)
- TeleportPlayerToExploitLocation(player);
- break;
- case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in Battleground::Update().
- //buff_guid = BgObjects[BG_WS_OBJECT_SPEEDBUFF_1];
- break;
- case 3687: // Horde elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in Battleground::Update().
- //buff_guid = BgObjects[BG_WS_OBJECT_SPEEDBUFF_2];
- break;
- case 3706: // Alliance elixir of regeneration spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_REGENBUFF_1];
- break;
- case 3708: // Horde elixir of regeneration spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_REGENBUFF_2];
- break;
- case 3707: // Alliance elixir of berserk spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_BERSERKBUFF_1];
- break;
- case 3709: // Horde elixir of berserk spawn
- //buff_guid = BgObjects[BG_WS_OBJECT_BERSERKBUFF_2];
- break;
- case 3646: // Alliance Flag spawn
- if (_flagState[TEAM_HORDE] && !_flagState[TEAM_ALLIANCE])
- if (GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
- EventPlayerCapturedFlag(player);
- break;
- case 3647: // Horde Flag spawn
- if (_flagState[TEAM_ALLIANCE] && !_flagState[TEAM_HORDE])
- if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
- EventPlayerCapturedFlag(player);
- break;
- case 3649: // unk1
- case 3688: // unk2
- case 4628: // unk3
- case 4629: // unk4
- break;
- default:
- Battleground::HandleAreaTrigger(player, trigger, entered);
- break;
- }
-
- //if (buff_guid)
- // HandleTriggerBuff(buff_guid, player);
-}
-
bool BattlegroundWS::SetupBattleground()
{
- // flags
- if (!AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, BG_WS_FLAG_RESPAWN_TIME/1000)
- || !AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, BG_WS_FLAG_RESPAWN_TIME/1000)
- // buffs
- || !AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME)
- || !AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME)
- // alliance gates
- || !AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY)
- // horde gates
- || !AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY)
- || !AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY)
-)
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn some object Battleground not created!");
- return false;
- }
-
- WorldSafeLocsEntry const* sg = sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_ALLIANCE);
- if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.124139f, TEAM_ALLIANCE))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn Alliance spirit guide! Battleground not created!");
- return false;
- }
-
- sg = sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_HORDE);
- if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.193953f, TEAM_HORDE))
- {
- TC_LOG_ERROR("sql.sql", "BatteGroundWS: Failed to spawn Horde spirit guide! Battleground not created!");
- return false;
- }
-
- TC_LOG_DEBUG("bg.battleground", "BatteGroundWS: BG objects and spirit guides spawned");
-
return true;
}
@@ -750,12 +264,6 @@ void BattlegroundWS::Reset()
//call parent's class reset
Battleground::Reset();
- m_FlagKeepers[TEAM_ALLIANCE].Clear();
- m_FlagKeepers[TEAM_HORDE].Clear();
- m_DroppedFlagGUID[TEAM_ALLIANCE].Clear();
- m_DroppedFlagGUID[TEAM_HORDE].Clear();
- _flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
- _flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
m_TeamScores[TEAM_ALLIANCE] = 0;
m_TeamScores[TEAM_HORDE] = 0;
@@ -773,12 +281,12 @@ void BattlegroundWS::Reset()
}
_lastFlagCaptureTeam = 0;
_bothFlagsKept = false;
- _flagDebuffState = 0;
- _flagSpellForceTimer = 0;
- _flagsDropTimer[TEAM_ALLIANCE] = 0;
- _flagsDropTimer[TEAM_HORDE] = 0;
- _flagsTimer[TEAM_ALLIANCE] = 0;
- _flagsTimer[TEAM_HORDE] = 0;
+
+ _doors.clear();
+ _flags = { };
+ _assaultStackCount = 0;
+ _flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
+ _capturePointAreaTriggers = { };
}
void BattlegroundWS::EndBattleground(uint32 winner)
@@ -788,6 +296,7 @@ void BattlegroundWS::EndBattleground(uint32 winner)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), ALLIANCE);
if (winner == HORDE)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorWinKills), HORDE);
+
// Complete map_end rewards (even if no team wins)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
@@ -826,25 +335,7 @@ bool BattlegroundWS::UpdatePlayerScore(Player* player, uint32 type, uint32 value
WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveyard(Player* player)
{
- //if status in progress, it returns main graveyards with spiritguides
- //else it will return the graveyard in the flagroom - this is especially good
- //if a player dies in preparation phase - then the player can't cheat
- //and teleport to the graveyard outside the flagroom
- //and start running around, while the doors are still closed
- if (GetPlayerTeam(player->GetGUID()) == ALLIANCE)
- {
- if (GetStatus() == STATUS_IN_PROGRESS)
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_ALLIANCE);
- else
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_FLAGROOM_ALLIANCE);
- }
- else
- {
- if (GetStatus() == STATUS_IN_PROGRESS)
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_MAIN_HORDE);
- else
- return sObjectMgr->GetWorldSafeLoc(WS_GRAVEYARD_FLAGROOM_HORDE);
- }
+ return sObjectMgr->GetClosestGraveyard(*player, player->GetBGTeam(), player);
}
WorldSafeLocsEntry const* BattlegroundWS::GetExploitTeleportLocation(Team team)
@@ -861,3 +352,229 @@ uint32 BattlegroundWS::GetPrematureWinner()
return Battleground::GetPrematureWinner();
}
+
+void BattlegroundWS::OnGameObjectCreate(GameObject* gameObject)
+{
+ switch (gameObject->GetEntry())
+ {
+ case BG_WS_OBJECT_ALLIANCE_DOOR:
+ case BG_WS_OBJECT_PORTCULLIS_009:
+ case BG_WS_OBJECT_PORTCULLIS_002:
+ case BG_WS_OBJECT_COLLISION_PC_SIZE:
+ case BG_WS_OBJECT_HORDE_GATE_1:
+ case BG_WS_OBJECT_HORDE_GATE_2:
+ _doors.insert(gameObject->GetGUID());
+ break;
+ case BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE:
+ _flags[TEAM_ALLIANCE] = gameObject->GetGUID();
+ break;
+ case BG_WS_OBJECT_HORDE_FLAG_IN_BASE:
+ _flags[TEAM_HORDE] = gameObject->GetGUID();
+ break;
+ default:
+ break;
+ }
+}
+
+void BattlegroundWS::OnAreaTriggerCreate(AreaTrigger* areaTrigger)
+{
+ if (!areaTrigger->IsServerSide())
+ return;
+
+ switch (areaTrigger->GetEntry())
+ {
+ case AT_CAPTURE_POINT_ALLIANCE:
+ _capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
+ break;
+ case AT_CAPTURE_POINT_HORDE:
+ _capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
+ break;
+ default:
+ break;
+ }
+}
+
+void BattlegroundWS::OnFlagStateChange(GameObject* flagInBase, FlagState /*oldValue*/, FlagState newValue, Player* player)
+{
+ uint32 team = flagInBase->GetEntry() == BG_WS_OBJECT_HORDE_FLAG_IN_BASE ? HORDE : ALLIANCE;
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ UpdateFlagState(team, newValue);
+
+ switch (newValue)
+ {
+ case FlagState::InBase:
+ {
+ if (GetStatus() == STATUS_IN_PROGRESS)
+ {
+ ResetAssaultDebuff();
+ if (player)
+ {
+ // flag got returned to base by player interaction
+ UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1); // +1 flag returns
+
+ if (team == ALLIANCE)
+ {
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
+ }
+ }
+ // Flag respawned due to timeout/capture
+ else if (GetFlagState(otherTeamId) != FlagState::Respawning)
+ {
+ // if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
+ SendBroadcastText(BG_WS_TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
+ PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
+ }
+
+ HandleFlagRoomCapturePoint();
+ }
+ break;
+ }
+ case FlagState::Dropped:
+ {
+ player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
+ RemoveAssaultDebuffFromPlayer(player);
+
+ uint32 recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_HORDE_FLAG;
+ if (team == ALLIANCE)
+ {
+ recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG;
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ }
+ else
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
+
+ player->CastSpell(player, recentlyDroppedSpellId, true);
+ break;
+ }
+ case FlagState::Taken:
+ {
+ if (team == HORDE)
+ {
+ SendBroadcastText(BG_WS_TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
+ }
+
+ if (GetFlagState(otherTeamId) == FlagState::Taken)
+ _bothFlagsKept = true;
+
+ ApplyAssaultDebuffToPlayer(player);
+
+ flagInBase->CastSpell(player, BG_WS_SPELL_QUICK_CAP_TIMER, true);
+ player->StartCriteriaTimer(CriteriaStartEvent::BeSpellTarget, BG_WS_SPELL_QUICK_CAP_TIMER, uint32(GameTime::GetGameTime() - flagInBase->GetFlagTakenFromBaseTime()));
+ break;
+ }
+ case FlagState::Respawning:
+ ResetAssaultDebuff();
+ break;
+ default:
+ break;
+ }
+}
+
+bool BattlegroundWS::CanCaptureFlag(AreaTrigger* areaTrigger, Player* player)
+{
+ if (GetStatus() != STATUS_IN_PROGRESS)
+ return false;
+
+ uint32 team = GetPlayerTeam(player->GetGUID());
+ TeamId teamId = GetTeamIndexByTeamId(team);
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
+ return false;
+
+ // check if enemy flag's carrier is this player
+ if (GetFlagCarrierGUID(otherTeamId) != player->GetGUID())
+ return false;
+
+ // check that team's flag is in base
+ return GetFlagState(teamId) == FlagState::InBase;
+}
+
+void BattlegroundWS::OnCaptureFlag(AreaTrigger* /*areaTrigger*/, Player* player)
+{
+ uint32 winner = 0;
+
+ uint32 team = GetPlayerTeam(player->GetGUID());
+ TeamId teamId = GetTeamIndexByTeamId(team);
+ TeamId otherTeamId = GetTeamIndexByTeamId(GetOtherTeam(team));
+
+ /*
+ 1. Update flag states & score world states
+ 2. udpate points
+ 3. chat message & sound
+ 4. update criterias & achievements
+ 5. remove all related auras
+ ?. Reward honor & reputation
+ */
+
+ // 1. update the flag states
+ for (uint8 i = 0; i < _flags.size(); i++)
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[i]))
+ gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
+
+ // 2. update points
+ if (GetTeamScore(teamId) < BG_WS_MAX_TEAM_SCORE)
+ AddPoint(team, 1);
+
+ UpdateTeamScore(teamId);
+
+ // 3. chat message & sound
+ if (team == ALLIANCE)
+ {
+ SendBroadcastText(BG_WS_TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
+ RewardReputationToTeam(890, m_ReputationCapture, ALLIANCE);
+ player->CastSpell(player, SPELL_CAPTURED_ALLIANCE_COSMETIC_FX);
+ }
+ else
+ {
+ SendBroadcastText(BG_WS_TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
+ PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
+ RewardReputationToTeam(889, m_ReputationCapture, HORDE);
+ player->CastSpell(player, SPELL_CAPTURED_HORDE_COSMETIC_FX);
+ }
+
+ // 4. update criteria's for achievement, player score etc.
+ UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
+
+ // 5. Remove all related auras
+ RemoveAssaultDebuffFromPlayer(player);
+
+ if (GameObject* gameObject = GetBgMap()->GetGameObject(_flags[otherTeamId]))
+ player->RemoveAurasDueToSpell(gameObject->GetGOInfo()->newflag.pickupSpell, gameObject->GetGUID());
+
+ player->RemoveAurasDueToSpell(BG_WS_SPELL_QUICK_CAP_TIMER);
+
+ player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
+
+ RewardHonorToTeam(GetBonusHonorFromKill(2), team);
+
+ // update last flag capture to be used if teamscore is equal
+ SetLastFlagCapture(team);
+
+ if (GetTeamScore(teamId) == BG_WS_MAX_TEAM_SCORE)
+ winner = team;
+
+ if (winner)
+ {
+ UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
+ UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
+ UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
+
+ RewardHonorToTeam(BG_WSG_Honor[BattlegroundMgr::IsBGWeekend(GetTypeID()) ? 1 : 0][BG_WSG_WIN], winner);
+ EndBattleground(winner);
+ }
+}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
index 8a4269ef583..2163ede682a 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
@@ -20,6 +20,7 @@
#include "Battleground.h"
#include "BattlegroundScore.h"
+#include "Timer.h"
enum BG_WS_TimerOrScore
{
@@ -62,12 +63,13 @@ enum BG_WS_SpellId
{
BG_WS_SPELL_WARSONG_FLAG = 23333,
BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334,
- BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266, // fake spell, does not exist but used as timer start event
+ //BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266,
BG_WS_SPELL_SILVERWING_FLAG = 23335,
BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336,
- BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265, // fake spell, does not exist but used as timer start event
+ //BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265,
BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
- BG_WS_SPELL_BRUTAL_ASSAULT = 46393
+ BG_WS_SPELL_BRUTAL_ASSAULT = 46393,
+ BG_WS_SPELL_QUICK_CAP_TIMER = 183317, // serverside
};
enum BG_WS_WorldStates
@@ -91,90 +93,52 @@ enum BG_WS_WorldStates
// alliance criteria: BG_WS_FLAG_STATE_HORDE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
// horde criteria: BG_WS_FLAG_STATE_ALLIANCE == 1 && BG_WS_FLAG_STATE_NEUTRAL == 0 && WS(1664) > 0
-enum BG_WS_ObjectTypes
+enum BG_WS_ExploitTeleportLocations
{
- BG_WS_OBJECT_DOOR_A_1 = 0,
- BG_WS_OBJECT_DOOR_A_2 = 1,
- BG_WS_OBJECT_DOOR_A_3 = 2,
- BG_WS_OBJECT_DOOR_A_4 = 3,
- BG_WS_OBJECT_DOOR_A_5 = 4,
- BG_WS_OBJECT_DOOR_A_6 = 5,
- BG_WS_OBJECT_DOOR_H_1 = 6,
- BG_WS_OBJECT_DOOR_H_2 = 7,
- BG_WS_OBJECT_DOOR_H_3 = 8,
- BG_WS_OBJECT_DOOR_H_4 = 9,
- BG_WS_OBJECT_A_FLAG = 10,
- BG_WS_OBJECT_H_FLAG = 11,
- BG_WS_OBJECT_SPEEDBUFF_1 = 12,
- BG_WS_OBJECT_SPEEDBUFF_2 = 13,
- BG_WS_OBJECT_REGENBUFF_1 = 14,
- BG_WS_OBJECT_REGENBUFF_2 = 15,
- BG_WS_OBJECT_BERSERKBUFF_1 = 16,
- BG_WS_OBJECT_BERSERKBUFF_2 = 17,
- BG_WS_OBJECT_MAX = 18
+ WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 7051,
+ WS_EXPLOIT_TELEPORT_LOCATION_HORDE = 7050
};
enum BG_WS_ObjectEntry
{
- BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918,
- BG_OBJECT_DOOR_A_2_WS_ENTRY = 179919,
- BG_OBJECT_DOOR_A_3_WS_ENTRY = 179920,
- BG_OBJECT_DOOR_A_4_WS_ENTRY = 179921,
- BG_OBJECT_DOOR_A_5_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_A_6_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_H_1_WS_ENTRY = 179916,
- BG_OBJECT_DOOR_H_2_WS_ENTRY = 179917,
- BG_OBJECT_DOOR_H_3_WS_ENTRY = 180322,
- BG_OBJECT_DOOR_H_4_WS_ENTRY = 180322,
- BG_OBJECT_A_FLAG_WS_ENTRY = 179830,
- BG_OBJECT_H_FLAG_WS_ENTRY = 179831,
- BG_OBJECT_A_FLAG_GROUND_WS_ENTRY = 179785,
- BG_OBJECT_H_FLAG_GROUND_WS_ENTRY = 179786
+ // doors
+ BG_WS_OBJECT_ALLIANCE_DOOR = 309704,
+ BG_WS_OBJECT_PORTCULLIS_009 = 309705, // Doodad_7NE_Blackrook_Portcullis009
+ BG_WS_OBJECT_PORTCULLIS_002 = 309883, // Doodad_7NE_Blackrook_Portcullis002
+ BG_WS_OBJECT_COLLISION_PC_SIZE = 242273,
+ BG_WS_OBJECT_HORDE_GATE_1 = 352709,
+ BG_WS_OBJECT_HORDE_GATE_2 = 352710,
+
+ // flags
+ BG_WS_OBJECT_ALLIANCE_FLAG_IN_BASE = 227741,
+ BG_WS_OBJECT_HORDE_FLAG_IN_BASE = 227740
};
-enum BG_WS_FlagState
+enum BG_WS_CarrierDebuffs
{
- BG_WS_FLAG_STATE_ON_BASE = 1,
- BG_WS_FLAG_STATE_ON_PLAYER = 2,
- BG_WS_FLAG_STATE_ON_GROUND = 3,
- BG_WS_FLAG_STATE_WAIT_RESPAWN = 4,
-};
+ WS_SPELL_FOCUSED_ASSAULT = 46392,
+ WS_SPELL_BRUTAL_ASSAULT = 46393,
-enum BG_WS_Graveyards
-{
- WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
- WS_GRAVEYARD_FLAGROOM_HORDE = 770,
- WS_GRAVEYARD_MAIN_ALLIANCE = 771,
- WS_GRAVEYARD_MAIN_HORDE = 772
+ SPELL_CAPTURED_ALLIANCE_COSMETIC_FX = 262508,
+ SPELL_CAPTURED_HORDE_COSMETIC_FX = 262512,
};
-enum BG_WS_ExploitTeleportLocations
+enum BG_WS_Objectives
{
- WS_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3784,
- WS_EXPLOIT_TELEPORT_LOCATION_HORDE = 3785
+ WS_OBJECTIVE_CAPTURE_FLAG = 928,
+ WS_OBJECTIVE_RETURN_FLAG = 929
};
-enum BG_WS_CreatureTypes
+enum BG_WS_AreaTriggers
{
- WS_SPIRIT_MAIN_ALLIANCE = 0,
- WS_SPIRIT_MAIN_HORDE = 1,
-
- BG_CREATURES_MAX_WS = 2
+ AT_CAPTURE_POINT_ALLIANCE = 30,
+ AT_CAPTURE_POINT_HORDE = 31
};
-enum BG_WS_CarrierDebuffs
-{
- WS_SPELL_FOCUSED_ASSAULT = 46392,
- WS_SPELL_BRUTAL_ASSAULT = 46393
-};
+static constexpr uint32 WS_EVENT_START_BATTLE = 35912;
-enum BG_WS_Objectives
-{
- WS_OBJECTIVE_CAPTURE_FLAG = 42,
- WS_OBJECTIVE_RETURN_FLAG = 44
-};
-
-#define WS_EVENT_START_BATTLE 8563
+static constexpr Seconds FLAG_ASSAULT_TIMER = 30s;
+static constexpr uint16 FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
struct BattlegroundWGScore final : public BattlegroundScore
{
@@ -223,32 +187,13 @@ class BattlegroundWS : public Battleground
/* inherited from BattlegroundClass */
void AddPlayer(Player* player, BattlegroundQueueTypeId queueId) override;
- void StartingEventCloseDoors() override;
void StartingEventOpenDoors() override;
/* BG Flags */
- ObjectGuid GetFlagPickerGUID(int32 team) const override
- {
- if (team == TEAM_ALLIANCE || team == TEAM_HORDE)
- return m_FlagKeepers[team];
- return ObjectGuid::Empty;
- }
- void SetAllianceFlagPicker(ObjectGuid guid) { m_FlagKeepers[TEAM_ALLIANCE] = guid; }
- void SetHordeFlagPicker(ObjectGuid guid) { m_FlagKeepers[TEAM_HORDE] = guid; }
- bool IsAllianceFlagPickedup() const { return !m_FlagKeepers[TEAM_ALLIANCE].IsEmpty(); }
- bool IsHordeFlagPickedup() const { return !m_FlagKeepers[TEAM_HORDE].IsEmpty(); }
- void RespawnFlag(uint32 Team, bool captured);
- void RespawnFlagAfterDrop(uint32 Team);
- uint8 GetFlagState(uint32 team) { return _flagState[GetTeamIndexByTeamId(team)]; }
-
- /* Battleground Events */
- void EventPlayerDroppedFlag(Player* player) override;
- void EventPlayerClickedOnFlag(Player* player, GameObject* target_obj) override;
- void EventPlayerCapturedFlag(Player* player);
- void HandleFlagRoomCapturePoint(int32 team);
-
- void RemovePlayer(Player* player, ObjectGuid guid, uint32 team) override;
- void HandleAreaTrigger(Player* player, uint32 trigger, bool entered) override;
+ FlagState GetFlagState(TeamId team) const;
+ ObjectGuid const& GetFlagCarrierGUID(TeamId team) const;
+ void HandleFlagRoomCapturePoint();
+
void HandleKillPlayer(Player* player, Player* killer) override;
bool SetupBattleground() override;
void Reset() override;
@@ -256,17 +201,10 @@ class BattlegroundWS : public Battleground
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override;
WorldSafeLocsEntry const* GetExploitTeleportLocation(Team team) override;
- void UpdateFlagState(uint32 team, uint32 value);
+ void UpdateFlagState(uint32 team, FlagState value);
void SetLastFlagCapture(uint32 team) { _lastFlagCaptureTeam = team; }
void UpdateTeamScore(uint32 team);
bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override;
- void SetDroppedFlagGUID(ObjectGuid guid, int32 team = -1) override
- {
- if (team == TEAM_ALLIANCE || team == TEAM_HORDE)
- m_DroppedFlagGUID[team] = guid;
- }
-
- ObjectGuid GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)]; }
/* Scorekeeping */
void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
@@ -275,22 +213,35 @@ class BattlegroundWS : public Battleground
uint32 GetPrematureWinner() override;
+ void OnGameObjectCreate(GameObject* gameObject) override;
+ void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override;
+ void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override;
+
+ bool CanCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
+ void OnCaptureFlag(AreaTrigger* areatrigger, Player* player) override;
+
protected:
void PostUpdateImpl(uint32 diff) override;
+ void DoForFlagKeepers(std::function<void(Player*)> action) const;
+
+ // Focused & Brutal Assault debuffs
+ void ResetAssaultDebuff();
+ void ApplyAssaultDebuffToPlayer(Player* player);
+ void RemoveAssaultDebuffFromPlayer(Player* player);
private:
- ObjectGuid m_FlagKeepers[2]; // 0 - alliance, 1 - horde
- ObjectGuid m_DroppedFlagGUID[2];
- uint8 _flagState[2]; // for checking flag state
- int32 _flagsTimer[2];
- int32 _flagsDropTimer[2];
uint32 _lastFlagCaptureTeam; // Winner is based on this if score is equal
uint32 m_ReputationCapture;
uint32 m_HonorWinKills;
uint32 m_HonorEndKills;
- int32 _flagSpellForceTimer;
bool _bothFlagsKept;
- uint8 _flagDebuffState; // 0 - no debuffs, 1 - focused assault, 2 - brutal assault
+
+ GuidSet _doors;
+ std::array<ObjectGuid, 2> _flags;
+
+ TimeTracker _flagAssaultTimer;
+ uint16 _assaultStackCount;
+ std::array<ObjectGuid, 2> _capturePointAreaTriggers;
};
#endif
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4a6b11f002a..5126853d96d 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25759,10 +25759,21 @@ bool Player::CanUseBattlegroundObject(GameObject* gameobject) const
return false;
}
+ bool hasRecentlyDroppedFlagDebuff = HasAura([](Aura const* aura) -> bool
+ {
+ if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG)
+ return true;
+ else if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_HORDE_FLAG)
+ return true;
+ else if (aura->GetSpellInfo()->Id == SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG)
+ return true;
+ return false;
+ });
+
// BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
// Note: Mount, stealth and invisibility will be removed when used
return (!isTotalImmune() && // Damage immune
- !HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // Still has recently held flag debuff
+ !hasRecentlyDroppedFlagDebuff && // Still has recently held flag debuff
IsAlive()); // Alive
}