Fateswhisper

Implementation 1vs1 arena

Dec 14th, 2015
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 53.09 KB | None | 0 0
  1. From fafc1961c248391e9c64a90078205a3bfa716167 Mon Sep 17 00:00:00 2001
  2. From: fateswhisper <[email protected]>
  3. Date: Wed, 16 Apr 2014 16:07:10 +0400
  4. Subject: [PATCH] Implementation 1vs1 arena
  5.  
  6. ---
  7. .../2014-04-16 characters_arena_1_v_1.sql | 2 +
  8. .../world/2014-04-16-00 world.sai.sql | 76 +++++
  9. .../world/2014-04-16-01 world.creature.sql | 2 +
  10. .../world/2014_04_16_00_world_sai.sql | 76 -----
  11. src/server/game/Battlegrounds/ArenaTeam.cpp | 4 +-
  12. src/server/game/Battlegrounds/ArenaTeam.h | 2 +-
  13. src/server/game/Battlegrounds/Battleground.cpp | 5 +
  14. src/server/game/Battlegrounds/Battleground.h | 2 +-
  15. src/server/game/Battlegrounds/BattlegroundMgr.cpp | 2 +-
  16. .../game/Battlegrounds/BattlegroundQueue.cpp | 2 +
  17. src/server/game/Entities/Player/Player.cpp | 1 +
  18. src/server/game/Handlers/BattleGroundHandler.cpp | 5 +
  19. src/server/game/Handlers/PetitionsHandler.cpp | 4 +-
  20. src/server/game/Scripting/ScriptLoader.cpp | 2 +
  21. src/server/game/World/World.cpp | 8 +
  22. src/server/game/World/World.h | 7 +
  23. src/server/scripts/Custom/CMakeLists.txt | 2 +
  24. src/server/scripts/Custom/npc_arena1v1.cpp | 309 +++++++++++++++++++++
  25. src/server/scripts/Custom/npc_arena1v1.h | 69 +++++
  26. src/server/worldserver/worldserver.conf.dist | 65 +++++
  27. 20 files changed, 564 insertions(+), 81 deletions(-)
  28. create mode 100644 sql/updates aztec/characters/2014-04-16 characters_arena_1_v_1.sql
  29. create mode 100644 sql/updates aztec/world/2014-04-16-00 world.sai.sql
  30. create mode 100644 sql/updates aztec/world/2014-04-16-01 world.creature.sql
  31. delete mode 100644 sql/updates aztec/world/2014_04_16_00_world_sai.sql
  32. create mode 100644 src/server/scripts/Custom/npc_arena1v1.cpp
  33. create mode 100644 src/server/scripts/Custom/npc_arena1v1.h
  34.  
  35. diff --git a/sql/updates aztec/characters/2014-04-16 characters_arena_1_v_1.sql b/sql/updates aztec/characters/2014-04-16 characters_arena_1_v_1.sql
  36. new file mode 100644
  37. index 0000000..9f6e4a4
  38. --- /dev/null
  39. +++ b/sql/updates aztec/characters/2014-04-16 characters_arena_1_v_1.sql
  40. @@ -0,0 +1,2 @@
  41. +-- Delete all 5v5 teams and members (core will crash if any 5v5 team exist)
  42. +DELETE arena_team_member, arena_team FROM arena_team_member, arena_team WHERE arena_team_member.arenaTeamId = arena_team.arenaTeamId AND arena_team.type = 5;
  43. diff --git a/sql/updates aztec/world/2014-04-16-00 world.sai.sql b/sql/updates aztec/world/2014-04-16-00 world.sai.sql
  44. new file mode 100644
  45. index 0000000..7f0c476
  46. --- /dev/null
  47. +++ b/sql/updates aztec/world/2014-04-16-00 world.sai.sql
  48. @@ -0,0 +1,76 @@
  49. +-- Runes of Compulsion (Quest: 12093)
  50. +SET @RUNEWEAVER := 26820; -- Iron Rune-Weaver
  51. +SET @RUNE := 26785; -- Directional Rune
  52. +SET @DR1 := 188471; -- Directional Rune 1
  53. +SET @DR2 := 188505; -- Directional Rune 2
  54. +SET @DR3 := 188506; -- Directional Rune 3
  55. +SET @DR4 := 188507; -- Directional Rune 4
  56. +SET @OD := 26920; -- Overseer Durval
  57. +SET @OK := 26921; -- Overseer Korgan
  58. +SET @OL := 26922; -- Overseer Lochli
  59. +SET @OB := 26923; -- Overseer Brunon
  60. +
  61. +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (@RUNEWEAVER, @RUNE, @OD, @OK, @OL, @OB);
  62. +UPDATE `creature_template` SET `faction_A`=1954, `faction_H`=1954 WHERE `entry` IN (@OD, @OK, @OL, @OB);
  63. +UPDATE `gameobject_template` SET `flags`=16 WHERE `entry` IN (@DR1, @DR2, @DR3, @DR4);
  64. +
  65. +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (@RUNEWEAVER, @RUNE, @OD, @OK, @OL, @OB);
  66. +DELETE FROM `smart_scripts` WHERE `source_type`=9 AND `entryorguid` IN (@RUNE*100);
  67. +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
  68. +(@RUNEWEAVER, 0, 0, 1, 1, 0, 100, 1, 1000, 1000, 1000, 1000, 11, 47463, 2, 0, 0, 0, 0, 11, @RUNE, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Channel Rune-Weaver Channel on Directional Rune'),
  69. +(@RUNEWEAVER, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR1, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 1'),
  70. +(@RUNEWEAVER, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR2, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 2'),
  71. +(@RUNEWEAVER, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR3, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 3'),
  72. +(@RUNEWEAVER, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR4, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 4'),
  73. +(@RUNEWEAVER, 0, 5, 0, 25, 0, 100, 0, 0, 0, 0, 0, 45, 2, 1, 0, 0, 0, 0, 11, @RUNE, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On Reset - Set Data 2 1 on Directional Rune'),
  74. +(@RUNEWEAVER, 0, 6, 0, 0, 0, 100, 0, 4000, 7000, 10000, 16000, 11, 52713, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - Combat - Cast Rune Weaving on victim'),
  75. +(@RUNEWEAVER, 0, 7, 0, 6, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 11, @RUNE, 50, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On Death - Set Data 1 1 on Directional Rune'),
  76. +(@RUNE, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Data 1 1 - Increase Phase'),
  77. +(@RUNE, 0, 1, 0, 38, 0, 100, 0, 2, 1, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Data 2 1 - Reset to Phase 0'),
  78. +(@RUNE, 0, 2, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OD, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4485.58, -4655.58, 77.65009, 3.228859, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Durval'),
  79. +(@RUNE, 0, 3, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OK, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4317.391, -4882.59, 33.49857, 4.520403, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Korgan'),
  80. +(@RUNE, 0, 4, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OL, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4215.784, -5049.129, 5.86421, 2.75762, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Lochli'),
  81. +(@RUNE, 0, 5, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OB, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 3986.997, -5246.744, 7.280532, 0.8901179, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Brunon'),
  82. +(@RUNE, 0, 6, 0, 60, 8, 100, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Update OOC in Phase 4 - Reset to Phase 0'),
  83. +(@OD, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - On Just Summoned - Say'),
  84. +(@OD, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - On Link - Cast Spawn - Blue Lightning'),
  85. +(@OD, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR1, 10, 0, 0, 0, 0, 0, 'Overseer Durval - On Link - Activate Directional Rune 1'),
  86. +(@OD, 0, 3, 0, 0, 0, 100, 0, 5000, 9000, 8000, 11000, 11, 52715, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - In Combat - Cast Rune of Destruction'),
  87. +(@OK, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - On Just Summoned - Say'),
  88. +(@OK, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - On Link - Cast Spawn - Blue Lightning'),
  89. +(@OK, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR2, 10, 0, 0, 0, 0, 0, 'Overseer Korgan - On Link - Activate Directional Rune 2'),
  90. +(@OK, 0, 3, 0, 0, 0, 100, 0, 3000, 5000, 7000, 9000, 11, 32018, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - In Combat - Cast Call Lightning'),
  91. +(@OK, 0, 4, 0, 2, 0, 100, 0, 0, 30, 12000, 16000, 11, 52714, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - Between 0-30% Health - Cast Revitalizing Rune'),
  92. +(@OL, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - On Just Summoned - Say'),
  93. +(@OL, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - On Link - Cast Spawn - Blue Lightning'),
  94. +(@OL, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR3, 10, 0, 0, 0, 0, 0, 'Overseer Lochli - On Link - Activate Directional Rune 3'),
  95. +(@OL, 0, 3, 0, 0, 0, 100, 0, 8000, 12000, 11000, 15000, 11, 52717, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - In Combat - Cast Thunderstorm'),
  96. +(@OB, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Brunon - On Just Summoned - Say'),
  97. +(@OB, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Brunon - On Link - Cast Spawn - Blue Lightning'),
  98. +(@OB, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR4, 10, 0, 0, 0, 0, 0, 'Overseer Brunon - On Link - Activate Directional Rune 4');
  99. +
  100. +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=@RUNE;
  101. +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
  102. +(22, 3, @RUNE, 0, 0, 30, 1, @DR1, 5, 0, 0, 0, 0, '', 'Execute SAI id 2 only if within 5 yards of Directional Rune 1'),
  103. +(22, 4, @RUNE, 0, 0, 30, 1, @DR2, 5, 0, 0, 0, 0, '', 'Execute SAI id 3 only if within 5 yards of Directional Rune 2'),
  104. +(22, 5, @RUNE, 0, 0, 30, 1, @DR3, 5, 0, 0, 0, 0, '', 'Execute SAI id 4 only if within 5 yards of Directional Rune 3'),
  105. +(22, 6, @RUNE, 0, 0, 30, 1, @DR4, 5, 0, 0, 0, 0, '', 'Execute SAI id 5 only if within 5 yards of Directional Rune 4');
  106. +
  107. +DELETE FROM `creature_text` WHERE `entry` IN (@OD, @OK, @OL, @OB);
  108. +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
  109. +(@OD, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26090),
  110. +(@OD, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26091),
  111. +(@OD, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26092),
  112. +(@OD, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26089),
  113. +(@OK, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26090),
  114. +(@OK, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26091),
  115. +(@OK, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26092),
  116. +(@OK, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26089),
  117. +(@OL, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26090),
  118. +(@OL, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26091),
  119. +(@OL, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26092),
  120. +(@OL, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26089),
  121. +(@OB, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26090),
  122. +(@OB, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26091),
  123. +(@OB, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26092),
  124. +(@OB, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26089);
  125. \ No newline at end of file
  126. diff --git a/sql/updates aztec/world/2014-04-16-01 world.creature.sql b/sql/updates aztec/world/2014-04-16-01 world.creature.sql
  127. new file mode 100644
  128. index 0000000..876e9fd
  129. --- /dev/null
  130. +++ b/sql/updates aztec/world/2014-04-16-01 world.creature.sql
  131. @@ -0,0 +1,2 @@
  132. +UPDATE `creature_template` SET `name`='1v1 Arena', `subname`='Arena Battlemaster', `ScriptName`='npc_1v1arena' WHERE `entry`=50002;
  133. +UPDATE `creature` SET `position_x`=-1865.04, `position_y`=-4136.98, `position_z`=10.7252, `orientation`=5.4452 WHERE `guid`=213320;
  134. \ No newline at end of file
  135. diff --git a/sql/updates aztec/world/2014_04_16_00_world_sai.sql b/sql/updates aztec/world/2014_04_16_00_world_sai.sql
  136. deleted file mode 100644
  137. index 7f0c476..0000000
  138. --- a/sql/updates aztec/world/2014_04_16_00_world_sai.sql
  139. +++ /dev/null
  140. @@ -1,76 +0,0 @@
  141. --- Runes of Compulsion (Quest: 12093)
  142. -SET @RUNEWEAVER := 26820; -- Iron Rune-Weaver
  143. -SET @RUNE := 26785; -- Directional Rune
  144. -SET @DR1 := 188471; -- Directional Rune 1
  145. -SET @DR2 := 188505; -- Directional Rune 2
  146. -SET @DR3 := 188506; -- Directional Rune 3
  147. -SET @DR4 := 188507; -- Directional Rune 4
  148. -SET @OD := 26920; -- Overseer Durval
  149. -SET @OK := 26921; -- Overseer Korgan
  150. -SET @OL := 26922; -- Overseer Lochli
  151. -SET @OB := 26923; -- Overseer Brunon
  152. -
  153. -UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (@RUNEWEAVER, @RUNE, @OD, @OK, @OL, @OB);
  154. -UPDATE `creature_template` SET `faction_A`=1954, `faction_H`=1954 WHERE `entry` IN (@OD, @OK, @OL, @OB);
  155. -UPDATE `gameobject_template` SET `flags`=16 WHERE `entry` IN (@DR1, @DR2, @DR3, @DR4);
  156. -
  157. -DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (@RUNEWEAVER, @RUNE, @OD, @OK, @OL, @OB);
  158. -DELETE FROM `smart_scripts` WHERE `source_type`=9 AND `entryorguid` IN (@RUNE*100);
  159. -INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
  160. -(@RUNEWEAVER, 0, 0, 1, 1, 0, 100, 1, 1000, 1000, 1000, 1000, 11, 47463, 2, 0, 0, 0, 0, 11, @RUNE, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Channel Rune-Weaver Channel on Directional Rune'),
  161. -(@RUNEWEAVER, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR1, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 1'),
  162. -(@RUNEWEAVER, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR2, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 2'),
  163. -(@RUNEWEAVER, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR3, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 3'),
  164. -(@RUNEWEAVER, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 15, @DR4, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On spawn & reset - Reset Directional Rune 4'),
  165. -(@RUNEWEAVER, 0, 5, 0, 25, 0, 100, 0, 0, 0, 0, 0, 45, 2, 1, 0, 0, 0, 0, 11, @RUNE, 30, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On Reset - Set Data 2 1 on Directional Rune'),
  166. -(@RUNEWEAVER, 0, 6, 0, 0, 0, 100, 0, 4000, 7000, 10000, 16000, 11, 52713, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - Combat - Cast Rune Weaving on victim'),
  167. -(@RUNEWEAVER, 0, 7, 0, 6, 0, 100, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 11, @RUNE, 50, 0, 0, 0, 0, 0, 'Iron Rune-Weaver - On Death - Set Data 1 1 on Directional Rune'),
  168. -(@RUNE, 0, 0, 0, 38, 0, 100, 0, 1, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Data 1 1 - Increase Phase'),
  169. -(@RUNE, 0, 1, 0, 38, 0, 100, 0, 2, 1, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Data 2 1 - Reset to Phase 0'),
  170. -(@RUNE, 0, 2, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OD, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4485.58, -4655.58, 77.65009, 3.228859, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Durval'),
  171. -(@RUNE, 0, 3, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OK, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4317.391, -4882.59, 33.49857, 4.520403, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Korgan'),
  172. -(@RUNE, 0, 4, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OL, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 4215.784, -5049.129, 5.86421, 2.75762, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Lochli'),
  173. -(@RUNE, 0, 5, 0, 60, 8, 100, 0, 0, 0, 0, 0, 12, @OB, 1, 120000, 0, 0, 0, 8, 0, 0, 0, 3986.997, -5246.744, 7.280532, 0.8901179, 'Directional Rune - On Update OOC in Phase 4 - Summon Overseer Brunon'),
  174. -(@RUNE, 0, 6, 0, 60, 8, 100, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Directional Rune - On Update OOC in Phase 4 - Reset to Phase 0'),
  175. -(@OD, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - On Just Summoned - Say'),
  176. -(@OD, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - On Link - Cast Spawn - Blue Lightning'),
  177. -(@OD, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR1, 10, 0, 0, 0, 0, 0, 'Overseer Durval - On Link - Activate Directional Rune 1'),
  178. -(@OD, 0, 3, 0, 0, 0, 100, 0, 5000, 9000, 8000, 11000, 11, 52715, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Overseer Durval - In Combat - Cast Rune of Destruction'),
  179. -(@OK, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - On Just Summoned - Say'),
  180. -(@OK, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - On Link - Cast Spawn - Blue Lightning'),
  181. -(@OK, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR2, 10, 0, 0, 0, 0, 0, 'Overseer Korgan - On Link - Activate Directional Rune 2'),
  182. -(@OK, 0, 3, 0, 0, 0, 100, 0, 3000, 5000, 7000, 9000, 11, 32018, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - In Combat - Cast Call Lightning'),
  183. -(@OK, 0, 4, 0, 2, 0, 100, 0, 0, 30, 12000, 16000, 11, 52714, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Korgan - Between 0-30% Health - Cast Revitalizing Rune'),
  184. -(@OL, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - On Just Summoned - Say'),
  185. -(@OL, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - On Link - Cast Spawn - Blue Lightning'),
  186. -(@OL, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR3, 10, 0, 0, 0, 0, 0, 'Overseer Lochli - On Link - Activate Directional Rune 3'),
  187. -(@OL, 0, 3, 0, 0, 0, 100, 0, 8000, 12000, 11000, 15000, 11, 52717, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Lochli - In Combat - Cast Thunderstorm'),
  188. -(@OB, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Brunon - On Just Summoned - Say'),
  189. -(@OB, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Overseer Brunon - On Link - Cast Spawn - Blue Lightning'),
  190. -(@OB, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 15, @DR4, 10, 0, 0, 0, 0, 0, 'Overseer Brunon - On Link - Activate Directional Rune 4');
  191. -
  192. -DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=@RUNE;
  193. -INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
  194. -(22, 3, @RUNE, 0, 0, 30, 1, @DR1, 5, 0, 0, 0, 0, '', 'Execute SAI id 2 only if within 5 yards of Directional Rune 1'),
  195. -(22, 4, @RUNE, 0, 0, 30, 1, @DR2, 5, 0, 0, 0, 0, '', 'Execute SAI id 3 only if within 5 yards of Directional Rune 2'),
  196. -(22, 5, @RUNE, 0, 0, 30, 1, @DR3, 5, 0, 0, 0, 0, '', 'Execute SAI id 4 only if within 5 yards of Directional Rune 3'),
  197. -(22, 6, @RUNE, 0, 0, 30, 1, @DR4, 5, 0, 0, 0, 0, '', 'Execute SAI id 5 only if within 5 yards of Directional Rune 4');
  198. -
  199. -DELETE FROM `creature_text` WHERE `entry` IN (@OD, @OK, @OL, @OB);
  200. -INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
  201. -(@OD, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26090),
  202. -(@OD, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26091),
  203. -(@OD, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26092),
  204. -(@OD, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Durval', 26089),
  205. -(@OK, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26090),
  206. -(@OK, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26091),
  207. -(@OK, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26092),
  208. -(@OK, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Korgan', 26089),
  209. -(@OL, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26090),
  210. -(@OL, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26091),
  211. -(@OL, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26092),
  212. -(@OL, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Lochli', 26089),
  213. -(@OB, 0, 0, 'You''ll pay for this!', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26090),
  214. -(@OB, 0, 1, 'Fool! You''ll never get away with this!', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26091),
  215. -(@OB, 0, 2, 'You dare to defy the sons of iron?', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26092),
  216. -(@OB, 0, 3, 'What do you think you''re doing?', 12, 0, 100, 25, 0, 0, 'Overseer Brunon', 26089);
  217. \ No newline at end of file
  218. diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
  219. index 2ca6053..2dbc70d 100644
  220. --- a/src/server/game/Battlegrounds/ArenaTeam.cpp
  221. +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
  222. @@ -439,7 +439,7 @@ void ArenaTeam::Query(WorldSession* session)
  223. WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
  224. data << uint32(GetId()); // team id
  225. data << GetName(); // team name
  226. - data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
  227. + data << uint32(GetType() == 1 ? 5 : GetType()); // arena team type (2=2x2, 3=3x3 or 1=1x1(modify 1 to 5, so player can see arenateam in 5v5 slot))
  228. data << uint32(BackgroundColor); // background color
  229. data << uint32(EmblemStyle); // emblem style
  230. data << uint32(EmblemColor); // emblem color
  231. @@ -611,6 +611,8 @@ uint32 ArenaTeam::GetPoints(uint32 memberRating)
  232. points *= 0.76f;
  233. else if (Type == ARENA_TEAM_3v3)
  234. points *= 0.88f;
  235. + else if (Type == ARENA_TEAM_5v5) // 1v1 Arena
  236. + points *= sWorld->getFloatConfig(CONFIG_ARENA_1V1_ARENAPOINTS_MULTI);
  237.  
  238. return (uint32) points;
  239. }
  240. diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h
  241. index cd9e2be..1f78c84 100644
  242. --- a/src/server/game/Battlegrounds/ArenaTeam.h
  243. +++ b/src/server/game/Battlegrounds/ArenaTeam.h
  244. @@ -82,7 +82,7 @@ enum ArenaTeamTypes
  245. {
  246. ARENA_TEAM_2v2 = 2,
  247. ARENA_TEAM_3v3 = 3,
  248. - ARENA_TEAM_5v5 = 5
  249. + ARENA_TEAM_5v5 = 1 // 1v1 Arena - 5v5 doesn't exist anymore
  250. };
  251.  
  252. struct ArenaTeamMember
  253. diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
  254. index 3d42338..768cfdf 100644
  255. --- a/src/server/game/Battlegrounds/Battleground.cpp
  256. +++ b/src/server/game/Battlegrounds/Battleground.cpp
  257. @@ -478,6 +478,11 @@ inline void Battleground::_ProcessJoin(uint32 diff)
  258. // First start warning - 2 or 1 minute
  259. SendMessageToAll(StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL);
  260. }
  261. +
  262. + // 1v1 Arena - Start arena after 15s, when all players are in arena
  263. + if(GetArenaType() == ARENA_TYPE_5v5 && GetStartDelayTime() > StartDelayTimes[BG_STARTING_EVENT_THIRD] && (m_PlayersCount[0] + m_PlayersCount[1]) == 2)
  264. + SetStartDelayTime(StartDelayTimes[BG_STARTING_EVENT_THIRD]);
  265. +
  266. // After 1 minute or 30 seconds, warning is signaled
  267. else if (GetStartDelayTime() <= StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2))
  268. {
  269. diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
  270. index 01d8b50..e7b3806 100644
  271. --- a/src/server/game/Battlegrounds/Battleground.h
  272. +++ b/src/server/game/Battlegrounds/Battleground.h
  273. @@ -201,7 +201,7 @@ enum ArenaType
  274. {
  275. ARENA_TYPE_2v2 = 2,
  276. ARENA_TYPE_3v3 = 3,
  277. - ARENA_TYPE_5v5 = 5
  278. + ARENA_TYPE_5v5 = 1 // 1v1 Arena - 5v5 doesn't exist anymore
  279. };
  280.  
  281. enum BattlegroundType
  282. diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  283. index 220fca6..1fd8ab3 100644
  284. --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  285. +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
  286. @@ -606,7 +606,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
  287. maxPlayersPerTeam = 3;
  288. break;
  289. case ARENA_TYPE_5v5:
  290. - maxPlayersPerTeam = 5;
  291. + maxPlayersPerTeam = 1; // 1v1 Arena
  292. break;
  293. }
  294.  
  295. diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  296. index cd33b9f..83e7986 100644
  297. --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  298. +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
  299. @@ -167,6 +167,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
  300. {
  301. ArenaTeam* Team = sArenaTeamMgr->GetArenaTeamById(arenateamid);
  302. if (Team)
  303. + if ((Team->GetType() == ARENA_TYPE_5v5 && sWorld->getBoolConfig(CONFIG_ARENA_1V1_ANNOUNCER)) || Team->GetType() != ARENA_TYPE_5v5)
  304. sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, Team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
  305. }
  306.  
  307. @@ -385,6 +386,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
  308. // announce to world if arena team left queue for rated match, show only once
  309. if (group->ArenaType && group->IsRated && group->Players.empty() && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
  310. if (ArenaTeam* Team = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId))
  311. + if (Team && ((Team->GetType() == ARENA_TYPE_5v5 && sWorld->getBoolConfig(CONFIG_ARENA_1V1_ANNOUNCER)) || Team->GetType() != ARENA_TYPE_5v5))
  312. sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, Team->GetName().c_str(), group->ArenaType, group->ArenaType, group->ArenaTeamRating);
  313.  
  314. // if player leaves queue and he is invited to rated arena match, then he have to lose
  315. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
  316. index 0a65c5c..6b8f1cb 100644
  317. --- a/src/server/game/Entities/Player/Player.cpp
  318. +++ b/src/server/game/Entities/Player/Player.cpp
  319. @@ -22022,6 +22022,7 @@ uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const
  320. uint32 max_personal_rating = 0;
  321. for (uint8 i = minarenaslot; i < MAX_ARENA_SLOT; ++i)
  322. {
  323. + if(i == 2 && sWorld->getBoolConfig(CONFIG_ARENA_1V1_VENDOR_RATING) == false) continue;
  324. if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamId(i)))
  325. {
  326. uint32 p_rating = GetArenaPersonalRating(i);
  327. diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
  328. index 866aced..9e70bcd 100644
  329. --- a/src/server/game/Handlers/BattleGroundHandler.cpp
  330. +++ b/src/server/game/Handlers/BattleGroundHandler.cpp
  331. @@ -34,6 +34,7 @@
  332. #include "Opcodes.h"
  333. #include "DisableMgr.h"
  334. #include "Group.h"
  335. +#include "../../scripts/Custom/npc_arena1v1.h"
  336.  
  337. #include "Cfbg/Cfbg.h"
  338.  
  339. @@ -447,6 +448,10 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
  340. if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
  341. return; // cheating?
  342.  
  343. + // 1v1 Arena. Player can't join arena when forbidden talents are used.
  344. + if(bgQueueTypeId == BATTLEGROUND_QUEUE_5v5 && Arena1v1CheckTalents(_player) == false)
  345. + return;
  346. +
  347. if (!_player->InBattleground())
  348. _player->SetBattlegroundEntryPoint();
  349.  
  350. diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
  351. index d02b898..f57f2e8 100644
  352. --- a/src/server/game/Handlers/PetitionsHandler.cpp
  353. +++ b/src/server/game/Handlers/PetitionsHandler.cpp
  354. @@ -953,7 +953,7 @@ void WorldSession::SendPetitionShowList(uint64 guid)
  355. }
  356. else
  357. {
  358. - data << uint8(3); // count
  359. + data << uint8(2); // count
  360. // 2v2
  361. data << uint32(1); // index
  362. data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
  363. @@ -969,12 +969,14 @@ void WorldSession::SendPetitionShowList(uint64 guid)
  364. data << uint32(3); // unknown
  365. data << uint32(3); // required signs?
  366. // 5v5
  367. + /* Disable purchase 5v5 petition - edit to 1v1 doesn't work (client prevent it)
  368. data << uint32(3); // index
  369. data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
  370. data << uint32(CHARTER_DISPLAY_ID); // charter display id
  371. data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost
  372. data << uint32(5); // unknown
  373. data << uint32(5); // required signs?
  374. + */
  375. }
  376.  
  377. SendPacket(&data);
  378. diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
  379. index 97fa24f..d0f9b0c 100644
  380. --- a/src/server/game/Scripting/ScriptLoader.cpp
  381. +++ b/src/server/game/Scripting/ScriptLoader.cpp
  382. @@ -1449,6 +1449,7 @@ void AddSC_fast_arena_start();
  383. void AddSC_npc_Arena_resetMMR();
  384. void Add_SC_Custom_Rates();
  385. void AddSC_REFORGER_NPC();
  386. +void AddSC_npc_1v1arena();
  387. #endif
  388.  
  389. void AddCustomScripts()
  390. @@ -1462,5 +1463,6 @@ void AddCustomScripts()
  391. AddSC_npc_Arena_resetMMR();
  392. Add_SC_Custom_Rates();
  393. AddSC_REFORGER_NPC();
  394. + AddSC_npc_1v1arena();
  395. #endif
  396. }
  397. diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
  398. index 0eed446..bce84d9 100644
  399. --- a/src/server/game/World/World.cpp
  400. +++ b/src/server/game/World/World.cpp
  401. @@ -1060,6 +1060,14 @@ void World::LoadConfigSettings(bool reload)
  402. m_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetBoolDefault("Arena.ArenaSeason.InProgress", true);
  403. m_bool_configs[CONFIG_ARENA_LOG_EXTENDED_INFO] = sConfigMgr->GetBoolDefault("ArenaLog.ExtendedInfo", false);
  404.  
  405. + m_bool_configs[CONFIG_ARENA_1V1_ENABLE] = sConfigMgr->GetBoolDefault("Arena.1v1.Enable", true);
  406. + m_bool_configs[CONFIG_ARENA_1V1_ANNOUNCER] = sConfigMgr->GetBoolDefault("Arena.1v1.Announcer", false);
  407. + m_int_configs[CONFIG_ARENA_1V1_MIN_LEVEL] = sConfigMgr->GetIntDefault("Arena.1v1.MinLevel", 80);
  408. + m_int_configs[CONFIG_ARENA_1V1_COSTS] = sConfigMgr->GetIntDefault("Arena.1v1.Costs", 400000);
  409. + m_bool_configs[CONFIG_ARENA_1V1_VENDOR_RATING] = sConfigMgr->GetBoolDefault("Arena.1v1.VendorRating", false);
  410. + m_float_configs[CONFIG_ARENA_1V1_ARENAPOINTS_MULTI] = sConfigMgr->GetFloatDefault("Arena.1v1.ArenaPointsMulti", 0.64f);
  411. + m_bool_configs[CONFIG_ARENA_1V1_BLOCK_FORBIDDEN_TALENTS] = sConfigMgr->GetBoolDefault("Arena.1v1.BlockForbiddenTalents", true);
  412. +
  413. m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetBoolDefault("OffhandCheckAtSpellUnlearn", true);
  414.  
  415. m_bool_configs[BATTLEGROUND_CROSSFACTION_ENABLED] = sConfigMgr->GetBoolDefault("CrossfactionBG.enable", true);
  416. diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
  417. index bd47237..2b04f79 100644
  418. --- a/src/server/game/World/World.h
  419. +++ b/src/server/game/World/World.h
  420. @@ -129,6 +129,10 @@ enum WorldBoolConfigs
  421. CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
  422. CONFIG_ARENA_SEASON_IN_PROGRESS,
  423. CONFIG_ARENA_LOG_EXTENDED_INFO,
  424. + CONFIG_ARENA_1V1_ENABLE,
  425. + CONFIG_ARENA_1V1_ANNOUNCER,
  426. + CONFIG_ARENA_1V1_VENDOR_RATING,
  427. + CONFIG_ARENA_1V1_BLOCK_FORBIDDEN_TALENTS,
  428. CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN,
  429. CONFIG_VMAP_INDOOR_CHECK,
  430. CONFIG_START_ALL_SPELLS,
  431. @@ -188,6 +192,7 @@ enum WorldFloatConfigs
  432. CONFIG_STATS_LIMITS_PARRY,
  433. CONFIG_STATS_LIMITS_BLOCK,
  434. CONFIG_STATS_LIMITS_CRIT,
  435. + CONFIG_ARENA_1V1_ARENAPOINTS_MULTI,
  436. FLOAT_CONFIG_VALUE_COUNT
  437. };
  438.  
  439. @@ -295,6 +300,8 @@ enum WorldIntConfigs
  440. CONFIG_ARENA_START_RATING,
  441. CONFIG_ARENA_START_PERSONAL_RATING,
  442. CONFIG_ARENA_START_MATCHMAKER_RATING,
  443. + CONFIG_ARENA_1V1_MIN_LEVEL,
  444. + CONFIG_ARENA_1V1_COSTS,
  445. CONFIG_MAX_WHO,
  446. CONFIG_HONOR_AFTER_DUEL,
  447. CONFIG_PVP_TOKEN_MAP_TYPE,
  448. diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
  449. index f3844da..6124ea4 100644
  450. --- a/src/server/scripts/Custom/CMakeLists.txt
  451. +++ b/src/server/scripts/Custom/CMakeLists.txt
  452. @@ -18,6 +18,8 @@ set(scripts_STAT_SRCS
  453. Custom/npc_Arena_resetMMR.cpp
  454. Custom/custom_rates.cpp
  455. Custom/Reforging.cpp
  456. + Custom/npc_arena1v1.cpp
  457. + Custom/npc_arena1v1.h
  458. )
  459.  
  460. message(" -> Prepared: Custom")
  461. diff --git a/src/server/scripts/Custom/npc_arena1v1.cpp b/src/server/scripts/Custom/npc_arena1v1.cpp
  462. new file mode 100644
  463. index 0000000..d00049d
  464. --- /dev/null
  465. +++ b/src/server/scripts/Custom/npc_arena1v1.cpp
  466. @@ -0,0 +1,309 @@
  467. +/*
  468. + *
  469. + * Copyright (C) 2013 Emu-Devstore <http://emu-devstore.com/>
  470. + * Written by Teiby <http://www.teiby.de/>
  471. + *
  472. + */
  473. +
  474. +#include "ScriptMgr.h"
  475. +#include "ArenaTeamMgr.h"
  476. +#include "Common.h"
  477. +#include "DisableMgr.h"
  478. +#include "BattlegroundMgr.h"
  479. +#include "Battleground.h"
  480. +#include "ArenaTeam.h"
  481. +#include "Language.h"
  482. +#include "npc_arena1v1.h"
  483. +
  484. +
  485. +class npc_1v1arena : public CreatureScript
  486. +{
  487. +public:
  488. + npc_1v1arena() : CreatureScript("npc_1v1arena")
  489. + {
  490. + }
  491. +
  492. +
  493. + bool JoinQueueArena(Player* player, Creature* me, bool isRated)
  494. + {
  495. + if(!player || !me)
  496. + return false;
  497. +
  498. + if(sWorld->getIntConfig(CONFIG_ARENA_1V1_MIN_LEVEL) > player->getLevel())
  499. + return false;
  500. +
  501. + uint64 guid = player->GetGUID();
  502. + uint8 arenaslot = ArenaTeam::GetSlotByType(ARENA_TEAM_5v5);
  503. + uint8 arenatype = ARENA_TYPE_5v5;
  504. + uint32 arenaRating = 0;
  505. + uint32 matchmakerRating = 0;
  506. +
  507. + // ignore if we already in BG or BG queue
  508. + if (player->InBattleground())
  509. + return false;
  510. +
  511. + //check existance
  512. + Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
  513. + if (!bg)
  514. + {
  515. + TC_LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
  516. + return false;
  517. + }
  518. +
  519. + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL))
  520. + {
  521. + ChatHandler(player->GetSession()).PSendSysMessage(LANG_ARENA_DISABLED);
  522. + return false;
  523. + }
  524. +
  525. + BattlegroundTypeId bgTypeId = bg->GetTypeID();
  526. + BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
  527. + PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), player->getLevel());
  528. + if (!bracketEntry)
  529. + return false;
  530. +
  531. + GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL;
  532. +
  533. + // check if already in queue
  534. + if (player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
  535. + //player is already in this queue
  536. + return false;
  537. + // check if has free queue slots
  538. + if (!player->HasFreeBattlegroundQueueId())
  539. + return false;
  540. +
  541. + uint32 ateamId = 0;
  542. +
  543. + if(isRated)
  544. + {
  545. + ateamId = player->GetArenaTeamId(arenaslot);
  546. + ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
  547. + if (!at)
  548. + {
  549. + player->GetSession()->SendNotInArenaTeamPacket(arenatype);
  550. + return false;
  551. + }
  552. +
  553. + // get the team rating for queueing
  554. + arenaRating = at->GetRating();
  555. + matchmakerRating = arenaRating;
  556. + // the arenateam id must match for everyone in the group
  557. +
  558. + if (arenaRating <= 0)
  559. + arenaRating = 1;
  560. + }
  561. +
  562. + BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
  563. + bg->SetRated(isRated);
  564. +
  565. + GroupQueueInfo* ginfo = bgQueue.AddGroup(player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId);
  566. + uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
  567. + uint32 queueSlot = player->AddBattlegroundQueueId(bgQueueTypeId);
  568. +
  569. + WorldPacket data;
  570. + // send status packet (in queue)
  571. + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0);
  572. + player->GetSession()->SendPacket(&data);
  573. +
  574. + sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
  575. +
  576. + return true;
  577. + }
  578. +
  579. +
  580. + bool CreateArenateam(Player* player, Creature* me)
  581. + {
  582. + if(!player || !me)
  583. + return false;
  584. +
  585. + uint8 slot = ArenaTeam::GetSlotByType(ARENA_TEAM_5v5);
  586. + if (slot >= MAX_ARENA_SLOT)
  587. + return false;
  588. +
  589. + // Check if player is already in an arena team
  590. + if (player->GetArenaTeamId(slot))
  591. + {
  592. + player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM);
  593. + return false;
  594. + }
  595. +
  596. +
  597. + // Teamname = playername
  598. + // if teamname exist, we have to choose another name (playername + number)
  599. + int i = 1;
  600. + std::stringstream teamName;
  601. + teamName << player->GetName();
  602. + do
  603. + {
  604. + if(sArenaTeamMgr->GetArenaTeamByName(teamName.str()) != NULL) // teamname exist, so choose another name
  605. + {
  606. + teamName.str(std::string());
  607. + teamName << player->GetName() << i;
  608. + }
  609. + else
  610. + break;
  611. + } while (i < 100); // should never happen
  612. +
  613. + // Create arena team
  614. + ArenaTeam* arenaTeam = new ArenaTeam();
  615. +
  616. + if (!arenaTeam->Create(player->GetGUID(), ARENA_TEAM_5v5, teamName.str(), 4283124816, 45, 4294242303, 5, 4294705149))
  617. + {
  618. + delete arenaTeam;
  619. + return false;
  620. + }
  621. +
  622. + // Register arena team
  623. + sArenaTeamMgr->AddArenaTeam(arenaTeam);
  624. + arenaTeam->AddMember(player->GetGUID());
  625. +
  626. + ChatHandler(player->GetSession()).SendSysMessage("1v1 Arenateam successful created!");
  627. +
  628. + return true;
  629. + }
  630. +
  631. +
  632. + bool OnGossipHello(Player* player, Creature* me)
  633. + {
  634. + if(!player || !me)
  635. + return true;
  636. +
  637. + if(sWorld->getBoolConfig(CONFIG_ARENA_1V1_ENABLE) == false)
  638. + {
  639. + ChatHandler(player->GetSession()).SendSysMessage("1v1 disabled!");
  640. + return true;
  641. + }
  642. +
  643. + if(player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5))
  644. + player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_CHAT, "Leave queue 1v1 Arena", GOSSIP_SENDER_MAIN, 3, "Are you sure?", 0, false);
  645. + else
  646. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Sign up 1v1 Arena (unrated)", GOSSIP_SENDER_MAIN, 20);
  647. +
  648. + if(player->GetArenaTeamId(ArenaTeam::GetSlotByType(ARENA_TEAM_5v5)) == NULL)
  649. + player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_CHAT, "Create new 1v1 Arenateam", GOSSIP_SENDER_MAIN, 1, "Create 1v1 arenateam?", sWorld->getIntConfig(CONFIG_ARENA_1V1_COSTS), false);
  650. + else
  651. + {
  652. + if(player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5) == false)
  653. + {
  654. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Sign up 1v1 Arena (rated)", GOSSIP_SENDER_MAIN, 2);
  655. + player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_CHAT, "Disband arenateam", GOSSIP_SENDER_MAIN, 5, "Are you sure?", 0, false);
  656. + }
  657. +
  658. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Show statistics", GOSSIP_SENDER_MAIN, 4);
  659. + }
  660. +
  661. + // player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Script Info", GOSSIP_SENDER_MAIN, 8);
  662. + player->SEND_GOSSIP_MENU(68, me->GetGUID());
  663. + return true;
  664. + }
  665. +
  666. +
  667. +
  668. + bool OnGossipSelect(Player* player, Creature* me, uint32 /*uiSender*/, uint32 uiAction)
  669. + {
  670. + if(!player || !me)
  671. + return true;
  672. +
  673. + player->PlayerTalkClass->ClearMenus();
  674. +
  675. + switch (uiAction)
  676. + {
  677. + case 1: // Create new Arenateam
  678. + {
  679. + if(sWorld->getIntConfig(CONFIG_ARENA_1V1_MIN_LEVEL) <= player->getLevel())
  680. + {
  681. + if(player->GetMoney() >= sWorld->getIntConfig(CONFIG_ARENA_1V1_COSTS) && CreateArenateam(player, me))
  682. + player->ModifyMoney(sWorld->getIntConfig(CONFIG_ARENA_1V1_COSTS) * -1);
  683. + }
  684. + else
  685. + {
  686. + ChatHandler(player->GetSession()).PSendSysMessage("You need level %u+ to create an 1v1 arenateam.", sWorld->getIntConfig(CONFIG_ARENA_1V1_MIN_LEVEL));
  687. + player->CLOSE_GOSSIP_MENU();
  688. + return true;
  689. + }
  690. + }
  691. + break;
  692. +
  693. + case 2: // Join Queue Arena (rated)
  694. + {
  695. + if(Arena1v1CheckTalents(player) && JoinQueueArena(player, me, true) == false)
  696. + ChatHandler(player->GetSession()).SendSysMessage("Something went wrong while join queue.");
  697. +
  698. + player->CLOSE_GOSSIP_MENU();
  699. + return true;
  700. + }
  701. + break;
  702. +
  703. + case 20: // Join Queue Arena (unrated)
  704. + {
  705. + if(Arena1v1CheckTalents(player) && JoinQueueArena(player, me, false) == false)
  706. + ChatHandler(player->GetSession()).SendSysMessage("Something went wrong while join queue.");
  707. +
  708. + player->CLOSE_GOSSIP_MENU();
  709. + return true;
  710. + }
  711. + break;
  712. +
  713. + case 3: // Leave Queue
  714. + {
  715. + WorldPacket Data;
  716. + Data << (uint8)0x1 << (uint8)0x0 << (uint32)BATTLEGROUND_AA << (uint16)0x0 << (uint8)0x0;
  717. + player->GetSession()->HandleBattleFieldPortOpcode(Data);
  718. + player->CLOSE_GOSSIP_MENU();
  719. + return true;
  720. + }
  721. + break;
  722. +
  723. + case 4: // get statistics
  724. + {
  725. + ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(player->GetArenaTeamId(ArenaTeam::GetSlotByType(ARENA_TEAM_5v5)));
  726. + if(at)
  727. + {
  728. + std::stringstream s;
  729. + s << "Rating: " << at->GetStats().Rating;
  730. + s << "\nRank: " << at->GetStats().Rank;
  731. + s << "\nSeason Games: " << at->GetStats().SeasonGames;
  732. + s << "\nSeason Wins: " << at->GetStats().SeasonWins;
  733. + s << "\nWeek Games: " << at->GetStats().WeekGames;
  734. + s << "\nWeek Wins: " << at->GetStats().WeekWins;
  735. +
  736. + ChatHandler(player->GetSession()).PSendSysMessage(s.str().c_str());
  737. + }
  738. + }
  739. + break;
  740. +
  741. +
  742. + case 5: // Disband arenateam
  743. + {
  744. + WorldPacket Data;
  745. + Data << (uint32)player->GetArenaTeamId(ArenaTeam::GetSlotByType(ARENA_TEAM_5v5));
  746. + player->GetSession()->HandleArenaTeamLeaveOpcode(Data);
  747. + ChatHandler(player->GetSession()).SendSysMessage("Arenateam deleted!");
  748. + player->CLOSE_GOSSIP_MENU();
  749. + return true;
  750. + }
  751. + break;
  752. +
  753. + case 8: // Script Info
  754. + {
  755. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Developer: Teiby", GOSSIP_SENDER_MAIN, uiAction);
  756. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Website: www.teiby.de", GOSSIP_SENDER_MAIN, uiAction);
  757. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Version: 2.1", GOSSIP_SENDER_MAIN, uiAction);
  758. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "<-- Back", GOSSIP_SENDER_MAIN, 7);
  759. + player->SEND_GOSSIP_MENU(68, me->GetGUID());
  760. + return true;
  761. + }
  762. + break;
  763. +
  764. + }
  765. +
  766. + OnGossipHello(player, me);
  767. + return true;
  768. + }
  769. +};
  770. +
  771. +
  772. +void AddSC_npc_1v1arena()
  773. +{
  774. + new npc_1v1arena();
  775. +}
  776. \ No newline at end of file
  777. diff --git a/src/server/scripts/Custom/npc_arena1v1.h b/src/server/scripts/Custom/npc_arena1v1.h
  778. new file mode 100644
  779. index 0000000..2e0efbe
  780. --- /dev/null
  781. +++ b/src/server/scripts/Custom/npc_arena1v1.h
  782. @@ -0,0 +1,69 @@
  783. +/*
  784. + *
  785. + * Copyright (C) 2013 Emu-Devstore <http://emu-devstore.com/>
  786. + * Written by Teiby <http://www.teiby.de/>
  787. + *
  788. + */
  789. +
  790. +#ifndef ARENA_1V1_H
  791. +#define ARENA_1V1_H
  792. +
  793. +// TalentTab.dbc -> TalentTabID
  794. +const uint32 FORBIDDEN_TALENTS_IN_1V1_ARENA[] =
  795. +{
  796. + // Healer
  797. + 201, // PriestDiscipline
  798. + 202, // PriestHoly
  799. + 382, // PaladinHoly
  800. + 262, // ShamanRestoration
  801. + 282, // DruidRestoration
  802. +
  803. + // Tanks
  804. + //383, // PaladinProtection
  805. + //163, // WarriorProtection
  806. +
  807. + 0 // End
  808. +};
  809. +
  810. +
  811. +// Return false, if player have invested more than 35 talentpoints in a forbidden talenttree.
  812. +static bool Arena1v1CheckTalents(Player* player)
  813. +{
  814. + if(!player)
  815. + return false;
  816. +
  817. + if(sWorld->getBoolConfig(CONFIG_ARENA_1V1_BLOCK_FORBIDDEN_TALENTS) == false)
  818. + return true;
  819. +
  820. + uint32 count = 0;
  821. + for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
  822. + {
  823. + TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
  824. +
  825. + if (!talentInfo)
  826. + continue;
  827. +
  828. + for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
  829. + {
  830. + if (talentInfo->RankID[rank] == 0)
  831. + continue;
  832. +
  833. + if (player->HasTalent(talentInfo->RankID[rank], player->GetActiveSpec()))
  834. + {
  835. + for(int8 i = 0; FORBIDDEN_TALENTS_IN_1V1_ARENA[i] != 0; i++)
  836. + if(FORBIDDEN_TALENTS_IN_1V1_ARENA[i] == talentInfo->TalentTab)
  837. + count += rank + 1;
  838. + }
  839. + }
  840. + }
  841. +
  842. + if(count >= 36)
  843. + {
  844. + ChatHandler(player->GetSession()).SendSysMessage("You can't join, because you have invested too many points in a forbidden talent. Please edit your talents.");
  845. + return false;
  846. + }
  847. + else
  848. + return true;
  849. +}
  850. +
  851. +#endif
  852. \ No newline at end of file
  853. diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
  854. index 03400fb..b509026 100644
  855. --- a/src/server/worldserver/worldserver.conf.dist
  856. +++ b/src/server/worldserver/worldserver.conf.dist
  857. @@ -3178,4 +3178,69 @@ Anticheat.DetectionsEnabled = 31
  858. Anticheat.MaxReportsForDailyReport = 70
  859.  
  860. #
  861. +###################################################################################################
  862. +# 1V1 ARENA CONFIG
  863. +#
  864. +# Arena.1v1.Enable
  865. +# Description: Enable the 1v1 arena.
  866. +# Default: 0 - (Disabled)
  867. +# 1 - (Enabled)
  868. +
  869. +Arena.1v1.Enable = 1
  870. +
  871. +#
  872. +# Arena.1v1.Announcer
  873. +# Description: Announce 1v1 arena queue status to chat.
  874. +# Arena.QueueAnnouncer.Enable must be enabled.
  875. +# Default: 0 - (Disabled)
  876. +# 1 - (Enabled)
  877. +
  878. +Arena.1v1.Announcer = 0
  879. +
  880. +#
  881. +# Arena.1v1.MinLevel
  882. +# Description: Min level to create an arena team
  883. +# Default: 80
  884. +
  885. +Arena.1v1.MinLevel = 80
  886. +
  887. +#
  888. +# Arena.1v1.Costs
  889. +# Description: Costs for create an arena team
  890. +# Default: 400000 - (40 gold)
  891. +
  892. +Arena.1v1.Costs = 400000
  893. +
  894. +#
  895. +# Arena.1v1.VendorRating
  896. +# Description: If true, 1v1 rating will use to calculate highest personal-rating (extended costs).
  897. +# Note: The vendor-item will show as not buyable (red), but players can buy it, if enabled and rating is high enough.
  898. +# Default: 0 - (false)
  899. +# 1 - (true)
  900. +
  901. +Arena.1v1.VendorRating = 0
  902. +
  903. +#
  904. +# Arena.1v1.ArenaPointsMulti
  905. +# Description: An 5v5 arena team with 1500 rating will gain 344 points per week (blizzlike).
  906. +# 3v3 with same rating will gain 302 points (5v5points * 0.88)
  907. +# 2v2 will gain 261 points (5v5points * 0.76)
  908. +# and 1v1 will gain 167 points (5v5points * 0.64)
  909. +# With this multiplier you can modify the arenapoints for 1v1.
  910. +# Default: 0.64
  911. +
  912. +Arena.1v1.ArenaPointsMulti = 0.64
  913. +
  914. +#
  915. +# Arena.1v1.BlockForbiddenTalents
  916. +# Description: If true, healers can't join 1v1 arena, if they invested more than 35 talentpoints in a healing-talenttree.
  917. +# You can also block tanks and other talents, if you modify FORBIDDEN_TALENTS_IN_1V1_ARENA in the npc_arena1v1.h file (hardcoding). See TalentTab.dbc for available talents (you will need an DBC-Editor).
  918. +# Default: 1 - (true)
  919. +# 0 - (false)
  920. +
  921. +Arena.1v1.BlockForbiddenTalents = 1
  922. +
  923. +#
  924. +###################################################################################################
  925. +
  926. ###################################################################################################
  927. \ No newline at end of file
  928. --
  929. 2.1.1.1.g1fb337f
Advertisement
Add Comment
Please, Sign In to add comment