Merge branch 'master' into 4.x and some warning fixes

This commit is contained in:
Spp
2011-12-27 10:15:27 +01:00
148 changed files with 2881 additions and 969 deletions
+7 -7
View File
@@ -23,23 +23,23 @@
namespace G3D {
void logPrintf(const char* fmt, ...) {
va_list arg_list;
va_start(arg_list, fmt);
va_list arg_list;
va_start(arg_list, fmt);
Log::common()->vprintf(fmt, arg_list);
va_end(arg_list);
}
void logLazyPrintf(const char* fmt, ...) {
va_list arg_list;
va_start(arg_list, fmt);
va_list arg_list;
va_start(arg_list, fmt);
Log::common()->lazyvprintf(fmt, arg_list);
va_end(arg_list);
}
Log* Log::commonLog = NULL;
Log::Log(const std::string& filename, int stripFromStackBottom) :
Log::Log(const std::string& filename, int stripFromStackBottom) :
stripFromStackBottom(stripFromStackBottom) {
this->filename = filename;
@@ -50,7 +50,7 @@ Log::Log(const std::string& filename, int stripFromStackBottom) :
std::string drive, base, ext;
Array<std::string> path;
parseFilename(filename, drive, path, base, ext);
std::string logName = base + ((ext != "") ? ("." + ext) : "");
std::string logName = base + ((ext != "") ? ("." + ext) : "");
// Write time is greater than 1ms. This may be a network drive.... try another file.
#ifdef G3D_WIN32
@@ -80,7 +80,7 @@ Log::Log(const std::string& filename, int stripFromStackBottom) :
Log::~Log() {
section("Shutdown");
println("Closing log file");
// Make sure we don't leave a dangling pointer
if (Log::commonLog == this) {
Log::commonLog = NULL;
@@ -3,4 +3,4 @@ INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`pr
(28012,0,0,'The trickster Mage-Lord Urom protects the third ring. He will appear alone and defenseless, but do not be fooled by appearences! Urom is a powerful conjurer who commands a menagerie of Phantasmal creatures. Seek him out above.',12,0,0,0,0,0,''),
(28012,1,1,'Your greatest challenge lies ahead. Ley-Guardian Eregos is a Blue dragon of immense power. You will find him flying above the uppermost ring.',12,0,0,0,0,0,'');
UPDATE `creature_template` SET `ScriptName`='npc_image_belgaristrasz' WHERE `entry`=28012;
UPDATE `creature_template` SET `ScriptName`='npc_image_belgaristrasz' WHERE `entry`=28012;
@@ -9,4 +9,4 @@ INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,
(7178,5,49346,1,''), -- Emerald Drake
(7178,12,1,0, ''), -- hc mode only
(7179,5,49464,1,''), -- Ruby Drake
(7179,12,1,0, ''); -- hc mode only
(7179,12,1,0, ''); -- hc mode only
@@ -1,2 +1,2 @@
-- Fix speed of oculus drakes
UPDATE `creature_template_addon` SET `auras`='50325' WHERE `entry` IN (27755,27692,27756);
UPDATE `creature_template_addon` SET `auras`='50325' WHERE `entry` IN (27755,27692,27756);
@@ -1 +1 @@
UPDATE `gameobject_template` SET `scriptName` = 'go_ethereal_teleport_pad' WHERE `entry` = 184073; -- Update Ethereal Teleport Pad scriptname
UPDATE `gameobject_template` SET `scriptName` = 'go_ethereal_teleport_pad' WHERE `entry` = 184073; -- Update Ethereal Teleport Pad scriptname
@@ -1,4 +1,4 @@
-- Greater Fire Elemental script
UPDATE `creature_template` SET `ScriptName`='npc_fire_elemental' WHERE `entry`=15438;
-- Greater Earth Elemental script
UPDATE `creature_template` SET `ScriptName`='npc_earth_elemental' WHERE `entry`=15352;
UPDATE `creature_template` SET `ScriptName`='npc_earth_elemental' WHERE `entry`=15352;
@@ -2,4 +2,4 @@
DELETE FROM `spell_bonus_data` WHERE `entry` IN (13376,57984);
INSERT INTO `spell_bonus_data` (`entry`, `direct_bonus`, `dot_bonus`,`ap_bonus`, `ap_dot_bonus`, `comments`) VALUES
(13376,0.032,-1,-1,-1,'Greater Fire Elemental - Fire Shield'),
(57984,0.4289,-1,-1,-1,'Greater Fire Elemental - Fire Blast');
(57984,0.4289,-1,-1,-1,'Greater Fire Elemental - Fire Blast');
@@ -0,0 +1,42 @@
-- Gossip Menu insert from sniff
DELETE FROM `gossip_menu` WHERE `entry`=7610 AND `text_id`=9261;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7610,9261);
DELETE FROM `gossip_menu` WHERE `entry`=8249 AND `text_id`=10266;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (8249,10266);
DELETE FROM `gossip_menu` WHERE `entry`=7612 AND `text_id`=9263;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7612,9263);
DELETE FROM `gossip_menu` WHERE `entry`=7611 AND `text_id`=9262;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7611,9262);
DELETE FROM `gossip_menu` WHERE `entry`=7588 AND `text_id`=9236;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7588,9236);
DELETE FROM `gossip_menu` WHERE `entry`=7590 AND `text_id`=9238;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7590,9238);
DELETE FROM `gossip_menu` WHERE `entry`=7591 AND `text_id`=9239;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7591,9239);
DELETE FROM `gossip_menu` WHERE `entry`=7589 AND `text_id`=9237;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7589,9237);
DELETE FROM `gossip_menu` WHERE `entry`=7526 AND `text_id`=9128;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7526,9128);
DELETE FROM `gossip_menu` WHERE `entry`=7614 AND `text_id`=9265;
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (7614,9265);
-- Creature Gossip_menu_id Update from sniff
UPDATE `creature_template` SET `gossip_menu_id`=7610 WHERE `entry`=18004;
UPDATE `creature_template` SET `gossip_menu_id`=8249 WHERE `entry`=21172;
UPDATE `creature_template` SET `gossip_menu_id`=7612 WHERE `entry`=18005;
UPDATE `creature_template` SET `gossip_menu_id`=7611 WHERE `entry`=18006;
UPDATE `creature_template` SET `gossip_menu_id`=7588 WHERE `entry`=18010;
UPDATE `creature_template` SET `gossip_menu_id`=7590 WHERE `entry`=18019;
UPDATE `creature_template` SET `gossip_menu_id`=7589 WHERE `entry`=18009;
UPDATE `creature_template` SET `gossip_menu_id`=7614 WHERE `entry`=18003;
-- Creature Gossip_menu_option Update from sniff
DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (8249,7612,7611,7588,7590,7589,7495) AND `id`=0;
DELETE FROM `gossip_menu_option` WHERE `menu_id`=7590 AND `id`=1;
INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES
(8249,0,1, 'I want to browse your goods.',3,128,0,0,0,0, ''),
(7612,0,1, 'I wish to buy from you.',3,128,0,0,0,0, ''),
(7611,0,1, 'I would like to buy from you.',3,128,0,0,0,0, ''),
(7588,0,1, 'Show me your wares, Maktu.',3,128,0,0,0,0, ''),
(7590,0,1, 'Let me browse your reagents and poison supplies.',3,128,0,0,0,0, ''),
(7590,1,0, 'Specialist, eh? Just what kind of specialist are you, anyway?',1,1,7591,0,0,0, ''),
(7589,0,1, 'I wish to browse your wares.',3,128,0,0,0,0, ''),
(7495,0,0, 'Watcher Leesa''oh, why are you out here?',1,1,7526,0,0,0, '');
@@ -0,0 +1,3 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_luck_of_the_draw';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(72221,'spell_gen_luck_of_the_draw');
@@ -0,0 +1,3 @@
DELETE FROM `trinity_string` WHERE `entry`=5031;
INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
(5031, 'AIName: %s ScriptName: %s');
@@ -0,0 +1,87 @@
-- Remove empty EAI Script call from the following entries
UPDATE `creature_template` SET `AIName` = '' WHERE `entry` IN (30243,30632);
-- Crimson Hammersmith summon from Blacksmithing Plans fix
-- Black Guard Swordsmith summon from Blacksmithing Plans fix
UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` IN (176325, 176327);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (176325, 176327) AND `source_type`=1;
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
(176325, 1, 0, 0, 64, 0, 100, 1, 0, 0, 0, 0, 12, 11120, 6, 60000, 0, 0, 0, 8, 0, 0, 0, 3585.5, -3000.15, 125, 2.19912, 'Blacksmithing Plans - summon Crimson Hammersmith'),
(176327, 1, 0, 0, 64, 0, 100, 1, 0, 0, 0, 0, 12, 11121, 6, 60000, 0, 0, 0, 8, 0, 0, 0, 3818.4, -3693.32, 144.242, 0.261799, 'Blacksmithing Plans - summon Black Guard Swordsmith');
-- Sleeping Giants fix
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24669;
DELETE FROM `smart_scripts` WHERE (`entryorguid`=24669 AND `source_type`=0);
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
(24669, 0, 0, 1, 8, 0, 100, 0, 44261, 1, 0, 0, 33, 24669, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Dormant Vrykul - Sleeping Giants quest credit'),
(24669, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Dormant Vrykul - Sleeping Giants despawn');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=18 AND `SourceEntry`=34083;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(18, 0, 34083, 0, 24, 1, 24669, 0, 63, '', 'Awakening Rod target limit to Dormant Vrykul'); -- changed to item script by Nay, not tested.
-- Culling of Stratholme Hemotoxin SAI spell fix version
SET @ENTRY := 28199;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `creature_ai_scripts` WHERE (`creature_id`=@ENTRY);
DELETE FROM `smart_scripts` WHERE (`entryorguid`=@ENTRY);
INSERT INTO `smart_scripts` VALUES
(@ENTRY, 0, 0, 0, 9, 0, 25, 2, 0, 20, 5000, 8000, 11, 52522, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Tomb Stalker - Cast Hemotoxin Normal'),
(@ENTRY, 0, 1, 0, 9, 0, 40, 4, 0, 20, 5000, 8000, 11, 58782, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Tomb Stalker - Cast Hemotoxin Heroic');
DELETE FROM `creature` WHERE `id` IN (28318, 29346);
INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`) VALUES
(40153, 28318, 530, 1, 1, 0, 0, -1775.148438, 5548.291992, -12.428190, 4.146070, 300, 0, 0, 1, 0, 0, 0, 0, 0), -- Grand Apothecary Putress
(40251, 29346, 530, 1, 1, 0, 0, 1925, -4123.1899, 43.1780, 4.79965, 300, 0, 0, 1, 0, 0, 0, 0, 0); -- Apothecary Karlov
-- Fix NPCs falling underground when killed by nelegalno
UPDATE `creature_template` SET `InhabitType` = 3 WHERE `entry` IN (5936, 24899); -- Orca and Scoodles
-- Removes wrong restriction from G.N.E.R.D. rage
DELETE FROM `achievement_criteria_data` WHERE `criteria_id`=3882 AND `type`=16;
-- Kalu'ak Fishing Derby start time fix
UPDATE `game_event` SET `start_time` = '2011-01-01 13:00:00' WHERE `eventEntry`=63;
UPDATE `game_event` SET `start_time` = '2011-01-01 14:00:00' WHERE `eventEntry`=64;
-- Stranglethorn Fishing Extravaganza start time fix ( http://old.wowhead.com/event=301 )
UPDATE `game_event` SET `start_time` = '2011-01-01 14:00:00' WHERE `eventEntry` IN (14, 15, 62);
UPDATE `game_event` SET `description` = 'Stranglethorn Fishing Extravaganza Announce' WHERE `eventEntry`=14;
UPDATE `game_event` SET `description` = 'Stranglethorn Fishing Extravaganza Fishing Pools' WHERE `eventEntry`=15;
UPDATE `game_event` SET `description` = 'Stranglethorn Fishing Extravaganza Turn-ins' WHERE `eventEntry`=62;
-- Eitrigg's Wisdom fix
SET @GOSSIP = 21312;
SET @NPC = 3144;
SET @QUEST = 4941;
-- Add gossip options for each menu id
DELETE FROM `gossip_menu_option` WHERE `menu_id` BETWEEN @GOSSIP AND @GOSSIP+7;
INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`) VALUES
(@GOSSIP, 0, 0, 'Hello, Eitrigg. I bring news from Blackrock Spire.', 1, 1, @GOSSIP+1, 0, 0, 0, ''),
(@GOSSIP+1, 0, 0, 'There is only one Warchief, Eitrigg!', 1, 1, @GOSSIP+2, 0, 0, 0, ''),
(@GOSSIP+2, 0, 0, 'What do you mean?', 1, 1, @GOSSIP+3, 0, 0, 0, ''),
(@GOSSIP+3, 0, 0, 'Hearthglen? But...', 1, 1, @GOSSIP+4, 0, 0, 0, ''),
(@GOSSIP+4, 0, 0, 'I will take you up on that offer, Eitrigg.', 1, 1, @GOSSIP+5, 0, 0, 0, ''),
(@GOSSIP+5, 0, 0, 'Ah, so that is how they pushed the Dark Iron to the lower parts of the Spire.', 1, 1, @GOSSIP+6, 0, 0, 0, ''),
(@GOSSIP+6, 0, 0, 'Perhaps there exists a way?', 1, 1, @GOSSIP+7, 0, 0, 0, ''),
(@GOSSIP+7, 0, 0, 'As you wish, Eitrigg.', 1, 1, 0, 0, 0, 0, '');
-- Add gossip menus (text values already in db)
DELETE FROM `gossip_menu` WHERE `entry`BETWEEN @GOSSIP+1 AND @GOSSIP+7;
INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES
(@GOSSIP+1, 3574),
(@GOSSIP+2, 3575),
(@GOSSIP+3, 3576),
(@GOSSIP+4, 3577),
(@GOSSIP+5, 3578),
(@GOSSIP+6, 3579),
(@GOSSIP+7, 3580);
-- Add Condtion so gossip only shows when on quest
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=@GOSSIP;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(15, @GOSSIP, 0, 0, 9, 4941, 0, 0, 0, '', NULL);
-- Add SAI for quest complete and close of gossip when last option selected
UPDATE `creature_template` SET `AIName`= 'SmartAI' WHERE `entry`=@NPC;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@NPC;
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,0,0,1,62,0,100,0,@GOSSIP+7,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0.0,0.0,0.0,0.0,'Eitrigg - Select As you wish, Eitrigg. - Close gossip'),
(@NPC,0,1,0,61,0,100,0,0,0,0,0,15,@QUEST,0,0,0,0,0,7,0,0,0,0.0,0.0,0.0,0.0,'Eitrigg - On link - Give credit quest (4941)');
@@ -0,0 +1,94 @@
-- Quest: The Black Knight's Orders (13663) SQL fix
-- Black Knights Camp Spawns
SET @OGUID=100489; -- Need 10
SET @CGUID=152277; -- Need 3
DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @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,194357,571,1,1,9070.324,2050.733,67.21755,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+1,194357,571,1,1,9073.764,2050.120,68.15718,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+2,194357,571,1,1,9074.699,2050.709,68.17049,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+3,194357,571,1,1,9069.595,2050.349,67.21755,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+4,194357,571,1,1,9069.961,2050.538,67.21755,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+5,194357,571,1,1,9072.077,2049.292,67.78963,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+6,194357,571,1,1,9065.680,2052.618,67.28638,0,0,0,0,1,0,0,0), -- Poison Vial
(@OGUID+7,194394,571,1,1,9083.578,2041.696,67.81812,0,0,0,0,1,0,0,0), -- Cult Rune Circle
(@OGUID+8,195011,571,1,1,9078.471,2057.547,67.21606,0,0,0,0.9981346,0.06105176,0,0,0), -- Bonfire
(@OGUID+9,300007,571,1,1,8523.51,566.994,552.841,2.1518,0,0,0.880019,0.474938,300,0,1); -- Spell Focus GO?
DELETE FROM `creature` WHERE `id`=33537;
INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES
(@CGUID+0,33537,571,1,1,0,0,9071.043,2075.388,67.21542,4.935980,120,0,0,1,0,0,0,0,0),
(@CGUID+1,33537,571,1,1,0,0,9074.414,2049.259,67.34636,2.181662,120,0,0,1,0,0,0,0,0),
(@CGUID+2,33537,571,1,1,0,0,9081.280,2058.925,67.38979,3.612832,120,0,0,1,0,0,0,0,0);
-- Template updates
UPDATE `creature_template` SET `unit_flags`=`unit_flags`|8,`speed_run`=4, `InhabitType`=5 WHERE `entry`=33519; -- Black Knight''s Gryphon
UPDATE `creature_template` SET `faction_A`=2080,`faction_H`=2080,`unit_flags`=`unit_flags`|32768,`equipment_id`=823 WHERE `entry`=33537; -- Cult Conspirator
-- See black knight's invisibility while on quest The Black Knight's Orders
DELETE FROM `spell_area` WHERE `spell`=67471 AND `area` IN (4658);
INSERT INTO `spell_area` (`spell`,`area`,`quest_start`,`quest_start_active`,`quest_end`,`aura_spell`,`racemask`,`gender`,`autocast`) VALUES
(67471,4658,13663,1,13663,0,0,2,1); -- See Black Knight Invis
-- Addon data
DELETE FROM `creature_template_addon` WHERE `entry` IN (33519,33537);
INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
(33519,0,0,2049,0,NULL),-- Black Knight''s Gryphon
(33537,0,1,1,0,NULL); -- Cult Conspirator
-- SAI for Black Knight''s Gryphon
SET @entry :=33519;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@entry;
DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@entry;
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
(@entry,0,0,0,27,0,100,0,0,0,0,0,53,0,@entry,0,13663,0,0,1,0,0,0,0,0,0,0,'Black Knight''s Gryphon - On passenger - Start WP movement'),
(@entry,0,1,0,40,0,100,0,40,@entry,0,0,33,33519,0,0,0,0,0,7,0,0,0,0,0,0,0,'Black Knight''s Gryphon - On WP 40 - Quest Credit'),
(@entry,0,2,0,40,0,100,0,43,@entry,0,0,11,50630,0,0,0,0,0,7,0,0,0,0,0,0,0,'Black Knight''s Gryphon - On WP 43 - Dismount Spell'),
(@entry,0,3,0,40,0,100,0,44,@entry,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Black Knight''s Gryphon - On WP 44 - Despawn');
DELETE FROM `waypoints` WHERE `entry`=33519;
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(33519, 1,8521.271,569.5960,552.8375,'Black Knight''s Gryphon'),
(33519, 2,8517.864,579.1095,553.2125,'Black Knight''s Gryphon'),
(33519, 3,8513.146,594.6724,551.2125,'Black Knight''s Gryphon'),
(33519, 4,8505.263,606.5569,550.4177,'Black Knight''s Gryphon'),
(33519, 5,8503.017,628.4188,547.4177,'Black Knight''s Gryphon'),
(33519, 6,8480.271,652.7083,547.4177,'Black Knight''s Gryphon'),
(33519, 7,8459.121,686.1427,547.4177,'Black Knight''s Gryphon'),
(33519, 8,8436.802,713.8687,547.3428,'Black Knight''s Gryphon'),
(33519, 9,8405.380,740.0045,547.4177,'Black Knight''s Gryphon'),
(33519,10,8386.139,770.6009,547.5881,'Black Knight''s Gryphon'),
(33519,11,8374.297,802.2525,547.9304,'Black Knight''s Gryphon'),
(33519,12,8374.271,847.0363,548.0427,'Black Knight''s Gryphon'),
(33519,13,8385.988,868.9881,548.0491,'Black Knight''s Gryphon'),
(33519,14,8413.027,867.8573,547.2991,'Black Knight''s Gryphon'),
(33519,15,8452.552,869.0339,547.2991,'Black Knight''s Gryphon'),
(33519,16,8473.058,875.2012,547.2955,'Black Knight''s Gryphon'),
(33519,17,8472.278,912.3134,547.4169,'Black Knight''s Gryphon'),
(33519,18,8479.666,954.1650,547.3298,'Black Knight''s Gryphon'),
(33519,19,8477.349,1001.368,547.3372,'Black Knight''s Gryphon'),
(33519,20,8484.538,1025.797,547.4622,'Black Knight''s Gryphon'),
(33519,21,8525.363,1029.284,547.4177,'Black Knight''s Gryphon'),
(33519,22,8532.808,1052.904,548.1677,'Black Knight''s Gryphon'),
(33519,23,8537.356,1077.927,554.5791,'Black Knight''s Gryphon'),
(33519,24,8540.528,1083.379,569.6827,'Black Knight''s Gryphon'),
(33519,25,8563.641,1140.965,569.6827,'Black Knight''s Gryphon'),
(33519,26,8594.897,1205.458,569.6827,'Black Knight''s Gryphon'),
(33519,27,8617.104,1257.399,566.1833,'Black Knight''s Gryphon'),
(33519,28,8648.496,1329.349,558.0187,'Black Knight''s Gryphon'),
(33519,29,8667.723,1388.411,546.1880,'Black Knight''s Gryphon'),
(33519,30,8699.145,1474.898,528.2197,'Black Knight''s Gryphon'),
(33519,31,8726.869,1546.006,501.7741,'Black Knight''s Gryphon'),
(33519,32,8739.058,1592.157,478.5511,'Black Knight''s Gryphon'),
(33519,33,8750.799,1636.771,455.0797,'Black Knight''s Gryphon'),
(33519,34,8760.006,1669.482,423.2208,'Black Knight''s Gryphon'),
(33519,35,8783.310,1701.852,375.8872,'Black Knight''s Gryphon'),
(33519,36,8817.336,1735.731,343.3323,'Black Knight''s Gryphon'),
(33519,37,8882.320,1789.754,301.5807,'Black Knight''s Gryphon'),
(33519,38,8958.597,1841.807,259.9141,'Black Knight''s Gryphon'),
(33519,39,9045.891,1908.076,233.4143,'Black Knight''s Gryphon'),
(33519,40,9107.177,1964.594,215.9704,'Black Knight''s Gryphon'),
(33519,41,9134.763,2036.925,175.1925,'Black Knight''s Gryphon'),
(33519,42,9128.608,2089.091,141.3593,'Black Knight''s Gryphon'),
(33519,43,9093.364,2128.384,99.38685,'Black Knight''s Gryphon'),
(33519,44,9050.709,2123.656,60.24802,'Black Knight''s Gryphon');
@@ -0,0 +1,14 @@
SET @JEEVES := 35642;
SET @SPELL_GOODBYE := 68052;
DELETE FROM `spell_linked_spell` WHERE `spell_effect`=@SPELL_GOODBYE AND `spell_trigger`=-68054 AND `type`=0;
INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES
(-68054,@SPELL_GOODBYE,0, 'Jeeves - Say Goodbye');
UPDATE `creature_template` SET `AIName`= 'SmartAI' WHERE `entry`=@JEEVES;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@JEEVES AND `source_type`=0;
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
(@JEEVES,0,0,0,8,0,100,0,@SPELL_GOODBYE,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Jeeves - On Spellhit - Say Line 0");
DELETE FROM `creature_text` WHERE `entry`=@JEEVES;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@JEEVES,0,0,"If you'll excuse me, I'm afraid I have other business I must attend to. Please call on me again in the future.",12,0,100,3,0,0, 'Jeeves');
@@ -0,0 +1,17 @@
-- Fix condition for Bom'bay's npc_text, gossip_menu and gossip_menu_option
-- Player must to complete quest 826 'Zalazane' to see gossip_menu_option
DELETE FROM `gossip_menu` WHERE `entry`=3062 AND `text_id` IN (3794,3795);
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
(3062,3794), -- text before to complete quest 826
(3062,3795); -- text after to complete quest 826
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` IN (14,15) AND `SourceGroup`=3062;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(14,3062,3794,0,14,826,0,0,0,'', "Bom'bay - show text 3794 if player does not have quest Zalazane"),
(14,3062,3795,0,8,826,0,0,0,'', "Bom'bay - show text 3795 if player has quest Zalazane rewarded"),
(15,3062,0,0,8,826,0,0,0,'', "Bom'bay - show gossip option 0 if player has quest Zalazane rewarded"),
(15,3062,1,0,8,826,0,0,0,'', "Bom'bay - show gossip option 1 if player has quest Zalazane rewarded"),
(15,3062,2,0,8,826,0,0,0,'', "Bom'bay - show gossip option 2 if player has quest Zalazane rewarded"),
(15,3062,3,0,8,826,0,0,0,'', "Bom'bay - show gossip option 3 if player has quest Zalazane rewarded"),
(15,3062,4,0,8,826,0,0,0,'', "Bom'bay - show gossip option 4 if player has quest Zalazane rewarded"),
(15,3062,5,0,8,826,0,0,0,'', "Bom'bay - show gossip option 5 if player has quest Zalazane rewarded"),
(15,3062,6,0,8,826,0,0,0,'', "Bom'bay - show gossip option 6 if player has quest Zalazane rewarded");
@@ -0,0 +1,7 @@
UPDATE spell_dbc SET EffectImplicitTargetA1 = 22, EffectImplicitTargetB1 = 7 WHERE Id = 58630;
DELETE FROM conditions WHERE SourceTypeOrReferenceId = 13 AND SourceEntry IN (61863, 68663);
INSERT INTO conditions (SourceTypeOrReferenceId, SourceEntry, ConditionTypeOrReference, ConditionValue1, Comment) VALUES
(13, 61863, 18, 1, 'The Prophet Tharon''ja - Achievement Check'),
(13, 68663, 18, 1, 'The Black Knight - Kill Credit'),
(13, 58630, 18, 1, 'Mal''Ganis - Kill Credit');
@@ -0,0 +1,2 @@
-- Quest: Arcane Refreshment only available for mages
UPDATE `quest_template` SET `RequiredClasses`=`RequiredClasses`|128 WHERE `Id`=7463;
@@ -0,0 +1,11 @@
-- Achievement Fa-la-la-la-Ogri'la
DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (3936,3937,3938);
INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
-- requires aura
(3936, 5, 44827, 0, ''),
(3937, 5, 44825, 0, ''),
(3938, 5, 44824, 0, ''),
-- requires Holiday Winter Veil
(3936, 16, 141, 0, ''),
(3937, 16, 141, 0, ''),
(3938, 16, 141, 0, '');
@@ -0,0 +1,10 @@
-- Scriptname for the cages
UPDATE `gameobject_template` SET `ScriptName`='go_veil_skith_cage' WHERE `entry` IN (185202,185203,185204,185205);
-- Texts for Captive Child
DELETE FROM `creature_text` WHERE `entry`=22314;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(22314,0,0,"Woot!",12,0,100,0,0,0,"Captive Child"),
(22314,0,1,"I think those weird bird guys were going to eat us. Gross!",12,0,100,0,0,0,"Captive Child"),
(22314,0,2,"Yay! We're free!",12,0,100,0,0,0,"Captive Child"),
(22314,0,3,"Gross!",12,0,100,0,0,0,"Captive Child");
@@ -0,0 +1 @@
UPDATE `spell_proc_event` SET `SpellFamilyMask0` = 0 WHERE `entry` IN (5952,51679);
@@ -0,0 +1,41 @@
-- Reward from Treats for Greatfather Winter (horde)
SET @mail:=102; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (6962); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,17685,100,1,0,1,1); -- Attach item to mail
-- Reward from Treats for Greatfather Winter (alliance)
SET @mail:=118; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (7025); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,17685,100,1,0,1,1); -- Attach item to mail
-- Reward from Stolen Winter Veil Treats (horde)
SET @mail:=108; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (6963); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,17712,100,1,0,1,1); -- Attach item to mail
-- Reward from Stolen Winter Veil Treats (alliance)
SET @mail:=117; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (7042); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,17712,100,1,0,1,1); -- Attach item to mail
-- Reward from Metzen the Reindeer (horde)
SET @mail:=122; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (8746); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,21216,100,1,0,1,1); -- Attach item to mail
-- Reward from Metzen the Reindeer (alliance)
SET @mail:=161; -- Set in DBC
UPDATE quest_template SET RewardMailTemplateId=@mail, RewardMailDelay=86400 WHERE Id IN (8762); -- Set mail delivery
DELETE FROM mail_loot_template WHERE entry=@mail;
INSERT INTO mail_loot_template (entry,item,ChanceOrQuestChance,lootmode,groupid,mincountOrRef,maxcount) VALUES
(@mail,21216,100,1,0,1,1); -- Attach item to mail
@@ -0,0 +1,3 @@
DELETE FROM `areatrigger_scripts` WHERE `entry`=4752;
INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
(4752,'at_nats_landing');
@@ -0,0 +1 @@
UPDATE `gameobject_template` SET `ScriptName`='go_demon_portal' WHERE `entry` IN (177243,177365,177369,177397,177398,177399,177400,177366,177367,177368);
@@ -0,0 +1,9 @@
UPDATE `gameobject_template` SET `ScriptName`='go_captain_tyralius_prison' WHERE `entry`=184588;
UPDATE `quest_template` SET `RequiredSpellCast1`=0 WHERE `id`=10422;
DELETE FROM `creature_text` WHERE `entry`=20787;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(20787,0,0,"You've saved me, fleshling! Ameer will hear of this noble act.",12,0,100,0,0,0,"Captain Tyralius");
-- Heroes of Old
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=2702;
DELETE FROM `quest_start_scripts` WHERE `id`=2702;
@@ -0,0 +1,23 @@
-- Bloodfen Raptor SAI
SET @ENTRY := 4351;
SET @SPELL_ROPE := 42325;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,0,8,0,100,0,@SPELL_ROPE,0,0,0,33,23727,0,0,0,0,0,7,0,0,0,0,0,0,0,"Bloodfen Raptor - On Spellhit - Quest Credit"),
(@ENTRY,0,1,0,2,0,100,1,0,20,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bloodfen Raptor - At 20% HP - Say Line 0");
-- Bloodfen Screecher SAI
SET @ENTRY := 4352;
SET @SPELL_ROPE := 42325;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,0,8,0,100,0,@SPELL_ROPE,0,0,0,33,23727,0,0,0,0,0,7,0,0,0,0,0,0,0,"Bloodfen Screecher - On Spellhit - Quest Credit"),
(@ENTRY,0,1,0,2,0,100,1,0,20,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bloodfen Screecher - At 20% HP - Say Line 0");
-- Texts
DELETE FROM `creature_text` WHERE `entry` IN (4351,4352);
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(4351,0,0,"%s looks weak enough to capture.",16,0,100,0,0,0,"Bloodfen Raptor"),
(4352,0,0,"%s looks weak enough to capture.",16,0,100,0,0,0,"Bloodfen Screecher");
@@ -0,0 +1,4 @@
UPDATE `item_template` SET `ScriptName`='' WHERE `entry`=23654;
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_q9452_cast_net';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(29866,'spell_q9452_cast_net');
@@ -0,0 +1,9 @@
DELETE FROM `areatrigger_scripts` WHERE `ScriptName`='at_bring_your_orphan_to';
INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
(3551,'at_bring_your_orphan_to'),
(3549,'at_bring_your_orphan_to'),
(3547,'at_bring_your_orphan_to'),
(3546,'at_bring_your_orphan_to'),
(3552,'at_bring_your_orphan_to'),
(3548,'at_bring_your_orphan_to'),
(4356,'at_bring_your_orphan_to');
@@ -0,0 +1,3 @@
-- Zuhuled the Wacked
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=10866;
DELETE FROM `quest_start_scripts` WHERE `id`=10866;
@@ -0,0 +1,19 @@
-- Acidic Swamp Ooze SAI
SET @ENTRY := 4393;
SET @SPELL_END_CHANNEL := 42485;
SET @SPELL_BUBBLING_OOZE := 43135;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,0,8,0,100,0,@SPELL_END_CHANNEL,0,0,0,33,23797,0,0,0,0,0,7,0,0,0,0,0,0,0,"Acidic Swamp Ooze - On Spellhit - Quest Credit"),
(@ENTRY,0,1,0,2,0,100,1,0,15,0,0,11,@SPELL_BUBBLING_OOZE,0,0,0,0,0,2,0,0,0,0,0,0,0,"Acidic Swamp Ooze - At 15% HP - Cast Bubbling Ooze");
-- Bubbling Swamp Ooze SAI
SET @ENTRY := 4394;
SET @SPELL_END_CHANNEL := 42485;
SET @SPELL_BUBBLING_OOZE := 43135;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,0,8,0,100,0,@SPELL_END_CHANNEL,0,0,0,33,23797,0,0,0,0,0,7,0,0,0,0,0,0,0,"Bubbling Swamp Ooze - On Spellhit - Quest Credit"),
(@ENTRY,0,1,0,2,0,100,1,0,15,0,0,11,@SPELL_BUBBLING_OOZE,0,0,0,0,0,2,0,0,0,0,0,0,0,"Bubbling Swamp Ooze - At 15% HP - Cast Bubbling Ooze");
@@ -0,0 +1,5 @@
-- Areatrigger scriptname for Brewfest
DELETE FROM `areatrigger_scripts` WHERE `entry` IN (4829,4820);
INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
(4829,'at_brewfest'), -- Durotar
(4820,'at_brewfest'); -- Dun Morogh
@@ -0,0 +1,89 @@
-- Make the human versions in Pyrewood Village despawn during night and the worgens spawn during night
SET @GUID := 152280;
DELETE FROM `game_event_creature` WHERE `eventEntry`=25;
INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES
-- Humans
(-25,17908),(-25,18404),(-25,18408),
(-25,19002),(-25,19005),(-25,19084),
(-25,19219),(-25,19222),(-25,19223),
(-25,19224),(-25,19227),(-25,19229),
(-25,19316),(-25,19343),(-25,18307),
(-25,17911),(-25,17910),(-25,18236),
(-25,18237),(-25,18239),(-25,18291),
(-25,18306),(-25,18350),(-25,18400),
(-25,18411),(-25,18413),(-25,18996),
(-25,19008),(-25,19012),(-25,19015),
(-25,19019),(-25,19220),(-25,19228),
(-25,17663),(-25,17905),(-25,18220),
(-25,18221),(-25,18238),(-25,18310),
(-25,18354),(-25,18355),(-25,18405),
(-25,18407),(-25,18409),(-25,19007),
(-25,18235),(-25,18309),
-- Worgens
(25,@GUID+1),(25,@GUID+2),(25,@GUID+3),
(25,@GUID+4),(25,@GUID+5),(25,@GUID+6),
(25,@GUID+7),(25,@GUID+8),(25,@GUID+9),
(25,@GUID+10),(25,@GUID+11),(25,@GUID+12),
(25,@GUID+13),(25,@GUID+14),(25,@GUID+15),
(25,@GUID+16),(25,@GUID+17),(25,@GUID+18),
(25,@GUID+19),(25,@GUID+20),(25,@GUID+21),
(25,@GUID+22),(25,@GUID+23),(25,@GUID+24),
(25,@GUID+25),(25,@GUID+26),(25,@GUID+27),
(25,@GUID+28),(25,@GUID+29),(25,@GUID+30),
(25,@GUID+31),(25,@GUID+32),(25,@GUID+33),
(25,@GUID+34),(25,@GUID+35),(25,@GUID+36),
(25,@GUID+37),(25,@GUID+38),(25,@GUID+39),
(25,@GUID+40),(25,@GUID+41),(25,@GUID+42),
(25,@GUID+43),(25,@GUID+44),(25,@GUID+45),
(25,@GUID+46),(25,@GUID+0);
-- Spawn all Moonrage versions of the humans
DELETE FROM `creature` WHERE `id` IN (3533,3531,3529,1896,1893,1892);
INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES
(@GUID+0,3533,0,1,1,0,-408.091,1604.03,18.2868,5.5676,600,0,0,300,0,0,0,0,0),
(@GUID+1,3531,0,1,1,0,-360.278,1495.03,17.196,0.830526,600,0,0,328,0,0,0,0,0),
(@GUID+2,3529,0,1,1,0,-345.967,1501.4,18.9875,0.942478,600,0,0,328,0,0,0,0,0),
(@GUID+3,1896,0,1,1,0,-327.462,1555.21,25.2491,1.61376,600,0,0,276,295,0,0,0,0),
(@GUID+4,1896,0,1,1,0,-407.955,1451.33,27.0859,0.767945,600,0,0,276,295,0,0,0,0),
(@GUID+5,1896,0,1,1,0,-391.907,1432.23,27.0313,6.07375,600,0,0,276,295,0,0,0,0),
(@GUID+6,1896,0,1,1,0,-344.082,1504.01,18.7918,4.18879,600,0,0,276,295,0,0,0,0),
(@GUID+7,1896,0,1,1,0,-329.456,1545.74,30.1367,2.26893,600,0,0,276,295,0,0,0,0),
(@GUID+8,1896,0,1,1,0,-414.124,1581.03,19.7275,6.10865,600,0,0,276,295,0,0,0,0),
(@GUID+9,1896,0,1,1,0,-413.706,1579.64,24.2994,2.9861,600,0,0,276,295,0,0,0,0),
(@GUID+10,1896,0,1,1,0,-423.094,1578.33,24.3098,2.98749,600,0,0,276,295,0,0,0,0),
(@GUID+11,1896,0,1,1,0,-411.947,1517.76,19.7711,4.86947,600,0,0,276,295,0,0,0,0),
(@GUID+12,1896,0,1,1,0,-424.202,1543.84,18.5687,6.17846,600,0,0,276,295,0,0,0,0),
(@GUID+13,1896,0,1,1,0,-397.475,1543.61,17.1712,3.0459,600,5,0,276,295,1,0,0,0),
(@GUID+14,1896,0,1,1,0,-378.435,1625.51,16.8077,0.694863,600,3,0,276,295,1,0,0,0),
(@GUID+15,1893,0,1,1,0,-404.028,1460.9,31.7653,5.84685,600,0,0,300,0,0,0,0,0),
(@GUID+16,1893,0,1,1,0,-410.983,1453.18,31.679,5.59007,600,5,0,300,0,1,0,0,0),
(@GUID+17,1893,0,1,1,0,-333.219,1548.41,25.2864,4.7729,600,0,0,300,0,0,0,0,0),
(@GUID+18,1893,0,1,1,0,-339.031,1547.76,30.0369,3.83411,600,3,0,300,0,1,0,0,0),
(@GUID+19,1893,0,1,1,0,-341.711,1553.34,24.5273,3.26377,600,0,0,300,0,0,0,0,0),
(@GUID+20,1893,0,1,1,0,-380.605,1435.24,25.7369,5.98648,600,0,0,300,0,0,0,0,0),
(@GUID+21,1893,0,1,1,0,-378.287,1655.98,10.346,2.89725,600,3,0,300,0,1,0,0,0),
(@GUID+22,1893,0,1,1,0,-411.642,1509.01,19.8575,1.55334,600,0,0,300,0,0,0,0,0),
(@GUID+23,1893,0,1,1,0,-390.535,1466.63,25.9869,5.34071,600,0,0,300,0,0,0,0,0),
(@GUID+24,1893,0,1,1,0,-391.615,1601.72,17.1706,4.86947,600,0,0,300,0,0,0,0,0),
(@GUID+25,1893,0,1,1,0,-355.263,1580.06,18.0622,0.078739,600,0,0,300,0,0,0,0,0),
(@GUID+26,1893,0,1,1,0,-442.388,1539.5,19.6376,4.53468,600,5,0,300,0,1,0,0,0),
(@GUID+27,1893,0,1,1,0,-389.73,1634.41,17.4309,6.20095,600,0,0,300,0,0,0,0,0),
(@GUID+28,1893,0,1,1,0,-385.558,1618.24,24.2887,4.07713,600,3,0,300,0,1,0,0,0),
(@GUID+29,1893,0,1,1,0,-385.776,1632.95,24.2887,3.83402,600,0,0,300,0,0,0,0,0),
(@GUID+30,1893,0,1,1,0,-384.391,1560.98,17.1156,2.65866,600,5,0,300,0,1,0,0,0),
(@GUID+31,1893,0,1,1,0,-420.551,1544.65,18.3187,2.70724,600,0,0,300,0,2,0,0,0),
(@GUID+32,1893,0,1,1,0,-372.427,1611.08,24.3721,1.32645,600,0,0,300,0,0,0,0,0),
(@GUID+33,1892,0,1,1,0,-405.033,1458.8,27.0968,0.15708,600,0,0,300,0,0,0,0,0),
(@GUID+34,1892,0,1,1,0,-350.427,1448.5,24.3665,4.72984,600,0,0,300,0,0,0,0,0),
(@GUID+35,1892,0,1,1,0,-370.983,1576.35,16.981,1.98656,600,0,0,300,0,2,0,0,0),
(@GUID+36,1892,0,1,1,0,-377.63,1491.95,18.4887,5.32325,600,0,0,300,0,0,0,0,0),
(@GUID+37,1892,0,1,1,0,-381.301,1653.14,17.7911,4.4855,600,0,0,300,0,0,0,0,0),
(@GUID+38,1892,0,1,1,0,-354.378,1421.62,28.2597,5.14872,600,0,0,300,0,0,0,0,0),
(@GUID+39,1892,0,1,1,0,-432.435,1531.27,18.7313,4.20121,600,5,0,300,0,1,0,0,0),
(@GUID+40,1892,0,1,1,0,-350.822,1606.93,18.0028,3.78911,600,0,0,300,0,0,0,0,0),
(@GUID+41,1892,0,1,1,0,-416.268,1576.92,19.5441,3.61468,600,0,0,300,0,0,0,0,0),
(@GUID+42,1892,0,1,1,0,-439.617,1517.84,19.5619,3.33314,600,5,0,300,0,1,0,0,0),
(@GUID+43,1892,0,1,1,0,-358.11,1528.2,24.9468,1.18862,600,0,0,300,0,0,0,0,0),
(@GUID+44,1892,0,1,1,0,-433.404,1564.13,19.7291,1.48262,600,5,0,300,0,1,0,0,0),
(@GUID+45,1892,0,1,1,0,-363.818,1545.45,24.4813,3.24746,600,0,0,300,0,0,0,0,0),
(@GUID+46,1892,0,1,1,0,-345.242,1601.84,17.0845,2.23485,600,0,0,300,0,0,0,0,0);
@@ -0,0 +1,47 @@
-- Terenthis SAI
SET @ENTRY := 3693;
SET @QUEST := 986;
UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `quest_end_scripts` WHERE `id`=993; -- For some reason this entry was different..
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100,@ENTRY*100+1);
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
-- Start quest
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,12,6086,1,25000,0,0,0,8,0,0,0,6435.25,368.004,13.9412,1.09956,"Terenthis - On Script - Summon Auberdine Sentinel"),
(@ENTRY*100,9,1,0,0,0,100,0,5000,5000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 0"),
(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 1"),
(@ENTRY*100,9,3,0,0,0,100,0,9000,9000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 2"),
-- End quest
(@ENTRY,0,1,0,20,0,100,0,@QUEST,0,0,0,80,@ENTRY*100+1,0,2,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Quest Finish - Run Script"),
(@ENTRY*100+1,9,0,0,0,0,100,0,0,0,0,0,12,3695,1,50000,0,0,0,8,0,0,0,6435.25,368.004,13.9412,1.09956,"Terenthis - On Script - Summon Grimclaw"),
(@ENTRY*100+1,9,1,0,0,0,100,0,5000,5000,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 3"),
(@ENTRY*100+1,9,2,0,0,0,100,0,7000,7000,0,0,1,4,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 4"),
(@ENTRY*100+1,9,3,0,0,0,100,0,9000,9000,0,0,1,5,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 5"),
(@ENTRY*100+1,9,4,0,0,0,100,0,11000,11000,0,0,1,6,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 6"),
(@ENTRY*100+1,9,5,0,0,0,100,0,14000,14000,0,0,1,7,0,0,0,0,0,1,0,0,0,0,0,0,0,"Terenthis - On Script - Say Line 7");
-- Texts
DELETE FROM `db_script_string` WHERE `entry` IN (2000000009,2000000010,2000000011,2000000050,2000000051,2000000052,2000000053,2000000054);
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"What is happening?",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,1,0,"Volcor needs help?",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,2,0,"All right, I shall find people to help him.",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,3,0,"Hello Grimclaw.",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,4,0,"What is happening?",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,5,0,"Volcor needs help?",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,6,0,"You know where he is?",12,0,0,0,0,0,"Terenthis"),
(@ENTRY,7,0,"Well, ok. I am sending people. We will need to find and help him!",12,0,0,0,0,0,"Terenthis");
-- Grimclaw SAI
SET @ENTRY := 3695;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,0,22,0,100,0,101,5000,5000,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Grimclaw - Emote Receive 'Wave' - Emote Line 0");
-- Text
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Grimclaw growls in your direction before taking time to sniff you.",16,0,0,0,0,0,"Grimclaw");
@@ -0,0 +1,3 @@
-- The Thunderspike
UPDATE `gameobject_template` SET `AIName`='',`ScriptName`='go_thunderspike' WHERE `entry`=184729;
DELETE FROM `event_scripts` WHERE `id`=13685;
@@ -0,0 +1,52 @@
-- [Q] [A] Escape Through Force
-- [Q] [A] Escape Through Stealth
-- Volcor SAI
SET @ENTRY := 3692;
SET @QUEST_FORCE := 994;
SET @QUEST_STEALTH := 995;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id` IN (@QUEST_FORCE,@QUEST_STEALTH);
DELETE FROM `quest_start_scripts` WHERE `id` IN (@QUEST_FORCE,@QUEST_STEALTH);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100,@ENTRY*100+1);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST_FORCE,0,0,0,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,"Volcor - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Volcor - On Script - Say Line 0"),
(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,53,0,@ENTRY,0,0,0,2,1,0,0,0,0,0,0,0,"Volcor - On Script - Start WP"),
(@ENTRY*100,9,2,0,0,0,100,0,135000,135000,0,0,1,2,0,0,0,0,0,7,0,0,0,0,0,0,0,"Volcor - On Script - Say Line 2"),
(@ENTRY*100,9,3,0,0,0,100,0,0,0,0,0,15,@QUEST_FORCE,0,0,0,0,7,0,0,0,0,0,0,0,0,"Volcor - On Script - Quest Credit"),
(@ENTRY,0,1,0,19,0,100,0,@QUEST_STEALTH,0,0,0,80,@ENTRY*100+1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Volcor - On Quest Accept - Run Script"),
(@ENTRY*100+1,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,1,3,0,0,0,0,0,0,"Volcor - On Script - Say Line 0"),
(@ENTRY*100+1,9,1,0,0,0,100,0,0,0,0,0,53,0,@ENTRY,0,0,0,2,1,0,0,0,0,0,0,0,"Volcor - On Script - Start WP"),
(@ENTRY*100+1,9,2,0,0,0,100,0,135000,135000,0,0,1,3,0,0,0,0,0,7,0,0,0,0,0,0,0,"Volcor - On Script - Say Line 3"),
(@ENTRY*100+1,9,3,0,0,0,100,0,0,0,0,0,15,@QUEST_STEALTH,0,0,0,0,7,0,0,0,0,0,0,0,0,"Volcor - On Script - Quest Credit"),
(@ENTRY,0,2,0,40,0,100,0,15,@ENTRY*100,0,0,41,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Volcor - On WP 15 - Forced Despawn"),
(@ENTRY,0,3,0,4,0,100,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,"Volcor - On Aggro - Say Line 1");
-- Texts
DELETE FROM `db_script_string` WHERE `entry` BETWEEN 2000000012 AND 2000000016;
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"All right, let's go.",12,0,100,0,0,0,"Volcor"),
(@ENTRY,1,0,"Oh no! They are here!",12,0,100,0,0,0,"Volcor"),
(@ENTRY,2,0,"OK, $N. Now I can get to the Auberdine alone. Go to Terenthis, he's waiting for you. Thanks for the help!",12,0,100,0,0,0,"Volcor"),
(@ENTRY,3,0,"OK, good luck friend. Thanks for the help.",12,0,100,0,0,0,"Volcor");
-- Waypoints
DELETE FROM `waypoints` WHERE `entry`=@ENTRY;
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(@ENTRY,1,4606.61,2.96905,69.909,"Volcor"),
(@ENTRY,2,4615.56,19.7957,70.7951,"Volcor"),
(@ENTRY,3,4626.26,38.1105,69.0281,"Volcor"),
(@ENTRY,4,4633.11,48.379,67.5631,"Volcor"),
(@ENTRY,5,4637.2,71.7156,63.3412,"Volcor"),
(@ENTRY,6,4645.39,88.5048,60.3851,"Volcor"),
(@ENTRY,7,4660.2,104.218,58.4603,"Volcor"),
(@ENTRY,8,4675.33,115.93,56.8969,"Volcor"),
(@ENTRY,9,4688.21,131.397,55.5033,"Volcor"),
(@ENTRY,10,4701.45,145.562,53.2203,"Volcor"),
(@ENTRY,11,4709.21,155.279,52.0846,"Volcor"),
(@ENTRY,12,4716.9,169.528,53.5005,"Volcor"),
(@ENTRY,13,4725.44,180.07,54.7346,"Volcor"),
(@ENTRY,14,4734.01,194.431,55.3888,"Volcor"),
(@ENTRY,15,4747.92,209.436,53.1076,"Volcor");
@@ -0,0 +1,44 @@
-- [Q] [A/H] Therylune's Escape
-- Therylune SAI
SET @ENTRY := 3584;
SET @QUEST := 945;
UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY;
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
(@ENTRY,0,0,1,19,0,100,0,@QUEST,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Therylune - On Quest Accept - Say Line 0"),
(@ENTRY,0,1,0,61,0,100,0,0,0,0,0,53,0,@ENTRY,0,0,0,2,1,0,0,0,0,0,0,0,"Therylune - On Quest Accept - Start WP"),
(@ENTRY,0,2,3,40,0,100,0,20,@ENTRY,0,0,1,1,0,0,0,0,0,7,0,0,0,0,0,0,0,"Therylune - On WP 20 - Say Line 1"),
(@ENTRY,0,3,0,61,0,100,0,0,0,0,0,15,@QUEST,0,0,0,0,7,0,0,0,0,0,0,0,0,"Therylune - On WP 20 - Quest Credit"),
(@ENTRY,0,4,0,40,0,100,0,21,@ENTRY,0,0,41,5000,0,0,0,0,1,0,0,0,0,0,0,0,0,"Therylune - On WP 21 - Forced Despawn");
-- Texts
DELETE FROM `db_script_string` WHERE `entry` IN (2000000017,2000000018);
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Ok, let's go!",12,0,100,0,0,0,"Therylune"),
(@ENTRY,1,0,"I can make it the rest of the way, $N. Thanks!",12,0,100,0,0,0,"Therylune");
-- Waypoints
DELETE FROM `waypoints` WHERE `entry`=@ENTRY;
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(@ENTRY,1,4520.4,420.235,33.5284,"Therylune"),
(@ENTRY,2,4512.26,408.881,32.9308,"Therylune"),
(@ENTRY,3,4507.94,396.47,32.9476,"Therylune"),
(@ENTRY,4,4507.53,383.781,32.995,"Therylune"),
(@ENTRY,5,4512.1,374.02,33.166,"Therylune"),
(@ENTRY,6,4519.75,373.241,33.1574,"Therylune"),
(@ENTRY,7,4592.41,369.127,31.4893,"Therylune"),
(@ENTRY,8,4598.55,364.801,31.4947,"Therylune"),
(@ENTRY,9,4602.76,357.649,32.9265,"Therylune"),
(@ENTRY,10,4597.88,352.629,34.0317,"Therylune"),
(@ENTRY,11,4590.23,350.9,36.2977,"Therylune"),
(@ENTRY,12,4581.5,348.254,38.3878,"Therylune"),
(@ENTRY,13,4572.05,348.059,42.3539,"Therylune"),
(@ENTRY,14,4564.75,344.041,44.2463,"Therylune"),
(@ENTRY,15,4556.63,341.003,47.6755,"Therylune"),
(@ENTRY,16,4554.38,334.968,48.8003,"Therylune"),
(@ENTRY,17,4557.63,329.783,49.9532,"Therylune"),
(@ENTRY,18,4563.32,316.829,53.2409,"Therylune"),
(@ENTRY,19,4566.09,303.127,55.0396,"Therylune"),
(@ENTRY,20,4561.65,295.456,57.0984,"Therylune"),
(@ENTRY,21,4551.03,293.333,57.1534,"Therylune");
@@ -0,0 +1,39 @@
-- [Q] [A/H] Enchanted Azsharite Fel Weaponry
-- [Q] [A/H] Expert Blacksmith!
-- Galvan the Ancient SAI
SET @ENTRY := 7802;
SET @QUEST_ENCHANTED := 3625;
SET @QUEST_EXPERT_BS := 2765;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id` IN (@QUEST_ENCHANTED,@QUEST_EXPERT_BS);
UPDATE `creature` SET `position_x`=-12033.400391,`position_y`=-1003.859985,`position_z`=49.779499,`orientation`=3.910880 WHERE `guid`=384 AND `id`=@ENTRY; -- Galvan the Ancient should be at a different position..
DELETE FROM `creature` WHERE `guid`=1864 AND `id`=684; -- Flying panther in the middle of our event spot..
DELETE FROM `creature_addon` WHERE `guid`=1864;
DELETE FROM `quest_start_scripts` WHERE `id` IN (@QUEST_ENCHANTED,@QUEST_EXPERT_BS);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100,@ENTRY*100+1);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST_ENCHANTED,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,69,0,0,0,0,0,0,8,0,0,0,-12040.5,-1008.7,49.4,3.66,"Galvan the Ancient - On Script - Move To Anvil"),
(@ENTRY*100,9,1,0,0,0,100,0,4000,4000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,2,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,3,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,4,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,5,0,0,0,100,0,2000,2000,0,0,69,0,0,0,0,0,0,8,0,0,0,-12040.988281,-1007.649170,49.481323,2.364430,"Galvan the Ancient - On Script - Move To Forge"),
(@ENTRY*100,9,6,0,0,0,100,0,1000,1000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,7,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,8,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,9,0,0,0,100,0,2000,2000,0,0,15,@QUEST_ENCHANTED,0,0,0,0,0,7,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Quest Credit"),
(@ENTRY*100,9,10,0,0,0,100,0,5000,5000,0,0,69,0,0,0,0,0,0,8,0,0,0,-12033.400391,-1003.859985,49.779499,3.910880,"Galvan the Ancient - On Script - Move To Homeposition"),
(@ENTRY,0,1,0,19,0,100,0,@QUEST_EXPERT_BS,0,0,0,80,@ENTRY*100+1,0,2,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Quest Accept - Run Script"),
(@ENTRY*100+1,9,0,0,0,0,100,0,0,0,0,0,69,0,0,0,0,0,0,8,0,0,0,-12040.5,-1008.7,49.4,3.66,"Galvan the Ancient - On Script - Move To Anvil"),
(@ENTRY*100+1,9,1,0,0,0,100,0,4000,4000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,2,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,3,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,4,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,5,0,0,0,100,0,2000,2000,0,0,69,0,0,0,0,0,0,8,0,0,0,-12040.988281,-1007.649170,49.481323,2.364430,"Galvan the Ancient - On Script - Move To Forge"),
(@ENTRY*100+1,9,6,0,0,0,100,0,1000,1000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,7,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,8,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100+1,9,9,0,0,0,100,0,2000,2000,0,0,15,@QUEST_EXPERT_BS,0,0,0,0,0,7,0,0,0,0,0,0,0,"Galvan the Ancient - On Script - Quest Credit"),
(@ENTRY*100+1,9,10,0,0,0,100,0,5000,5000,0,0,69,0,0,0,0,0,0,8,0,0,0,-12033.400391,-1003.859985,49.779499,3.910880,"Galvan the Ancient - On Script - Move To Homeposition");
@@ -0,0 +1,58 @@
-- [Q] [A/H] The Summoning
-- Bath'rah the Windwatcher SAI
SET @ENTRY := 6176;
SET @QUEST := 1713;
SET @SPELL_SUMMON := 8606;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100,@ENTRY*100+1);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,1000,1000,0,0,53,0,@ENTRY,0,0,0,2,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Script - Start WP"),
(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Script - Say Line 0"),
(@ENTRY,0,1,0,0,0,100,0,7,@ENTRY,0,0,80,@ENTRY*100+1,0,2,0,0,0,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On WP 7 - Run Script"),
(@ENTRY*100+1,9,0,0,0,0,100,0,0,0,0,0,11,@SPELL_SUMMON,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Script - Cast Summon Cyclonian"),
(@ENTRY*100+1,9,1,0,0,0,100,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Script - Say Line 1"),
(@ENTRY*100+1,9,2,0,0,0,100,0,15000,15000,0,0,53,0,@ENTRY*10,0,0,0,2,1,0,0,0,0,0,0,0,"Bath'rah the Windwatcher - On Script - Start WP");
-- Waypoints
DELETE FROM `waypoints` WHERE `entry` IN (@ENTRY,@ENTRY*10);
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(@ENTRY,1,253.05,-1459.09,52.09,"Bath'rah the Windwatcher"),
(@ENTRY,2,256.87,-1440.35,50.09,"Bath'rah the Windwatcher"),
(@ENTRY,3,273.74,-1433.18,50.29,"Bath'rah the Windwatcher"),
(@ENTRY,4,297.77,-1436.7,46.96,"Bath'rah the Windwatcher"),
(@ENTRY,5,329.59,-1442.08,40.31,"Bath'rah the Windwatcher"),
(@ENTRY,6,332.73,-1455.6,42.24,"Bath'rah the Windwatcher"),
(@ENTRY,7,323.83,-1468.92,42.24,"Bath'rah the Windwatcher"),
(@ENTRY*10,1,332.73,-1455.6,42.24,"Bath'rah the Windwatcher"),
(@ENTRY*10,2,329.59,-1442.08,40.31,"Bath'rah the Windwatcher"),
(@ENTRY*10,3,297.77,-1436.7,46.96,"Bath'rah the Windwatcher"),
(@ENTRY*10,4,273.74,-1433.18,50.29,"Bath'rah the Windwatcher"),
(@ENTRY*10,5,256.87,-1440.35,50.09,"Bath'rah the Windwatcher"),
(@ENTRY*10,6,253.05,-1459.09,52.09,"Bath'rah the Windwatcher"),
(@ENTRY*10,7,250.84,-1470.58,55.4491,"Bath'rah the Windwatcher");
-- Texts
DELETE FROM `db_script_string` WHERE `entry` IN (2000000029,2000000043);
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Follow me, $N. I will soon begin the summoning.",12,0,100,0,0,0,"Bath'rah the Windwatcher"),
(@ENTRY,1,0,"%s begins a spell of summoning...",41,0,100,0,0,0,"Bath'rah the Windwatcher");
-- Waypoints
DELETE FROM `waypoints` WHERE `entry`=@ENTRY;
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(@ENTRY,1,253.05,-1459.09,52.09,"Bath'rah the Windwatcher"),
(@ENTRY,2,256.87,-1440.35,50.09,"Bath'rah the Windwatcher"),
(@ENTRY,3,273.74,-1433.18,50.29,"Bath'rah the Windwatcher"),
(@ENTRY,4,297.77,-1436.7,46.96,"Bath'rah the Windwatcher"),
(@ENTRY,5,329.59,-1442.08,40.31,"Bath'rah the Windwatcher"),
(@ENTRY,6,332.73,-1455.6,42.24,"Bath'rah the Windwatcher"),
(@ENTRY,7,323.83,-1468.92,42.24,"Bath'rah the Windwatcher"),
(@ENTRY,8,332.73,-1455.6,42.24,"Bath'rah the Windwatcher"),
(@ENTRY,9,329.59,-1442.08,40.31,"Bath'rah the Windwatcher"),
(@ENTRY,10,297.77,-1436.7,46.96,"Bath'rah the Windwatcher"),
(@ENTRY,11,273.74,-1433.18,50.29,"Bath'rah the Windwatcher"),
(@ENTRY,12,256.87,-1440.35,50.09,"Bath'rah the Windwatcher"),
(@ENTRY,13,253.05,-1459.09,52.09,"Bath'rah the Windwatcher"),
(@ENTRY,14,250.84,-1470.58,55.4491,"Bath'rah the Windwatcher");
@@ -0,0 +1,25 @@
-- [Q] [A/H] Freed from the Hive
-- Zukk'ash Pod SAI
SET @ENTRY := 164954;
SET @QUEST := 4265;
UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1;
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
(@ENTRY,1,0,0,19,0,100,0,@QUEST,0,0,0,12,9546,1,25000,0,0,0,8,0,0,0,-5314.81,430.89,11.79,3.46,"Zukk'ash Pod - On Quest Accept - Summon Raschal the Courier");
-- Raschal the Courier SAI
SET @ENTRY := 9546;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,54,0,100,0,0,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Raschal the Courier - Just Summoned - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,2000,2000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Raschal the Courier - On Script - Say Line 0"),
(@ENTRY*100,9,1,0,0,0,100,0,6000,6000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Raschal the Courier - On Script - Say Line 1"),
(@ENTRY*100,9,2,0,0,0,100,0,8000,8000,0,0,15,@QUEST,0,0,0,0,7,0,0,0,0,0,0,0,0,"Raschal the Courier - On Script - Quest Credit"),
(@ENTRY*100,9,3,0,0,0,100,0,2000,2000,0,0,41,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Raschal the Courier - On Script - Forced Despawn");
-- Text
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Oh man, I thought I was dead for sure. Ugh... still dizzy...",12,0,100,0,0,0,"Raschal the Courier"),
(@ENTRY,1,0,"I can get back to the Stronghold on my own, I think. Now that you bought me some time, I should be able to stealth out of here. Who ever you are... thank you. May Elune bless you always!",12,0,100,0,0,0,"Raschal the Courier");
@@ -0,0 +1,28 @@
-- [Q] [A] The Touch of Zanzil
-- Doc Mixilpixil SAI
SET @ENTRY := 7207;
SET @QUEST := 2608;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Doc Mixilpixil - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,1000,1000,0,0,5,353,0,0,0,0,0,1,0,0,0,0,0,0,0,"Doc Mixilpixil - On Script - Emote STATE_SPELLKNEELSTART"),
(@ENTRY*100,9,1,0,0,0,100,0,2000,2000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Doc Mixilpixil - On Script - Say Line 0"),
(@ENTRY*100,9,2,0,0,0,100,0,3000,3000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Doc Mixilpixil - On Script - Say Line 1"),
(@ENTRY*100,9,3,0,0,0,100,0,3000,3000,0,0,53,0,@ENTRY,0,0,0,2,1,0,0,0,0,0,0,0,"Doc Mixilpixil - On Script - Start WP"),
(@ENTRY,0,1,2,40,0,100,0,3,@ENTRY,0,0,41,5000,0,0,0,0,1,0,0,0,0,0,0,0,0,"Doc Mixilpixil - On WP 3 - Make Ready To Despawn"),
(@ENTRY,0,2,0,61,0,100,0,0,0,0,0,15,@QUEST,0,0,0,0,7,0,0,0,0,0,0,0,0,"Doc Mixilpixil - On WP 3 - Quest Credit");
-- Text
DELETE FROM `db_script_string` WHERE `entry` IN (2000000020,2000000021);
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"That's interesting...",12,0,100,0,0,0,"Doc Mixilpixil"),
(@ENTRY,1,0,"I need to consult Noram and Horatio.",12,0,100,0,0,0,"Doc Mixilpixil");
-- Waypoints
DELETE FROM `waypoints` WHERE `entry`=@ENTRY;
INSERT INTO `waypoints` (`entry`,`pointid`,`position_x`,`position_y`,`position_z`,`point_comment`) VALUES
(@ENTRY,1,-8805.29,338.5,95.09,"Doc Mixilpixil"),
(@ENTRY,2,-8804.15,325.58,95.09,"Doc Mixilpixil"),
(@ENTRY,3,-8805.56,331.96,95.09,"Doc Mixilpixil");
@@ -0,0 +1,25 @@
-- [Q] [A/H] The Torch of Retribution
-- Kalaran Windblade SAI
SET @ENTRY := 8479;
SET @QUEST := 3453;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,10000,10000,0,0,11,12511,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Cast Torch Combine"),
(@ENTRY*100,9,1,0,0,0,100,0,8000,8000,0,0,11,12511,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Cast Torch Combine"),
(@ENTRY*100,9,2,0,0,0,100,0,7000,7000,0,0,11,12511,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Cast Torch Combine"),
(@ENTRY*100,9,3,0,0,0,100,0,10000,10000,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Say Line 0"),
(@ENTRY*100,9,4,0,0,0,100,0,5000,5000,0,0,11,12511,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Cast Torch Combine"),
(@ENTRY*100,9,5,0,0,0,100,0,1000,1000,0,0,70,0,0,0,0,0,0,14,24166,149410,0,0,0,0,0,"Kalaran Windblade - On Script - Respawn Light of Retribution (GO)"),
(@ENTRY*100,9,6,0,0,0,100,0,2000,2000,0,0,70,0,0,0,0,0,0,14,16762,149047,0,0,0,0,0,"Kalaran Windblade - On Script - Respawn Torch of Retribution (GO)"),
(@ENTRY*100,9,7,0,0,0,100,0,7000,7000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Say Line 1"),
(@ENTRY*100,9,8,0,0,0,100,0,1000,1000,0,0,15,@QUEST,0,0,0,0,0,7,0,0,0,0,0,0,0,"Kalaran Windblade - On Script - Quest Credit");
-- Text
DELETE FROM `db_script_string` WHERE `entry` IN (2000000019,2000000044);
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Be patient, $N. The torch is almost done.",12,0,100,0,0,0,"Kalaran Windblade"),
(@ENTRY,1,0,"It is done...",12,0,100,0,0,0,"Kalaran Windblade");
@@ -0,0 +1,27 @@
-- [Q] [A/H] Did You Lose This?
-- Trenton Lighthammer SAI
SET @ENTRY := 7804;
SET @QUEST := 3321;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `quest_end_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,20,0,100,0,@QUEST,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Trenton Lighthammer - On Quest Complete - Say Line 0"),
(@ENTRY,0,1,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,1000,1000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,1,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,2,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,3,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,4,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,5,0,0,0,100,0,2000,2000,0,0,66,0,0,0,0,0,0,8,0,0,0,0,0,0,2.842743,"Trenton Lighthammer - On Script - Face Forge"),
(@ENTRY*100,9,6,0,0,0,100,0,1000,1000,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,7,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,8,0,0,0,100,0,1500,1500,0,0,5,28,0,0,0,0,0,1,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Emote STATE_WORK_SHEATHED"),
(@ENTRY*100,9,9,0,0,0,100,0,2000,2000,0,0,15,@QUEST,0,0,0,0,0,7,0,0,0,0,0,0,0,"Trenton Lighthammer - On Script - Quest Credit");
-- Texts
DELETE FROM `db_script_string` WHERE `entry`=2000000076;
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Hear ye, denizens of Tanaris! Let it be known $N is an exalted member of the Mithril Order. A blacksmith of honor, dedication, and infinite patience. Three cheers for $N!",14,0,100,0,0,0,"Trenton Lighthammer");
@@ -0,0 +1,18 @@
-- [Q] [A/H] Scarlet Armies Approach...
-- Orbaz Bloodbane SAI
SET @ENTRY := 28914;
SET @QUEST := 12757;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Orbaz Bloodbane - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,"Orbaz Bloodbane - On Script - Say Line 0"),
(@ENTRY*100,9,1,0,0,0,100,0,3000,3000,0,0,11,53097,0,0,0,0,0,1,0,0,0,0,0,0,0,"Orbaz Bloodbane - On Script - Cast Portal: Acherus");
-- Text
DELETE FROM `waypoint_scripts` WHERE `id`=491;
DELETE FROM `db_script_string` WHERE `entry`=2000000008;
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Make haste, $N. Use the portal!",12,0,100,25,0,0,"Orbaz Bloodlane");
@@ -0,0 +1,19 @@
-- [Q] [H] Hinott's Assistance
-- Serge Hinott SAI
SET @ENTRY := 2391;
SET @QUEST := 2480;
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY;
UPDATE `quest_template` SET `StartScript`=0,`CompleteScript`=0 WHERE `id`=@QUEST;
DELETE FROM `quest_start_scripts` WHERE `id`=@QUEST;
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (@ENTRY,@ENTRY*100);
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
(@ENTRY,0,0,0,19,0,100,0,@QUEST,0,0,0,80,@ENTRY*100,0,2,0,0,0,1,0,0,0,0,0,0,0,"Serge Hinott - On Quest Accept - Run Script"),
(@ENTRY*100,9,0,0,0,0,100,0,2000,2000,0,0,69,0,0,0,0,0,0,8,0,0,0,-4.33,-900.68,57.54,1.54,"Serge Hinott - On Script - Move To Pos"),
(@ENTRY*100,9,1,0,0,0,100,0,18000,18000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Serge Hinott - On Script - Say Line 0"),
(@ENTRY*100,9,2,0,0,0,100,0,10000,10000,0,0,15,@QUEST,0,0,0,0,0,7,0,0,0,0,0,0,0,"Serge Hinott - On Script - Quest Credit"),
(@ENTRY*100,9,3,0,0,0,100,0,1000,1000,0,0,69,0,0,0,0,0,0,8,0,0,0,-4.66,-903.92,57.54,3.48,"Serge Hinott - On Script - Move To Pos");
-- Text
DELETE FROM `db_script_string` WHERE `entry`=2000000026;
DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@ENTRY,0,0,"Whoops!",12,0,100,113,0,0,"Serge Hinott");
@@ -840,7 +840,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
me->Mount(action.mount.modelId);
}
else
me->Unmount();
me->Dismount();
break;
}
+1 -1
View File
@@ -108,7 +108,7 @@ enum EventAI_ActionType
ACTION_T_SET_SHEATH = 40, // Sheath (0-passive, 1-melee, 2-ranged)
ACTION_T_FORCE_DESPAWN = 41, // No Params
ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue, format(0-flat, 1-percent from max health)
ACTION_T_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to unmount)
ACTION_T_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount)
ACTION_T_SET_PHASE_MASK = 97,
ACTION_T_SET_STAND_STATE = 98,
@@ -994,7 +994,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
(*itr)->ToUnit()->Mount(e.action.morphOrMount.model);
}
else
(*itr)->ToUnit()->Unmount();
(*itr)->ToUnit()->Dismount();
}
delete targets;
@@ -409,7 +409,7 @@ enum SMART_ACTION
SMART_ACTION_SET_SHEATH = 40, // Sheath (0-unarmed, 1-melee, 2-ranged)
SMART_ACTION_FORCE_DESPAWN = 41, // timer
SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue(+pct, -flat)
SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to unmount)
SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount)
SMART_ACTION_SET_INGAME_PHASE_MASK = 44, // mask
SMART_ACTION_SET_DATA = 45, // Field, Data (only creature TODO)
+22 -9
View File
@@ -37,8 +37,16 @@ AccountOpResult CreateAccount(std::string username, std::string password)
if (GetId(username))
return AOR_NAME_ALREDY_EXIST; // username does already exist
LoginDatabase.PExecute("INSERT INTO account(username, sha_pass_hash, joindate) VALUES('%s', '%s', NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str());
LoginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_ADD_ACCOUNT);
stmt->setString(0, username);
stmt->setString(1, CalculateShaPassHash(username, password));
LoginDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_ADD_REALM_CHARS);
LoginDatabase.Execute(stmt);
return AOR_OK; // everything's fine
}
@@ -104,11 +112,13 @@ AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::s
normalizeString(newUsername);
normalizeString(newPassword);
std::string safeNewUsername = newUsername;
LoginDatabase.EscapeString(safeNewUsername);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_USERNAME);
LoginDatabase.PExecute("UPDATE account SET v='0', s='0', username='%s', sha_pass_hash='%s' WHERE id='%d'", safeNewUsername.c_str(),
CalculateShaPassHash(newUsername, newPassword).c_str(), accountId);
stmt->setString(0, newUsername);
stmt->setString(1, CalculateShaPassHash(newUsername, newPassword));
stmt->setUInt32(2, accountId);
LoginDatabase.Execute(stmt);
return AOR_OK;
}
@@ -126,9 +136,12 @@ AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
normalizeString(username);
normalizeString(newPassword);
// also reset s and v to force update at next realmd login
LoginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
CalculateShaPassHash(username, newPassword).c_str(), accountId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_PASSWORD);
stmt->setString(0, CalculateShaPassHash(username, newPassword));
stmt->setUInt32(1, accountId);
LoginDatabase.Execute(stmt);
return AOR_OK;
}
@@ -567,7 +567,13 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
{
// we will remove not existed criteria for all characters
sLog->outError("Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u", id);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
stmt->setUInt16(0, uint16(id));
CharacterDatabase.Execute(stmt);
continue;
}
@@ -997,6 +1003,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
}
if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
if (!data->Meets(GetPlayer(), unit))
continue;
SetCriteriaProgress(achievementCriteria, 1);
break;
}
@@ -1426,6 +1436,18 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS:
case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD:
case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL:
case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS:
case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING:
case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD:
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD:
break; // Not implemented yet :(
}
@@ -1966,7 +1988,7 @@ bool AchievementMgr::HasAchieved(uint32 achievementId) const
return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
}
bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit)
bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 /*miscValue1*/, uint64 /*miscValue2*/, Unit* unit)
{
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL))
return false;
@@ -2275,17 +2297,23 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
{
Field* fields = result->Fetch();
uint32 achievement_id = fields[0].GetUInt32();
const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievement_id);
uint32 achievementId = fields[0].GetUInt32();
const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievementId);
if (!achievement)
{
// we will remove not existed achievement for all characters
sLog->outError("Non-existing achievement %u data removed from table `character_achievement`.", achievement_id);
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u", achievement_id);
// Remove non existent achievements from all characters
sLog->outError("Non-existing achievement %u data removed from table `character_achievement`.", achievementId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEVMENT);
stmt->setUInt16(0, uint16(achievementId));
CharacterDatabase.Execute(stmt);
continue;
}
else if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
m_allCompletedAchievements.insert(achievement_id);
m_allCompletedAchievements.insert(achievementId);
} while (result->NextRow());
sLog->outString(">> Loaded %lu completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
+7 -2
View File
@@ -70,8 +70,13 @@ void LoadFromDB()
void SaveAddon(AddonInfo const& addon)
{
std::string name = addon.Name;
CharacterDatabase.EscapeString(name);
CharacterDatabase.PExecute("INSERT INTO addons (name, crc) VALUES ('%s', %u)", name.c_str(), addon.CRC);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_ADDON);
stmt->setString(0, name);
stmt->setUInt32(1, addon.CRC);
CharacterDatabase.Execute(stmt);
m_knownAddons.push_back(SavedAddon(addon.Name, addon.CRC));
}
@@ -834,7 +834,6 @@ void Battleground::EndBattleground(uint32 winner)
uint32 winner_kills = player->GetRandomWinner() ? BG_REWARD_WINNER_HONOR_LAST : BG_REWARD_WINNER_HONOR_FIRST;
uint32 loser_kills = player->GetRandomWinner() ? BG_REWARD_LOSER_HONOR_LAST : BG_REWARD_LOSER_HONOR_FIRST;
uint32 winner_arena = player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST;
// remove temporary currency bonus auras before rewarding player
player->RemoveAura(SPELL_HONORABLE_DEFENDER_25Y);
@@ -847,7 +846,7 @@ void Battleground::EndBattleground(uint32 winner)
{
UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills));
/*if (CanAwardArenaPoints())
player->ModifyConquestPoints(winner_arena);*/
player->ModifyConquestPoints(player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST);*/
if (!player->GetRandomWinner())
player->SetRandomWinner(true);
}
+6 -6
View File
@@ -154,8 +154,8 @@ class ChatHandler
bool HandleCastTargetCommand(const char *args);
bool HandleCastDestCommand(const char *args);
bool HandleCharacterCustomizeCommand(const char * args);
bool HandleCharacterChangeFactionCommand(const char * args);
bool HandleCharacterCustomizeCommand(const char* args);
bool HandleCharacterChangeFactionCommand(const char* args);
bool HandleCharacterChangeRaceCommand(const char * args);
bool HandleCharacterDeletedDeleteCommand(const char* args);
bool HandleCharacterDeletedListCommand(const char* args);
@@ -163,7 +163,7 @@ class ChatHandler
bool HandleCharacterDeletedOldCommand(const char* args);
bool HandleCharacterEraseCommand(const char* args);
bool HandleCharacterLevelCommand(const char* args);
bool HandleCharacterRenameCommand(const char * args);
bool HandleCharacterRenameCommand(const char* args);
bool HandleCharacterReputationCommand(const char* args);
bool HandleCharacterTitlesCommand(const char* args);
@@ -215,9 +215,9 @@ class ChatHandler
bool HandleResetAllCommand(const char * args);
bool HandleResetHonorCommand(const char * args);
bool HandleResetLevelCommand(const char * args);
bool HandleResetSpellsCommand(const char * args);
bool HandleResetSpellsCommand(const char* args);
bool HandleResetStatsCommand(const char * args);
bool HandleResetTalentsCommand(const char * args);
bool HandleResetTalentsCommand(const char* args);
bool HandleSendItemsCommand(const char* args);
bool HandleSendMailCommand(const char* args);
@@ -355,7 +355,7 @@ class ChatHandler
bool HandleBanHelper(BanMode mode, char const* args);
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
bool HandleUnBanHelper(BanMode mode, char const* args);
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);
void HandleLearnSkillRecipesHelper(Player* player, uint32 skill_id);
// Stores informations about a deleted character
+1 -1
View File
@@ -122,7 +122,7 @@ bool ChatHandler::HandleDismountCommand(const char* /*args*/)
return false;
}
m_session->GetPlayer()->Unmount();
m_session->GetPlayer()->Dismount();
m_session->GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);
return true;
}
+84 -42
View File
@@ -63,11 +63,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
return false;
uint32 account_id = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
// find only player from same account if any
if (!target)
if (WorldSession* session = sWorld->FindSession(account_id))
if (WorldSession* session = sWorld->FindSession(accountId))
target = session->GetPlayer();
uint32 notspeaktime = (uint32) atoi(delayStr);
@@ -76,21 +76,30 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (HasLowerSecurity (target, target_guid, true))
return false;
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_MUTE_TIME);
if (target)
{
//! Target is online, mute will be in effect right away.
int64 mutetime = time(NULL) + notspeaktime * MINUTE;
target->GetSession()->m_muteTime = mutetime;
LoginDatabase.PExecute("UPDATE account SET mutetime = " SI64FMTD " WHERE id = '%u'", mutetime, account_id);
// Target is online, mute will be in effect right away.
int64 muteTime = time(NULL) + notspeaktime * MINUTE;
target->GetSession()->m_muteTime = muteTime;
stmt->setInt64(0, muteTime);
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str());
}
else
{
//! Target is offline, mute will be in effect starting from the next login.
// Target is offline, mute will be in effect starting from the next login.
int32 muteTime = -int32(notspeaktime * MINUTE);
LoginDatabase.PExecute("UPDATE account SET mutetime = %d WHERE id = %u", muteTime, account_id);
stmt->setInt64(0, muteTime);
}
stmt->setUInt32(1, accountId);
LoginDatabase.Execute(stmt);
std::string nameLink = playerLink(target_name);
PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str());
@@ -107,11 +116,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
return false;
uint32 account_id = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
// find only player from same account if any
if (!target)
if (WorldSession* session = sWorld->FindSession(account_id))
if (WorldSession* session = sWorld->FindSession(accountId))
target = session->GetPlayer();
// must have strong lesser security level
@@ -130,7 +139,12 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
target->GetSession()->m_muteTime = 0;
}
LoginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_MUTE_TIME);
stmt->setInt64(0, 0);
stmt->setUInt32(1, accountId);
LoginDatabase.Execute(stmt);
if (target)
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
@@ -443,9 +457,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
bool ChatHandler::HandleCharacterRenameCommand(const char* args)
{
Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
@@ -460,13 +474,19 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
else
{
// check offline security
if (HasLowerSecurity(NULL, target_guid))
if (HasLowerSecurity(NULL, targetGuid))
return false;
std::string oldNameLink = playerLink(target_name);
std::string oldNameLink = playerLink(targetName);
PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));
PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
}
return true;
@@ -476,80 +496,102 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
{
Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
if (target)
{
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = playerLink(target_name);
std::string oldNameLink = playerLink(targetName);
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
bool ChatHandler::HandleCharacterChangeFactionCommand(const char * args)
bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args)
{
Player* target;
uint64 target_guid;
std::string target_name;
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
if (target)
{
// TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '64' WHERE guid = %u", target->GetGUIDLow());
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = playerLink(target_name);
std::string oldNameLink = playerLink(targetName);
// TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '64' WHERE guid = %u", GUID_LOPART(target_guid));
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args)
{
Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
if (target)
{
// TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE);
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '128' WHERE guid = %u", target->GetGUIDLow());
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = playerLink(target_name);
std::string oldNameLink = playerLink(targetName);
// TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '128' WHERE guid = %u", GUID_LOPART(target_guid));
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
+47 -25
View File
@@ -2177,28 +2177,33 @@ bool ChatHandler::HandleHoverCommand(const char *args)
return true;
}
void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel)
{
if (player)
{
player->GiveLevel(newlevel);
player->GiveLevel(newLevel);
player->InitTalentForLevel();
player->SetUInt32Value(PLAYER_XP, 0);
if (needReportToTarget(player))
{
if (oldlevel == newlevel)
if (oldLevel == newLevel)
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET, GetNameLink().c_str());
else if (oldlevel < newlevel)
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newlevel);
else if (oldLevel < newLevel)
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newLevel);
else // if (oldlevel > newlevel)
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newlevel);
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newLevel);
}
}
else
{
// update level and XP at level, all other will be updated at loading
CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
// Update level and reset XP, everything else will be updated at login
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_LEVEL);
stmt->setUInt8(0, uint8(newLevel));
stmt->setUInt32(1, GUID_LOPART(playerGuid));
CharacterDatabase.Execute(stmt);
}
}
@@ -2560,12 +2565,12 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
return true;
}
bool ChatHandler::HandleResetSpellsCommand(const char * args)
bool ChatHandler::HandleResetSpellsCommand(const char* args)
{
Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
@@ -2578,19 +2583,25 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
}
else
{
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, target_name.c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
}
return true;
}
bool ChatHandler::HandleResetTalentsCommand(const char * args)
bool ChatHandler::HandleResetTalentsCommand(const char* args)
{
Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
uint64 targetGuid;
std::string targetName;
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
{
// Try reset talents as Hunter Pet
Creature* creature = getSelectedCreature();
@@ -2628,11 +2639,16 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
target->SendTalentsInfoData(true);
return true;
}
else if (target_guid)
else if (targetGuid)
{
uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", at_flags, GUID_LOPART(target_guid));
std::string nameLink = playerLink(target_name);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
std::string nameLink = playerLink(targetName);
PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
return true;
}
@@ -2673,7 +2689,11 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
return false;
}
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'", atLogin, atLogin);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ALL_AT_LOGIN_FLAGS);
stmt->setUInt16(0, uint16(atLogin));
CharacterDatabase.Execute(stmt);
TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
@@ -3278,7 +3298,8 @@ bool ChatHandler::HandleBanListCharacterCommand(const char *args)
bool ChatHandler::HandleBanListAccountCommand(const char *args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_OLD_BANS);
LoginDatabase.Execute(stmt);
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
@@ -3383,7 +3404,8 @@ bool ChatHandler::HandleBanListHelper(QueryResult result)
bool ChatHandler::HandleBanListIPCommand(const char *args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_OLD_IP_BANS);
LoginDatabase.Execute(stmt);
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
+8 -13
View File
@@ -52,7 +52,7 @@ struct LocalDB2Data
};
template<class T>
inline void LoadDB2(uint32& availableDb2Locales, StoreProblemList1& errlist, DB2Storage<T>& storage, const std::string& db2_path, const std::string& filename)
inline void LoadDB2(StoreProblemList1& errlist, DB2Storage<T>& storage, const std::string& db2_path, const std::string& filename)
{
// compatibility format and C++ structure sizes
ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename));
@@ -60,14 +60,10 @@ inline void LoadDB2(uint32& availableDb2Locales, StoreProblemList1& errlist, DB2
++DB2FilesCount;
std::string db2_filename = db2_path + filename;
if (storage.Load(db2_filename.c_str()))
{
}
else
if (!storage.Load(db2_filename.c_str()))
{
// sort problematic db2 to (1) non compatible and (2) nonexistent
FILE * f = fopen(db2_filename.c_str(), "rb");
if (f)
if (FILE * f = fopen(db2_filename.c_str(), "rb"))
{
char buf[100];
snprintf(buf, 100,"(exist, but have %d fields instead " SIZEFMTD ") Wrong client version DBC file?", storage.GetFieldCount(), strlen(storage.GetFormat()));
@@ -84,12 +80,11 @@ void LoadDB2Stores(const std::string& dataPath)
std::string db2Path = dataPath + "dbc/";
StoreProblemList1 bad_db2_files;
uint32 availableDb2Locales = 0xFFFFFFFF;
LoadDB2(availableDb2Locales, bad_db2_files, sItemStore, db2Path, "Item.db2");
LoadDB2(availableDb2Locales, bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
LoadDB2(availableDb2Locales, bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2");
LoadDB2(availableDb2Locales, bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2");
LoadDB2(bad_db2_files, sItemStore, db2Path, "Item.db2");
LoadDB2(bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
LoadDB2(bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2");
LoadDB2(bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2");
// error checks
if (bad_db2_files.size() >= DB2FilesCount)
{
@@ -110,7 +105,7 @@ void LoadDB2Stores(const std::string& dataPath)
if (!sItemStore.LookupEntry(72068) || // last item added in 4.2.2 (14545)
!sItemExtendedCostStore.LookupEntry(3652) ) // last item extended cost added in 4.2.2 (14545)
{
sLog->outString("");
sLog->outString();
sLog->outError("Please extract correct db2 files from client 4.2.2 14545.");
exit(1);
}
+10 -9
View File
@@ -82,14 +82,14 @@ enum AchievementFlags
enum AchievementCriteriaCondition
{
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell
ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
};
#define MAX_ADDITIONAL_CRITERIA_CONDITIONS 3
@@ -179,7 +179,7 @@ enum AchievementCriteriaFlags
enum AchievementCriteriaTimedTypes
{
ACHIEVEMENT_TIMED_TYPE_EVENT = 1, // Timer is started by internal event with id in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by acceting quest with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by accepting quest with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER = 5, // Timer is started by casting a spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent
@@ -539,6 +539,7 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_EJECTABLE = 0x00000020, // ejectable
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000,
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
+1 -1
View File
@@ -748,7 +748,7 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction)
return NULL;
}
char const* GetPetName(uint32 petfamily, uint32 dbclang)
char const* GetPetName(uint32 petfamily, uint32 /*dbclang*/)
{
if (!petfamily)
return NULL;
+2 -1
View File
@@ -2184,7 +2184,8 @@ struct VehicleSeatEntry
bool CanEnterOrExit() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT; }
bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH; }
bool IsUsableByOverride() const { return (m_flags & VEHICLE_SEAT_FLAG_UNCONTROLLED)
|| (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3)); }
|| (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 |
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4)); }
bool IsEjectable() const { return m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE; }
};
+2 -14
View File
@@ -26,7 +26,7 @@
#include "GossipDef.h"
#include "World.h"
Corpse::Corpse(CorpseType type) : WorldObject()
Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES)
, m_type(type)
{
m_objectType |= TYPEMASK_CORPSE;
@@ -39,9 +39,6 @@ Corpse::Corpse(CorpseType type) : WorldObject()
m_time = time(NULL);
lootForBody = false;
if (type != CORPSE_BONES)
m_isWorldObject = true;
}
Corpse::~Corpse()
@@ -162,21 +159,12 @@ void Corpse::DeleteFromDB(SQLTransaction& trans)
trans->Append(stmt);
}
bool Corpse::LoadFromDB(uint32 guid, Field* fields)
bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
uint32 ownerGuid = fields[16].GetUInt32();
m_type = CorpseType(fields[12].GetUInt8());
if (m_type >= MAX_CORPSE_TYPE)
{
sLog->outError("Corpse (guid: %u, owner: %u) have wrong corpse type (%u), not loading.", guid, ownerGuid, m_type);
return false;
}
if (m_type != CORPSE_BONES)
m_isWorldObject = true;
float posX = fields[0].GetFloat();
float posY = fields[1].GetFloat();
float posZ = fields[2].GetFloat();
+1 -1
View File
@@ -59,7 +59,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
bool Create(uint32 guidlow, Player* owner);
void SaveToDB();
bool LoadFromDB(uint32 guid, Field* fields);
bool LoadCorpseFromDB(uint32 guid, Field* fields);
void DeleteBonesFromWorld();
void DeleteFromDB(SQLTransaction& trans);
@@ -137,7 +137,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
return true;
}
Creature::Creature(): Unit(), MapCreature(),
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapCreature(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0),
m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
@@ -160,6 +160,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL)
ResetLootMode(); // restore default loot mode
TriggerJustRespawned = false;
m_isTempWorldObject = false;
}
Creature::~Creature()
+4 -1
View File
@@ -442,7 +442,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
{
public:
explicit Creature();
explicit Creature(bool isWorldObject = false);
virtual ~Creature();
void AddToWorld();
@@ -709,6 +709,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
uint32 GetGUIDTransport() { return guid_transport; }
void FarTeleportTo(Map* map, float X, float Y, float Z, float O);
bool m_isTempWorldObject; //true when possessed
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
@@ -22,8 +22,8 @@
#include "ObjectMgr.h"
#include "TemporarySummon.h"
TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner) :
Creature(), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) :
Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
m_timer(0), m_lifetime(0)
{
m_summonerGUID = owner ? owner->GetGUID() : 0;
@@ -272,7 +272,7 @@ void TempSummon::RemoveFromWorld()
Creature::RemoveFromWorld();
}
Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner) : TempSummon(properties, owner)
Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : TempSummon(properties, owner, isWorldObject)
, m_owner(owner)
{
ASSERT(m_owner);
@@ -306,7 +306,7 @@ bool Minion::IsGuardianPet() const
return isPet() || (m_Properties && m_Properties->Category == SUMMON_CATEGORY_PET);
}
Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Minion(properties, owner, isWorldObject)
, m_bonusSpellDamage(0)
{
memset(m_statFromOwner, 0, sizeof(float)*MAX_STATS);
@@ -340,7 +340,7 @@ void Guardian::InitSummon()
m_owner->ToPlayer()->CharmSpellInitialize();
}
Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false) //maybe true?
{
ASSERT(owner->GetTypeId() == TYPEID_PLAYER);
m_owner = (Player*)owner;
@@ -24,7 +24,7 @@
class TempSummon : public Creature
{
public:
explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner);
explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
virtual ~TempSummon() {}
void Update(uint32 time);
virtual void InitStats(uint32 lifetime);
@@ -48,7 +48,7 @@ class TempSummon : public Creature
class Minion : public TempSummon
{
public:
Minion(SummonPropertiesEntry const* properties, Unit* owner);
Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
void InitStats(uint32 duration);
void RemoveFromWorld();
Unit* GetOwner() { return m_owner; }
@@ -64,7 +64,7 @@ class Minion : public TempSummon
class Guardian : public Minion
{
public:
Guardian(SummonPropertiesEntry const* properties, Unit* owner);
Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
void InitStats(uint32 duration);
bool InitStatsForLevel(uint8 level);
void InitSummon();
@@ -27,7 +27,7 @@
#include "GridNotifiersImpl.h"
#include "ScriptMgr.h"
DynamicObject::DynamicObject() : WorldObject(),
DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
_aura(NULL), _removedAura(NULL), _caster(NULL), _duration(0), _isViewpoint(false)
{
m_objectType |= TYPEMASK_DYNAMICOBJECT;
@@ -79,7 +79,7 @@ void DynamicObject::RemoveFromWorld()
}
}
bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type)
bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type)
{
SetMap(caster->GetMap());
Relocate(pos);
@@ -105,8 +105,7 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime());
m_isWorldObject = active;
if (active)
if (IsWorldObject())
setActive(true); //must before add to map to be put in world container
if (!GetMap()->AddToMap(this))
@@ -35,13 +35,13 @@ enum DynamicObjectType
class DynamicObject : public WorldObject, public GridObject<DynamicObject>
{
public:
DynamicObject();
DynamicObject(bool isWorldObject);
~DynamicObject();
void AddToWorld();
void RemoveFromWorld();
bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type);
bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type);
void Update(uint32 p_time);
void Remove();
void SetDuration(int32 newDuration);
@@ -30,7 +30,7 @@
#include "CreatureAISelector.h"
#include "Group.h"
GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue), m_AI(NULL)
GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -770,8 +770,18 @@ void GameObject::DeleteFromDB()
{
sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
sObjectMgr->DeleteGOData(m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
stmt->setUInt32(0, m_DBTableGuid);
WorldDatabase.Execute(stmt);
stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT);
stmt->setUInt32(0, m_DBTableGuid);
WorldDatabase.Execute(stmt);
}
GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid)
+19 -8
View File
@@ -82,7 +82,7 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1)
WorldObject::~WorldObject()
{
// this may happen because there are many !create/delete
if (m_isWorldObject && m_currMap)
if (IsWorldObject() && m_currMap)
{
if (GetTypeId() == TYPEID_CORPSE)
{
@@ -1174,8 +1174,8 @@ void MovementInfo::OutDebug()
sLog->outString("splineElevation: %f", splineElevation);
}
WorldObject::WorldObject(): WorldLocation(),
m_isWorldObject(false), m_name(""), m_isActive(false), m_zoneScript(NULL),
WorldObject::WorldObject(bool isWorldObject): WorldLocation(),
m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL),
m_transport(NULL), m_currMap(NULL), m_InstanceId(0),
m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0)
{
@@ -1191,6 +1191,17 @@ void WorldObject::SetWorldObject(bool on)
GetMap()->AddObjectToSwitchList(this, on);
}
bool WorldObject::IsWorldObject() const
{
if (m_isWorldObject)
return true;
if (ToCreature() && ToCreature()->m_isTempWorldObject)
return true;
return false;
}
void WorldObject::setActive(bool on)
{
if (m_isActive == on)
@@ -2004,7 +2015,7 @@ void WorldObject::SetMap(Map* map)
m_currMap = map;
m_mapId = map->GetId();
m_InstanceId = map->GetInstanceId();
if (m_isWorldObject)
if (IsWorldObject())
m_currMap->AddWorldObject(this);
}
@@ -2012,7 +2023,7 @@ void WorldObject::ResetMap()
{
ASSERT(m_currMap);
ASSERT(!IsInWorld());
if (m_isWorldObject)
if (IsWorldObject())
m_currMap->RemoveWorldObject(this);
m_currMap = NULL;
//maybe not for corpse
@@ -2102,10 +2113,10 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
switch (mask)
{
case UNIT_MASK_SUMMON:
summon = new TempSummon(properties, summoner);
summon = new TempSummon(properties, summoner, false);
break;
case UNIT_MASK_GUARDIAN:
summon = new Guardian(properties, summoner);
summon = new Guardian(properties, summoner, false);
break;
case UNIT_MASK_PUPPET:
summon = new Puppet(properties, summoner);
@@ -2114,7 +2125,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
summon = new Totem(properties, summoner);
break;
case UNIT_MASK_MINION:
summon = new Minion(properties, summoner);
summon = new Minion(properties, summoner, false);
break;
default:
return NULL;
+5 -2
View File
@@ -561,7 +561,7 @@ class FlaggedValuesArray32
class WorldObject : public Object, public WorldLocation
{
protected:
explicit WorldObject();
explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list
public:
virtual ~WorldObject();
@@ -800,6 +800,9 @@ class WorldObject : public Object, public WorldLocation
bool isActiveObject() const { return m_isActive; }
void setActive(bool isActiveObject);
void SetWorldObject(bool apply);
bool IsPermanentWorldObject() const { return m_isWorldObject; }
bool IsWorldObject() const;
template<class NOTIFIER> void VisitNearbyObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); }
template<class NOTIFIER> void VisitNearbyGridObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); }
template<class NOTIFIER> void VisitNearbyWorldObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); }
@@ -812,7 +815,6 @@ class WorldObject : public Object, public WorldLocation
double rand_chance() const { return GetMap()->mtRand.randExc(100.0);}
#endif
bool m_isWorldObject;
uint32 LastUsedScriptID;
// Transports
@@ -830,6 +832,7 @@ class WorldObject : public Object, public WorldLocation
protected:
std::string m_name;
bool m_isActive;
const bool m_isWorldObject;
ZoneScript* m_zoneScript;
// transports
@@ -25,7 +25,7 @@
#include "World.h"
#include "zlib.h"
UpdateData::UpdateData(uint16 map) : m_blockCount(0), m_map(map)
UpdateData::UpdateData(uint16 map) : m_map(map), m_blockCount(0)
{
}
+17 -14
View File
@@ -33,7 +33,7 @@
#define PET_XP_FACTOR 0.05f
Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner),
Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true),
m_usedTalentCount(0), m_removed(false), m_owner(owner),
m_petType(type), m_duration(0),
m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL)
@@ -50,8 +50,6 @@ m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL)
m_name = "Pet";
m_regenTimer = PET_FOCUS_REGEN_INTERVAL;
m_isWorldObject = true;
}
Pet::~Pet()
@@ -1205,24 +1203,29 @@ void Pet::_SaveAuras(SQLTransaction& trans)
}
}
bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do pet spell book cleanup
if (state == PETSPELL_UNCHANGED) // spell load case
{
sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.", spell_id);
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE spell = '%u'", spell_id);
sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.", spellId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_PET_SPELL);
stmt->setUInt32(0, spellId);
CharacterDatabase.Execute(stmt);
}
else
sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
PetSpellMap::iterator itr = m_spells.find(spell_id);
PetSpellMap::iterator itr = m_spells.find(spellId);
if (itr != m_spells.end())
{
if (itr->second.state == PETSPELL_REMOVED)
@@ -1261,7 +1264,7 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
newspell.active = active;
// talent: unlearn all other talent ranks (high and low)
if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -1269,7 +1272,7 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[i];
if (!rankSpellId || rankSpellId == spell_id)
if (!rankSpellId || rankSpellId == spellId)
continue;
// skip unknown ranks
@@ -1310,17 +1313,17 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
}
}
m_spells[spell_id] = newspell;
m_spells[spellId] = newspell;
if (spellInfo->IsPassive() && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState))))
CastSpell(this, spell_id, true);
CastSpell(this, spellId, true);
else
m_charmInfo->AddSpellToActionBar(spellInfo);
if (newspell.active == ACT_ENABLED)
ToggleAutocast(spellInfo, true);
uint32 talentCost = GetTalentSpellCost(spell_id);
uint32 talentCost = GetTalentSpellCost(spellId);
if (talentCost)
{
int32 free_points = GetMaxTalentPointsForLevel(getLevel());
+1 -1
View File
@@ -181,7 +181,7 @@ class Pet : public Guardian
void _LoadSpells();
void _SaveSpells(SQLTransaction& trans);
bool addSpell(uint32 spell_id, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool addSpell(uint32 spellId, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
void learnSpellHighRank(uint32 spellid);
void InitLevelupSpellsForLevel();
+109 -59
View File
@@ -630,7 +630,7 @@ UpdateMask Player::updateVisualBits;
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -842,7 +842,6 @@ Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputa
m_grantableLevels = 0;
m_ControlledByPlayer = true;
m_isWorldObject = true;
sWorld->IncreasePlayerCount();
@@ -1844,7 +1843,7 @@ void Player::setDeathState(DeathState s)
//clear aura case after resurrection by another way (spells will be applied before next death)
SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
}
bool Player::BuildEnumData(QueryResult result, ByteBuffer* data)
bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* data)
{
// 0 1 2 3 4 5 6 7
// "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
@@ -1865,7 +1864,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data)
uint32 playerBytes = fields[5].GetUInt32();
uint32 playerFlags = fields[14].GetUInt32();
uint32 atLoginFlags = fields[15].GetUInt32();
uint32 zone = fields[8].GetUInt32();
uint32 zone = fields[8].GetUInt16();
uint32 petDisplayId = 0;
uint32 petLevel = 0;
uint32 petFamily = 0;
@@ -3454,19 +3453,24 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spell_id);
CharacterDatabase.PExecute("DELETE FROM character_talent WHERE spell = '%u'", spell_id);
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
stmt->setUInt32(0, spellId);
CharacterDatabase.Execute(stmt);
}
else
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
@@ -3476,19 +3480,24 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
sLog->outError("Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spell_id);
CharacterDatabase.PExecute("DELETE FROM character_talent WHERE spell = '%u'", spell_id);
sLog->outError("Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
stmt->setUInt32(0, spellId);
CharacterDatabase.Execute(stmt);
}
else
sLog->outError("Player::addTalent: Broken spell #%u learning not allowed.", spell_id);
sLog->outError("Player::addTalent: Broken spell #%u learning not allowed.", spellId);
return false;
}
PlayerTalentMap::iterator itr = m_talents[spec]->find(spell_id);
PlayerTalentMap::iterator itr = m_talents[spec]->find(spellId);
if (itr != m_talents[spec]->end())
itr->second->state = PLAYERSPELL_UNCHANGED;
else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -3496,7 +3505,7 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[rank];
if (!rankSpellId || rankSpellId == spell_id)
if (!rankSpellId || rankSpellId == spellId)
continue;
itr = m_talents[spec]->find(rankSpellId);
@@ -3511,25 +3520,30 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
newtalent->state = state;
newtalent->spec = spec;
(*m_talents[spec])[spell_id] = newtalent;
(*m_talents[spec])[spellId] = newtalent;
return true;
}
return false;
}
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading /*=false*/)
bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'", spell_id);
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
stmt->setUInt32(0, spellId);
CharacterDatabase.Execute(stmt);
}
else
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
@@ -3539,11 +3553,16 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
sLog->outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spell_id);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'", spell_id);
sLog->outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
stmt->setUInt32(0, spellId);
CharacterDatabase.Execute(stmt);
}
else
sLog->outError("Player::addSpell: Broken spell #%u learning not allowed.", spell_id);
sLog->outError("Player::addSpell: Broken spell #%u learning not allowed.", spellId);
return false;
}
@@ -3554,18 +3573,18 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
bool disabled_case = false;
bool superceded_old = false;
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
PlayerSpellMap::iterator itr = m_spells.find(spellId);
// Remove temporary spell if found to prevent conflicts
if (itr != m_spells.end() && itr->second->state == PLAYERSPELL_TEMPORARY)
RemoveTemporarySpell(spell_id);
RemoveTemporarySpell(spellId);
else if (itr != m_spells.end())
{
uint32 next_active_spell_id = 0;
// fix activate state for non-stackable low rank (and find next spell for !active case)
if (!spellInfo->IsStackableWithRanks() && spellInfo->IsRanked())
{
if (uint32 next = sSpellMgr->GetNextSpellInChain(spell_id))
if (uint32 next = sSpellMgr->GetNextSpellInChain(spellId))
{
if (HasSpell(next))
{
@@ -3608,7 +3627,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (active)
{
if (spellInfo->IsPassive() && IsNeedCastPassiveSpellAtLearn(spellInfo))
CastSpell (this, spell_id, true);
CastSpell (this, spellId, true);
}
else if (IsInWorld())
{
@@ -3616,14 +3635,14 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
// update spell ranks in spellbook and action bar
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
data << uint32(spell_id);
data << uint32(spellId);
data << uint32(next_active_spell_id);
GetSession()->SendPacket(&data);
}
else
{
WorldPacket data(SMSG_REMOVED_SPELL, 4);
data << uint32(spell_id);
data << uint32(spellId);
GetSession()->SendPacket(&data);
}
}
@@ -3667,7 +3686,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (!disabled_case) // skip new spell adding if spell already known (disabled spells case)
{
// talent: unlearn all other talent ranks (high and low)
if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -3675,7 +3694,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[rank];
if (!rankSpellId || rankSpellId == spell_id)
if (!rankSpellId || rankSpellId == spellId)
continue;
removeSpell(rankSpellId, false, false);
@@ -3683,7 +3702,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
}
// non talent spell: learn low ranks (recursive call)
else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spell_id))
else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spellId))
{
if (!IsInWorld() || disabled) // at spells loading, no output, but allow save
addSpell(prev_spell, active, true, true, disabled);
@@ -3716,7 +3735,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
data << uint32(itr2->first);
data << uint32(spell_id);
data << uint32(spellId);
GetSession()->SendPacket(&data);
}
@@ -3731,7 +3750,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
data << uint32(spell_id);
data << uint32(spellId);
data << uint32(itr2->first);
GetSession()->SendPacket(&data);
}
@@ -3746,31 +3765,31 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
}
m_spells[spell_id] = newspell;
m_spells[spellId] = newspell;
// return false if spell disabled
if (newspell->disabled)
return false;
}
uint32 talentCost = GetTalentSpellCost(spell_id);
uint32 talentCost = GetTalentSpellCost(spellId);
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
if (!loading && talentCost > 0 && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
{
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
CastSpell(this, spell_id, true);
CastSpell(this, spellId, true);
}
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
else if (spellInfo->IsPassive())
{
if (IsNeedCastPassiveSpellAtLearn(spellInfo))
CastSpell(this, spell_id, true);
CastSpell(this, spellId, true);
}
else if (spellInfo->HasEffect(SPELL_EFFECT_SKILL_STEP))
{
CastSpell(this, spell_id, true);
CastSpell(this, spellId, true);
return false;
}
@@ -3787,9 +3806,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
// add dependent skills
uint16 maxskill = GetMaxSkillValueForLevel();
SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spell_id);
SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId);
SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spell_id);
SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId);
if (spellLearnSkill)
{
@@ -3847,7 +3866,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
// learn dependent spells
SpellLearnSpellMapBounds spell_bounds = sSpellMgr->GetSpellLearnSpellMapBounds(spell_id);
SpellLearnSpellMapBounds spell_bounds = sSpellMgr->GetSpellLearnSpellMapBounds(spellId);
for (SpellLearnSpellMap::const_iterator itr2 = spell_bounds.first; itr2 != spell_bounds.second; ++itr2)
{
@@ -3869,7 +3888,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId);
}
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spell_id);
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId);
}
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
@@ -4959,8 +4978,14 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
case CHAR_DELETE_UNLINK:
CharacterDatabase.PExecute("UPDATE characters SET deleteInfos_Name=name, deleteInfos_Account=account, deleteDate='" UI64FMTD "', name='', account=0 WHERE guid=%u", uint64(time(NULL)), guid);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_DELETE_INFO);
stmt->setUInt32(0, guid);
CharacterDatabase.Execute(stmt);
break;
}
default:
sLog->outError("Player::DeleteFromDB: Unsupported delete method: %u.", charDelete_method);
}
@@ -5880,11 +5905,13 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
float Player::OCTRegenHPPerSpirit()
{
/*
uint8 level = getLevel();
uint32 pclass = getClass();
if (level > GT_MAX_LEVEL)
level = GT_MAX_LEVEL;
*/
// Formula from PaperDollFrame script
float spirit = GetStat(STAT_SPIRIT);
@@ -7454,7 +7481,14 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
zone = sMapMgr->GetZoneId(map, posx, posy, posz);
if (zone > 0)
CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ZONE);
stmt->setUInt16(0, uint16(zone));
stmt->setUInt32(1, guidLow);
CharacterDatabase.Execute(stmt);
}
}
return zone;
@@ -12337,7 +12371,13 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
DestroyItem(slot, i, update);
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
stmt->setUInt32(0, pItem->GetGUIDLow());
CharacterDatabase.Execute(stmt);
}
RemoveEnchantmentDurations(pItem);
RemoveItemDurations(pItem);
@@ -16491,7 +16531,13 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS ||
(AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name)))
{
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid ='%u'", uint32(AT_LOGIN_RENAME), guid);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
stmt->setUInt32(1, guid);
CharacterDatabase.Execute(stmt);
return false;
}
@@ -17507,29 +17553,33 @@ void Player::_LoadMailedItems(Mail* mail)
{
Field* fields = result->Fetch();
uint32 item_guid_low = fields[11].GetUInt32();
uint32 item_template = fields[12].GetUInt32();
uint32 itemGuid = fields[11].GetUInt32();
uint32 itemTemplate = fields[12].GetUInt32();
mail->AddItem(item_guid_low, item_template);
mail->AddItem(itemGuid, itemTemplate);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item_template);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemTemplate);
if (!proto)
{
sLog->outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), item_guid_low, item_template, mail->messageID);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
sLog->outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), itemGuid, itemTemplate, mail->messageID);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
stmt->setUInt32(0, itemGuid);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
stmt->setUInt32(0, item_guid_low);
stmt->setUInt32(0, itemGuid);
CharacterDatabase.Execute(stmt);
continue;
}
Item* item = NewItemOrBag(proto);
if (!item->LoadFromDB(item_guid_low, MAKE_NEW_GUID(fields[13].GetUInt32(), 0, HIGHGUID_PLAYER), fields, item_template))
if (!item->LoadFromDB(itemGuid, MAKE_NEW_GUID(fields[13].GetUInt32(), 0, HIGHGUID_PLAYER), fields, itemTemplate))
{
sLog->outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
sLog->outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, itemGuid);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", itemGuid);
item->FSetState(ITEM_REMOVED);
SQLTransaction temp = SQLTransaction(NULL);
@@ -20208,7 +20258,7 @@ bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/)
void Player::CleanupAfterTaxiFlight()
{
m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
Unmount();
Dismount();
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
getHostileRefManager().setOnlineOfflineState(true);
}
+3 -3
View File
@@ -1122,7 +1122,7 @@ class Player : public Unit, public GridObject<Player>
void Update(uint32 time);
static bool BuildEnumData(QueryResult result, ByteBuffer* data);
static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* data);
void SetInWater(bool apply);
@@ -1665,7 +1665,7 @@ class Player : public Unit, public GridObject<Player>
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask);
void SendInitialSpells();
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading = false);
bool addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false);
void learnSpell(uint32 spell_id, bool dependent);
void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true);
void resetSpells(bool myClassOnly = false);
@@ -1689,7 +1689,7 @@ class Player : public Unit, public GridObject<Player>
void LearnTalent(uint32 talentId, uint32 talentRank);
void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank);
bool AddTalent(uint32 spell, uint8 spec, bool learning);
bool AddTalent(uint32 spellId, uint8 spec, bool learning);
bool HasTalent(uint32 spell_id, uint8 spec) const;
uint32 CalculateTalentsPoints() const;
+1 -1
View File
@@ -25,7 +25,7 @@
#include "SpellMgr.h"
#include "SpellInfo.h"
Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false)
{
m_unitTypeMask |= UNIT_MASK_TOTEM;
m_duration = 0;
@@ -633,7 +633,8 @@ void Transport::BuildStopMovePacket(Map const* targetMap)
uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim)
{
Map* map = GetMap();
Creature* creature = new Creature;
//make it world object so it will not be unloaded with grid
Creature* creature = new Creature(true);
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0))
{
@@ -666,7 +667,6 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
map->AddToMap(creature);
m_NPCPassengerSet.insert(creature);
creature->SetWorldObject(true); //so it will not be unloaded with grid
if (tguid == 0)
{
@@ -281,12 +281,10 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
uint16 index = UNIT_FIELD_ATTACK_POWER;
uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
if (ranged)
{
index = UNIT_FIELD_RANGED_ATTACK_POWER;
index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
switch (getClass())
{
@@ -392,7 +390,6 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
}
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
Pet* pet = GetPet(); //update pet's AP
@@ -932,7 +929,6 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
}
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
@@ -1283,7 +1279,6 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
+176 -171
View File
@@ -144,7 +144,7 @@ _hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo)
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Unit::Unit(): WorldObject(),
Unit::Unit(bool isWorldObject): WorldObject(isWorldObject),
m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false),
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
@@ -11967,7 +11967,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
}
void Unit::Unmount()
void Unit::Dismount()
{
if (!IsMounted())
return;
@@ -11988,7 +11988,7 @@ void Unit::Unmount()
data.appendPackGUID(GetGUID());
SendMessageToSet(&data, true);
// unmount as a vehicle
// dismount as a vehicle
if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
{
// Send other players that we are no longer a vehicle
@@ -12110,7 +12110,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
}
if (!(creature->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_MOUNTED_COMBAT))
Unmount();
Dismount();
}
for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
@@ -14369,6 +14369,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (procTriggered.empty())
return;
// Note: must SetCantProc(false) before return
if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC))
SetCantProc(true);
@@ -14393,6 +14394,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
cooldown = i->spellProcEvent->cooldown;
// Note: must SetCantProc(false) before return
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
SetCantProc(true);
@@ -14405,176 +14407,179 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
if (!handled)
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
if (!(i->effMask & (1<<effIndex)))
continue;
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
ASSERT(triggeredByAura);
switch (triggeredByAura->GetAuraType())
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
// Don`t drop charge or add cooldown for not started trigger
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
{
// target has to be valid
if (!target)
return;
if (!(i->effMask & (1<<effIndex)))
continue;
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
takeCharges = true;
break;
}
case SPELL_AURA_MANA_SHIELD:
case SPELL_AURA_DUMMY:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_OBS_MOD_POWER:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
case SPELL_AURA_MOD_MELEE_HASTE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
ASSERT(triggeredByAura);
HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
takeCharges = true;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE:
switch (triggeredByAura->GetAuraType())
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
HandleAuraRaidProcFromCharge(triggeredByAura);
takeCharges = true;
break;
}
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// Skip melee hits or instant cast spells
if (procSpell && procSpell->CalcCastTime() != 0)
takeCharges = true;
break;
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
// Skip Melee hits and spells ws wrong school
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
// Skip melee hits and spells ws wrong school or zero cost
if (procSpell &&
(procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
(triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
case SPELL_AURA_MECHANIC_IMMUNITY:
// Compare mechanic
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
takeCharges = true;
break;
case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
// Compare mechanic
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
takeCharges = true;
break;
case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
// Compare casters
if (triggeredByAura->GetCasterGUID() == target->GetGUID())
takeCharges = true;
break;
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
// CC Auras which use their amount amount to drop
// Are there any more auras which need this?
case SPELL_AURA_MOD_CONFUSE:
case SPELL_AURA_MOD_FEAR:
case SPELL_AURA_MOD_STUN:
case SPELL_AURA_MOD_ROOT:
case SPELL_AURA_TRANSFORM:
{
// chargeable mods are breaking on hit
if (useCharges)
takeCharges = true;
else
case SPELL_AURA_PROC_TRIGGER_SPELL:
{
// Spell own direct damage at apply wont break the CC
if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
{
Aura* aura = triggeredByAura->GetBase();
// called from spellcast, should not have ticked yet
if (aura->GetDuration() == aura->GetMaxDuration())
break;
}
int32 damageLeft = triggeredByAura->GetAmount();
// No damage left
if (damageLeft < int32(damage))
i->aura->Remove();
else
triggeredByAura->SetAmount(damageLeft - damage);
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
// Don`t drop charge or add cooldown for not started trigger
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
break;
}
//case SPELL_AURA_ADD_FLAT_MODIFIER:
//case SPELL_AURA_ADD_PCT_MODIFIER:
// HandleSpellModAuraProc
//break;
default:
// nothing do, just charges counter
takeCharges = true;
break;
}
}
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
{
// target has to be valid
if (!target)
break;
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
DealSpellDamage(&damageInfo, true);
takeCharges = true;
break;
}
case SPELL_AURA_MANA_SHIELD:
case SPELL_AURA_DUMMY:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_OBS_MOD_POWER:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
case SPELL_AURA_MOD_MELEE_HASTE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
takeCharges = true;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
HandleAuraRaidProcFromCharge(triggeredByAura);
takeCharges = true;
break;
}
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
{
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
}
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// Skip melee hits or instant cast spells
if (procSpell && procSpell->CalcCastTime() != 0)
takeCharges = true;
break;
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
// Skip Melee hits and spells ws wrong school
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
// Skip melee hits and spells ws wrong school or zero cost
if (procSpell &&
(procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
(triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
case SPELL_AURA_MECHANIC_IMMUNITY:
// Compare mechanic
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
takeCharges = true;
break;
case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
// Compare mechanic
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
takeCharges = true;
break;
case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
// Compare casters
if (triggeredByAura->GetCasterGUID() == target->GetGUID())
takeCharges = true;
break;
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
takeCharges = true;
break;
// CC Auras which use their amount amount to drop
// Are there any more auras which need this?
case SPELL_AURA_MOD_CONFUSE:
case SPELL_AURA_MOD_FEAR:
case SPELL_AURA_MOD_STUN:
case SPELL_AURA_MOD_ROOT:
case SPELL_AURA_TRANSFORM:
{
// chargeable mods are breaking on hit
if (useCharges)
takeCharges = true;
else
{
// Spell own direct damage at apply wont break the CC
if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
{
Aura* aura = triggeredByAura->GetBase();
// called from spellcast, should not have ticked yet
if (aura->GetDuration() == aura->GetMaxDuration())
break;
}
int32 damageLeft = triggeredByAura->GetAmount();
// No damage left
if (damageLeft < int32(damage))
i->aura->Remove();
else
triggeredByAura->SetAmount(damageLeft - damage);
}
break;
}
//case SPELL_AURA_ADD_FLAT_MODIFIER:
//case SPELL_AURA_ADD_PCT_MODIFIER:
// HandleSpellModAuraProc
//break;
default:
// nothing do, just charges counter
takeCharges = true;
break;
} // switch (triggeredByAura->GetAuraType())
} // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
} // if (!handled)
// Remove charge (aura can be removed by triggers)
if (useCharges && takeCharges)
i->aura->DropCharge(AURA_REMOVE_BY_EXPIRE);
@@ -15908,9 +15913,9 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
if (!charmer)
return false;
// unmount players when charmed
// dismount players when charmed
if (GetTypeId() == TYPEID_PLAYER)
Unmount();
Dismount();
ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle());
@@ -17056,7 +17061,7 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
InterruptNonMeleeSpells(false);
player->StopCastingCharm();
player->StopCastingBindSight();
Unmount();
Dismount();
RemoveAurasByType(SPELL_AURA_MOUNTED);
// drop flag at invisible in bg
@@ -17156,7 +17161,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
// Vehicle just died, we die too
if (vehicle->GetBase()->getDeathState() == JUST_DIED)
setDeathState(JUST_DIED);
// If for other reason we as minion are exiting the vehicle (ejected, master unmounted) - unsummon
// If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
else
ToTempSummon()->UnSummon(2000); // Approximation
}
+3 -3
View File
@@ -66,7 +66,7 @@ enum SpellAuraInterruptFlags
AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by unmounting
AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
@@ -1443,7 +1443,7 @@ class Unit : public WorldObject
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); }
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0);
void Unmount();
void Dismount();
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void DealDamageMods(Unit* pVictim, uint32 &damage, uint32* absorb);
@@ -2235,7 +2235,7 @@ class Unit : public WorldObject
}
protected:
explicit Unit ();
explicit Unit (bool isWorldObject);
UnitAI* i_AI, *i_disabledAI;
+9 -3
View File
@@ -5217,7 +5217,7 @@ void ObjectMgr::LoadInstanceEncounters()
{
if (itr != dungeonLastBosses.end())
{
sLog->outErrorDb("Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName[0]);
sLog->outErrorDb("Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName);
continue;
}
@@ -6795,9 +6795,15 @@ void ObjectMgr::LoadCorpses()
{
Field* fields = result->Fetch();
uint32 guid = fields[16].GetUInt32();
CorpseType type = CorpseType(fields[13].GetUInt8());
if (type >= MAX_CORPSE_TYPE)
{
sLog->outError("Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type);
continue;
}
Corpse* corpse = new Corpse();
if (!corpse->LoadFromDB(guid, fields))
Corpse* corpse = new Corpse(type);
if (!corpse->LoadCorpseFromDB(guid, fields))
{
delete corpse;
continue;
+6 -1
View File
@@ -100,7 +100,12 @@ class Grid
/** Returns the number of object within the grid.
*/
unsigned int ActiveObjectsInGrid(void) const { return /*m_activeGridObjects.size()+*/i_objects.template Count<ACTIVE_OBJECT>(); }
//unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); }
template<class T>
uint32 GetWorldObjectCountInGrid() const
{
return i_objects.template Count<T>();
}
/** Inserts a container type object into the grid.
*/
+1 -1
View File
@@ -31,7 +31,7 @@ void ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32
info.UpdateTimeTracker(t_diff);
if (info.getTimeTracker().Passed())
{
if (grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(grid))
if (!grid.GetWorldObjectCountInNGrid<Player>() && !m.ActiveObjectsNearGrid(grid))
{
ObjectGridStoper worker;
TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer> visitor(worker);
+18 -4
View File
@@ -158,14 +158,28 @@ class NGrid
GetGridType(x, y).Visit(visitor);
}
unsigned int ActiveObjectsInGrid(void) const
//This gets the player count in grid
//I disable this to avoid confusion (active object usually means something else)
/*
uint32 GetActiveObjectCountInGrid() const
{
unsigned int count=0;
for (unsigned int x=0; x < N; ++x)
for (unsigned int y=0; y < N; ++y)
uint32 count = 0;
for (uint32 x = 0; x < N; ++x)
for (uint32 y = 0; y < N; ++y)
count += i_cells[x][y].ActiveObjectsInGrid();
return count;
}
*/
template<class T>
uint32 GetWorldObjectCountInNGrid() const
{
uint32 count = 0;
for (uint32 x = 0; x < N; ++x)
for (uint32 y = 0; y < N; ++y)
count += i_cells[x][y].template GetWorldObjectCountInGrid<T>();
return count;
}
private:
uint32 i_gridId;
@@ -344,7 +344,7 @@ bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
{
return AnyDeadUnitObjectInRangeCheck::operator()(u)
&& i_spellInfo->CheckTarget(i_searchObj, u, true)
&& (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(u, i_check);
}
@@ -352,14 +352,14 @@ bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
{
Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
return owner && AnyDeadUnitObjectInRangeCheck::operator()(u)
&& i_spellInfo->CheckTarget(i_searchObj, owner, true)
&& (i_spellInfo->CheckTarget(i_searchObj, owner, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(owner, i_check);
}
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
{
return AnyDeadUnitObjectInRangeCheck::operator()(u)
&& i_spellInfo->CheckTarget(i_searchObj, u, true)
&& (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(u, i_check);
}
@@ -43,7 +43,7 @@ namespace Trinity
std::set<Unit*> i_visibleNow;
Player::ClientGUIDs vis_guids;
VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs), i_data(player.GetMapId()) {}
VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) {}
template<class T> void Visit(GridRefManager<T> &m);
void SendToSelf(void);
};
+147 -33
View File
@@ -123,12 +123,30 @@ bool Group::Create(Player* leader)
sGroupMgr->RegisterGroupDbStoreId(m_dbStoreId, this);
// store group in database
CharacterDatabase.PExecute("INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '%u', '%u', '%u')",
m_dbStoreId, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod),
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6],
m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), m_raidDifficulty);
// Store group in database
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP);
uint8 index = 0;
stmt->setUInt32(index++, m_dbStoreId);
stmt->setUInt32(index++, GUID_LOPART(m_leaderGuid));
stmt->setUInt8(index++, uint8(m_lootMethod));
stmt->setUInt32(index++, GUID_LOPART(m_looterGuid));
stmt->setUInt8(index++, uint8(m_lootThreshold));
stmt->setUInt32(index++, uint32(m_targetIcons[0]));
stmt->setUInt32(index++, uint32(m_targetIcons[1]));
stmt->setUInt32(index++, uint32(m_targetIcons[2]));
stmt->setUInt32(index++, uint32(m_targetIcons[3]));
stmt->setUInt32(index++, uint32(m_targetIcons[4]));
stmt->setUInt32(index++, uint32(m_targetIcons[5]));
stmt->setUInt32(index++, uint32(m_targetIcons[6]));
stmt->setUInt32(index++, uint32(m_targetIcons[7]));
stmt->setUInt8(index++, uint8(m_groupType));
stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
stmt->setUInt32(index++, uint8(m_raidDifficulty));
CharacterDatabase.Execute(stmt);
ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
@@ -200,7 +218,15 @@ void Group::ConvertToLFG()
m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_UNK1);
m_lootMethod = NEED_BEFORE_GREED;
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_dbStoreId);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_TYPE);
stmt->setUInt8(0, uint8(m_groupType));
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
}
@@ -211,7 +237,15 @@ void Group::ConvertToRaid()
_initRaidSubGroupsCounter();
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_dbStoreId);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_TYPE);
stmt->setUInt8(0, uint8(m_groupType));
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
// update quest related GO states (quest activity dependent from raid membership)
@@ -343,8 +377,18 @@ bool Group::AddMember(Player* player)
// insert into the table if we're not a battleground group
if (!isBGGroup())
CharacterDatabase.PExecute("INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(%u, %u, %u, %u, %u)",
m_dbStoreId, GUID_LOPART(member.guid), member.flags, member.group, member.roles);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP_MEMBER);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, GUID_LOPART(member.guid));
stmt->setUInt8(2, member.flags);
stmt->setUInt8(3, member.group);
stmt->setUInt8(4, member.roles);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
sScriptMgr->OnGroupAddMember(this, player->GetGUID());
@@ -435,7 +479,11 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
}
// Remove player from group in DB
CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid=%u", GUID_LOPART(guid));
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
stmt->setUInt32(0, GUID_LOPART(guid));
CharacterDatabase.Execute(stmt);
// Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player)
@@ -530,14 +578,24 @@ void Group::ChangeLeader(uint64 guid)
}
// Same in the database
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = '%u'))",
m_dbStoreId, player->GetGUIDLow());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, player->GetGUIDLow());
CharacterDatabase.Execute(stmt);
// Copy the permanent binds from the new leader to the group
Player::ConvertInstancesToGroup(player, this, true);
// update the group leader
CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), m_dbStoreId);
// Update the group leader
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_LEADER);
stmt->setUInt32(0, player->GetGUIDLow());
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
m_leaderGuid = player->GetGUID();
@@ -1322,7 +1380,14 @@ bool Group::_setMembersGroup(uint64 guid, uint8 group)
SubGroupCounterIncrease(group);
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid));
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_SUBGROUP);
stmt->setUInt8(0, group);
stmt->setUInt32(1, GUID_LOPART(guid));
CharacterDatabase.Execute(stmt);
}
return true;
}
@@ -1366,7 +1431,14 @@ void Group::ChangeMembersGroup(uint64 guid, uint8 group)
// Preserve new sub group in database for non-raid groups
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid));
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_SUBGROUP);
stmt->setUInt8(0, group);
stmt->setUInt32(1, GUID_LOPART(guid));
CharacterDatabase.Execute(stmt);
}
// In case the moved player is online, update the player object with the new sub group references
if (Player* player = ObjectAccessor::FindPlayer(guid))
@@ -1554,7 +1626,14 @@ void Group::SetDungeonDifficulty(Difficulty difficulty)
{
m_dungeonDifficulty = difficulty;
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, m_dbStoreId);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_DIFFICULTY);
stmt->setUInt8(0, uint8(m_dungeonDifficulty));
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1571,7 +1650,14 @@ void Group::SetRaidDifficulty(Difficulty difficulty)
{
m_raidDifficulty = difficulty;
if (!isBGGroup())
CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, m_dbStoreId);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_RAID_DIFFICULTY);
stmt->setUInt8(0, uint8(m_raidDifficulty));
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1609,9 +1695,9 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
{
InstanceSave* p = itr->second.save;
InstanceSave* instanceSave = itr->second.save;
const MapEntry* entry = sMapStore.LookupEntry(itr->first);
if (!entry || entry->IsRaid() != isRaid || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
if (!entry || entry->IsRaid() != isRaid || (!instanceSave->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
{
++itr;
continue;
@@ -1629,10 +1715,10 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
bool isEmpty = true;
// if the map is loaded, reset it
Map* map = sMapMgr->FindMap(p->GetMapId(), p->GetInstanceId());
if (map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !p->CanReset()))
Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
if (map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !instanceSave->CanReset()))
{
if (p->CanReset())
if (instanceSave->CanReset())
isEmpty = ((InstanceMap*)map)->Reset(method);
else
isEmpty = !map->HavePlayers();
@@ -1641,25 +1727,32 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
if (SendMsgTo)
{
if (isEmpty)
SendMsgTo->SendResetInstanceSuccess(p->GetMapId());
SendMsgTo->SendResetInstanceSuccess(instanceSave->GetMapId());
else
SendMsgTo->SendResetInstanceFailed(0, p->GetMapId());
SendMsgTo->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY)
{
// do not reset the instance, just unbind if others are permanently bound to it
if (p->CanReset())
p->DeleteFromDB();
if (instanceSave->CanReset())
instanceSave->DeleteFromDB();
else
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId());
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE);
stmt->setUInt32(0, instanceSave->GetInstanceId());
CharacterDatabase.Execute(stmt);
}
// i don't know for sure if hash_map iterators
m_boundInstances[diff].erase(itr);
itr = m_boundInstances[diff].begin();
// this unloads the instance save unless online players are bound to it
// (eg. permanent binds or GM solo binds)
p->RemoveGroup(this);
instanceSave->RemoveGroup(this);
}
else
++itr;
@@ -1712,7 +1805,15 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, boo
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
if (!load && (!bind.save || permanent != bind.perm || save != bind.save))
CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", m_dbStoreId, save->GetInstanceId(), permanent);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP_INSTANCE);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, save->GetInstanceId());
stmt->setBool(2, permanent);
CharacterDatabase.Execute(stmt);
}
if (bind.save != save)
{
@@ -1736,7 +1837,15 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
if (itr != m_boundInstances[difficulty].end())
{
if (!unload)
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", m_dbStoreId, itr->second.save->GetInstanceId());
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_GUID);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, itr->second.save->GetInstanceId());
CharacterDatabase.Execute(stmt);
}
itr->second.save->RemoveGroup(this); // save can become invalid
m_boundInstances[difficulty].erase(itr);
}
@@ -1965,7 +2074,12 @@ void Group::SetGroupMemberFlag(uint64 guid, bool apply, GroupMemberFlags flag)
ToggleGroupMemberFlag(slot, flag, apply);
// Preserve the new setting in the db
CharacterDatabase.PExecute("UPDATE group_member SET memberFlags='%u' WHERE memberGuid='%u'", slot->flags, GUID_LOPART(guid));
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_FLAG);
stmt->setUInt8(0, slot->flags);
stmt->setUInt32(0, GUID_LOPART(guid));
CharacterDatabase.Execute(stmt);
// Broadcast the changes to the group
SendUpdate();
+17 -4
View File
@@ -138,7 +138,14 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
{
// save the resettime for normal instances only when they get unloaded
if (time_t resettime = itr->second->GetResetTimeForDB())
CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId);
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_INSTANCE_RESETTIME);
stmt->setUInt32(0, uint32(resettime));
stmt->setUInt32(1, InstanceId);
CharacterDatabase.Execute(stmt);
}
delete itr->second;
m_instanceSaveById.erase(itr);
@@ -573,13 +580,19 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
if (period < DAY)
period = DAY;
uint64 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff;
uint32 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff;
SetResetTimeFor(mapid, difficulty, next_reset);
ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0));
// update it in the DB
CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%d' AND difficulty = '%d'", uint32(next_reset), mapid, difficulty);
// Update it in the DB
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GLOBAL_INSTANCE_RESETTIME);
stmt->setUInt32(0, next_reset);
stmt->setUInt16(1, uint16(mapid));
stmt->setUInt8(2, uint8(difficulty));
CharacterDatabase.Execute(stmt);
}
// note: this isn't fast but it's meant to be executed very rarely
+33 -22
View File
@@ -30,6 +30,7 @@
#include "MapManager.h"
#include "ObjectMgr.h"
#include "Group.h"
#include "LFGMgr.h"
union u_map_magic
{
@@ -58,7 +59,7 @@ Map::~Map()
while (!i_worldObjects.empty())
{
WorldObject* obj = *i_worldObjects.begin();
ASSERT(obj->m_isWorldObject);
ASSERT(obj->IsWorldObject());
//ASSERT(obj->GetTypeId() == TYPEID_CORPSE);
obj->RemoveFromWorld();
obj->ResetMap();
@@ -237,7 +238,7 @@ template<class T>
void Map::AddToGrid(T* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
if (obj->m_isWorldObject)
if (obj->IsWorldObject())
grid->GetGridType(cell.CellX(), cell.CellY()).template AddWorldObject<T>(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).template AddGridObject<T>(obj);
@@ -247,7 +248,7 @@ template<>
void Map::AddToGrid(Creature* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
if (obj->m_isWorldObject)
if (obj->IsWorldObject())
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
@@ -255,9 +256,9 @@ void Map::AddToGrid(Creature* obj, Cell const& cell)
obj->SetCurrentCell(cell);
}
template<class T>
void Map::SwitchGridContainers(T* obj, bool on)
void Map::SwitchGridContainers(Creature* obj, bool on)
{
ASSERT(!obj->IsPermanentWorldObject());
CellCoord p = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
if (!p.IsCoordValid())
{
@@ -277,15 +278,18 @@ void Map::SwitchGridContainers(T* obj, bool on)
obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
if (on)
grid.AddWorldObject<T>(obj);
{
grid.AddWorldObject(obj);
AddWorldObject(obj);
}
else
grid.AddGridObject<T>(obj);
obj->m_isWorldObject = on;
{
grid.AddGridObject(obj);
RemoveWorldObject(obj);
}
obj->m_isTempWorldObject = on;
}
template void Map::SwitchGridContainers(Creature*, bool);
//template void Map::SwitchGridContainers(DynamicObject*, bool);
template<class T>
void Map::DeleteFromWorld(T* obj)
{
@@ -908,8 +912,15 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
const uint32 y = ngrid.getY();
{
if (!unloadAll && ActiveObjectsNearGrid(ngrid))
return false;
if (!unloadAll)
{
//pets, possessed creatures (must be active), transport passengers
if (ngrid.GetWorldObjectCountInNGrid<Creature>())
return false;
if (ActiveObjectsNearGrid(ngrid))
return false;
}
sLog->outDebug(LOG_FILTER_MAPS, "Unloading grid[%u, %u] for map %u", x, y, GetId());
@@ -1974,15 +1985,8 @@ void Map::RemoveAllObjectsInRemoveList()
bool on = itr->second;
i_objectsToSwitch.erase(itr);
switch (obj->GetTypeId())
{
case TYPEID_UNIT:
if (!obj->ToCreature()->isPet())
SwitchGridContainers(obj->ToCreature(), on);
break;
default:
break;
}
if (obj->GetTypeId() == TYPEID_UNIT && !obj->IsPermanentWorldObject())
SwitchGridContainers(obj->ToCreature(), on);
}
//sLog->outDebug(LOG_FILTER_MAPS, "Object remover 1 check.");
@@ -2318,6 +2322,13 @@ bool InstanceMap::AddPlayerToMap(Player* player)
ASSERT(playerBind->save == mapSave);
}
}
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 (dungeon->map == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM)
player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
}
// for normal instances cancel the reset schedule when the
+1 -1
View File
@@ -405,7 +405,7 @@ class Map : public GridRefManager<NGridType>
void RemoveFromActive(Creature* obj);
template<class T> void SwitchGridContainers(T* obj, bool active);
void SwitchGridContainers(Creature* creature, bool toWorldContainer);
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER &notifier);
+2 -1
View File
@@ -946,8 +946,9 @@ enum TrinityStrings
LANG_GOINFO_NAME = 5027,
LANG_GOINFO_LOOTID = 5028,
LANG_COMMAND_LOOKUP_MAX_RESULTS = 5029,
// Room for more Trinity strings 5030-9999
LANG_FLEE = 5030,
LANG_NPCINFO_AIINFO = 5031,
// Room for more Trinity strings 5032-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,
@@ -1367,6 +1367,8 @@ MovementStatusElements* GetMovementStatusElementsSequence(Opcodes opcode)
return MovementStartSwimSequence;
case MSG_MOVE_STOP_ASCEND:
return MovementStopAscendSequence;
default:
break;
}
return NULL;
}
@@ -197,7 +197,7 @@ bool LoginQueryHolder::Initialize()
return res;
}
void WorldSession::HandleCharEnum(QueryResult result)
void WorldSession::HandleCharEnum(PreparedQueryResult result)
{
WorldPacket data(SMSG_CHAR_ENUM, 270);
@@ -304,35 +304,16 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/)
CharacterDatabase.Execute(stmt);
/// get all the data necessary for loading all characters (along with their pets) on the account
_charEnumCallback =
CharacterDatabase.AsyncPQuery(
!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
"WHERE characters.account = '%u' ORDER BY characters.guid"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20 21
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid, character_declinedname.genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
"WHERE characters.account = '%u' ORDER BY characters.guid",
PET_SAVE_AS_CURRENT, GetAccountId()
);
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM_DECLINED_NAME);
else
stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM);
stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
stmt->setUInt32(1, GetAccountId());
_charEnumCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
@@ -485,7 +466,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
This is much more efficient than synchronous requests on packet handler, and much less DoS prone.
It also prevents data syncrhonisation errors.
*/
switch (createInfo->Stage)
switch (_charCreateCallback.GetStage())
{
case 0:
{
@@ -495,8 +476,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_NAME_IN_USE);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
@@ -507,8 +487,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
_charCreateCallback.FreeResult();
_charCreateCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
createInfo->Stage++;
_charCreateCallback.NextStage();
}
break;
case 1:
@@ -529,8 +508,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_ACCOUNT_LIMIT);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
@@ -542,8 +520,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
_charCreateCallback.FreeResult();
_charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
createInfo->Stage++;
_charCreateCallback.NextStage();
}
break;
case 2:
@@ -559,8 +536,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_SERVER_LIMIT);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
}
@@ -576,11 +552,11 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
stmt->setUInt32(0, GetAccountId());
stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
_charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
createInfo->Stage++;
_charCreateCallback.NextStage();
return;
}
createInfo->Stage++;
_charCreateCallback.NextStage();
HandleCharCreateCallback(PreparedQueryResult(NULL), createInfo); // Will jump to case 3
}
break;
@@ -614,8 +590,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
}
@@ -642,8 +617,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_PVP_TEAMS_VIOLATION);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
}
@@ -675,8 +649,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
}
@@ -697,8 +670,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
@@ -719,8 +691,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_ERROR);
SendPacket(&data);
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
return;
}
@@ -761,8 +732,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass());
delete createInfo;
_charCreateCallback.SetParam(NULL);
_charCreateCallback.FreeResult();
_charCreateCallback.Reset();
}
break;
}
@@ -858,7 +828,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data)
playerGuid = BitConverter::ToUInt64(bytes);
sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", playerGuid);
sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", GUID_LOPART(playerGuid));
if (!CharCanLogin(GUID_LOPART(playerGuid)))
{
@@ -888,7 +858,7 @@ void WorldSession::HandleLoadScreenOpcode(WorldPacket& recvPacket)
// TODO: Do something with this packet
}
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
uint64 playerGuid = holder->GetGuid();
@@ -1201,13 +1171,13 @@ void WorldSession::HandleShowingCloakOpcode(WorldPacket& recv_data)
void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
{
uint64 guid;
std::string newname;
std::string newName;
recv_data >> guid;
recv_data >> newname;
recv_data >> newName;
// prevent character rename to invalid name
if (!normalizePlayerName(newname))
if (!normalizePlayerName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_NO_NAME);
@@ -1215,7 +1185,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
uint8 res = ObjectMgr::CheckPlayerName(newname, true);
uint8 res = ObjectMgr::CheckPlayerName(newName, true);
if (res != CHAR_NAME_SUCCESS)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
@@ -1225,7 +1195,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
}
// check name limitations
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname))
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_RESERVED);
@@ -1233,21 +1203,22 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
std::string escaped_newname = newname;
CharacterDatabase.EscapeString(escaped_newname);
// make sure that the character belongs to the current account, that rename at login is enabled
// Ensure that the character belongs to the current account, that rename at login is enabled
// and that there is no character with the desired new name
_charRenameCallback.SetParam(newname);
_charRenameCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery(
"SELECT guid, name FROM characters WHERE guid = %d AND account = %d AND (at_login & %d) = %d AND NOT EXISTS (SELECT NULL FROM characters WHERE name = '%s')",
GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str()
)
);
_charRenameCallback.SetParam(newName);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_FREE_NAME);
stmt->setUInt32(0, GUID_LOPART(guid));
stmt->setUInt32(1, GetAccountId());
stmt->setUInt16(2, AT_LOGIN_RENAME);
stmt->setUInt16(3, AT_LOGIN_RENAME);
stmt->setString(4, newName);
_charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname)
void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName)
{
if (!result)
{
@@ -1257,22 +1228,38 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std:
return;
}
uint32 guidLow = result->Fetch()[0].GetUInt32();
Field* fields = result->Fetch();
uint32 guidLow = fields[0].GetUInt32();
std::string oldName = fields[1].GetString();
uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
std::string oldname = result->Fetch()[1].GetString();
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
// Update name and at_login flag in the db
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_NAME);
sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
stmt->setString(0, newName);
stmt->setUInt16(1, AT_LOGIN_RENAME);
stmt->setUInt32(2, guidLow);
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
CharacterDatabase.Execute(stmt);
// Removed declined name from db
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
stmt->setUInt32(0, guidLow);
CharacterDatabase.Execute(stmt);
sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str());
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newName.size()+1));
data << uint8(RESPONSE_SUCCESS);
data << uint64(guid);
data << newname;
data << newName;
SendPacket(&data);
sWorld->UpdateCharacterNameData(guidLow, newname);
sWorld->UpdateCharacterNameData(guidLow, newName);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
@@ -538,24 +538,23 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket & recv_data)
if (!normalizePlayerName(friendName))
return;
CharacterDatabase.EscapeString(friendName); // prevent SQL injection - normal name must not be changed by this call
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to add friend : '%s'", GetPlayer()->GetName(), friendName.c_str());
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to add friend : '%s'",
GetPlayer()->GetName(), friendName.c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUID_RACE_ACC_BY_NAME);
stmt->setString(0, friendName);
_addFriendCallback.SetParam(friendNote);
_addFriendCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery("SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str())
);
_addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult result, std::string friendNote)
void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string friendNote)
{
if (!GetPlayer())
return;
uint64 friendGuid;
uint32 friendAcctid;
uint32 friendAccountId;
uint32 team;
FriendsResult friendResult;
@@ -564,11 +563,13 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult result, std::string
if (result)
{
friendGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
team = Player::TeamForRace((*result)[1].GetUInt8());
friendAcctid = (*result)[2].GetUInt32();
Field* fields = result->Fetch();
if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAcctid, realmID)))
friendGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
team = Player::TeamForRace(fields[1].GetUInt8());
friendAccountId = fields[2].GetUInt32();
if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
{
if (friendGuid)
{
@@ -620,22 +621,24 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE");
std::string IgnoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
recv_data >> IgnoreName;
recv_data >> ignoreName;
if (!normalizePlayerName(IgnoreName))
if (!normalizePlayerName(ignoreName))
return;
CharacterDatabase.EscapeString(IgnoreName); // prevent SQL injection - normal name must not be changed by this call
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to Ignore: '%s'",
GetPlayer()->GetName(), IgnoreName.c_str());
GetPlayer()->GetName(), ignoreName.c_str());
_addIgnoreCallback = CharacterDatabase.AsyncPQuery("SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUID_BY_NAME);
stmt->setString(0, ignoreName);
_addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult result)
void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -713,9 +716,12 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)
sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", type.c_str());
sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", content.c_str());
CharacterDatabase.EscapeString(type);
CharacterDatabase.EscapeString(content);
CharacterDatabase.PExecute ("INSERT INTO bugreport (type, content) VALUES('%s', '%s')", type.c_str(), content.c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_BUG_REPORT);
stmt->setString(0, type);
stmt->setString(1, content);
CharacterDatabase.Execute(stmt);
}
void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
@@ -1612,7 +1618,7 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recv_data*/)
return;
}
_player->Unmount();
_player->Dismount();
_player->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
@@ -295,7 +295,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
// if we boarded a transport, add us to it
if (plMover && !plMover->GetTransport())
{
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
if ((*iter)->GetGUID() == movementInfo.t_guid)
@@ -593,19 +593,22 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
HaveSpline = false;
MovementStatusElements *sequence = GetMovementStatusElementsSequence(data.GetOpcode());
if(sequence == NULL)
if (sequence == NULL)
return;
uint8 guid[8];
uint8 tguid[8];
*(uint64*)guid = 0;
*(uint64*)tguid = 0;
for(uint32 i=0; i < MSE_COUNT; i++)
BytesGuid guid;
BytesGuid tguid;
guid.guid = 0;
tguid.guid = 0;
for (uint32 i = 0; i < MSE_COUNT; i++)
{
MovementStatusElements element = sequence[i];
if (element >= MSEGuidByte0 && element <= MSEGuidByte7)
{
data.ReadByteMask(guid[element - MSEGuidByte0]);
data.ReadByteMask(guid.bytes[element - MSEGuidByte0]);
continue;
}
@@ -613,13 +616,13 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
element <= MSETransportGuidByte7)
{
if (HaveTransportData)
data.ReadByteMask(tguid[element - MSETransportGuidByte0]);
data.ReadByteMask(tguid.bytes[element - MSETransportGuidByte0]);
continue;
}
if (element >= MSEGuidByte0_2 && element <= MSEGuidByte7_2)
{
data.ReadByteSeq(guid[element - MSEGuidByte0_2]);
data.ReadByteSeq(guid.bytes[element - MSEGuidByte0_2]);
continue;
}
@@ -627,7 +630,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
element <= MSETransportGuidByte7_2)
{
if (HaveTransportData)
data.ReadByteSeq(tguid[element - MSETransportGuidByte0_2]);
data.ReadByteSeq(tguid.bytes[element - MSETransportGuidByte0_2]);
continue;
}
@@ -738,8 +741,8 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
}
}
mi->guid = *(uint64*)guid;
mi->t_guid = *(uint64*)tguid;
mi->guid = guid.guid;
mi->t_guid = tguid.guid;
if (HaveTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
if (GetPlayer()->GetTransport())
@@ -901,4 +904,4 @@ void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi)
WPError(false, "Incorrect sequence element detected at ReadMovementInfo");
}
}
}
}
@@ -520,14 +520,17 @@ void WorldSession::HandleListStabledPetsOpcode(WorldPacket & recv_data)
void WorldSession::SendStablePet(uint64 guid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOTS_DETAIL);
stmt->setUInt32(0, _player->GetGUIDLow());
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
_sendStabledPetCallback.SetParam(guid);
_sendStabledPetCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery("SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot",
_player->GetGUIDLow(), PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT)
);
_sendStabledPetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::SendStablePetCallback(QueryResult result, uint64 guid)
void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid)
{
if (!GetPlayer())
return;
@@ -619,39 +622,43 @@ void WorldSession::HandleStablePet(WorldPacket & recv_data)
return;
}
_stablePetCallback = CharacterDatabase.AsyncPQuery("SELECT owner, slot, id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ",
_player->GetGUIDLow(), PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOTS);
stmt->setUInt32(0, _player->GetGUIDLow());
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
_stablePetCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleStablePetCallback(QueryResult result)
void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
{
if (!GetPlayer())
return;
uint32 free_slot = 1;
uint8 freeSlot = 1;
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 slot = fields[1].GetUInt32();
uint8 slot = fields[1].GetUInt8();
// slots ordered in query, and if not equal then free
if (slot != free_slot)
if (slot != freeSlot)
break;
// this slot not free, skip
++free_slot;
++freeSlot;
}
while (result->NextRow());
}
WorldPacket data(SMSG_STABLE_RESULT, 1);
if (free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
if (freeSlot > 0 && freeSlot <= GetPlayer()->m_stableSlots)
{
_player->RemovePet(_player->GetPet(), PetSaveMode(free_slot));
_player->RemovePet(_player->GetPet(), PetSaveMode(freeSlot));
SendStableResult(STABLE_SUCCESS_STABLE);
}
else
@@ -676,32 +683,36 @@ void WorldSession::HandleUnstablePet(WorldPacket & recv_data)
if (GetPlayer()->HasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_ENTRY);
stmt->setUInt32(0, _player->GetGUIDLow());
stmt->setUInt32(1, petnumber);
stmt->setUInt8(2, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(3, PET_SAVE_LAST_STABLE_SLOT);
_unstablePetCallback.SetParam(petnumber);
_unstablePetCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'",
_player->GetGUIDLow(), petnumber, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT)
);
_unstablePetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::HandleUnstablePetCallback(QueryResult result, uint32 petnumber)
void WorldSession::HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId)
{
if (!GetPlayer())
return;
uint32 creature_id = 0;
uint32 petEntry = 0;
if (result)
{
Field* fields = result->Fetch();
creature_id = fields[0].GetUInt32();
petEntry = fields[0].GetUInt32();
}
if (!creature_id)
if (!petEntry)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature_id);
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
if (!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets()))
{
// if problem in exotic pet
@@ -723,11 +734,11 @@ void WorldSession::HandleUnstablePetCallback(QueryResult result, uint32 petnumbe
if (pet)
_player->RemovePet(pet, PET_SAVE_AS_DELETED);
Pet* newpet = new Pet(_player, HUNTER_PET);
if (!newpet->LoadPetFromDB(_player, creature_id, petnumber))
Pet* newPet = new Pet(_player, HUNTER_PET);
if (!newPet->LoadPetFromDB(_player, petEntry, petId))
{
delete newpet;
newpet = NULL;
delete newPet;
newPet = NULL;
SendStableResult(STABLE_ERR_STABLE);
return;
}
@@ -777,9 +788,9 @@ void WorldSession::HandleStableSwapPet(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_SWAP_PET.");
uint64 npcGUID;
uint32 pet_number;
uint32 petId;
recv_data >> npcGUID >> pet_number;
recv_data >> npcGUID >> petId;
if (!CheckStableMaster(npcGUID))
{
@@ -799,15 +810,18 @@ void WorldSession::HandleStableSwapPet(WorldPacket & recv_data)
return;
}
// find swapped pet slot in stable
_stableSwapCallback.SetParam(pet_number);
_stableSwapCallback.SetFutureResult(
CharacterDatabase.PQuery("SELECT slot, entry FROM character_pet WHERE owner = '%u' AND id = '%u'",
_player->GetGUIDLow(), pet_number)
);
// Find swapped pet slot in stable
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOT_BY_ID);
stmt->setUInt32(0, _player->GetGUIDLow());
stmt->setUInt32(1, petId);
_stableSwapCallback.SetParam(petId);
_stableSwapCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnumber)
void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId)
{
if (!GetPlayer())
return;
@@ -820,16 +834,16 @@ void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnum
Field* fields = result->Fetch();
uint32 slot = fields[0].GetUInt8();
uint32 creature_id = fields[1].GetUInt32();
uint32 slot = fields[0].GetUInt8();
uint32 petEntry = fields[1].GetUInt32();
if (!creature_id)
if (!petEntry)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature_id);
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
if (!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets()))
{
// if problem in exotic pet
@@ -847,7 +861,7 @@ void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnum
// summon unstabled pet
Pet* newpet = new Pet(_player);
if (!newpet->LoadPetFromDB(_player, creature_id, petnumber))
if (!newpet->LoadPetFromDB(_player, petEntry, petId))
{
delete newpet;
SendStableResult(STABLE_ERR_STABLE);
@@ -372,18 +372,18 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_RENAME"); // ok
uint64 petitionguid;
uint64 petitionGuid;
uint32 type;
std::string newname;
std::string newName;
recv_data >> petitionguid; // guid
recv_data >> newname; // new name
recv_data >> petitionGuid; // guid
recv_data >> newName; // new name
Item* item = _player->GetItemByGuid(petitionguid);
Item* item = _player->GetItemByGuid(petitionGuid);
if (!item)
return;
QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid));
if (result)
{
@@ -392,46 +392,48 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
}
else
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid));
return;
}
if (type == GUILD_CHARTER_TYPE)
{
if (sGuildMgr->GetGuildByName(newname))
if (sGuildMgr->GetGuildByName(newName))
{
Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newname);
Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newName);
return;
}
if (sObjectMgr->IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
{
Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newname);
Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newName);
return;
}
}
else
{
if (sArenaTeamMgr->GetArenaTeamByName(newname))
if (sArenaTeamMgr->GetArenaTeamByName(newName))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
return;
}
if (sObjectMgr->IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_INVALID);
return;
}
}
std::string db_newname = newname;
CharacterDatabase.EscapeString(db_newname);
CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
db_newname.c_str(), GUID_LOPART(petitionguid));
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str());
WorldPacket data(MSG_PETITION_RENAME, (8+newname.size()+1));
data << uint64(petitionguid);
data << newname;
stmt->setString(0, newName);
stmt->setUInt32(1, GUID_LOPART(petitionGuid));
CharacterDatabase.Execute(stmt);
sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str());
WorldPacket data(MSG_PETITION_RENAME, (8+newName.size()+1));
data << uint64(petitionGuid);
data << newName;
SendPacket(&data);
}
@@ -440,34 +442,34 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_SIGN"); // ok
Field* fields;
uint64 petitionguid;
uint64 petitionGuid;
uint8 unk;
recv_data >> petitionguid; // petition guid
recv_data >> petitionGuid; // petition guid
recv_data >> unk;
QueryResult result = CharacterDatabase.PQuery(
"SELECT ownerguid, "
" (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
" type "
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid), GUID_LOPART(petitionGuid));
if (!result)
{
sLog->outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionguid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
sLog->outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionGuid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
return;
}
fields = result->Fetch();
uint64 ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
uint64 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
uint8 signs = fields[1].GetUInt8();
uint32 type = fields[2].GetUInt32();
uint32 plguidlo = _player->GetGUIDLow();
if (GUID_LOPART(ownerguid) == plguidlo)
uint32 playerGuid = _player->GetGUIDLow();
if (GUID_LOPART(ownerGuid) == playerGuid)
return;
// not let enemies sign guild charter
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerguid))
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerGuid))
{
if (type != GUILD_CHARTER_TYPE)
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
@@ -519,12 +521,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
//client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
//not allow sign another player from already sign player account
result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid));
result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionGuid));
if (result)
{
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
data << uint64(petitionguid);
data << uint64(petitionGuid);
data << uint64(_player->GetGUID());
data << (uint32)PETITION_SIGN_ALREADY_SIGNED;
@@ -532,17 +534,24 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
SendPacket(&data);
// update for owner if online
if (Player* owner = ObjectAccessor::FindPlayer(ownerguid))
if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
return;
}
CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(ownerguid), GUID_LOPART(petitionguid), plguidlo, GetAccountId());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_PETITION_SIGNATURE);
sLog->outDebug(LOG_FILTER_NETWORKIO, "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(), plguidlo, GetAccountId());
stmt->setUInt32(0, GUID_LOPART(ownerGuid));
stmt->setUInt32(1, GUID_LOPART(petitionGuid));
stmt->setUInt32(2, playerGuid);
stmt->setUInt32(3, GetAccountId());
CharacterDatabase.Execute(stmt);
sLog->outDebug(LOG_FILTER_NETWORKIO, "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionGuid), _player->GetName(), playerGuid, GetAccountId());
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
data << uint64(petitionguid);
data << uint64(petitionGuid);
data << uint64(_player->GetGUID());
data << uint32(PETITION_SIGN_OK);
@@ -555,7 +564,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
if (Player* owner = ObjectAccessor::FindPlayer(ownerguid))
if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
}
@@ -169,7 +169,6 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
{
const int GO_DATA_FIELDS_NUMBER = 32;
uint32 entry;
recv_data >> entry;
uint64 guid;
@@ -213,26 +213,26 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
sLog->outDetail("bagIndex: %u, slot: %u", bagIndex, slot);
Item* pItem = pUser->GetItemByPos(bagIndex, slot);
if (!pItem)
Item* item = pUser->GetItemByPos(bagIndex, slot);
if (!item)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
return;
}
ItemTemplate const* proto = pItem->GetTemplate();
ItemTemplate const* proto = item->GetTemplate();
if (!proto)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
return;
}
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
{
pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pItem, NULL);
pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
sLog->outError("Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!",
pUser->GetName(), pUser->GetGUIDLow(), pItem->GetGUIDLow(), proto->ItemId);
pUser->GetName(), pUser->GetGUIDLow(), item->GetGUIDLow(), proto->ItemId);
return;
}
@@ -244,43 +244,48 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
if (!lockInfo)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL);
sLog->outError("WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", pItem->GetGUIDLow(), lockId);
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
sLog->outError("WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUIDLow(), lockId);
return;
}
// was not unlocked yet
if (pItem->IsLocked())
if (item->IsLocked())
{
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL);
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
return;
}
}
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped?
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped?
{
QueryResult result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
QueryResult result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", item->GetGUIDLow());
if (result)
{
Field* fields = result->Fetch();
uint32 entry = fields[0].GetUInt32();
uint32 flags = fields[1].GetUInt32();
pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0);
pItem->SetEntry(entry);
pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
pItem->SetState(ITEM_CHANGED, pUser);
item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0);
item->SetEntry(entry);
item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
item->SetState(ITEM_CHANGED, pUser);
}
else
{
sLog->outError("Wrapped item %u don't have record in character_gifts table and will deleted", pItem->GetGUIDLow());
pUser->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
sLog->outError("Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUIDLow());
pUser->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
return;
}
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
stmt->setUInt32(0, item->GetGUIDLow());
CharacterDatabase.Execute(stmt);
}
else
pUser->SendLoot(pItem->GetGUID(), LOOT_CORPSE);
pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
}
void WorldSession::HandleGameObjectUseOpcode(WorldPacket & recv_data)
+38 -8
View File
@@ -241,7 +241,18 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
///- Retrieve packets from the receive queue and call the appropriate handlers
/// not process packets if socket already closed
WorldPacket* packet = NULL;
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
//! Delete packet after processing by default
bool deletePacket = true;
//! To prevent infinite loop
WorldPacket* firstDelayedPacket = NULL;
//! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all
//! *properly timed* packets, and we're now at the part of the queue where we find
//! delayed packets that were re-enqueued due to improper timing. To prevent an infinite
//! loop caused by re-enqueueing the same packets over and over again, we stop updating this session
//! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session.
while (m_Socket && !m_Socket->IsClosed() &&
!_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
_recvQueue.next(packet, updater))
{
const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()];
try
@@ -252,8 +263,20 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!_player)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
//! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
//! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
if (!m_playerRecentlyLogout)
LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN", "the player has not logged in yet");
{
//! Prevent infinite loop
if (!firstDelayedPacket)
firstDelayedPacket = packet;
//! Because checking a bool is faster than reallocating memory
deletePacket = false;
QueuePacket(packet);
//! Log
sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. "
"Player is currently not in world yet.", opHandle->name, packet->GetOpcode());
}
}
else if (_player->IsInWorld())
{
@@ -331,7 +354,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
}
}
delete packet;
if (deletePacket)
delete packet;
}
ProcessQueryCallbacks();
@@ -355,6 +379,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!m_Socket)
return false; //Will remove this session from the world session map
}
return true;
}
@@ -514,7 +539,13 @@ void WorldSession::LogoutPlayer(bool Save)
///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
//No SQL injection as AccountId is uint32
CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ACCOUNT_ONLINE);
stmt->setUInt32(0, GetAccountId());
CharacterDatabase.Execute(stmt);
sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
}
@@ -888,7 +919,7 @@ void WorldSession::InitializeQueryCallbackParameters()
void WorldSession::ProcessQueryCallbacks()
{
QueryResult result;
PreparedQueryResult result;
//! HandleCharEnumOpcode
if (_charEnumCallback.ready())
@@ -900,9 +931,8 @@ void WorldSession::ProcessQueryCallbacks()
if (_charCreateCallback.IsReady())
{
PreparedQueryResult pResult;
_charCreateCallback.GetResult(pResult);
HandleCharCreateCallback(pResult, _charCreateCallback.GetParam());
_charCreateCallback.GetResult(result);
HandleCharCreateCallback(result, _charCreateCallback.GetParam());
// Don't call FreeResult() here, the callback handler will do that depending on the events in the callback chain
}
+24 -22
View File
@@ -80,6 +80,12 @@ struct AccountData
std::string Data;
};
union BytesGuid
{
uint8 bytes[8];
uint64 guid;
};
enum PartyOperation
{
PARTY_OP_INVITE = 0,
@@ -188,7 +194,7 @@ class CharacterCreateInfo
protected:
CharacterCreateInfo(std::string name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId,
WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair),
OutfitId(outfitId), Data(data), CharCount(0), Stage(0)
OutfitId(outfitId), Data(data), CharCount(0)
{}
/// User specified variables
@@ -207,9 +213,6 @@ class CharacterCreateInfo
/// Server side data
uint8 CharCount;
/// Internal
uint8 Stage; // Stage of the callback chain
private:
virtual ~CharacterCreateInfo(){};
};
@@ -308,7 +311,7 @@ class WorldSession
// Pet
void SendPetNameQuery(uint64 guid, uint32 petnumber);
void SendStablePet(uint64 guid);
void SendStablePetCallback(QueryResult result, uint64 guid);
void SendStablePetCallback(PreparedQueryResult result, uint64 guid);
void SendStableResult(uint8 guid);
bool CheckStableMaster(uint64 guid);
@@ -405,7 +408,7 @@ class WorldSession
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
void HandleLoadScreenOpcode(WorldPacket& recvPacket);
void HandleCharEnum(QueryResult result);
void HandleCharEnum(PreparedQueryResult result);
void HandlePlayerLogin(LoginQueryHolder * holder);
void HandleCharFactionOrRaceChange(WorldPacket& recv_data);
void HandleRandomizeCharNameOpcode(WorldPacket& recv_data);
@@ -477,10 +480,10 @@ class WorldSession
void HandleEmoteOpcode(WorldPacket& recvPacket);
void HandleContactListOpcode(WorldPacket& recvPacket);
void HandleAddFriendOpcode(WorldPacket& recvPacket);
void HandleAddFriendOpcodeCallBack(QueryResult result, std::string friendNote);
void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string friendNote);
void HandleDelFriendOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcodeCallBack(QueryResult result);
void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result);
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
@@ -596,13 +599,13 @@ class WorldSession
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
void HandleStablePet(WorldPacket& recvPacket);
void HandleStablePetCallback(QueryResult result);
void HandleStablePetCallback(PreparedQueryResult result);
void HandleUnstablePet(WorldPacket& recvPacket);
void HandleUnstablePetCallback(QueryResult result, uint32 petnumber);
void HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId);
void HandleBuyStableSlot(WorldPacket& recvPacket);
void HandleStableRevivePet(WorldPacket& recvPacket);
void HandleStableSwapPet(WorldPacket& recvPacket);
void HandleStableSwapPetCallback(QueryResult result, uint32 petnumber);
void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId);
void HandleDuelAcceptedOpcode(WorldPacket& recvPacket);
void HandleDuelCancelledOpcode(WorldPacket& recvPacket);
@@ -756,7 +759,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recv_data);
void HandleCharRenameOpcode(WorldPacket& recv_data);
void HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname);
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName);
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
void HandleTotemDestroyed(WorldPacket& recv_data);
@@ -905,16 +908,15 @@ class WorldSession
void InitializeQueryCallbackParameters();
void ProcessQueryCallbacks();
ACE_Future_Set<QueryResult> _nameQueryCallbacks;
QueryResultFuture _charEnumCallback;
QueryResultFuture _addIgnoreCallback;
QueryResultFuture _stablePetCallback;
QueryCallback<QueryResult, std::string> _charRenameCallback;
QueryCallback<QueryResult, std::string> _addFriendCallback;
QueryCallback<QueryResult, uint32> _unstablePetCallback;
QueryCallback<QueryResult, uint32> _stableSwapCallback;
QueryCallback<QueryResult, uint64> _sendStabledPetCallback;
QueryCallback<PreparedQueryResult, CharacterCreateInfo*> _charCreateCallback;
PreparedQueryResultFuture _charEnumCallback;
PreparedQueryResultFuture _addIgnoreCallback;
PreparedQueryResultFuture _stablePetCallback;
QueryCallback<PreparedQueryResult, std::string> _charRenameCallback;
QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
QueryCallback<PreparedQueryResult, uint64> _sendStabledPetCallback;
QueryCallback<PreparedQueryResult, CharacterCreateInfo*, true> _charCreateCallback;
QueryResultHolderFuture _charLoginCallback;
private:

Some files were not shown because too many files have changed in this diff Show More