diff options
-rw-r--r-- | sql/updates/world/master/2023_08_29_00_world.sql | 139 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Battleground.h | 4 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundMgr.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp | 951 | ||||
-rw-r--r-- | src/server/game/Battlegrounds/Zones/BattlegroundWS.h | 165 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 13 |
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 } |