[8608] implement BattleGround Alterac Valley

sql won't be included - please look at your database
providers forum

also note, that creature_loot_template id 0
is used for the loot of dead players in this bg
(after a player died and you remove insignia from him..
he not only drops money - he drops some random items too)

further work must be done in better code for adjusting right
levels to creatures - maybe using something similar like it's
done in heroic instances

also quests and creatures needs some scripts in future

thanks to:
netsky - initial start of this patch
bogie - 2nd person writing on this patch
triply, kapatejib, vladimir - code review and suggestions
arrai - for his great tool and help
and all testers / code contributers - I won't write
down a list, else I would forget most probably one ^^
This commit is contained in:
balrok 2009-10-07 11:57:28 +02:00
parent ed5130c1c1
commit 45f6a474bf
20 changed files with 1795 additions and 139 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_8607_02_mangos_command` bit(1) default NULL
`required_8608_02_mangos_battleground_events` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -256,6 +256,175 @@ INSERT INTO battleground_events (map, event1, event2, description) VALUES
(572, 254, 0, 'doors'),
(562, 253, 0, 'buffs'),
(562, 254, 0, 'doors');
-- alterac valley
(30, 254, 0, 'Doors'),
(30, 0, 0, 'Firstaid Station - Alliance assaulted'),
(30, 0, 1, 'Firstaid Station - ALliance control'),
(30, 0, 2, 'Firstaid Station - Horde assaulted'),
(30, 0, 3, 'Firstaid Station - Horde control'),
(30, 1, 0, 'Stormpike Grave - Alliance assaulted'),
(30, 1, 1, 'Stormpike Grave - ALliance control'),
(30, 1, 2, 'Stormpike Grave - Horde assaulted'),
(30, 1, 3, 'Stormpike Grave - Horde control'),
(30, 2, 0, 'Stoneheart Grave - Alliance assaulted'),
(30, 2, 1, 'Stoneheart Grave - ALliance control'),
(30, 2, 2, 'Stoneheart Grave - Horde assaulted'),
(30, 2, 3, 'Stoneheart Grave - Horde control'),
(30, 3, 0, 'Snowfall Grave - Alliance assaulted'),
(30, 3, 1, 'Snowfall Grave - ALliance control'),
(30, 3, 2, 'Snowfall Grave - Horde assaulted'),
(30, 3, 3, 'Snowfall Grave - Horde control'),
(30, 3, 5, 'Snowfall Grave - Neutral control'),
(30, 4, 0, 'Iceblood Grave - Alliance assaulted'),
(30, 4, 1, 'Iceblood Grave - ALliance control'),
(30, 4, 2, 'Iceblood Grave - Horde assaulted'),
(30, 4, 3, 'Iceblood Grave - Horde control'),
(30, 5, 0, 'Frostwolf Grave - Alliance assaulted'),
(30, 5, 1, 'Frostwolf Grave - ALliance control'),
(30, 5, 2, 'Frostwolf Grave - Horde assaulted'),
(30, 5, 3, 'Frostwolf Grave - Horde control'),
(30, 6, 0, 'Frostwolf Hut - Alliance assaulted'),
(30, 6, 1, 'Frostwolf Hut - ALliance control'),
(30, 6, 2, 'Frostwolf Hut - Horde assaulted'),
(30, 6, 3, 'Frostwolf Hut - Horde control'),
(30, 7, 1, 'Dunbaldar South - ALliance control'),
(30, 7, 2, 'Dunbaldar South - Horde assaulted'),
(30, 7, 3, 'Dunbaldar South - Horde control'),
(30, 8, 1, 'Dunbaldar North - ALliance control'),
(30, 8, 2, 'Dunbaldar North - Horde assaulted'),
(30, 8, 3, 'Dunbaldar North - Horde control'),
(30, 9, 1, 'Icewing Bunker - ALliance control'),
(30, 9, 2, 'Icewing Bunker - Horde assaulted'),
(30, 9, 3, 'Icewing Bunker - Horde control'),
(30, 10, 1, 'Stoneheart Bunker - ALliance control'),
(30, 10, 2, 'Stoneheart Bunker - Horde assaulted'),
(30, 10, 3, 'Stoneheart Bunker - Horde control'),
(30, 11, 0, 'Iceblood Tower - Alliance assaulted'),
(30, 11, 1, 'Iceblood Tower - ALliance control'),
(30, 11, 3, 'Iceblood Tower - Horde control'),
(30, 12, 0, 'Tower Point - Alliance assaulted'),
(30, 12, 1, 'Tower Point - ALliance control'),
(30, 12, 3, 'Tower Point - Horde control'),
(30, 13, 0, 'Frostwolf east Tower - Alliance assaulted'),
(30, 13, 1, 'Frostwolf east Tower - ALliance control'),
(30, 13, 3, 'Frostwolf east Tower - Horde control'),
(30, 14, 0, 'Frostwolf west Tower - Alliance assaulted'),
(30, 14, 1, 'Frostwolf west Tower - ALliance control'),
(30, 14, 3, 'Frostwolf west Tower - Horde control'),
(30, 15, 0, 'Firstaid Station - Alliance Defender Quest0'),
(30, 15, 1, 'Firstaid Station - Alliance Defender Quest1'),
(30, 15, 2, 'Firstaid Station - Alliance Defender Quest2'),
(30, 15, 3, 'Firstaid Station - Alliance Defender Quest3'),
(30, 15, 4, 'Firstaid Station - Horde Defender Quest0'),
(30, 15, 5, 'Firstaid Station - Horde Defender Quest1'),
(30, 15, 6, 'Firstaid Station - Horde Defender Quest2'),
(30, 15, 7, 'Firstaid Station - Horde Defender Quest3'),
(30, 16, 0, 'Stormpike Grave - Alliance Defender Quest0'),
(30, 16, 1, 'Stormpike Grave - Alliance Defender Quest1'),
(30, 16, 2, 'Stormpike Grave - Alliance Defender Quest2'),
(30, 16, 3, 'Stormpike Grave - Alliance Defender Quest3'),
(30, 16, 4, 'Stormpike Grave - Horde Defender Quest0'),
(30, 16, 5, 'Stormpike Grave - Horde Defender Quest1'),
(30, 16, 6, 'Stormpike Grave - Horde Defender Quest2'),
(30, 16, 7, 'Stormpike Grave - Horde Defender Quest3'),
(30, 17, 0, 'Stoneheart Grave - Alliance Defender Quest0'),
(30, 17, 1, 'Stoneheart Grave - Alliance Defender Quest1'),
(30, 17, 2, 'Stoneheart Grave - Alliance Defender Quest2'),
(30, 17, 3, 'Stoneheart Grave - Alliance Defender Quest3'),
(30, 17, 4, 'Stoneheart Grave - Horde Defender Quest0'),
(30, 17, 5, 'Stoneheart Grave - Horde Defender Quest1'),
(30, 17, 6, 'Stoneheart Grave - Horde Defender Quest2'),
(30, 17, 7, 'Stoneheart Grave - Horde Defender Quest3'),
(30, 18, 0, 'Snowfall Grave - Alliance Defender Quest0'),
(30, 18, 1, 'Snowfall Grave - Alliance Defender Quest1'),
(30, 18, 2, 'Snowfall Grave - Alliance Defender Quest2'),
(30, 18, 3, 'Snowfall Grave - Alliance Defender Quest3'),
(30, 18, 4, 'Snowfall Grave - Horde Defender Quest0'),
(30, 18, 5, 'Snowfall Grave - Horde Defender Quest1'),
(30, 18, 6, 'Snowfall Grave - Horde Defender Quest2'),
(30, 18, 7, 'Snowfall Grave - Horde Defender Quest3'),
(30, 19, 0, 'Iceblood Grave - Alliance Defender Quest0'),
(30, 19, 1, 'Iceblood Grave - Alliance Defender Quest1'),
(30, 19, 2, 'Iceblood Grave - Alliance Defender Quest2'),
(30, 19, 3, 'Iceblood Grave - Alliance Defender Quest3'),
(30, 19, 4, 'Iceblood Grave - Horde Defender Quest0'),
(30, 19, 5, 'Iceblood Grave - Horde Defender Quest1'),
(30, 19, 6, 'Iceblood Grave - Horde Defender Quest2'),
(30, 19, 7, 'Iceblood Grave - Horde Defender Quest3'),
(30, 20, 0, 'Frostwolf Grave - Alliance Defender Quest0'),
(30, 20, 1, 'Frostwolf Grave - Alliance Defender Quest1'),
(30, 20, 2, 'Frostwolf Grave - Alliance Defender Quest2'),
(30, 20, 3, 'Frostwolf Grave - Alliance Defender Quest3'),
(30, 20, 4, 'Frostwolf Grave - Horde Defender Quest0'),
(30, 20, 5, 'Frostwolf Grave - Horde Defender Quest1'),
(30, 20, 6, 'Frostwolf Grave - Horde Defender Quest2'),
(30, 20, 7, 'Frostwolf Grave - Horde Defender Quest3'),
(30, 21, 0, 'Frostwolf Hut - Alliance Defender Quest0'),
(30, 21, 1, 'Frostwolf Hut - Alliance Defender Quest1'),
(30, 21, 2, 'Frostwolf Hut - Alliance Defender Quest2'),
(30, 21, 3, 'Frostwolf Hut - Alliance Defender Quest3'),
(30, 21, 4, 'Frostwolf Hut - Horde Defender Quest0'),
(30, 21, 5, 'Frostwolf Hut - Horde Defender Quest1'),
(30, 21, 6, 'Frostwolf Hut - Horde Defender Quest2'),
(30, 21, 7, 'Frostwolf Hut - Horde Defender Quest3'),
(30, 46, 0, 'North Mine - Alliance Boss'),
(30, 46, 1, 'North Mine - Horde Boss'),
(30, 46, 2, 'North Mine - Neutral Boss'),
(30, 47, 0, 'South Mine - Alliance Boss'),
(30, 47, 1, 'South Mine - Horde Boss'),
(30, 47, 2, 'South Mine - Neutral Boss'),
(30, 48, 0, 'Alliance Captain'),
(30, 49, 0, 'Horde Captain'),
(30, 50, 0, 'North Mine - Alliance Control'),
(30, 50, 1, 'North Mine - Horde Control'),
(30, 50, 2, 'North Mine - Neutral Control'),
(30, 51, 0, 'South Mine - Alliance Control'),
(30, 51, 1, 'South Mine - Horde Control'),
(30, 51, 2, 'South Mine - Neutral Control'),
(30, 52, 0, 'Alliance Marshal - Dunbaldar South'),
(30, 53, 0, 'Alliance Marshal - Dunbaldar North'),
(30, 54, 0, 'Alliance Marshal - Icewing Bunker'),
(30, 55, 0, 'Alliance Marshal - Stoneheart Bunker'),
(30, 56, 0, 'Horde Marshal - Iceblood Tower'),
(30, 57, 0, 'Horde Marshal - Towerpoint'),
(30, 58, 0, 'Horde Marshal - East Frostwolf Tower'),
(30, 59, 0, 'Horde Marshal - West Frostwolf Tower'),
(30, 60, 0, 'Herald - that guy who yells all the time ;)'),
(30, 61, 0, 'Alliance - Boss'),
(30, 62, 0, 'Horde - Boss'),
(30, 63, 0, 'Alliance - Captain Dead'),
(30, 64, 0, 'Horde - Captain Dead');
/*!40000 ALTER TABLE `battleground_events` ENABLE KEYS */;
UNLOCK TABLES;
@ -3155,6 +3324,40 @@ INSERT INTO `mangos_string` VALUES
(753,'The battle for Warsong Gulch begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(754,'The battle for Arathi Basin begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(755,'The battle begins in 2 minutes.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(757,'Alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(758,'Horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(759,'%s was destroyed by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(760,'The %s is under attack! If left unchecked, the %s will destroy it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(761,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(762,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(763,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(764,'The %s is under attack! If left unchecked, the %s will capture it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(765,'The %s has taken the %s! Its supplies will now be used for reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(766,'Irondeep Mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(767,'Coldtooth Mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(768,'Stormpike Aid Station',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(769,'Dun Baldar South Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(770,'Dun Baldar North Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(771,'Stormpike Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(772,'Icewing Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(773,'Stonehearth Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(774,'Stonehearth Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(775,'Snowfall Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(776,'Iceblood Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(777,'Iceblood Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(778,'Tower Point',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(779,'Frostwolf Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(780,'East Frostwolf Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(781,'West Frostwolf Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(782,'Frostwolf Relief Hut',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(783,'2 minutes until the battle for Alterac Valley begins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(784,'1 minute until the battle for Alterac Valley begins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(785,'30 seconds until the battle for Alterac Valley begins. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(786,'The battle for Alterac Valley has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(787,'The Alliance Team is running out of reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(788,'The Horde Team is running out of reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(789,'The Frostwolf General is Dead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(790,'The Stormpike General is Dead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),

View file

@ -0,0 +1,41 @@
ALTER TABLE db_version CHANGE COLUMN required_8607_02_mangos_command required_8608_01_mangos_mangos_string bit;
DELETE FROM mangos_string WHERE entry>756 and entry<791;
DELETE FROM mangos_string WHERE entry=752 or entry=753;
INSERT INTO mangos_string VALUES
(752,'Only the Alliance can use that portal',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(753,'Only the Horde can use that portal',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(757,'Alliance',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(758,'Horde',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(759,'%s was destroyed by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(760,'The %s is under attack! If left unchecked, the %s will destroy it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(761,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(762,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(763,'The %s was taken by the %s!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(764,'The %s is under attack! If left unchecked, the %s will capture it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(765,'The %s has taken the %s! Its supplies will now be used for reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(766,'Irondeep Mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(767,'Coldtooth Mine',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(768,'Stormpike Aid Station',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(769,'Dun Baldar South Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(770,'Dun Baldar North Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(771,'Stormpike Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(772,'Icewing Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(773,'Stonehearth Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(774,'Stonehearth Bunker',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(775,'Snowfall Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(776,'Iceblood Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(777,'Iceblood Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(778,'Tower Point',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(779,'Frostwolf Graveyard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(780,'East Frostwolf Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(781,'West Frostwolf Tower',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(782,'Frostwolf Relief Hut',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(783,'2 minutes until the battle for Alterac Valley begins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(784,'1 minute until the battle for Alterac Valley begins.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(785,'30 seconds until the battle for Alterac Valley begins. Prepare yourselves!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(786,'The battle for Alterac Valley has begun!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(787,'The Alliance Team is running out of reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(788,'The Horde Team is running out of reinforcements!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(789,'The Frostwolf General is Dead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(790,'The Stormpike General is Dead!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -0,0 +1,182 @@
ALTER TABLE db_version CHANGE COLUMN required_8608_01_mangos_mangos_string required_8608_02_mangos_battleground_events bit;
DELETE FROM battleground_events WHERE map = 30;
INSERT INTO battleground_events (map, event1, event2, description) VALUES
-- alterac valley
(30, 254, 0, 'Doors'),
(30, 0, 0, 'Firstaid Station - Alliance assaulted'),
(30, 0, 1, 'Firstaid Station - ALliance control'),
(30, 0, 2, 'Firstaid Station - Horde assaulted'),
(30, 0, 3, 'Firstaid Station - Horde control'),
(30, 1, 0, 'Stormpike Grave - Alliance assaulted'),
(30, 1, 1, 'Stormpike Grave - ALliance control'),
(30, 1, 2, 'Stormpike Grave - Horde assaulted'),
(30, 1, 3, 'Stormpike Grave - Horde control'),
(30, 2, 0, 'Stoneheart Grave - Alliance assaulted'),
(30, 2, 1, 'Stoneheart Grave - ALliance control'),
(30, 2, 2, 'Stoneheart Grave - Horde assaulted'),
(30, 2, 3, 'Stoneheart Grave - Horde control'),
(30, 3, 0, 'Snowfall Grave - Alliance assaulted'),
(30, 3, 1, 'Snowfall Grave - ALliance control'),
(30, 3, 2, 'Snowfall Grave - Horde assaulted'),
(30, 3, 3, 'Snowfall Grave - Horde control'),
(30, 3, 5, 'Snowfall Grave - Neutral control'),
(30, 4, 0, 'Iceblood Grave - Alliance assaulted'),
(30, 4, 1, 'Iceblood Grave - ALliance control'),
(30, 4, 2, 'Iceblood Grave - Horde assaulted'),
(30, 4, 3, 'Iceblood Grave - Horde control'),
(30, 5, 0, 'Frostwolf Grave - Alliance assaulted'),
(30, 5, 1, 'Frostwolf Grave - ALliance control'),
(30, 5, 2, 'Frostwolf Grave - Horde assaulted'),
(30, 5, 3, 'Frostwolf Grave - Horde control'),
(30, 6, 0, 'Frostwolf Hut - Alliance assaulted'),
(30, 6, 1, 'Frostwolf Hut - ALliance control'),
(30, 6, 2, 'Frostwolf Hut - Horde assaulted'),
(30, 6, 3, 'Frostwolf Hut - Horde control'),
-- (30, 7, 0, 'Dunbaldar South - Alliance assaulted'),
(30, 7, 1, 'Dunbaldar South - ALliance control'),
(30, 7, 2, 'Dunbaldar South - Horde assaulted'),
(30, 7, 3, 'Dunbaldar South - Horde control'),
-- (30, 8, 0, 'Dunbaldar North - Alliance assaulted'),
(30, 8, 1, 'Dunbaldar North - ALliance control'),
(30, 8, 2, 'Dunbaldar North - Horde assaulted'),
(30, 8, 3, 'Dunbaldar North - Horde control'),
-- (30, 9, 0, 'Icewing Bunker - Alliance assaulted'),
(30, 9, 1, 'Icewing Bunker - ALliance control'),
(30, 9, 2, 'Icewing Bunker - Horde assaulted'),
(30, 9, 3, 'Icewing Bunker - Horde control'),
-- (30, 10, 0, 'Stoneheart Bunker - Alliance assaulted'),
(30, 10, 1, 'Stoneheart Bunker - ALliance control'),
(30, 10, 2, 'Stoneheart Bunker - Horde assaulted'),
(30, 10, 3, 'Stoneheart Bunker - Horde control'),
(30, 11, 0, 'Iceblood Tower - Alliance assaulted'),
(30, 11, 1, 'Iceblood Tower - ALliance control'),
-- (30, 11, 2, 'Iceblood Tower - Horde assaulted'),
(30, 11, 3, 'Iceblood Tower - Horde control'),
(30, 12, 0, 'Tower Point - Alliance assaulted'),
(30, 12, 1, 'Tower Point - ALliance control'),
-- (30, 12, 2, 'Tower Point - Horde assaulted'),
(30, 12, 3, 'Tower Point - Horde control'),
(30, 13, 0, 'Frostwolf east Tower - Alliance assaulted'),
(30, 13, 1, 'Frostwolf east Tower - ALliance control'),
-- (30, 13, 2, 'Frostwolf east Tower - Horde assaulted'),
(30, 13, 3, 'Frostwolf east Tower - Horde control'),
(30, 14, 0, 'Frostwolf west Tower - Alliance assaulted'),
(30, 14, 1, 'Frostwolf west Tower - ALliance control'),
-- (30, 14, 2, 'Frostwolf west Tower - Horde assaulted'),
(30, 14, 3, 'Frostwolf west Tower - Horde control'),
(30, 15, 0, 'Firstaid Station - Alliance Defender Quest0'),
(30, 15, 1, 'Firstaid Station - Alliance Defender Quest1'),
(30, 15, 2, 'Firstaid Station - Alliance Defender Quest2'),
(30, 15, 3, 'Firstaid Station - Alliance Defender Quest3'),
(30, 15, 4, 'Firstaid Station - Horde Defender Quest0'),
(30, 15, 5, 'Firstaid Station - Horde Defender Quest1'),
(30, 15, 6, 'Firstaid Station - Horde Defender Quest2'),
(30, 15, 7, 'Firstaid Station - Horde Defender Quest3'),
(30, 16, 0, 'Stormpike Grave - Alliance Defender Quest0'),
(30, 16, 1, 'Stormpike Grave - Alliance Defender Quest1'),
(30, 16, 2, 'Stormpike Grave - Alliance Defender Quest2'),
(30, 16, 3, 'Stormpike Grave - Alliance Defender Quest3'),
(30, 16, 4, 'Stormpike Grave - Horde Defender Quest0'),
(30, 16, 5, 'Stormpike Grave - Horde Defender Quest1'),
(30, 16, 6, 'Stormpike Grave - Horde Defender Quest2'),
(30, 16, 7, 'Stormpike Grave - Horde Defender Quest3'),
(30, 17, 0, 'Stoneheart Grave - Alliance Defender Quest0'),
(30, 17, 1, 'Stoneheart Grave - Alliance Defender Quest1'),
(30, 17, 2, 'Stoneheart Grave - Alliance Defender Quest2'),
(30, 17, 3, 'Stoneheart Grave - Alliance Defender Quest3'),
(30, 17, 4, 'Stoneheart Grave - Horde Defender Quest0'),
(30, 17, 5, 'Stoneheart Grave - Horde Defender Quest1'),
(30, 17, 6, 'Stoneheart Grave - Horde Defender Quest2'),
(30, 17, 7, 'Stoneheart Grave - Horde Defender Quest3'),
(30, 18, 0, 'Snowfall Grave - Alliance Defender Quest0'),
(30, 18, 1, 'Snowfall Grave - Alliance Defender Quest1'),
(30, 18, 2, 'Snowfall Grave - Alliance Defender Quest2'),
(30, 18, 3, 'Snowfall Grave - Alliance Defender Quest3'),
(30, 18, 4, 'Snowfall Grave - Horde Defender Quest0'),
(30, 18, 5, 'Snowfall Grave - Horde Defender Quest1'),
(30, 18, 6, 'Snowfall Grave - Horde Defender Quest2'),
(30, 18, 7, 'Snowfall Grave - Horde Defender Quest3'),
(30, 19, 0, 'Iceblood Grave - Alliance Defender Quest0'),
(30, 19, 1, 'Iceblood Grave - Alliance Defender Quest1'),
(30, 19, 2, 'Iceblood Grave - Alliance Defender Quest2'),
(30, 19, 3, 'Iceblood Grave - Alliance Defender Quest3'),
(30, 19, 4, 'Iceblood Grave - Horde Defender Quest0'),
(30, 19, 5, 'Iceblood Grave - Horde Defender Quest1'),
(30, 19, 6, 'Iceblood Grave - Horde Defender Quest2'),
(30, 19, 7, 'Iceblood Grave - Horde Defender Quest3'),
(30, 20, 0, 'Frostwolf Grave - Alliance Defender Quest0'),
(30, 20, 1, 'Frostwolf Grave - Alliance Defender Quest1'),
(30, 20, 2, 'Frostwolf Grave - Alliance Defender Quest2'),
(30, 20, 3, 'Frostwolf Grave - Alliance Defender Quest3'),
(30, 20, 4, 'Frostwolf Grave - Horde Defender Quest0'),
(30, 20, 5, 'Frostwolf Grave - Horde Defender Quest1'),
(30, 20, 6, 'Frostwolf Grave - Horde Defender Quest2'),
(30, 20, 7, 'Frostwolf Grave - Horde Defender Quest3'),
(30, 21, 0, 'Frostwolf Hut - Alliance Defender Quest0'),
(30, 21, 1, 'Frostwolf Hut - Alliance Defender Quest1'),
(30, 21, 2, 'Frostwolf Hut - Alliance Defender Quest2'),
(30, 21, 3, 'Frostwolf Hut - Alliance Defender Quest3'),
(30, 21, 4, 'Frostwolf Hut - Horde Defender Quest0'),
(30, 21, 5, 'Frostwolf Hut - Horde Defender Quest1'),
(30, 21, 6, 'Frostwolf Hut - Horde Defender Quest2'),
(30, 21, 7, 'Frostwolf Hut - Horde Defender Quest3'),
(30, 46, 0, 'North Mine - Alliance Boss'),
(30, 46, 1, 'North Mine - Horde Boss'),
(30, 46, 2, 'North Mine - Neutral Boss'),
(30, 47, 0, 'South Mine - Alliance Boss'),
(30, 47, 1, 'South Mine - Horde Boss'),
(30, 47, 2, 'South Mine - Neutral Boss'),
(30, 48, 0, 'Alliance Captain'),
(30, 49, 0, 'Horde Captain'),
(30, 50, 0, 'North Mine - Alliance Control'),
(30, 50, 1, 'North Mine - Horde Control'),
(30, 50, 2, 'North Mine - Neutral Control'),
(30, 51, 0, 'South Mine - Alliance Control'),
(30, 51, 1, 'South Mine - Horde Control'),
(30, 51, 2, 'South Mine - Neutral Control'),
(30, 52, 0, 'Alliance Marshal - Dunbaldar South'),
(30, 53, 0, 'Alliance Marshal - Dunbaldar North'),
(30, 54, 0, 'Alliance Marshal - Icewing Bunker'),
(30, 55, 0, 'Alliance Marshal - Stoneheart Bunker'),
(30, 56, 0, 'Horde Marshal - Iceblood Tower'),
(30, 57, 0, 'Horde Marshal - Towerpoint'),
(30, 58, 0, 'Horde Marshal - East Frostwolf Tower'),
(30, 59, 0, 'Horde Marshal - West Frostwolf Tower'),
(30, 60, 0, 'Herald - that guy who yells all the time ;)'),
(30, 61, 0, 'Alliance - Boss'),
(30, 62, 0, 'Horde - Boss'),
(30, 63, 0, 'Alliance - Captain Dead'),
(30, 64, 0, 'Horde - Captain Dead');

View file

@ -132,6 +132,8 @@ pkgdata_DATA = \
8600_01_mangos_command.sql \
8607_01_mangos_string.sql \
8607_02_mangos_command.sql \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
README
## Additional files to include when running 'make dist'
@ -244,4 +246,6 @@ EXTRA_DIST = \
8600_01_mangos_command.sql \
8607_01_mangos_string.sql \
8607_02_mangos_command.sql \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
README

View file

@ -80,6 +80,53 @@ namespace MaNGOS
va_list* i_args;
};
class BattleGroundYellBuilder
{
public:
BattleGroundYellBuilder(uint32 language, int32 textId, Creature const* source, va_list* args = NULL)
: i_language(language), i_textId(textId), i_source(source), i_args(args) {}
void operator()(WorldPacket& data, int32 loc_idx)
{
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
if(i_args)
{
// we need copy va_list before use or original va_list will corrupted
va_list ap;
va_copy(ap,*i_args);
char str [2048];
vsnprintf(str,2048,text, ap );
va_end(ap);
do_helper(data,&str[0]);
}
else
do_helper(data,text);
}
private:
void do_helper(WorldPacket& data, char const* text)
{
//copyied from BuildMonsterChat
data << (uint8)CHAT_MSG_MONSTER_YELL;
data << (uint32)i_language;
data << (uint64)i_source->GetGUID();
data << (uint32)0; //2.1.0
data << (uint32)(strlen(i_source->GetName())+1);
data << i_source->GetName();
data << (uint64)0; //Unit Target - isn't important for bgs
data << (uint32)strlen(text)+1;
data << text;
data << (uint8)0; // ChatTag - for bgs allways 0?
}
uint32 i_language;
int32 i_textId;
Creature const* i_source;
va_list* i_args;
};
class BattleGround2ChatBuilder
{
public:
@ -113,6 +160,40 @@ namespace MaNGOS
int32 i_arg1;
int32 i_arg2;
};
class BattleGround2YellBuilder
{
public:
BattleGround2YellBuilder(uint32 language, int32 textId, Creature const* source, int32 arg1, int32 arg2)
: i_language(language), i_textId(textId), i_source(source), i_arg1(arg1), i_arg2(arg2) {}
void operator()(WorldPacket& data, int32 loc_idx)
{
char const* text = objmgr.GetMangosString(i_textId,loc_idx);
char const* arg1str = i_arg1 ? objmgr.GetMangosString(i_arg1,loc_idx) : "";
char const* arg2str = i_arg2 ? objmgr.GetMangosString(i_arg2,loc_idx) : "";
char str [2048];
snprintf(str,2048,text, arg1str, arg2str );
//copyied from BuildMonsterChat
data << (uint8)CHAT_MSG_MONSTER_YELL;
data << (uint32)i_language;
data << (uint64)i_source->GetGUID();
data << (uint32)0; //2.1.0
data << (uint32)(strlen(i_source->GetName())+1);
data << i_source->GetName();
data << (uint64)0; //Unit Target - isn't important for bgs
data << (uint32)strlen(str)+1;
data << str;
data << (uint8)0; // ChatTag - for bgs allways 0?
}
private:
uint32 i_language;
int32 i_textId;
Creature const* i_source;
int32 i_arg1;
int32 i_arg2;
};
} // namespace MaNGOS
template<class Do>
@ -664,6 +745,12 @@ void BattleGround::EndBattleGround(uint32 winner)
plr->ResurrectPlayer(1.0f);
plr->SpawnCorpseBones();
}
else
{
//needed cause else in av some creatures will kill the players at the end
plr->CombatStop();
plr->getHostilRefManager().deleteReferences();
}
//this line is obsolete - team is set ALWAYS
//if(!team) team = plr->GetTeam();
@ -1381,6 +1468,13 @@ void BattleGround::OnObjectDBLoad(Creature* creature)
SpawnBGCreature(creature->GetGUID(), RESPAWN_ONE_DAY);
}
uint64 BattleGround::GetSingleCreatureGuid(uint8 event1, uint8 event2)
{
BGCreatures::const_iterator itr = m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.begin();
if (itr != m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.end())
return *itr;
return 0;
}
void BattleGround::OnObjectDBLoad(GameObject* obj)
{
@ -1525,6 +1619,16 @@ void BattleGround::SendMessageToAll(int32 entry, ChatMsg type, Player const* sou
BroadcastWorker(bg_do);
}
void BattleGround::SendYellToAll(int32 entry, uint32 language, uint64 const& guid)
{
Creature* source = GetBgMap()->GetCreature(guid);
if(!source)
return;
MaNGOS::BattleGroundYellBuilder bg_builder(language, entry, source);
MaNGOS::LocalizedPacketDo<MaNGOS::BattleGroundYellBuilder> bg_do(bg_builder);
BroadcastWorker(bg_do);
}
void BattleGround::PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...)
{
va_list ap;
@ -1544,6 +1648,16 @@ void BattleGround::SendMessage2ToAll(int32 entry, ChatMsg type, Player const* so
BroadcastWorker(bg_do);
}
void BattleGround::SendYell2ToAll(int32 entry, uint32 language, uint64 const& guid, int32 arg1, int32 arg2)
{
Creature* source = GetBgMap()->GetCreature(guid);
if(!source)
return;
MaNGOS::BattleGround2YellBuilder bg_builder(language, entry, source, arg1, arg2);
MaNGOS::LocalizedPacketDo<MaNGOS::BattleGround2YellBuilder> bg_do(bg_builder);
BroadcastWorker(bg_do);
}
void BattleGround::EndNow()
{
RemoveFromBGFreeSlotQueue();
@ -1604,8 +1718,6 @@ void BattleGround::HandleTriggerBuff(uint64 const& go_guid)
void BattleGround::HandleKillPlayer( Player *player, Player *killer )
{
//keep in mind that for arena this will have to be changed a bit
// add +1 deaths
UpdatePlayerScore(player, SCORE_DEATHS, 1);

View file

@ -198,10 +198,7 @@ enum ScoreType
SCORE_GRAVEYARDS_DEFENDED = 12,
SCORE_TOWERS_ASSAULTED = 13,
SCORE_TOWERS_DEFENDED = 14,
SCORE_MINES_CAPTURED = 15,
SCORE_LEADERS_KILLED = 16,
SCORE_SECONDARY_OBJECTIVES = 17
// TODO : implement them
SCORE_SECONDARY_OBJECTIVES = 15
};
enum ArenaType
@ -439,10 +436,12 @@ class BattleGround
void BlockMovement(Player *plr);
void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL);
void SendYellToAll(int32 entry, uint32 language, uint64 const& guid);
void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ... );
// specialized version with 2 string id args
void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0);
void SendYell2ToAll(int32 entry, uint32 language, uint64 const& guid, int32 arg1, int32 arg2);
/* Raid Group */
Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
@ -473,6 +472,7 @@ class BattleGround
virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {}
// must be implemented in BG subclass if need AND call base class generic code
virtual void HandleKillPlayer(Player *player, Player *killer);
virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/) { return; };
/* Battleground events */
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
@ -505,10 +505,14 @@ class BattleGround
return false;
return m_ActiveEvents[event1] == event2;
}
uint64 GetSingleCreatureGuid(uint8 event1, uint8 event2);
void OpenDoorEvent(uint8 event1, uint8 event2 = 0);
bool IsDoor(uint8 event1, uint8 event2);
/* other things */
virtual void OnCreatureRespawn(Creature* /*creature*/) {}
void HandleTriggerBuff(uint64 const& go_guid);
// TODO: make this protected:

View file

@ -191,20 +191,17 @@ void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
switch(Trigger)
{
case 3948: // Arathi Basin Alliance Exit.
if (Source->GetTeam() != ALLIANCE)
Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
Source->GetSession()->SendNotification(LANG_BATTLEGROUND_ONLY_ALLIANCE_USE);
else
Source->LeaveBattleground();
break;
case 3949: // Arathi Basin Horde Exit.
if (Source->GetTeam() != HORDE)
Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
Source->GetSession()->SendNotification(LANG_BATTLEGROUND_ONLY_HORDE_USE);
else
Source->LeaveBattleground();
break;

View file

@ -16,38 +16,288 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Object.h"
#include "Player.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
#include "BattleGroundMgr.h"
#include "Creature.h"
#include "GameObject.h"
#include "Language.h"
#include "WorldPacket.h"
BattleGroundAV::BattleGroundAV()
{
//TODO FIX ME!
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AV_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AV_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AV_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AV_HAS_BEGUN;
}
BattleGroundAV::~BattleGroundAV()
{
}
void BattleGroundAV::HandleKillPlayer(Player *player, Player *killer)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
BattleGround::HandleKillPlayer(player, killer);
UpdateScore(GetTeamIndexByTeamId(player->GetTeam()), -1);
}
void BattleGroundAV::HandleKillUnit(Creature *creature, Player *killer)
{
sLog.outDebug("BattleGroundAV: HandleKillUnit %i", creature->GetEntry());
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint8 event1 = (sBattleGroundMgr.GetCreatureEventIndex(creature->GetDBTableGUIDLow())).event1;
if (event1 == BG_EVENT_NONE)
return;
switch(event1)
{
case BG_AV_BOSS_A:
CastSpellOnTeam(BG_AV_BOSS_KILL_QUEST_SPELL, HORDE); // this is a spell which finishes a quest where a player has to kill the boss
RewardReputationToTeam(BG_AV_FACTION_H, m_RepBoss, HORDE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE);
SendYellToAll(LANG_BG_AV_H_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
EndBattleGround(HORDE);
break;
case BG_AV_BOSS_H:
CastSpellOnTeam(BG_AV_BOSS_KILL_QUEST_SPELL, ALLIANCE); // this is a spell which finishes a quest where a player has to kill the boss
RewardReputationToTeam(BG_AV_FACTION_A, m_RepBoss, ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE);
SendYellToAll(LANG_BG_AV_A_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
EndBattleGround(ALLIANCE);
break;
case BG_AV_CAPTAIN_A:
if (IsActiveEvent(BG_AV_NodeEventCaptainDead_A, 0))
return;
RewardReputationToTeam(BG_AV_FACTION_H, m_RepCaptain, HORDE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), HORDE);
UpdateScore(BG_TEAM_ALLIANCE, (-1) * BG_AV_RES_CAPTAIN);
// spawn destroyed aura
SpawnEvent(BG_AV_NodeEventCaptainDead_A, 0, true);
break;
case BG_AV_CAPTAIN_H:
if (IsActiveEvent(BG_AV_NodeEventCaptainDead_H, 0))
return;
RewardReputationToTeam(BG_AV_FACTION_A, m_RepCaptain, ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_CAPTAIN), ALLIANCE);
UpdateScore(BG_TEAM_HORDE, (-1) * BG_AV_RES_CAPTAIN);
// spawn destroyed aura
SpawnEvent(BG_AV_NodeEventCaptainDead_H, 0, true);
break;
case BG_AV_MINE_BOSSES_NORTH:
ChangeMineOwner(BG_AV_NORTH_MINE, GetTeamIndexByTeamId(killer->GetTeam()));
break;
case BG_AV_MINE_BOSSES_SOUTH:
ChangeMineOwner(BG_AV_SOUTH_MINE, GetTeamIndexByTeamId(killer->GetTeam()));
break;
}
}
void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint8 team = GetTeamIndexByTeamId(player->GetTeam());
uint32 reputation = 0; // reputation for the whole team (other reputation must be done in db)
// TODO add events (including quest not available anymore, next quest availabe, go/npc de/spawning)
sLog.outError("BattleGroundAV: Quest %i completed", questid);
switch(questid)
{
case BG_AV_QUEST_A_SCRAPS1:
case BG_AV_QUEST_A_SCRAPS2:
case BG_AV_QUEST_H_SCRAPS1:
case BG_AV_QUEST_H_SCRAPS2:
m_Team_QuestStatus[team][0] += 20;
reputation = 1;
if( m_Team_QuestStatus[team][0] == 500 || m_Team_QuestStatus[team][0] == 1000 || m_Team_QuestStatus[team][0] == 1500 ) //25,50,75 turn ins
{
sLog.outDebug("BattleGroundAV: Quest %i completed starting with unit upgrading..", questid);
for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i)
if (m_Nodes[i].Owner == team && m_Nodes[i].State == POINT_CONTROLLED)
PopulateNode(i);
}
break;
case BG_AV_QUEST_A_COMMANDER1:
case BG_AV_QUEST_H_COMMANDER1:
m_Team_QuestStatus[team][1]++;
reputation = 1;
if (m_Team_QuestStatus[team][1] == 120)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
break;
case BG_AV_QUEST_A_COMMANDER2:
case BG_AV_QUEST_H_COMMANDER2:
m_Team_QuestStatus[team][2]++;
reputation = 2;
if (m_Team_QuestStatus[team][2] == 60)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
break;
case BG_AV_QUEST_A_COMMANDER3:
case BG_AV_QUEST_H_COMMANDER3:
m_Team_QuestStatus[team][3]++;
reputation = 5;
RewardReputationToTeam(team, 1, player->GetTeam());
if (m_Team_QuestStatus[team][1] == 30)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
break;
case BG_AV_QUEST_A_BOSS1:
case BG_AV_QUEST_H_BOSS1:
m_Team_QuestStatus[team][4] += 4; // there are 2 quests where you can turn in 5 or 1 item.. ( + 4 cause +1 will be done some lines below)
reputation = 4;
case BG_AV_QUEST_A_BOSS2:
case BG_AV_QUEST_H_BOSS2:
m_Team_QuestStatus[team][4]++;
reputation += 1;
if (m_Team_QuestStatus[team][4] >= 200)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
break;
case BG_AV_QUEST_A_NEAR_MINE:
case BG_AV_QUEST_H_NEAR_MINE:
m_Team_QuestStatus[team][5]++;
reputation = 2;
if (m_Team_QuestStatus[team][5] == 28)
{
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
if (m_Team_QuestStatus[team][6] == 7)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here - ground assault ready", questid);
}
break;
case BG_AV_QUEST_A_OTHER_MINE:
case BG_AV_QUEST_H_OTHER_MINE:
m_Team_QuestStatus[team][6]++;
reputation = 3;
if (m_Team_QuestStatus[team][6] == 7)
{
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
if (m_Team_QuestStatus[team][5] == 20)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here - ground assault ready", questid);
}
break;
case BG_AV_QUEST_A_RIDER_HIDE:
case BG_AV_QUEST_H_RIDER_HIDE:
m_Team_QuestStatus[team][7]++;
reputation = 1;
if (m_Team_QuestStatus[team][7] == 25)
{
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
if (m_Team_QuestStatus[team][8] == 25)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here - rider assault ready", questid);
}
break;
case BG_AV_QUEST_A_RIDER_TAME:
case BG_AV_QUEST_H_RIDER_TAME:
m_Team_QuestStatus[team][8]++;
reputation = 1;
if (m_Team_QuestStatus[team][8] == 25)
{
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here", questid);
if (m_Team_QuestStatus[team][7] == 25)
sLog.outDebug("BattleGroundAV: Quest %i completed (need to implement some events here - rider assault ready", questid);
}
break;
default:
sLog.outDebug("BattleGroundAV: Quest %i completed but is not interesting for us", questid);
return;
break;
}
if (reputation)
RewardReputationToTeam((player->GetTeam() == ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, reputation, player->GetTeam());
}
void BattleGroundAV::UpdateScore(BattleGroundTeamId team, int32 points )
{
// note: to remove reinforcements points must be negative, for adding reinforcements points must be positive
assert( team == BG_TEAM_ALLIANCE || team == BG_TEAM_HORDE);
m_TeamScores[team] += points; // m_TeamScores is int32 - so no problems here
if (points < 0)
{
if (m_TeamScores[team] < 1)
{
m_TeamScores[team] = 0;
// other team will win:
EndBattleGround((team == BG_TEAM_ALLIANCE)? HORDE : ALLIANCE);
}
else if (!m_IsInformedNearLose[team] && m_TeamScores[team] < BG_AV_SCORE_NEAR_LOSE)
{
SendMessageToAll((team == BG_TEAM_HORDE) ? LANG_BG_AV_H_NEAR_LOSE : LANG_BG_AV_A_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
PlaySoundToAll(BG_AV_SOUND_NEAR_LOSE);
m_IsInformedNearLose[team] = true;
}
}
// must be called here, else it could display a negative value
UpdateWorldState(((team == BG_TEAM_HORDE) ? BG_AV_Horde_Score : BG_AV_Alliance_Score), m_TeamScores[team]);
}
void BattleGroundAV::OnObjectDBLoad(Creature* creature)
{
uint32 level = creature->getLevel();
if (level != 0)
level += GetMaxLevel() - 60; // maybe we can do this more generic for custom level - range.. actually it's ok
creature->SetLevel(level);
BattleGround::OnObjectDBLoad(creature);
}
void BattleGroundAV::OnCreatureRespawn(Creature* creature)
{
uint32 level = creature->getLevel();
if (level != 0)
level += GetMaxLevel() - 60; // maybe we can do this more generic for custom level - range.. actually it's ok
creature->SetLevel(level);
}
void BattleGroundAV::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() != STATUS_IN_PROGRESS)
return;
// add points from mine owning, and look if the neutral team can reclaim the mine
for(uint8 mine = 0; mine < BG_AV_MAX_MINES; mine++)
{
if (m_Mine_Owner[mine] == BG_TEAM_ALLIANCE || m_Mine_Owner[mine] == BG_TEAM_HORDE)
{
m_Mine_Timer[mine] -=diff;
if (m_Mine_Timer[mine] <= 0)
{
UpdateScore(BattleGroundTeamId(m_Mine_Owner[mine]), 1);
m_Mine_Timer[mine] = BG_AV_MINE_TICK_TIMER;
}
if (m_Mine_Reclaim_Timer[mine] > diff)
m_Mine_Reclaim_Timer[mine] -= diff;
else
ChangeMineOwner(mine, BG_AV_NEUTRAL_TEAM);
}
}
// looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team
for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
{
if (m_Nodes[i].State == POINT_ASSAULTED)
{
if (m_Nodes[i].Timer > diff)
m_Nodes[i].Timer -= diff;
else
EventPlayerDestroyedPoint(i);
}
}
}
void BattleGroundAV::StartingEventCloseDoors()
{
sLog.outDebug("BattleGroundAV: entering state STATUS_WAIT_JOIN ...");
}
void BattleGroundAV::StartingEventOpenDoors()
{
UpdateWorldState(BG_AV_SHOW_H_SCORE, 1);
UpdateWorldState(BG_AV_SHOW_A_SCORE, 1);
OpenDoorEvent(BG_EVENT_DOOR);
}
void BattleGroundAV::AddPlayer(Player *plr)
@ -55,42 +305,101 @@ void BattleGroundAV::AddPlayer(Player *plr)
BattleGround::AddPlayer(plr);
// create score and add it to map, default values are set in constructor
BattleGroundAVScore* sc = new BattleGroundAVScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundAV::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
void BattleGroundAV::EndBattleGround(uint32 winner)
{
// calculate bonuskills for both teams:
uint32 tower_survived[BG_TEAMS_COUNT] = {0, 0};
uint32 graves_owned[BG_TEAMS_COUNT] = {0, 0};
uint32 mines_owned[BG_TEAMS_COUNT] = {0, 0};
// towers all not destroyed:
for(BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i)
if (m_Nodes[i].State == POINT_CONTROLLED)
if (m_Nodes[i].TotalOwner == BG_TEAM_ALLIANCE)
++tower_survived[BG_TEAM_ALLIANCE];
for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i)
if (m_Nodes[i].State == POINT_CONTROLLED)
if (m_Nodes[i].TotalOwner == BG_TEAM_HORDE)
++tower_survived[BG_TEAM_HORDE];
// graves all controlled
for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
if (m_Nodes[i].State == POINT_CONTROLLED)
++graves_owned[m_Nodes[i].Owner];
for (uint32 i = 0; i < BG_AV_MAX_MINES; ++i)
if (m_Mine_Owner[i] != BG_AV_NEUTRAL_TEAM)
++mines_owned[m_Mine_Owner[i]];
// now we have the values give the honor/reputation to the teams:
uint32 team[BG_TEAMS_COUNT] = { ALLIANCE, HORDE };
uint32 faction[BG_TEAMS_COUNT] = { BG_AV_FACTION_A, BG_AV_FACTION_H };
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{
if (tower_survived[i])
{
RewardReputationToTeam(faction[i], tower_survived[i] * m_RepSurviveTower, team[i]);
RewardHonorToTeam(GetBonusHonorFromKill(tower_survived[i] * BG_AV_KILL_SURVIVING_TOWER), team[i]);
}
sLog.outDebug("BattleGroundAV: EndbattleGround: bgteam: %u towers:%u honor:%u rep:%u", i, tower_survived[i], GetBonusHonorFromKill(tower_survived[i] * BG_AV_KILL_SURVIVING_TOWER), tower_survived[i] * BG_AV_REP_SURVIVING_TOWER);
if (graves_owned[i])
RewardReputationToTeam(faction[i], graves_owned[i] * m_RepOwnedGrave, team[i]);
if (mines_owned[i])
RewardReputationToTeam(faction[i], mines_owned[i] * m_RepOwnedMine, team[i]);
// captain survived?:
if (!IsActiveEvent(BG_AV_NodeEventCaptainDead_A + GetTeamIndexByTeamId(team[i]), 0))
{
RewardReputationToTeam(faction[i], m_RepSurviveCaptain, team[i]);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_SURVIVING_CAPTAIN), team[i]);
}
}
// both teams:
if (m_HonorMapComplete)
{
RewardHonorToTeam(m_HonorMapComplete, ALLIANCE);
RewardHonorToTeam(m_HonorMapComplete, HORDE);
}
BattleGround::EndBattleGround(winner);
}
void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/)
{
}
void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint32 SpellId = 0;
switch(Trigger)
{
case 95:
case 2606:
case 2608:
if (Source->GetTeam() != ALLIANCE)
Source->GetSession()->SendNotification(LANG_BATTLEGROUND_ONLY_ALLIANCE_USE);
else
Source->LeaveBattleground();
break;
case 2606:
if (Source->GetTeam() != HORDE)
Source->GetSession()->SendNotification(LANG_BATTLEGROUND_ONLY_HORDE_USE);
else
Source->LeaveBattleground();
break;
case 3326:
case 3327:
case 3328:
case 3329:
case 3330:
case 3331:
//Source->Unmount();
break;
default:
sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
sLog.outDebug("BattleGroundAV: WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);
// Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
if (SpellId)
Source->CastSpell(Source, SpellId, true);
}
void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
@ -114,12 +423,6 @@ void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
case SCORE_TOWERS_DEFENDED:
((BattleGroundAVScore*)itr->second)->TowersDefended += value;
break;
case SCORE_MINES_CAPTURED:
((BattleGroundAVScore*)itr->second)->MinesCaptured += value;
break;
case SCORE_LEADERS_KILLED:
((BattleGroundAVScore*)itr->second)->LeadersKilled += value;
break;
case SCORE_SECONDARY_OBJECTIVES:
((BattleGroundAVScore*)itr->second)->SecondaryObjectives += value;
break;
@ -128,3 +431,411 @@ void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
break;
}
}
void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
{
sLog.outDebug("BattleGroundAV: player destroyed point node %i", node);
// despawn banner
DestroyNode(node);
PopulateNode(node);
UpdateNodeWorldState(node);
uint32 owner = m_Nodes[node].Owner;
if (IsTower(node))
{
uint8 tmp = node - BG_AV_NODES_DUNBALDAR_SOUTH;
// despawn marshal (one of those guys protecting the boss)
SpawnEvent(BG_AV_MARSHAL_A_SOUTH + tmp, 0, false);
UpdateScore(BattleGroundTeamId(owner^0x1), (-1) * BG_AV_RES_TOWER);
RewardReputationToTeam((owner == BG_TEAM_ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, m_RepTowerDestruction, owner);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner);
SendYell2ToAll(LANG_BG_AV_TOWER_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( owner == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE);
}
else
{
SendYell2ToAll(LANG_BG_AV_GRAVE_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( owner == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE);
}
}
void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team)
{
m_Mine_Timer[mine] = BG_AV_MINE_TICK_TIMER;
// TODO implement quest 7122
// mine=0 northmine, mine=1 southmine
// TODO changing the owner should result in setting respawntime to infinite for current creatures (they should fight the new ones), spawning new mine owners creatures and changing the chest - objects so that the current owning team can use them
assert(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE);
if (m_Mine_Owner[mine] == int8(team))
return;
if (team != BG_TEAM_ALLIANCE && team != BG_TEAM_HORDE)
team = BG_AV_NEUTRAL_TEAM;
m_Mine_PrevOwner[mine] = m_Mine_Owner[mine];
m_Mine_Owner[mine] = team;
SendMineWorldStates(mine);
SpawnEvent(BG_AV_MINE_EVENT + mine, team, true);
SpawnEvent(BG_AV_MINE_BOSSES + mine, team, true);
if (team == BG_TEAM_ALLIANCE || team == BG_TEAM_HORDE)
{
PlaySoundToAll((team == BG_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_GOOD : BG_AV_SOUND_HORDE_GOOD);
m_Mine_Reclaim_Timer[mine] = BG_AV_MINE_RECLAIM_TIMER;
SendYell2ToAll(LANG_BG_AV_MINE_TAKEN , LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
(team == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE,
(mine == BG_AV_NORTH_MINE) ? LANG_BG_AV_MINE_NORTH : LANG_BG_AV_MINE_SOUTH);
}
}
bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId, uint32 team)
{
if (GOId == BG_AV_OBJECTID_MINE_N)
return (m_Mine_Owner[BG_AV_NORTH_MINE] == GetTeamIndexByTeamId(team));
if (GOId == BG_AV_OBJECTID_MINE_S)
return (m_Mine_Owner[BG_AV_SOUTH_MINE] == GetTeamIndexByTeamId(team));
return true; // cause it's no mine'object it is ok if this is true
}
/// will spawn and despawn creatures around a node
/// more a wrapper around spawnevent cause graveyards are special
void BattleGroundAV::PopulateNode(BG_AV_Nodes node)
{
uint32 team = m_Nodes[node].Owner;
if (IsGrave(node) && team != BG_AV_NEUTRAL_TEAM)
{
uint32 graveDefenderType;
if (m_Team_QuestStatus[team][0] < 500 )
graveDefenderType = 0;
else if (m_Team_QuestStatus[team][0] < 1000 )
graveDefenderType = 1;
else if (m_Team_QuestStatus[team][0] < 1500 )
graveDefenderType = 2;
else
graveDefenderType = 3;
if (m_Nodes[node].State == POINT_CONTROLLED) // we can spawn the current owner event
SpawnEvent(BG_AV_NODES_MAX + node, team * BG_AV_MAX_GRAVETYPES + graveDefenderType, true);
else // we despawn the event from the prevowner
SpawnEvent(BG_AV_NODES_MAX + node, m_Nodes[node].PrevOwner * BG_AV_MAX_GRAVETYPES + graveDefenderType, false);
}
SpawnEvent(node, (team * BG_AV_MAX_STATES) + m_Nodes[node].State, true);
}
/// called when using a banner
void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target_obj)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
sLog.outDebug("BattleGroundAV: using gameobject %i", target_obj->GetEntry());
uint8 event = (sBattleGroundMgr.GetGameObjectEventIndex(target_obj->GetDBTableGUIDLow())).event1;
if (event >= BG_AV_NODES_MAX) // not a node
return;
BG_AV_Nodes node = BG_AV_Nodes(event);
switch ((sBattleGroundMgr.GetGameObjectEventIndex(target_obj->GetDBTableGUIDLow())).event2 % BG_AV_MAX_STATES)
{
case POINT_CONTROLLED:
EventPlayerAssaultsPoint(source, node);
break;
case POINT_ASSAULTED:
EventPlayerDefendsPoint(source, node);
break;
default:
break;
}
}
void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node)
{
assert(GetStatus() == STATUS_IN_PROGRESS);
uint32 team = GetTeamIndexByTeamId(player->GetTeam());
if (m_Nodes[node].Owner == team || m_Nodes[node].State != POINT_ASSAULTED)
return;
if( m_Nodes[node].TotalOwner == BG_AV_NEUTRAL_TEAM ) // initial snowfall capture
{
// until snowfall doesn't belong to anyone it is better handled in assault - code (best would be to have a special function
// for neutral nodes.. but doing this just for snowfall will be a bit to much i think
assert(node == BG_AV_NODES_SNOWFALL_GRAVE); // currently the only neutral grave
EventPlayerAssaultsPoint(player, node);
return;
}
sLog.outDebug("BattleGroundAV: player defends node: %i", node);
if (m_Nodes[node].PrevOwner != team)
{
sLog.outError("BattleGroundAV: player defends point which doesn't belong to his team %i", node);
return;
}
DefendNode(node, team); // set the right variables for nodeinfo
PopulateNode(node); // spawn node-creatures (defender for example)
UpdateNodeWorldState(node); // send new mapicon to the player
if (IsTower(node))
{
SendYell2ToAll( LANG_BG_AV_TOWER_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
GetNodeName(node),
( team == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY:LANG_BG_AV_HORDE);
UpdatePlayerScore(player, SCORE_TOWERS_DEFENDED, 1);
PlaySoundToAll(BG_AV_SOUND_BOTH_TOWER_DEFEND);
}
else
{
SendYell2ToAll(LANG_BG_AV_GRAVE_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
GetNodeName(node),
( team == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY:LANG_BG_AV_HORDE);
UpdatePlayerScore(player, SCORE_GRAVEYARDS_DEFENDED, 1);
// update the statistic for the defending player
PlaySoundToAll((team == BG_TEAM_ALLIANCE)?BG_AV_SOUND_ALLIANCE_GOOD:BG_AV_SOUND_HORDE_GOOD);
}
}
void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node)
{
// TODO implement quest 7101, 7081
uint32 team = GetTeamIndexByTeamId(player->GetTeam());
sLog.outDebug("BattleGroundAV: player assaults node %i", node);
if (m_Nodes[node].Owner == team || team == m_Nodes[node].TotalOwner)
return;
AssaultNode(node, team); // update nodeinfo variables
UpdateNodeWorldState(node); // send mapicon
PopulateNode(node);
if (IsTower(node))
{
SendYell2ToAll(LANG_BG_AV_TOWER_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
GetNodeName(node),
( team == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY:LANG_BG_AV_HORDE);
UpdatePlayerScore(player, SCORE_GRAVEYARDS_ASSAULTED, 1);
}
else
{
SendYell2ToAll(LANG_BG_AV_GRAVE_ASSAULTED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
GetNodeName(node),
( team == BG_TEAM_ALLIANCE ) ? LANG_BG_AV_ALLY:LANG_BG_AV_HORDE);
// update the statistic for the assaulting player
UpdatePlayerScore(player, SCORE_GRAVEYARDS_ASSAULTED, 1);
}
PlaySoundToAll((team == BG_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_ASSAULTS : BG_AV_SOUND_HORDE_ASSAULTS);
}
void BattleGroundAV::FillInitialWorldStates(WorldPacket& data)
{
bool stateok;
for (uint32 i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
{
for (uint8 j = 0; j < BG_AV_MAX_STATES; j++)
{
stateok = (m_Nodes[i].State == j);
data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, BG_TEAM_ALLIANCE)]) << uint32((m_Nodes[i].Owner == BG_TEAM_ALLIANCE && stateok) ? 1 : 0);
data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j, BG_TEAM_HORDE)]) << uint32((m_Nodes[i].Owner == BG_TEAM_HORDE && stateok) ? 1 : 0);
}
}
if( m_Nodes[BG_AV_NODES_SNOWFALL_GRAVE].Owner == BG_AV_NEUTRAL_TEAM ) // cause neutral teams aren't handled generic
data << uint32(AV_SNOWFALL_N) << uint32(1);
data << uint32(BG_AV_Alliance_Score) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]);
data << uint32(BG_AV_Horde_Score) << uint32(m_TeamScores[BG_TEAM_HORDE]);
if( GetStatus() == STATUS_IN_PROGRESS ) // only if game is running the teamscores are displayed
{
data << uint32(BG_AV_SHOW_A_SCORE) << uint32(1);
data << uint32(BG_AV_SHOW_H_SCORE) << uint32(1);
}
else
{
data << uint32(BG_AV_SHOW_A_SCORE) << uint32(0);
data << uint32(BG_AV_SHOW_H_SCORE) << uint32(0);
}
SendMineWorldStates(BG_AV_NORTH_MINE);
SendMineWorldStates(BG_AV_SOUTH_MINE);
}
void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node)
{
UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].State,m_Nodes[node].Owner)], 1);
if( m_Nodes[node].PrevOwner == BG_AV_NEUTRAL_TEAM ) // currently only snowfall is supported as neutral node
UpdateWorldState(AV_SNOWFALL_N, 0);
else
UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].PrevState,m_Nodes[node].PrevOwner)], 0);
}
void BattleGroundAV::SendMineWorldStates(uint32 mine)
{
assert(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE);
assert(m_Mine_PrevOwner[mine] == BG_TEAM_ALLIANCE || m_Mine_PrevOwner[mine] == BG_TEAM_HORDE || m_Mine_PrevOwner[mine] == BG_AV_NEUTRAL_TEAM);
assert(m_Mine_Owner[mine] == BG_TEAM_ALLIANCE || m_Mine_Owner[mine] == BG_TEAM_HORDE || m_Mine_Owner[mine] == BG_AV_NEUTRAL_TEAM);
UpdateWorldState(BG_AV_MineWorldStates[mine][m_Mine_Owner[mine]], 1);
if (m_Mine_Owner[mine] != m_Mine_PrevOwner[mine])
UpdateWorldState(BG_AV_MineWorldStates[mine][m_Mine_PrevOwner[mine]], 0);
}
WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(Player *plr)
{
float x = plr->GetPositionX();
float y = plr->GetPositionY();
uint32 team = GetTeamIndexByTeamId(plr->GetTeam());
WorldSafeLocsEntry const* good_entry = NULL;
if (GetStatus() == STATUS_IN_PROGRESS)
{
// Is there any occupied node for this team?
float mindist = 9999999.0f;
for(uint8 i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i)
{
if (m_Nodes[i].Owner != team || m_Nodes[i].State != POINT_CONTROLLED)
continue;
WorldSafeLocsEntry const * entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[i] );
if (!entry)
continue;
float dist = (entry->x - x) * (entry->x - x) + (entry->y - y) * (entry->y - y);
if (mindist > dist)
{
mindist = dist;
good_entry = entry;
}
}
}
// If not, place ghost in the starting-cave
if (!good_entry)
good_entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[team + 7] );
return good_entry;
}
uint32 BattleGroundAV::GetNodeName(BG_AV_Nodes node)
{
switch (node)
{
case BG_AV_NODES_FIRSTAID_STATION: return LANG_BG_AV_NODE_GRAVE_STORM_AID;
case BG_AV_NODES_DUNBALDAR_SOUTH: return LANG_BG_AV_NODE_TOWER_DUN_S;
case BG_AV_NODES_DUNBALDAR_NORTH: return LANG_BG_AV_NODE_TOWER_DUN_N;
case BG_AV_NODES_STORMPIKE_GRAVE: return LANG_BG_AV_NODE_GRAVE_STORMPIKE;
case BG_AV_NODES_ICEWING_BUNKER: return LANG_BG_AV_NODE_TOWER_ICEWING;
case BG_AV_NODES_STONEHEART_GRAVE: return LANG_BG_AV_NODE_GRAVE_STONE;
case BG_AV_NODES_STONEHEART_BUNKER: return LANG_BG_AV_NODE_TOWER_STONE;
case BG_AV_NODES_SNOWFALL_GRAVE: return LANG_BG_AV_NODE_GRAVE_SNOW;
case BG_AV_NODES_ICEBLOOD_TOWER: return LANG_BG_AV_NODE_TOWER_ICE;
case BG_AV_NODES_ICEBLOOD_GRAVE: return LANG_BG_AV_NODE_GRAVE_ICE;
case BG_AV_NODES_TOWER_POINT: return LANG_BG_AV_NODE_TOWER_POINT;
case BG_AV_NODES_FROSTWOLF_GRAVE: return LANG_BG_AV_NODE_GRAVE_FROST;
case BG_AV_NODES_FROSTWOLF_ETOWER: return LANG_BG_AV_NODE_TOWER_FROST_E;
case BG_AV_NODES_FROSTWOLF_WTOWER: return LANG_BG_AV_NODE_TOWER_FROST_W;
case BG_AV_NODES_FROSTWOLF_HUT: return LANG_BG_AV_NODE_GRAVE_FROST_HUT;
default: return 0; break;
}
}
void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint32 team)
{
assert(team < 3); // alliance:0, horde:1, neutral:2
assert(m_Nodes[node].TotalOwner != team);
assert(m_Nodes[node].Owner != team);
assert(m_Nodes[node].State != POINT_ASSAULTED || !m_Nodes[node].TotalOwner ); // only assault an assaulted node if no totalowner exists
// the timer gets another time, if the previous owner was 0 == Neutral
m_Nodes[node].Timer = (m_Nodes[node].PrevOwner != BG_AV_NEUTRAL_TEAM) ? BG_AV_CAPTIME : BG_AV_SNOWFALL_FIRSTCAP;
m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
m_Nodes[node].Owner = team;
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = POINT_ASSAULTED;
}
void BattleGroundAV::DestroyNode(BG_AV_Nodes node)
{
assert(m_Nodes[node].State == POINT_ASSAULTED);
m_Nodes[node].TotalOwner = m_Nodes[node].Owner;
m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = POINT_CONTROLLED;
m_Nodes[node].Timer = 0;
}
void BattleGroundAV::InitNode(BG_AV_Nodes node, uint32 team, bool tower)
{
assert(team < 3); // alliance:0, horde:1, neutral:2
m_Nodes[node].TotalOwner = team;
m_Nodes[node].Owner = team;
m_Nodes[node].PrevOwner = team;
m_Nodes[node].State = POINT_CONTROLLED;
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = POINT_CONTROLLED;
m_Nodes[node].Timer = 0;
m_Nodes[node].Tower = tower;
m_ActiveEvents[node] = team * BG_AV_MAX_STATES + m_Nodes[node].State;
if (IsGrave(node)) // grave-creatures are special cause of a quest
m_ActiveEvents[node + BG_AV_NODES_MAX] = team * BG_AV_MAX_GRAVETYPES;
}
void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint32 team)
{
assert(team < 3); // alliance:0, horde:1, neutral:2
assert(m_Nodes[node].TotalOwner == team);
assert(m_Nodes[node].Owner != team);
assert(m_Nodes[node].State != POINT_CONTROLLED);
m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
m_Nodes[node].Owner = team;
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = POINT_CONTROLLED;
m_Nodes[node].Timer = 0;
}
void BattleGroundAV::Reset()
{
BattleGround::Reset();
// set the reputation and honor variables:
bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID());
m_HonorMapComplete = (isBGWeekend) ? BG_AV_KILL_MAP_COMPLETE_HOLIDAY : BG_AV_KILL_MAP_COMPLETE;
m_RepTowerDestruction = (isBGWeekend) ? BG_AV_REP_TOWER_HOLIDAY : BG_AV_REP_TOWER;
m_RepCaptain = (isBGWeekend) ? BG_AV_REP_CAPTAIN_HOLIDAY : BG_AV_REP_CAPTAIN;
m_RepBoss = (isBGWeekend) ? BG_AV_REP_BOSS_HOLIDAY : BG_AV_REP_BOSS;
m_RepOwnedGrave = (isBGWeekend) ? BG_AV_REP_OWNED_GRAVE_HOLIDAY : BG_AV_REP_OWNED_GRAVE;
m_RepSurviveCaptain = (isBGWeekend) ? BG_AV_REP_SURVIVING_CAPTAIN_HOLIDAY : BG_AV_REP_SURVIVING_CAPTAIN;
m_RepSurviveTower = (isBGWeekend) ? BG_AV_REP_SURVIVING_TOWER_HOLIDAY : BG_AV_REP_SURVIVING_TOWER;
for(uint8 i = 0; i < BG_TEAMS_COUNT; i++)
{
for(uint8 j = 0; j < 9; j++) // 9 quests getting tracked
m_Team_QuestStatus[i][j] = 0;
m_TeamScores[i] = BG_AV_SCORE_INITIAL_POINTS;
m_IsInformedNearLose[i] = false;
m_ActiveEvents[BG_AV_NodeEventCaptainDead_A + i] = BG_EVENT_NONE;
}
for(uint8 i = 0; i < BG_AV_MAX_MINES; i++)
{
m_Mine_Owner[i] = BG_AV_NEUTRAL_TEAM;
m_Mine_PrevOwner[i] = m_Mine_Owner[i];
m_ActiveEvents[BG_AV_MINE_BOSSES+ i] = BG_AV_NEUTRAL_TEAM;
m_ActiveEvents[BG_AV_MINE_EVENT + i] = BG_AV_NEUTRAL_TEAM;
m_Mine_Timer[i] = BG_AV_MINE_TICK_TIMER;
}
m_ActiveEvents[BG_AV_CAPTAIN_A] = 0;
m_ActiveEvents[BG_AV_CAPTAIN_H] = 0;
m_ActiveEvents[BG_AV_HERALD] = 0;
m_ActiveEvents[BG_AV_BOSS_A] = 0;
m_ActiveEvents[BG_AV_BOSS_H] = 0;
for(BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) // towers
m_ActiveEvents[BG_AV_MARSHAL_A_SOUTH + i - BG_AV_NODES_DUNBALDAR_SOUTH] = 0;
for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_STONEHEART_GRAVE; ++i) // alliance graves
InitNode(i, BG_TEAM_ALLIANCE, false);
for(BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i) // alliance towers
InitNode(i, BG_TEAM_ALLIANCE, true);
for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_GRAVE; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) // horde graves
InitNode(i, BG_TEAM_HORDE, false);
for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) // horde towers
InitNode(i, BG_TEAM_HORDE, true);
InitNode(BG_AV_NODES_SNOWFALL_GRAVE, BG_AV_NEUTRAL_TEAM, false); // give snowfall neutral owner
}

View file

@ -21,17 +21,279 @@
class BattleGround;
#define BG_AV_MAX_NODE_DISTANCE 25 // distance in which players are still counted in range of a banner (for alliance towers this is calculated from the center of the tower)
#define BG_AV_BOSS_KILL_QUEST_SPELL 23658
#define BG_AV_CAPTIME 240000 // 4 minutes
#define BG_AV_SNOWFALL_FIRSTCAP 300000 // 5 minutes but i also have seen 4:05
#define BG_AV_SCORE_INITIAL_POINTS 600
#define BG_AV_SCORE_NEAR_LOSE 120
// description: KILL = bonushonor kill one kill is 21honor worth at 0
// REP reputation, RES = ressources a team will lose
#define BG_AV_KILL_BOSS 4
#define BG_AV_REP_BOSS 350
#define BG_AV_REP_BOSS_HOLIDAY 525
#define BG_AV_KILL_CAPTAIN 3
#define BG_AV_REP_CAPTAIN 125
#define BG_AV_REP_CAPTAIN_HOLIDAY 185
#define BG_AV_RES_CAPTAIN 100
#define BG_AV_KILL_TOWER 3
#define BG_AV_REP_TOWER 12
#define BG_AV_REP_TOWER_HOLIDAY 18
#define BG_AV_RES_TOWER 75
#define BG_AV_KILL_GET_COMMANDER 1 // for a safely returned wingcommander TODO implement it
// bonushonor at the end
#define BG_AV_KILL_SURVIVING_TOWER 2
#define BG_AV_REP_SURVIVING_TOWER 12
#define BG_AV_REP_SURVIVING_TOWER_HOLIDAY 18
#define BG_AV_KILL_SURVIVING_CAPTAIN 2
#define BG_AV_REP_SURVIVING_CAPTAIN 125
#define BG_AV_REP_SURVIVING_CAPTAIN_HOLIDAY 175
#define BG_AV_KILL_MAP_COMPLETE 0
#define BG_AV_KILL_MAP_COMPLETE_HOLIDAY 4
#define BG_AV_REP_OWNED_GRAVE 12
#define BG_AV_REP_OWNED_GRAVE_HOLIDAY 18
#define BG_AV_REP_OWNED_MINE 24
#define BG_AV_REP_OWNED_MINE_HOLIDAY 36
enum BG_AV_Sounds
{
BG_AV_SOUND_NEAR_LOSE = 8456, // not confirmed yet
BG_AV_SOUND_ALLIANCE_ASSAULTS = 8212, // tower,grave + enemy boss if someone tries to attack him
BG_AV_SOUND_HORDE_ASSAULTS = 8174,
BG_AV_SOUND_ALLIANCE_GOOD = 8173, // if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave
BG_AV_SOUND_HORDE_GOOD = 8213,
BG_AV_SOUND_BOTH_TOWER_DEFEND = 8192,
BG_AV_SOUND_ALLIANCE_CAPTAIN = 8232, // gets called when someone attacks them and at the beginning after 3min + rand(x) * 10sec (maybe buff)
BG_AV_SOUND_HORDE_CAPTAIN = 8333,
};
enum BG_AV_OTHER_VALUES
{
BG_AV_NORTH_MINE = 0,
BG_AV_SOUTH_MINE = 1,
BG_AV_MINE_TICK_TIMER = 45000,
BG_AV_MINE_RECLAIM_TIMER = 1200000, // TODO: get the right value.. this is currently 20 minutes
BG_AV_NEUTRAL_TEAM = 2, // this is the neutral owner of snowfall
BG_AV_FACTION_A = 730,
BG_AV_FACTION_H = 729,
};
#define BG_AV_MAX_MINES 2
enum BG_AV_ObjectIds
{
// mine supplies
BG_AV_OBJECTID_MINE_N = 178785,
BG_AV_OBJECTID_MINE_S = 178784,
};
enum BG_AV_Nodes
{
BG_AV_NODES_FIRSTAID_STATION = 0,
BG_AV_NODES_STORMPIKE_GRAVE = 1,
BG_AV_NODES_STONEHEART_GRAVE = 2,
BG_AV_NODES_SNOWFALL_GRAVE = 3,
BG_AV_NODES_ICEBLOOD_GRAVE = 4,
BG_AV_NODES_FROSTWOLF_GRAVE = 5,
BG_AV_NODES_FROSTWOLF_HUT = 6,
BG_AV_NODES_DUNBALDAR_SOUTH = 7,
BG_AV_NODES_DUNBALDAR_NORTH = 8,
BG_AV_NODES_ICEWING_BUNKER = 9,
BG_AV_NODES_STONEHEART_BUNKER = 10,
BG_AV_NODES_ICEBLOOD_TOWER = 11,
BG_AV_NODES_TOWER_POINT = 12,
BG_AV_NODES_FROSTWOLF_ETOWER = 13,
BG_AV_NODES_FROSTWOLF_WTOWER = 14,
BG_AV_NODES_ERROR = 255,
};
#define BG_AV_NODES_MAX 15
// for nodeevents we will use event1=node
// event2 is related to BG_AV_States
// 0 = alliance assaulted
// 1 = alliance control
// 2 = horde assaulted
// 3 = horde control
// 4 = neutral assaulted
// 5 = neutral control
// graves have special creatures - their defenders can be in 4 different states
// through some quests with armor scraps
// so i use event1=BG_AV_NODES_MAX+node (15-21)
// and event2=type
#define BG_AV_MINE_BOSSES 46 // + mineid will be exact event
#define BG_AV_MINE_BOSSES_NORTH 46
#define BG_AV_MINE_BOSSES_SOUTH 47
#define BG_AV_CAPTAIN_A 48
#define BG_AV_CAPTAIN_H 49
#define BG_AV_MINE_EVENT 50 // + mineid will be exact event
#define BG_AV_MINE_EVENT_NORTH 50
#define BG_AV_MINE_EVENT_SOUTH 51
#define BG_AV_MARSHAL_A_SOUTH 52
#define BG_AV_MARSHAL_A_NORTH 53
#define BG_AV_MARSHAL_A_ICE 54
#define BG_AV_MARSHAL_A_STONE 55
#define BG_AV_MARSHAL_H_ICE 56
#define BG_AV_MARSHAL_H_TOWER 57
#define BG_AV_MARSHAL_H_ETOWER 58
#define BG_AV_MARSHAL_H_WTOWER 59
#define BG_AV_HERALD 60
#define BG_AV_BOSS_A 61
#define BG_AV_BOSS_H 62
#define BG_AV_NodeEventCaptainDead_A 63
#define BG_AV_NodeEventCaptainDead_H 64
enum BG_AV_Graveyards
{
BG_AV_GRAVE_STORM_AID = 751,
BG_AV_GRAVE_STORM_GRAVE = 689,
BG_AV_GRAVE_STONE_GRAVE = 729,
BG_AV_GRAVE_SNOWFALL = 169,
BG_AV_GRAVE_ICE_GRAVE = 749,
BG_AV_GRAVE_FROSTWOLF = 690,
BG_AV_GRAVE_FROST_HUT = 750,
BG_AV_GRAVE_MAIN_ALLIANCE = 611,
BG_AV_GRAVE_MAIN_HORDE = 610
};
const uint32 BG_AV_GraveyardIds[9]= {
BG_AV_GRAVE_STORM_AID,
BG_AV_GRAVE_STORM_GRAVE,
BG_AV_GRAVE_STONE_GRAVE,
BG_AV_GRAVE_SNOWFALL,
BG_AV_GRAVE_ICE_GRAVE,
BG_AV_GRAVE_FROSTWOLF,
BG_AV_GRAVE_FROST_HUT,
BG_AV_GRAVE_MAIN_ALLIANCE,
BG_AV_GRAVE_MAIN_HORDE
};
enum BG_AV_States
{
POINT_ASSAULTED = 0,
POINT_CONTROLLED = 1
};
#define BG_AV_MAX_STATES 2
enum BG_AV_WorldStates
{
BG_AV_Alliance_Score = 3127,
BG_AV_Horde_Score = 3128,
BG_AV_SHOW_H_SCORE = 3133,
BG_AV_SHOW_A_SCORE = 3134,
AV_SNOWFALL_N = 1966,
};
// alliance_control horde_control neutral_control
const uint32 BG_AV_MineWorldStates[2][3] = {
{1358, 1359, 1360},
{1355, 1356, 1357}
};
// alliance_control alliance_assault h_control h_assault
const uint32 BG_AV_NodeWorldStates[BG_AV_NODES_MAX][4] = {
// Stormpike first aid station
{1326,1325,1328,1327},
// Stormpike Graveyard
{1335,1333,1336,1334},
// Stoneheart Grave
{1304,1302,1303,1301},
// Snowfall Grave
{1343,1341,1344,1342},
// Iceblood grave
{1348,1346,1349,1347},
// Frostwolf Grave
{1339,1337,1340,1338},
// Frostwolf Hut
{1331,1329,1332,1330},
// Dunbaldar South Bunker
{1375,1361,1378,1370},
// Dunbaldar North Bunker
{1374,1362,1379,1371},
// Icewing Bunker
{1376,1363,1380,1372},
// Stoneheart Bunker
{1377,1364,1381,1373},
// Iceblood Tower
{1390,1368,1395,1385},
// Tower Point
{1389,1367,1394,1384},
// Frostwolf East
{1388,1366,1393,1383},
// Frostwolf West
{1387,1365,1392,1382},
};
// through the armorscap-quest 4 different gravedefender exist
#define BG_AV_MAX_GRAVETYPES 4
enum BG_AV_QuestIds
{
BG_AV_QUEST_A_SCRAPS1 = 7223, // first quest
BG_AV_QUEST_A_SCRAPS2 = 6781, // repeatable
BG_AV_QUEST_H_SCRAPS1 = 7224,
BG_AV_QUEST_H_SCRAPS2 = 6741,
BG_AV_QUEST_A_COMMANDER1 = 6942, // soldier
BG_AV_QUEST_H_COMMANDER1 = 6825,
BG_AV_QUEST_A_COMMANDER2 = 6941, // leutnant
BG_AV_QUEST_H_COMMANDER2 = 6826,
BG_AV_QUEST_A_COMMANDER3 = 6943, // commander
BG_AV_QUEST_H_COMMANDER3 = 6827,
BG_AV_QUEST_A_BOSS1 = 7386, // 5 cristal/blood
BG_AV_QUEST_H_BOSS1 = 7385,
BG_AV_QUEST_A_BOSS2 = 6881, // 1
BG_AV_QUEST_H_BOSS2 = 6801,
BG_AV_QUEST_A_NEAR_MINE = 5892, // the mine near start location of team
BG_AV_QUEST_H_NEAR_MINE = 5893,
BG_AV_QUEST_A_OTHER_MINE = 6982, // the other mine ;)
BG_AV_QUEST_H_OTHER_MINE = 6985,
BG_AV_QUEST_A_RIDER_HIDE = 7026,
BG_AV_QUEST_H_RIDER_HIDE = 7002,
BG_AV_QUEST_A_RIDER_TAME = 7027,
BG_AV_QUEST_H_RIDER_TAME = 7001
};
struct BG_AV_NodeInfo
{
uint32 TotalOwner;
uint32 Owner;
uint32 PrevOwner;
BG_AV_States State;
BG_AV_States PrevState;
uint32 Timer;
bool Tower;
};
inline BG_AV_Nodes &operator++(BG_AV_Nodes &i)
{
return i = BG_AV_Nodes(i + 1);
}
class BattleGroundAVScore : public BattleGroundScore
{
public:
BattleGroundAVScore() : GraveyardsAssaulted(0), GraveyardsDefended(0), TowersAssaulted(0), TowersDefended(0), MinesCaptured(0), LeadersKilled(0), SecondaryObjectives(0) {};
BattleGroundAVScore() : GraveyardsAssaulted(0), GraveyardsDefended(0), TowersAssaulted(0), TowersDefended(0), SecondaryObjectives(0) {};
virtual ~BattleGroundAVScore() {};
uint32 GraveyardsAssaulted;
uint32 GraveyardsDefended;
uint32 TowersAssaulted;
uint32 TowersDefended;
uint32 MinesCaptured;
uint32 LeadersKilled;
uint32 SecondaryObjectives;
};
@ -46,16 +308,79 @@ class BattleGroundAV : public BattleGround
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void OnObjectDBLoad(Creature* creature);
virtual void OnCreatureRespawn(Creature* creature);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
// world states
virtual void FillInitialWorldStates(WorldPacket& data);
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
//bool SetupBattleGround();
virtual void Reset();
/* Scorekeeping */
/*general stuff*/
void UpdateScore(BattleGroundTeamId team, int32 points);
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
/*handle stuff*/ // these are functions which get called from extern scripts
virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj);
void HandleKillPlayer(Player* player, Player *killer);
void HandleKillUnit(Creature *creature, Player *killer);
void HandleQuestComplete(uint32 questid, Player *player);
bool PlayerCanDoMineQuest(int32 GOId,uint32 team);
void EndBattleGround(uint32 winner);
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player *plr);
private:
/* Nodes occupying */
void EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node);
void EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node);
void EventPlayerDestroyedPoint(BG_AV_Nodes node);
void AssaultNode(BG_AV_Nodes node, uint32 team);
void DestroyNode(BG_AV_Nodes node);
void InitNode(BG_AV_Nodes node, uint32 team, bool tower);
void DefendNode(BG_AV_Nodes node, uint32 team);
void PopulateNode(BG_AV_Nodes node);
uint32 GetNodeName(BG_AV_Nodes node);
const bool IsTower(BG_AV_Nodes node) { return (node == BG_AV_NODES_ERROR)? false : m_Nodes[node].Tower; }
const bool IsGrave(BG_AV_Nodes node) { return (node == BG_AV_NODES_ERROR)? false : !m_Nodes[node].Tower; }
/*mine*/
void ChangeMineOwner(uint8 mine, uint32 team);
/*worldstates*/
uint8 GetWorldStateType(uint8 state, uint32 team) const { return team * BG_AV_MAX_STATES + state; }
void SendMineWorldStates(uint32 mine);
void UpdateNodeWorldState(BG_AV_Nodes node);
/*variables */
uint32 m_Team_QuestStatus[BG_TEAMS_COUNT][9]; // [x][y] x=team y=questcounter
BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX];
int8 m_Mine_Owner[BG_AV_MAX_MINES];
int8 m_Mine_PrevOwner[BG_AV_MAX_MINES]; // only for worldstates needed
int32 m_Mine_Timer[BG_AV_MAX_MINES];
uint32 m_Mine_Reclaim_Timer[BG_AV_MAX_MINES];
bool m_IsInformedNearLose[BG_TEAMS_COUNT];
bool m_captainAlive[BG_TEAMS_COUNT];
uint32 m_HonorMapComplete;
uint32 m_RepTowerDestruction;
uint32 m_RepCaptain;
uint32 m_RepBoss;
uint32 m_RepOwnedGrave;
uint32 m_RepOwnedMine;
uint32 m_RepSurviveCaptain;
uint32 m_RepSurviveTower;
};
#endif

View file

@ -1383,7 +1383,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << (uint32)((BattleGroundAVScore*)itr->second)->GraveyardsDefended; // GraveyardsDefended
*data << (uint32)((BattleGroundAVScore*)itr->second)->TowersAssaulted; // TowersAssaulted
*data << (uint32)((BattleGroundAVScore*)itr->second)->TowersDefended; // TowersDefended
*data << (uint32)((BattleGroundAVScore*)itr->second)->MinesCaptured; // MinesCaptured
*data << (uint32)((BattleGroundAVScore*)itr->second)->SecondaryObjectives; // SecondaryObjectives - free some of the Lieutnants
break;
case BATTLEGROUND_WS:
*data << (uint32)0x00000002; // count of next fields

View file

@ -366,6 +366,9 @@ void Creature::Update(uint32 diff)
else
setDeathState( JUST_ALIVED );
if (GetMap()->IsBattleGround() && ((BattleGroundMap*)GetMap())->GetBG())
((BattleGroundMap*)GetMap())->GetBG()->OnCreatureRespawn(this); // for alterac valley needed to adjust the correct level again
//Call AI respawn virtual function
i_AI->JustRespawned();

View file

@ -34,6 +34,7 @@
#include "CellImpl.h"
#include "InstanceData.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
#include "Util.h"
GameObject::GameObject() : WorldObject()
@ -744,7 +745,14 @@ bool GameObject::ActivateToQuest( Player *pTarget)const
case GAMEOBJECT_TYPE_CHEST:
{
if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), pTarget))
{
//look for battlegroundAV for some objects which are only activated after mine gots captured by own team
if (GetEntry() == BG_AV_OBJECTID_MINE_N || GetEntry() == BG_AV_OBJECTID_MINE_S)
if (BattleGround *bg = pTarget->GetBattleGround())
if (bg->GetTypeID() == BATTLEGROUND_AV && !(((BattleGroundAV*)bg)->PlayerCanDoMineQuest(GetEntry(),pTarget->GetTeam())))
return false;
return true;
}
break;
}
case GAMEOBJECT_TYPE_GOOBER:

View file

@ -686,16 +686,51 @@ enum MangosStrings
LANG_DIST_ARENA_POINTS_TEAM_START = 744,
LANG_DIST_ARENA_POINTS_TEAM_END = 745,
LANG_DIST_ARENA_POINTS_END = 746,
// = 747, not used
// = 748, not used
// = 749, not used
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 750, // "Not enough players. This game will close in %u mins."
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS = 751, // "Not enough players. This game will close in %u seconds."
// = 752, not used
// LANG_BG_WS_START_TWO_MINUTES = 753, - defined above
// LANG_BG_AB_START_TWO_MINUTES = 754, - defined above
// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
// Room for batleground/arena strings 756-799 not used
LANG_BATTLEGROUND_ONLY_ALLIANCE_USE = 752, // "Only The Alliance can use that portal"
LANG_BATTLEGROUND_ONLY_HORDE_USE = 753, // "Only The Horde can use that portal"
LANG_BG_AV_ALLY = 757,
LANG_BG_AV_HORDE = 758,
LANG_BG_AV_TOWER_TAKEN = 759,
LANG_BG_AV_TOWER_ASSAULTED = 760,
LANG_BG_AV_TOWER_DEFENDED = 761,
LANG_BG_AV_GRAVE_TAKEN = 762,
LANG_BG_AV_GRAVE_DEFENDED = 763,
LANG_BG_AV_GRAVE_ASSAULTED = 764,
LANG_BG_AV_MINE_TAKEN = 765,
LANG_BG_AV_MINE_NORTH = 766,
LANG_BG_AV_MINE_SOUTH = 767,
LANG_BG_AV_NODE_GRAVE_STORM_AID = 768,
LANG_BG_AV_NODE_TOWER_DUN_S = 769,
LANG_BG_AV_NODE_TOWER_DUN_N = 770,
LANG_BG_AV_NODE_GRAVE_STORMPIKE = 771,
LANG_BG_AV_NODE_TOWER_ICEWING = 772,
LANG_BG_AV_NODE_GRAVE_STONE = 773,
LANG_BG_AV_NODE_TOWER_STONE = 774,
LANG_BG_AV_NODE_GRAVE_SNOW = 775,
LANG_BG_AV_NODE_TOWER_ICE = 776,
LANG_BG_AV_NODE_GRAVE_ICE = 777,
LANG_BG_AV_NODE_TOWER_POINT = 778,
LANG_BG_AV_NODE_GRAVE_FROST = 779,
LANG_BG_AV_NODE_TOWER_FROST_E = 780,
LANG_BG_AV_NODE_TOWER_FROST_W = 781,
LANG_BG_AV_NODE_GRAVE_FROST_HUT = 782,
LANG_BG_AV_START_TWO_MINUTES = 783,
LANG_BG_AV_START_ONE_MINUTE = 784,
LANG_BG_AV_START_HALF_MINUTE = 785,
LANG_BG_AV_HAS_BEGUN = 786,
LANG_BG_AV_A_NEAR_LOSE = 787,
LANG_BG_AV_H_NEAR_LOSE = 788,
LANG_BG_AV_H_GENERAL_DEAD = 789,
LANG_BG_AV_A_GENERAL_DEAD = 790,
// Room for batleground/arena strings 790-799 not used
// in game strings
// = 800, not used

View file

@ -65,6 +65,16 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
loot = &pItem->loot;
}
else if (IS_CORPSE_GUID(lguid))
{
Corpse *bones = ObjectAccessor::GetCorpse(*player, lguid);
if (!bones)
{
player->SendLootRelease(lguid);
return;
}
loot = &bones->loot;
}
else
{
Creature* pCreature = GetPlayer()->GetMap()->GetCreature(lguid);

View file

@ -782,9 +782,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
{
BattleGround* bg = GetPlayer()->GetBattleGround();
if(bg)
if(bg->GetStatus() == STATUS_IN_PROGRESS)
bg->HandleAreaTrigger(GetPlayer(), Trigger_ID);
return;
}

View file

@ -51,6 +51,7 @@
#include "Transports.h"
#include "Weather.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
#include "BattleGroundMgr.h"
#include "ArenaTeam.h"
#include "Chat.h"
@ -7410,6 +7411,14 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (go->getLootState() == GO_READY)
{
uint32 lootid = go->GetGOInfo()->GetLootId();
if ((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S))
if (BattleGround *bg = GetBattleGround())
if (bg->GetTypeID() == BATTLEGROUND_AV)
if (!(((BattleGroundAV*)bg)->PlayerCanDoMineQuest(go->GetEntry(), GetTeam())))
{
SendLootRelease(guid);
return;
}
if (lootid)
{
@ -7476,6 +7485,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
bones->lootForBody = true;
uint32 pLevel = bones->loot.gold;
bones->loot.clear();
if (GetBattleGround()->GetTypeID() == BATTLEGROUND_AV)
loot->FillLoot(0, LootTemplates_Creature, this, false);
// It may need a better formula
// Now it works like this: lvl10: ~6copper, lvl70: ~9silver
bones->loot.gold = (uint32)( urand(50, 150) * 0.016f * pow( ((float)pLevel)/5.76f, 2.5f) * sWorld.getRate(RATE_DROP_MONEY) );
@ -7759,81 +7770,86 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
case 2257:
break;
case 2597: // AV
data << uint32(0x7ae) << uint32(0x1); // 7
data << uint32(0x532) << uint32(0x1); // 8
data << uint32(0x531) << uint32(0x0); // 9
data << uint32(0x52e) << uint32(0x0); // 10
data << uint32(0x571) << uint32(0x0); // 11
data << uint32(0x570) << uint32(0x0); // 12
data << uint32(0x567) << uint32(0x1); // 13
data << uint32(0x566) << uint32(0x1); // 14
data << uint32(0x550) << uint32(0x1); // 15
data << uint32(0x544) << uint32(0x0); // 16
data << uint32(0x536) << uint32(0x0); // 17
data << uint32(0x535) << uint32(0x1); // 18
data << uint32(0x518) << uint32(0x0); // 19
data << uint32(0x517) << uint32(0x0); // 20
data << uint32(0x574) << uint32(0x0); // 21
data << uint32(0x573) << uint32(0x0); // 22
data << uint32(0x572) << uint32(0x0); // 23
data << uint32(0x56f) << uint32(0x0); // 24
data << uint32(0x56e) << uint32(0x0); // 25
data << uint32(0x56d) << uint32(0x0); // 26
data << uint32(0x56c) << uint32(0x0); // 27
data << uint32(0x56b) << uint32(0x0); // 28
data << uint32(0x56a) << uint32(0x1); // 29
data << uint32(0x569) << uint32(0x1); // 30
data << uint32(0x568) << uint32(0x1); // 13
data << uint32(0x565) << uint32(0x0); // 32
data << uint32(0x564) << uint32(0x0); // 33
data << uint32(0x563) << uint32(0x0); // 34
data << uint32(0x562) << uint32(0x0); // 35
data << uint32(0x561) << uint32(0x0); // 36
data << uint32(0x560) << uint32(0x0); // 37
data << uint32(0x55f) << uint32(0x0); // 38
data << uint32(0x55e) << uint32(0x0); // 39
data << uint32(0x55d) << uint32(0x0); // 40
data << uint32(0x3c6) << uint32(0x4); // 41
data << uint32(0x3c4) << uint32(0x6); // 42
data << uint32(0x3c2) << uint32(0x4); // 43
data << uint32(0x516) << uint32(0x1); // 44
data << uint32(0x515) << uint32(0x0); // 45
data << uint32(0x3b6) << uint32(0x6); // 46
data << uint32(0x55c) << uint32(0x0); // 47
data << uint32(0x55b) << uint32(0x0); // 48
data << uint32(0x55a) << uint32(0x0); // 49
data << uint32(0x559) << uint32(0x0); // 50
data << uint32(0x558) << uint32(0x0); // 51
data << uint32(0x557) << uint32(0x0); // 52
data << uint32(0x556) << uint32(0x0); // 53
data << uint32(0x555) << uint32(0x0); // 54
data << uint32(0x554) << uint32(0x1); // 55
data << uint32(0x553) << uint32(0x1); // 56
data << uint32(0x552) << uint32(0x1); // 57
data << uint32(0x551) << uint32(0x1); // 58
data << uint32(0x54f) << uint32(0x0); // 59
data << uint32(0x54e) << uint32(0x0); // 60
data << uint32(0x54d) << uint32(0x1); // 61
data << uint32(0x54c) << uint32(0x0); // 62
data << uint32(0x54b) << uint32(0x0); // 63
data << uint32(0x545) << uint32(0x0); // 64
data << uint32(0x543) << uint32(0x1); // 65
data << uint32(0x542) << uint32(0x0); // 66
data << uint32(0x540) << uint32(0x0); // 67
data << uint32(0x53f) << uint32(0x0); // 68
data << uint32(0x53e) << uint32(0x0); // 69
data << uint32(0x53d) << uint32(0x0); // 70
data << uint32(0x53c) << uint32(0x0); // 71
data << uint32(0x53b) << uint32(0x0); // 72
data << uint32(0x53a) << uint32(0x1); // 73
data << uint32(0x539) << uint32(0x0); // 74
data << uint32(0x538) << uint32(0x0); // 75
data << uint32(0x537) << uint32(0x0); // 76
data << uint32(0x534) << uint32(0x0); // 77
data << uint32(0x533) << uint32(0x0); // 78
data << uint32(0x530) << uint32(0x0); // 79
data << uint32(0x52f) << uint32(0x0); // 80
data << uint32(0x52d) << uint32(0x1); // 81
if (bg && bg->GetTypeID() == BATTLEGROUND_AV)
bg->FillInitialWorldStates(data);
else
{
data << uint32(0x7ae) << uint32(0x1); // 7 snowfall n
data << uint32(0x532) << uint32(0x1); // 8 frostwolfhut hc
data << uint32(0x531) << uint32(0x0); // 9 frostwolfhut ac
data << uint32(0x52e) << uint32(0x0); // 10 stormpike firstaid a_a
data << uint32(0x571) << uint32(0x0); // 11 east frostwolf tower horde assaulted -unused
data << uint32(0x570) << uint32(0x0); // 12 west frostwolf tower horde assaulted - unused
data << uint32(0x567) << uint32(0x1); // 13 frostwolfe c
data << uint32(0x566) << uint32(0x1); // 14 frostwolfw c
data << uint32(0x550) << uint32(0x1); // 15 irondeep (N) ally
data << uint32(0x544) << uint32(0x0); // 16 ice grave a_a
data << uint32(0x536) << uint32(0x0); // 17 stormpike grave h_c
data << uint32(0x535) << uint32(0x1); // 18 stormpike grave a_c
data << uint32(0x518) << uint32(0x0); // 19 stoneheart grave a_a
data << uint32(0x517) << uint32(0x0); // 20 stoneheart grave h_a
data << uint32(0x574) << uint32(0x0); // 21 1396 unk
data << uint32(0x573) << uint32(0x0); // 22 iceblood tower horde assaulted -unused
data << uint32(0x572) << uint32(0x0); // 23 towerpoint horde assaulted - unused
data << uint32(0x56f) << uint32(0x0); // 24 1391 unk
data << uint32(0x56e) << uint32(0x0); // 25 iceblood a
data << uint32(0x56d) << uint32(0x0); // 26 towerp a
data << uint32(0x56c) << uint32(0x0); // 27 frostwolfe a
data << uint32(0x56b) << uint32(0x0); // 28 froswolfw a
data << uint32(0x56a) << uint32(0x1); // 29 1386 unk
data << uint32(0x569) << uint32(0x1); // 30 iceblood c
data << uint32(0x568) << uint32(0x1); // 31 towerp c
data << uint32(0x565) << uint32(0x0); // 32 stoneh tower a
data << uint32(0x564) << uint32(0x0); // 33 icewing tower a
data << uint32(0x563) << uint32(0x0); // 34 dunn a
data << uint32(0x562) << uint32(0x0); // 35 duns a
data << uint32(0x561) << uint32(0x0); // 36 stoneheart bunker alliance assaulted - unused
data << uint32(0x560) << uint32(0x0); // 37 icewing bunker alliance assaulted - unused
data << uint32(0x55f) << uint32(0x0); // 38 dunbaldar south alliance assaulted - unused
data << uint32(0x55e) << uint32(0x0); // 39 dunbaldar north alliance assaulted - unused
data << uint32(0x55d) << uint32(0x0); // 40 stone tower d
data << uint32(0x3c6) << uint32(0x0); // 41 966 unk
data << uint32(0x3c4) << uint32(0x0); // 42 964 unk
data << uint32(0x3c2) << uint32(0x0); // 43 962 unk
data << uint32(0x516) << uint32(0x1); // 44 stoneheart grave a_c
data << uint32(0x515) << uint32(0x0); // 45 stonheart grave h_c
data << uint32(0x3b6) << uint32(0x0); // 46 950 unk
data << uint32(0x55c) << uint32(0x0); // 47 icewing tower d
data << uint32(0x55b) << uint32(0x0); // 48 dunn d
data << uint32(0x55a) << uint32(0x0); // 49 duns d
data << uint32(0x559) << uint32(0x0); // 50 1369 unk
data << uint32(0x558) << uint32(0x0); // 51 iceblood d
data << uint32(0x557) << uint32(0x0); // 52 towerp d
data << uint32(0x556) << uint32(0x0); // 53 frostwolfe d
data << uint32(0x555) << uint32(0x0); // 54 frostwolfw d
data << uint32(0x554) << uint32(0x1); // 55 stoneh tower c
data << uint32(0x553) << uint32(0x1); // 56 icewing tower c
data << uint32(0x552) << uint32(0x1); // 57 dunn c
data << uint32(0x551) << uint32(0x1); // 58 duns c
data << uint32(0x54f) << uint32(0x0); // 59 irondeep (N) horde
data << uint32(0x54e) << uint32(0x0); // 60 irondeep (N) ally
data << uint32(0x54d) << uint32(0x1); // 61 mine (S) neutral
data << uint32(0x54c) << uint32(0x0); // 62 mine (S) horde
data << uint32(0x54b) << uint32(0x0); // 63 mine (S) ally
data << uint32(0x545) << uint32(0x0); // 64 iceblood h_a
data << uint32(0x543) << uint32(0x1); // 65 iceblod h_c
data << uint32(0x542) << uint32(0x0); // 66 iceblood a_c
data << uint32(0x540) << uint32(0x0); // 67 snowfall h_a
data << uint32(0x53f) << uint32(0x0); // 68 snowfall a_a
data << uint32(0x53e) << uint32(0x0); // 69 snowfall h_c
data << uint32(0x53d) << uint32(0x0); // 70 snowfall a_c
data << uint32(0x53c) << uint32(0x0); // 71 frostwolf g h_a
data << uint32(0x53b) << uint32(0x0); // 72 frostwolf g a_a
data << uint32(0x53a) << uint32(0x1); // 73 frostwolf g h_c
data << uint32(0x539) << uint32(0x0); // 74 frostwolf g a_c
data << uint32(0x538) << uint32(0x0); // 75 stormpike grave h_a
data << uint32(0x537) << uint32(0x0); // 76 stormpike grave a_a
data << uint32(0x534) << uint32(0x0); // 77 frostwolf hut h_a
data << uint32(0x533) << uint32(0x0); // 78 frostwolf hut a_a
data << uint32(0x530) << uint32(0x0); // 79 stormpike first aid h_a
data << uint32(0x52f) << uint32(0x0); // 80 stormpike first aid h_c
data << uint32(0x52d) << uint32(0x1); // 81 stormpike first aid a_c
}
break;
case 3277: // WS
if (bg && bg->GetTypeID() == BATTLEGROUND_WS)
@ -12645,6 +12661,10 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
RemoveTimedQuest(quest_id);
if (BattleGround* bg = GetBattleGround())
if (bg->GetTypeID() == BATTLEGROUND_AV)
((BattleGroundAV*)bg)->HandleQuestComplete(pQuest->GetQuestId(), this);
if (pQuest->GetRewChoiceItemsCount() > 0)
{
if (uint32 itemId = pQuest->RewChoiceItemId[reward])
@ -13751,7 +13771,8 @@ bool Player::HasQuestForItem( uint32 itemid ) const
continue;
// hide quest if player is in raid-group and quest is no raid quest
if(GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID)
if (GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID
&& !InBattleGround())
continue;
// There should be no mixed ReqItem/ReqSource drop

View file

@ -3044,7 +3044,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
if (BattleGround *bg = player->GetBattleGround())
{
// check if it's correct bg
if (bg && bg->GetTypeID() == BATTLEGROUND_AB)
if (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_AV)
bg->EventPlayerClickedOnFlag(player, gameObjTarget);
return;
}

View file

@ -718,10 +718,12 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(BattleGround *bg = killed->GetBattleGround())
if(player)
bg->HandleKillPlayer(killed, player);
//later we can add support for creature->player kills here i'm
//not sure, but i guess those kills also get counted in av
//else if(GetTypeId() == TYPEID_UNIT)
// bg->HandleKillPlayer(killed,(Creature*)this);
}
else if(pVictim->GetTypeId() == TYPEID_UNIT)
{
if (player)
if (BattleGround *bg = player->GetBattleGround())
bg->HandleKillUnit((Creature*)pVictim, player);
}
}
else // if (health <= damage)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8607"
#define REVISION_NR "8608"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport"
#define REVISION_DB_MANGOS "required_8607_02_mangos_command"
#define REVISION_DB_MANGOS "required_8608_02_mangos_battleground_events"
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__