diff options
18 files changed, 482 insertions, 266 deletions
diff --git a/sql/updates/world/2013_01_08_01_world_raise_the_barricades.sql b/sql/updates/world/2013_01_08_01_world_raise_the_barricades.sql new file mode 100644 index 00000000000..636beb404de --- /dev/null +++ b/sql/updates/world/2013_01_08_01_world_raise_the_barricades.sql @@ -0,0 +1,19 @@ +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=31887; +DELETE FROM `smart_scripts` WHERE `entryorguid`=31887 AND `source_type`=0; +INSERT INTO `smart_scripts`(`entryorguid`,`id`,`link`,`event_type`,`event_param1`,`action_type`,`action_param1`,`action_param2`,`target_type`,`comment`) VALUES +(31887,0,1,8,59925,88,3188700,3188702,1,'Ebon Blade Marker - On spell hit of Construct Barricade - Call random actionlist'), +(31887,1,2,61,0,33,31887,0,7,'Ebon Blade Marker - On spell hit of Construct Barricade - Give quest credit'), +(31887,2,0,61,0,41,0,0,1,'Ebon Blade Marker - On spell hit of Construct Barricade - Despawn'); + +DELETE FROM `smart_scripts` WHERE `entryorguid` BETWEEN 3188700 AND 3188702 AND `source_type`=9; +INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`action_type`,`action_param1`,`target_type`,`comment`) VALUES +(3188700,9,11,59922,1,'Ebon Blade Marker - Actionlist - Cast Summon Barricade A'), +(3188701,9,11,59923,1,'Ebon Blade Marker - Actionlist - Cast Summon Barricade B'), +(3188702,9,11,59924,1,'Ebon Blade Marker - Actionlist - Cast Summon Barricade C'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=59925; +INSERT INTO `conditions`(`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`Comment`) VALUE +(13,1,59925,31,3,31887,'Construct Barricade - Target must be Ebon Blade Marker'); + +UPDATE `creature_addon` INNER JOIN `creature` ON `creature`.`guid`=`creature_addon`.`guid` SET `auras`='59919' WHERE `id`=31887; +UPDATE `creature` SET `MovementType`=0,`spawndist`=0 WHERE `id`=31887; diff --git a/sql/updates/world/2013_01_09_00_world_misc.sql b/sql/updates/world/2013_01_09_00_world_misc.sql new file mode 100644 index 00000000000..a5402c60534 --- /dev/null +++ b/sql/updates/world/2013_01_09_00_world_misc.sql @@ -0,0 +1,149 @@ +SET @GUID := 43491; +SET @OGUID := 16964; +SET @NPC_ELM_BUNNY := 23837; +SET @NPC_HARKOA := 28401; +SET @NPC_KHUFU := 28479; +SET @NPC_QUETZLUN_PROPHET := 28671; +SET @NPC_QUETZLUN_SPIRIT := 28785; +SET @NPC_DRAINED_PROPHET := 28795; + +DELETE FROM `spell_dbc` WHERE `Id`=25900; +INSERT INTO `spell_dbc` (`Id`,`Dispel`,`Mechanic`,`Attributes`,`AttributesEx`,`AttributesEx2`,`AttributesEx3`,`AttributesEx4`,`AttributesEx5`,`AttributesEx6`,`AttributesEx7`,`Stances`,`StancesNot`,`Targets`,`CastingTimeIndex`,`AuraInterruptFlags`,`ProcFlags`,`ProcChance`,`ProcCharges`,`MaxLevel`,`BaseLevel`,`SpellLevel`,`DurationIndex`,`RangeIndex`,`StackAmount`,`EquippedItemClass`,`EquippedItemSubClassMask`,`EquippedItemInventoryTypeMask`,`Effect1`,`Effect2`,`Effect3`,`EffectDieSides1`,`EffectDieSides2`,`EffectDieSides3`,`EffectRealPointsPerLevel1`,`EffectRealPointsPerLevel2`,`EffectRealPointsPerLevel3`,`EffectBasePoints1`,`EffectBasePoints2`,`EffectBasePoints3`,`EffectMechanic1`,`EffectMechanic2`,`EffectMechanic3`,`EffectImplicitTargetA1`,`EffectImplicitTargetA2`,`EffectImplicitTargetA3`,`EffectImplicitTargetB1`,`EffectImplicitTargetB2`,`EffectImplicitTargetB3`,`EffectRadiusIndex1`,`EffectRadiusIndex2`,`EffectRadiusIndex3`,`EffectApplyAuraName1`,`EffectApplyAuraName2`,`EffectApplyAuraName3`,`EffectAmplitude1`,`EffectAmplitude2`,`EffectAmplitude3`,`EffectMultipleValue1`,`EffectMultipleValue2`,`EffectMultipleValue3`,`EffectMiscValue1`,`EffectMiscValue2`,`EffectMiscValue3`,`EffectMiscValueB1`,`EffectMiscValueB2`,`EffectMiscValueB3`,`EffectTriggerSpell1`,`EffectTriggerSpell2`,`EffectTriggerSpell3`,`EffectSpellClassMaskA1`,`EffectSpellClassMaskA2`,`EffectSpellClassMaskA3`,`EffectSpellClassMaskB1`,`EffectSpellClassMaskB2`,`EffectSpellClassMaskB3`,`EffectSpellClassMaskC1`,`EffectSpellClassMaskC2`,`EffectSpellClassMaskC3`,`MaxTargetLevel`,`SpellFamilyName`,`SpellFamilyFlags1`,`SpellFamilyFlags2`,`SpellFamilyFlags3`,`MaxAffectedTargets`,`DmgClass`,`PreventionType`,`AreaGroupId`,`SchoolMask`,`Comment`) VALUES +(25900,0,0,256,268435456,0,0,0,0,0,0,0,0,0,1,0,0,101,0,0,0,0,21,1,0,-1,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'Stun Self'); + +UPDATE `creature` SET `spawndist`=0, `MovementType`=0 WHERE `guid`=97576; +DELETE FROM `creature` WHERE `guid`=@GUID; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`MovementType`) VALUES +(@GUID,@NPC_HARKOA,571,1,1,0,5746.506,-3608.833,387.1909,1.396263,300,0,0); + +DELETE FROM `gameobject` WHERE `guid` IN (@OGUID+0,@OGUID+1,@OGUID+2,@OGUID+3,@OGUID+4,@OGUID+5,@OGUID+6,@OGUID+7,@OGUID+8,@OGUID+9); +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(@OGUID+0,190736,571,1,1,5335.713,-3770.941,371.7576,4.677484,0,0,-0.7193394,0.6946588,-30,255,0), +(@OGUID+1,190737,571,1,1,5329.674,-3770.804,371.3612,0.2617982,0,0,0.1305256,0.9914449,-30,255,0), +(@OGUID+2,190738,571,1,1,5332.682,-3770.142,371.5185,1.815142,0,0,0.7880106,0.6156617,-30,255,0), +(@OGUID+3,190738,571,1,1,5336.708,-3774.066,371.4286,4.415683,0,0,-0.8038568,0.5948228,-30,255,0), +(@OGUID+4,190737,571,1,1,5335.804,-3777.733,371.3452,2.565632,0,0,0.9588194,0.2840165,-30,255,0), +(@OGUID+5,190738,571,1,1,5711.15,-4361.727,385.8019,1.762782,0,0,0.7716246,0.6360782,-30,255,0), +(@OGUID+6,190737,571,1,1,5725.948,-4372.56,386.2328,0.122173,0,0,0.06104851,0.9981348,-30,255,0), +(@OGUID+7,190736,571,1,1,5707.201,-4371.69,385.8015,2.670348,0,0,0.9723692,0.2334484,-30,255,0), +(@OGUID+8,190737,571,1,1,5721.946,-4361.917,385.7987,1.151916,0,0,0.5446386,0.8386708,-30,255,0), +(@OGUID+9,190737,571,1,1,5717.053,-4378.755,385.8015,0.05235888,0,0,0.02617645,0.9996573,-30,255,0); + +UPDATE `gameobject_template` SET `flags`=4 WHERE `entry` IN (188260,188262,188263,188345,188351,188461,188499,188518,188525,188530,188600,188601,188670,188691,190208,190223,190399,190534,190537,190540,190541,190542,190543,191780,191781,191782,191783); + +UPDATE `creature_addon` SET `auras`='25900 51666 52485' WHERE `guid`=118591; +DELETE FROM `creature_addon` WHERE `guid`=@GUID; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(@GUID,0,0,0,1,0,'25900 52483'); + +DELETE FROM `creature_template_addon` WHERE `entry`=@NPC_QUETZLUN_SPIRIT; +INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(@NPC_QUETZLUN_SPIRIT,0,0,0,1,0,'51126 41408'); + +DELETE FROM `spell_area` WHERE `spell`=52351 AND `area`=4325; +DELETE FROM `spell_area` WHERE `spell`=52484 AND `area`=4323; +INSERT INTO `spell_area` (`spell`,`area`,`quest_start`,`quest_end`,`aura_spell`,`racemask`,`gender`,`autocast`) VALUES +(52351,4325,12675,0,0,0,2,1), +(52484,4323,12685,0,0,0,2,1); + +DELETE FROM `event_scripts` WHERE `id`=18858 AND `command` IN (9,10,15); +INSERT INTO `event_scripts` (`id`,`delay`,`command`,`datalong`,`datalong2`,`dataint`,`x`,`y`,`z`,`o`) VALUES +(18858,0,9,@OGUID+5,30,0,0,0,0,0), +(18858,0,9,@OGUID+6,30,0,0,0,0,0), +(18858,0,9,@OGUID+7,30,0,0,0,0,0), +(18858,0,9,@OGUID+8,30,0,0,0,0,0), +(18858,0,9,@OGUID+9,30,0,0,0,0,0), +(18858,0,10,@NPC_ELM_BUNNY,30000,0,5711.149,-4361.718,387.6694,5.253441), +(18858,0,10,@NPC_ELM_BUNNY,30000,0,5726.004,-4372.459,387.9738,2.775074), +(18858,0,10,@NPC_ELM_BUNNY,30000,0,5707.188,-4371.667,387.4335,3.228859), +(18858,0,10,@NPC_ELM_BUNNY,30000,0,5721.946,-4361.917,387.8101,4.29351), +(18858,0,10,@NPC_ELM_BUNNY,30000,0,5717.041,-4378.735,387.6418,1.570796); + +DELETE FROM `creature_text` WHERE `entry` IN (@NPC_HARKOA,@NPC_QUETZLUN_PROPHET,@NPC_QUETZLUN_SPIRIT); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@NPC_HARKOA,0,0,'$N, please come to me. I''m here in Zim''Torga now.',15,0,100,0,0,0,'Har''koa'), +(@NPC_QUETZLUN_PROPHET,0,0,'What is this you pathetic, little worm? Come to die?',14,0,100,0,0,0,'Prophet of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET,1,0,'I recognize your stench. You''re the one who stealthed by me on the back of that snow leopard runt!',14,0,100,0,0,0,'Prophet of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET,2,0,'What? How is this possible?',14,0,100,0,0,0,'Prophet of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET,3,0,'Wait... STOP! You can''t take back the power!!!',14,0,100,0,0,0,'Prophet of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET,4,0,'NOOOOooooooooooooooooo!',14,0,100,0,0,0,'Prophet of Quetz''lun'), +(@NPC_QUETZLUN_SPIRIT,0,0,'TIME TO DIE, FOOL!',14,0,100,0,0,0,'Spirit of Quetz''lun'), +(@NPC_QUETZLUN_SPIRIT,1,0,'I''ve returned to invite you to my housewarming in the underworld!',14,0,100,0,0,7056,'Spirit of Quetz''lun'), +(@NPC_QUETZLUN_SPIRIT,2,0,'I''d say come along quietly, but we both know that''s not going to happen. My little friend here is going to ease your way into the afterlife.',14,0,100,0,0,0,'Spirit of Quetz''lun'), +(@NPC_QUETZLUN_SPIRIT,3,0,'Well done. I''ll see to it that my prophet enjoys his eternal stay with me.',14,0,100,0,0,0,'Spirit of Quetz''lun'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (52340,52381,52388); +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=@NPC_ELM_BUNNY; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=@NPC_HARKOA; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,52340,0,0,31,0,3,@NPC_ELM_BUNNY,0,0,0,'','Spell Har''koa''s Spirit targets ELM General Purpose Bunny'), +(13,1,52381,0,0,31,0,3,@NPC_QUETZLUN_PROPHET,0,0,0,'','Spell Reclaim Power targets Quetz''lun''s Prophet'), +(13,1,52388,0,0,31,0,3,@NPC_ELM_BUNNY,0,0,0,'','Spell Ritual Bunny Channel targets ELM General Purpose Bunny'), +(22,1,@NPC_ELM_BUNNY,0,0,23,1,4325,0,0,0,0,'','SAI Elm General Purpose Bunny spellcast Ritual Bunny Channel if at Quetz''lun''s Altar'), +(22,14,@NPC_HARKOA,0,0,1,0,52485,0,0,0,0,'','SAI Har''koa custom gossip if player has aura See Har''koa at Zim''Torga'); + +UPDATE `creature_model_info` SET `bounding_radius`=2.38, `combat_reach`=10.5 WHERE `modelid`=25685; +UPDATE `creature_model_info` SET `bounding_radius`=0.4340275, `combat_reach`=1.875 WHERE `modelid`=27857; + +UPDATE `creature_template` SET `gossip_menu_id`=9749, `unit_flags`=33536 WHERE `entry`=@NPC_HARKOA; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (@NPC_KHUFU,@NPC_QUETZLUN_PROPHET,@NPC_DRAINED_PROPHET); +UPDATE `creature_template` SET `unit_flags`=33536, `AIName`='SmartAI' WHERE `entry`=@NPC_QUETZLUN_SPIRIT; + +-- SmartAIs +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@NPC_ELM_BUNNY,@NPC_KHUFU,@NPC_QUETZLUN_PROPHET,@NPC_QUETZLUN_SPIRIT,@NPC_DRAINED_PROPHET) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@NPC_HARKOA AND `source_type`=0 AND `id` BETWEEN 2 AND 15; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@NPC_HARKOA*100,@NPC_QUETZLUN_PROPHET*100,@NPC_QUETZLUN_SPIRIT*100) AND `source_type`=9; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@NPC_ELM_BUNNY,0,0,1,54,0,100,0,0,0,0,0,11,52388,0,0,0,0,0,1,0,0,0,0,0,0,0, 'ELM General Purpose Bunny - Just summoned - Spellcast Ritual Bunny Channel'), +(@NPC_ELM_BUNNY,0,1,0,61,0,100,0,0,0,0,0,45,0,1,0,0,0,0,19,@NPC_QUETZLUN_PROPHET,30,0,0,0,0,0, 'ELM General Purpose Bunny - Just summoned - Set data 0 1 Prophet of Quetz''lun'), + +(@NPC_KHUFU,0,0,1,20,0,100,0,12685,0,0,0,64,1,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Khufu - On quest rewarded - Store targetlist'), +(@NPC_KHUFU,0,1,2,61,0,100,0,0,0,0,0,100,1,0,0,0,0,0,19,@NPC_HARKOA,100,0,0,0,0,0, 'Khufu - On quest rewarded - Send targetlist to Har''koa'), +(@NPC_KHUFU,0,2,0,61,0,100,0,0,0,0,0,45,0,1,0,0,0,0,19,@NPC_HARKOA,100,0,0,0,0,0, 'Khufu - On quest rewarded - Set data 0 1 Har''koa'), + +(@NPC_HARKOA,0,2,3,20,0,100,0,12684,0,0,0,70,30,0,0,0,0,0,14,@OGUID+0,190736,0,0,0,0,0, 'Har''koa - On quest rewarded - Spawn Underworld Fragment'), +(@NPC_HARKOA,0,3,4,61,0,100,0,0,0,0,0,70,30,0,0,0,0,0,14,@OGUID+1,190737,0,0,0,0,0, 'Har''koa - On quest rewarded - Spawn Underworld Fragment'), +(@NPC_HARKOA,0,4,5,61,0,100,0,0,0,0,0,70,30,0,0,0,0,0,14,@OGUID+2,190738,0,0,0,0,0, 'Har''koa - On quest rewarded - Spawn Underworld Fragment'), +(@NPC_HARKOA,0,5,6,61,0,100,0,0,0,0,0,70,30,0,0,0,0,0,14,@OGUID+3,190738,0,0,0,0,0, 'Har''koa - On quest rewarded - Spawn Underworld Fragment'), +(@NPC_HARKOA,0,6,7,61,0,100,0,0,0,0,0,70,30,0,0,0,0,0,14,@OGUID+4,190737,0,0,0,0,0, 'Har''koa - On quest rewarded - Spawn Underworld Fragment'), +(@NPC_HARKOA,0,7,8,61,0,100,0,0,0,0,0,12,@NPC_ELM_BUNNY,3,30000,0,0,0,8,0,0,0,5335.713,-3770.931,373.7013,3.926991, 'Har''koa - On quest rewarded - Spawn Elm General Purpose Bunny'), +(@NPC_HARKOA,0,8,9,61,0,100,0,0,0,0,0,12,@NPC_ELM_BUNNY,3,30000,0,0,0,8,0,0,0,5329.658,-3770.809,372.8022,4.433136, 'Har''koa - On quest rewarded - Spawn Elm General Purpose Bunny'), +(@NPC_HARKOA,0,9,10,61,0,100,0,0,0,0,0,12,@NPC_ELM_BUNNY,3,30000,0,0,0,8,0,0,0,5332.665,-3770.165,373.2305,4.08407, 'Har''koa - On quest rewarded - Spawn Elm General Purpose Bunny'), +(@NPC_HARKOA,0,10,11,61,0,100,0,0,0,0,0,12,@NPC_ELM_BUNNY,3,30000,0,0,0,8,0,0,0,5336.709,-3774.087,372.9049,0, 'Har''koa - On quest rewarded - Spawn Elm General Purpose Bunny'), +(@NPC_HARKOA,0,11,12,61,0,100,0,0,0,0,0,12,@NPC_ELM_BUNNY,3,30000,0,0,0,8,0,0,0,5335.774,-3777.741,373.3314,3.385939, 'Har''koa - On quest rewarded - Spawn Elm General Purpose Bunny'), +(@NPC_HARKOA,0,12,0,61,0,100,0,0,0,0,0,80,@NPC_HARKOA*100,2,0,0,0,0,1,0,0,0,0,0,0,0, 'Har''koa - On quest rewarded - Run script'), +(@NPC_HARKOA,0,13,0,64,0,100,0,0,0,0,0,98,9687,13139,0,0,0,0,7,0,0,0,0,0,0,0, 'Har''koa - On gossip hello - Send custom gossip'), +(@NPC_HARKOA,0,14,15,38,0,100,0,0,1,0,0,1,0,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Har''koa - On data 0 1 set - Say line'), +(@NPC_HARKOA,0,15,0,61,0,100,0,0,0,0,0,45,0,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Har''koa - On data 0 1 set - Reset data'), + +(@NPC_QUETZLUN_PROPHET,0,0,1,38,0,100,1,0,1,0,0,11,52353,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Prophet - On data 0 1 set - Spellcast Script Effect - Creature Capture GUID to Dot Variable'), +(@NPC_QUETZLUN_PROPHET,0,1,2,61,0,100,0,0,0,0,0,64,1,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Prophet - On data 0 1 set - Store targetlist'), +(@NPC_QUETZLUN_PROPHET,0,2,0,61,0,100,0,0,0,0,0,80,@NPC_QUETZLUN_PROPHET*100,2,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Prophet - On data 0 1 set - Run script'), +(@NPC_QUETZLUN_PROPHET,0,3,4,6,0,100,0,0,0,0,0,45,0,1,0,0,0,0,19,@NPC_QUETZLUN_SPIRIT,50,0,0,0,0,0, 'Quetz''lun''s Prophet - On death - Set data 0 1 Spirit of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET,0,4,0,61,0,100,0,0,0,0,0,18,256|64,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Prophet - On death - Set unit_flags IMMUNE_TO_PC and UNK_6'), + +(@NPC_QUETZLUN_SPIRIT,0,0,1,54,0,100,0,0,0,0,0,11,34427,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Spirit - Just summoned - Spellcast Ethereal Teleport'), +(@NPC_QUETZLUN_SPIRIT,0,1,0,61,0,100,0,0,0,0,0,80,@NPC_QUETZLUN_SPIRIT*100,2,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Spirit - Just summoned - Run script'), +(@NPC_QUETZLUN_SPIRIT,0,2,3,38,0,100,0,0,1,0,0,1,3,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Spirit - On data 0 1 set - Say line'), +(@NPC_QUETZLUN_SPIRIT,0,3,0,61,0,100,0,0,0,0,0,41,10000,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Spirit - On data 0 1 set - Despawn after 10 seconds'), + +(@NPC_DRAINED_PROPHET,0,0,0,2,0,100,0,0,70,30000,30000,11,54601,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Drained Prophet - On health below 70% - Spellcast Serpent Form'), + +(@NPC_HARKOA*100,9,0,0,0,0,100,0,18000,18000,0,0,11,52340,0,0,0,0,0,0,0,0,0,0,0,0,0, 'Har''koa script - Spellcast Har''koa''s Spirit'), + +(@NPC_QUETZLUN_PROPHET*100,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Say line'), +(@NPC_QUETZLUN_PROPHET*100,9,1,0,0,0,100,0,5600,5600,0,0,1,1,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Say line'), +(@NPC_QUETZLUN_PROPHET*100,9,2,0,0,0,100,0,6200,6200,0,0,12,@NPC_QUETZLUN_SPIRIT,8,0,0,0,0,8,0,0,0,5716.019,-4371.387,385.8849,4.757225, 'Quetz''lun''s Prophet script 0 - Summon Quetz''lun''s Spirit'), +(@NPC_QUETZLUN_PROPHET*100,9,3,0,0,0,100,0,100,100,0,0,1,2,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Say line'), +(@NPC_QUETZLUN_PROPHET*100,9,4,0,0,0,100,0,15400,15400,0,0,1,3,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Say line'), +(@NPC_QUETZLUN_PROPHET*100,9,5,0,0,0,100,0,5000,5000,0,0,28,53143,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Remove aura Cosmetic Arcane Force Shield'), +(@NPC_QUETZLUN_PROPHET*100,9,6,0,0,0,100,0,100,100,0,0,1,4,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 0 - Say line'), +(@NPC_QUETZLUN_PROPHET*100,9,7,0,0,0,100,0,200,200,0,0,36,28795,1,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 1 - Morph to Drained Prophet of Quetz''lun'), +(@NPC_QUETZLUN_PROPHET*100,9,8,0,0,0,100,0,0,0,0,0,19,256|64,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 1 - Remove unit_flags IMMUNE_TO_PC and UNK_6'), +(@NPC_QUETZLUN_PROPHET*100,9,9,0,0,0,100,0,0,0,0,0,11,52354,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 1 - Spellcast Script Effect - Creature Attack GUID from Dot Variable'), +(@NPC_QUETZLUN_PROPHET*100,9,10,0,0,0,100,0,0,0,0,0,49,0,0,0,0,0,0,12,1,0,0,0,0,0,0, 'Quetz''lun''s Prophet script 1 - Attack'), + +(@NPC_QUETZLUN_SPIRIT*100,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Spirit script - Say line'), +(@NPC_QUETZLUN_SPIRIT*100,9,1,0,0,0,100,0,4800,4800,0,0,1,1,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Spirit script - Say line'), +(@NPC_QUETZLUN_SPIRIT*100,9,2,0,0,0,100,0,8200,8200,0,0,11,52381,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Quetz''lun''s Spirit script - Spellcast Reclaim Power'), +(@NPC_QUETZLUN_SPIRIT*100,9,3,0,0,0,100,0,100,100,0,0,1,2,0,0,0,0,0,21,50,0,0,0,0,0,0, 'Quetz''lun''s Spirit script - Say line'); diff --git a/sql/updates/world/2013_01_09_01_world_lfg_dungeon_rewards.sql b/sql/updates/world/2013_01_09_01_world_lfg_dungeon_rewards.sql new file mode 100644 index 00000000000..dfc5f7cf075 --- /dev/null +++ b/sql/updates/world/2013_01_09_01_world_lfg_dungeon_rewards.sql @@ -0,0 +1,6 @@ +ALTER TABLE `lfg_dungeon_rewards` + DROP `firstMoneyVar`, + DROP `firstXPVar`, + DROP `otherMoneyVar`, + DROP `otherXPVar`; + diff --git a/sql/updates/world/2013_01_09_02_world_sai.sql b/sql/updates/world/2013_01_09_02_world_sai.sql new file mode 100644 index 00000000000..bd164ff4b5e --- /dev/null +++ b/sql/updates/world/2013_01_09_02_world_sai.sql @@ -0,0 +1,18 @@ +-- remove unused waypoint_scripts +DELETE FROM `waypoint_scripts` WHERE `id` IN (380,381,382,383,384); +DELETE FROM `db_script_string` WHERE `entry` IN (2000005237,2000005238,2000005239,2000005240,2000005241); + +-- fix incorrect event 15 parameters for SAI: +UPDATE `smart_scripts` SET `event_param2`=0,`event_param3`=30 WHERE `entryorguid`=9450 AND `source_type`=0 AND `id`=11; +UPDATE `smart_scripts` SET `event_param2`=0,`event_param3`=10 WHERE `entryorguid`=11878 AND `source_type`=0 AND `id`=18; +UPDATE `smart_scripts` SET `event_param2`=0,`event_param3`=15 WHERE `entryorguid`=12339 AND `source_type`=0 AND `id`=4; + +-- update horribad entries for Crimson Hand Blood Knight: +DELETE FROM `smart_scripts` WHERE `entryorguid`=20049; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(20049,0,0,0, 0,0,100,2,5000,5000,25000,50000,11,39077,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - In Combat - Cast Hammer of Justice'), +(20049,0,1,0,12,0,100,2,20,20,15000,15000,11,37259,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - On Target below 20% HP - Cast Hammer of Wrath'), +(20049,0,2,0,14,0,100,2,0,100,35000,35000,11,37257,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - On Friendly Unit At 0 - 100% Health - Cast Flash of Light'), +(20049,0,3,0, 0,0,100,2,60000,60000,120000,160000,11,37257,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - In Combat - Cast Flash of Light'), +(20049,0,4,0,14,0,100,2,50,20,40000,40000,11,37260,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - On Friendly Unit below 50% HP - Cast Renew'), +(20049,0,5,0,15,0,100,2,0,0,15,0,11,39078,0,0,0,0,0,7,0,0,0,0,0,0,0, 'Crimson Hand Blood Knight - On Friendly Unit in CC - Cast Cleanse'); diff --git a/sql/updates/world/2013_01_09_03_world_spell_script_names.sql b/sql/updates/world/2013_01_09_03_world_spell_script_names.sql new file mode 100644 index 00000000000..14d0eb8bfd9 --- /dev/null +++ b/sql/updates/world/2013_01_09_03_world_spell_script_names.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=26192; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(26192, 'spell_skeram_arcane_explosion'); diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 2550f909a8b..9d5d8e40b54 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -188,7 +188,7 @@ void LFGMgr::LoadRewards() RewardMapStore.clear(); // ORDER BY is very important for GetRandomDungeonReward! - QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); + QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, otherQuestId FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); if (!result) { @@ -205,11 +205,7 @@ void LFGMgr::LoadRewards() uint32 dungeonId = fields[0].GetUInt32(); uint32 maxLevel = fields[1].GetUInt8(); uint32 firstQuestId = fields[2].GetUInt32(); - uint32 firstMoneyVar = fields[3].GetUInt32(); - uint32 firstXPVar = fields[4].GetUInt32(); - uint32 otherQuestId = fields[5].GetUInt32(); - uint32 otherMoneyVar = fields[6].GetUInt32(); - uint32 otherXPVar = fields[7].GetUInt32(); + uint32 otherQuestId = fields[3].GetUInt32(); if (!GetLFGDungeon(dungeonId)) { @@ -223,10 +219,10 @@ void LFGMgr::LoadRewards() maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); } - if (firstQuestId && !sObjectMgr->GetQuestTemplate(firstQuestId)) + if (!firstQuestId || !sObjectMgr->GetQuestTemplate(firstQuestId)) { sLog->outError(LOG_FILTER_SQL, "First quest %u specified for dungeon %u in table `lfg_dungeon_rewards` does not exist!", firstQuestId, dungeonId); - firstQuestId = 0; + continue; } if (otherQuestId && !sObjectMgr->GetQuestTemplate(otherQuestId)) @@ -235,9 +231,10 @@ void LFGMgr::LoadRewards() otherQuestId = 0; } - RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar))); + RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, otherQuestId))); ++count; - } while (result->NextRow()); + } + while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg dungeon rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } @@ -434,7 +431,7 @@ void LFGMgr::Update(uint32 diff) } else SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid))); - SendLfgUpdateProposal(guid, m_lfgProposalId, proposal); + SendLfgUpdateProposal(guid, proposal); } if (proposal.state == LFG_PROPOSAL_SUCCESS) @@ -552,27 +549,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const LfgState state = GetState(gguid); if (state == LFG_STATE_QUEUED) { - LfgDungeonSet const& playerDungeons = GetSelectedDungeons(guid); - if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK - { - player->GetSession()->SendLfgJoinResult(joinData); // Default value of joinData.result = LFG_JOIN_OK - if (grp) - { - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, comment); - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) - if (itr->getSource() && itr->getSource()->GetSession()) - itr->getSource()->GetSession()->SendLfgUpdateParty(updateData); - } - else - player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment)); - - return; - } - else // Remove from queue and rejoin - { - LFGQueue& queue = GetQueue(gguid); - queue.RemoveFromQueue(gguid); - } + LFGQueue& queue = GetQueue(gguid); + queue.RemoveFromQueue(gguid); } // Check player or group member restrictions @@ -620,7 +598,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const bool isDungeon = false; for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end() && joinData.result == LFG_JOIN_OK; ++it) { - switch (GetDungeonType(*it)) + LfgType type = GetDungeonType(*it); + switch (type) { case LFG_TYPE_RANDOM: if (dungeons.size() > 1) // Only allow 1 random dungeon @@ -640,6 +619,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const isRaid = true; break; default: + sLog->outError(LOG_FILTER_LFG, "Wrong dungeon type %u for dungeon %u", type, *it); joinData.result = LFG_JOIN_DUNGEON_INVALID; break; } @@ -719,8 +699,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { LfgRolesMap rolesMap; rolesMap[guid] = roles; - LFGQueue& queue = GetQueue(gguid); - queue.AddQueueData(guid, time_t(time(NULL)), dungeons, rolesMap); + LFGQueue& queue = GetQueue(guid); + queue.AddQueueData(guid, time(NULL), dungeons, rolesMap); if (!isContinue) { @@ -873,7 +853,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* { uint64 pguid = it->first; - if (!sendRoleChosen) + if (sendRoleChosen) SendLfgRoleChosen(pguid, guid, roles); SendLfgRoleCheckUpdate(pguid, roleCheck); @@ -916,7 +896,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* @param[in] players Set of players to check their dungeon restrictions @param[out] lockMap Map of players Lock status info of given dungeons (Empty if dungeons is not empty) */ -void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, const LfgGuidSet& players, LfgLockPartyMap& lockMap) +void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap) { lockMap.clear(); for (LfgGuidSet::const_iterator it = players.begin(); it != players.end() && !dungeons.empty(); ++it) @@ -1083,9 +1063,10 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal) grp->SendUpdate(); } -uint32 LFGMgr::AddProposal(LfgProposal const& proposal) +uint32 LFGMgr::AddProposal(LfgProposal& proposal) { - ProposalsStore[++m_lfgProposalId] = proposal; + proposal.id = ++m_lfgProposalId; + ProposalsStore[m_lfgProposalId] = proposal; return m_lfgProposalId; } @@ -1129,16 +1110,14 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) if (!allAnswered) { for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) - { - uint64 guid = it->first; - SendLfgUpdateProposal(guid, proposalId, proposal); - } + SendLfgUpdateProposal(it->first, proposal); + return; } bool sendUpdate = proposal.state != LFG_PROPOSAL_SUCCESS; proposal.state = LFG_PROPOSAL_SUCCESS; - time_t joinTime = time_t(time(NULL)); + time_t joinTime = time(NULL); LFGQueue& queue = GetQueue(guid); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); @@ -1149,7 +1128,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) uint32 dungeonId = (*GetSelectedDungeons(pguid).begin()); int32 waitTime = -1; if (sendUpdate) - SendLfgUpdateProposal(pguid, proposalId, proposal); + SendLfgUpdateProposal(pguid, proposal); if (gguid) { @@ -1236,7 +1215,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate uint64 guid = it->first; uint64 gguid = it->second.group ? it->second.group : guid; - SendLfgUpdateProposal(guid, itProposal->first, proposal); + SendLfgUpdateProposal(guid, proposal); if (toRemove.find(gguid) != toRemove.end()) // Didn't accept or in same group that someone that didn't accept { @@ -1465,106 +1444,126 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* } } - if (error == LFG_TELEPORTERROR_OK) - { - if (!player->GetMap()->IsDungeon()) - player->SetBattlegroundEntryPoint(); - - if (player->isInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->CleanupAfterTaxiFlight(); - } + if (!player->GetMap()->IsDungeon()) + player->SetBattlegroundEntryPoint(); - if (!player->TeleportTo(mapid, x, y, z, orientation)) - { - error = LFG_TELEPORTERROR_INVALID_LOCATION; - sLog->outError(LOG_FILTER_LFG, "TeleportPlayer: Failed to teleport [" UI64FMTD "] to map %u (x: %f, y: %f, z: %f)", player->GetGUID(), mapid, x, y, z); - } + if (player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); } + + if (!player->TeleportTo(mapid, x, y, z, orientation)) + error = LFG_TELEPORTERROR_INVALID_LOCATION; } + else + error = LFG_TELEPORTERROR_INVALID_LOCATION; if (error != LFG_TELEPORTERROR_OK) player->GetSession()->SendLfgTeleportError(uint8(error)); - sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in. Result: %u", - player->GetName().c_str(), error); + sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in to map %u " + "(x: %f, y: %f, z: %f) Result: %u", player->GetName().c_str(), dungeon->map, + dungeon->x, dungeon->y, dungeon->z, error); } /** - Give completion reward to player + Finish a dungeon and give reward, if any. - @param[in] dungeonId Id of the dungeon finished - @param[in] player Player to reward + @param[in] guid Group guid + @param[in] dungeonId Dungeonid */ -void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) +void LFGMgr::FinishDungeon(uint64 gguid, const uint32 dungeonId) { - Group* group = player->GetGroup(); - if (!group || !group->isLFGGroup()) - { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] is not in a group or not a LFGGroup. Ignoring", player->GetGUID()); - return; - } - - uint64 guid = player->GetGUID(); - uint64 gguid = player->GetGroup()->GetGUID(); uint32 gDungeonId = GetDungeon(gguid); if (gDungeonId != dungeonId) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", guid, dungeonId, gDungeonId); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", gguid, dungeonId, gDungeonId); return; } - if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded group. Ignoring", gguid); return; } - // Mark dungeon as finished SetState(gguid, LFG_STATE_FINISHED_DUNGEON); - // Clear player related lfg stuff - uint32 rDungeonId = (*GetSelectedDungeons(guid).begin()); - SetState(guid, LFG_STATE_FINISHED_DUNGEON); - - // Give rewards only if its a random or seasonal dungeon - LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + const LfgGuidSet& players = GetPlayers(gguid); + for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random nor seasonal", guid, rDungeonId); - return; - } + uint64 guid = (*it); + if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + continue; + } - // Update achievements - if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + uint32 rDungeonId = 0; + const LfgDungeonSet& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + rDungeonId = (*dungeons.begin()); - LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); - if (!reward) - return; + SetState(guid, LFG_STATE_FINISHED_DUNGEON); - uint8 index = 0; - Quest const* qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; + // Give rewards only if its a random dungeon + LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. - if (player->CanRewardQuest(qReward, false)) - player->RewardQuest(qReward, 0, NULL, false); - else - { - index = 1; - qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; - // we give reward without informing client (retail does this) - player->RewardQuest(qReward, 0, NULL, false); - } + if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] dungeon %u is not random or seasonal", guid, rDungeonId); + continue; + } + + Player* player = ObjectAccessor::FindPlayer(guid); + if (!player || !player->IsInWorld()) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] not found in world", guid); + continue; + } + + LFGDungeonData const* dungeonDone = GetLFGDungeon(dungeonId); + uint32 mapId = dungeonDone ? uint32(dungeonDone->map) : 0; - // Give rewards - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), index > 0 ? " " : " not"); - player->GetSession()->SendLfgPlayerReward(dungeon->Entry(), GetDungeon(gguid, false), index, reward, qReward); + if (player->GetMapId() != mapId) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] is in map %u and should be in %u to get reward", guid, player->GetMapId(), mapId); + continue; + } + + // Update achievements + if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + + LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); + if (!reward) + continue; + + bool done = false; + Quest const* quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); + if (!quest) + continue; + + // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. + if (player->CanRewardQuest(quest, false)) + player->RewardQuest(quest, 0, NULL, false); + else + { + done = true; + quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); + if (!quest) + continue; + // we give reward without informing client (retail does this) + player->RewardQuest(quest, 0, NULL, false); + } + + // Give rewards + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), done? " " : " not"); + LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest); + player->GetSession()->SendLfgPlayerReward(data); + } + SetDungeon(gguid, 0); } // --------------------------------------------------------------------------// @@ -1577,7 +1576,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) @param[in] randomdungeon Random dungeon id (if value = 0 will return all dungeons) @returns Set of dungeons that can be done. */ -const LfgDungeonSet& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) +LfgDungeonSet const& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) { LFGDungeonData const* dungeon = GetLFGDungeon(randomdungeon); uint32 group = dungeon ? dungeon->group : 0; @@ -1675,13 +1674,13 @@ bool LFGMgr::IsTeleported(uint64 pguid) return false; } -const LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64 guid) +LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetSelectedDungeons(); } -const LfgLockMap& LFGMgr::GetLockedDungeons(uint64 guid) +LfgLockMap const& LFGMgr::GetLockedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetLockedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetLockedDungeons(); @@ -1728,7 +1727,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) if (IS_GROUP_GUID(guid)) { LfgGroupData& data = GroupsStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1741,7 +1740,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) else { LfgPlayerData& data = PlayersStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1765,19 +1764,19 @@ void LFGMgr::SetRoles(uint64 guid, uint8 roles) PlayersStore[guid].SetRoles(roles); } -void LFGMgr::SetComment(uint64 guid, const std::string& comment) +void LFGMgr::SetComment(uint64 guid, std::string const& comment) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetComment: [" UI64FMTD "] comment: %s", guid, comment.c_str()); PlayersStore[guid].SetComment(comment); } -void LFGMgr::SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons) +void LFGMgr::SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons) { - sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "]", guid); + sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "] Dungeons: %s", guid, ConcatenateDungeons(dungeons).c_str()); PlayersStore[guid].SetSelectedDungeons(dungeons); } -void LFGMgr::SetLockedDungeons(uint64 guid, const LfgLockMap& lock) +void LFGMgr::SetLockedDungeons(uint64 guid, LfgLockMap const& lock) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetLockedDungeons: [" UI64FMTD "]", guid); PlayersStore[guid].SetLockedDungeons(lock); @@ -1918,10 +1917,10 @@ void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot) player->GetSession()->SendLfgBootProposalUpdate(boot); } -void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal) +void LFGMgr::SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendLfgUpdateProposal(proposalId, proposal); + player->GetSession()->SendLfgUpdateProposal(proposal); } void LFGMgr::SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data) @@ -1940,7 +1939,7 @@ LFGQueue& LFGMgr::GetQueue(uint64 guid) uint8 queueId = 0; if (IS_GROUP_GUID(guid)) { - const LfgGuidSet& players = GetPlayers(guid); + LfgGuidSet const& players = GetPlayers(guid); uint64 pguid = players.empty() ? 0 : (*players.begin()); if (pguid) queueId = GetTeam(pguid); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 2041c18a081..0a1b90ee04d 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -28,6 +28,7 @@ class Group; class Player; +class Quest; enum LfgOptions { @@ -37,9 +38,9 @@ enum LfgOptions enum LFGMgrEnum { - LFG_TIME_ROLECHECK = 40 * IN_MILLISECONDS, + LFG_TIME_ROLECHECK = 45 * IN_MILLISECONDS, LFG_TIME_BOOT = 120, - LFG_TIME_PROPOSAL = 120, + LFG_TIME_PROPOSAL = 45, LFG_QUEUEUPDATE_INTERVAL = 15 * IN_MILLISECONDS, LFG_SPELL_DUNGEON_COOLDOWN = 71328, LFG_SPELL_DUNGEON_DESERTER = 71041, @@ -188,27 +189,25 @@ struct LfgQueueStatusData uint8 dps; }; +struct LfgPlayerRewardData +{ + LfgPlayerRewardData(uint32 random, uint32 current, bool _done, Quest const* _quest): + rdungeonEntry(random), sdungeonEntry(current), done(_done), quest(_quest) { } + uint32 rdungeonEntry; + uint32 sdungeonEntry; + bool done; + Quest const* quest; +}; + /// Reward info struct LfgReward { + LfgReward(uint32 _maxLevel = 0, uint32 _firstQuest = 0, uint32 _otherQuest = 0): + maxLevel(_maxLevel), firstQuest(_firstQuest), otherQuest(_otherQuest) { } + uint32 maxLevel; - struct - { - uint32 questId; - uint32 variableMoney; - uint32 variableXP; - } reward[2]; - - LfgReward(uint32 _maxLevel = 0, uint32 firstQuest = 0, uint32 firstVarMoney = 0, uint32 firstVarXp = 0, uint32 otherQuest = 0, uint32 otherVarMoney = 0, uint32 otherVarXp = 0) - : maxLevel(_maxLevel) - { - reward[0].questId = firstQuest; - reward[0].variableMoney = firstVarMoney; - reward[0].variableXP = firstVarXp; - reward[1].questId = otherQuest; - reward[1].variableMoney = otherVarMoney; - reward[1].variableXP = otherVarXp; - } + uint32 firstQuest; + uint32 otherQuest; }; /// Stores player data related to proposal to join @@ -223,10 +222,11 @@ struct LfgProposalPlayer /// Stores group data related to proposal to join struct LfgProposal { - LfgProposal(uint32 dungeon = 0): dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), + LfgProposal(uint32 dungeon = 0): id(0), dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), group(0), leader(0), cancelTime(0), encounters(0), isNew(true) { } + uint32 id; ///< Proposal Id uint32 dungeonId; ///< Dungeon to join LfgProposalState state; ///< State of the proposal uint64 group; ///< Proposal group (0 if new) @@ -235,7 +235,8 @@ struct LfgProposal uint32 encounters; ///< Dungeon Encounters bool isNew; ///< Determines if it's new group or not LfgGuidList queues; ///< Queue Ids to remove/readd - LfgProposalPlayerContainer players; ///< Players data + LfgGuidList showorder; ///< Show order in update window + LfgProposalPlayerContainer players; ///< Players data }; /// Stores all rolecheck info of a group that wants to join @@ -299,7 +300,7 @@ class LFGMgr // Reward void LoadRewards(); - void RewardDungeonDoneFor(uint32 const dungeonId, Player* player); + void FinishDungeon(uint64 gguid, uint32 dungeonId); LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); // Queue @@ -314,7 +315,7 @@ class LFGMgr void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); // Proposals - uint32 AddProposal(LfgProposal const& proposal); + uint32 AddProposal(LfgProposal& proposal); void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); // Teleportation @@ -403,7 +404,7 @@ class LFGMgr 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); + void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal); // General variables uint32 m_QueueTimer; ///< used to check interval of update diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp index 0a7f812d03a..410076f7e75 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.cpp +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -113,12 +113,12 @@ uint8 LfgPlayerData::GetRoles() const return m_Roles; } -const std::string& LfgPlayerData::GetComment() const +std::string const& LfgPlayerData::GetComment() const { return m_Comment; } -const LfgDungeonSet& LfgPlayerData::GetSelectedDungeons() const +LfgDungeonSet const& LfgPlayerData::GetSelectedDungeons() const { return m_SelectedDungeons; } diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index dae789b2eb4..e75a1bdc4b3 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -139,7 +139,7 @@ void LFGQueue::RemoveFromCurrentQueue(uint64 guid) currentQueueStore.remove(guid); } -void LFGQueue::AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap) +void LFGQueue::AddQueueData(uint64 guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap) { QueueDataStore[guid] = LfgQueueData(joinTime, dungeons, rolesMap); AddToQueue(guid); @@ -217,7 +217,6 @@ void LFGQueue::SetCompatibilityData(std::string const& key, LfgCompatibilityData CompatibleMapStore[key] = data; } - /** Get the compatibility of a group of guids @@ -482,8 +481,9 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } + uint64 gguid = *check.begin(); proposal.queues = check; - proposal.isNew = numLfgGroups != 1; + proposal.isNew = numLfgGroups != 1 || !sLFGMgr->GetDungeon(gguid); if (!sLFGMgr->AllQueued(check)) { diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index a8b41c39ab0..acb78d2c0f2 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -52,7 +52,7 @@ struct LfgQueueData healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) { } - LfgQueueData(time_t _joinTime, const LfgDungeonSet &_dungeons, LfgRolesMap const& _roles): + LfgQueueData(time_t _joinTime, LfgDungeonSet const& _dungeons, LfgRolesMap const& _roles): joinTime(_joinTime), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED), dungeons(_dungeons), roles(_roles) { } @@ -87,7 +87,7 @@ class LFGQueue // 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 AddQueueData(uint64 guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap); void RemoveQueueData(uint64 guid); // Update Timers (when proposal success) diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 39750536863..568b61eef2f 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -107,20 +107,10 @@ void LFGGroupScript::OnAddMember(Group* group, uint64 guid) 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_UPDATE_STATUS); - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - if (Player* plrg = itr->getSource()) - { - plrg->GetSession()->SendLfgUpdatePlayer(updateData); - plrg->GetSession()->SendLfgUpdateParty(updateData); - } - } if (state == LFG_STATE_QUEUED) sLFGMgr->LeaveLfg(guid); - // 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); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index aadbf245243..a7df171b1c5 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -499,7 +499,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } } -void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recvData) +void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index a6f89f353a0..0654ae326f9 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,7 +23,7 @@ #include "WorldPacket.h" #include "WorldSession.h" -void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock) +void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) { data << uint32(lock.size()); // Size of lock dungeons for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) @@ -54,7 +54,6 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) } uint8 numDungeons; - uint32 dungeon; uint32 roles; recvData >> roles; @@ -70,6 +69,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { + uint32 dungeon; recvData >> dungeon; newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry } @@ -80,20 +80,21 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) recvData >> comment; sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s", GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str()); + sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment); } void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recvData*/) { - Group* grp = GetPlayer()->GetGroup(); + Group* group = GetPlayer()->GetGroup(); uint64 guid = GetPlayer()->GetGUID(); - uint64 gguid = grp ? grp->GetGUID() : guid; + uint64 gguid = group ? group->GetGUID() : guid; sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LEAVE %s in group: %u", - GetPlayerInfo().c_str(), grp ? 1 : 0); + GetPlayerInfo().c_str(), group ? 1 : 0); // Check cheating - only leader can leave the queue - if (!grp || grp->GetLeaderGUID() == GetPlayer()->GetGUID()) + if (!group || group->GetLeaderGUID() == GetPlayer()->GetGUID()) sLFGMgr->LeaveLfg(gguid); } @@ -114,14 +115,14 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData) uint8 roles; recvData >> roles; // Player Group Roles uint64 guid = GetPlayer()->GetGUID(); - Group* grp = GetPlayer()->GetGroup(); - if (!grp) + Group* group = GetPlayer()->GetGroup(); + if (!group) { sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES %s Not in group", GetPlayerInfo().c_str()); return; } - uint64 gguid = grp->GetGUID(); + uint64 gguid = group->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u", GUID_LOPART(gguid), GetPlayerInfo().c_str(), roles); sLFGMgr->UpdateRoleCheck(gguid, guid, roles); @@ -131,11 +132,11 @@ void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recvData) { std::string comment; recvData >> comment; - uint64 guid = GetPlayer()->GetGUID(); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_COMMENT %s comment: %s", GetPlayerInfo().c_str(), comment.c_str()); - sLFGMgr->SetComment(guid, comment); + sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment); } void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recvData) @@ -193,15 +194,15 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; - uint8 done = 0; + bool done = false; if (reward) { - quest = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); + quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); if (quest) { done = !GetPlayer()->CanRewardQuest(quest, false); if (done) - quest = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); + quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); } } @@ -210,8 +211,8 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* data << uint8(done); data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->XPValue(GetPlayer())); - data << uint32(reward->reward[done].variableMoney); - data << uint32(reward->reward[done].variableXP); + data << uint32(0); + data << uint32(0); data << uint8(quest->GetRewItemsCount()); if (quest->GetRewItemsCount()) { @@ -244,13 +245,13 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST %s", GetPlayerInfo().c_str()); - Group* grp = GetPlayer()->GetGroup(); - if (!grp) + Group* group = GetPlayer()->GetGroup(); + if (!group) return; // Get the locked dungeons of the other party members LfgLockPartyMap lockMap; - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); if (!plrg) @@ -312,7 +313,7 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) } } -void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData) +void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) { bool queued = false; uint8 size = uint8(updateData.dungeons.size()); @@ -457,7 +458,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) SendPacket(&data); } -void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) +void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) { uint32 size = 0; for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) @@ -465,6 +466,7 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u", GetPlayerInfo().c_str(), joinData.result, joinData.state); + WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size); data << uint32(joinData.result); // Check Result data << uint32(joinData.state); // Check Value @@ -473,10 +475,14 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) +void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) { - sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", - GetPlayerInfo().c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " + "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " + "queuedTime: %u, tanks: %u, healers: %u, dps: %u", + GetPlayerInfo().c_str(), 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(queueData.dungeonId); // Dungeon @@ -492,40 +498,41 @@ void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* quest) +void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) { - if (!rdungeonEntry || !sdungeonEntry || !quest) + if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest) return; - uint8 itemNum = uint8(quest ? quest->GetRewItemsCount() : 0); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u, sdungeonEntry: %u, done: %u", + GetPlayerInfo().c_str(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done); + + uint8 itemNum = rewardData.quest->GetRewItemsCount(); - sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u - sdungeonEntry: %u - done: %u", - GetPlayerInfo().c_str(), rdungeonEntry, sdungeonEntry, done); WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4)); - data << uint32(rdungeonEntry); // Random Dungeon Finished - data << uint32(sdungeonEntry); // Dungeon Finished - data << uint8(done); + data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished + data << uint32(rewardData.sdungeonEntry); // Dungeon Finished + data << uint8(rewardData.done); data << uint32(1); - data << uint32(quest->GetRewOrReqMoney()); - data << uint32(quest->XPValue(GetPlayer())); - data << uint32(reward->reward[done].variableMoney); - data << uint32(reward->reward[done].variableXP); + data << uint32(rewardData.quest->GetRewOrReqMoney()); + data << uint32(rewardData.quest->XPValue(GetPlayer())); + data << uint32(0); + data << uint32(0); data << uint8(itemNum); if (itemNum) { for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) - if (uint32 itemId = quest->RewardItemId[i]) + if (uint32 itemId = rewardData.quest->RewardItemId[i]) { ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); data << uint32(itemId); data << uint32(item ? item->DisplayInfoID : 0); - data << uint32(quest->RewardItemIdCount[i]); + data << uint32(rewardData.quest->RewardItemIdCount[i]); } } SendPacket(&data); } -void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) +void WorldSession::SendLfgBootProposalUpdate(LfgPlayerBoot const& boot) { uint64 guid = GetPlayer()->GetGUID(); LfgAnswer playerVote = boot.votes.find(guid)->second; @@ -560,7 +567,7 @@ void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& proposal) +void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) { uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = proposal.players.find(guid)->second.group; @@ -569,7 +576,6 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PROPOSAL_UPDATE %s state: %u", GetPlayerInfo().c_str(), 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) @@ -582,9 +588,10 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) dungeonEntry = dungeon->Entry(); + WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeonEntry); // Dungeon data << uint8(proposal.state); // Proposal state - data << uint32(proposalId); // Proposal ID + data << uint32(proposal.id); // Proposal ID data << uint32(proposal.encounters); // encounters done data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 3deec5a880a..bfd9bd62647 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -20,6 +20,7 @@ #include "CreatureAI.h" #include "DatabaseEnv.h" #include "GameObject.h" +#include "Group.h" #include "InstanceScript.h" #include "LFGMgr.h" #include "Log.h" @@ -422,28 +423,41 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 instance->SendToPlayers(&data); } -void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source) +void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* /*source*/) { DungeonEncounterList const* encounters = sObjectMgr->GetDungeonEncounterList(instance->GetId(), instance->GetDifficulty()); if (!encounters) return; + uint32 dungeonId = 0; + for (DungeonEncounterList::const_iterator itr = encounters->begin(); itr != encounters->end(); ++itr) { - if ((*itr)->creditType == type && (*itr)->creditEntry == creditEntry) + DungeonEncounter const* encounter = *itr; + if (encounter->creditType == type && encounter->creditEntry == creditEntry) { - completedEncounters |= 1 << (*itr)->dbcEntry->encounterIndex; - sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName[0]); - if (uint32 dungeonId = (*itr)->lastEncounterDungeon) + completedEncounters |= 1 << encounter->dbcEntry->encounterIndex; + if (encounter->lastEncounterDungeon) { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->getSource()) - if (!source || player->IsAtGroupRewardDistance(source)) - sLFGMgr->RewardDungeonDoneFor(dungeonId, player); + dungeonId = encounter->lastEncounterDungeon; + sLog->outDebug(LOG_FILTER_LFG, "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u", instance->GetMapName(), instance->GetInstanceId(), encounter->dbcEntry->encounterName[0], dungeonId); + break; } - return; + } + } + + if (dungeonId) + { + Map::PlayerList const& players = instance->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if (Player* player = i->getSource()) + if (Group* grp = player->GetGroup()) + if (grp->isLFGGroup()) + { + sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId); + return; + } } } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 468fe769857..7237d5f74f7 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -763,7 +763,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode }, - /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveBattlefieldOpcode }, + /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldLeaveOpcode }, /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 5561834303d..39f5425d9df 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -53,7 +53,7 @@ struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; struct LfgQueueStatusData; -struct LfgReward; +struct LfgPlayerRewardData; struct LfgRoleCheck; struct LfgUpdateData; struct MovementInfo; @@ -270,7 +270,7 @@ class WorldSession void SendAttackStop(Unit const* enemy); - void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId); + void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB); void SendTradeStatus(TradeStatus status); void SendUpdateTrade(bool trader_data = true); @@ -327,7 +327,7 @@ class WorldSession void SendDiscoverNewTaxiNode(uint32 nodeid); // Guild/Arena Team - void SendArenaTeamCommandResult(uint32 team_action, std::string const& team, std::string const& player, uint32 error_id); + void SendArenaTeamCommandResult(uint32 team_action, std::string const& team, std::string const& player, uint32 error_id = 0); void SendNotInArenaTeamPacket(uint8 type); void SendPetitionShowList(uint64 guid); @@ -741,7 +741,7 @@ class WorldSession void HandlePVPLogDataOpcode(WorldPacket& recvData); void HandleBattleFieldPortOpcode(WorldPacket& recvData); void HandleBattlefieldListOpcode(WorldPacket& recvData); - void HandleLeaveBattlefieldOpcode(WorldPacket& recvData); + void HandleBattlefieldLeaveOpcode(WorldPacket& recvData); void HandleBattlemasterJoinArena(WorldPacket& recvData); void HandleReportPvPAFK(WorldPacket& recvData); @@ -762,14 +762,14 @@ class WorldSession void HandleInstanceLockResponse(WorldPacket& recvPacket); // Battlefield - void SendBfInvitePlayerToWar(uint32 BattleId,uint32 ZoneId,uint32 time); - void SendBfInvitePlayerToQueue(uint32 BattleId); - void SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue = true, bool Full = false); - void SendBfEntered(uint32 BattleId); - void SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); - void HandleBfQueueInviteResponse(WorldPacket &recvData); - void HandleBfEntryInviteResponse(WorldPacket &recvData); - void HandleBfExitRequest(WorldPacket &recvData); + void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time); + void SendBfInvitePlayerToQueue(uint32 battleId); + void SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue = true, bool full = false); + void SendBfEntered(uint32 battleId); + void SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); + void HandleBfQueueInviteResponse(WorldPacket& recvData); + void HandleBfEntryInviteResponse(WorldPacket& recvData); + void HandleBfExitRequest(WorldPacket& recvData); // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket& recvData); @@ -785,16 +785,16 @@ class WorldSession void HandleLfrLeaveOpcode(WorldPacket& recvData); void HandleLfgGetStatus(WorldPacket& recvData); - void SendLfgUpdatePlayer(const LfgUpdateData& updateData); - void SendLfgUpdateParty(const LfgUpdateData& updateData); + void SendLfgUpdatePlayer(LfgUpdateData const& updateData); + void SendLfgUpdateParty(LfgUpdateData const& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(const LfgRoleCheck& pRoleCheck); + void SendLfgRoleCheckUpdate(LfgRoleCheck const& pRoleCheck); void SendLfgLfrList(bool update); - void SendLfgJoinResult(const LfgJoinResultData& joinData); - void SendLfgQueueStatus(const LfgQueueStatusData& queueData); - void SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest *qRew); - void SendLfgBootProposalUpdate(const LfgPlayerBoot& boot); - void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal& proposal); + void SendLfgJoinResult(LfgJoinResultData const& joinData); + void SendLfgQueueStatus(LfgQueueStatusData const& queueData); + void SendLfgPlayerReward(LfgPlayerRewardData const& lfgPlayerRewardData); + void SendLfgBootProposalUpdate(LfgPlayerBoot const& boot); + void SendLfgUpdateProposal(LfgProposal const& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 6733200e44d..4927666073b 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -29,6 +29,7 @@ EndScriptData */ #include "scarlet_monastery.h" #include "LFGMgr.h" #include "Player.h" +#include "Group.h" #include "SpellInfo.h" //this texts are already used by 3975 and 3976 @@ -576,10 +577,7 @@ public: Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (!players.isEmpty()) - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->getSource()) - if (player->IsAtGroupRewardDistance(me)) - sLFGMgr->RewardDungeonDoneFor(285, player); + sLFGMgr->FinishDungeon(players.begin()->getSource()->GetGroup()->GetGUID(), 285); } void SpellHit(Unit* caster, const SpellInfo* spell) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 32d4c621450..ba554c3703d 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -29,7 +29,7 @@ enum Yells SAY_KILL_PLAYER = 6 }; -enum eAIs +enum AIs { AI_MELEE = 0, AI_RANGED = 1, @@ -1484,8 +1484,11 @@ class mob_toc_hunter : public CreatureScript events.ScheduleEvent(EVENT_STEADY_SHOT, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS)); return; case EVENT_WING_CLIP: - if (me->GetDistance2d(me->getVictim()) < 6.0f) - DoCastVictim(SPELL_WING_CLIP); + if (Unit* target = me->getVictim()) + { + if (me->GetDistance2d(target) < 6.0f) + DoCast(target, SPELL_WING_CLIP); + } events.ScheduleEvent(EVENT_WING_CLIP, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS)); return; case EVENT_WYVERN_STING: @@ -1670,13 +1673,16 @@ class mob_toc_warrior : public CreatureScript events.ScheduleEvent(EVENT_SUNDER_ARMOR, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS)); return; case EVENT_SHATTERING_THROW: - if (me->getVictim()->HasAuraWithMechanic(1<<MECHANIC_IMMUNE_SHIELD)) + if (Unit* target = me->getVictim()) { - DoCastVictim(SPELL_SHATTERING_THROW); - events.RescheduleEvent(EVENT_SHATTERING_THROW, 5*MINUTE*IN_MILLISECONDS); + if (target->HasAuraWithMechanic(1 << MECHANIC_IMMUNE_SHIELD)) + { + DoCast(target, SPELL_SHATTERING_THROW); + events.RescheduleEvent(EVENT_SHATTERING_THROW, 5*MINUTE*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_SHATTERING_THROW, 3*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_SHATTERING_THROW, 3*IN_MILLISECONDS); return; case EVENT_RETALIATION: if (HealthBelowPct(50)) @@ -1746,13 +1752,16 @@ class mob_toc_dk : public CreatureScript events.ScheduleEvent(EVENT_DEATH_COIL, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS)); return; case EVENT_DEATH_GRIP: - if (me->IsInRange(me->getVictim(), 5.0f, 30.0f, false)) + if (Unit* target = me->getVictim()) { - DoCast(me->getVictim(), SPELL_DEATH_GRIP); - events.RescheduleEvent(EVENT_DEATH_GRIP, 35*IN_MILLISECONDS); + if (me->IsInRange(target, 5.0f, 30.0f, false)) + { + DoCast(target, SPELL_DEATH_GRIP); + events.RescheduleEvent(EVENT_DEATH_GRIP, 35*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_DEATH_GRIP, 3*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_DEATH_GRIP, 3*IN_MILLISECONDS); return; case EVENT_FROST_STRIKE: DoCastVictim(SPELL_FROST_STRIKE); @@ -1862,13 +1871,16 @@ class mob_toc_rogue : public CreatureScript events.RescheduleEvent(EVENT_BLADE_FLURRY, 5*IN_MILLISECONDS); return; case EVENT_SHADOWSTEP: - if (me->IsInRange(me->getVictim(), 10.0f, 40.0f, false)) + if (Unit* target = me->getVictim()) { - DoCast(me->getVictim(), SPELL_SHADOWSTEP); - events.RescheduleEvent(EVENT_SHADOWSTEP, 30*IN_MILLISECONDS); + if (me->IsInRange(target, 10.0f, 40.0f, false)) + { + DoCast(target, SPELL_SHADOWSTEP); + events.RescheduleEvent(EVENT_SHADOWSTEP, 30*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_SHADOWSTEP, 5*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_SHADOWSTEP, 5*IN_MILLISECONDS); return; case EVENT_HEMORRHAGE: DoCastVictim(SPELL_HEMORRHAGE); |