Merge branch 'master' of https://github.com/TrinityCore/TrinityCore into mmaps
This commit is contained in:
@@ -14,7 +14,9 @@ Thanks to the WCell team (especially Ralek) for research on realm reconnect
|
||||
sequence, item scaling stats algorithm, gameobject rotation issues.
|
||||
|
||||
Thanks go out to the following people for various patches/code (listed in the
|
||||
order they were added): w12x, dythzer, XEQT, death420, balrok, TOM_RUS,
|
||||
order they were added) (there may be duplicates or invalid names, most of them
|
||||
were extracted from commits):
|
||||
w12x, dythzer, XEQT, death420, balrok, TOM_RUS,
|
||||
runningnak3d, Seline, KingPin, raczman, bogie, Neo2003, NoFantasy, Derex,
|
||||
freghar, toilet1, megamage, MadJack, WarHead, gvcoman, Ntsc, arrai, jrkpote,
|
||||
Seraphim, vagoth, KerchumA222, Rognar, Blaymoira, DragonHunter, Molius, ApoC,
|
||||
@@ -33,9 +35,9 @@ teacher4, zhenya, Albrecht de Endrau, Phacops, Naicisum, thenecromancer, shax,
|
||||
cryingcloud, freeganja, Foks, daveh, Az@zel, evilstar, Corfen, Astellar, Maxxie,
|
||||
DEN_North, StarJoker, Nezemnoy, X-Savior, subhuman_bob, Ambal, Brueggus, sparc,
|
||||
jojo, Trojan, tvaroh, Genars, BombermaG, Bulkin, nesocip, xILOSWag, SilverIce,
|
||||
Uruviel, timmit, SeT, Seizerkiller, Stokrotka, JoN0, Tanatos, Hunteee, Alyen,
|
||||
Uruviel, timmit, Seizerkiller, Stokrotka, JoN0, Tanatos, Hunteee, Alyen,
|
||||
Farah, Them, DaGNU, arthurcik, BudIcePenguin, Amok, Amit86, onkelz28, Azrael,
|
||||
Larva, Roland, DerDyddye, Vicos, PSZ, CRAZyBUg, irish, Sephiroth1984, hunuza,
|
||||
Larva, Roland, DerDyddye, Vicos, PSZ, CRAZyBUg, irish, Sephiroth1984,
|
||||
mike753, Xlybriem, Paytheo, ArticDevil, FearX, Beaste, bufferoverflow, Jeniczek,
|
||||
Den, bobaz, crackm, seirge, D_Skywalk, mknjc, Christyan, Saeba, Nevan, tlexii,
|
||||
liszt, duckman, Joro, Charlie, smellbee, bigjohnson4, maxdestroyer, Destalker,
|
||||
@@ -64,7 +66,7 @@ footman, elron103, make_the_king, destros, MetaphysicalDrama, disassebler,
|
||||
Malcrom, Vladmimír Lipták, retriman, hyriuu, Smakapotatis, PainKiller,
|
||||
bkhorizon, n0n4m3, Chesterfield, Frankir, Wowka321, Morpheux, p0wer,
|
||||
Ouden, toshik, laise, yavi, Splinter, Syntec, Arthas, denyde, unholy,
|
||||
Vaughner, blackmanos, edrinn, Liberate, Shauren, dr.tenma, click, silverice,
|
||||
Vaughner, blackmanos, edrinn, Liberate, Shauren, dr.tenma, click,
|
||||
SupaBad, Xanadu, Socolin, Shocker, Silinoron, 0xFuture, xK1, Ramus, menke,
|
||||
wowgargamel, Dark0r, Kierkegaard, Leak, ge0rg, StormByte, joshwhedon,
|
||||
BlackCat0110, JuliuSZS, n4rk0, filip.havlicek, m.ax, laviniu, LordJZ, Scazzato88,
|
||||
@@ -72,5 +74,29 @@ svannon, jurkovic.nikola, Willian Krueger, BioHazard, Ille000, Erocoloco,
|
||||
terrorbringer, antihrists, Havenard, scarymovie87, D3VIL, FaTe753, PrinceCreed,
|
||||
spgm, Dakeyras, sombre88, 19Maxx83, moriquendu, Ille, breakerfly,
|
||||
zthoreen, clement.roussel, p.alexej, Ceris, Nayre, Kiper, announce, thmarth,
|
||||
Ner'zhul, DarkXuan, leak, linencloth, SnakeIce, Supabad, Tome, Nay, Kaelima,
|
||||
Svannon
|
||||
Ner'zhul, DarkXuan, linencloth, SnakeIce, Tome, Nay, Kaelima,
|
||||
Subv, Tuxity, tibbi, Gigatotem, Nexflame, trickerer, zxbiohazardzx, w1sht0l1v3,
|
||||
Warpten, CeIa, Kandera, horn, Dimitro, thesensei, Sovak, Vincent-Michael,
|
||||
Xanvial, faq, Gacko, Geodar, hexa-, MacWarrior, cyberbrest, Myran2, Northstrider,
|
||||
AFROM, CrYser, Kretol, Bizzy, nelegalno, Kinzcool, armano2, Tomas, Aristoo, Trista,
|
||||
[email protected], oMadMano, Kiddie, blub, Santiago, tobmaps, Mik43l, danik, Souler,
|
||||
joschiwald, CDawg, WishToDie, gecko32, gadge, neuro_999, Stefo, dr.skull, NTX, Hexit,
|
||||
Stalker-Riddick, thomas33, Manuel Carrasco, Imprtat, Chaplain, teyrnon, zorix, Greymane,
|
||||
Venugh, e000, Amit, Alternative, Exodius, Jorge, shlomi1515, tharaca, Alestaan, Valcorb,
|
||||
Odyssey, Chipsi, Pesthuf, stfx, Yaki Khadafi, David Klepá�ek, SignFinder, unknown,
|
||||
NNN666, AliveShiro, 4m1g0, mweinelt, Abdollah Hasan, Xees, zori, warriorpoetex, qaywsx,
|
||||
ghost, Discovered, faq_, Jildor, The Game, Kezo90, Helias, Frca, Ramusik, elecyb, Joni,
|
||||
Multivitamin, faramir118, cookta2012, Gyx, ShinDarth, Lopin, Martin Weinelt,
|
||||
Bezo, frozenarmor, E. van Harten, LiMCrosS, Albis, Go6o, Pitcrawler, Matthew Goff, neurorulez,
|
||||
Ka0z, glkrlos, zwerg, Merlin2010, furion, Giuseppe Montesanto, LihO, Bootz, PKX, burnham,
|
||||
Drake Fish, Vlad, Discover, Heisenberg, Kapoeira, Emo Norfik, tREAk, zoidmann, Wilds, weclub,
|
||||
Jon, Cron, Alexander, Vinolentus, LaserJet, mns, Stalker_Riddick, Yelvann, draco, Geekotron,
|
||||
bytewarrior, Fredi Machado, Studioworks, 3kids, idostyle@zoit, Sebastián Orellana, DemiDroL,
|
||||
n4ndo, et2012, Rochet2, Grobi, Google, Wispeckt, hacknowledge, wonopon, Naga,
|
||||
Joeri Thissen, Payn, Fest, insider42, DrTenma, L30m4nc3r, Akama, Jesper Meyer, Kiperr,
|
||||
maanuel, vcrx6, Furion89, Mark07, lost-illusion, SeTM, TCKiper, vlad852, tehmarto, boom,
|
||||
Per Wilhelmsen, telsamat, Various, erimioa, Sawiner, zergtmn, SimonDMII, pek2011, alexbolotsin,
|
||||
laly, mrquickfx, Koord, amnell, GWRde, EdwinDW, gildor, darkstalker, Feanordev, _manuel_,
|
||||
thymuswisewood, sohrab, Lazzalf, Taser, Ottowayne, Exordian, nucleartux, John Holiver, j4r0d,
|
||||
Trazom62, Brian, enjoi, teacher, Alex Bolotsin, Troy, silver1ce, nihal, arcanzic, Chaz Brown,
|
||||
pendragon, aven_coda, cca220v, ArcticDevil, derex_tri
|
||||
@@ -618,7 +618,7 @@ DROP TABLE IF EXISTS `character_glyphs`;
|
||||
CREATE TABLE `character_glyphs` (
|
||||
`guid` int(10) unsigned NOT NULL,
|
||||
`spec` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`glyph1` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`glyph1` smallint(5) unsigned DEFAULT '0',
|
||||
`glyph2` smallint(5) unsigned DEFAULT '0',
|
||||
`glyph3` smallint(5) unsigned DEFAULT '0',
|
||||
`glyph4` smallint(5) unsigned DEFAULT '0',
|
||||
@@ -1429,9 +1429,11 @@ CREATE TABLE `gm_tickets` (
|
||||
`closedBy` int(10) NOT NULL DEFAULT '0',
|
||||
`assignedTo` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'GUID of admin to whom ticket is assigned',
|
||||
`comment` text NOT NULL,
|
||||
`response` text NOT NULL,
|
||||
`completed` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`escalated` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`viewed` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`haveTicket` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ticketId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE character_glyphs CHANGE glyph1 glyph1 smallint(5) unsigned DEFAULT '0';
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `gm_tickets`
|
||||
ADD COLUMN `response` text NOT NULL AFTER `comment`,
|
||||
ADD COLUMN `haveTicket` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `viewed`;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- increase droprate for Plump Buzzard Wing
|
||||
UPDATE `creature_loot_template` SET `chanceOrQuestChance`=-50 WHERE `item`=23239;
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE `spell_proc_event` SET `procflags`=0x15510 WHERE `entry`=53386;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Improved Scorch, Improved Shadow Bolt and Winter's Chill effect should not stack
|
||||
DELETE FROM `spell_group` WHERE `id`=1037;
|
||||
INSERT INTO `spell_group`(`id`,`spell_id`) VALUES
|
||||
(1037,22959),
|
||||
(1037,17800),
|
||||
(1037,12579);
|
||||
|
||||
DELETE FROM `spell_group_stack_rules` WHERE `group_id`=1037;
|
||||
INSERT INTO `spell_group_stack_rules`(`group_id`,`stack_rule`) VALUES (1037,3);
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Blood Frenzy (Warrior) and Savage Combat effect should not stack
|
||||
DELETE FROM `spell_group` WHERE `id`=1119;
|
||||
INSERT INTO `spell_group`(`id`,`spell_id`) VALUES
|
||||
(1119,30069),
|
||||
(1119,58684);
|
||||
|
||||
DELETE FROM `spell_group_stack_rules` WHERE `group_id`=1119;
|
||||
INSERT INTO `spell_group_stack_rules`(`group_id`,`stack_rule`) VALUES (1119,3);
|
||||
|
||||
-- Remove invalid spell_groups
|
||||
DELETE FROM `spell_group` WHERE `id` IN (1038,1039);
|
||||
@@ -0,0 +1,9 @@
|
||||
SET @GROUP := 1120;
|
||||
-- Totem of Wrath and Heart of the Crusader effect should not stack
|
||||
DELETE FROM `spell_group` WHERE `id`=@GROUP;
|
||||
INSERT INTO `spell_group`(`id`,`spell_id`) VALUES
|
||||
(@GROUP,21183),
|
||||
(@GROUP,30708);
|
||||
|
||||
DELETE FROM `spell_group_stack_rules` WHERE `group_id`=@GROUP;
|
||||
INSERT INTO `spell_group_stack_rules`(`group_id`,`stack_rule`) VALUES (@GROUP,3);
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Remove all bgs from e1bee86ee6f5c3ab7b1da6d1b54c98c2851f11ec
|
||||
DELETE FROM `battleground_template` WHERE `id` = 6; -- all Bgs
|
||||
@@ -0,0 +1,92 @@
|
||||
SET @GUID = 74685;
|
||||
SET @MAP = 571;
|
||||
DELETE FROM `gameobject` WHERE (`id` IN (192254,192255,192269,192284,192285,192336,192338,192339,192349,192350,192351,192352,192353,192354,192355,192356,192357,192358,192359,192360,192361,192362,192363,192364,192366,192367,192368,192369,192370,192371,192372,192373,192374,192375,192378,192379,192416,192488,192501) AND `guid` != 67250) OR `guid` BETWEEN @GUID AND @GUID+87;
|
||||
INSERT INTO `gameobject` (`guid`,`id`,`map`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`) VALUES
|
||||
(@GUID+0, 192488, @MAP, 64, 5262.540039, 3047.949951, 432.054993, 3.106650), -- Flag on tower
|
||||
(@GUID+1, 192501, @MAP, 128, 5262.540039, 3047.949951, 432.054993, 3.106650), -- Flag on tower
|
||||
(@GUID+2, 192374, @MAP, 64, 5272.939941, 2976.550049, 444.492004, 3.124120), -- Flag on Wall Intersect
|
||||
(@GUID+3, 192416, @MAP, 128, 5272.939941, 2976.550049, 444.492004, 3.124120), -- Flag on Wall Intersect
|
||||
(@GUID+4, 192375, @MAP, 64, 5235.189941, 2941.899902, 444.278015, 1.588250), -- Flag on Wall Intersect
|
||||
(@GUID+5, 192416, @MAP, 128, 5235.189941, 2941.899902, 444.278015, 1.588250), -- Flag on Wall Intersect
|
||||
(@GUID+6, 192488, @MAP, 64, 5163.129883, 2952.590088, 433.502991, 1.535890), -- Flag on tower
|
||||
(@GUID+7, 192501, @MAP, 128, 5163.129883, 2952.590088, 433.502991, 1.535890), -- Flag on tower
|
||||
(@GUID+8, 192488, @MAP, 64, 5145.109863, 2935.000000, 433.385986, 3.141590), -- Flag on tower
|
||||
(@GUID+9, 192501, @MAP, 128, 5145.109863, 2935.000000, 433.385986, 3.141590), -- Flag on tower
|
||||
(@GUID+10, 192488, @MAP, 64, 5158.810059, 2883.129883, 431.618011, 3.141590), -- Flag on wall
|
||||
(@GUID+11, 192416, @MAP, 128, 5158.810059, 2883.129883, 431.618011, 3.141590), -- Flag on wall
|
||||
(@GUID+12, 192336, @MAP, 64, 5154.490234, 2862.149902, 445.011993, 3.141590), -- Flag on Wall Intersect
|
||||
(@GUID+13, 192416, @MAP, 128, 5154.490234, 2862.149902, 445.011993, 3.141590), -- Flag on Wall Intersect
|
||||
(@GUID+14, 192255, @MAP, 64, 5154.520020, 2853.310059, 409.183014, 3.141590), -- Flag on the floor
|
||||
(@GUID+15, 192269, @MAP, 128, 5154.520020, 2853.310059, 409.183014, 3.141590), -- Flag on the floor
|
||||
(@GUID+16, 192254, @MAP, 64, 5154.459961, 2828.939941, 409.188995, 3.141590), -- Flag on the floor
|
||||
(@GUID+17, 192269, @MAP, 128, 5154.459961, 2828.939941, 409.188995, 3.141590), -- Flag on the floor
|
||||
(@GUID+18, 192349, @MAP, 64, 5155.310059, 2820.739990, 444.979004, -3.13286), -- Flag on wall intersect
|
||||
(@GUID+19, 192416, @MAP, 128, 5155.310059, 2820.739990, 444.979004, -3.13286), -- Flag on wall intersect
|
||||
(@GUID+20, 192488, @MAP, 64, 5160.339844, 2798.610107, 430.769012, 3.141590), -- Flag on wall
|
||||
(@GUID+21, 192416, @MAP, 128, 5160.339844, 2798.610107, 430.769012, 3.141590), -- Flag on wall
|
||||
(@GUID+22, 192488, @MAP, 64, 5146.040039, 2747.209961, 433.584015, 3.071770), -- Flag on tower
|
||||
(@GUID+23, 192501, @MAP, 128, 5146.040039, 2747.209961, 433.584015, 3.071770), -- Flag on tower
|
||||
(@GUID+24, 192488, @MAP, 64, 5163.779785, 2729.679932, 433.394012, -1.58825), -- Flag on tower
|
||||
(@GUID+25, 192501, @MAP, 128, 5163.779785, 2729.679932, 433.394012, -1.58825), -- Flag on tower
|
||||
(@GUID+26, 192366, @MAP, 64, 5236.270020, 2739.459961, 444.992004, -1.59698), -- Flag on wall intersect
|
||||
(@GUID+27, 192416, @MAP, 128, 5236.270020, 2739.459961, 444.992004, -1.59698), -- Flag on wall intersect
|
||||
(@GUID+28, 192367, @MAP, 64, 5271.799805, 2704.870117, 445.183014, -3.13286), -- Flag on wall intersect
|
||||
(@GUID+29, 192416, @MAP, 128, 5271.799805, 2704.870117, 445.183014, -3.13286), -- Flag on wall intersect
|
||||
(@GUID+30, 192488, @MAP, 64, 5260.819824, 2631.800049, 433.324005, 3.054330), -- Flag on tower
|
||||
(@GUID+31, 192501, @MAP, 128, 5260.819824, 2631.800049, 433.324005, 3.054330), -- Flag on tower
|
||||
(@GUID+32, 192488, @MAP, 64, 5278.379883, 2613.830078, 433.408997, -1.58825), -- Flag on tower
|
||||
(@GUID+33, 192501, @MAP, 128, 5278.379883, 2613.830078, 433.408997, -1.58825), -- Flag on tower
|
||||
(@GUID+34, 192364, @MAP, 64, 5350.879883, 2622.719971, 444.686005, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+35, 192416, @MAP, 128, 5350.879883, 2622.719971, 444.686005, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+36, 192370, @MAP, 64, 5392.270020, 2639.739990, 435.330994, 1.509710), -- Flag on wall intersect
|
||||
(@GUID+37, 192416, @MAP, 128, 5392.270020, 2639.739990, 435.330994, 1.509710), -- Flag on wall intersect
|
||||
(@GUID+38, 192369, @MAP, 64, 5350.950195, 2640.360107, 435.407990, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+39, 192416, @MAP, 128, 5350.950195, 2640.360107, 435.407990, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+40, 192368, @MAP, 64, 5289.459961, 2704.679932, 435.875000, -0.01745), -- Flag on wall intersect
|
||||
(@GUID+41, 192416, @MAP, 128, 5289.459961, 2704.679932, 435.875000, -0.01745), -- Flag on wall intersect
|
||||
(@GUID+42, 192362, @MAP, 64, 5322.120117, 2763.610107, 444.973999, -1.55334), -- Flag on wall intersect
|
||||
(@GUID+43, 192416, @MAP, 128, 5322.120117, 2763.610107, 444.973999, -1.55334), -- Flag on wall intersect
|
||||
(@GUID+44, 192363, @MAP, 64, 5363.609863, 2763.389893, 445.023987, -1.54462), -- Flag on wall intersect
|
||||
(@GUID+45, 192416, @MAP, 128, 5363.609863, 2763.389893, 445.023987, -1.54462), -- Flag on wall intersect
|
||||
(@GUID+46, 192379, @MAP, 64, 5363.419922, 2781.030029, 435.763000, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+47, 192416, @MAP, 128, 5363.419922, 2781.030029, 435.763000, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+48, 192378, @MAP, 64, 5322.020020, 2781.129883, 435.811005, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+49, 192416, @MAP, 128, 5322.020020, 2781.129883, 435.811005, 1.570800), -- Flag on wall intersect
|
||||
(@GUID+50, 192355, @MAP, 64, 5288.919922, 2820.219971, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+51, 192416, @MAP, 128, 5288.919922, 2820.219971, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+52, 192354, @MAP, 64, 5288.410156, 2861.790039, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+53, 192416, @MAP, 128, 5288.410156, 2861.790039, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+54, 192358, @MAP, 64, 5322.229980, 2899.429932, 435.808014, -1.58825), -- Flag on wall intersect
|
||||
(@GUID+55, 192416, @MAP, 128, 5322.229980, 2899.429932, 435.808014, -1.58825), -- Flag on wall intersect
|
||||
(@GUID+56, 192359, @MAP, 64, 5364.350098, 2899.399902, 435.838989, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+57, 192416, @MAP, 128, 5364.350098, 2899.399902, 435.838989, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+58, 192338, @MAP, 64, 5397.759766, 2873.080078, 455.460999, 3.106650), -- Flag on keep
|
||||
(@GUID+59, 192416, @MAP, 128, 5397.759766, 2873.080078, 455.460999, 3.106650), -- Flag on keep
|
||||
(@GUID+60, 192339, @MAP, 64, 5397.390137, 2809.330078, 455.343994, 3.106650), -- Flag on keep
|
||||
(@GUID+61, 192416, @MAP, 128, 5397.390137, 2809.330078, 455.343994, 3.106650), -- Flag on keep
|
||||
(@GUID+62, 192284, @MAP, 64, 5372.479980, 2862.500000, 409.049011, 3.141590), -- Flag on floor
|
||||
(@GUID+63, 192269, @MAP, 128, 5372.479980, 2862.500000, 409.049011, 3.141590), -- Flag on floor
|
||||
(@GUID+64, 192285, @MAP, 64, 5371.490234, 2820.800049, 409.177002, 3.141590), -- Flag on floor
|
||||
(@GUID+65, 192269, @MAP, 128, 5371.490234, 2820.800049, 409.177002, 3.141590), -- Flag on floor
|
||||
(@GUID+66, 192371, @MAP, 64, 5364.290039, 2916.939941, 445.330994, 1.579520), -- Flag on wall intersect
|
||||
(@GUID+67, 192416, @MAP, 128, 5364.290039, 2916.939941, 445.330994, 1.579520), -- Flag on wall intersect
|
||||
(@GUID+68, 192372, @MAP, 64, 5322.859863, 2916.949951, 445.153992, 1.562070), -- Flag on wall intersect
|
||||
(@GUID+69, 192416, @MAP, 128, 5322.859863, 2916.949951, 445.153992, 1.562070), -- Flag on wall intersect
|
||||
(@GUID+70, 192373, @MAP, 64, 5290.350098, 2976.560059, 435.221008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+71, 192416, @MAP, 128, 5290.350098, 2976.560059, 435.221008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+72, 192360, @MAP, 64, 5352.370117, 3037.090088, 435.252014, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+73, 192416, @MAP, 128, 5352.370117, 3037.090088, 435.252014, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+74, 192361, @MAP, 64, 5392.649902, 3037.110107, 433.713013, -1.52716), -- Flag on wall intersect
|
||||
(@GUID+75, 192416, @MAP, 128, 5392.649902, 3037.110107, 433.713013, -1.52716), -- Flag on wall intersect
|
||||
(@GUID+76, 192356, @MAP, 64, 5237.069824, 2757.030029, 435.795990, 1.518440), -- Flag on wall intersect
|
||||
(@GUID+77, 192416, @MAP, 128, 5237.069824, 2757.030029, 435.795990, 1.518440), -- Flag on wall intersect
|
||||
(@GUID+78, 192352, @MAP, 64, 5173.020020, 2820.929932, 435.720001, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+79, 192416, @MAP, 128, 5173.020020, 2820.929932, 435.720001, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+80, 192353, @MAP, 64, 5172.109863, 2862.570068, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+81, 192416, @MAP, 128, 5172.109863, 2862.570068, 435.721008, 0.017452), -- Flag on wall intersect
|
||||
(@GUID+82, 192357, @MAP, 64, 5235.339844, 2924.340088, 435.040009, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+83, 192416, @MAP, 128, 5235.339844, 2924.340088, 435.040009, -1.57080), -- Flag on wall intersect
|
||||
(@GUID+84, 192350, @MAP, 64, 5270.689941, 2861.780029, 445.058014, -3.11539), -- Flag on wall intersect
|
||||
(@GUID+85, 192416, @MAP, 128, 5270.689941, 2861.780029, 445.058014, -3.11539), -- Flag on wall intersect
|
||||
(@GUID+86, 192351, @MAP, 64, 5271.279785, 2820.159912, 445.200989, -3.13286), -- Flag on wall intersect
|
||||
(@GUID+87, 192416, @MAP, 128, 5271.279785, 2820.159912, 445.200989, -3.13286); -- Flag on wall intersect
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Orb rotation focus
|
||||
UPDATE `creature_template` SET `modelid1`=11868,`modelid2`=169,`minlevel`=80,`maxlevel`=80,`faction_A`=14,`faction_H`=14,`speed_walk`=2.2,`speed_run`=0.785714,`baseattacktime`=2000,`unit_flags`=33554688 WHERE `entry` IN(43280,43281,43282);
|
||||
UPDATE `creature_template` SET `difficulty_entry_1`=43280, `difficulty_entry_2`=43281,`difficulty_entry_3`=43282 WHERE `entry`=40091;
|
||||
|
||||
-- Orb carrier
|
||||
UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=14,`faction_H`=14,`speed_walk`=1.2,`speed_run`=1.14286,`baseattacktime`=2000 WHERE `entry` IN(40470,40471,40472);
|
||||
UPDATE `creature_template` SET `difficulty_entry_1`=40470, `difficulty_entry_2`=40471,`difficulty_entry_3`=40472 WHERE `entry`=40081;
|
||||
|
||||
-- Saviana Ragefire
|
||||
UPDATE `creature_template` SET `exp`=2 WHERE `entry`=39823;
|
||||
|
||||
-- General Zarithrian
|
||||
UPDATE `creature_template` SET `exp`=2 WHERE `entry`=39805;
|
||||
|
||||
-- Twilight Halion
|
||||
UPDATE `creature_template` SET `difficulty_entry_1`=40143, `difficulty_entry_2`=40144,`difficulty_entry_3`=40145 WHERE `entry`=40142;
|
||||
UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`speed_walk`=1.6,`speed_run`=1.42857,`baseattacktime`=1800,`unit_flags`=559168,`dynamicflags`=12 WHERE `entry` IN(40143,40144,40145);
|
||||
|
||||
-- Halion
|
||||
UPDATE `creature_template` SET `speed_walk`=1.6,`speed_run`=1.42857,`baseattacktime`=1500,`unit_flags`=32832,`dynamicflags`=12,`flags_extra`=1 WHERE `entry` IN(39864,39944,39945);
|
||||
UPDATE `creature_template` SET `dmg_multiplier`=50 WHERE `entry`=39944;
|
||||
UPDATE `creature_template` SET `dmg_multiplier`=85 WHERE `entry`=39945;
|
||||
|
||||
-- Onyx Flamecaller
|
||||
UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`faction_A`=103,`faction_H`=103,`exp`=2,`speed_walk`=0.88888,`speed_run`=1.42857,`baseattacktime`=2000,`unit_flags`=32768,`equipment_id`=2468 WHERE `entry`=39815;
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `spell_area` ADD COLUMN `quest_start_status` INT(11) NOT NULL DEFAULT 64; -- default is QUEST_STATUS_REWARDED
|
||||
ALTER TABLE `spell_area` ADD COLUMN `quest_end_status` INT(11) NOT NULL DEFAULT 11; -- default is QUEST_STATUS_COMPLETE | QUEST_STATUS_NONE | QUEST_STATUS_INCOMPLETE
|
||||
UPDATE spell_area SET `quest_start_status` = (1 << 6) | (1 << 3) | (1 << 1) WHERE `quest_start_active` = 1;
|
||||
ALTER TABLE spell_area DROP COLUMN `quest_start_active`;
|
||||
@@ -0,0 +1,17 @@
|
||||
DELETE FROM `trinity_string` WHERE `entry` IN (9986, 9987, 9989, 9990, 9991, 9992, 9993, 9994, 9995, 9996, 9997, 9998, 9999);
|
||||
INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`)
|
||||
VALUES
|
||||
(9986, 'Error', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9987, 'None', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9988, 'Leader', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9989, 'Dps', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9990, 'Healer', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9991, 'Tank', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9992, 'Raid browser', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9993, 'Finished dungeon', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9994, 'In dungeon', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9995, 'Vote kick', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9996, 'Proposal', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9997, 'Queued', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9998, 'Role check', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(9999, 'None', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
@@ -0,0 +1,36 @@
|
||||
-- Gnomeregan/Blastmaster Emi Shortfuse's event
|
||||
DELETE FROM `script_texts` WHERE `entry` BETWEEN -1090028 AND -1090000;
|
||||
DELETE FROM `creature_text` WHERE `entry` IN (7361,7998);
|
||||
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`) VALUES
|
||||
-- Emi Shortfuse
|
||||
(7998,0,0, 'With your help, I can evaluate these tunnels.',12,0,100,0,0,0, 'SAY_BLASTMASTER_0'),
|
||||
(7998,1,0, 'Let''s see if we can find out where these Troggs are coming from... and put a stop to the invasion!',12,0,100,0,0,0, 'SAY_BLASTMASTER_1'),
|
||||
(7998,2,0, 'Such devastation... what horrible mess...',12,0,100,0,0,0, 'SAY_BLASTMASTER_2'),
|
||||
(7998,3,0, 'It''s quiet here...',12,0,100,0,0,0, 'SAY_BLASTMASTER_3'),
|
||||
(7998,4,0, '...too quiet.',12,0,100,0,0,0, 'SAY_BLASTMASTER_4'),
|
||||
(7998,5,0, 'Look! Over there at the tunnel wall!',12,0,100,0,0,0, 'SAY_BLASTMASTER_5'),
|
||||
(7998,6,0, 'Trogg incrusion! Defend me while I blast the hole closed!',12,0,100,0,0,0, 'SAY_BLASTMASTER_6'),
|
||||
(7998,7,0, 'The charges are set. Get back before they blow!',12,0,100,0,0,0, 'SAY_BLASTMASTER_7'),
|
||||
(7998,8,0, 'Incoming blast in 10 seconds!',14,0,100,0,0,0, 'SAY_BLASTMASTER_8'),
|
||||
(7998,9,0, 'Incoming blast in 5 seconds. Clear the tunnel!',14,0,100,0,0,0, 'SAY_BLASTMASTER_9'),
|
||||
(7998,10,0, 'FIRE IN THE HOLE!',14,0,100,0,0,0, 'SAY_BLASTMASTER_10'),
|
||||
(7998,11,0, 'Well done! Without your help I would have never been able to thwart that wave of troggs.',12,0,100,0,0,0, 'SAY_BLASTMASTER_11'),
|
||||
(7998,12,0, 'Did you hear something?',12,0,100,0,0,0, 'SAY_BLASTMASTER_12'),
|
||||
(7998,13,0, 'I heard something over there.',12,0,100,0,0,0, 'SAY_BLASTMASTER_13'),
|
||||
(7998,14,0, 'More troggs! Ward them off as I prepare the explosives!',12,0,100,0,0,0, 'SAY_BLASTMASTER_14'),
|
||||
(7998,15,0, 'The final charge is set. Stand back!',12,0,100,0,0,0, 'SAY_BLASTMASTER_15'),
|
||||
(7998,16,0, 'The final charge is set. Stand back!',12,0,100,0,0,0, 'SAY_BLASTMASTER_16'),
|
||||
(7998,17,0, 'Incoming blast in 10 seconds!',14,0,100,0,0,0, 'SAY_BLASTMASTER_17'),
|
||||
(7998,18,0, 'Incoming blast in 5 seconds. Clear the tunnel!',14,0,100,0,0,0, 'SAY_BLASTMASTER_18'),
|
||||
(7998,19,0, 'I don''t think one charge is going to cut it. Keep fending them off!',12,0,100,0,0,0, 'SAY_BLASTMASTER_19'),
|
||||
(7998,20,0, 'FIRE IN THE HOLE!',14,0,100,0,0,0, 'SAY_BLASTMASTER_20'),
|
||||
(7998,21,0, 'Well done! Without your help I would have never been able to thwart that wave of troggs.',12,0,100,0,0,0, 'SAY_BLASTMASTER_21'),
|
||||
(7998,22,0, 'Did you hear something?',12,0,100,0,0,0, 'SAY_BLASTMASTER_22'),
|
||||
(7998,23,0, 'I heard something over there.',12,0,100,0,0,0, 'SAY_BLASTMASTER_23'),
|
||||
(7998,24,0, 'More troggs! Ward them off as I prepare the explosives!',12,0,100,0,0,0, 'SAY_BLASTMASTER_24'),
|
||||
(7998,25,0, 'The final charge is set. Stand back!',12,0,100,0,0,0, 'SAY_BLASTMASTER_25'),
|
||||
(7998,26,0, '10 seconds to blast! Stand back!!!',14,0,100,0,0,0, 'SAY_BLASTMASTER_26'),
|
||||
(7998,27,0, '5 seconds until detonation!!',14,0,100,0,0,0, 'SAY_BLASTMASTER_27'),
|
||||
(7998,28,0, 'Superb! Because of your help, my people stand a chance of re-taking our belowed city. Three cheers to you!',12,0,100,0,0,0, 'SAY_BLASTMASTER_28'),
|
||||
-- Grubbis
|
||||
(7361,0,0, 'We come from below! You can never stop us!',14,0,100,0,0,0, 'SAY_GRUBBIS');
|
||||
@@ -71,6 +71,8 @@ void PetAI::_stopAttack()
|
||||
}
|
||||
|
||||
me->AttackStop();
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->SendMeleeAttackStop(); // Should stop pet's attack button from flashing
|
||||
me->GetCharmInfo()->SetIsCommandAttack(false);
|
||||
HandleReturnMovement();
|
||||
}
|
||||
@@ -89,7 +91,8 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||
m_updateAlliesTimer -= diff;
|
||||
|
||||
// me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
|
||||
if (me->getVictim())
|
||||
// Must also check if victim is alive
|
||||
if (me->getVictim() && me->getVictim()->isAlive())
|
||||
{
|
||||
// is only necessary to stop casting, the pet must not exit combat
|
||||
if (me->getVictim()->HasBreakableByDamageCrowdControlAura(me))
|
||||
@@ -121,11 +124,17 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||
if (nextTarget)
|
||||
AttackStart(nextTarget);
|
||||
else
|
||||
{
|
||||
me->GetCharmInfo()->SetIsCommandAttack(false);
|
||||
HandleReturnMovement();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
me->GetCharmInfo()->SetIsCommandAttack(false);
|
||||
HandleReturnMovement();
|
||||
}
|
||||
}
|
||||
else if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW)) // no charm info and no victim
|
||||
HandleReturnMovement();
|
||||
|
||||
@@ -301,7 +310,7 @@ void PetAI::KilledUnit(Unit* victim)
|
||||
// Can't use _stopAttack() because that activates movement handlers and ignores
|
||||
// next target selection
|
||||
me->AttackStop();
|
||||
me->GetCharmInfo()->SetIsCommandAttack(false);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->SendMeleeAttackStop(); // Stops the pet's 'Attack' button from flashing
|
||||
|
||||
Unit* nextTarget = SelectNextTarget();
|
||||
@@ -309,7 +318,10 @@ void PetAI::KilledUnit(Unit* victim)
|
||||
if (nextTarget)
|
||||
AttackStart(nextTarget);
|
||||
else
|
||||
{
|
||||
me->GetCharmInfo()->SetIsCommandAttack(false);
|
||||
HandleReturnMovement(); // Return
|
||||
}
|
||||
}
|
||||
|
||||
void PetAI::AttackStart(Unit* target)
|
||||
|
||||
@@ -32,8 +32,6 @@ class PetAI : public CreatureAI
|
||||
explicit PetAI(Creature* c);
|
||||
|
||||
void EnterEvadeMode();
|
||||
void JustDied(Unit* /*who*/) { _stopAttack(); }
|
||||
|
||||
void UpdateAI(const uint32);
|
||||
static int Permissible(const Creature*);
|
||||
|
||||
|
||||
@@ -2821,10 +2821,12 @@ void SmartScript::InitTimer(SmartScriptHolder& e)
|
||||
case SMART_EVENT_UPDATE:
|
||||
case SMART_EVENT_UPDATE_IC:
|
||||
case SMART_EVENT_UPDATE_OOC:
|
||||
case SMART_EVENT_OOC_LOS:
|
||||
case SMART_EVENT_IC_LOS:
|
||||
RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max);
|
||||
break;
|
||||
case SMART_EVENT_IC_LOS:
|
||||
case SMART_EVENT_OOC_LOS:
|
||||
RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax);
|
||||
break;
|
||||
default:
|
||||
e.active = true;
|
||||
break;
|
||||
|
||||
@@ -1596,6 +1596,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
|
||||
{
|
||||
// Check map id requirement
|
||||
if (miscValue1 == achievementCriteria->win_arena.mapID)
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
// std case: not exist in DBC, not triggered in code as result
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
|
||||
@@ -1606,7 +1613,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
break;
|
||||
// FIXME: not triggered in code as result, need to implement
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
|
||||
@@ -1749,6 +1755,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
return progress->counter >= achievementCriteria->use_lfg.dungeonsComplete;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
return progress->counter >= achievementCriteria->get_killing_blow.killCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
|
||||
return achievementCriteria->win_arena.count && progress->counter >= achievementCriteria->win_arena.count;
|
||||
// handle all statistic-only criteria here
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
|
||||
|
||||
@@ -188,29 +188,6 @@ bool BattlefieldWG::SetupBattlefield()
|
||||
go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetDefenderTeam()]);
|
||||
}
|
||||
|
||||
// Spawn banners in the keep
|
||||
for (uint8 i = 0; i < WG_KEEPGAMEOBJECT_MAX; i++)
|
||||
{
|
||||
if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entryHorde, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o))
|
||||
{
|
||||
go->SetRespawnTime(GetDefenderTeam()? RESPAWN_ONE_DAY : RESPAWN_IMMEDIATELY);
|
||||
m_KeepGameObject[1].insert(go);
|
||||
}
|
||||
if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entryAlliance, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o))
|
||||
{
|
||||
go->SetRespawnTime(GetDefenderTeam()? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY);
|
||||
m_KeepGameObject[0].insert(go);
|
||||
}
|
||||
}
|
||||
|
||||
// Show defender banner in keep
|
||||
for (GameObjectSet::const_iterator itr = m_KeepGameObject[GetDefenderTeam()].begin(); itr != m_KeepGameObject[GetDefenderTeam()].end(); ++itr)
|
||||
(*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY);
|
||||
|
||||
// Hide attackant banner in keep
|
||||
for (GameObjectSet::const_iterator itr = m_KeepGameObject[GetAttackerTeam()].begin(); itr != m_KeepGameObject[GetAttackerTeam()].end(); ++itr)
|
||||
(*itr)->SetRespawnTime(RESPAWN_ONE_DAY);
|
||||
|
||||
UpdateCounterVehicle(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -440,10 +440,9 @@ uint32 const VehNumWorldState[] = { 3680, 3490 };
|
||||
uint32 const MaxVehNumWorldState[] = { 3681, 3491 };
|
||||
uint32 const ClockWorldState[] = { 3781, 4354 };
|
||||
uint32 const WintergraspFaction[] = { 1732, 1735, 35 };
|
||||
float const WintergraspStalkerPos[] = { 0, 0, 0, 0 };
|
||||
float const WintergraspStalkerPos[] = { 4948.985f, 2937.789f, 550.5172f, 1.815142f };
|
||||
|
||||
uint8 const WG_MAX_OBJ = 32;
|
||||
uint8 const WG_KEEPGAMEOBJECT_MAX = 44;
|
||||
uint8 const WG_MAX_TURRET = 15;
|
||||
uint8 const WG_MAX_KEEP_NPC = 39;
|
||||
uint8 const WG_MAX_OUTSIDE_NPC = 14;
|
||||
@@ -580,6 +579,19 @@ struct WintergraspBuildingSpawnData
|
||||
uint32 nameId;
|
||||
};
|
||||
|
||||
struct WintergraspRebuildableBuildingData
|
||||
{
|
||||
uint32 entry;
|
||||
uint64 Guid;
|
||||
uint32 WorldState;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float o;
|
||||
uint32 type;
|
||||
uint32 nameId;
|
||||
};
|
||||
|
||||
const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] =
|
||||
{
|
||||
// Wall (Not spawned in db)
|
||||
@@ -628,99 +640,6 @@ const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] =
|
||||
{ GO_WINTERGRASP_VAULT_GATE, 3773, 5397.11f, 2841.54f, 425.899f, 3.14159f, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST, 0 },
|
||||
};
|
||||
|
||||
|
||||
// *********************************************************
|
||||
// **********Keep Element(GameObject,Creature)**************
|
||||
// *********************************************************
|
||||
|
||||
// Keep gameobject
|
||||
// 192488 : 10 in sql, 19 in header
|
||||
// 192501 : 12 in sql, 17 in header
|
||||
// 192416 : 1 in sql, 33 in header
|
||||
// 192374 : 1 in sql, 1 in header
|
||||
// 192375 : 1 in sql, 1 in header
|
||||
// 192336 : 1 in sql, 1 in header
|
||||
// 192255 : 1 in sql, 1 in header
|
||||
// 192269 : 1 in sql, 7 in header
|
||||
// 192254 : 1 in sql, 1 in header
|
||||
// 192349 : 1 in sql, 1 in header
|
||||
// 192366 : 1 in sql, 3 in header
|
||||
// 192367 : 1 in sql, 1 in header
|
||||
// 192364 : 1 in sql, 1 in header
|
||||
// 192370 : 1 in sql, 1 in header
|
||||
// 192369 : 1 in sql, 1 in header
|
||||
// 192368 : 1 in sql, 1 in header
|
||||
// 192362 : 1 in sql, 1 in header
|
||||
// 192363 : 1 in sql, 1 in header
|
||||
// 192379 : 1 in sql, 1 in header
|
||||
// 192378 : 1 in sql, 1 in header
|
||||
// 192355 : 1 in sql, 1 in header
|
||||
// 192354 : 1 in sql, 1 in header
|
||||
// 192358 : 1 in sql, 1 in header
|
||||
// 192359 : 1 in sql, 1 in header
|
||||
// 192338 : 1 in sql, 1 in header
|
||||
// 192339 : 1 in sql, 1 in header
|
||||
// 192284 : 1 in sql, 1 in header
|
||||
// 192285 : 1 in sql, 1 in header
|
||||
// 192371 : 1 in sql, 1 in header
|
||||
// 192372 : 1 in sql, 1 in header
|
||||
// 192373 : 1 in sql, 1 in header
|
||||
// 192360 : 1 in sql, 1 in header
|
||||
// 192361 : 1 in sql, 1 in header
|
||||
// 192356 : 1 in sql, 1 in header
|
||||
// 192352 : 1 in sql, 1 in header
|
||||
// 192353 : 1 in sql, 1 in header
|
||||
// 192357 : 1 in sql, 1 in header
|
||||
// 192350 : 1 in sql, 1 in header
|
||||
// 192351 : 1 in sql, 1 in header
|
||||
const WintergraspObjectPositionData WGKeepGameObject[WG_KEEPGAMEOBJECT_MAX] =
|
||||
{
|
||||
{ 5262.540039f, 3047.949951f, 432.054993f, 3.106650f, 192488, 192501 }, // Flag on tower
|
||||
{ 5272.939941f, 2976.550049f, 444.492004f, 3.124120f, 192374, 192416 }, // Flag on Wall Intersect
|
||||
{ 5235.189941f, 2941.899902f, 444.278015f, 1.588250f, 192375, 192416 }, // Flag on Wall Intersect
|
||||
{ 5163.129883f, 2952.590088f, 433.502991f, 1.535890f, 192488, 192501 }, // Flag on tower
|
||||
{ 5145.109863f, 2935.000000f, 433.385986f, 3.141590f, 192488, 192501 }, // Flag on tower
|
||||
{ 5158.810059f, 2883.129883f, 431.618011f, 3.141590f, 192488, 192416 }, // Flag on wall
|
||||
{ 5154.490234f, 2862.149902f, 445.011993f, 3.141590f, 192336, 192416 }, // Flag on Wall Intersect
|
||||
{ 5154.520020f, 2853.310059f, 409.183014f, 3.141590f, 192255, 192269 }, // Flag on the floor
|
||||
{ 5154.459961f, 2828.939941f, 409.188995f, 3.141590f, 192254, 192269 }, // Flag on the floor
|
||||
{ 5155.310059f, 2820.739990f, 444.979004f, -3.13286f, 192349, 192416 }, // Flag on wall intersect
|
||||
{ 5160.339844f, 2798.610107f, 430.769012f, 3.141590f, 192488, 192416 }, // Flag on wall
|
||||
{ 5146.040039f, 2747.209961f, 433.584015f, 3.071770f, 192488, 192501 }, // Flag on tower
|
||||
{ 5163.779785f, 2729.679932f, 433.394012f, -1.58825f, 192488, 192501 }, // Flag on tower
|
||||
{ 5236.270020f, 2739.459961f, 444.992004f, -1.59698f, 192366, 192416 }, // Flag on wall intersect
|
||||
{ 5271.799805f, 2704.870117f, 445.183014f, -3.13286f, 192367, 192416 }, // Flag on wall intersect
|
||||
{ 5260.819824f, 2631.800049f, 433.324005f, 3.054330f, 192488, 192501 }, // Flag on tower
|
||||
{ 5278.379883f, 2613.830078f, 433.408997f, -1.58825f, 192488, 192501 }, // Flag on tower
|
||||
{ 5350.879883f, 2622.719971f, 444.686005f, -1.57080f, 192364, 192416 }, // Flag on wall intersect
|
||||
{ 5392.270020f, 2639.739990f, 435.330994f, 1.509710f, 192370, 192416 }, // Flag on wall intersect
|
||||
{ 5350.950195f, 2640.360107f, 435.407990f, 1.570800f, 192369, 192416 }, // Flag on wall intersect
|
||||
{ 5289.459961f, 2704.679932f, 435.875000f, -0.01745f, 192368, 192416 }, // Flag on wall intersect
|
||||
{ 5322.120117f, 2763.610107f, 444.973999f, -1.55334f, 192362, 192416 }, // Flag on wall intersect
|
||||
{ 5363.609863f, 2763.389893f, 445.023987f, -1.54462f, 192363, 192416 }, // Flag on wall intersect
|
||||
{ 5363.419922f, 2781.030029f, 435.763000f, 1.570800f, 192379, 192416 }, // Flag on wall intersect
|
||||
{ 5322.020020f, 2781.129883f, 435.811005f, 1.570800f, 192378, 192416 }, // Flag on wall intersect
|
||||
{ 5288.919922f, 2820.219971f, 435.721008f, 0.017452f, 192355, 192416 }, // Flag on wall intersect
|
||||
{ 5288.410156f, 2861.790039f, 435.721008f, 0.017452f, 192354, 192416 }, // Flag on wall intersect
|
||||
{ 5322.229980f, 2899.429932f, 435.808014f, -1.58825f, 192358, 192416 }, // Flag on wall intersect
|
||||
{ 5364.350098f, 2899.399902f, 435.838989f, -1.57080f, 192359, 192416 }, // Flag on wall intersect
|
||||
{ 5397.759766f, 2873.080078f, 455.460999f, 3.106650f, 192338, 192416 }, // Flag on keep
|
||||
{ 5397.390137f, 2809.330078f, 455.343994f, 3.106650f, 192339, 192416 }, // Flag on keep
|
||||
{ 5372.479980f, 2862.500000f, 409.049011f, 3.141590f, 192284, 192269 }, // Flag on floor
|
||||
{ 5371.490234f, 2820.800049f, 409.177002f, 3.141590f, 192285, 192269 }, // Flag on floor
|
||||
{ 5364.290039f, 2916.939941f, 445.330994f, 1.579520f, 192371, 192416 }, // Flag on wall intersect
|
||||
{ 5322.859863f, 2916.949951f, 445.153992f, 1.562070f, 192372, 192416 }, // Flag on wall intersect
|
||||
{ 5290.350098f, 2976.560059f, 435.221008f, 0.017452f, 192373, 192416 }, // Flag on wall intersect
|
||||
{ 5352.370117f, 3037.090088f, 435.252014f, -1.57080f, 192360, 192416 }, // Flag on wall intersect
|
||||
{ 5392.649902f, 3037.110107f, 433.713013f, -1.52716f, 192361, 192416 }, // Flag on wall intersect
|
||||
{ 5237.069824f, 2757.030029f, 435.795990f, 1.518440f, 192356, 192416 }, // Flag on wall intersect
|
||||
{ 5173.020020f, 2820.929932f, 435.720001f, 0.017452f, 192352, 192416 }, // Flag on wall intersect
|
||||
{ 5172.109863f, 2862.570068f, 435.721008f, 0.017452f, 192353, 192416 }, // Flag on wall intersect
|
||||
{ 5235.339844f, 2924.340088f, 435.040009f, -1.57080f, 192357, 192416 }, // Flag on wall intersect
|
||||
{ 5270.689941f, 2861.780029f, 445.058014f, -3.11539f, 192350, 192416 }, // Flag on wall intersect
|
||||
{ 5271.279785f, 2820.159912f, 445.200989f, -3.13286f, 192351, 192416 } // Flag on wall intersect
|
||||
};
|
||||
|
||||
const Position WGTurret[WG_MAX_TURRET] =
|
||||
{
|
||||
{ 5391.19f, 3060.8f, 419.616f, 1.69557f },
|
||||
|
||||
@@ -523,6 +523,8 @@ inline void Battleground::_ProcessJoin(uint32 diff)
|
||||
|
||||
player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
player->ResetAllPowers();
|
||||
if (!player->isGameMaster())
|
||||
{
|
||||
// remove auras with duration lower than 30s
|
||||
Unit::AuraApplicationMap & auraMap = player->GetAppliedAuras();
|
||||
for (Unit::AuraApplicationMap::iterator iter = auraMap.begin(); iter != auraMap.end();)
|
||||
@@ -539,6 +541,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
@@ -856,6 +859,7 @@ void Battleground::EndBattleground(uint32 winner)
|
||||
// update achievement BEFORE personal rating update
|
||||
uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot());
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId());
|
||||
|
||||
winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ bool BattlegroundSA::ResetObjs()
|
||||
uint32 atF = BG_SA_Factions[Attackers];
|
||||
uint32 defF = BG_SA_Factions[Attackers ? TEAM_ALLIANCE : TEAM_HORDE];
|
||||
|
||||
for (uint8 i = 0; i <BG_SA_MAXOBJ; i++)
|
||||
for (uint8 i = 0; i < BG_SA_MAXOBJ; i++)
|
||||
DelObject(i);
|
||||
|
||||
for (uint8 i = 0; i < BG_SA_MAXNPC; i++)
|
||||
@@ -94,14 +94,16 @@ bool BattlegroundSA::ResetObjs()
|
||||
|
||||
for (uint8 i = BG_SA_BOAT_ONE; i < BG_SA_SIGIL_1; i++)
|
||||
{
|
||||
uint32 boatid=0;
|
||||
uint32 boatid = 0;
|
||||
switch (i)
|
||||
{
|
||||
case BG_SA_BOAT_ONE:
|
||||
boatid= Attackers ? BG_SA_BOAT_ONE_H : BG_SA_BOAT_ONE_A;
|
||||
boatid = Attackers ? BG_SA_BOAT_ONE_H : BG_SA_BOAT_ONE_A;
|
||||
break;
|
||||
case BG_SA_BOAT_TWO:
|
||||
boatid= Attackers ? BG_SA_BOAT_TWO_H : BG_SA_BOAT_TWO_A;
|
||||
boatid = Attackers ? BG_SA_BOAT_TWO_H : BG_SA_BOAT_TWO_A;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!AddObject(i, boatid, BG_SA_ObjSpawnlocs[i][0],
|
||||
@@ -110,6 +112,7 @@ bool BattlegroundSA::ResetObjs()
|
||||
BG_SA_ObjSpawnlocs[i][3], 0, 0, 0, 0, RESPAWN_ONE_DAY))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8 i = BG_SA_SIGIL_1; i < BG_SA_CENTRAL_FLAG; i++)
|
||||
{
|
||||
if (!AddObject(i, BG_SA_ObjEntries[i],
|
||||
@@ -127,7 +130,7 @@ bool BattlegroundSA::ResetObjs()
|
||||
|
||||
//Cannons and demolishers - NPCs are spawned
|
||||
//By capturing GYs.
|
||||
for (uint8 i = 0; i < BG_SA_NPC_SPARKLIGHT; i++)
|
||||
for (uint8 i = 0; i < BG_SA_DEMOLISHER_5; i++)
|
||||
{
|
||||
if (!AddCreature(BG_SA_NpcEntries[i], i, (Attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE),
|
||||
BG_SA_NpcSpawnlocs[i][0], BG_SA_NpcSpawnlocs[i][1],
|
||||
@@ -153,8 +156,8 @@ bool BattlegroundSA::ResetObjs()
|
||||
TotalTime = 0;
|
||||
ShipsStarted = false;
|
||||
|
||||
//Graveyards!
|
||||
for (uint8 i = 0;i < BG_SA_MAX_GY; i++)
|
||||
//Graveyards
|
||||
for (uint8 i = 0; i < BG_SA_MAX_GY; i++)
|
||||
{
|
||||
WorldSafeLocsEntry const* sg = NULL;
|
||||
sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
|
||||
@@ -181,7 +184,7 @@ bool BattlegroundSA::ResetObjs()
|
||||
//GY capture points
|
||||
for (uint8 i = BG_SA_CENTRAL_FLAG; i < BG_SA_PORTAL_DEFFENDER_BLUE; i++)
|
||||
{
|
||||
AddObject(i, (BG_SA_ObjEntries[i] - (Attackers == TEAM_ALLIANCE ? 1:0)),
|
||||
AddObject(i, (BG_SA_ObjEntries[i] - (Attackers == TEAM_ALLIANCE ? 1 : 0)),
|
||||
BG_SA_ObjSpawnlocs[i][0], BG_SA_ObjSpawnlocs[i][1],
|
||||
BG_SA_ObjSpawnlocs[i][2], BG_SA_ObjSpawnlocs[i][3],
|
||||
0, 0, 0, 0, RESPAWN_ONE_DAY);
|
||||
@@ -206,14 +209,14 @@ bool BattlegroundSA::ResetObjs()
|
||||
GetBGObject(i)->SetUInt32Value(GAMEOBJECT_FACTION, atF);
|
||||
}
|
||||
|
||||
//Player may enter BEFORE we set up bG - lets update his worldstates anyway...
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE, GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE, GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE, GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
//Player may enter BEFORE we set up BG - lets update his worldstates anyway...
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE, GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE, GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE, GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
|
||||
if (Attackers == TEAM_ALLIANCE)
|
||||
{
|
||||
@@ -254,6 +257,9 @@ bool BattlegroundSA::ResetObjs()
|
||||
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
|
||||
SendTransportInit(player);
|
||||
|
||||
// set status manually so preparation is cast correctly in 2nd round too
|
||||
SetStatus(STATUS_WAIT_JOIN);
|
||||
|
||||
TeleportPlayers();
|
||||
return true;
|
||||
}
|
||||
@@ -295,7 +301,8 @@ void BattlegroundSA::PostUpdateImpl(uint32 diff)
|
||||
InitSecondRound = false;
|
||||
SendMessageToAll(LANG_BG_SA_ROUND_TWO_ONE_MINUTE, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWaitTimer -= diff;
|
||||
return;
|
||||
@@ -312,7 +319,7 @@ void BattlegroundSA::PostUpdateImpl(uint32 diff)
|
||||
ToggleTimer();
|
||||
DemolisherStartState(false);
|
||||
Status = BG_SA_ROUND_ONE;
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, (Attackers == TEAM_ALLIANCE)?23748:21702);
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, (Attackers == TEAM_ALLIANCE) ? 23748 : 21702);
|
||||
}
|
||||
if (TotalTime >= BG_SA_BOAT_START)
|
||||
StartShips();
|
||||
@@ -332,7 +339,12 @@ void BattlegroundSA::PostUpdateImpl(uint32 diff)
|
||||
ToggleTimer();
|
||||
DemolisherStartState(false);
|
||||
Status = BG_SA_ROUND_TWO;
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, (Attackers == TEAM_ALLIANCE)?23748:21702);
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, (Attackers == TEAM_ALLIANCE) ? 23748 : 21702);
|
||||
// status was set to STATUS_WAIT_JOIN manually for Preparation, set it back now
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if (Player* p = ObjectAccessor::FindPlayer(itr->first))
|
||||
p->RemoveAurasDueToSpell(SPELL_PREPARATION);
|
||||
}
|
||||
if (TotalTime >= 30000)
|
||||
{
|
||||
@@ -371,7 +383,6 @@ void BattlegroundSA::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
RoundScores[1].time = BG_SA_ROUNDLENGTH;
|
||||
RoundScores[1].winner = (Attackers == TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE;
|
||||
|
||||
if (RoundScores[0].time == RoundScores[1].time)
|
||||
EndBattleground(0);
|
||||
else if (RoundScores[0].time < RoundScores[1].time)
|
||||
@@ -411,7 +422,7 @@ void BattlegroundSA::FillInitialWorldStates(WorldPacket& data)
|
||||
|
||||
data << uint32(BG_SA_BONUS_TIMER) << uint32(0);
|
||||
|
||||
data << uint32(BG_SA_HORDE_ATTACKS)<< horde_attacks;
|
||||
data << uint32(BG_SA_HORDE_ATTACKS) << horde_attacks;
|
||||
data << uint32(BG_SA_ALLY_ATTACKS) << ally_attacks;
|
||||
|
||||
//Time will be sent on first update...
|
||||
@@ -420,13 +431,13 @@ void BattlegroundSA::FillInitialWorldStates(WorldPacket& data)
|
||||
data << uint32(BG_SA_TIMER_SEC_TENS) << uint32(0);
|
||||
data << uint32(BG_SA_TIMER_SEC_DECS) << uint32(0);
|
||||
|
||||
data << uint32(BG_SA_RIGHT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
data << uint32(BG_SA_LEFT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
data << uint32(BG_SA_CENTER_GY_HORDE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE?1:0);
|
||||
data << uint32(BG_SA_RIGHT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
data << uint32(BG_SA_LEFT_GY_HORDE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
data << uint32(BG_SA_CENTER_GY_HORDE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_HORDE ? 1 : 0);
|
||||
|
||||
data << uint32(BG_SA_RIGHT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
data << uint32(BG_SA_LEFT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
data << uint32(BG_SA_CENTER_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE?1:0);
|
||||
data << uint32(BG_SA_RIGHT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_RIGHT_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
data << uint32(BG_SA_LEFT_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_LEFT_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
data << uint32(BG_SA_CENTER_GY_ALLIANCE) << uint32(GraveyardStatus[BG_SA_CENTRAL_CAPTURABLE_GY] == TEAM_ALLIANCE ? 1 : 0);
|
||||
|
||||
data << uint32(BG_SA_HORDE_DEFENCE_TOKEN) << ally_attacks;
|
||||
data << uint32(BG_SA_ALLIANCE_DEFENCE_TOKEN) << horde_attacks;
|
||||
@@ -450,9 +461,9 @@ void BattlegroundSA::AddPlayer(Player* player)
|
||||
player->CastSpell(player, 12438, true);//Without this player falls before boat loads...
|
||||
|
||||
if (urand(0, 1))
|
||||
player->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
|
||||
player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
|
||||
else
|
||||
player->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
|
||||
player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -513,14 +524,18 @@ void BattlegroundSA::TeleportPlayers()
|
||||
player->ResetAllPowers();
|
||||
player->CombatStopWithPets(true);
|
||||
|
||||
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if (Player* p = ObjectAccessor::FindPlayer(itr->first))
|
||||
p->CastSpell(p, SPELL_PREPARATION, true);
|
||||
|
||||
if (player->GetTeamId() == Attackers)
|
||||
{
|
||||
player->CastSpell(player, 12438, true); //Without this player falls before boat loads...
|
||||
|
||||
if (urand(0, 1))
|
||||
player->TeleportTo(607, 2682.936f, -830.368f, 50.0f, 2.895f, 0);
|
||||
player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
|
||||
else
|
||||
player->TeleportTo(607, 2577.003f, 980.261f, 50.0f, 0.807f, 0);
|
||||
player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
|
||||
}
|
||||
else
|
||||
player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0);
|
||||
@@ -572,13 +587,13 @@ void BattlegroundSA::OverrideGunFaction()
|
||||
if (!BgCreatures[0])
|
||||
return;
|
||||
|
||||
for (uint8 i = BG_SA_GUN_1; i <= BG_SA_GUN_10;i++)
|
||||
for (uint8 i = BG_SA_GUN_1; i <= BG_SA_GUN_10; i++)
|
||||
{
|
||||
if (Creature* gun = GetBGCreature(i))
|
||||
gun->setFaction(BG_SA_Factions[Attackers? TEAM_ALLIANCE : TEAM_HORDE]);
|
||||
gun->setFaction(BG_SA_Factions[Attackers ? TEAM_ALLIANCE : TEAM_HORDE]);
|
||||
}
|
||||
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4;i++)
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
|
||||
{
|
||||
if (Creature* dem = GetBGCreature(i))
|
||||
dem->setFaction(BG_SA_Factions[Attackers]);
|
||||
@@ -590,6 +605,7 @@ void BattlegroundSA::DemolisherStartState(bool start)
|
||||
if (!BgCreatures[0])
|
||||
return;
|
||||
|
||||
// set flags only for the demolishers on the beach, factory ones dont need it
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
|
||||
{
|
||||
if (Creature* dem = GetBGCreature(i))
|
||||
@@ -636,6 +652,8 @@ void BattlegroundSA::DestroyGate(Player* player, GameObject* go)
|
||||
if (GateStatus[BG_SA_RED_GATE] == BG_SA_GATE_DESTROYED)
|
||||
rewardHonor = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 5)
|
||||
@@ -663,7 +681,7 @@ WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveYard(Player* player)
|
||||
safeloc = BG_SA_GYEntries[BG_SA_DEFENDER_LAST_GY];
|
||||
|
||||
closest = sWorldSafeLocsStore.LookupEntry(safeloc);
|
||||
nearest = sqrt((closest->x - x)*(closest->x - x) + (closest->y - y)*(closest->y - y)+(closest->z - z)*(closest->z - z));
|
||||
nearest = sqrt((closest->x - x)*(closest->x - x) + (closest->y - y)*(closest->y - y) + (closest->z - z)*(closest->z - z));
|
||||
|
||||
for (uint8 i = BG_SA_RIGHT_CAPTURABLE_GY; i < BG_SA_MAX_GY; i++)
|
||||
{
|
||||
@@ -671,7 +689,7 @@ WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveYard(Player* player)
|
||||
continue;
|
||||
|
||||
ret = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]);
|
||||
dist = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y)+(ret->z - z)*(ret->z - z));
|
||||
dist = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y) + (ret->z - z)*(ret->z - z));
|
||||
if (dist < nearest)
|
||||
{
|
||||
closest = ret;
|
||||
@@ -737,7 +755,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
case BG_SA_LEFT_CAPTURABLE_GY:
|
||||
flag = BG_SA_LEFT_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0:1)),
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
|
||||
BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
|
||||
|
||||
@@ -746,8 +764,18 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
|
||||
BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
|
||||
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
for (uint8 j = BG_SA_DEMOLISHER_7; j <= BG_SA_DEMOLISHER_8; j++)
|
||||
{
|
||||
AddCreature(BG_SA_NpcEntries[j], j, (Attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE),
|
||||
BG_SA_NpcSpawnlocs[j][0], BG_SA_NpcSpawnlocs[j][1],
|
||||
BG_SA_NpcSpawnlocs[j][2], BG_SA_NpcSpawnlocs[j][3], 600);
|
||||
|
||||
if (Creature* dem = GetBGCreature(j))
|
||||
dem->setFaction(BG_SA_Factions[Attackers]);
|
||||
}
|
||||
|
||||
UpdateWorldState(BG_SA_LEFT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 1 : 0));
|
||||
UpdateWorldState(BG_SA_LEFT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 0 : 1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_WEST);
|
||||
else
|
||||
@@ -756,7 +784,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
case BG_SA_RIGHT_CAPTURABLE_GY:
|
||||
flag = BG_SA_RIGHT_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0:1)),
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
|
||||
BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
|
||||
|
||||
@@ -765,8 +793,18 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
BG_SA_NpcSpawnlocs[npc][0], BG_SA_NpcSpawnlocs[npc][1],
|
||||
BG_SA_NpcSpawnlocs[npc][2], BG_SA_NpcSpawnlocs[npc][3]);
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
for (uint8 j = BG_SA_DEMOLISHER_5; j <= BG_SA_DEMOLISHER_6; j++)
|
||||
{
|
||||
AddCreature(BG_SA_NpcEntries[j], j, (Attackers == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE),
|
||||
BG_SA_NpcSpawnlocs[j][0], BG_SA_NpcSpawnlocs[j][1],
|
||||
BG_SA_NpcSpawnlocs[j][2], BG_SA_NpcSpawnlocs[j][3], 600);
|
||||
|
||||
if (Creature* dem = GetBGCreature(j))
|
||||
dem->setFaction(BG_SA_Factions[Attackers]);
|
||||
}
|
||||
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 1 : 0));
|
||||
UpdateWorldState(BG_SA_RIGHT_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 0 : 1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_EAST);
|
||||
else
|
||||
@@ -775,12 +813,12 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
case BG_SA_CENTRAL_CAPTURABLE_GY:
|
||||
flag = BG_SA_CENTRAL_FLAG;
|
||||
DelObject(flag);
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0:1)),
|
||||
AddObject(flag, (BG_SA_ObjEntries[flag] - (Source->GetTeamId() == TEAM_ALLIANCE ? 0 : 1)),
|
||||
BG_SA_ObjSpawnlocs[flag][0], BG_SA_ObjSpawnlocs[flag][1],
|
||||
BG_SA_ObjSpawnlocs[flag][2], BG_SA_ObjSpawnlocs[flag][3], 0, 0, 0, 0, RESPAWN_ONE_DAY);
|
||||
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE? 1:0));
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE? 0:1));
|
||||
UpdateWorldState(BG_SA_CENTER_GY_ALLIANCE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 1 : 0));
|
||||
UpdateWorldState(BG_SA_CENTER_GY_HORDE, (GraveyardStatus[i] == TEAM_ALLIANCE ? 0 : 1));
|
||||
if (Source->GetTeamId() == TEAM_ALLIANCE)
|
||||
SendWarningToAll(LANG_BG_SA_A_GY_SOUTH);
|
||||
else
|
||||
@@ -794,7 +832,11 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
|
||||
|
||||
void BattlegroundSA::EventPlayerUsedGO(Player* Source, GameObject* object)
|
||||
{
|
||||
if (object->GetEntry() == BG_SA_ObjEntries[BG_SA_TITAN_RELIC] && GateStatus[BG_SA_ANCIENT_GATE] == BG_SA_GATE_DESTROYED && GateStatus[BG_SA_YELLOW_GATE] == BG_SA_GATE_DESTROYED && (GateStatus[BG_SA_PURPLE_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_RED_GATE] == BG_SA_GATE_DESTROYED) && (GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED))
|
||||
if (object->GetEntry() == BG_SA_ObjEntries[BG_SA_TITAN_RELIC] &&
|
||||
GateStatus[BG_SA_ANCIENT_GATE] == BG_SA_GATE_DESTROYED &&
|
||||
GateStatus[BG_SA_YELLOW_GATE] == BG_SA_GATE_DESTROYED &&
|
||||
(GateStatus[BG_SA_PURPLE_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_RED_GATE] == BG_SA_GATE_DESTROYED) &&
|
||||
(GateStatus[BG_SA_GREEN_GATE] == BG_SA_GATE_DESTROYED || GateStatus[BG_SA_BLUE_GATE] == BG_SA_GATE_DESTROYED))
|
||||
{
|
||||
if (Source->GetTeamId() == Attackers)
|
||||
{
|
||||
@@ -872,7 +914,7 @@ void BattlegroundSA::EndBattleground(uint32 winner)
|
||||
|
||||
void BattlegroundSA::UpdateDemolisherSpawns()
|
||||
{
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_4; i++)
|
||||
for (uint8 i = BG_SA_DEMOLISHER_1; i <= BG_SA_DEMOLISHER_8; i++)
|
||||
{
|
||||
if (BgCreatures[i])
|
||||
{
|
||||
@@ -881,19 +923,14 @@ void BattlegroundSA::UpdateDemolisherSpawns()
|
||||
if (Demolisher->isDead())
|
||||
{
|
||||
// Demolisher is not in list
|
||||
if (DemoliserRespawnList.find(i)==DemoliserRespawnList.end())
|
||||
if (DemoliserRespawnList.find(i) == DemoliserRespawnList.end())
|
||||
{
|
||||
DemoliserRespawnList[i]=getMSTime()+30000;
|
||||
DemoliserRespawnList[i] = getMSTime()+30000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DemoliserRespawnList[i] < getMSTime())
|
||||
{
|
||||
uint8 gy = (i >= BG_SA_DEMOLISHER_3 ? 3 : 2);
|
||||
if (GraveyardStatus[gy] == Attackers)
|
||||
Demolisher->Relocate(BG_SA_NpcSpawnlocs[i + 11][0], BG_SA_NpcSpawnlocs[i + 11][1],
|
||||
BG_SA_NpcSpawnlocs[i + 11][2], BG_SA_NpcSpawnlocs[i + 11][3]);
|
||||
else
|
||||
Demolisher->Relocate(BG_SA_NpcSpawnlocs[i][0], BG_SA_NpcSpawnlocs[i][1],
|
||||
BG_SA_NpcSpawnlocs[i][2], BG_SA_NpcSpawnlocs[i][3]);
|
||||
|
||||
|
||||
@@ -126,15 +126,19 @@ enum BG_SA_NPCs
|
||||
BG_SA_GUN_8,
|
||||
BG_SA_GUN_9,
|
||||
BG_SA_GUN_10,
|
||||
BG_SA_DEMOLISHER_1,
|
||||
BG_SA_DEMOLISHER_2,
|
||||
BG_SA_DEMOLISHER_3,
|
||||
BG_SA_DEMOLISHER_4,
|
||||
BG_SA_NPC_TRIGGER_1,
|
||||
BG_SA_NPC_TRIGGER_2,
|
||||
BG_SA_NPC_TRIGGER_3,
|
||||
BG_SA_NPC_TRIGGER_4,
|
||||
BG_SA_NPC_TRIGGER_5,
|
||||
BG_SA_DEMOLISHER_1,
|
||||
BG_SA_DEMOLISHER_2,
|
||||
BG_SA_DEMOLISHER_3,
|
||||
BG_SA_DEMOLISHER_4,
|
||||
BG_SA_DEMOLISHER_5,
|
||||
BG_SA_DEMOLISHER_6,
|
||||
BG_SA_DEMOLISHER_7,
|
||||
BG_SA_DEMOLISHER_8,
|
||||
BG_SA_NPC_SPARKLIGHT,
|
||||
BG_SA_NPC_RIGSPARK,
|
||||
BG_SA_MAXNPC
|
||||
@@ -160,17 +164,22 @@ uint32 const BG_SA_NpcEntries[BG_SA_MAXNPC] =
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
// 4 beach demolishers
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
// Triggers
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
// 4 beach demolishers
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
// 4 factory demolishers
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
// Used Demolisher Salesman
|
||||
NPC_RIGGER_SPARKLIGHT,
|
||||
NPC_GORGRIL_RIGSPARK
|
||||
@@ -189,25 +198,25 @@ float const BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] =
|
||||
{ 1249.634f, -224.189f, 66.72f, 0.635f },
|
||||
{ 1236.213f, 92.287f, 64.965f, 5.751f },
|
||||
{ 1215.11f, 57.772f, 64.739f, 5.78f },
|
||||
// Demolishers
|
||||
{ 1611.597656f, -117.270073f, 8.719355f, 2.513274f},
|
||||
{ 1575.562500f, -158.421875f, 5.024450f, 2.129302f},
|
||||
{ 1618.047729f, 61.424641f, 7.248210f, 3.979351f},
|
||||
{ 1575.103149f, 98.873344f, 2.830360f, 3.752458f},
|
||||
// Triggers
|
||||
{ 1453.49f, -250.453f, 30.896f, 4.2883f},
|
||||
{ 1377.05f, 97.036f, 30.8605f, 2.46539f},
|
||||
{ 1186.05f, 58.8048f, 56.5491f, 2.75992f},
|
||||
{ 1042.83f, -72.839f, 84.8145f, 3.58615f},
|
||||
{ 1233.62f, -250.49f, 55.4036f, 3.7016f},
|
||||
// Npcs
|
||||
{ 1348.644165f, -298.786469f, 31.080130f, 1.710423f},
|
||||
{ 1358.191040f, 195.527786f, 31.018187f, 4.171337f},
|
||||
// Demolishers
|
||||
{ 1611.597656f, -117.270073f, 8.719355f, 2.513274f},
|
||||
{ 1575.562500f, -158.421875f, 5.024450f, 2.129302f},
|
||||
{ 1618.047729f, 61.424641f, 7.248210f, 3.979351f},
|
||||
{ 1575.103149f, 98.873344f, 2.830360f, 3.752458f},
|
||||
// Demolishers 2
|
||||
{ 1371.055786f, -317.071136f, 35.007359f, 1.947460f},
|
||||
{ 1424.034912f, -260.195190f, 31.084425f, 2.820013f},
|
||||
{ 1353.139893f, 223.745438f, 35.265411f, 4.343684f},
|
||||
{ 1404.809570f, 197.027237f, 32.046032f, 3.605401f}
|
||||
{ 1404.809570f, 197.027237f, 32.046032f, 3.605401f},
|
||||
// Npcs
|
||||
{ 1348.644165f, -298.786469f, 31.080130f, 1.710423f},
|
||||
{ 1358.191040f, 195.527786f, 31.018187f, 4.171337f}
|
||||
};
|
||||
|
||||
enum BG_SA_Objects
|
||||
|
||||
@@ -222,6 +222,7 @@ struct AchievementCriteriaEntry
|
||||
struct
|
||||
{
|
||||
uint32 mapID; // 3 Reference to Map.dbc
|
||||
uint32 count; // 4 Number of times that the arena must be won.
|
||||
} win_arena;
|
||||
|
||||
// ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33
|
||||
@@ -1195,7 +1196,7 @@ struct ItemSetEntry
|
||||
struct LFGDungeonEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
//char* name[16]; // 1-17 Name lang
|
||||
char* name[16]; // 1-17 Name lang
|
||||
uint32 minlevel; // 18
|
||||
uint32 maxlevel; // 19
|
||||
uint32 reclevel; // 20
|
||||
|
||||
@@ -19,111 +19,111 @@
|
||||
#ifndef TRINITY_DBCSFRM_H
|
||||
#define TRINITY_DBCSFRM_H
|
||||
|
||||
const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
|
||||
char const Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
|
||||
const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp";
|
||||
const std::string CustomAchievementIndex = "ID";
|
||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx";
|
||||
const char AreaGroupEntryfmt[]="niiiiiii";
|
||||
const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
|
||||
const char AreaTriggerEntryfmt[]="niffffffff";
|
||||
const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
|
||||
const char BankBagSlotPricesEntryfmt[]="ni";
|
||||
const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
|
||||
const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx";
|
||||
const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
|
||||
const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
char const AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
|
||||
char const AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx";
|
||||
char const AreaGroupEntryfmt[]="niiiiiii";
|
||||
char const AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
|
||||
char const AreaTriggerEntryfmt[]="niffffffff";
|
||||
char const AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx";
|
||||
char const BankBagSlotPricesEntryfmt[]="ni";
|
||||
char const BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
|
||||
char const BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx";
|
||||
char const CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
|
||||
char const ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
// ChatChannelsEntryfmt, index not used (more compact store)
|
||||
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
||||
const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
||||
const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
|
||||
const char CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx";
|
||||
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
||||
const char CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx";
|
||||
const char CreatureSpellDatafmt[]="niiiixxxx";
|
||||
const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
|
||||
const char CurrencyTypesfmt[]="xnxi";
|
||||
const char DestructibleModelDatafmt[]="nxxixxxixxxixxxixxx";
|
||||
const char DungeonEncounterfmt[]="niixissssssssssssssssxx";
|
||||
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char DurabilityQualityfmt[]="nf";
|
||||
const char EmotesEntryfmt[]="nxxiiix";
|
||||
const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
|
||||
const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
|
||||
const char GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx";
|
||||
const char GemPropertiesEntryfmt[]="nixxi";
|
||||
const char GlyphPropertiesfmt[]="niii";
|
||||
const char GlyphSlotfmt[]="nii";
|
||||
const char GtBarberShopCostBasefmt[]="f";
|
||||
const char GtCombatRatingsfmt[]="f";
|
||||
const char GtChanceToMeleeCritBasefmt[]="f";
|
||||
const char GtChanceToMeleeCritfmt[]="f";
|
||||
const char GtChanceToSpellCritBasefmt[]="f";
|
||||
const char GtChanceToSpellCritfmt[]="f";
|
||||
const char GtOCTClassCombatRatingScalarfmt[]="df";
|
||||
const char GtOCTRegenHPfmt[]="f";
|
||||
//const char GtOCTRegenMPfmt[]="f";
|
||||
const char GtRegenHPPerSptfmt[]="f";
|
||||
const char GtRegenMPPerSptfmt[]="f";
|
||||
const char Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix";
|
||||
const char Itemfmt[]="niiiiiii";
|
||||
const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
|
||||
//const char ItemCondExtCostsEntryfmt[]="xiii";
|
||||
const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix";
|
||||
const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
const char ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx";
|
||||
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx";
|
||||
const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiiiixxixixxxxxxxxxxxxxxxxx";
|
||||
const char LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
|
||||
const char MapDifficultyEntryfmt[]="diisxxxxxxxxxxxxxxxxiix";
|
||||
const char MovieEntryfmt[]="nxx";
|
||||
const char OverrideSpellDatafmt[]="niiiiiiiiiix";
|
||||
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char QuestXPfmt[]="niiiiiiiiii";
|
||||
const char QuestFactionRewardfmt[]="niiiiiiiiii";
|
||||
const char PvPDifficultyfmt[]="diiiii";
|
||||
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
||||
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
||||
const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiii";
|
||||
const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
|
||||
const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
|
||||
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellCastTimefmt[]="nixx";
|
||||
const char SpellDifficultyfmt[]="niiii";
|
||||
char const ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
||||
char const ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
||||
char const CinematicSequencesEntryfmt[]="nxxxxxxxxx";
|
||||
char const CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx";
|
||||
char const CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
||||
char const CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx";
|
||||
char const CreatureSpellDatafmt[]="niiiixxxx";
|
||||
char const CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
|
||||
char const CurrencyTypesfmt[]="xnxi";
|
||||
char const DestructibleModelDatafmt[]="nxxixxxixxxixxxixxx";
|
||||
char const DungeonEncounterfmt[]="niixissssssssssssssssxx";
|
||||
char const DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
char const DurabilityQualityfmt[]="nf";
|
||||
char const EmotesEntryfmt[]="nxxiiix";
|
||||
char const EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
|
||||
char const FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||
char const FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
|
||||
char const GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx";
|
||||
char const GemPropertiesEntryfmt[]="nixxi";
|
||||
char const GlyphPropertiesfmt[]="niii";
|
||||
char const GlyphSlotfmt[]="nii";
|
||||
char const GtBarberShopCostBasefmt[]="f";
|
||||
char const GtCombatRatingsfmt[]="f";
|
||||
char const GtChanceToMeleeCritBasefmt[]="f";
|
||||
char const GtChanceToMeleeCritfmt[]="f";
|
||||
char const GtChanceToSpellCritBasefmt[]="f";
|
||||
char const GtChanceToSpellCritfmt[]="f";
|
||||
char const GtOCTClassCombatRatingScalarfmt[]="df";
|
||||
char const GtOCTRegenHPfmt[]="f";
|
||||
//char const GtOCTRegenMPfmt[]="f";
|
||||
char const GtRegenHPPerSptfmt[]="f";
|
||||
char const GtRegenMPPerSptfmt[]="f";
|
||||
char const Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix";
|
||||
char const Itemfmt[]="niiiiiii";
|
||||
char const ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
//char const ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";
|
||||
//char const ItemCondExtCostsEntryfmt[]="xiii";
|
||||
char const ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix";
|
||||
char const ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
char const ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx";
|
||||
char const ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx";
|
||||
char const ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
char const LFGDungeonEntryfmt[]="nssssssssssssssssxiiiiiiiiixxixixxxxxxxxxxxxxxxxx";
|
||||
char const LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
char const MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||
char const MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
|
||||
char const MapDifficultyEntryfmt[]="diisxxxxxxxxxxxxxxxxiix";
|
||||
char const MovieEntryfmt[]="nxx";
|
||||
char const OverrideSpellDatafmt[]="niiiiiiiiiix";
|
||||
char const QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
char const QuestXPfmt[]="niiiiiiiiii";
|
||||
char const QuestFactionRewardfmt[]="niiiiiiiiii";
|
||||
char const PvPDifficultyfmt[]="diiiii";
|
||||
char const RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
||||
char const ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
||||
char const ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiii";
|
||||
char const SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
|
||||
char const SkillLineAbilityfmt[]="niiiixxiiiiixx";
|
||||
char const SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const SpellCastTimefmt[]="nixx";
|
||||
char const SpellDifficultyfmt[]="niiii";
|
||||
const std::string CustomSpellDifficultyfmt="ppppp";
|
||||
const std::string CustomSpellDifficultyIndex="id";
|
||||
const char SpellDurationfmt[]="niii";
|
||||
const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
|
||||
char const SpellDurationfmt[]="niii";
|
||||
char const SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
|
||||
const std::string CustomSpellEntryfmt="papppppppppppapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa";
|
||||
const std::string CustomSpellEntryIndex = "Id";
|
||||
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii";
|
||||
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
||||
const char SpellRadiusfmt[]="nfxf";
|
||||
const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellRuneCostfmt[]="niiii";
|
||||
const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii";
|
||||
const char StableSlotPricesfmt[] = "ni";
|
||||
const char SummonPropertiesfmt[] = "niiiii";
|
||||
const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
|
||||
const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
|
||||
const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
|
||||
const char TaxiPathEntryfmt[]="niii";
|
||||
const char TaxiPathNodeEntryfmt[]="diiifffiiii";
|
||||
const char TeamContributionPointsfmt[]="df";
|
||||
const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
|
||||
const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
|
||||
const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
|
||||
const char WorldMapAreaEntryfmt[]="xinxffffixx";
|
||||
const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
|
||||
const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
|
||||
char const SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
char const SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii";
|
||||
char const SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
||||
char const SpellRadiusfmt[]="nfxf";
|
||||
char const SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const SpellRuneCostfmt[]="niiii";
|
||||
char const SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii";
|
||||
char const StableSlotPricesfmt[] = "ni";
|
||||
char const SummonPropertiesfmt[] = "niiiii";
|
||||
char const TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
|
||||
char const TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
|
||||
char const TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";
|
||||
char const TaxiPathEntryfmt[]="niii";
|
||||
char const TaxiPathNodeEntryfmt[]="diiifffiiii";
|
||||
char const TeamContributionPointsfmt[]="df";
|
||||
char const TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
char const VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx";
|
||||
char const VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
|
||||
char const WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx";
|
||||
char const WorldMapAreaEntryfmt[]="xinxffffixx";
|
||||
char const WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
|
||||
char const WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,19 +20,26 @@
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
enum LFGEnum
|
||||
{
|
||||
LFG_TANKS_NEEDED = 1,
|
||||
LFG_HEALERS_NEEDED = 1,
|
||||
LFG_DPS_NEEDED = 3
|
||||
};
|
||||
|
||||
enum LfgRoles
|
||||
{
|
||||
ROLE_NONE = 0x00,
|
||||
ROLE_LEADER = 0x01,
|
||||
ROLE_TANK = 0x02,
|
||||
ROLE_HEALER = 0x04,
|
||||
ROLE_DAMAGE = 0x08
|
||||
PLAYER_ROLE_NONE = 0x00,
|
||||
PLAYER_ROLE_LEADER = 0x01,
|
||||
PLAYER_ROLE_TANK = 0x02,
|
||||
PLAYER_ROLE_HEALER = 0x04,
|
||||
PLAYER_ROLE_DAMAGE = 0x08
|
||||
};
|
||||
|
||||
enum LfgUpdateType
|
||||
{
|
||||
LFG_UPDATETYPE_DEFAULT = 0, // Internal Use
|
||||
LFG_UPDATETYPE_LEADER = 1,
|
||||
LFG_UPDATETYPE_LEADER_UNK1 = 1, // FIXME: At group leave
|
||||
LFG_UPDATETYPE_ROLECHECK_ABORTED = 4,
|
||||
LFG_UPDATETYPE_JOIN_PROPOSAL = 5,
|
||||
LFG_UPDATETYPE_ROLECHECK_FAILED = 6,
|
||||
@@ -44,7 +51,7 @@ enum LfgUpdateType
|
||||
LFG_UPDATETYPE_PROPOSAL_BEGIN = 13,
|
||||
LFG_UPDATETYPE_CLEAR_LOCK_LIST = 14,
|
||||
LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 15,
|
||||
LFG_UPDATETYPE_GROUP_DISBAND = 16
|
||||
LFG_UPDATETYPE_GROUP_DISBAND_UNK16 = 16, // FIXME: Sometimes at group disband
|
||||
};
|
||||
|
||||
enum LfgState
|
||||
@@ -62,7 +69,6 @@ enum LfgState
|
||||
/// Instance lock types
|
||||
enum LfgLockStatusType
|
||||
{
|
||||
LFG_LOCKSTATUS_OK = 0, // Internal use only
|
||||
LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION = 1,
|
||||
LFG_LOCKSTATUS_TOO_LOW_LEVEL = 2,
|
||||
LFG_LOCKSTATUS_TOO_HIGH_LEVEL = 3,
|
||||
@@ -73,18 +79,24 @@ enum LfgLockStatusType
|
||||
LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL = 1002,
|
||||
LFG_LOCKSTATUS_QUEST_NOT_COMPLETED = 1022,
|
||||
LFG_LOCKSTATUS_MISSING_ITEM = 1025,
|
||||
LFG_LOCKSTATUS_NOT_IN_SEASON = 1031
|
||||
LFG_LOCKSTATUS_NOT_IN_SEASON = 1031,
|
||||
LFG_LOCKSTATUS_MISSING_ACHIEVEMENT = 1034
|
||||
};
|
||||
|
||||
/// Dungeon and reason why player can't join
|
||||
struct LfgLockStatus
|
||||
/// Answer state (Also used to check compatibilites)
|
||||
enum LfgAnswer
|
||||
{
|
||||
uint32 dungeon; ///< Dungeon Id
|
||||
LfgLockStatusType lockstatus; ///< Lock type
|
||||
LFG_ANSWER_PENDING = -1,
|
||||
LFG_ANSWER_DENY = 0,
|
||||
LFG_ANSWER_AGREE = 1
|
||||
};
|
||||
|
||||
typedef std::set<uint32> LfgDungeonSet;
|
||||
typedef std::map<uint32, LfgLockStatusType> LfgLockMap;
|
||||
typedef std::map<uint32, uint32> LfgLockMap;
|
||||
typedef std::map<uint64, LfgLockMap> LfgLockPartyMap;
|
||||
typedef std::set<uint64> LfgGuidSet;
|
||||
typedef std::list<uint64> LfgGuidList;
|
||||
typedef std::map<uint64, uint8> LfgRolesMap;
|
||||
typedef std::map<uint64, uint64> LfgGroupsMap;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,23 +18,25 @@
|
||||
#include "LFG.h"
|
||||
#include "LFGGroupData.h"
|
||||
|
||||
LfgGroupData::LfgGroupData():
|
||||
m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Dungeon(0),
|
||||
m_VotesNeeded(LFG_GROUP_KICK_VOTES_NEEDED), m_KicksLeft(LFG_GROUP_MAX_KICKS)
|
||||
{
|
||||
}
|
||||
LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE),
|
||||
m_Leader(0), m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS)
|
||||
{ }
|
||||
|
||||
LfgGroupData::~LfgGroupData()
|
||||
{ }
|
||||
|
||||
bool LfgGroupData::IsLfgGroup()
|
||||
{
|
||||
return m_OldState != LFG_STATE_NONE;
|
||||
}
|
||||
|
||||
void LfgGroupData::SetState(LfgState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case LFG_STATE_FINISHED_DUNGEON:
|
||||
case LFG_STATE_NONE:
|
||||
case LFG_STATE_DUNGEON:
|
||||
case LFG_STATE_FINISHED_DUNGEON:
|
||||
m_OldState = state;
|
||||
// No break on purpose
|
||||
default:
|
||||
@@ -47,6 +49,29 @@ void LfgGroupData::RestoreState()
|
||||
m_State = m_OldState;
|
||||
}
|
||||
|
||||
void LfgGroupData::AddPlayer(uint64 guid)
|
||||
{
|
||||
m_Players.insert(guid);
|
||||
}
|
||||
|
||||
uint8 LfgGroupData::RemovePlayer(uint64 guid)
|
||||
{
|
||||
LfgGuidSet::iterator it = m_Players.find(guid);
|
||||
if (it != m_Players.end())
|
||||
m_Players.erase(it);
|
||||
return uint8(m_Players.size());
|
||||
}
|
||||
|
||||
void LfgGroupData::RemoveAllPlayers()
|
||||
{
|
||||
m_Players.clear();
|
||||
}
|
||||
|
||||
void LfgGroupData::SetLeader(uint64 guid)
|
||||
{
|
||||
m_Leader = guid;
|
||||
}
|
||||
|
||||
void LfgGroupData::SetDungeon(uint32 dungeon)
|
||||
{
|
||||
m_Dungeon = dungeon;
|
||||
@@ -63,6 +88,21 @@ LfgState LfgGroupData::GetState() const
|
||||
return m_State;
|
||||
}
|
||||
|
||||
LfgState LfgGroupData::GetOldState() const
|
||||
{
|
||||
return m_OldState;
|
||||
}
|
||||
|
||||
const LfgGuidSet &LfgGroupData::GetPlayers() const
|
||||
{
|
||||
return m_Players;
|
||||
}
|
||||
|
||||
uint64 LfgGroupData::GetLeader() const
|
||||
{
|
||||
return m_Leader;
|
||||
}
|
||||
|
||||
uint32 LfgGroupData::GetDungeon(bool asId /* = true */) const
|
||||
{
|
||||
if (asId)
|
||||
@@ -71,11 +111,6 @@ uint32 LfgGroupData::GetDungeon(bool asId /* = true */) const
|
||||
return m_Dungeon;
|
||||
}
|
||||
|
||||
uint8 LfgGroupData::GetVotesNeeded() const
|
||||
{
|
||||
return m_VotesNeeded;
|
||||
}
|
||||
|
||||
uint8 LfgGroupData::GetKicksLeft() const
|
||||
{
|
||||
return m_KicksLeft;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
enum LfgGroupEnum
|
||||
{
|
||||
LFG_GROUP_MAX_KICKS = 3,
|
||||
LFG_GROUP_KICK_VOTES_NEEDED = 3
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -35,31 +34,43 @@ class LfgGroupData
|
||||
LfgGroupData();
|
||||
~LfgGroupData();
|
||||
|
||||
bool IsLfgGroup();
|
||||
|
||||
// General
|
||||
void SetState(LfgState state);
|
||||
void RestoreState();
|
||||
void AddPlayer(uint64 guid);
|
||||
uint8 RemovePlayer(uint64 guid);
|
||||
void RemoveAllPlayers();
|
||||
void SetLeader(uint64 guid);
|
||||
|
||||
// Dungeon
|
||||
void SetDungeon(uint32 dungeon);
|
||||
|
||||
// VoteKick
|
||||
void SetVotesNeeded(uint8 votes);
|
||||
void DecreaseKicksLeft();
|
||||
|
||||
// General
|
||||
LfgState GetState() const;
|
||||
LfgState GetOldState() const;
|
||||
LfgGuidSet const& GetPlayers() const;
|
||||
uint64 GetLeader() const;
|
||||
|
||||
// Dungeon
|
||||
uint32 GetDungeon(bool asId = true) const;
|
||||
|
||||
// VoteKick
|
||||
uint8 GetVotesNeeded() const;
|
||||
uint8 GetKicksLeft() const;
|
||||
|
||||
private:
|
||||
// General
|
||||
LfgState m_State; ///< State if group in LFG
|
||||
LfgState m_OldState; ///< Old State
|
||||
uint64 m_Leader; ///< Leader GUID
|
||||
LfgGuidSet m_Players; ///< Players in group
|
||||
// Dungeon
|
||||
uint32 m_Dungeon; ///< Dungeon entry
|
||||
// Vote Kick
|
||||
uint8 m_VotesNeeded; ///< Votes need to kick success
|
||||
uint8 m_KicksLeft; ///< Number of kicks left
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,24 +21,23 @@
|
||||
#include "Common.h"
|
||||
#include <ace/Singleton.h>
|
||||
#include "LFG.h"
|
||||
#include "LFGQueue.h"
|
||||
#include "LFGGroupData.h"
|
||||
#include "LFGPlayerData.h"
|
||||
|
||||
class LfgGroupData;
|
||||
class LfgPlayerData;
|
||||
class Group;
|
||||
class Player;
|
||||
|
||||
enum LFGenum
|
||||
enum LFGMgrEnum
|
||||
{
|
||||
LFG_TIME_ROLECHECK = 40*IN_MILLISECONDS,
|
||||
LFG_TIME_BOOT = 2*MINUTE,
|
||||
LFG_TIME_PROPOSAL = 2*MINUTE,
|
||||
LFG_TANKS_NEEDED = 1,
|
||||
LFG_HEALERS_NEEDED = 1,
|
||||
LFG_DPS_NEEDED = 3,
|
||||
LFG_QUEUEUPDATE_INTERVAL = 15*IN_MILLISECONDS,
|
||||
LFG_TIME_ROLECHECK = 40 * IN_MILLISECONDS,
|
||||
LFG_TIME_BOOT = 120,
|
||||
LFG_TIME_PROPOSAL = 120,
|
||||
LFG_QUEUEUPDATE_INTERVAL = 15 * IN_MILLISECONDS,
|
||||
LFG_SPELL_DUNGEON_COOLDOWN = 71328,
|
||||
LFG_SPELL_DUNGEON_DESERTER = 71041,
|
||||
LFG_SPELL_LUCK_OF_THE_DRAW = 72221
|
||||
LFG_SPELL_LUCK_OF_THE_DRAW = 72221,
|
||||
LFG_GROUP_KICK_VOTES_NEEDED = 3
|
||||
};
|
||||
|
||||
enum LfgFlags
|
||||
@@ -52,11 +51,9 @@ enum LfgFlags
|
||||
/// Determines the type of instance
|
||||
enum LfgType
|
||||
{
|
||||
LFG_TYPE_NONE = 0, // Internal use only
|
||||
LFG_TYPE_NONE = 0,
|
||||
LFG_TYPE_DUNGEON = 1,
|
||||
LFG_TYPE_RAID = 2,
|
||||
LFG_TYPE_QUEST = 3,
|
||||
LFG_TYPE_ZONE = 4,
|
||||
LFG_TYPE_HEROIC = 5,
|
||||
LFG_TYPE_RANDOM = 6
|
||||
};
|
||||
@@ -72,13 +69,14 @@ enum LfgProposalState
|
||||
/// Teleport errors
|
||||
enum LfgTeleportError
|
||||
{
|
||||
// 3, 7, 8 = "You can't do that right now" | 5 = No client reaction
|
||||
// 7 = "You can't do that right now" | 5 = No client reaction
|
||||
LFG_TELEPORTERROR_OK = 0, // Internal use
|
||||
LFG_TELEPORTERROR_PLAYER_DEAD = 1,
|
||||
LFG_TELEPORTERROR_FALLING = 2,
|
||||
LFG_TELEPORTERROR_DONT_REPORT = 3,
|
||||
LFG_TELEPORTERROR_IN_VEHICLE = 3,
|
||||
LFG_TELEPORTERROR_FATIGUE = 4,
|
||||
LFG_TELEPORTERROR_INVALID_LOCATION = 6
|
||||
LFG_TELEPORTERROR_INVALID_LOCATION = 6,
|
||||
LFG_TELEPORTERROR_CHARMING = 8 // FIXME - It can be 7 or 8 (Need proper data)
|
||||
};
|
||||
|
||||
/// Queue join results
|
||||
@@ -116,42 +114,27 @@ enum LfgRoleCheckState
|
||||
LFG_ROLECHECK_NO_ROLE = 6 // Someone selected no role
|
||||
};
|
||||
|
||||
/// Answer state (Also used to check compatibilites)
|
||||
enum LfgAnswer
|
||||
{
|
||||
LFG_ANSWER_PENDING = -1,
|
||||
LFG_ANSWER_DENY = 0,
|
||||
LFG_ANSWER_AGREE = 1
|
||||
};
|
||||
|
||||
// Forward declaration (just to have all typedef together)
|
||||
struct LFGDungeonData;
|
||||
struct LfgReward;
|
||||
struct LfgLockStatus;
|
||||
struct LfgQueueInfo;
|
||||
struct LfgRoleCheck;
|
||||
struct LfgProposal;
|
||||
struct LfgProposalPlayer;
|
||||
struct LfgPlayerBoot;
|
||||
|
||||
typedef std::set<uint64> LfgGuidSet;
|
||||
typedef std::list<uint64> LfgGuidList;
|
||||
typedef std::map<uint8, LfgGuidList> LfgGuidListMap;
|
||||
typedef std::set<Player*> PlayerSet;
|
||||
typedef std::list<Player*> LfgPlayerList;
|
||||
typedef std::map<uint8, LfgQueue> LfgQueueMap;
|
||||
typedef std::multimap<uint32, LfgReward const*> LfgRewardMap;
|
||||
typedef std::pair<LfgRewardMap::const_iterator, LfgRewardMap::const_iterator> LfgRewardMapBounds;
|
||||
typedef std::map<std::string, LfgAnswer> LfgCompatibleMap;
|
||||
typedef std::map<uint64, LfgDungeonSet> LfgDungeonMap;
|
||||
typedef std::map<uint64, uint8> LfgRolesMap;
|
||||
typedef std::map<uint8, LfgDungeonSet> LfgCachedDungeonMap;
|
||||
typedef std::map<uint64, LfgAnswer> LfgAnswerMap;
|
||||
typedef std::map<uint64, LfgRoleCheck*> LfgRoleCheckMap;
|
||||
typedef std::map<uint64, LfgQueueInfo*> LfgQueueInfoMap;
|
||||
typedef std::map<uint32, LfgProposal*> LfgProposalMap;
|
||||
typedef std::map<uint64, LfgProposalPlayer*> LfgProposalPlayerMap;
|
||||
typedef std::map<uint32, LfgPlayerBoot*> LfgPlayerBootMap;
|
||||
typedef std::map<uint64, LfgRoleCheck> LfgRoleCheckMap;
|
||||
typedef std::map<uint32, LfgProposal> LfgProposalMap;
|
||||
typedef std::map<uint64, LfgProposalPlayer> LfgProposalPlayerMap;
|
||||
typedef std::map<uint64, LfgPlayerBoot> LfgPlayerBootMap;
|
||||
typedef std::map<uint64, LfgGroupData> LfgGroupDataMap;
|
||||
typedef std::map<uint64, LfgPlayerData> LfgPlayerDataMap;
|
||||
typedef std::map<uint32, Position> LfgEntrancePositionMap;
|
||||
typedef UNORDERED_MAP<uint32, LFGDungeonData> LFGDungeonMap;
|
||||
|
||||
// Data needed by SMSG_LFG_JOIN_RESULT
|
||||
struct LfgJoinResultData
|
||||
@@ -167,7 +150,7 @@ struct LfgJoinResultData
|
||||
struct LfgUpdateData
|
||||
{
|
||||
LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT): updateType(_type), comment("") {}
|
||||
LfgUpdateData(LfgUpdateType _type, const LfgDungeonSet& _dungeons, std::string _comment):
|
||||
LfgUpdateData(LfgUpdateType _type, LfgDungeonSet const& _dungeons, std::string _comment):
|
||||
updateType(_type), dungeons(_dungeons), comment(_comment) {}
|
||||
|
||||
LfgUpdateType updateType;
|
||||
@@ -175,6 +158,26 @@ struct LfgUpdateData
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
// Data needed by SMSG_LFG_QUEUE_STATUS
|
||||
struct LfgQueueStatusData
|
||||
{
|
||||
LfgQueueStatusData(uint32 _dungeonId = 0, int32 _waitTime = -1, int32 _waitTimeAvg = -1, int32 _waitTimeTank = -1, int32 _waitTimeHealer = -1,
|
||||
int32 _waitTimeDps = -1, uint32 _queuedTime = 0, uint8 _tanks = 0, uint8 _healers = 0, uint8 _dps = 0) :
|
||||
dungeonId(_dungeonId), waitTime(_waitTime), waitTimeAvg(_waitTimeAvg), waitTimeTank(_waitTimeTank), waitTimeHealer(_waitTimeHealer),
|
||||
waitTimeDps(_waitTimeDps), queuedTime(_queuedTime), tanks(_tanks), healers(_healers), dps(_dps) {}
|
||||
|
||||
uint32 dungeonId;
|
||||
int32 waitTime;
|
||||
int32 waitTimeAvg;
|
||||
int32 waitTimeTank;
|
||||
int32 waitTimeHealer;
|
||||
int32 waitTimeDps;
|
||||
uint32 queuedTime;
|
||||
uint8 tanks;
|
||||
uint8 healers;
|
||||
uint8 dps;
|
||||
};
|
||||
|
||||
/// Reward info
|
||||
struct LfgReward
|
||||
{
|
||||
@@ -198,45 +201,31 @@ struct LfgReward
|
||||
}
|
||||
};
|
||||
|
||||
/// Stores player or group queue info
|
||||
struct LfgQueueInfo
|
||||
{
|
||||
LfgQueueInfo(): joinTime(0), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) {};
|
||||
time_t joinTime; ///< Player queue join time (to calculate wait times)
|
||||
uint8 tanks; ///< Tanks needed
|
||||
uint8 healers; ///< Healers needed
|
||||
uint8 dps; ///< Dps needed
|
||||
LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s
|
||||
LfgRolesMap roles; ///< Selected Player Role/s
|
||||
};
|
||||
|
||||
/// Stores player data related to proposal to join
|
||||
struct LfgProposalPlayer
|
||||
{
|
||||
LfgProposalPlayer(): role(0), accept(LFG_ANSWER_PENDING), groupLowGuid(0) {};
|
||||
LfgProposalPlayer(): role(0), accept(LFG_ANSWER_PENDING), group(0) { }
|
||||
uint8 role; ///< Proposed role
|
||||
LfgAnswer accept; ///< Accept status (-1 not answer | 0 Not agree | 1 agree)
|
||||
uint32 groupLowGuid; ///< Original group guid (Low guid) 0 if no original group
|
||||
uint64 group; ///< Original group guid. 0 if no original group
|
||||
};
|
||||
|
||||
/// Stores group data related to proposal to join
|
||||
struct LfgProposal
|
||||
{
|
||||
LfgProposal(uint32 dungeon = 0): dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), groupLowGuid(0), leader(0), cancelTime(0) {}
|
||||
LfgProposal(uint32 dungeon = 0): dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING),
|
||||
group(0), leader(0), cancelTime(0), encounters(0), isNew(true)
|
||||
{ }
|
||||
|
||||
~LfgProposal()
|
||||
{
|
||||
for (LfgProposalPlayerMap::iterator it = players.begin(); it != players.end(); ++it)
|
||||
delete it->second;
|
||||
};
|
||||
uint32 dungeonId; ///< Dungeon to join
|
||||
LfgProposalState state; ///< State of the proposal
|
||||
uint32 groupLowGuid; ///< Proposal group (0 if new)
|
||||
uint64 group; ///< Proposal group (0 if new)
|
||||
uint64 leader; ///< Leader guid.
|
||||
time_t cancelTime; ///< Time when we will cancel this proposal
|
||||
uint32 encounters; ///< Dungeon Encounters
|
||||
bool isNew; ///< Determines if it's new group or not
|
||||
LfgGuidList queues; ///< Queue Ids to remove/readd
|
||||
LfgProposalPlayerMap players; ///< Players data
|
||||
|
||||
};
|
||||
|
||||
/// Stores all rolecheck info of a group that wants to join
|
||||
@@ -257,10 +246,36 @@ struct LfgPlayerBoot
|
||||
bool inProgress; ///< Vote in progress
|
||||
LfgAnswerMap votes; ///< Player votes (-1 not answer | 0 Not agree | 1 agree)
|
||||
uint64 victim; ///< Player guid to be kicked (can't vote)
|
||||
uint8 votedNeeded; ///< Votes needed to kick the player
|
||||
std::string reason; ///< kick reason
|
||||
};
|
||||
|
||||
struct LFGDungeonData
|
||||
{
|
||||
LFGDungeonData(): id(0), name(""), map(0), type(0), expansion(0), group(0), minlevel(0),
|
||||
maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f)
|
||||
{ }
|
||||
LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name[0]), map(dbc->map),
|
||||
type(dbc->type), expansion(dbc->expansion), group(dbc->grouptype),
|
||||
minlevel(dbc->minlevel), maxlevel(dbc->maxlevel), difficulty(Difficulty(dbc->difficulty)),
|
||||
seasonal(dbc->flags & LFG_FLAG_SEASONAL), x(0.0f), y(0.0f), z(0.0f), o(0.0f)
|
||||
{ }
|
||||
|
||||
uint32 id;
|
||||
std::string name;
|
||||
uint16 map;
|
||||
uint8 type;
|
||||
uint8 expansion;
|
||||
uint8 group;
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
Difficulty difficulty;
|
||||
bool seasonal;
|
||||
float x, y, z, o;
|
||||
|
||||
// Helpers
|
||||
uint32 Entry() const { return id + (type << 24); }
|
||||
};
|
||||
|
||||
class LFGMgr
|
||||
{
|
||||
friend class ACE_Singleton<LFGMgr, ACE_Null_Mutex>;
|
||||
@@ -274,108 +289,121 @@ class LFGMgr
|
||||
|
||||
// Reward
|
||||
void LoadRewards();
|
||||
void RewardDungeonDoneFor(const uint32 dungeonId, Player* player);
|
||||
void RewardDungeonDoneFor(uint32 const dungeonId, Player* player);
|
||||
LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level);
|
||||
|
||||
// Queue
|
||||
void Join(Player* player, uint8 roles, const LfgDungeonSet& dungeons, const std::string& comment);
|
||||
void Leave(Player* player, Group* grp = NULL);
|
||||
void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment);
|
||||
void LeaveLfg(uint64 guid);
|
||||
|
||||
// Role Check
|
||||
void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = ROLE_NONE);
|
||||
void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE);
|
||||
|
||||
// Group Matching
|
||||
static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
|
||||
void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap);
|
||||
|
||||
// Proposals
|
||||
uint32 AddProposal(LfgProposal const& proposal);
|
||||
void UpdateProposal(uint32 proposalId, uint64 guid, bool accept);
|
||||
|
||||
// Teleportation
|
||||
void LoadEntrancePositions();
|
||||
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false);
|
||||
|
||||
// Vote kick
|
||||
void InitBoot(Group* grp, uint64 kguid, uint64 vguid, std::string reason);
|
||||
void UpdateBoot(Player* player, bool accept);
|
||||
void OfferContinue(Group* grp);
|
||||
void InitBoot(uint64 gguid, uint64 kguid, uint64 vguid, std::string const& reason);
|
||||
void UpdateBoot(uint64 guid, bool accept);
|
||||
|
||||
HolidayIds GetDungeonSeason(uint32 dungeonId);
|
||||
void InitializeLockedDungeons(Player* player, uint8 level = 0);
|
||||
|
||||
void InitializeLockedDungeons(Player* player);
|
||||
void SetRoles(uint64 guid, uint8 roles);
|
||||
void SetComment(uint64 guid, std::string const& comment);
|
||||
void SetTeam(uint64 guid, uint8 team);
|
||||
void SetGroup(uint64 guid, uint64 group);
|
||||
void SetLeader(uint64 gguid, uint64 leader);
|
||||
void SetState(uint64 guid, LfgState state);
|
||||
void SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons);
|
||||
|
||||
void _LoadFromDB(Field* fields, uint64 guid);
|
||||
void _SaveToDB(uint64 guid, uint32 db_guid);
|
||||
|
||||
void SetComment(uint64 guid, const std::string& comment);
|
||||
const LfgLockMap& GetLockedDungeons(uint64 guid);
|
||||
LfgState GetState(uint64 guid);
|
||||
const LfgDungeonSet& GetSelectedDungeons(uint64 guid);
|
||||
uint32 GetDungeon(uint64 guid, bool asId = true);
|
||||
void SetState(uint64 guid, LfgState state);
|
||||
void ClearState(uint64 guid);
|
||||
void RemovePlayerData(uint64 guid);
|
||||
void RemoveGroupData(uint64 guid);
|
||||
uint8 GetKicksLeft(uint64 gguid);
|
||||
uint8 GetVotesNeeded(uint64 gguid);
|
||||
bool IsTeleported(uint64 pguid);
|
||||
void SetRoles(uint64 guid, uint8 roles);
|
||||
void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
|
||||
uint8 RemovePlayerFromGroup(uint64 gguid, uint64 guid);
|
||||
void AddPlayerToGroup(uint64 gguid, uint64 guid);
|
||||
|
||||
LfgLockMap const& GetLockedDungeons(uint64 guid);
|
||||
LfgDungeonSet const& GetSelectedDungeons(uint64 guid);
|
||||
uint32 GetDungeon(uint64 guid, bool asId = true);
|
||||
LfgState GetState(uint64 guid);
|
||||
uint8 GetKicksLeft(uint64 gguid);
|
||||
uint64 GetLeader(uint64 guid);
|
||||
bool IsLfgGroup(uint64 guid);
|
||||
uint8 GetRoles(uint64 guid);
|
||||
std::string const& GetComment(uint64 gguid);
|
||||
LfgGuidSet const& GetPlayers(uint64 guid);
|
||||
|
||||
bool IsTeleported(uint64 guid);
|
||||
|
||||
bool AllQueued(LfgGuidList const& check);
|
||||
static bool HasIgnore(uint64 guid1, uint64 guid2);
|
||||
static void SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data);
|
||||
|
||||
bool IsSeasonActive(uint32 dungeonId);
|
||||
|
||||
static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons);
|
||||
static std::string GetRolesString(uint8 roles);
|
||||
static char const * GetStateString(LfgState state);
|
||||
|
||||
void LoadLFGDungeons(bool reload = false);
|
||||
LFGDungeonData const* GetLFGDungeon(uint32 id);
|
||||
LFGDungeonMap& GetLFGDungeonMap();
|
||||
|
||||
void ClearState(uint64 guid, char const *debugMsg);
|
||||
private:
|
||||
|
||||
uint8 GetRoles(uint64 guid);
|
||||
const std::string& GetComment(uint64 gguid);
|
||||
void RestoreState(uint64 guid);
|
||||
void SetDungeon(uint64 guid, uint32 dungeon);
|
||||
void SetLockedDungeons(uint64 guid, const LfgLockMap& lock);
|
||||
void DecreaseKicksLeft(uint64 guid);
|
||||
uint8 GetTeam(uint64 guid);
|
||||
uint64 GetGroup(uint64 guid);
|
||||
void RestoreState(uint64 guid, char const *debugMsg);
|
||||
|
||||
// Queue
|
||||
void AddToQueue(uint64 guid, uint8 queueId);
|
||||
bool RemoveFromQueue(uint64 guid);
|
||||
void SetDungeon(uint64 guid, uint32 dungeon);
|
||||
void SetLockedDungeons(uint64 guid, LfgLockMap const& lock);
|
||||
void DecreaseKicksLeft(uint64 guid);
|
||||
|
||||
// Proposals
|
||||
void RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType type);
|
||||
|
||||
// Group Matching
|
||||
LfgProposal* FindNewGroups(LfgGuidList& check, LfgGuidList& all);
|
||||
bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
|
||||
bool CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal);
|
||||
void GetCompatibleDungeons(LfgDungeonSet& dungeons, const PlayerSet& players, LfgLockPartyMap& lockMap);
|
||||
void SetCompatibles(std::string concatenatedGuids, bool compatibles);
|
||||
LfgAnswer GetCompatibles(std::string concatenatedGuids);
|
||||
void RemoveFromCompatibles(uint64 guid);
|
||||
void MakeNewGroup(LfgProposal const& proposal);
|
||||
|
||||
// Generic
|
||||
const LfgDungeonSet& GetDungeonsByRandom(uint32 randomdungeon);
|
||||
LfgQueue &GetQueue(uint64 guid);
|
||||
LfgDungeonSet const& GetDungeonsByRandom(uint32 randomdungeon);
|
||||
LfgType GetDungeonType(uint32 dungeon);
|
||||
std::string ConcatenateGuids(LfgGuidList check);
|
||||
|
||||
void SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot);
|
||||
void SendLfgJoinResult(uint64 guid, LfgJoinResultData const& data);
|
||||
void SendLfgRoleChosen(uint64 guid, uint64 pguid, uint8 roles);
|
||||
void SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck);
|
||||
void SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data);
|
||||
void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data);
|
||||
void SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal);
|
||||
|
||||
// General variables
|
||||
bool m_update; ///< Doing an update?
|
||||
uint32 m_QueueTimer; ///< used to check interval of update
|
||||
uint32 m_lfgProposalId; ///< used as internal counter for proposals
|
||||
int32 m_WaitTimeAvg; ///< Average wait time to find a group queuing as multiple roles
|
||||
int32 m_WaitTimeTank; ///< Average wait time to find a group queuing as tank
|
||||
int32 m_WaitTimeHealer; ///< Average wait time to find a group queuing as healer
|
||||
int32 m_WaitTimeDps; ///< Average wait time to find a group queuing as dps
|
||||
uint32 m_NumWaitTimeAvg; ///< Num of players used to calc avs wait time
|
||||
uint32 m_NumWaitTimeTank; ///< Num of players used to calc tank wait time
|
||||
uint32 m_NumWaitTimeHealer; ///< Num of players used to calc healers wait time
|
||||
uint32 m_NumWaitTimeDps; ///< Num of players used to calc dps wait time
|
||||
LfgDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType
|
||||
LfgEntrancePositionMap m_entrancePositions; ///< Stores special entrance positions
|
||||
uint32 m_options; ///< Stores config options
|
||||
|
||||
LfgQueueMap m_Queues; ///< Queues
|
||||
LfgCachedDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType
|
||||
// Reward System
|
||||
LfgRewardMap m_RewardMap; ///< Stores rewards for random dungeons
|
||||
// Queue
|
||||
LfgQueueInfoMap m_QueueInfoMap; ///< Queued groups
|
||||
LfgGuidListMap m_currentQueue; ///< Ordered list. Used to find groups
|
||||
LfgGuidListMap m_newToQueue; ///< New groups to add to queue
|
||||
LfgCompatibleMap m_CompatibleMap; ///< Compatible dungeons
|
||||
LfgGuidList m_teleport; ///< Players being teleported
|
||||
LFGDungeonMap m_LfgDungeonMap;
|
||||
// Rolecheck - Proposal - Vote Kicks
|
||||
LfgRoleCheckMap m_RoleChecks; ///< Current Role checks
|
||||
LfgProposalMap m_Proposals; ///< Current Proposals
|
||||
LfgPlayerBootMap m_Boots; ///< Current player kicks
|
||||
LfgPlayerDataMap m_Players; ///< Player data
|
||||
LfgGroupDataMap m_Groups; ///< Group data
|
||||
LfgGuidList m_teleport; ///< Players being teleported
|
||||
};
|
||||
|
||||
#define sLFGMgr ACE_Singleton<LFGMgr, ACE_Null_Mutex>::instance()
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "LFGPlayerData.h"
|
||||
|
||||
LfgPlayerData::LfgPlayerData():
|
||||
m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Roles(0), m_Comment("")
|
||||
LfgPlayerData::LfgPlayerData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE),
|
||||
m_Team(0), m_Group(0), m_Roles(0), m_Comment("")
|
||||
{}
|
||||
|
||||
LfgPlayerData::~LfgPlayerData()
|
||||
@@ -30,8 +30,11 @@ void LfgPlayerData::SetState(LfgState state)
|
||||
switch (state)
|
||||
{
|
||||
case LFG_STATE_NONE:
|
||||
case LFG_STATE_DUNGEON:
|
||||
case LFG_STATE_FINISHED_DUNGEON:
|
||||
m_Roles = 0;
|
||||
m_SelectedDungeons.clear();
|
||||
// No break on purpose
|
||||
case LFG_STATE_DUNGEON:
|
||||
m_OldState = state;
|
||||
// No break on purpose
|
||||
default:
|
||||
@@ -51,6 +54,16 @@ void LfgPlayerData::SetLockedDungeons(const LfgLockMap& lockStatus)
|
||||
m_LockedDungeons = lockStatus;
|
||||
}
|
||||
|
||||
void LfgPlayerData::SetTeam(uint8 team)
|
||||
{
|
||||
m_Team = team;
|
||||
}
|
||||
|
||||
void LfgPlayerData::SetGroup(uint64 group)
|
||||
{
|
||||
m_Group = group;
|
||||
}
|
||||
|
||||
void LfgPlayerData::SetRoles(uint8 roles)
|
||||
{
|
||||
m_Roles = roles;
|
||||
@@ -66,21 +79,31 @@ void LfgPlayerData::SetSelectedDungeons(const LfgDungeonSet& dungeons)
|
||||
m_SelectedDungeons = dungeons;
|
||||
}
|
||||
|
||||
void LfgPlayerData::ClearSelectedDungeons()
|
||||
{
|
||||
m_SelectedDungeons.clear();
|
||||
}
|
||||
|
||||
LfgState LfgPlayerData::GetState() const
|
||||
{
|
||||
return m_State;
|
||||
}
|
||||
|
||||
const LfgLockMap & LfgPlayerData::GetLockedDungeons() const
|
||||
LfgState LfgPlayerData::GetOldState() const
|
||||
{
|
||||
return m_OldState;
|
||||
}
|
||||
|
||||
const LfgLockMap& LfgPlayerData::GetLockedDungeons() const
|
||||
{
|
||||
return m_LockedDungeons;
|
||||
}
|
||||
|
||||
uint8 LfgPlayerData::GetTeam() const
|
||||
{
|
||||
return m_Team;
|
||||
}
|
||||
|
||||
uint64 LfgPlayerData::GetGroup() const
|
||||
{
|
||||
return m_Group;
|
||||
}
|
||||
|
||||
uint8 LfgPlayerData::GetRoles() const
|
||||
{
|
||||
return m_Roles;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#ifndef _LFGPLAYERDATA_H
|
||||
#define _LFGPLAYERDATA_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "LFG.h"
|
||||
|
||||
/**
|
||||
@@ -33,20 +32,26 @@ class LfgPlayerData
|
||||
// General
|
||||
void SetState(LfgState state);
|
||||
void ClearState();
|
||||
void SetLockedDungeons(const LfgLockMap& lock);
|
||||
void SetLockedDungeons(LfgLockMap const& lock);
|
||||
void SetTeam(uint8 team);
|
||||
void SetGroup(uint64 group);
|
||||
|
||||
// Queue
|
||||
void SetRoles(uint8 roles);
|
||||
void SetComment(const std::string& comment);
|
||||
void SetComment(std::string const& comment);
|
||||
void SetSelectedDungeons(const LfgDungeonSet& dungeons);
|
||||
void ClearSelectedDungeons();
|
||||
|
||||
// General
|
||||
LfgState GetState() const;
|
||||
const LfgLockMap& GetLockedDungeons() const;
|
||||
LfgState GetOldState() const;
|
||||
LfgLockMap const& GetLockedDungeons() const;
|
||||
uint8 GetTeam() const;
|
||||
uint64 GetGroup() const;
|
||||
|
||||
// Queue
|
||||
uint8 GetRoles() const;
|
||||
const std::string& GetComment() const;
|
||||
const LfgDungeonSet& GetSelectedDungeons() const;
|
||||
std::string const& GetComment() const;
|
||||
LfgDungeonSet const& GetSelectedDungeons() const;
|
||||
|
||||
private:
|
||||
// General
|
||||
@@ -54,6 +59,9 @@ class LfgPlayerData
|
||||
LfgState m_OldState; ///< Old State
|
||||
// Player
|
||||
LfgLockMap m_LockedDungeons; ///< Dungeons player can't do and reason
|
||||
uint8 m_Team; ///< Player team - determines the queue to join
|
||||
uint64 m_Group; ///< Original group of player when joined LFG
|
||||
|
||||
// Queue
|
||||
uint8 m_Roles; ///< Roles the player selected when joined LFG
|
||||
std::string m_Comment; ///< Player comment used when joined LFG
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ObjectDefines.h"
|
||||
#include "Containers.h"
|
||||
#include "DBCStructure.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Group.h"
|
||||
#include "LFGQueue.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
|
||||
/**
|
||||
Given a list of guids returns the concatenation using | as delimiter
|
||||
|
||||
@param[in] check list of guids
|
||||
@returns Concatenated string
|
||||
*/
|
||||
std::string ConcatenateGuids(LfgGuidList const& check)
|
||||
{
|
||||
if (check.empty())
|
||||
return "";
|
||||
|
||||
// need the guids in order to avoid duplicates
|
||||
LfgGuidSet guids(check.begin(), check.end());
|
||||
|
||||
std::ostringstream o;
|
||||
|
||||
LfgGuidSet::const_iterator it = guids.begin();
|
||||
o << (*it);
|
||||
for (++it; it != guids.end(); ++it)
|
||||
o << '|' << (*it);
|
||||
|
||||
return o.str();
|
||||
}
|
||||
|
||||
char const * GetCompatibleString(LfgCompatibility compatibles)
|
||||
{
|
||||
switch (compatibles)
|
||||
{
|
||||
case LFG_COMPATIBILITY_PENDING:
|
||||
return "Pending";
|
||||
case LFG_COMPATIBLES_BAD_STATES:
|
||||
return "Compatibles (Bad States)";
|
||||
case LFG_COMPATIBLES_MATCH:
|
||||
return "Match";
|
||||
case LFG_COMPATIBLES_WITH_LESS_PLAYERS:
|
||||
return "Compatibles (Not enough players)";
|
||||
case LFG_INCOMPATIBLES_HAS_IGNORES:
|
||||
return "Has ignores";
|
||||
case LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS:
|
||||
return "Multiple Lfg Groups";
|
||||
case LFG_INCOMPATIBLES_NO_DUNGEONS:
|
||||
return "Incompatible dungeons";
|
||||
case LFG_INCOMPATIBLES_NO_ROLES:
|
||||
return "Incompatible roles";
|
||||
case LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS:
|
||||
return "Too much players";
|
||||
case LFG_INCOMPATIBLES_WRONG_GROUP_SIZE:
|
||||
return "Wrong group size";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void LfgQueue::AddToQueue(uint64 guid)
|
||||
{
|
||||
LfgQueueDataMap::iterator itQueue = m_QueueDataMap.find(guid);
|
||||
if (itQueue == m_QueueDataMap.end())
|
||||
{
|
||||
sLog->outError(LOG_FILTER_LFG, "LfgQueue::AddToQueue: Queue data not found for [" UI64FMTD "]", guid);
|
||||
return;
|
||||
}
|
||||
|
||||
AddToNewQueue(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::RemoveFromQueue(uint64 guid)
|
||||
{
|
||||
RemoveFromNewQueue(guid);
|
||||
RemoveFromCurrentQueue(guid);
|
||||
RemoveFromCompatibles(guid);
|
||||
RemoveQueueData(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::AddToNewQueue(uint64 guid)
|
||||
{
|
||||
m_newToQueue.push_back(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::RemoveFromNewQueue(uint64 guid)
|
||||
{
|
||||
m_newToQueue.remove(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::AddToCurrentQueue(uint64 guid)
|
||||
{
|
||||
m_currentQueue.push_back(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::RemoveFromCurrentQueue(uint64 guid)
|
||||
{
|
||||
m_currentQueue.remove(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap)
|
||||
{
|
||||
m_QueueDataMap[guid] = LfgQueueData(joinTime, dungeons, rolesMap);
|
||||
AddToQueue(guid);
|
||||
}
|
||||
|
||||
void LfgQueue::RemoveQueueData(uint64 guid)
|
||||
{
|
||||
LfgQueueDataMap::iterator it = m_QueueDataMap.find(guid);
|
||||
if (it != m_QueueDataMap.end())
|
||||
m_QueueDataMap.erase(it);
|
||||
}
|
||||
|
||||
void LfgQueue::UpdateWaitTimeAvg(int32 waitTime, uint32 dungeonId)
|
||||
{
|
||||
LfgWaitTime &wt = m_waitTimesAvg[dungeonId];
|
||||
uint32 old_number = wt.number++;
|
||||
wt.time = int32((wt.time * old_number + waitTime) / wt.number);
|
||||
}
|
||||
|
||||
void LfgQueue::UpdateWaitTimeTank(int32 waitTime, uint32 dungeonId)
|
||||
{
|
||||
LfgWaitTime &wt = m_waitTimesTank[dungeonId];
|
||||
uint32 old_number = wt.number++;
|
||||
wt.time = int32((wt.time * old_number + waitTime) / wt.number);
|
||||
}
|
||||
|
||||
void LfgQueue::UpdateWaitTimeHealer(int32 waitTime, uint32 dungeonId)
|
||||
{
|
||||
LfgWaitTime &wt = m_waitTimesHealer[dungeonId];
|
||||
uint32 old_number = wt.number++;
|
||||
wt.time = int32((wt.time * old_number + waitTime) / wt.number);
|
||||
}
|
||||
|
||||
void LfgQueue::UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId)
|
||||
{
|
||||
LfgWaitTime &wt = m_waitTimesDps[dungeonId];
|
||||
uint32 old_number = wt.number++;
|
||||
wt.time = int32((wt.time * old_number + waitTime) / wt.number);
|
||||
}
|
||||
|
||||
/**
|
||||
Remove from cached compatible dungeons any entry that contains the given guid
|
||||
|
||||
@param[in] guid Guid to remove from compatible cache
|
||||
*/
|
||||
void LfgQueue::RemoveFromCompatibles(uint64 guid)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << guid;
|
||||
std::string strGuid = out.str();
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LfgQueue::RemoveFromCompatibles: Removing [" UI64FMTD "]", guid);
|
||||
for (LfgCompatibleMap::iterator itNext = m_CompatibleMap.begin(); itNext != m_CompatibleMap.end();)
|
||||
{
|
||||
LfgCompatibleMap::iterator it = itNext++;
|
||||
if (it->first.find(strGuid) != std::string::npos) // Found, remove it
|
||||
m_CompatibleMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stores the compatibility of a list of guids
|
||||
|
||||
@param[in] key String concatenation of guids (| used as separator)
|
||||
@param[in] compatibles type of compatibility
|
||||
*/
|
||||
void LfgQueue::SetCompatibles(const std::string &key, LfgCompatibility compatibles)
|
||||
{
|
||||
m_CompatibleMap[key] = compatibles;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the compatibility of a group of guids
|
||||
|
||||
@param[in] key String concatenation of guids (| used as separator)
|
||||
@return LfgCompatibility type of compatibility
|
||||
*/
|
||||
LfgCompatibility LfgQueue::GetCompatibles(std::string const& key)
|
||||
{
|
||||
LfgCompatibleMap::iterator it = m_CompatibleMap.find(key);
|
||||
if (it != m_CompatibleMap.end())
|
||||
return it->second;
|
||||
|
||||
return LFG_COMPATIBILITY_PENDING;
|
||||
}
|
||||
|
||||
uint8 LfgQueue::FindGroups()
|
||||
{
|
||||
uint8 proposals = 0;
|
||||
LfgGuidList firstNew;
|
||||
while (!m_newToQueue.empty())
|
||||
{
|
||||
uint64 frontguid = m_newToQueue.front();
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LfgQueue::FindGroups: checking [" UI64FMTD "] newToQueue(%u), currentQueue(%u)", frontguid, uint32(m_newToQueue.size()), uint32(m_currentQueue.size()));
|
||||
firstNew.clear();
|
||||
firstNew.push_back(frontguid);
|
||||
RemoveFromNewQueue(frontguid);
|
||||
|
||||
LfgGuidList temporalList = m_currentQueue;
|
||||
LfgCompatibility compatibles = FindNewGroups(firstNew, temporalList);
|
||||
|
||||
if (compatibles == LFG_COMPATIBLES_MATCH)
|
||||
++proposals;
|
||||
else
|
||||
AddToCurrentQueue(frontguid); // Lfg group not found, add this group to the queue.
|
||||
}
|
||||
return proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
Checks que main queue to try to form a Lfg group. Returns first match found (if any)
|
||||
|
||||
@param[in] check List of guids trying to match with other groups
|
||||
@param[in] all List of all other guids in main queue to match against
|
||||
@return LfgCompatibility type of compatibility between groups
|
||||
*/
|
||||
LfgCompatibility LfgQueue::FindNewGroups(LfgGuidList& check, LfgGuidList& all)
|
||||
{
|
||||
std::string strGuids = ConcatenateGuids(check);
|
||||
LfgCompatibility compatibles = GetCompatibles(strGuids);
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::FindNewGroup: (%s): %s - all(%s)", strGuids.c_str(), GetCompatibleString(compatibles), ConcatenateGuids(all).c_str());
|
||||
if (compatibles == LFG_COMPATIBILITY_PENDING || compatibles == LFG_COMPATIBLES_BAD_STATES) // Not previously cached, calculate
|
||||
compatibles = CheckCompatibility(check);
|
||||
|
||||
if (compatibles != LFG_COMPATIBLES_WITH_LESS_PLAYERS)
|
||||
return compatibles;
|
||||
|
||||
// Try to match with queued groups
|
||||
while (!all.empty())
|
||||
{
|
||||
check.push_back(all.front());
|
||||
all.pop_front();
|
||||
LfgCompatibility subcompatibility = FindNewGroups(check, all);
|
||||
if (subcompatibility == LFG_COMPATIBLES_MATCH)
|
||||
return LFG_COMPATIBLES_MATCH;
|
||||
check.pop_back();
|
||||
}
|
||||
return compatibles;
|
||||
}
|
||||
|
||||
/**
|
||||
Check compatibilities between groups. If group is Matched proposal will be created
|
||||
|
||||
@param[in] check List of guids to check compatibilities
|
||||
@return LfgCompatibility type of compatibility
|
||||
*/
|
||||
LfgCompatibility LfgQueue::CheckCompatibility(LfgGuidList check)
|
||||
{
|
||||
std::string strGuids = ConcatenateGuids(check);
|
||||
LfgProposal proposal;
|
||||
LfgDungeonSet proposalDungeons;
|
||||
LfgGroupsMap proposalGroups;
|
||||
LfgRolesMap proposalRoles;
|
||||
|
||||
// Check for correct size
|
||||
if (check.size() > MAXGROUPSIZE || check.empty())
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s): Size wrong - Not compatibles", strGuids.c_str());
|
||||
return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE;
|
||||
}
|
||||
|
||||
// Player joining alone always compatible
|
||||
if (check.size() == 1 && IS_PLAYER_GUID(check.front()))
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
|
||||
// Check all-but-new compatiblitity
|
||||
if (check.size() > 2)
|
||||
{
|
||||
uint64 frontGuid = check.front();
|
||||
check.pop_front();
|
||||
|
||||
// Check all-but-new compatibilities (New, A, B, C, D) --> check(A, B, C, D)
|
||||
LfgCompatibility child_compatibles = CheckCompatibility(check);
|
||||
if (child_compatibles < LFG_COMPATIBLES_WITH_LESS_PLAYERS) // Group not compatible
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) child %s not compatibles", strGuids.c_str(), ConcatenateGuids(check).c_str());
|
||||
SetCompatibles(strGuids, child_compatibles);
|
||||
return child_compatibles;
|
||||
}
|
||||
check.push_front(frontGuid);
|
||||
}
|
||||
|
||||
// Check if more than one LFG group and number of players joining
|
||||
uint8 numPlayers = 0;
|
||||
uint8 numLfgGroups = 0;
|
||||
for (LfgGuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAXGROUPSIZE; ++it)
|
||||
{
|
||||
uint64 guid = (*it);
|
||||
LfgQueueDataMap::iterator itQueue = m_QueueDataMap.find(guid);
|
||||
if (itQueue == m_QueueDataMap.end())
|
||||
{
|
||||
sLog->outError(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: [" UI64FMTD "] is not queued but listed as queued!", guid);
|
||||
RemoveFromQueue(guid);
|
||||
return LFG_COMPATIBILITY_PENDING;
|
||||
}
|
||||
|
||||
// Store group so we don't need to call Mgr to get it later (if it's player group will be 0 otherwise would have joined as group)
|
||||
for (LfgRolesMap::const_iterator it2 = itQueue->second.roles.begin(); it2 != itQueue->second.roles.end(); ++it2)
|
||||
proposalGroups[it2->first] = IS_GROUP(itQueue->first) ? itQueue->first : 0;
|
||||
|
||||
numPlayers += itQueue->second.roles.size();
|
||||
|
||||
if (sLFGMgr->IsLfgGroup(guid))
|
||||
{
|
||||
if (!numLfgGroups)
|
||||
proposal.group = guid;
|
||||
++numLfgGroups;
|
||||
}
|
||||
}
|
||||
|
||||
// Group with less that MAXGROUPSIZE members always compatible
|
||||
if (check.size() == 1 && numPlayers != MAXGROUPSIZE)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) sigle group. Compatibles", strGuids.c_str());
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
}
|
||||
|
||||
if (numLfgGroups > 1)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) More than one Lfggroup (%u)", strGuids.c_str(), numLfgGroups);
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS);
|
||||
return LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS;
|
||||
}
|
||||
|
||||
if (numPlayers > MAXGROUPSIZE)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Too much players (%u)", strGuids.c_str(), numPlayers);
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS);
|
||||
return LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS;
|
||||
}
|
||||
|
||||
// If it's single group no need to check for duplicate players, ignores, bad roles or bad dungeons as it's been checked before joining
|
||||
if (check.size() > 1)
|
||||
{
|
||||
for (LfgGuidList::const_iterator it = check.begin(); it != check.end(); ++it)
|
||||
{
|
||||
const LfgRolesMap &roles = m_QueueDataMap[(*it)].roles;
|
||||
for (LfgRolesMap::const_iterator itRoles = roles.begin(); itRoles != roles.end(); ++itRoles)
|
||||
{
|
||||
LfgRolesMap::const_iterator itPlayer;
|
||||
for (itPlayer = proposalRoles.begin(); itPlayer != proposalRoles.end(); ++itPlayer)
|
||||
{
|
||||
if (itRoles->first == itPlayer->first)
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: ERROR! Player multiple times in queue! [" UI64FMTD "]", itRoles->first);
|
||||
else if (sLFGMgr->HasIgnore(itRoles->first, itPlayer->first))
|
||||
break;
|
||||
}
|
||||
if (itPlayer == proposalRoles.end())
|
||||
proposalRoles[itRoles->first] = itRoles->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (uint8 playersize = numPlayers - proposalRoles.size())
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) not compatible, %u players are ignoring each other", strGuids.c_str(), playersize);
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_HAS_IGNORES);
|
||||
return LFG_INCOMPATIBLES_HAS_IGNORES;
|
||||
}
|
||||
|
||||
LfgRolesMap debugRoles = proposalRoles; // DEBUG
|
||||
if (!LFGMgr::CheckGroupRoles(proposalRoles))
|
||||
{
|
||||
std::ostringstream o;
|
||||
for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it)
|
||||
o << ", " << it->first << ": " << sLFGMgr->GetRolesString(it->second);
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Roles not compatible%s", strGuids.c_str(), o.str().c_str());
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES);
|
||||
return LFG_INCOMPATIBLES_NO_ROLES;
|
||||
}
|
||||
|
||||
LfgGuidList::iterator itguid = check.begin();
|
||||
proposalDungeons = m_QueueDataMap[*itguid].dungeons;
|
||||
std::ostringstream o;
|
||||
o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(proposalDungeons) << ")";
|
||||
for (++itguid; itguid != check.end(); ++itguid)
|
||||
{
|
||||
LfgDungeonSet temporal;
|
||||
LfgDungeonSet &dungeons = m_QueueDataMap[*itguid].dungeons;
|
||||
o << ", " << *itguid << ": (" << sLFGMgr->ConcatenateDungeons(dungeons) << ")";
|
||||
std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
|
||||
proposalDungeons = temporal;
|
||||
}
|
||||
|
||||
if (proposalDungeons.empty())
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) No compatible dungeons%s", strGuids.c_str(), o.str().c_str());
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_DUNGEONS);
|
||||
return LFG_INCOMPATIBLES_NO_DUNGEONS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 gguid = *check.begin();
|
||||
const LfgQueueData &queue = m_QueueDataMap[gguid];
|
||||
proposalDungeons = queue.dungeons;
|
||||
proposalRoles = queue.roles;
|
||||
LFGMgr::CheckGroupRoles(proposalRoles); // assing new roles
|
||||
}
|
||||
|
||||
// Enough players?
|
||||
if (numPlayers != MAXGROUPSIZE)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers);
|
||||
SetCompatibles(strGuids, LFG_COMPATIBLES_WITH_LESS_PLAYERS);
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
}
|
||||
|
||||
proposal.queues = check;
|
||||
if (check.size() == 1)
|
||||
{
|
||||
for (LfgGroupsMap::const_iterator it = proposalGroups.begin(); it != proposalGroups.end(); ++it)
|
||||
if (proposal.group && it->second != proposal.group)
|
||||
proposal.isNew = false;
|
||||
}
|
||||
|
||||
if (!sLFGMgr->AllQueued(check))
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) Group MATCH but can't create proposal!", strGuids.c_str());
|
||||
SetCompatibles(strGuids, LFG_COMPATIBLES_BAD_STATES);
|
||||
return LFG_COMPATIBLES_BAD_STATES;
|
||||
}
|
||||
|
||||
// Create a new proposal
|
||||
proposal.cancelTime = time(NULL) + LFG_TIME_PROPOSAL;
|
||||
proposal.state = LFG_PROPOSAL_INITIATING;
|
||||
proposal.leader = 0;
|
||||
proposal.dungeonId = Trinity::Containers::SelectRandomContainerElement(proposalDungeons);
|
||||
|
||||
bool leader = false;
|
||||
for (LfgRolesMap::const_iterator itRoles = proposalRoles.begin(); itRoles != proposalRoles.end(); ++itRoles)
|
||||
{
|
||||
// Assing new leader
|
||||
if (itRoles->second & PLAYER_ROLE_LEADER)
|
||||
{
|
||||
if (!leader || !proposal.leader || urand(0, 1))
|
||||
proposal.leader = itRoles->first;
|
||||
leader = true;
|
||||
}
|
||||
else if (!leader && (!proposal.leader || urand(0, 1)))
|
||||
proposal.leader = itRoles->first;
|
||||
|
||||
// Assing player data and roles
|
||||
LfgProposalPlayer &data = proposal.players[itRoles->first];
|
||||
data.role = itRoles->second;
|
||||
data.group = proposalGroups.find(itRoles->first)->second;
|
||||
if (!proposal.isNew && data.group && data.group == proposal.group) // Player from existing group, autoaccept
|
||||
data.accept = LFG_ANSWER_AGREE;
|
||||
}
|
||||
|
||||
// Mark proposal members as not queued (but not remove queue data)
|
||||
for (LfgGuidList::const_iterator itQueue = proposal.queues.begin(); itQueue != proposal.queues.end(); ++itQueue)
|
||||
{
|
||||
uint64 guid = (*itQueue);
|
||||
RemoveFromNewQueue(guid);
|
||||
RemoveFromCurrentQueue(guid);
|
||||
}
|
||||
|
||||
sLFGMgr->AddProposal(proposal);
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGQueue::CheckCompatibility: (%s) MATCH! Group formed", strGuids.c_str());
|
||||
SetCompatibles(strGuids, LFG_COMPATIBLES_MATCH);
|
||||
return LFG_COMPATIBLES_MATCH;
|
||||
}
|
||||
|
||||
void LfgQueue::UpdateQueueTimers(time_t currTime)
|
||||
{
|
||||
for (LfgQueueDataMap::const_iterator itQueue = m_QueueDataMap.begin(); itQueue != m_QueueDataMap.end(); ++itQueue)
|
||||
{
|
||||
const LfgQueueData &queueinfo = itQueue->second;
|
||||
uint32 dungeonId = (*queueinfo.dungeons.begin());
|
||||
uint32 queuedTime = uint32(currTime - queueinfo.joinTime);
|
||||
uint8 role = PLAYER_ROLE_NONE;
|
||||
int32 waitTime = -1;
|
||||
int32 wtTank = m_waitTimesTank[dungeonId].time;
|
||||
int32 wtHealer = m_waitTimesHealer[dungeonId].time;
|
||||
int32 wtDps = m_waitTimesDps[dungeonId].time;
|
||||
int32 wtAvg = m_waitTimesAvg[dungeonId].time;
|
||||
|
||||
for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer)
|
||||
role |= itPlayer->second;
|
||||
role &= ~PLAYER_ROLE_LEADER;
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case PLAYER_ROLE_NONE: // Should not happen - just in case
|
||||
waitTime = -1;
|
||||
break;
|
||||
case PLAYER_ROLE_TANK:
|
||||
waitTime = wtTank;
|
||||
break;
|
||||
case PLAYER_ROLE_HEALER:
|
||||
waitTime = wtHealer;
|
||||
break;
|
||||
case PLAYER_ROLE_DAMAGE:
|
||||
waitTime = wtDps;
|
||||
break;
|
||||
default:
|
||||
waitTime = wtAvg;
|
||||
break;
|
||||
}
|
||||
|
||||
LfgQueueStatusData queueData(dungeonId, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps);
|
||||
for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer)
|
||||
{
|
||||
uint64 pguid = itPlayer->first;
|
||||
LFGMgr::SendLfgQueueStatus(pguid, queueData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
time_t LfgQueue::GetJoinTime(uint64 guid)
|
||||
{
|
||||
return m_QueueDataMap[guid].joinTime;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LFGQUEUE_H
|
||||
#define _LFGQUEUE_H
|
||||
|
||||
#include "LFG.h"
|
||||
|
||||
enum LfgCompatibility
|
||||
{
|
||||
LFG_COMPATIBILITY_PENDING,
|
||||
LFG_INCOMPATIBLES_WRONG_GROUP_SIZE,
|
||||
LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS,
|
||||
LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS,
|
||||
LFG_INCOMPATIBLES_HAS_IGNORES,
|
||||
LFG_INCOMPATIBLES_NO_ROLES,
|
||||
LFG_INCOMPATIBLES_NO_DUNGEONS,
|
||||
LFG_COMPATIBLES_WITH_LESS_PLAYERS, // Values under this = not compatible (do not modify order)
|
||||
LFG_COMPATIBLES_BAD_STATES,
|
||||
LFG_COMPATIBLES_MATCH // Must be the last one
|
||||
};
|
||||
|
||||
/// Stores player or group queue info
|
||||
struct LfgQueueData
|
||||
{
|
||||
LfgQueueData(): joinTime(time_t(time(NULL))), tanks(LFG_TANKS_NEEDED),
|
||||
healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED)
|
||||
{ }
|
||||
|
||||
LfgQueueData(time_t _joinTime, const LfgDungeonSet &_dungeons, const LfgRolesMap &_roles)
|
||||
{
|
||||
joinTime = _joinTime;
|
||||
dungeons = _dungeons;
|
||||
roles = _roles;
|
||||
tanks = LFG_TANKS_NEEDED;
|
||||
healers = LFG_HEALERS_NEEDED;
|
||||
dps = LFG_DPS_NEEDED;
|
||||
|
||||
for (LfgRolesMap::const_iterator it = roles.begin(); it != roles.end(); ++it)
|
||||
{
|
||||
uint8 role = it->second;
|
||||
if (role & PLAYER_ROLE_TANK)
|
||||
--tanks;
|
||||
else if (role & PLAYER_ROLE_HEALER)
|
||||
--healers;
|
||||
else
|
||||
--dps;
|
||||
}
|
||||
}
|
||||
|
||||
time_t joinTime; ///< Player queue join time (to calculate wait times)
|
||||
uint8 tanks; ///< Tanks needed
|
||||
uint8 healers; ///< Healers needed
|
||||
uint8 dps; ///< Dps needed
|
||||
LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s
|
||||
LfgRolesMap roles; ///< Selected Player Role/s
|
||||
};
|
||||
|
||||
struct LfgWaitTime
|
||||
{
|
||||
LfgWaitTime(): time(-1), number(0) {}
|
||||
int32 time; ///< Wait time
|
||||
uint32 number; ///< Number of people used to get that wait time
|
||||
};
|
||||
|
||||
typedef std::map<uint32, LfgWaitTime> LfgWaitTimesMap;
|
||||
typedef std::map<std::string, LfgCompatibility> LfgCompatibleMap;
|
||||
typedef std::map<uint64, LfgQueueData> LfgQueueDataMap;
|
||||
|
||||
/**
|
||||
Stores all data related to queue
|
||||
*/
|
||||
class LfgQueue
|
||||
{
|
||||
public:
|
||||
|
||||
// Add/Remove from queue
|
||||
void AddToQueue(uint64 guid);
|
||||
void RemoveFromQueue(uint64 guid);
|
||||
void AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap);
|
||||
void RemoveQueueData(uint64 guid);
|
||||
|
||||
// Update Timers (when proposal success)
|
||||
void UpdateWaitTimeAvg(int32 waitTime, uint32 dungeonId);
|
||||
void UpdateWaitTimeTank(int32 waitTime, uint32 dungeonId);
|
||||
void UpdateWaitTimeHealer(int32 waitTime, uint32 dungeonId);
|
||||
void UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId);
|
||||
|
||||
// Update Queue timers
|
||||
void UpdateQueueTimers(time_t currTime);
|
||||
time_t GetJoinTime(uint64 guid);
|
||||
|
||||
// Find new group
|
||||
uint8 FindGroups();
|
||||
|
||||
// Just for debugging purposes
|
||||
LfgCompatibleMap const& GetCompatibleMap();
|
||||
std::string DumpQueueInfo() const;
|
||||
std::string DumpCompatibleInfo() const;
|
||||
private:
|
||||
void AddToNewQueue(uint64 guid);
|
||||
void AddToCurrentQueue(uint64 guid);
|
||||
void RemoveFromNewQueue(uint64 guid);
|
||||
void RemoveFromCurrentQueue(uint64 guid);
|
||||
|
||||
void SetCompatibles(std::string const& key, LfgCompatibility compatibles);
|
||||
LfgCompatibility GetCompatibles(std::string const& key);
|
||||
void RemoveFromCompatibles(uint64 guid);
|
||||
|
||||
LfgCompatibility FindNewGroups(LfgGuidList& check, LfgGuidList& all);
|
||||
LfgCompatibility CheckCompatibility(LfgGuidList check);
|
||||
|
||||
// Queue
|
||||
LfgQueueDataMap m_QueueDataMap; ///< Queued groups
|
||||
LfgCompatibleMap m_CompatibleMap; ///< Compatible dungeons
|
||||
|
||||
LfgWaitTimesMap m_waitTimesAvg; ///< Average wait time to find a group queuing as multiple roles
|
||||
LfgWaitTimesMap m_waitTimesTank; ///< Average wait time to find a group queuing as tank
|
||||
LfgWaitTimesMap m_waitTimesHealer; ///< Average wait time to find a group queuing as healer
|
||||
LfgWaitTimesMap m_waitTimesDps; ///< Average wait time to find a group queuing as dps
|
||||
LfgGuidList m_currentQueue; ///< Ordered list. Used to find groups
|
||||
LfgGuidList m_newToQueue; ///< New groups to add to queue
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -39,12 +39,12 @@ void LFGPlayerScript::OnLevelChanged(Player* player, uint8 /*oldLevel*/)
|
||||
|
||||
void LFGPlayerScript::OnLogout(Player* player)
|
||||
{
|
||||
sLFGMgr->Leave(player);
|
||||
uint64 guid = player->GetGUID();
|
||||
sLFGMgr->LeaveLfg(guid);
|
||||
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
|
||||
player->GetSession()->SendLfgUpdateParty(updateData);
|
||||
player->GetSession()->SendLfgUpdatePlayer(updateData);
|
||||
player->GetSession()->SendLfgUpdateSearch(false);
|
||||
uint64 guid = player->GetGUID();
|
||||
player->GetSession()->SendLfgLfrList(false);
|
||||
// TODO - Do not remove, add timer before deleting
|
||||
sLFGMgr->RemovePlayerData(guid);
|
||||
}
|
||||
@@ -52,6 +52,7 @@ void LFGPlayerScript::OnLogout(Player* player)
|
||||
void LFGPlayerScript::OnLogin(Player* player)
|
||||
{
|
||||
sLFGMgr->InitializeLockedDungeons(player);
|
||||
sLFGMgr->SetTeam(player->GetGUID(), player->GetTeam());
|
||||
// TODO - Restore LfgPlayerData and send proper status to player if it was in a group
|
||||
}
|
||||
|
||||
@@ -69,10 +70,18 @@ LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript")
|
||||
void LFGGroupScript::OnAddMember(Group* group, uint64 guid)
|
||||
{
|
||||
uint64 gguid = group->GetGUID();
|
||||
if (!gguid)
|
||||
return;
|
||||
uint64 leader = group->GetLeaderGUID();
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnAddMember [" UI64FMTD "]: added [" UI64FMTD "]", gguid, guid);
|
||||
if (leader == guid)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnAddMember [" UI64FMTD "]: added [" UI64FMTD "] leader " UI64FMTD "]", gguid, guid, leader);
|
||||
sLFGMgr->SetLeader(gguid, guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
LfgState gstate = sLFGMgr->GetState(gguid);
|
||||
LfgState state = sLFGMgr->GetState(guid);
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnAddMember [" UI64FMTD "]: added [" UI64FMTD "] leader " UI64FMTD "] gstate: %u, state: %u", gguid, guid, leader, gstate, state);
|
||||
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_CLEAR_LOCK_LIST);
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
@@ -83,61 +92,67 @@ void LFGGroupScript::OnAddMember(Group* group, uint64 guid)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - if group is queued and new player is added convert to rolecheck without notify the current players queued
|
||||
if (sLFGMgr->GetState(gguid) == LFG_STATE_QUEUED)
|
||||
sLFGMgr->Leave(NULL, group);
|
||||
if (state == LFG_STATE_QUEUED)
|
||||
sLFGMgr->LeaveLfg(guid);
|
||||
|
||||
if (sLFGMgr->GetState(guid) == LFG_STATE_QUEUED)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(guid))
|
||||
sLFGMgr->Leave(player);
|
||||
// TODO - if group is queued and new player is added convert to rolecheck without notify the current players queued
|
||||
if (gstate == LFG_STATE_QUEUED)
|
||||
sLFGMgr->LeaveLfg(gguid);
|
||||
}
|
||||
|
||||
sLFGMgr->SetGroup(guid, gguid);
|
||||
sLFGMgr->AddPlayerToGroup(gguid, guid);
|
||||
}
|
||||
|
||||
void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason)
|
||||
{
|
||||
uint64 gguid = group->GetGUID();
|
||||
if (!gguid || method == GROUP_REMOVEMETHOD_DEFAULT)
|
||||
return;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnRemoveMember [" UI64FMTD "]: remove [" UI64FMTD "] Method: %d Kicker: [" UI64FMTD "] Reason: %s", gguid, guid, method, kicker, (reason ? reason : ""));
|
||||
if (sLFGMgr->GetState(gguid) == LFG_STATE_QUEUED)
|
||||
{
|
||||
// TODO - Do not remove, just remove the one leaving and rejoin queue with all other data
|
||||
sLFGMgr->Leave(NULL, group);
|
||||
}
|
||||
|
||||
if (!group->isLFGGroup())
|
||||
return;
|
||||
bool isLFG = group->isLFGGroup();
|
||||
|
||||
if (method == GROUP_REMOVEMETHOD_KICK) // Player have been kicked
|
||||
if (isLFG && method == GROUP_REMOVEMETHOD_KICK) // Player have been kicked
|
||||
{
|
||||
// TODO - Update internal kick cooldown of kicker
|
||||
std::string str_reason = "";
|
||||
if (reason)
|
||||
str_reason = std::string(reason);
|
||||
sLFGMgr->InitBoot(group, kicker, guid, str_reason);
|
||||
sLFGMgr->InitBoot(gguid, kicker, guid, str_reason);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 state = sLFGMgr->GetState(gguid);
|
||||
sLFGMgr->ClearState(guid);
|
||||
LfgState state = sLFGMgr->GetState(gguid);
|
||||
|
||||
// If group is being formed after proposal success do nothing more
|
||||
if (state == LFG_STATE_PROPOSAL && method == GROUP_REMOVEMETHOD_DEFAULT)
|
||||
{
|
||||
// LfgData: Remove player from group
|
||||
sLFGMgr->SetGroup(guid, 0);
|
||||
sLFGMgr->RemovePlayerFromGroup(gguid, guid);
|
||||
return;
|
||||
}
|
||||
|
||||
sLFGMgr->LeaveLfg(guid);
|
||||
sLFGMgr->SetState(guid, LFG_STATE_NONE);
|
||||
sLFGMgr->SetGroup(guid, 0);
|
||||
uint8 players = sLFGMgr->RemovePlayerFromGroup(gguid, guid);
|
||||
|
||||
if (Player* player = ObjectAccessor::FindPlayer(guid))
|
||||
{
|
||||
if (method == GROUP_REMOVEMETHOD_LEAVE && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON && sLFGMgr->GetDungeon(gguid, false))
|
||||
if (method == GROUP_REMOVEMETHOD_LEAVE && state == LFG_STATE_DUNGEON &&
|
||||
players >= LFG_GROUP_KICK_VOTES_NEEDED)
|
||||
player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, true);
|
||||
/*
|
||||
else if (group->isLfgKickActive())
|
||||
//else if (state == LFG_STATE_BOOT)
|
||||
// Update internal kick cooldown of kicked
|
||||
*/
|
||||
|
||||
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_LEADER);
|
||||
player->GetSession()->SendLfgUpdateParty(updateData);
|
||||
if (player->GetMap()->IsDungeon()) // Teleport player out the dungeon
|
||||
player->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_LEADER_UNK1));
|
||||
if (isLFG && player->GetMap()->IsDungeon()) // Teleport player out the dungeon
|
||||
sLFGMgr->TeleportPlayer(player, true);
|
||||
}
|
||||
|
||||
if (state != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon
|
||||
sLFGMgr->OfferContinue(group);
|
||||
if (isLFG && state != LFG_STATE_FINISHED_DUNGEON) // Need more players to finish the dungeon
|
||||
if (Player* leader = ObjectAccessor::FindPlayer(sLFGMgr->GetLeader(gguid)))
|
||||
leader->GetSession()->SendLfgOfferContinue(sLFGMgr->GetDungeon(gguid, false));
|
||||
}
|
||||
|
||||
void LFGGroupScript::OnDisband(Group* group)
|
||||
@@ -151,30 +166,19 @@ void LFGGroupScript::OnDisband(Group* group)
|
||||
void LFGGroupScript::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid)
|
||||
{
|
||||
uint64 gguid = group->GetGUID();
|
||||
if (!gguid)
|
||||
return;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnChangeLeader [" UI64FMTD "]: old [" UI64FMTD "] new [" UI64FMTD "]", gguid, newLeaderGuid, oldLeaderGuid);
|
||||
Player* player = ObjectAccessor::FindPlayer(newLeaderGuid);
|
||||
|
||||
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_LEADER);
|
||||
if (player)
|
||||
player->GetSession()->SendLfgUpdateParty(updateData);
|
||||
|
||||
player = ObjectAccessor::FindPlayer(oldLeaderGuid);
|
||||
if (player)
|
||||
{
|
||||
updateData.updateType = LFG_UPDATETYPE_GROUP_DISBAND;
|
||||
player->GetSession()->SendLfgUpdateParty(updateData);
|
||||
}
|
||||
sLFGMgr->SetLeader(gguid, newLeaderGuid);
|
||||
}
|
||||
|
||||
void LFGGroupScript::OnInviteMember(Group* group, uint64 guid)
|
||||
{
|
||||
uint64 gguid = group->GetGUID();
|
||||
if (!gguid)
|
||||
return;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnInviteMember [" UI64FMTD "]: invite [" UI64FMTD "] leader [" UI64FMTD "]", gguid, guid, group->GetLeaderGUID());
|
||||
sLFGMgr->Leave(NULL, group);
|
||||
uint64 leader = group->GetLeaderGUID();
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnInviteMember [" UI64FMTD "]: invite [" UI64FMTD "] leader [" UI64FMTD "]", gguid, guid, leader);
|
||||
// No gguid == new group being formed
|
||||
// No leader == after group creation first invite is new leader
|
||||
// leader and no gguid == first invite after leader is added to new group (this is the real invite)
|
||||
if (leader && !gguid)
|
||||
sLFGMgr->LeaveLfg(leader);
|
||||
}
|
||||
|
||||
@@ -1522,14 +1522,18 @@ void GameObject::Use(Unit* user)
|
||||
|
||||
Player* player = user->ToPlayer();
|
||||
|
||||
if (player->CanUseBattlegroundObject())
|
||||
if (player->CanUseBattlegroundObject(this))
|
||||
{
|
||||
// in battleground check
|
||||
Battleground* bg = player->GetBattleground();
|
||||
if (!bg)
|
||||
return;
|
||||
|
||||
if (player->GetVehicle())
|
||||
return;
|
||||
|
||||
player->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
|
||||
player->RemoveAurasByType(SPELL_AURA_MOD_INVISIBILITY);
|
||||
// BG flag click
|
||||
// AB:
|
||||
// 15001
|
||||
@@ -1562,14 +1566,18 @@ void GameObject::Use(Unit* user)
|
||||
|
||||
Player* player = user->ToPlayer();
|
||||
|
||||
if (player->CanUseBattlegroundObject())
|
||||
if (player->CanUseBattlegroundObject(this))
|
||||
{
|
||||
// in battleground check
|
||||
Battleground* bg = player->GetBattleground();
|
||||
if (!bg)
|
||||
return;
|
||||
|
||||
if (player->GetVehicle())
|
||||
return;
|
||||
|
||||
player->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
|
||||
player->RemoveAurasByType(SPELL_AURA_MOD_INVISIBILITY);
|
||||
// BG flag dropped
|
||||
// WS:
|
||||
// 179785 - Silverwing Flag
|
||||
|
||||
@@ -598,9 +598,16 @@ void KillRewarder::_RewardGroup()
|
||||
|
||||
// 3.1.3. Reward each group member (even dead or corpse) within reward distance.
|
||||
for (GroupReference* itr = _group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
if (Player* member = itr->getSource())
|
||||
{
|
||||
if (member->IsAtGroupRewardDistance(_victim))
|
||||
{
|
||||
_RewardPlayer(member, isDungeon);
|
||||
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1573,6 +1580,16 @@ void Player::Update(uint32 p_time)
|
||||
if (now > m_Last_tick + 1)
|
||||
UpdateSoulboundTradeItems();
|
||||
|
||||
// If mute expired, remove it from the DB
|
||||
if (GetSession()->m_muteTime && GetSession()->m_muteTime < now)
|
||||
{
|
||||
GetSession()->m_muteTime = 0;
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME);
|
||||
stmt->setInt64(0, 0); // Set the mute time to 0
|
||||
stmt->setUInt32(1, GetSession()->GetAccountId());
|
||||
LoginDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
if (!m_timedquests.empty())
|
||||
{
|
||||
QuestSet::iterator iter = m_timedquests.begin();
|
||||
@@ -9036,7 +9053,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
||||
{
|
||||
// data depends on zoneid/mapid...
|
||||
Battleground* bg = GetBattleground();
|
||||
uint16 NumberOfFields = 0;
|
||||
uint32 mapid = GetMapId();
|
||||
OutdoorPvP* pvp = sOutdoorPvPMgr->GetOutdoorPvPToZoneId(zoneid);
|
||||
InstanceScript* instance = GetInstanceScript();
|
||||
@@ -9044,94 +9060,12 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "Sending SMSG_INIT_WORLD_STATES to Map: %u, Zone: %u", mapid, zoneid);
|
||||
|
||||
// may be exist better way to do this...
|
||||
switch (zoneid)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 36:
|
||||
case 38:
|
||||
case 40:
|
||||
case 41:
|
||||
case 51:
|
||||
case 267:
|
||||
case 1519:
|
||||
case 1537:
|
||||
case 2257:
|
||||
case 2918:
|
||||
NumberOfFields = 8;
|
||||
break;
|
||||
case 139:
|
||||
NumberOfFields = 41;
|
||||
break;
|
||||
case 1377:
|
||||
NumberOfFields = 15;
|
||||
break;
|
||||
case 2597:
|
||||
NumberOfFields = 83;
|
||||
break;
|
||||
case 3277:
|
||||
NumberOfFields = 18;
|
||||
break;
|
||||
case 3358:
|
||||
case 3820:
|
||||
NumberOfFields = 40;
|
||||
break;
|
||||
case 3483:
|
||||
NumberOfFields = 27;
|
||||
break;
|
||||
case 3518:
|
||||
NumberOfFields = 39;
|
||||
break;
|
||||
case 3519:
|
||||
NumberOfFields = 38;
|
||||
break;
|
||||
case 3521:
|
||||
NumberOfFields = 37;
|
||||
break;
|
||||
case 3698:
|
||||
case 3702:
|
||||
case 3968:
|
||||
case 4378:
|
||||
case 3703:
|
||||
NumberOfFields = 11;
|
||||
break;
|
||||
case 4384:
|
||||
NumberOfFields = 30;
|
||||
break;
|
||||
case 4710:
|
||||
NumberOfFields = 28;
|
||||
break;
|
||||
case 4812: // Icecrown Citadel
|
||||
case 4100: // The Culling of Stratholme
|
||||
NumberOfFields = 13;
|
||||
break;
|
||||
case 4987: // The Ruby Sanctum
|
||||
NumberOfFields = 3;
|
||||
break;
|
||||
case 4273: // Ulduar
|
||||
NumberOfFields = 10;
|
||||
break;
|
||||
case 4197: // Wintergrasp
|
||||
/// Use the max here, and fill with zeros if missing.
|
||||
NumberOfFields = 10 + WG_MAX_OBJ + WG_MAX_WORKSHOP;
|
||||
break;
|
||||
default:
|
||||
NumberOfFields = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(NumberOfFields*8)));
|
||||
WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(12*8)));
|
||||
data << uint32(mapid); // mapid
|
||||
data << uint32(zoneid); // zone id
|
||||
data << uint32(areaid); // area id, new 2.1.0
|
||||
size_t countPos = data.wpos();
|
||||
data << uint16(NumberOfFields); // count of uint64 blocks
|
||||
data << uint16(0); // count of uint64 blocks
|
||||
data << uint32(0x8d8) << uint32(0x0); // 1
|
||||
data << uint32(0x8d7) << uint32(0x0); // 2
|
||||
data << uint32(0x8d6) << uint32(0x0); // 3
|
||||
@@ -9694,8 +9628,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
||||
bf->FillInitialWorldStates(data);
|
||||
break;
|
||||
}
|
||||
else
|
||||
data.put<uint16>(countPos, 12);
|
||||
// No break here, intended.
|
||||
default:
|
||||
data << uint32(0x914) << uint32(0x0); // 7
|
||||
@@ -9704,6 +9636,10 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
||||
data << uint32(0x915) << uint32(0x0); // 10
|
||||
break;
|
||||
}
|
||||
|
||||
uint16 length = (data.wpos() - countPos) / 8;
|
||||
data.put<uint16>(countPos, length);
|
||||
|
||||
GetSession()->SendPacket(&data);
|
||||
SendBGWeekendWorldStates();
|
||||
SendBattlefieldWorldStates();
|
||||
@@ -11965,7 +11901,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
|
||||
bool lootedObjectInDungeon = false;
|
||||
Map const* map = lootedObject->GetMap();
|
||||
if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true))
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId))
|
||||
if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty()))
|
||||
lootedObjectInDungeon = true;
|
||||
|
||||
@@ -15044,19 +14980,6 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
|
||||
if (questGiver && quest->GetQuestStartScript() != 0)
|
||||
GetMap()->ScriptsStart(sQuestStartScripts, quest->GetQuestStartScript(), questGiver, this);
|
||||
|
||||
// Some spells applied at quest activation
|
||||
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id, true);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
uint32 zone, area;
|
||||
GetZoneAndAreaId(zone, area);
|
||||
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
}
|
||||
|
||||
@@ -15245,33 +15168,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId());
|
||||
|
||||
uint32 zone = 0;
|
||||
uint32 area = 0;
|
||||
|
||||
// remove auras from spells with quest reward state limitations
|
||||
SpellAreaForQuestMapBounds saEndBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
|
||||
if (saEndBounds.first != saEndBounds.second)
|
||||
{
|
||||
GetZoneAndAreaId(zone, area);
|
||||
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr)
|
||||
if (!itr->second->IsFitToRequirements(this, zone, area))
|
||||
RemoveAurasDueToSpell(itr->second->spellId);
|
||||
}
|
||||
|
||||
// Some spells applied at quest reward
|
||||
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id, false);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
if (!zone || !area)
|
||||
GetZoneAndAreaId(zone, area);
|
||||
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
|
||||
//lets remove flag for delayed teleports
|
||||
SetCanDelayTeleport(false);
|
||||
}
|
||||
@@ -15814,6 +15710,30 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
|
||||
m_QuestStatusSave[quest_id] = true;
|
||||
}
|
||||
|
||||
uint32 zone = 0, area = 0;
|
||||
|
||||
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
GetZoneAndAreaId(zone, area);
|
||||
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (itr->second->autocast && itr->second->IsFitToRequirements(this, zone, area))
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
|
||||
saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
|
||||
if (saBounds.first != saBounds.second)
|
||||
{
|
||||
if (!zone || !area)
|
||||
GetZoneAndAreaId(zone, area);
|
||||
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (!itr->second->IsFitToRequirements(this, zone, area))
|
||||
RemoveAurasDueToSpell(itr->second->spellId);
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
}
|
||||
|
||||
@@ -23341,7 +23261,7 @@ PartyResult Player::CanUninviteFromGroup() const
|
||||
if (state == LFG_STATE_BOOT)
|
||||
return ERR_PARTY_LFG_BOOT_IN_PROGRESS;
|
||||
|
||||
if (grp->GetMembersCount() <= sLFGMgr->GetVotesNeeded(gguid))
|
||||
if (grp->GetMembersCount() <= LFG_GROUP_KICK_VOTES_NEEDED)
|
||||
return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS;
|
||||
|
||||
if (state == LFG_STATE_FINISHED_DUNGEON)
|
||||
@@ -23374,8 +23294,22 @@ PartyResult Player::CanUninviteFromGroup() const
|
||||
|
||||
bool Player::isUsingLfg()
|
||||
{
|
||||
uint64 guid = GetGUID();
|
||||
return sLFGMgr->GetState(guid) != LFG_STATE_NONE;
|
||||
return sLFGMgr->GetState(GetGUID()) != LFG_STATE_NONE;
|
||||
}
|
||||
|
||||
bool Player::inRandomLfgDungeon()
|
||||
{
|
||||
if (isUsingLfg())
|
||||
{
|
||||
const LfgDungeonSet& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID());
|
||||
if (!dungeons.empty())
|
||||
{
|
||||
LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin());
|
||||
if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup)
|
||||
@@ -23568,21 +23502,19 @@ WorldObject* Player::GetViewpoint() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Player::CanUseBattlegroundObject()
|
||||
bool Player::CanUseBattlegroundObject(GameObject* gameobject)
|
||||
{
|
||||
// TODO : some spells gives player ForceReaction to one faction (ReputationMgr::ApplyForceReaction)
|
||||
// maybe gameobject code should handle that ForceReaction usage
|
||||
FactionTemplateEntry const* playerFaction = getFactionTemplateEntry();
|
||||
FactionTemplateEntry const* faction = sFactionTemplateStore.LookupEntry(gameobject->GetUInt32Value(GAMEOBJECT_FACTION));
|
||||
|
||||
if (playerFaction && faction && !playerFaction->IsFriendlyTo(*faction))
|
||||
return false;
|
||||
|
||||
// BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
|
||||
return (//InBattleground() && // in battleground - not need, check in other cases
|
||||
//!IsMounted() && - not correct, player is dismounted when he clicks on flag
|
||||
//player cannot use object when he is invulnerable (immune)
|
||||
!isTotalImmune() && // not totally immune
|
||||
//i'm not sure if these two are correct, because invisible players should get visible when they click on flag
|
||||
!HasStealthAura() && // not stealthed
|
||||
!HasInvisibilityAura() && // not invisible
|
||||
!HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // can't pickup
|
||||
isAlive() // live player
|
||||
);
|
||||
// Note: Mount, stealth and invisibility will be removed when used
|
||||
return (!isTotalImmune() && // Damage immune
|
||||
!HasAura(SPELL_RECENTLY_DROPPED_FLAG) && // Still has recently held flag debuff
|
||||
isAlive()); // Alive
|
||||
}
|
||||
|
||||
bool Player::CanCaptureTowerPoint()
|
||||
|
||||
@@ -2237,7 +2237,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
|
||||
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const;
|
||||
bool isTotalImmunity();
|
||||
bool CanUseBattlegroundObject();
|
||||
bool CanUseBattlegroundObject(GameObject* gameobject);
|
||||
bool isTotalImmune();
|
||||
bool CanCaptureTowerPoint();
|
||||
|
||||
@@ -2356,6 +2356,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist = false);
|
||||
|
||||
bool isUsingLfg();
|
||||
bool inRandomLfgDungeon();
|
||||
|
||||
typedef std::set<uint32> DFQuestsDoneList;
|
||||
DFQuestsDoneList m_DFQuests;
|
||||
|
||||
@@ -703,14 +703,8 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
|
||||
sLog->outDebug(LOG_FILTER_UNITS, "DealDamage: victim just died");
|
||||
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER && victim != this)
|
||||
{
|
||||
victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health);
|
||||
|
||||
// call before auras are removed
|
||||
if (Player* killer = GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
|
||||
}
|
||||
|
||||
Kill(victim, durabilityLoss);
|
||||
}
|
||||
else
|
||||
@@ -2302,6 +2296,9 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell)
|
||||
// Ranged attacks can only miss, resist and deflect
|
||||
if (attType == RANGED_ATTACK)
|
||||
{
|
||||
canParry = false;
|
||||
canDodge = false;
|
||||
|
||||
// only if in front
|
||||
if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION))
|
||||
{
|
||||
@@ -6637,30 +6634,30 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
|
||||
return false;
|
||||
triggered_spell_id = 0;
|
||||
Unit* beaconTarget = NULL;
|
||||
if (this->GetTypeId() != TYPEID_PLAYER)
|
||||
if (GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
beaconTarget = triggeredByAura->GetBase()->GetCaster();
|
||||
if (beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID())))
|
||||
if (!beaconTarget || beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID())))
|
||||
return false;
|
||||
basepoints0 = int32(damage);
|
||||
triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
|
||||
}
|
||||
else
|
||||
{ // Check Party/Raid Group
|
||||
if (Group *group = this->ToPlayer()->GetGroup())
|
||||
if (Group* group = ToPlayer()->GetGroup())
|
||||
{
|
||||
for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
if (Player* member = itr->getSource())
|
||||
{
|
||||
Player* Member = itr->getSource();
|
||||
|
||||
// check if it was heal by paladin which casted this beacon of light
|
||||
if (Member->GetAura(53563, victim->GetGUID()))
|
||||
if (member->GetAura(53563, victim->GetGUID()))
|
||||
{
|
||||
// do not proc when target of beacon of light is healed
|
||||
if (Member == this)
|
||||
if (member == this)
|
||||
return false;
|
||||
|
||||
beaconTarget = Member;
|
||||
beaconTarget = member;
|
||||
basepoints0 = int32(damage);
|
||||
triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
|
||||
break;
|
||||
@@ -6668,13 +6665,14 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (triggered_spell_id && beaconTarget)
|
||||
{
|
||||
victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true, 0, triggeredByAura);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
return false;
|
||||
}
|
||||
// Judgements of the Wise
|
||||
@@ -13661,6 +13659,9 @@ void Unit::SetLevel(uint8 lvl)
|
||||
// group update
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetGroup())
|
||||
ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL);
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
sWorld->UpdateCharacterNameDataLevel(ToPlayer()->GetGUIDLow(), lvl);
|
||||
}
|
||||
|
||||
void Unit::SetHealth(uint32 val)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "LFGMgr.h"
|
||||
|
||||
ScriptMapMap sQuestEndScripts;
|
||||
ScriptMapMap sQuestStartScripts;
|
||||
@@ -5028,7 +5029,7 @@ void ObjectMgr::LoadInstanceEncounters()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastEncounterDungeon && !sLFGDungeonStore.LookupEntry(lastEncounterDungeon))
|
||||
if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeon(lastEncounterDungeon))
|
||||
{
|
||||
sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
|
||||
continue;
|
||||
@@ -7590,6 +7591,27 @@ SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spell_id)
|
||||
return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id));
|
||||
}
|
||||
|
||||
// this allows calculating base reputations to offline players, just by race and class
|
||||
int32 ObjectMgr::GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass)
|
||||
{
|
||||
if (!factionEntry)
|
||||
return 0;
|
||||
|
||||
uint32 raceMask = (1 << (race - 1));
|
||||
uint32 classMask = (1 << (playerClass-1));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((!factionEntry->BaseRepClassMask[i] ||
|
||||
factionEntry->BaseRepClassMask[i] & classMask) &&
|
||||
(!factionEntry->BaseRepRaceMask[i] ||
|
||||
factionEntry->BaseRepRaceMask[i] & raceMask))
|
||||
return factionEntry->BaseRepValue[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SkillRangeType GetSkillRangeType(SkillLineEntry const* pSkill, bool racial)
|
||||
{
|
||||
switch (pSkill->categoryId)
|
||||
|
||||
@@ -749,6 +749,8 @@ class ObjectMgr
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32 GetBaseReputationOff(FactionEntry const* factionEntry, uint8 race, uint8 playerClass);
|
||||
|
||||
RepSpilloverTemplate const* GetRepSpilloverTemplate(uint32 factionId) const
|
||||
{
|
||||
RepSpilloverTemplateContainer::const_iterator itr = _repSpilloverTemplateStore.find(factionId);
|
||||
|
||||
@@ -523,7 +523,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
if (method == GROUP_REMOVEMETHOD_KICK)
|
||||
if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG)
|
||||
{
|
||||
data.Initialize(SMSG_GROUP_UNINVITE, 0);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
@@ -600,7 +600,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
|
||||
if (isLFGGroup() && GetMembersCount() == 1)
|
||||
{
|
||||
Player* Leader = ObjectAccessor::FindPlayer(GetLeaderGUID());
|
||||
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(sLFGMgr->GetDungeon(GetGUID()));
|
||||
LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(sLFGMgr->GetDungeon(GetGUID()));
|
||||
if ((Leader && dungeon && Leader->isAlive() && Leader->GetMapId() != uint32(dungeon->map)) || !dungeon)
|
||||
{
|
||||
Disband();
|
||||
|
||||
@@ -660,7 +660,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
std::string IP_str = GetRemoteAddress();
|
||||
sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow());
|
||||
sScriptMgr->OnPlayerCreate(&newChar);
|
||||
sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass());
|
||||
sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel());
|
||||
|
||||
newChar.CleanupsBeforeDelete();
|
||||
delete createInfo;
|
||||
@@ -1625,10 +1625,14 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
|
||||
|
||||
uint32 lowGuid = GUID_LOPART(guid);
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN);
|
||||
// get the players old (at this moment current) race
|
||||
CharacterNameData const* nameData = sWorld->GetCharacterNameData(lowGuid);
|
||||
uint8 oldRace = nameData->m_race;
|
||||
uint8 playerClass = nameData->m_class;
|
||||
uint8 level = nameData->m_level;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES);
|
||||
stmt->setUInt32(0, lowGuid);
|
||||
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
|
||||
if (!result)
|
||||
@@ -1640,11 +1644,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
|
||||
}
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
uint32 playerClass = uint32(fields[0].GetUInt8());
|
||||
uint32 level = uint32(fields[1].GetUInt8());
|
||||
uint32 at_loginFlags = fields[2].GetUInt16();
|
||||
uint32 at_loginFlags = fields[0].GetUInt16();
|
||||
char const* knownTitlesStr = fields[1].GetCString();
|
||||
uint32 used_loginFlag = ((recv_data.GetOpcode() == CMSG_CHAR_RACE_CHANGE) ? AT_LOGIN_CHANGE_RACE : AT_LOGIN_CHANGE_FACTION);
|
||||
char const* knownTitlesStr = fields[3].GetCString();
|
||||
|
||||
if (!sObjectMgr->GetPlayerInfo(race, playerClass))
|
||||
{
|
||||
@@ -2003,16 +2005,47 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
|
||||
{
|
||||
uint32 reputation_alliance = it->first;
|
||||
uint32 reputation_horde = it->second;
|
||||
uint32 newReputation = (team == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
|
||||
uint32 oldReputation = (team == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
|
||||
stmt->setUInt32(0, uint16(team == TEAM_ALLIANCE ? reputation_alliance : reputation_horde));
|
||||
// select old standing set in db
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
|
||||
stmt->setUInt32(0, oldReputation);
|
||||
stmt->setUInt32(1, lowGuid);
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);
|
||||
data << uint8(CHAR_CREATE_ERROR);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
int32 oldDBRep = fields[0].GetInt32();
|
||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
|
||||
|
||||
// old base reputation
|
||||
int32 oldBaseRep = sObjectMgr->GetBaseReputationOff(factionEntry, oldRace, playerClass);
|
||||
|
||||
// new base reputation
|
||||
int32 newBaseRep = sObjectMgr->GetBaseReputationOff(sFactionStore.LookupEntry(newReputation), race, playerClass);
|
||||
|
||||
// final reputation shouldnt change
|
||||
int32 FinalRep = oldDBRep + oldBaseRep;
|
||||
int32 newDBRep = FinalRep - newBaseRep;
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
|
||||
stmt->setUInt32(0, newReputation);
|
||||
stmt->setUInt32(1, lowGuid);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE);
|
||||
stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? reputation_alliance : reputation_horde));
|
||||
stmt->setUInt16(1, uint16(team == TEAM_ALLIANCE ? reputation_horde : reputation_alliance));
|
||||
stmt->setUInt32(2, lowGuid);
|
||||
stmt->setUInt16(0, uint16(newReputation));
|
||||
stmt->setInt32(1, newDBRep);
|
||||
stmt->setUInt16(2, uint16(oldReputation));
|
||||
stmt->setUInt32(3, lowGuid);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#include "LFGMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock)
|
||||
{
|
||||
@@ -82,18 +80,20 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data)
|
||||
std::string comment;
|
||||
recv_data >> comment;
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str());
|
||||
sLFGMgr->Join(GetPlayer(), uint8(roles), newDungeons, comment);
|
||||
sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment);
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/)
|
||||
{
|
||||
Group* grp = GetPlayer()->GetGroup();
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
uint64 gguid = grp ? grp->GetGUID() : guid;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", GetPlayer()->GetGUID(), grp ? 1 : 0);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", guid, grp ? 1 : 0);
|
||||
|
||||
// Check cheating - only leader can leave the queue
|
||||
if (!grp || grp->GetLeaderGUID() == GetPlayer()->GetGUID())
|
||||
sLFGMgr->Leave(GetPlayer(), grp);
|
||||
sLFGMgr->LeaveLfg(gguid);
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recv_data)
|
||||
@@ -128,7 +128,7 @@ void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data)
|
||||
std::string comment;
|
||||
recv_data >> comment;
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_LFG_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str());
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str());
|
||||
|
||||
sLFGMgr->SetComment(guid, comment);
|
||||
}
|
||||
@@ -138,8 +138,9 @@ void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recv_data)
|
||||
bool agree; // Agree to kick player
|
||||
recv_data >> agree;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", GetPlayer()->GetGUID(), agree ? 1 : 0);
|
||||
sLFGMgr->UpdateBoot(GetPlayer(), agree);
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", guid, agree ? 1 : 0);
|
||||
sLFGMgr->UpdateBoot(guid, agree);
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recv_data)
|
||||
@@ -154,32 +155,24 @@ void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recv_data)
|
||||
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/)
|
||||
{
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid);
|
||||
|
||||
// Get Random dungeons that can be done at a certain level and expansion
|
||||
LfgDungeonSet randomDungeons;
|
||||
uint8 level = GetPlayer()->getLevel();
|
||||
uint8 expansion = GetPlayer()->GetSession()->Expansion();
|
||||
for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
|
||||
{
|
||||
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i);
|
||||
if (dungeon && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel)
|
||||
{
|
||||
if (dungeon->flags & LFG_FLAG_SEASONAL)
|
||||
{
|
||||
if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID))
|
||||
if (!IsHolidayActive(holiday))
|
||||
continue;
|
||||
}
|
||||
else if (dungeon->type != LFG_TYPE_RANDOM)
|
||||
continue;
|
||||
|
||||
randomDungeons.insert(dungeon->Entry());
|
||||
}
|
||||
LFGDungeonMap& LfgDungeons = sLFGMgr->GetLFGDungeonMap();
|
||||
for (LFGDungeonMap::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr)
|
||||
{
|
||||
LFGDungeonData const& dungeon = itr->second;
|
||||
if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id)))
|
||||
&& dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel)
|
||||
randomDungeons.insert(dungeon.Entry());
|
||||
}
|
||||
|
||||
// Get player locked Dungeons
|
||||
LfgLockMap lock = sLFGMgr->GetLockedDungeons(guid);
|
||||
LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
|
||||
uint32 rsize = uint32(randomDungeons.size());
|
||||
uint32 lsize = uint32(lock.size());
|
||||
|
||||
@@ -191,39 +184,36 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data
|
||||
{
|
||||
data << uint32(*it); // Dungeon Entry (id + type)
|
||||
LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
|
||||
Quest const* qRew = NULL;
|
||||
Quest const* quest = NULL;
|
||||
uint8 done = 0;
|
||||
if (reward)
|
||||
{
|
||||
qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId);
|
||||
if (qRew)
|
||||
quest = sObjectMgr->GetQuestTemplate(reward->reward[0].questId);
|
||||
if (quest)
|
||||
{
|
||||
done = !GetPlayer()->CanRewardQuest(qRew, false);
|
||||
done = !GetPlayer()->CanRewardQuest(quest, false);
|
||||
if (done)
|
||||
qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId);
|
||||
quest = sObjectMgr->GetQuestTemplate(reward->reward[1].questId);
|
||||
}
|
||||
}
|
||||
if (qRew)
|
||||
|
||||
if (quest)
|
||||
{
|
||||
data << uint8(done);
|
||||
data << uint32(qRew->GetRewOrReqMoney());
|
||||
data << uint32(qRew->XPValue(GetPlayer()));
|
||||
data << uint32(quest->GetRewOrReqMoney());
|
||||
data << uint32(quest->XPValue(GetPlayer()));
|
||||
data << uint32(reward->reward[done].variableMoney);
|
||||
data << uint32(reward->reward[done].variableXP);
|
||||
data << uint8(qRew->GetRewItemsCount());
|
||||
if (qRew->GetRewItemsCount())
|
||||
data << uint8(quest->GetRewItemsCount());
|
||||
if (quest->GetRewItemsCount())
|
||||
{
|
||||
ItemTemplate const* iProto = NULL;
|
||||
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
if (uint32 itemId = quest->RewardItemId[i])
|
||||
{
|
||||
if (!qRew->RewardItemId[i])
|
||||
continue;
|
||||
|
||||
iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]);
|
||||
|
||||
data << uint32(qRew->RewardItemId[i]);
|
||||
data << uint32(iProto ? iProto->DisplayInfoID : 0);
|
||||
data << uint32(qRew->RewardItemIdCount[i]);
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
|
||||
data << uint32(itemId);
|
||||
data << uint32(item ? item->DisplayInfoID : 0);
|
||||
data << uint32(quest->RewardItemIdCount[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +234,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data
|
||||
void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data*/)
|
||||
{
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid);
|
||||
|
||||
Group* grp = GetPlayer()->GetGroup();
|
||||
if (!grp)
|
||||
@@ -275,11 +265,11 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfrSearchOpcode(WorldPacket& recv_data)
|
||||
void WorldSession::HandleLfrJoinOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
uint32 entry; // Raid id to search
|
||||
recv_data >> entry;
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry);
|
||||
//SendLfrUpdateListOpcode(entry);
|
||||
}
|
||||
|
||||
@@ -287,7 +277,7 @@ void WorldSession::HandleLfrLeaveOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
uint32 dungeonId; // Raid id queue to leave
|
||||
recv_data >> dungeonId;
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId);
|
||||
//sLFGMgr->LeaveLfr(GetPlayer(), dungeonId);
|
||||
}
|
||||
|
||||
@@ -295,6 +285,8 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData)
|
||||
{
|
||||
bool queued = false;
|
||||
bool extrainfo = false;
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
uint8 size = uint8(updateData.dungeons.size());
|
||||
|
||||
switch (updateData.updateType)
|
||||
{
|
||||
@@ -311,9 +303,6 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData)
|
||||
break;
|
||||
}
|
||||
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
uint8 size = uint8(updateData.dungeons.size());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_PLAYER [" UI64FMTD "] updatetype: %u", guid, updateData.updateType);
|
||||
WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
|
||||
data << uint8(updateData.updateType); // Lfg Update type
|
||||
@@ -338,6 +327,8 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData)
|
||||
bool join = false;
|
||||
bool extrainfo = false;
|
||||
bool queued = false;
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
uint8 size = uint8(updateData.dungeons.size());
|
||||
|
||||
switch (updateData.updateType)
|
||||
{
|
||||
@@ -361,9 +352,6 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData)
|
||||
break;
|
||||
}
|
||||
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
uint8 size = uint8(updateData.dungeons.size());
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", guid, updateData.updateType);
|
||||
WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
|
||||
data << uint8(updateData.updateType); // Lfg Update type
|
||||
@@ -397,45 +385,44 @@ void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles)
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck)
|
||||
void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck)
|
||||
{
|
||||
ASSERT(pRoleCheck);
|
||||
LfgDungeonSet dungeons;
|
||||
if (pRoleCheck->rDungeonId)
|
||||
dungeons.insert(pRoleCheck->rDungeonId);
|
||||
if (roleCheck.rDungeonId)
|
||||
dungeons.insert(roleCheck.rDungeonId);
|
||||
else
|
||||
dungeons = pRoleCheck->dungeons;
|
||||
dungeons = roleCheck.dungeons;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_ROLE_CHECK_UPDATE [" UI64FMTD "]", GetPlayer()->GetGUID());
|
||||
WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1));
|
||||
WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
|
||||
|
||||
data << uint32(pRoleCheck->state); // Check result
|
||||
data << uint8(pRoleCheck->state == LFG_ROLECHECK_INITIALITING);
|
||||
data << uint32(roleCheck.state); // Check result
|
||||
data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING);
|
||||
data << uint8(dungeons.size()); // Number of dungeons
|
||||
if (!dungeons.empty())
|
||||
{
|
||||
for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
|
||||
{
|
||||
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(*it);
|
||||
LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*it);
|
||||
data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon
|
||||
}
|
||||
}
|
||||
|
||||
data << uint8(pRoleCheck->roles.size()); // Players in group
|
||||
if (!pRoleCheck->roles.empty())
|
||||
data << uint8(roleCheck.roles.size()); // Players in group
|
||||
if (!roleCheck.roles.empty())
|
||||
{
|
||||
// Leader info MUST be sent 1st :S
|
||||
uint64 guid = pRoleCheck->leader;
|
||||
uint8 roles = pRoleCheck->roles.find(guid)->second;
|
||||
uint64 guid = roleCheck.leader;
|
||||
uint8 roles = roleCheck.roles.find(guid)->second;
|
||||
data << uint64(guid); // Guid
|
||||
data << uint8(roles > 0); // Ready
|
||||
data << uint32(roles); // Roles
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
data << uint8(player ? player->getLevel() : 0); // Level
|
||||
|
||||
for (LfgRolesMap::const_iterator it = pRoleCheck->roles.begin(); it != pRoleCheck->roles.end(); ++it)
|
||||
for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
|
||||
{
|
||||
if (it->first == pRoleCheck->leader)
|
||||
if (it->first == roleCheck.leader)
|
||||
continue;
|
||||
|
||||
guid = it->first;
|
||||
@@ -465,30 +452,31 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData)
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps)
|
||||
void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", GetPlayer()->GetGUID(), dungeon, waitTime, avgWaitTime, waitTimeTanks, waitTimeHealer, waitTimeDps, queuedTime, tanks, healers, dps);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u",
|
||||
GetPlayer()->GetGUID(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
|
||||
|
||||
WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 +4 + 1 + 1 + 1 + 4);
|
||||
data << uint32(dungeon); // Dungeon
|
||||
data << int32(avgWaitTime); // Average Wait time
|
||||
data << int32(waitTime); // Wait Time
|
||||
data << int32(waitTimeTanks); // Wait Tanks
|
||||
data << int32(waitTimeHealer); // Wait Healers
|
||||
data << int32(waitTimeDps); // Wait Dps
|
||||
data << uint8(tanks); // Tanks needed
|
||||
data << uint8(healers); // Healers needed
|
||||
data << uint8(dps); // Dps needed
|
||||
data << uint32(queuedTime); // Player wait time in queue
|
||||
data << uint32(queueData.dungeonId); // Dungeon
|
||||
data << int32(queueData.waitTimeAvg); // Average Wait time
|
||||
data << int32(queueData.waitTime); // Wait Time
|
||||
data << int32(queueData.waitTimeTank); // Wait Tanks
|
||||
data << int32(queueData.waitTimeHealer); // Wait Healers
|
||||
data << int32(queueData.waitTimeDps); // Wait Dps
|
||||
data << uint8(queueData.tanks); // Tanks needed
|
||||
data << uint8(queueData.healers); // Healers needed
|
||||
data << uint8(queueData.dps); // Dps needed
|
||||
data << uint32(queueData.queuedTime); // Player wait time in queue
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* qRew)
|
||||
void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* quest)
|
||||
{
|
||||
if (!rdungeonEntry || !sdungeonEntry || !qRew)
|
||||
if (!rdungeonEntry || !sdungeonEntry || !quest)
|
||||
return;
|
||||
|
||||
uint8 itemNum = uint8(qRew ? qRew->GetRewItemsCount() : 0);
|
||||
uint8 itemNum = uint8(quest ? quest->GetRewItemsCount() : 0);
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_REWARD [" UI64FMTD "] rdungeonEntry: %u - sdungeonEntry: %u - done: %u", GetPlayer()->GetGUID(), rdungeonEntry, sdungeonEntry, done);
|
||||
WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
|
||||
@@ -496,37 +484,33 @@ void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntr
|
||||
data << uint32(sdungeonEntry); // Dungeon Finished
|
||||
data << uint8(done);
|
||||
data << uint32(1);
|
||||
data << uint32(qRew->GetRewOrReqMoney());
|
||||
data << uint32(qRew->XPValue(GetPlayer()));
|
||||
data << uint32(quest->GetRewOrReqMoney());
|
||||
data << uint32(quest->XPValue(GetPlayer()));
|
||||
data << uint32(reward->reward[done].variableMoney);
|
||||
data << uint32(reward->reward[done].variableXP);
|
||||
data << uint8(itemNum);
|
||||
if (itemNum)
|
||||
{
|
||||
ItemTemplate const* iProto = NULL;
|
||||
for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
if (uint32 itemId = quest->RewardItemId[i])
|
||||
{
|
||||
if (!qRew->RewardItemId[i])
|
||||
continue;
|
||||
|
||||
iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]);
|
||||
|
||||
data << uint32(qRew->RewardItemId[i]);
|
||||
data << uint32(iProto ? iProto->DisplayInfoID : 0);
|
||||
data << uint32(qRew->RewardItemIdCount[i]);
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
|
||||
data << uint32(itemId);
|
||||
data << uint32(item ? item->DisplayInfoID : 0);
|
||||
data << uint32(quest->RewardItemIdCount[i]);
|
||||
}
|
||||
}
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot)
|
||||
void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot)
|
||||
{
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
LfgAnswer playerVote = pBoot->votes.find(guid)->second;
|
||||
LfgAnswer playerVote = boot.votes.find(guid)->second;
|
||||
uint8 votesNum = 0;
|
||||
uint8 agreeNum = 0;
|
||||
uint32 secsleft = uint8((pBoot->cancelTime - time(NULL)) / 1000);
|
||||
for (LfgAnswerMap::const_iterator it = pBoot->votes.begin(); it != pBoot->votes.end(); ++it)
|
||||
uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000);
|
||||
for (LfgAnswerMap::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
|
||||
{
|
||||
if (it->second != LFG_ANSWER_PENDING)
|
||||
{
|
||||
@@ -536,106 +520,72 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot)
|
||||
}
|
||||
}
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s",
|
||||
guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str());
|
||||
WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length());
|
||||
data << uint8(pBoot->inProgress); // Vote in progress
|
||||
guid, uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), boot.victim, votesNum, agreeNum, secsleft, LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str());
|
||||
WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
|
||||
data << uint8(boot.inProgress); // Vote in progress
|
||||
data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote
|
||||
data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree
|
||||
data << uint64(pBoot->victim); // Victim GUID
|
||||
data << uint64(boot.victim); // Victim GUID
|
||||
data << uint32(votesNum); // Total Votes
|
||||
data << uint32(agreeNum); // Agree Count
|
||||
data << uint32(secsleft); // Time Left
|
||||
data << uint32(pBoot->votedNeeded); // Needed Votes
|
||||
data << pBoot->reason.c_str(); // Kick reason
|
||||
data << uint32(LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
|
||||
data << boot.reason.c_str(); // Kick reason
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp)
|
||||
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& proposal)
|
||||
{
|
||||
if (!pProp)
|
||||
return;
|
||||
|
||||
uint64 guid = GetPlayer()->GetGUID();
|
||||
LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid);
|
||||
if (itPlayer == pProp->players.end()) // Player MUST be in the proposal
|
||||
return;
|
||||
uint64 gguid = proposal.players.find(guid)->second.group;
|
||||
bool silent = !proposal.isNew && gguid == proposal.group;
|
||||
uint32 dungeonEntry = proposal.dungeonId;
|
||||
|
||||
LfgProposalPlayer* ppPlayer = itPlayer->second;
|
||||
uint32 pLowGroupGuid = ppPlayer->groupLowGuid;
|
||||
uint32 dLowGuid = pProp->groupLowGuid;
|
||||
uint32 dungeonId = pProp->dungeonId;
|
||||
bool isSameDungeon = false;
|
||||
bool isContinue = false;
|
||||
Group* grp = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL;
|
||||
uint32 completedEncounters = 0;
|
||||
if (grp)
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", guid, proposal.state);
|
||||
WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1));
|
||||
|
||||
// show random dungeon if player selected random dungeon and it's not lfg group
|
||||
if (!silent)
|
||||
{
|
||||
uint64 gguid = grp->GetGUID();
|
||||
isContinue = grp->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON;
|
||||
isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue;
|
||||
LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
|
||||
if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
|
||||
dungeonEntry = (*playerDungeons.begin());
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state);
|
||||
WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + pProp->players.size() * (4 + 1 + 1 + 1 + 1 +1));
|
||||
if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry))
|
||||
dungeonEntry = dungeon->Entry();
|
||||
|
||||
if (!isContinue) // Only show proposal dungeon if it's continue
|
||||
{
|
||||
LfgDungeonSet playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
|
||||
if (playerDungeons.size() == 1)
|
||||
dungeonId = (*playerDungeons.begin());
|
||||
}
|
||||
data << uint32(dungeonEntry); // Dungeon
|
||||
data << uint8(proposal.state); // Proposal state
|
||||
data << uint32(proposalId); // Proposal ID
|
||||
data << uint32(proposal.encounters); // encounters done
|
||||
data << uint8(silent); // Show proposal window
|
||||
data << uint8(proposal.players.size()); // Group size
|
||||
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
for (LfgProposalPlayerMap::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
|
||||
{
|
||||
dungeonId = dungeon->Entry();
|
||||
|
||||
// Select a player inside to be get completed encounters from
|
||||
if (grp)
|
||||
{
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* groupMember = itr->getSource();
|
||||
if (groupMember && groupMember->GetMapId() == uint32(dungeon->map))
|
||||
{
|
||||
if (InstanceScript* instance = groupMember->GetInstanceScript())
|
||||
completedEncounters = instance->GetCompletedEncounterMask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data << uint32(dungeonId); // Dungeon
|
||||
data << uint8(pProp->state); // Result state
|
||||
data << uint32(proposalId); // Internal Proposal ID
|
||||
data << uint32(completedEncounters); // Bosses killed
|
||||
data << uint8(isSameDungeon); // Silent (show client window)
|
||||
data << uint8(pProp->players.size()); // Group size
|
||||
|
||||
for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer)
|
||||
{
|
||||
ppPlayer = itPlayer->second;
|
||||
data << uint32(ppPlayer->role); // Role
|
||||
data << uint8(itPlayer->first == guid); // Self player
|
||||
if (!ppPlayer->groupLowGuid) // Player not it a group
|
||||
LfgProposalPlayer const& player = it->second;
|
||||
data << uint32(player.role); // Role
|
||||
data << uint8(it->first == guid); // Self player
|
||||
if (!player.group) // Player not it a group
|
||||
{
|
||||
data << uint8(0); // Not in dungeon
|
||||
data << uint8(0); // Not same group
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint8(ppPlayer->groupLowGuid == dLowGuid); // In dungeon (silent)
|
||||
data << uint8(ppPlayer->groupLowGuid == pLowGroupGuid); // Same Group than player
|
||||
data << uint8(player.group == proposal.group); // In dungeon (silent)
|
||||
data << uint8(player.group == gguid); // Same Group than player
|
||||
}
|
||||
data << uint8(ppPlayer->accept != LFG_ANSWER_PENDING); // Answered
|
||||
data << uint8(ppPlayer->accept == LFG_ANSWER_AGREE); // Accepted
|
||||
data << uint8(player.accept != LFG_ANSWER_PENDING); // Answered
|
||||
data << uint8(player.accept == LFG_ANSWER_AGREE); // Accepted
|
||||
}
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendLfgUpdateSearch(bool update)
|
||||
void WorldSession::SendLfgLfrList(bool update)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_SEARCH [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0);
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_LFR_LIST [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0);
|
||||
WorldPacket data(SMSG_LFG_UPDATE_SEARCH, 1);
|
||||
data << uint8(update); // In Lfg Queue?
|
||||
SendPacket(&data);
|
||||
@@ -667,8 +617,8 @@ void WorldSession::SendLfgTeleportError(uint8 err)
|
||||
/*
|
||||
void WorldSession::SendLfrUpdateListOpcode(uint32 dungeonEntry)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_UPDATE_LFG_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry);
|
||||
WorldPacket data(SMSG_UPDATE_LFG_LIST);
|
||||
sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_LFG_UPDATE_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry);
|
||||
WorldPacket data(SMSG_LFG_UPDATE_LIST);
|
||||
SendPacket(&data);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "zlib.h"
|
||||
#include "Language.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Common.h"
|
||||
@@ -26,7 +27,7 @@
|
||||
#include "WorldSession.h"
|
||||
#include "Util.h"
|
||||
|
||||
void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data)
|
||||
void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
|
||||
{
|
||||
// Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
|
||||
if (sTicketMgr->GetStatus() == GMTICKET_QUEUE_STATUS_DISABLED)
|
||||
@@ -42,7 +43,46 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data)
|
||||
// Player must not have ticket
|
||||
if (!sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
|
||||
{
|
||||
GmTicket* ticket = new GmTicket(GetPlayer(), recv_data);
|
||||
GmTicket* ticket = new GmTicket(GetPlayer(), recvData);
|
||||
|
||||
uint32 count;
|
||||
std::list<uint32> times;
|
||||
uint32 decompressedSize;
|
||||
std::string chatLog;
|
||||
|
||||
recvData >> count;
|
||||
|
||||
for (uint32 i = 0; i < count; i++)
|
||||
{
|
||||
uint32 time;
|
||||
recvData >> time;
|
||||
times.push_back(time);
|
||||
}
|
||||
|
||||
recvData >> decompressedSize;
|
||||
|
||||
if (count && decompressedSize && decompressedSize < 0xFFFF)
|
||||
{
|
||||
uint32 pos = recvData.rpos();
|
||||
ByteBuffer dest;
|
||||
dest.resize(decompressedSize);
|
||||
|
||||
uLongf realSize = decompressedSize;
|
||||
if (uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recvData.contents() + pos), recvData.size() - pos) == Z_OK)
|
||||
{
|
||||
dest >> chatLog;
|
||||
ticket->SetChatLog(times, chatLog);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
|
||||
recvData.rfinish();
|
||||
return;
|
||||
}
|
||||
|
||||
recvData.rfinish(); // Will still have compressed data in buffer.
|
||||
}
|
||||
|
||||
sTicketMgr->AddTicket(ticket);
|
||||
sTicketMgr->UpdateLastChange();
|
||||
|
||||
|
||||
@@ -2483,8 +2483,8 @@ bool InstanceMap::AddPlayerToMap(Player* player)
|
||||
|
||||
if (group && group->isLFGGroup())
|
||||
if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin())))
|
||||
if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId))
|
||||
if (LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin())))
|
||||
if (uint32(dungeon->map) == GetId() && dungeon->difficulty == uint32(GetDifficulty()) && randomDungeon->type == uint32(LFG_TYPE_RANDOM))
|
||||
player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
|
||||
}
|
||||
|
||||
@@ -990,6 +990,21 @@ enum TrinityStrings
|
||||
LANG_WORLD_CLOSED = 7523,
|
||||
LANG_WORLD_OPENED = 7524,
|
||||
|
||||
LANG_LFG_STATE_NONE = 9986,
|
||||
LANG_LFG_STATE_ROLECHECK = 9987,
|
||||
LANG_LFG_STATE_QUEUED = 9988,
|
||||
LANG_LFG_STATE_PROPOSAL = 9989,
|
||||
LANG_LFG_STATE_BOOT = 9990,
|
||||
LANG_LFG_STATE_DUNGEON = 9991,
|
||||
LANG_LFG_STATE_FINISHED_DUNGEON = 9992,
|
||||
LANG_LFG_STATE_RAIDBROWSER = 9993,
|
||||
LANG_LFG_ROLE_TANK = 9994,
|
||||
LANG_LFG_ROLE_HEALER = 9995,
|
||||
LANG_LFG_ROLE_DAMAGE = 9996,
|
||||
LANG_LFG_ROLE_LEADER = 9997,
|
||||
LANG_LFG_ROLE_NONE = 9998,
|
||||
LANG_LFG_ERROR = 9999,
|
||||
|
||||
// Use for not-in-offcial-sources patches
|
||||
// 10000-10999
|
||||
// opvp hp
|
||||
@@ -1076,7 +1091,7 @@ enum TrinityStrings
|
||||
|
||||
// Use for custom patches 11000-11999
|
||||
LANG_AUTO_BROADCAST = 11000,
|
||||
LANG_INVALID_REALMID = 11001
|
||||
LANG_INVALID_REALMID = 11001,
|
||||
|
||||
// NOT RESERVED IDS 12000-1999999999
|
||||
// `db_script_string` table index 2000000000-2000009999 (MIN_DB_SCRIPT_STRING_ID-MAX_DB_SCRIPT_STRING_ID)
|
||||
|
||||
@@ -3402,7 +3402,8 @@ enum RemoveMethod
|
||||
{
|
||||
GROUP_REMOVEMETHOD_DEFAULT = 0,
|
||||
GROUP_REMOVEMETHOD_KICK = 1,
|
||||
GROUP_REMOVEMETHOD_LEAVE = 2
|
||||
GROUP_REMOVEMETHOD_LEAVE = 2,
|
||||
GROUP_REMOVEMETHOD_KICK_LFG = 3
|
||||
};
|
||||
|
||||
enum ActivateTaxiReply
|
||||
|
||||
@@ -888,7 +888,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||
/*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||
/*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode },
|
||||
/*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode },
|
||||
/*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrSearchOpcode },
|
||||
/*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrJoinOpcode },
|
||||
/*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode },
|
||||
/*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||
/*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||
|
||||
@@ -54,6 +54,7 @@ struct LfgJoinResultData;
|
||||
struct LfgLockStatus;
|
||||
struct LfgPlayerBoot;
|
||||
struct LfgProposal;
|
||||
struct LfgQueueStatusData;
|
||||
struct LfgReward;
|
||||
struct LfgRoleCheck;
|
||||
struct LfgUpdateData;
|
||||
@@ -815,19 +816,19 @@ class WorldSession
|
||||
void HandleLfgProposalResultOpcode(WorldPacket& recv_data);
|
||||
void HandleLfgSetBootVoteOpcode(WorldPacket& recv_data);
|
||||
void HandleLfgTeleportOpcode(WorldPacket& recv_data);
|
||||
void HandleLfrSearchOpcode(WorldPacket& recv_data);
|
||||
void HandleLfrJoinOpcode(WorldPacket& recv_data);
|
||||
void HandleLfrLeaveOpcode(WorldPacket& recv_data);
|
||||
|
||||
void SendLfgUpdatePlayer(const LfgUpdateData& updateData);
|
||||
void SendLfgUpdateParty(const LfgUpdateData& updateData);
|
||||
void SendLfgRoleChosen(uint64 guid, uint8 roles);
|
||||
void SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck);
|
||||
void SendLfgUpdateSearch(bool update);
|
||||
void SendLfgRoleCheckUpdate(const LfgRoleCheck& pRoleCheck);
|
||||
void SendLfgLfrList(bool update);
|
||||
void SendLfgJoinResult(const LfgJoinResultData& joinData);
|
||||
void SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps);
|
||||
void SendLfgQueueStatus(const LfgQueueStatusData& queueData);
|
||||
void SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest *qRew);
|
||||
void SendLfgBootPlayer(const LfgPlayerBoot* pBoot);
|
||||
void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal *pProp);
|
||||
void SendLfgBootProposalUpdate(const LfgPlayerBoot& boot);
|
||||
void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal& proposal);
|
||||
void SendLfgDisabled();
|
||||
void SendLfgOfferContinue(uint32 dungeonEntry);
|
||||
void SendLfgTeleportError(uint8 err);
|
||||
|
||||
@@ -2863,6 +2863,7 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode
|
||||
{
|
||||
target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
|
||||
target->GetMotionMaster()->MoveFall();
|
||||
target->m_movementInfo.SetFallTime(0);
|
||||
}
|
||||
|
||||
Player* player = target->ToPlayer();
|
||||
@@ -3254,9 +3255,8 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
|
||||
target->SetCanFly(apply);
|
||||
if (!apply)
|
||||
{
|
||||
target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
|
||||
target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||
target->m_movementInfo.SetFallTime(0);
|
||||
target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
|
||||
}
|
||||
|
||||
Player* player = target->ToPlayer();
|
||||
|
||||
@@ -5229,7 +5229,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
|
||||
m_targets.GetGOTarget()->GetGOInfo()->type != GAMEOBJECT_TYPE_TRAP))
|
||||
if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
|
||||
!m_caster->ToPlayer()->CanUseBattlegroundObject())
|
||||
!m_caster->ToPlayer()->CanUseBattlegroundObject(m_targets.GetGOTarget()))
|
||||
return SPELL_FAILED_TRY_AGAIN;
|
||||
|
||||
// get the lock entry
|
||||
@@ -5640,7 +5640,7 @@ SpellCastResult Spell::CheckCasterAuras() const
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundNotStun)
|
||||
if (foundNotStun && m_spellInfo->Id != 22812)
|
||||
prevented_reason = SPELL_FAILED_STUNNED;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1061,11 +1061,8 @@ SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds(uint32 spell_id) const
|
||||
return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spell_id), mSpellAreaMap.upper_bound(spell_id));
|
||||
}
|
||||
|
||||
SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const
|
||||
SpellAreaForQuestMapBounds SpellMgr::GetSpellAreaForQuestMapBounds(uint32 quest_id) const
|
||||
{
|
||||
if (active)
|
||||
return SpellAreaForQuestMapBounds(mSpellAreaForActiveQuestMap.lower_bound(quest_id), mSpellAreaForActiveQuestMap.upper_bound(quest_id));
|
||||
else
|
||||
return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id), mSpellAreaForQuestMap.upper_bound(quest_id));
|
||||
}
|
||||
|
||||
@@ -1099,11 +1096,11 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
|
||||
return false;
|
||||
|
||||
if (questStart) // not in expected required quest state
|
||||
if (!player || ((!questStartCanActive || !player->IsActiveQuest(questStart)) && !player->GetQuestRewardStatus(questStart)))
|
||||
if (!player || (((1 << player->GetQuestStatus(questStart)) & questStartStatus) == 0))
|
||||
return false;
|
||||
|
||||
if (questEnd) // not in expected forbidden quest state
|
||||
if (!player || player->GetQuestRewardStatus(questEnd))
|
||||
if (!player || (((1 << player->GetQuestStatus(questEnd)) & questEndStatus) == 0))
|
||||
return false;
|
||||
|
||||
if (auraSpell) // not have expected aura
|
||||
@@ -2433,12 +2430,11 @@ void SpellMgr::LoadSpellAreas()
|
||||
|
||||
mSpellAreaMap.clear(); // need for reload case
|
||||
mSpellAreaForQuestMap.clear();
|
||||
mSpellAreaForActiveQuestMap.clear();
|
||||
mSpellAreaForQuestEndMap.clear();
|
||||
mSpellAreaForAuraMap.clear();
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -2457,12 +2453,13 @@ void SpellMgr::LoadSpellAreas()
|
||||
spellArea.spellId = spell;
|
||||
spellArea.areaId = fields[1].GetUInt32();
|
||||
spellArea.questStart = fields[2].GetUInt32();
|
||||
spellArea.questStartCanActive = fields[3].GetBool();
|
||||
spellArea.questEnd = fields[4].GetUInt32();
|
||||
spellArea.auraSpell = fields[5].GetInt32();
|
||||
spellArea.raceMask = fields[6].GetUInt32();
|
||||
spellArea.gender = Gender(fields[7].GetUInt8());
|
||||
spellArea.autocast = fields[8].GetBool();
|
||||
spellArea.questStartStatus = fields[3].GetUInt32();
|
||||
spellArea.questEndStatus = fields[4].GetUInt32();
|
||||
spellArea.questEnd = fields[5].GetUInt32();
|
||||
spellArea.auraSpell = fields[6].GetInt32();
|
||||
spellArea.raceMask = fields[7].GetUInt32();
|
||||
spellArea.gender = Gender(fields[8].GetUInt8());
|
||||
spellArea.autocast = fields[9].GetBool();
|
||||
|
||||
if (SpellInfo const* spellInfo = GetSpellInfo(spell))
|
||||
{
|
||||
@@ -2494,7 +2491,7 @@ void SpellMgr::LoadSpellAreas()
|
||||
continue;
|
||||
|
||||
// duplicate by requirements
|
||||
ok =false;
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2524,12 +2521,6 @@ void SpellMgr::LoadSpellAreas()
|
||||
sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell, spellArea.questEnd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spellArea.questEnd == spellArea.questStart && !spellArea.questStartCanActive)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time", spell, spellArea.questEnd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (spellArea.auraSpell)
|
||||
@@ -2605,12 +2596,7 @@ void SpellMgr::LoadSpellAreas()
|
||||
|
||||
// for search at quest start/reward
|
||||
if (spellArea.questStart)
|
||||
{
|
||||
if (spellArea.questStartCanActive)
|
||||
mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
|
||||
else
|
||||
mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
|
||||
}
|
||||
|
||||
// for search at quest start/reward
|
||||
if (spellArea.questEnd)
|
||||
@@ -3486,6 +3472,10 @@ void SpellMgr::LoadDbcDataCorrections()
|
||||
case 71085: // Mana Void (periodic aura)
|
||||
spellInfo->DurationIndex = 9; // 30 seconds (missing)
|
||||
break;
|
||||
case 72015: // Frostbolt Volley (only heroic)
|
||||
case 72016: // Frostbolt Volley (only heroic)
|
||||
spellInfo->EffectRadiusIndex[2] = EFFECT_RADIUS_40_YARDS;
|
||||
break;
|
||||
case 70936: // Summon Suppressor (needs target selection script)
|
||||
spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY;
|
||||
spellInfo->EffectImplicitTargetB[0] = 0;
|
||||
|
||||
@@ -495,7 +495,8 @@ struct SpellArea
|
||||
int32 auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case
|
||||
uint32 raceMask; // can be applied only to races
|
||||
Gender gender; // can be applied only to gender
|
||||
bool questStartCanActive; // if true then quest start can be active (not only rewarded)
|
||||
uint32 questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
|
||||
uint32 questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
|
||||
bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
|
||||
|
||||
// helpers
|
||||
@@ -681,7 +682,7 @@ class SpellMgr
|
||||
|
||||
// Spell area
|
||||
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const;
|
||||
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const;
|
||||
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id) const;
|
||||
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const;
|
||||
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const;
|
||||
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const;
|
||||
@@ -740,7 +741,6 @@ class SpellMgr
|
||||
EnchantCustomAttribute mEnchantCustomAttr;
|
||||
SpellAreaMap mSpellAreaMap;
|
||||
SpellAreaForQuestMap mSpellAreaForQuestMap;
|
||||
SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
|
||||
SpellAreaForQuestMap mSpellAreaForQuestEndMap;
|
||||
SpellAreaForAuraMap mSpellAreaForAuraMap;
|
||||
SpellAreaForAreaMap mSpellAreaForAreaMap;
|
||||
|
||||
@@ -586,7 +586,7 @@ class AuraScript : public _SpellScript
|
||||
uint8 _currentScriptState;
|
||||
bool _defaultActionPrevented;
|
||||
ScriptStateStore(uint8 currentScriptState, AuraApplication const* auraApplication, bool defaultActionPrevented)
|
||||
: _currentScriptState(currentScriptState), _auraApplication(auraApplication), _defaultActionPrevented(defaultActionPrevented)
|
||||
: _auraApplication(auraApplication), _currentScriptState(currentScriptState), _defaultActionPrevented(defaultActionPrevented)
|
||||
{}
|
||||
};
|
||||
typedef std::stack<ScriptStateStore> ScriptStateStack;
|
||||
|
||||
@@ -31,45 +31,32 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
|
||||
// GM ticket
|
||||
GmTicket::GmTicket() { }
|
||||
|
||||
GmTicket::GmTicket(Player* player, WorldPacket& recv_data) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED)
|
||||
GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _haveTicket(false)
|
||||
{
|
||||
_id = sTicketMgr->GenerateTicketId();
|
||||
_playerName = player->GetName();
|
||||
_playerGuid = player->GetGUID();
|
||||
|
||||
uint32 mapId;
|
||||
recv_data >> mapId; // Map is sent as UInt32!
|
||||
recvData >> mapId; // Map is sent as UInt32!
|
||||
_mapId = mapId;
|
||||
|
||||
recv_data >> _posX;
|
||||
recv_data >> _posY;
|
||||
recv_data >> _posZ;
|
||||
recv_data >> _message;
|
||||
recvData >> _posX;
|
||||
recvData >> _posY;
|
||||
recvData >> _posZ;
|
||||
recvData >> _message;
|
||||
uint32 needResponse;
|
||||
recv_data >> needResponse;
|
||||
recvData >> needResponse;
|
||||
_needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
|
||||
uint8 unk1;
|
||||
recv_data >> unk1; // Requests further GM interaction on a ticket to which a GM has already responded
|
||||
|
||||
recv_data.rfinish();
|
||||
/*
|
||||
recv_data >> uint32(count); // text lines
|
||||
for (int i = 0; i < count; i++)
|
||||
recv_data >> uint32();
|
||||
|
||||
if (something)
|
||||
recv_data >> uint32();
|
||||
else
|
||||
compressed uint32 + string;
|
||||
*/
|
||||
recvData >> _haveTicket; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket"
|
||||
}
|
||||
|
||||
GmTicket::~GmTicket() { }
|
||||
|
||||
bool GmTicket::LoadFromDB(Field* fields)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket
|
||||
uint8 index = 0;
|
||||
_id = fields[ index].GetUInt32();
|
||||
_playerGuid = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
@@ -84,9 +71,11 @@ bool GmTicket::LoadFromDB(Field* fields)
|
||||
_closedBy = fields[++index].GetInt32();
|
||||
_assignedTo = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
_comment = fields[++index].GetString();
|
||||
_response = fields[++index].GetString();
|
||||
_completed = fields[++index].GetBool();
|
||||
_escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
|
||||
_viewed = fields[++index].GetBool();
|
||||
_haveTicket = fields[++index].GetBool();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -109,9 +98,11 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const
|
||||
stmt->setInt32 (++index, GUID_LOPART(_closedBy));
|
||||
stmt->setUInt32(++index, GUID_LOPART(_assignedTo));
|
||||
stmt->setString(++index, _comment);
|
||||
stmt->setString(++index, _response);
|
||||
stmt->setBool (++index, _completed);
|
||||
stmt->setUInt8 (++index, uint8(_escalatedStatus));
|
||||
stmt->setBool (++index, _viewed);
|
||||
stmt->setBool (++index, _haveTicket);
|
||||
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
@@ -125,6 +116,10 @@ void GmTicket::DeleteFromDB()
|
||||
|
||||
void GmTicket::WritePacket(WorldPacket& data) const
|
||||
{
|
||||
data << uint32(GMTICKET_STATUS_HASTEXT);
|
||||
data << uint32(_id);
|
||||
data << _message;
|
||||
data << uint8(_haveTicket);
|
||||
data << GetAge(_lastModifiedTime);
|
||||
if (GmTicket* ticket = sTicketMgr->GetOldestOpenTicket())
|
||||
data << GetAge(ticket->GetLastModifiedTime());
|
||||
@@ -223,6 +218,20 @@ void GmTicket::TeleportTo(Player* player) const
|
||||
player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0);
|
||||
}
|
||||
|
||||
void GmTicket::SetChatLog(std::list<uint32> time, std::string const& log)
|
||||
{
|
||||
std::stringstream ss(log);
|
||||
std::stringstream newss;
|
||||
std::string line;
|
||||
while (std::getline(ss, line))
|
||||
{
|
||||
newss << secsToTimeString(time.front()) << ": " << line << "\n";
|
||||
time.pop_front();
|
||||
}
|
||||
|
||||
_chatLog = newss.str();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ticket manager
|
||||
TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)) { }
|
||||
@@ -365,26 +374,12 @@ void TicketMgr::ShowEscalatedList(ChatHandler& handler) const
|
||||
|
||||
void TicketMgr::SendTicket(WorldSession* session, GmTicket* ticket) const
|
||||
{
|
||||
uint32 status = GMTICKET_STATUS_DEFAULT;
|
||||
std::string message;
|
||||
if (ticket)
|
||||
{
|
||||
message = ticket->GetMessage();
|
||||
status = GMTICKET_STATUS_HASTEXT;
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_GMTICKET_GETTICKET, (4 + 4 + (ticket ? message.length() + 1 + 4 + 4 + 4 + 1 + 1 : 0)));
|
||||
data << uint32(status); // standard 0x0A, 0x06 if text present
|
||||
data << uint32(ticket ? ticket->GetId() : 0); // ticketID
|
||||
WorldPacket data(SMSG_GMTICKET_GETTICKET, (ticket ? (4 + 4 + 1 + 4 + 4 + 4 + 1 + 1) : 4));
|
||||
|
||||
if (ticket)
|
||||
{
|
||||
data << message.c_str(); // ticket text
|
||||
data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client?
|
||||
|
||||
// we've got the easy stuff done by now.
|
||||
// Now we need to go through the client logic for displaying various levels of ticket load
|
||||
ticket->WritePacket(data);
|
||||
}
|
||||
else
|
||||
data << uint32(GMTICKET_STATUS_DEFAULT);
|
||||
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class GmTicket
|
||||
{
|
||||
public:
|
||||
GmTicket();
|
||||
explicit GmTicket(Player* player, WorldPacket& recv_data);
|
||||
explicit GmTicket(Player* player, WorldPacket& recvData);
|
||||
~GmTicket();
|
||||
|
||||
bool IsClosed() const { return _closedBy; }
|
||||
@@ -142,6 +142,9 @@ public:
|
||||
std::string FormatMessageString(ChatHandler& handler, bool detailed = false) const;
|
||||
std::string FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName) const;
|
||||
|
||||
void SetChatLog(std::list<uint32> time, std::string const& log);
|
||||
std::string GetChatLog() const { return _chatLog; }
|
||||
|
||||
private:
|
||||
uint32 _id;
|
||||
uint64 _playerGuid;
|
||||
@@ -160,7 +163,9 @@ private:
|
||||
GMTicketEscalationStatus _escalatedStatus;
|
||||
bool _viewed;
|
||||
bool _needResponse; // TODO: find out the use of this, and then store it in DB
|
||||
bool _haveTicket;
|
||||
std::string _response;
|
||||
std::string _chatLog; // No need to store in db, will be refreshed every session client side
|
||||
};
|
||||
typedef std::map<uint32, GmTicket*> GmTicketList;
|
||||
|
||||
|
||||
@@ -457,6 +457,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
|
||||
uint8 gender = GENDER_NONE;
|
||||
uint8 race = RACE_NONE;
|
||||
uint8 playerClass = 0;
|
||||
uint8 level = 1;
|
||||
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
while (!feof(fin))
|
||||
@@ -531,6 +532,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
|
||||
race = uint8(atol(getnth(line, 4).c_str()));
|
||||
playerClass = uint8(atol(getnth(line, 5).c_str()));
|
||||
gender = uint8(atol(getnth(line, 6).c_str()));
|
||||
level = uint8(atol(getnth(line, 7).c_str()));
|
||||
if (name == "")
|
||||
{
|
||||
// check if the original name already exists
|
||||
@@ -674,7 +676,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
// in case of name conflict player has to rename at login anyway
|
||||
sWorld->AddCharacterNameData(guid, name, gender, race, playerClass);
|
||||
sWorld->AddCharacterNameData(guid, name, gender, race, playerClass, level);
|
||||
|
||||
sObjectMgr->_hiItemGuid += items.size();
|
||||
sObjectMgr->_mailId += mails.size();
|
||||
|
||||
@@ -1469,14 +1469,15 @@ void World::SetInitialWorldSettings()
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Vehicle Accessories...");
|
||||
sObjectMgr->LoadVehicleAccessories(); // must be after LoadCreatureTemplates() and LoadNPCSpellClickSpells()
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG entrance positions...");
|
||||
sLFGMgr->LoadLFGDungeons();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Dungeon boss data...");
|
||||
sObjectMgr->LoadInstanceEncounters();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG rewards...");
|
||||
sLFGMgr->LoadRewards();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG entrance positions...");
|
||||
sLFGMgr->LoadEntrancePositions();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading SpellArea Data..."); // must be after quest load
|
||||
sSpellMgr->LoadSpellAreas();
|
||||
@@ -2945,7 +2946,7 @@ void World::LoadCharacterNameData()
|
||||
{
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading character name data");
|
||||
|
||||
QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters WHERE deleteDate IS NULL");
|
||||
QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class, level FROM characters WHERE deleteDate IS NULL");
|
||||
if (!result)
|
||||
{
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "No character name data loaded, empty query");
|
||||
@@ -2958,20 +2959,21 @@ void World::LoadCharacterNameData()
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
AddCharacterNameData(fields[0].GetUInt32(), fields[1].GetString(),
|
||||
fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/);
|
||||
fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/, fields[5].GetUInt8() /*level*/);
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loaded name data for %u characters", count);
|
||||
}
|
||||
|
||||
void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass)
|
||||
void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level)
|
||||
{
|
||||
CharacterNameData& data = _characterNameDataMap[guid];
|
||||
data.m_name = name;
|
||||
data.m_race = race;
|
||||
data.m_gender = gender;
|
||||
data.m_class = playerClass;
|
||||
data.m_level = level;
|
||||
}
|
||||
|
||||
void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender /*= GENDER_NONE*/, uint8 race /*= RACE_NONE*/)
|
||||
@@ -2989,6 +2991,15 @@ void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8
|
||||
itr->second.m_race = race;
|
||||
}
|
||||
|
||||
void World::UpdateCharacterNameDataLevel(uint32 guid, uint8 level)
|
||||
{
|
||||
std::map<uint32, CharacterNameData>::iterator itr = _characterNameDataMap.find(guid);
|
||||
if (itr == _characterNameDataMap.end())
|
||||
return;
|
||||
|
||||
itr->second.m_level = level;
|
||||
}
|
||||
|
||||
CharacterNameData const* World::GetCharacterNameData(uint32 guid) const
|
||||
{
|
||||
std::map<uint32, CharacterNameData>::const_iterator itr = _characterNameDataMap.find(guid);
|
||||
|
||||
@@ -538,6 +538,7 @@ struct CharacterNameData
|
||||
uint8 m_class;
|
||||
uint8 m_race;
|
||||
uint8 m_gender;
|
||||
uint8 m_level;
|
||||
};
|
||||
|
||||
/// The World
|
||||
@@ -759,8 +760,9 @@ class World
|
||||
bool isEventKillStart;
|
||||
|
||||
CharacterNameData const* GetCharacterNameData(uint32 guid) const;
|
||||
void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass);
|
||||
void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level);
|
||||
void UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE);
|
||||
void UpdateCharacterNameDataLevel(uint32 guid, uint8 level);
|
||||
void DeleteCharaceterNameData(uint32 guid) { _characterNameDataMap.erase(guid); }
|
||||
|
||||
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
|
||||
|
||||
@@ -224,7 +224,7 @@ public:
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
|
||||
stmt->setUInt32(0, delInfo.lowGuid);
|
||||
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
|
||||
sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8());
|
||||
sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8(), (*result)[3].GetUInt8());
|
||||
}
|
||||
|
||||
static void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel, ChatHandler* handler)
|
||||
|
||||
@@ -1002,15 +1002,19 @@ public:
|
||||
if (handler->HasLowerSecurity(target, 0))
|
||||
return false;
|
||||
|
||||
int32 addmoney = atoi((char*)args);
|
||||
int32 moneyToAdd = 0;
|
||||
if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c'))
|
||||
moneyToAdd = MoneyStringToMoney(std::string(args));
|
||||
else
|
||||
moneyToAdd = atoi(args);
|
||||
|
||||
uint32 moneyuser = target->GetMoney();
|
||||
uint32 targetMoney = target->GetMoney();
|
||||
|
||||
if (addmoney < 0)
|
||||
if (moneyToAdd < 0)
|
||||
{
|
||||
int32 newmoney = int32(moneyuser) + addmoney;
|
||||
int32 newmoney = int32(targetMoney) + moneyToAdd;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney);
|
||||
sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_CURRENT_MONEY), targetMoney, moneyToAdd, newmoney);
|
||||
if (newmoney <= 0)
|
||||
{
|
||||
handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str());
|
||||
@@ -1024,25 +1028,25 @@ public:
|
||||
if (newmoney > MAX_MONEY_AMOUNT)
|
||||
newmoney = MAX_MONEY_AMOUNT;
|
||||
|
||||
handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(addmoney), handler->GetNameLink(target).c_str());
|
||||
handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(moneyToAdd), handler->GetNameLink(target).c_str());
|
||||
if (handler->needReportToTarget(target))
|
||||
(ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), abs(addmoney));
|
||||
(ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), abs(moneyToAdd));
|
||||
target->SetMoney(newmoney);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, handler->GetNameLink(target).c_str());
|
||||
handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, moneyToAdd, handler->GetNameLink(target).c_str());
|
||||
if (handler->needReportToTarget(target))
|
||||
(ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), addmoney);
|
||||
(ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), moneyToAdd);
|
||||
|
||||
if (addmoney >=MAX_MONEY_AMOUNT)
|
||||
if (moneyToAdd >= MAX_MONEY_AMOUNT)
|
||||
target->SetMoney(MAX_MONEY_AMOUNT);
|
||||
else
|
||||
target->ModifyMoney(addmoney);
|
||||
target->ModifyMoney(moneyToAdd);
|
||||
}
|
||||
|
||||
sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_NEW_MONEY), moneyuser, addmoney, target->GetMoney());
|
||||
sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_NEW_MONEY), targetMoney, moneyToAdd, target->GetMoney());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -30,40 +30,41 @@ Script Data End */
|
||||
|
||||
#define GOSSIP_START_EVENT "I am ready to being"
|
||||
|
||||
enum eBlastmasterEmiShortfuse
|
||||
enum BlastmasterEmi
|
||||
{
|
||||
GOSSIP_TEXT_EMI = 1693,
|
||||
|
||||
SAY_BLASTMASTER_0 = -1090000,
|
||||
SAY_BLASTMASTER_1 = -1090001,
|
||||
SAY_BLASTMASTER_2 = -1090002,
|
||||
SAY_BLASTMASTER_3 = -1090003,
|
||||
SAY_BLASTMASTER_4 = -1090004,
|
||||
SAY_BLASTMASTER_5 = -1090005,
|
||||
SAY_BLASTMASTER_6 = -1090006,
|
||||
SAY_BLASTMASTER_7 = -1090007,
|
||||
SAY_BLASTMASTER_8 = -1090008,
|
||||
SAY_BLASTMASTER_9 = -1090009,
|
||||
SAY_BLASTMASTER_10 = -1090010,
|
||||
SAY_BLASTMASTER_11 = -1090011,
|
||||
SAY_BLASTMASTER_12 = -1090012,
|
||||
SAY_BLASTMASTER_13 = -1090013,
|
||||
SAY_BLASTMASTER_14 = -1090014,
|
||||
SAY_BLASTMASTER_15 = -1090015,
|
||||
SAY_BLASTMASTER_16 = -1090016,
|
||||
SAY_BLASTMASTER_17 = -1090017,
|
||||
SAY_BLASTMASTER_18 = -1090018,
|
||||
SAY_BLASTMASTER_19 = -1090019,
|
||||
SAY_BLASTMASTER_20 = -1090020,
|
||||
SAY_BLASTMASTER_21 = -1090021,
|
||||
SAY_BLASTMASTER_22 = -1090022,
|
||||
SAY_BLASTMASTER_23 = -1090023,
|
||||
SAY_BLASTMASTER_24 = -1090024,
|
||||
SAY_BLASTMASTER_25 = -1090025,
|
||||
SAY_BLASTMASTER_26 = -1090026,
|
||||
SAY_BLASTMASTER_27 = -1090027,
|
||||
SAY_BLASTMASTER_0 = 0,
|
||||
SAY_BLASTMASTER_1 = 1,
|
||||
SAY_BLASTMASTER_2 = 2,
|
||||
SAY_BLASTMASTER_3 = 3,
|
||||
SAY_BLASTMASTER_4 = 4,
|
||||
SAY_BLASTMASTER_5 = 5,
|
||||
SAY_BLASTMASTER_6 = 6,
|
||||
SAY_BLASTMASTER_7 = 7,
|
||||
SAY_BLASTMASTER_8 = 8,
|
||||
SAY_BLASTMASTER_9 = 9,
|
||||
SAY_BLASTMASTER_10 = 10,
|
||||
SAY_BLASTMASTER_11 = 11,
|
||||
SAY_BLASTMASTER_12 = 12,
|
||||
SAY_BLASTMASTER_13 = 13,
|
||||
SAY_BLASTMASTER_14 = 14,
|
||||
SAY_BLASTMASTER_15 = 15,
|
||||
SAY_BLASTMASTER_16 = 16,
|
||||
SAY_BLASTMASTER_17 = 17,
|
||||
SAY_BLASTMASTER_18 = 18,
|
||||
SAY_BLASTMASTER_19 = 19,
|
||||
SAY_BLASTMASTER_20 = 20,
|
||||
SAY_BLASTMASTER_21 = 21,
|
||||
SAY_BLASTMASTER_22 = 22,
|
||||
SAY_BLASTMASTER_23 = 23,
|
||||
SAY_BLASTMASTER_24 = 24,
|
||||
SAY_BLASTMASTER_25 = 25,
|
||||
SAY_BLASTMASTER_26 = 26,
|
||||
SAY_BLASTMASTER_27 = 27,
|
||||
SAY_BLASTMASTER_28 = 28,
|
||||
|
||||
SAY_GRUBBIS = -1090028
|
||||
SAY_GRUBBIS = 0
|
||||
};
|
||||
|
||||
const Position SpawnPosition[] =
|
||||
@@ -78,13 +79,16 @@ const Position SpawnPosition[] =
|
||||
{-552.534f, -110.012f, -153.577f, 0.747f},
|
||||
{-550.708f, -116.436f, -153.103f, 0.679f},
|
||||
{-554.030f, -115.983f, -152.635f, 0.695f},
|
||||
{-494.595f, -87.516f, 149.116f, 3.344f},
|
||||
{-494.595f, -87.516f, -149.116f, 3.344f},
|
||||
{-493.349f, -90.845f, -148.882f, 3.717f},
|
||||
{-491.995f, -87.619f, -148.197f, 3.230f},
|
||||
{-490.732f, -90.739f, -148.091f, 3.230f},
|
||||
{-490.554f, -89.114f, -148.055f, 3.230f},
|
||||
{-495.240f, -90.808f, -149.493f, 3.238f},
|
||||
{-494.195f, -89.553f, -149.131f, 3.254f}
|
||||
{-494.195f, -89.553f, -149.131f, 3.254f},
|
||||
{-511.3304f, -139.9622f, -152.4761f, 0.7504908f},
|
||||
{-510.6754f, -139.4371f, -152.6167f, 3.33359f},
|
||||
{-511.8976f, -139.3562f, -152.4785f, 3.961899f}
|
||||
};
|
||||
|
||||
class npc_blastmaster_emi_shortfuse : public CreatureScript
|
||||
@@ -305,7 +309,7 @@ public:
|
||||
break;
|
||||
case 14:
|
||||
SetInFace(false);
|
||||
DoScriptText(SAY_BLASTMASTER_26, me);
|
||||
Talk(SAY_BLASTMASTER_26);
|
||||
SetEscortPaused(true);
|
||||
NextStep(5000, false, 20);
|
||||
break;
|
||||
@@ -318,8 +322,8 @@ public:
|
||||
{
|
||||
case 1:
|
||||
SetEscortPaused(true);
|
||||
DoScriptText(SAY_BLASTMASTER_0, me);
|
||||
NextStep(1500, true);
|
||||
Talk(SAY_BLASTMASTER_0);
|
||||
NextStep(2000, true);
|
||||
break;
|
||||
case 2:
|
||||
if (!instance)
|
||||
@@ -368,7 +372,7 @@ public:
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
DoScriptText(SAY_BLASTMASTER_19, me);
|
||||
Talk(SAY_BLASTMASTER_19);
|
||||
break;
|
||||
case 4:
|
||||
if (GameObject* go = me->SummonGameObject(183410, -542.199f, -96.854f, -155.790f, 0, 0, 0, 0, 0, 1000))
|
||||
@@ -381,7 +385,7 @@ public:
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
DoScriptText(SAY_BLASTMASTER_15, me);
|
||||
Talk(SAY_BLASTMASTER_15);
|
||||
break;
|
||||
case 6:
|
||||
me->SummonCreature(NPC_CAVERNDEEP_AMBUSHER, SpawnPosition[10], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
@@ -406,10 +410,15 @@ public:
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (Creature* pGrubbis = me->SummonCreature(NPC_GRUBBIS, SpawnPosition[15], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000))
|
||||
DoScriptText(SAY_GRUBBIS, pGrubbis);
|
||||
if (Creature* grubbis = me->SummonCreature(NPC_GRUBBIS, SpawnPosition[15], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000))
|
||||
grubbis->AI()->Talk(SAY_GRUBBIS);
|
||||
me->SummonCreature(NPC_CHOMPER, SpawnPosition[16], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1800000);
|
||||
break;
|
||||
case 10:
|
||||
me->SummonGameObject(GO_RED_ROCKET, SpawnPosition[17].GetPositionX(), SpawnPosition[17].GetPositionY(), SpawnPosition[17].GetPositionZ(), SpawnPosition[17].GetOrientation(), 0, 0, 0, 0, 7200);
|
||||
me->SummonGameObject(GO_RED_ROCKET, SpawnPosition[18].GetPositionX(), SpawnPosition[18].GetPositionY(), SpawnPosition[18].GetPositionZ(), SpawnPosition[18].GetOrientation(), 0, 0, 0, 0, 7200);
|
||||
me->SummonGameObject(GO_RED_ROCKET, SpawnPosition[19].GetPositionX(), SpawnPosition[19].GetPositionY(), SpawnPosition[19].GetPositionZ(), SpawnPosition[19].GetOrientation(), 0, 0, 0, 0, 7200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,29 +431,29 @@ public:
|
||||
switch (uiPhase)
|
||||
{
|
||||
case 1:
|
||||
DoScriptText(SAY_BLASTMASTER_1, me);
|
||||
NextStep(1500, true);
|
||||
Talk(SAY_BLASTMASTER_1);
|
||||
NextStep(2000, true);
|
||||
break;
|
||||
case 2:
|
||||
SetEscortPaused(false);
|
||||
NextStep(0, false, 0);
|
||||
break;
|
||||
case 3:
|
||||
DoScriptText(SAY_BLASTMASTER_2, me);
|
||||
Talk(SAY_BLASTMASTER_2);
|
||||
SetEscortPaused(false);
|
||||
NextStep(0, false, 0);
|
||||
break;
|
||||
case 4:
|
||||
DoScriptText(SAY_BLASTMASTER_3, me);
|
||||
Talk(SAY_BLASTMASTER_3);
|
||||
NextStep(3000, true);
|
||||
break;
|
||||
case 5:
|
||||
DoScriptText(SAY_BLASTMASTER_4, me);
|
||||
Talk(SAY_BLASTMASTER_4);
|
||||
NextStep(3000, true);
|
||||
break;
|
||||
case 6:
|
||||
SetInFace(true);
|
||||
DoScriptText(SAY_BLASTMASTER_5, me);
|
||||
Talk(SAY_BLASTMASTER_5);
|
||||
Summon(1);
|
||||
if (instance)
|
||||
if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT)))
|
||||
@@ -452,12 +461,12 @@ public:
|
||||
NextStep(3000, true);
|
||||
break;
|
||||
case 7:
|
||||
DoScriptText(SAY_BLASTMASTER_6, me);
|
||||
Talk(SAY_BLASTMASTER_6);
|
||||
SetEscortPaused(false);
|
||||
NextStep(0, false, 0);
|
||||
break;
|
||||
case 8:
|
||||
me->HandleEmoteCommand(EMOTE_STATE_WORK);
|
||||
me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING);
|
||||
NextStep(25000, true);
|
||||
break;
|
||||
case 9:
|
||||
@@ -469,28 +478,28 @@ public:
|
||||
NextStep(0, false);
|
||||
break;
|
||||
case 11:
|
||||
DoScriptText(SAY_BLASTMASTER_17, me);
|
||||
Talk(SAY_BLASTMASTER_17);
|
||||
NextStep(5000, true);
|
||||
break;
|
||||
case 12:
|
||||
DoScriptText(SAY_BLASTMASTER_18, me);
|
||||
Talk(SAY_BLASTMASTER_18);
|
||||
NextStep(5000, true);
|
||||
break;
|
||||
case 13:
|
||||
DoScriptText(SAY_BLASTMASTER_20, me);
|
||||
Talk(SAY_BLASTMASTER_20);
|
||||
CaveDestruction(true);
|
||||
NextStep(8000, true);
|
||||
break;
|
||||
case 14:
|
||||
DoScriptText(SAY_BLASTMASTER_21, me);
|
||||
Talk(SAY_BLASTMASTER_21);
|
||||
NextStep(8500, true);
|
||||
break;
|
||||
case 15:
|
||||
DoScriptText(SAY_BLASTMASTER_22, me);
|
||||
Talk(SAY_BLASTMASTER_22);
|
||||
NextStep(2000, true);
|
||||
break;
|
||||
case 16:
|
||||
DoScriptText(SAY_BLASTMASTER_23, me);
|
||||
Talk(SAY_BLASTMASTER_23);
|
||||
SetInFace(false);
|
||||
if (instance)
|
||||
if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT)))
|
||||
@@ -499,7 +508,7 @@ public:
|
||||
break;
|
||||
case 17:
|
||||
SetEscortPaused(false);
|
||||
DoScriptText(SAY_BLASTMASTER_24, me);
|
||||
Talk(SAY_BLASTMASTER_24);
|
||||
Summon(6);
|
||||
NextStep(0, false);
|
||||
break;
|
||||
@@ -510,11 +519,11 @@ public:
|
||||
case 19:
|
||||
SetInFace(false);
|
||||
Summon(8);
|
||||
DoScriptText(SAY_BLASTMASTER_25, me);
|
||||
Talk(SAY_BLASTMASTER_25);
|
||||
NextStep(0, false);
|
||||
break;
|
||||
case 20:
|
||||
DoScriptText(SAY_BLASTMASTER_27, me);
|
||||
Talk(SAY_BLASTMASTER_27);
|
||||
NextStep(2000, true);
|
||||
break;
|
||||
case 21:
|
||||
@@ -523,7 +532,12 @@ public:
|
||||
break;
|
||||
case 22:
|
||||
CaveDestruction(false);
|
||||
DoScriptText(SAY_BLASTMASTER_20, me);
|
||||
Talk(SAY_BLASTMASTER_20);
|
||||
NextStep(2000, true);
|
||||
break;
|
||||
case 23:
|
||||
Summon(10);
|
||||
Talk(SAY_BLASTMASTER_28);
|
||||
NextStep(0, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
enum eGameObjects
|
||||
{
|
||||
GO_CAVE_IN_LEFT = 146085,
|
||||
GO_CAVE_IN_RIGHT = 146086
|
||||
GO_CAVE_IN_RIGHT = 146086,
|
||||
GO_RED_ROCKET = 103820
|
||||
};
|
||||
|
||||
enum eCreatures
|
||||
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
|
||||
void Reset()
|
||||
{
|
||||
uiDarkOffering = urand(290, 10);
|
||||
uiDarkOffering = urand(200, 1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 const uiDiff)
|
||||
|
||||
@@ -696,7 +696,7 @@ class npc_halion_controller : public CreatureScript
|
||||
halion->AI()->Talk(SAY_INTRO);
|
||||
break;
|
||||
case EVENT_TWILIGHT_MENDING:
|
||||
if (Creature* halion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HALION)))
|
||||
if (ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HALION))) // Just check if physical Halion is spawned
|
||||
if (Creature* twilightHalion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TWILIGHT_HALION)))
|
||||
twilightHalion->CastSpell((Unit*)NULL, SPELL_TWILIGHT_MENDING, true);
|
||||
break;
|
||||
@@ -1115,7 +1115,7 @@ class npc_combustion_consumption : public CreatureScript
|
||||
struct npc_combustion_consumptionAI : public Scripted_NoMovementAI
|
||||
{
|
||||
npc_combustion_consumptionAI(Creature* creature) : Scripted_NoMovementAI(creature),
|
||||
_summonerGuid(0), _instance(creature->GetInstanceScript())
|
||||
_instance(creature->GetInstanceScript()), _summonerGuid(0)
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
uiConsumeTimer = 15*IN_MILLISECONDS;
|
||||
uiAuraCountTimer = 15500;
|
||||
uiCrushTimer = urand(1*IN_MILLISECONDS, 5*IN_MILLISECONDS);
|
||||
uiInfectedWoundTimer = urand(60*IN_MILLISECONDS, 10*IN_MILLISECONDS);
|
||||
uiInfectedWoundTimer = urand(10*IN_MILLISECONDS, 60*IN_MILLISECONDS);
|
||||
uiExplodeCorpseTimer = 3*IN_MILLISECONDS;
|
||||
uiSpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS);
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ public:
|
||||
{
|
||||
npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
void MovementInform(uint32 /*type*/, uint32 id)
|
||||
{
|
||||
// When Belgaristraz finish his moving say grateful text
|
||||
if (me->GetEntry() == NPC_BELGARISTRASZ)
|
||||
|
||||
@@ -1581,12 +1581,12 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader
|
||||
}
|
||||
|
||||
|
||||
LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*itr);
|
||||
LFGDungeonData const* randomDungeon = sLFGMgr->GetLFGDungeon(*itr);
|
||||
if (Group* group = owner->GetGroup())
|
||||
if (Map const* map = owner->GetMap())
|
||||
if (group->isLFGGroup())
|
||||
if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId))
|
||||
if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty()))
|
||||
if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM)
|
||||
return; // in correct dungeon
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
enum HunterSpells
|
||||
{
|
||||
HUNTER_SPELL_READINESS = 23989,
|
||||
DRAENEI_SPELL_GIFT_OF_THE_NAARU = 59543,
|
||||
HUNTER_SPELL_BESTIAL_WRATH = 19574,
|
||||
HUNTER_PET_SPELL_LAST_STAND_TRIGGERED = 53479,
|
||||
HUNTER_PET_HEART_OF_THE_PHOENIX = 55709,
|
||||
@@ -340,6 +341,7 @@ class spell_hun_readiness : public SpellScriptLoader
|
||||
spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
|
||||
spellInfo->Id != HUNTER_SPELL_READINESS &&
|
||||
spellInfo->Id != HUNTER_SPELL_BESTIAL_WRATH &&
|
||||
spellInfo->Id != DRAENEI_SPELL_GIFT_OF_THE_NAARU &&
|
||||
spellInfo->GetRecoveryTime() > 0)
|
||||
caster->RemoveSpellCooldown((itr++)->first, true);
|
||||
else
|
||||
|
||||
@@ -1844,7 +1844,7 @@ class spell_item_unusual_compass : public SpellScriptLoader
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
caster->SetOrientation(frand(0.0f, 62832.0f) / 10000.0f);
|
||||
caster->SendMovementFlagUpdate();
|
||||
caster->SendMovementFlagUpdate(true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
|
||||
@@ -2115,14 +2115,12 @@ class npc_shadowfiend : public CreatureScript
|
||||
{
|
||||
npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (me->isSummon())
|
||||
if (Unit* owner = me->ToTempSummon()->GetSummoner())
|
||||
if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
|
||||
owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
|
||||
|
||||
PetAI::JustDied(killer);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender, level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC);
|
||||
@@ -327,8 +327,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
|
||||
|
||||
// GM Tickets
|
||||
PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed FROM gm_tickets", CONNECTION_SYNCH)
|
||||
PREPARE_STATEMENT(CHAR_REP_GM_TICKET, "REPLACE INTO gm_tickets (ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC)
|
||||
PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket FROM gm_tickets", CONNECTION_SYNCH)
|
||||
PREPARE_STATEMENT(CHAR_REP_GM_TICKET, "REPLACE INTO gm_tickets (ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC)
|
||||
PREPARE_STATEMENT(CHAR_DEL_GM_TICKET, "DELETE FROM gm_tickets WHERE ticketId = ?", CONNECTION_ASYNC)
|
||||
PREPARE_STATEMENT(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_tickets WHERE guid = ?", CONNECTION_ASYNC)
|
||||
|
||||
@@ -421,6 +421,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PREPARE_STATEMENT(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_AT_LOGIN_TITLES, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_PET_SPELL_LIST, "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet WHERE character_pet.owner = ? AND character_pet.id = pet_spell.guid AND character_pet.id <> ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_PET, "SELECT id FROM character_pet WHERE owner = ? AND id <> ?", CONNECTION_SYNCH);
|
||||
@@ -497,8 +498,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PREPARE_STATEMENT(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, "UPDATE item_instance ii, character_inventory ci SET ii.itemEntry = ? WHERE ii.itemEntry = ? AND ci.guid = ? AND ci.item = ii.guid", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_BY_SPELL, "DELETE FROM character_spell WHERE spell = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, "UPDATE character_spell SET spell = ? where spell = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_SEL_CHAR_REP_BY_FACTION, "SELECT standing FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_SYNCH);
|
||||
PREPARE_STATEMENT(CHAR_DEL_CHAR_REP_BY_FACTION, "DELETE FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ? where faction = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ?, standing = ? WHERE faction = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET knownTitles = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_RES_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET chosenTitle = 0 WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_COOLDOWN, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -384,6 +384,7 @@ enum CharacterDatabaseStatements
|
||||
CHAR_SEL_POOL_QUEST_SAVE,
|
||||
CHAR_SEL_CHARACTER_AT_LOGIN,
|
||||
CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN,
|
||||
CHAR_SEL_CHAR_AT_LOGIN_TITLES,
|
||||
CHAR_SEL_INSTANCE,
|
||||
CHAR_SEL_PET_SPELL_LIST,
|
||||
CHAR_SEL_CHAR_PET,
|
||||
@@ -460,6 +461,7 @@ enum CharacterDatabaseStatements
|
||||
CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE,
|
||||
CHAR_DEL_CHAR_SPELL_BY_SPELL,
|
||||
CHAR_UPD_CHAR_SPELL_FACTION_CHANGE,
|
||||
CHAR_SEL_CHAR_REP_BY_FACTION,
|
||||
CHAR_DEL_CHAR_REP_BY_FACTION,
|
||||
CHAR_UPD_CHAR_REP_FACTION_CHANGE,
|
||||
CHAR_UPD_CHAR_TITLES_FACTION_CHANGE,
|
||||
|
||||
@@ -150,6 +150,37 @@ std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int32 MoneyStringToMoney(const std::string& moneyString)
|
||||
{
|
||||
int32 money = 0;
|
||||
|
||||
if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
|
||||
std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
|
||||
std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
|
||||
return 0; // Bad format
|
||||
|
||||
Tokenizer tokens(moneyString, ' ');
|
||||
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||
{
|
||||
std::string tokenString(*itr);
|
||||
uint32 gCount = std::count(tokenString.begin(), tokenString.end(), 'g');
|
||||
uint32 sCount = std::count(tokenString.begin(), tokenString.end(), 's');
|
||||
uint32 cCount = std::count(tokenString.begin(), tokenString.end(), 'c');
|
||||
if (gCount + sCount + cCount != 1)
|
||||
return 0;
|
||||
|
||||
uint32 amount = atoi(*itr);
|
||||
if (gCount == 1)
|
||||
money += amount * 100 * 100;
|
||||
else if (sCount == 1)
|
||||
money += amount * 100;
|
||||
else if (cCount == 1)
|
||||
money += amount;
|
||||
}
|
||||
|
||||
return money;
|
||||
}
|
||||
|
||||
uint32 TimeStringToSecs(const std::string& timestring)
|
||||
{
|
||||
uint32 secs = 0;
|
||||
|
||||
@@ -66,6 +66,8 @@ private:
|
||||
|
||||
void stripLineInvisibleChars(std::string &src);
|
||||
|
||||
int32 MoneyStringToMoney(const std::string& moneyString);
|
||||
|
||||
std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
|
||||
uint32 TimeStringToSecs(const std::string& timestring);
|
||||
std::string TimeToTimestampStr(time_t t);
|
||||
|
||||
Reference in New Issue
Block a user