Merge commit 'origin/master' into 320

This commit is contained in:
tomrus88 2009-08-05 14:52:29 +04:00
commit f97da77cbd
38 changed files with 788 additions and 538 deletions

View file

@ -138,6 +138,11 @@ AC_PATH_PROGS(MYSQL_CONFIG, mysql_config, mysql_config, $PATH)
MYSQL_INCLUDES="`$MYSQL_CONFIG --cflags`" MYSQL_INCLUDES="`$MYSQL_CONFIG --cflags`"
MYSQL_LIBS="`$MYSQL_CONFIG --libs_r`" MYSQL_LIBS="`$MYSQL_CONFIG --libs_r`"
CXXFLAGS="-DDO_MYSQL $CXXFLAGS" CXXFLAGS="-DDO_MYSQL $CXXFLAGS"
# Workaround for --as-needed linker flag that comes sometimes from mysql
if echo $MYSQL_LIBS|grep "\-Wl,--as-needed" > /dev/null; then
MYSQL_LIBS=`echo $MYSQL_LIBS|sed -e "s/-Wl,--as-needed//"`;
AC_MSG_WARN([Your mysql libs contains -Wl,--as-needed, this is not good, problem fixed in more recent mysql versions])
fi
fi fi
else else
AC_MSG_RESULT($DO_MYSQL) AC_MSG_RESULT($DO_MYSQL)

View file

@ -750,8 +750,10 @@ bool prepare_new_index()
if(!use_new_index) return true; if(!use_new_index) return true;
// only use a new index if there are staged changes that should be preserved // only use a new index if there are staged changes that should be preserved
if( (cmd_pipe = popen( "git diff --cached", "r" )) == NULL ) if( (cmd_pipe = popen( "git diff --cached", "r" )) == NULL ) {
use_new_index = false;
return false; return false;
}
if(!fgets(buffer, MAX_BUF, cmd_pipe)) if(!fgets(buffer, MAX_BUF, cmd_pipe))
{ {

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`required_8254_01_mangos_spell_proc_event` bit(1) default NULL `required_8310_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -9791,7 +9791,7 @@ INSERT INTO `playercreateinfo_action` VALUES
(2,3,0,6603,0), (2,3,0,6603,0),
(2,3,1,2973,0), (2,3,1,2973,0),
(2,3,2,75,0), (2,3,2,75,0),
(2,3,4,20572,0), (2,3,9,20572,0),
(2,3,10,159,128), (2,3,10,159,128),
(2,3,11,117,128), (2,3,11,117,128),
(2,4,0,6603,0), (2,4,0,6603,0),
@ -9868,10 +9868,9 @@ INSERT INTO `playercreateinfo_action` VALUES
(3,6,5,47541,0), (3,6,5,47541,0),
(3,6,10,2481,0), (3,6,10,2481,0),
(4,1,72,6603,0), (4,1,72,6603,0),
(4,1,73,6603,0), (4,1,73,78,0),
(4,1,74,78,0), (4,1,82,58984,0),
(4,1,83,58984,0), (4,1,83,117,128),
(4,1,84,117,128),
(4,1,85,6603,0), (4,1,85,6603,0),
(4,1,97,6603,0), (4,1,97,6603,0),
(4,1,109,6603,0), (4,1,109,6603,0),
@ -9885,8 +9884,9 @@ INSERT INTO `playercreateinfo_action` VALUES
(4,4,1,1752,0), (4,4,1,1752,0),
(4,4,2,2098,0), (4,4,2,2098,0),
(4,4,3,2764,0), (4,4,3,2764,0),
(4,4,4,58984,0), (4,4,10,58984,0),
(4,4,11,4540,128), (4,4,11,4540,128),
(4,4,82,58984,0),
(4,5,0,6603,0), (4,5,0,6603,0),
(4,5,1,585,0), (4,5,1,585,0),
(4,5,2,2050,0), (4,5,2,2050,0),
@ -9904,7 +9904,7 @@ INSERT INTO `playercreateinfo_action` VALUES
(4,11,0,6603,0), (4,11,0,6603,0),
(4,11,1,5176,0), (4,11,1,5176,0),
(4,11,2,5185,0), (4,11,2,5185,0),
(4,11,3,58984,0), (4,11,9,58984,0),
(4,11,10,159,128), (4,11,10,159,128),
(4,11,11,4536,128), (4,11,11,4536,128),
(5,1,0,6603,0), (5,1,0,6603,0),
@ -10013,9 +10013,9 @@ INSERT INTO `playercreateinfo_action` VALUES
(7,6,4,45902,0), (7,6,4,45902,0),
(7,6,5,47541,0), (7,6,5,47541,0),
(7,6,10,20589,0), (7,6,10,20589,0),
(7,6,11,117,128), (7,6,11,41751,128),
(7,6,72,6603,0), (7,6,72,6603,0),
(7,6,83,117,128), (7,6,83,41751,128),
(7,6,84,6603,0), (7,6,84,6603,0),
(7,6,96,6603,0), (7,6,96,6603,0),
(7,6,108,6603,0), (7,6,108,6603,0),
@ -10043,21 +10043,21 @@ INSERT INTO `playercreateinfo_action` VALUES
(8,3,0,6603,0), (8,3,0,6603,0),
(8,3,1,2973,0), (8,3,1,2973,0),
(8,3,2,75,0), (8,3,2,75,0),
(8,3,3,20554,0),
(8,3,10,159,128), (8,3,10,159,128),
(8,3,11,4604,128), (8,3,11,4604,128),
(8,3,76,20554,0),
(8,4,0,6603,0), (8,4,0,6603,0),
(8,4,1,1752,0), (8,4,1,1752,0),
(8,4,2,2098,0), (8,4,2,2098,0),
(8,4,3,2764,0), (8,4,3,2764,0),
(8,4,4,26297,0),
(8,4,11,117,128), (8,4,11,117,128),
(8,4,76,20554,0),
(8,5,0,6603,0), (8,5,0,6603,0),
(8,5,1,585,0), (8,5,1,585,0),
(8,5,2,2050,0), (8,5,2,2050,0),
(8,5,3,20554,0),
(8,5,10,159,128), (8,5,10,159,128),
(8,5,11,4540,128), (8,5,11,4540,128),
(8,5,76,20554,0),
(8,6,0,6603,0), (8,6,0,6603,0),
(8,6,1,49576,0), (8,6,1,49576,0),
(8,6,2,45477,0), (8,6,2,45477,0),
@ -10068,15 +10068,15 @@ INSERT INTO `playercreateinfo_action` VALUES
(8,7,0,6603,0), (8,7,0,6603,0),
(8,7,1,403,0), (8,7,1,403,0),
(8,7,2,331,0), (8,7,2,331,0),
(8,7,3,20554,0),
(8,7,10,159,128), (8,7,10,159,128),
(8,7,11,117,128), (8,7,11,117,128),
(8,7,76,20554,0),
(8,8,0,6603,0), (8,8,0,6603,0),
(8,8,1,133,0), (8,8,1,133,0),
(8,8,2,168,0), (8,8,2,168,0),
(8,8,3,20554,0),
(8,8,10,159,128), (8,8,10,159,128),
(8,8,11,117,128), (8,8,11,117,128),
(8,8,76,20554,0),
(10,2,0,6603,0), (10,2,0,6603,0),
(10,2,1,21084,0), (10,2,1,21084,0),
(10,2,2,635,0), (10,2,2,635,0),
@ -10159,7 +10159,8 @@ INSERT INTO `playercreateinfo_action` VALUES
(11,6,3,45462,0), (11,6,3,45462,0),
(11,6,4,45902,0), (11,6,4,45902,0),
(11,6,5,47541,0), (11,6,5,47541,0),
(11,6,6,59545,0), (11,6,10,59545,0),
(11,6,11,41751,128),
(11,7,0,6603,0), (11,7,0,6603,0),
(11,7,1,403,0), (11,7,1,403,0),
(11,7,2,331,0), (11,7,2,331,0),
@ -17952,7 +17953,8 @@ INSERT INTO `spell_proc_event` VALUES
(63108, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63108, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(63156, 0x00000000, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (63156, 0x00000000, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(63245, 0x00000000, 5, 0x00000100, 0x00800000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (63245, 0x00000000, 5, 0x00000100, 0x00800000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(63730, 0x00000000, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); (63730, 0x00000000, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(64928, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
/*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */; /*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;

View file

@ -16,7 +16,7 @@
/* re-adding before command use. So need just adding new line to file. */ /* re-adding before command use. So need just adding new line to file. */
/* Current table fill progress state: */ /* Current table fill progress state: */
/* SpellEffect.cpp from start until end of Spell::EffectDummy */ /* SpellEffect.cpp from start until end of Spell::EffectPowerBurn */
DROP TABLE IF EXISTS spell_check; DROP TABLE IF EXISTS spell_check;
CREATE TABLE `spell_check` ( CREATE TABLE `spell_check` (
@ -58,6 +58,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(8220, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Flip Out', 'Spell::EffectDummy'), (8220, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Flip Out', 'Spell::EffectDummy'),
(8221, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'), (8221, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'),
(8222, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'), (8222, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'),
(8326, -1, -1, -1, -1, -1, -1, 6, -1,-1,'Ghost', 'Spell::EffectApplyAura'),
(8593, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Symbol of life', 'Spell::EffectDummy'), (8593, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Symbol of life', 'Spell::EffectDummy'),
(10399,11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), (10399,11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'),
(11687, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (11687, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'),
@ -98,6 +99,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(20473,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (20473,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
(20577, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Cannibalize', 'Spell::EffectDummy'), (20577, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Cannibalize', 'Spell::EffectDummy'),
(20578,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cannibalize', 'Spell::EffectDummy'), (20578,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cannibalize', 'Spell::EffectDummy'),
(20584,-1, -1, -1, -1, -1, -1, 6, -1,-1,'Ghost', 'Spell::EffectApplyAura'),
(20647,-1, -1, -1, -1, -1, -1, 2, -1, 0,'Execute', 'Spell::EffectDummy'), (20647,-1, -1, -1, -1, -1, -1, 2, -1, 0,'Execute', 'Spell::EffectDummy'),
(20929,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (20929,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
(20930,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (20930,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
@ -110,10 +112,13 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(23133, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Battle Chicken', 'Spell::EffectDummy'), (23133, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Battle Chicken', 'Spell::EffectDummy'),
(23170,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Brood Affliction: Bronze', 'Spell::EffectDummy'), (23170,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Brood Affliction: Bronze', 'Spell::EffectDummy'),
(23441,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter', 'Spell::EffectDummy'), (23441,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter', 'Spell::EffectDummy'),
(23442,-1, -1, -1, -1, -1, -1, 5, -1,-1,'Everlook Transporter', 'Spell::EffectTeleportUnits'),
(23444,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'), (23444,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'),
(23445,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Evil Twin', 'Spell::EffectDummy'), (23445,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Evil Twin', 'Spell::EffectDummy'),
(23445,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Evil Twin', 'Spell::EffectTeleportUnits'),
(23446,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter Failure', 'Spell::EffectDummy'), (23446,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter Failure', 'Spell::EffectDummy'),
(23448, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Transporter Arrival', 'Spell::EffectDummy'), (23448, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Transporter Arrival', 'Spell::EffectDummy'),
(23449,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(23453, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Transporter', 'Spell::EffectDummy'), (23453, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Transporter', 'Spell::EffectDummy'),
(23645, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Hourglass Sand', 'Spell::EffectDummy'), (23645, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Hourglass Sand', 'Spell::EffectDummy'),
(23725, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gift of Life', 'Spell::EffectDummy'), (23725, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gift of Life', 'Spell::EffectDummy'),
@ -123,6 +128,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(23885,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Bloodthirst', 'Spell::EffectDummy'), (23885,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Bloodthirst', 'Spell::EffectDummy'),
(23989, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Readiness', 'Spell::EffectDummy'), (23989, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Readiness', 'Spell::EffectDummy'),
(24340, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (24340, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(24575,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Brittle Armor', 'Spell::EffectTriggerSpell'),
(25599, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Thundercrash', 'Spell::EffectSchoolDMG'), (25599, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Thundercrash', 'Spell::EffectSchoolDMG'),
(25858,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'), (25858,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'),
(25859,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'), (25859,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'),
@ -134,6 +140,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(25913,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (25913,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
(25914,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (25914,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
(26074, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Holiday Cheer', 'Spell::EffectDummy'), (26074, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Holiday Cheer', 'Spell::EffectDummy'),
(26464,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mercurial Shield', 'Spell::EffectTriggerSpell'),
(26467,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Persistent Shield', 'Spell::EffectDummy'), (26467,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Persistent Shield', 'Spell::EffectDummy'),
(26558, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (26558, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(26635,-1, -1, -1, -1, -1, -1, 6, -1, 0,'Berserking', 'Spell::EffectDummy'), (26635,-1, -1, -1, -1, -1, -1, 6, -1, 0,'Berserking', 'Spell::EffectDummy'),
@ -145,6 +152,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(27176,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (27176,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'),
(27222, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (27222, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'),
(28006, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcane Cloaking', 'Spell::EffectDummy'), (28006, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcane Cloaking', 'Spell::EffectDummy'),
(28305,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mana Leech', 'Spell::EffectTriggerSpell'),
(28884, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (28884, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(29294,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Naxxramas Entry Flag Effect DND', 'Spell::EffectDummy'), (29294,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Naxxramas Entry Flag Effect DND', 'Spell::EffectDummy'),
(29200, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Purify Helboar Meat', 'Spell::EffectDummy'), (29200, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Purify Helboar Meat', 'Spell::EffectDummy'),
@ -163,6 +171,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(31231, 8, -1, -1, -1, -1, -1, 3, -1,-1,'Cheat Death', 'Spell::EffectDummy'), (31231, 8, -1, -1, -1, -1, -1, 3, -1,-1,'Cheat Death', 'Spell::EffectDummy'),
(31436, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Malevolent Cleave', 'Spell::EffectSchoolDMG'), (31436, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Malevolent Cleave', 'Spell::EffectSchoolDMG'),
(31789,10, -1, -1, -1, -1, -1, 3, -1, 0,'Righteous Defense', 'Spell::EffectDummy'), (31789,10, -1, -1, -1, -1, -1, 3, -1, 0,'Righteous Defense', 'Spell::EffectDummy'),
(31790,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Righteous Defense', 'Spell::EffectTriggerSpell'),
(31803,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Holy Vengeance', 'Spell::EffectSchoolDMG'), (31803,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Holy Vengeance', 'Spell::EffectSchoolDMG'),
(31818,-1, -1, -1, -1, -1, -1, 30, -1, 0,'Life Tap', 'Spell::EffectDummy'), (31818,-1, -1, -1, -1, -1, -1, 30, -1, 0,'Life Tap', 'Spell::EffectDummy'),
(32409,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Shadow Word: Death', 'Spell::EffectSchoolDMG'), (32409,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Shadow Word: Death', 'Spell::EffectSchoolDMG'),
@ -197,7 +206,16 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(36755,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), (36755,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'),
(36759,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), (36759,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'),
(36837, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (36837, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(36890,-1, -1, -1, -1, -1, -1, 5, -1,-1,'Area52 Transporter', 'Spell::EffectTeleportUnits'),
(36893,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(36895,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(36897,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(36899,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(36900,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Soul Split: Evil!', 'Spell::EffectTeleportUnits'),
(36901,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Soul Split: Good', 'Spell::EffectTeleportUnits'),
(36902,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'), (36902,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'),
(36940,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'),
(36941,-1, -1, -1, -1, -1, -1, 5, -1,-1,'Toshley\'s Station Transporter', 'Spell::EffectTeleportUnits'),
(37169,-1, -1, -1, -1, -1, -1, 6, 4,-1,'Eviscerate and Envenom Bonus Damage','Spell::EffectSchoolDMG'), (37169,-1, -1, -1, -1, -1, -1, 6, 4,-1,'Eviscerate and Envenom Bonus Damage','Spell::EffectSchoolDMG'),
(37506, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Scatter Shot', 'Spell::EffectDummy'), (37506, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Scatter Shot', 'Spell::EffectDummy'),
(37674, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Chaos Blast', 'Spell::EffectDummy'), (37674, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Chaos Blast', 'Spell::EffectDummy'),
@ -213,6 +231,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(39610,11, -1, -1, -1, -1, -1, 3, -1,-1,'Mana Tide Totem effect', 'Spell::EffectDummy'), (39610,11, -1, -1, -1, -1, -1, 3, -1,-1,'Mana Tide Totem effect', 'Spell::EffectDummy'),
(40810, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'), (40810, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
(41276, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (41276, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(41637,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Prayer of Mending', 'Spell::EffectApplyAura'),
(42384, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Brutal Swipe', 'Spell::EffectSchoolDMG'), (42384, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Brutal Swipe', 'Spell::EffectSchoolDMG'),
(43267, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'), (43267, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
(43268, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'), (43268, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
@ -337,6 +356,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
( 0, 7,0x0000044000000000,0x00000000, -1, -1, -1, -1, -1,-1,'Mangle (Cat) and Mangle (Bear)', 'Unit::HandleDummyAuraProc'), ( 0, 7,0x0000044000000000,0x00000000, -1, -1, -1, -1, -1,-1,'Mangle (Cat) and Mangle (Bear)', 'Unit::HandleDummyAuraProc'),
( 0, 9,0x0000000000000002,0x00000000, -1, 342, -1, 2, -1,-1,'Mongoose Bite', 'Spell::EffectSchoolDMG'), ( 0, 9,0x0000000000000002,0x00000000, -1, 342, -1, 2, -1,-1,'Mongoose Bite', 'Spell::EffectSchoolDMG'),
(0, 6,0x0080000000000000,0x00000000, -1, -1, -1, 3, -1,-1,'Penance', 'Spell::EffectDummy'), (0, 6,0x0080000000000000,0x00000000, -1, -1, -1, 3, -1,-1,'Penance', 'Spell::EffectDummy'),
( 0, 6,0x0000002000000000,0x00000000, -1, -1, -1, 6, -1,-1,'Prayer of Mending', 'Spell::EffectApplyAura'),
( 0, 8,0x0000024000000860,0x00000000, -1, -1, -1, -1, -1,-1,'Preparation (affected spells)', 'Spell::EffectDummy'), ( 0, 8,0x0000024000000860,0x00000000, -1, -1, -1, -1, -1,-1,'Preparation (affected spells)', 'Spell::EffectDummy'),
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 2, -1,-1,'Rake', 'Spell::EffectSchoolDMG'), /* used in */ ( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 2, -1,-1,'Rake', 'Spell::EffectSchoolDMG'), /* used in */
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 80, -1, 2,'Rake', 'Spell::EffectSchoolDMG'), /* exactly selected */ ( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 80, -1, 2,'Rake', 'Spell::EffectSchoolDMG'), /* exactly selected */
@ -355,6 +375,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(0, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'), (0, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'),
( 0, 9,0x0000000100000000,0x00000000, -1, -1, -1, 2, -1,-1,'Steady Shot', 'Spell::EffectSchoolDMG'), ( 0, 9,0x0000000100000000,0x00000000, -1, -1, -1, 2, -1,-1,'Steady Shot', 'Spell::EffectSchoolDMG'),
( 0, 9,0x0000000100000000,0x00000000, -1, -1, -1, 3, -1,-1,'Steady Shot', 'Spell::EffectDummy'), ( 0, 9,0x0000000100000000,0x00000000, -1, -1, -1, 3, -1,-1,'Steady Shot', 'Spell::EffectDummy'),
( 0, 8,0x0000000000400000,0x00000000, -1, -1, -1, -1, -1,-1,'Stealth', 'Spell::EffectTriggerSpell'),
( 0, 7,0x0010000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Swipe', 'Spell::EffectSchoolDMG'), ( 0, 7,0x0010000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Swipe', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000000000000080,0x00000000, -1, -1, -1, 2, -1,-1,'Thunder Clap', 'Spell::EffectSchoolDMG'), ( 0, 4,0x0000000000000080,0x00000000, -1, -1, -1, 2, -1,-1,'Thunder Clap', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000010000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Victory Rush', 'Spell::EffectSchoolDMG'), ( 0, 4,0x0000010000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Victory Rush', 'Spell::EffectSchoolDMG'),

View file

@ -0,0 +1,54 @@
ALTER TABLE db_version CHANGE COLUMN required_8254_01_mangos_spell_proc_event required_8294_01_mangos_playercreateinfo_action bit;
-- Remove Double attack icons for Night Elf Warrior
DELETE FROM playercreateinfo_action WHERE race=4 AND class=1 AND button=73;
-- Move Heroic Strike to correct location for Night Elf Warrior
DELETE FROM playercreateinfo_action WHERE race=4 AND class=1 AND button=74;
INSERT INTO playercreateinfo_action VALUES (4,1,73,78,0);
-- Moved Shadowmeld to correct location for Night Elf Warrior
DELETE FROM playercreateinfo_action WHERE race=4 AND class=1 AND button IN (82,83);
INSERT INTO playercreateinfo_action VALUES (4,1,82,58984,0);
-- Add correct Tough Jerky location for Night elf Warrior
DELETE FROM playercreateinfo_action WHERE race=4 AND class=1 AND button=84;
INSERT INTO playercreateinfo_action VALUES (4,1,83,117,128);
-- Moved Shadowmeld to correct location for Night Elf Druid
DELETE FROM playercreateinfo_action WHERE race=4 AND class=11 AND button IN (3,9);
INSERT INTO playercreateinfo_action VALUES (4,11,9,58984,0);
-- Moved Shadowmeld to correct location for Night Elf Rogue
DELETE FROM playercreateinfo_action WHERE race=4 AND class=4 AND button IN (4,10);
INSERT INTO playercreateinfo_action VALUES (4,4,10,58984,0);
-- Add Shadowmeld For Night Elf Rogue Shadow form bar
DELETE FROM playercreateinfo_action WHERE race=4 AND class=4 AND button = 82;
INSERT INTO playercreateinfo_action VALUES (4,4,82,58984,0);
-- Replace Tough Jerky for Gnome Death Knight Action Bar
DELETE FROM playercreateinfo_action WHERE race=7 AND class=6 AND button IN (11,83);
INSERT INTO playercreateinfo_action VALUES
(7,6,11,41751,128),
(7,6,83,41751,128);
-- Moved Gift of Naaru to correct location for Draenei Death Knight
DELETE FROM playercreateinfo_action WHERE race=11 AND class=6 AND button IN (6,10);
INSERT INTO playercreateinfo_action VALUES (11,6,10,59545,0);
-- Add Black Mushroom to Draenei Death Knight Action Bar
DELETE FROM playercreateinfo_action WHERE race=11 AND class=6 AND button IN (11);
INSERT INTO playercreateinfo_action VALUES
(11,6,11,41751,128);
-- Moved Blood Fury to correct action bar location for Orc Hunter
DELETE FROM playercreateinfo_action WHERE race=2 AND class=3 AND button IN (4,9);
INSERT INTO playercreateinfo_action VALUES (2,3,9,20572,0);
-- Moved Berserking to correct action bar location for Non-Heroic Troll classes
DELETE FROM playercreateinfo_action WHERE race=8 AND class IN (3,5,7,8) AND button IN (3,76);
INSERT INTO playercreateinfo_action VALUES
(8,3,3,20554,0),
(8,5,3,20554,0),
(8,7,3,20554,0),
(8,8,3,20554,0);
-- Updated and moved Berserking skill for Troll Rogue
DELETE FROM playercreateinfo_action WHERE race=8 AND class=4 AND button IN (4,76);
INSERT INTO playercreateinfo_action VALUES (8,4,4,26297,0);

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8294_01_mangos_playercreateinfo_action required_8310_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (64928);
INSERT INTO `spell_proc_event` VALUES
(64928, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);

View file

@ -261,6 +261,8 @@ pkgdata_DATA = \
8253_01_mangos_spell_chain.sql \ 8253_01_mangos_spell_chain.sql \
8253_02_mangos_spell_proc_event.sql \ 8253_02_mangos_spell_proc_event.sql \
8254_01_mangos_spell_proc_event.sql \ 8254_01_mangos_spell_proc_event.sql \
8294_01_mangos_playercreateinfo_action.sql \
8310_01_mangos_spell_proc_event.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -502,4 +504,6 @@ EXTRA_DIST = \
8253_01_mangos_spell_chain.sql \ 8253_01_mangos_spell_chain.sql \
8253_02_mangos_spell_proc_event.sql \ 8253_02_mangos_spell_proc_event.sql \
8254_01_mangos_spell_proc_event.sql \ 8254_01_mangos_spell_proc_event.sql \
8294_01_mangos_playercreateinfo_action.sql \
8310_01_mangos_spell_proc_event.sql \
README README

View file

@ -81,13 +81,14 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
switch(criteria->requiredType) switch(criteria->requiredType)
{ {
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
break; break;
@ -689,7 +690,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// std. case: increment at 1 // std. case: increment at 1
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
@ -1253,6 +1253,24 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, spellCount); SetCriteriaProgress(achievementCriteria, spellCount);
break; break;
} }
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if(!miscvalue1)
continue;
if(achievementCriteria->win_duel.duelCount)
{
// those requirements couldn't be found in the dbc
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
if(!data)
continue;
if(!data->Meets(GetPlayer(),unit))
continue;
}
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount()); SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount());
break; break;
@ -1942,6 +1960,10 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
if(criteria->do_emote.count==0) if(criteria->do_emote.count==0)
continue; continue;
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics
if(criteria->win_duel.duelCount==0)
continue;
break;
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases
break; break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases

View file

@ -201,14 +201,11 @@ BattleGround::~BattleGround()
// (this is done automatically in mapmanager update, when the instance is reset after the reset time) // (this is done automatically in mapmanager update, when the instance is reset after the reset time)
int size = m_BgCreatures.size(); int size = m_BgCreatures.size();
for(int i = 0; i < size; ++i) for(int i = 0; i < size; ++i)
{
DelCreature(i); DelCreature(i);
}
size = m_BgObjects.size(); size = m_BgObjects.size();
for(int i = 0; i < size; ++i) for(int i = 0; i < size; ++i)
{
DelObject(i); DelObject(i);
}
if (GetInstanceID()) // not spam by useless queries in case BG templates if (GetInstanceID()) // not spam by useless queries in case BG templates
{ {
@ -227,6 +224,9 @@ BattleGround::~BattleGround()
((BattleGroundMap*)map)->SetUnload(); ((BattleGroundMap*)map)->SetUnload();
// remove from bg free slot queue // remove from bg free slot queue
this->RemoveFromBGFreeSlotQueue(); this->RemoveFromBGFreeSlotQueue();
for(BattleGroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr)
delete itr->second;
} }
void BattleGround::Update(uint32 diff) void BattleGround::Update(uint32 diff)
@ -939,7 +939,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
participant = true; participant = true;
} }
std::map<uint64, BattleGroundScore*>::iterator itr2 = m_PlayerScores.find(guid); BattleGroundScoreMap::iterator itr2 = m_PlayerScores.find(guid);
if (itr2 != m_PlayerScores.end()) if (itr2 != m_PlayerScores.end())
{ {
delete itr2->second; // delete player's score delete itr2->second; // delete player's score
@ -1081,6 +1081,9 @@ void BattleGround::Reset()
m_InBGFreeSlotQueue = false; m_InBGFreeSlotQueue = false;
m_Players.clear(); m_Players.clear();
for(BattleGroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr)
delete itr->second;
m_PlayerScores.clear(); m_PlayerScores.clear();
} }
@ -1271,7 +1274,7 @@ bool BattleGround::HasFreeSlots() const
void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{ {
//this procedure is called from virtual function implemented in bg subclass //this procedure is called from virtual function implemented in bg subclass
std::map<uint64, BattleGroundScore*>::const_iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::const_iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found... if(itr == m_PlayerScores.end()) // player not found...
return; return;

View file

@ -375,8 +375,9 @@ class BattleGround
BattleGroundPlayerMap const& GetPlayers() const { return m_Players; } BattleGroundPlayerMap const& GetPlayers() const { return m_Players; }
uint32 GetPlayersSize() const { return m_Players.size(); } uint32 GetPlayersSize() const { return m_Players.size(); }
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); } typedef std::map<uint64, BattleGroundScore*> BattleGroundScoreMap;
std::map<uint64, BattleGroundScore*>::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); } BattleGroundScoreMap::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); }
BattleGroundScoreMap::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); }
uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); } uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); }
uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); } uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); }
@ -513,8 +514,8 @@ class BattleGround
void PlayerAddedToBGCheckIfBGIsRunning(Player* plr); void PlayerAddedToBGCheckIfBGIsRunning(Player* plr);
/* Scorekeeping */ /* Scorekeeping */
// Player scores
std::map<uint64, BattleGroundScore*> m_PlayerScores; BattleGroundScoreMap m_PlayerScores; // Player scores
// must be implemented in BG subclass // must be implemented in BG subclass
virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {} virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {}

View file

@ -659,8 +659,7 @@ WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if( itr == m_PlayerScores.end() ) // player not found... if( itr == m_PlayerScores.end() ) // player not found...
return; return;

View file

@ -96,8 +96,7 @@ void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found... if(itr == m_PlayerScores.end()) // player not found...
return; return;

View file

@ -180,8 +180,7 @@ bool BattleGroundBE::SetupBattleGround()
void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found... if(itr == m_PlayerScores.end()) // player not found...
return; return;

View file

@ -778,8 +778,7 @@ void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType
void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found if(itr == m_PlayerScores.end()) // player not found
return; return;

View file

@ -1333,7 +1333,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
*data << (int32)(bg->GetPlayerScoresSize()); *data << (int32)(bg->GetPlayerScoresSize());
for(std::map<uint64, BattleGroundScore*>::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr) for(BattleGround::BattleGroundScoreMap::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr)
{ {
*data << (uint64)itr->first; *data << (uint64)itr->first;
*data << (int32)itr->second->KillingBlows; *data << (int32)itr->second->KillingBlows;

View file

@ -72,8 +72,7 @@ void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found... if(itr == m_PlayerScores.end()) // player not found...
return; return;

View file

@ -631,8 +631,7 @@ void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{ {
std::map<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID()); BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found if(itr == m_PlayerScores.end()) // player not found
return; return;

View file

@ -818,6 +818,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
{ {
pCurrChar->resetTalents(true); pCurrChar->resetTalents(true);
pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
SendNotification(LANG_RESET_TALENTS); SendNotification(LANG_RESET_TALENTS);
} }
@ -835,6 +836,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)", sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)",
GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUIDLow()); GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUIDLow());
if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED))
pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
m_playerLoading = false; m_playerLoading = false;
delete holder; delete holder;
} }

View file

@ -808,17 +808,17 @@ void Guild::DisplayGuildEventlog(WorldSession *session)
for (GuildEventlog::const_iterator itr = m_GuildEventlog.begin(); itr != m_GuildEventlog.end(); ++itr) for (GuildEventlog::const_iterator itr = m_GuildEventlog.begin(); itr != m_GuildEventlog.end(); ++itr)
{ {
// Event type // Event type
data << uint8((*itr)->EventType); data << uint8(itr->EventType);
// Player 1 // Player 1
data << uint64((*itr)->PlayerGuid1); data << uint64(itr->PlayerGuid1);
// Player 2 not for left/join guild events // Player 2 not for left/join guild events
if( (*itr)->EventType != GUILD_EVENT_LOG_JOIN_GUILD && (*itr)->EventType != GUILD_EVENT_LOG_LEAVE_GUILD ) if (itr->EventType != GUILD_EVENT_LOG_JOIN_GUILD && itr->EventType != GUILD_EVENT_LOG_LEAVE_GUILD)
data << uint64((*itr)->PlayerGuid2); data << uint64(itr->PlayerGuid2);
// New Rank - only for promote/demote guild events // New Rank - only for promote/demote guild events
if( (*itr)->EventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || (*itr)->EventType == GUILD_EVENT_LOG_DEMOTE_PLAYER ) if (itr->EventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || itr->EventType == GUILD_EVENT_LOG_DEMOTE_PLAYER)
data << uint8((*itr)->NewRank); data << uint8(itr->NewRank);
// Event timestamp // Event timestamp
data << uint32(time(NULL)-(*itr)->TimeStamp); data << uint32(time(NULL)-itr->TimeStamp);
} }
session->SendPacket(&data); session->SendPacket(&data);
sLog.outDebug("WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)"); sLog.outDebug("WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)");
@ -837,14 +837,14 @@ void Guild::LoadGuildEventLogFromDB()
do do
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
GuildEventlogEntry *NewEvent = new GuildEventlogEntry; GuildEventlogEntry NewEvent;
// Fill entry // Fill entry
NewEvent->LogGuid = fields[0].GetUInt32(); NewEvent.LogGuid = fields[0].GetUInt32();
NewEvent->EventType = fields[1].GetUInt8(); NewEvent.EventType = fields[1].GetUInt8();
NewEvent->PlayerGuid1 = fields[2].GetUInt32(); NewEvent.PlayerGuid1 = fields[2].GetUInt32();
NewEvent->PlayerGuid2 = fields[3].GetUInt32(); NewEvent.PlayerGuid2 = fields[3].GetUInt32();
NewEvent->NewRank = fields[4].GetUInt8(); NewEvent.NewRank = fields[4].GetUInt8();
NewEvent->TimeStamp = fields[5].GetUInt64(); NewEvent.TimeStamp = fields[5].GetUInt64();
// Add entry to map // Add entry to map
m_GuildEventlog.push_front(NewEvent); m_GuildEventlog.push_front(NewEvent);
@ -854,9 +854,8 @@ void Guild::LoadGuildEventLogFromDB()
// Check lists size in case to many event entries in db // Check lists size in case to many event entries in db
// This cases can happen only if a crash occured somewhere and table has too many log entries // This cases can happen only if a crash occured somewhere and table has too many log entries
if (!m_GuildEventlog.empty()) if (!m_GuildEventlog.empty())
{ CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid=%u AND LogGuid < %u", Id, m_GuildEventlog.front().LogGuid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid=%u AND LogGuid < %u", Id, m_GuildEventlog.front()->LogGuid);
}
m_eventlogloaded = true; m_eventlogloaded = true;
} }
@ -865,16 +864,8 @@ void Guild::UnloadGuildEventlog()
{ {
if (!m_eventlogloaded) if (!m_eventlogloaded)
return; return;
GuildEventlogEntry *EventLogEntry;
if( !m_GuildEventlog.empty() ) m_GuildEventlog.clear();
{
do
{
EventLogEntry = *(m_GuildEventlog.begin());
m_GuildEventlog.pop_front();
delete EventLogEntry;
}while( !m_GuildEventlog.empty() );
}
m_eventlogloaded = false; m_eventlogloaded = false;
} }
@ -894,27 +885,25 @@ void Guild::RenumGuildEventlog()
// Add entry to guild eventlog // Add entry to guild eventlog
void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank) void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank)
{ {
GuildEventlogEntry *NewEvent = new GuildEventlogEntry; GuildEventlogEntry NewEvent;
// Fill entry // Fill entry
NewEvent->LogGuid = GuildEventlogMaxGuid++; NewEvent.LogGuid = GuildEventlogMaxGuid++;
NewEvent->EventType = EventType; NewEvent.EventType = EventType;
NewEvent->PlayerGuid1 = PlayerGuid1; NewEvent.PlayerGuid1 = PlayerGuid1;
NewEvent->PlayerGuid2 = PlayerGuid2; NewEvent.PlayerGuid2 = PlayerGuid2;
NewEvent->NewRank = NewRank; NewEvent.NewRank = NewRank;
NewEvent->TimeStamp = uint32(time(NULL)); NewEvent.TimeStamp = uint32(time(NULL));
// Check max entry limit and delete from db if needed // Check max entry limit and delete from db if needed
if (m_GuildEventlog.size() > GUILD_EVENTLOG_MAX_ENTRIES) if (m_GuildEventlog.size() > GUILD_EVENTLOG_MAX_ENTRIES)
{ {
GuildEventlogEntry *OldEvent = *(m_GuildEventlog.begin()); CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, m_GuildEventlog.front().LogGuid);
m_GuildEventlog.pop_front(); m_GuildEventlog.pop_front();
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid);
delete OldEvent;
} }
// Add entry to map // Add entry to map
m_GuildEventlog.push_back(NewEvent); m_GuildEventlog.push_back(NewEvent);
// Add new eventlog entry into DB // Add new eventlog entry into DB
CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "')", CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "')",
Id, NewEvent->LogGuid, uint32(NewEvent->EventType), NewEvent->PlayerGuid1, NewEvent->PlayerGuid2, uint32(NewEvent->NewRank), NewEvent->TimeStamp); Id, NewEvent.LogGuid, uint32(NewEvent.EventType), NewEvent.PlayerGuid1, NewEvent.PlayerGuid2, uint32(NewEvent.NewRank), NewEvent.TimeStamp);
} }
// ************************************************* // *************************************************
@ -1486,30 +1475,28 @@ void Guild::LoadGuildBankEventLogFromDB()
do do
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
GuildBankEvent *NewEvent = new GuildBankEvent; GuildBankEvent NewEvent;
NewEvent->LogGuid = fields[0].GetUInt32(); NewEvent.LogGuid = fields[0].GetUInt32();
NewEvent->LogEntry = fields[1].GetUInt8(); NewEvent.LogEntry = fields[1].GetUInt8();
uint8 TabId = fields[2].GetUInt8(); uint8 TabId = fields[2].GetUInt8();
NewEvent->PlayerGuid = fields[3].GetUInt32(); NewEvent.PlayerGuid = fields[3].GetUInt32();
NewEvent->ItemOrMoney = fields[4].GetUInt32(); NewEvent.ItemOrMoney = fields[4].GetUInt32();
NewEvent->ItemStackCount = fields[5].GetUInt8(); NewEvent.ItemStackCount = fields[5].GetUInt8();
NewEvent->DestTabId = fields[6].GetUInt8(); NewEvent.DestTabId = fields[6].GetUInt8();
NewEvent->TimeStamp = fields[7].GetUInt64(); NewEvent.TimeStamp = fields[7].GetUInt64();
if (TabId >= GUILD_BANK_MAX_TABS) if (TabId >= GUILD_BANK_MAX_TABS)
{ {
sLog.outError( "Guild::LoadGuildBankEventLogFromDB: Invalid tabid '%u' for guild bank log entry (guild: '%s', LogGuid: %u), skipped.", TabId, GetName().c_str(), NewEvent->LogGuid); sLog.outError( "Guild::LoadGuildBankEventLogFromDB: Invalid tabid '%u' for guild bank log entry (guild: '%s', LogGuid: %u), skipped.", TabId, GetName().c_str(), NewEvent.LogGuid);
delete NewEvent;
continue; continue;
} }
if (NewEvent->isMoneyEvent() && m_GuildBankEventLog_Money.size() >= GUILD_BANK_MAX_LOGS
|| m_GuildBankEventLog_Item[TabId].size() >= GUILD_BANK_MAX_LOGS) if (NewEvent.isMoneyEvent() && m_GuildBankEventLog_Money.size() >= GUILD_BANK_MAX_LOGS ||
{ m_GuildBankEventLog_Item[TabId].size() >= GUILD_BANK_MAX_LOGS)
delete NewEvent;
continue; continue;
}
if (NewEvent->isMoneyEvent()) if (NewEvent.isMoneyEvent())
m_GuildBankEventLog_Money.push_front(NewEvent); m_GuildBankEventLog_Money.push_front(NewEvent);
else else
m_GuildBankEventLog_Item[TabId].push_front(NewEvent); m_GuildBankEventLog_Item[TabId].push_front(NewEvent);
@ -1522,43 +1509,24 @@ void Guild::LoadGuildBankEventLogFromDB()
if (!m_GuildBankEventLog_Money.empty()) if (!m_GuildBankEventLog_Money.empty())
{ {
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u",
Id, m_GuildBankEventLog_Money.front()->LogGuid); Id, m_GuildBankEventLog_Money.front().LogGuid);
} }
for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
{ {
if (!m_GuildBankEventLog_Item[i].empty()) if (!m_GuildBankEventLog_Item[i].empty())
{ {
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u", CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid=%u AND LogGuid < %u",
Id, m_GuildBankEventLog_Item[i].front()->LogGuid); Id, m_GuildBankEventLog_Item[i].front().LogGuid);
} }
} }
} }
void Guild::UnloadGuildBankEventLog() void Guild::UnloadGuildBankEventLog()
{ {
GuildBankEvent *EventLogEntry; m_GuildBankEventLog_Money.clear();
if( !m_GuildBankEventLog_Money.empty() )
{
do
{
EventLogEntry = *(m_GuildBankEventLog_Money.begin());
m_GuildBankEventLog_Money.pop_front();
delete EventLogEntry;
}while( !m_GuildBankEventLog_Money.empty() );
}
for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i) for (int i = 0; i < GUILD_BANK_MAX_TABS; ++i)
{ m_GuildBankEventLog_Item[i].clear();
if( !m_GuildBankEventLog_Item[i].empty() )
{
do
{
EventLogEntry = *(m_GuildBankEventLog_Item[i].begin());
m_GuildBankEventLog_Item[i].pop_front();
delete EventLogEntry;
}while( !m_GuildBankEventLog_Item[i].empty() );
}
}
} }
void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
@ -1574,24 +1542,24 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
data << uint8(m_GuildBankEventLog_Money.size()); // number of log entries data << uint8(m_GuildBankEventLog_Money.size()); // number of log entries
for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Money.begin(); itr != m_GuildBankEventLog_Money.end(); ++itr) for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Money.begin(); itr != m_GuildBankEventLog_Money.end(); ++itr)
{ {
data << uint8((*itr)->LogEntry); data << uint8(itr->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); data << uint64(MAKE_NEW_GUID(itr->PlayerGuid,0,HIGHGUID_PLAYER));
if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || if (itr->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || itr->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || itr->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || itr->LogEntry == GUILD_BANK_LOG_UNK1 ||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK2) itr->LogEntry == GUILD_BANK_LOG_UNK2)
{ {
data << uint32((*itr)->ItemOrMoney); data << uint32(itr->ItemOrMoney);
} }
else else
{ {
data << uint32((*itr)->ItemOrMoney); data << uint32(itr->ItemOrMoney);
data << uint32((*itr)->ItemStackCount); data << uint32(itr->ItemStackCount);
if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) if (itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
data << uint8((*itr)->DestTabId); // moved tab data << uint8(itr->DestTabId); // moved tab
} }
data << uint32(time(NULL)-(*itr)->TimeStamp); data << uint32(time(NULL) - itr->TimeStamp);
} }
session->SendPacket(&data); session->SendPacket(&data);
} }
@ -1604,24 +1572,24 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
data << uint8(m_GuildBankEventLog_Item[TabId].size()); data << uint8(m_GuildBankEventLog_Item[TabId].size());
for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Item[TabId].begin(); itr != m_GuildBankEventLog_Item[TabId].end(); ++itr) for (GuildBankEventLog::const_iterator itr = m_GuildBankEventLog_Item[TabId].begin(); itr != m_GuildBankEventLog_Item[TabId].end(); ++itr)
{ {
data << uint8((*itr)->LogEntry); data << uint8(itr->LogEntry);
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); data << uint64(MAKE_NEW_GUID(itr->PlayerGuid,0,HIGHGUID_PLAYER));
if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || if (itr->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || itr->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || itr->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || itr->LogEntry == GUILD_BANK_LOG_UNK1 ||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK2) itr->LogEntry == GUILD_BANK_LOG_UNK2)
{ {
data << uint32((*itr)->ItemOrMoney); data << uint32(itr->ItemOrMoney);
} }
else else
{ {
data << uint32((*itr)->ItemOrMoney); data << uint32(itr->ItemOrMoney);
data << uint32((*itr)->ItemStackCount); data << uint32(itr->ItemStackCount);
if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) if (itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || itr->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
data << uint8((*itr)->DestTabId); // moved tab data << uint8(itr->DestTabId); // moved tab
} }
data << uint32(time(NULL)-(*itr)->TimeStamp); data << uint32(time(NULL) - itr->TimeStamp);
} }
session->SendPacket(&data); session->SendPacket(&data);
} }
@ -1630,24 +1598,23 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId) void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId)
{ {
GuildBankEvent *NewEvent = new GuildBankEvent; GuildBankEvent NewEvent;
NewEvent->LogGuid = LogMaxGuid++; NewEvent.LogGuid = LogMaxGuid++;
NewEvent->LogEntry = LogEntry; NewEvent.LogEntry = LogEntry;
NewEvent->PlayerGuid = PlayerGuidLow; NewEvent.PlayerGuid = PlayerGuidLow;
NewEvent->ItemOrMoney = ItemOrMoney; NewEvent.ItemOrMoney = ItemOrMoney;
NewEvent->ItemStackCount = ItemStackCount; NewEvent.ItemStackCount = ItemStackCount;
NewEvent->DestTabId = DestTabId; NewEvent.DestTabId = DestTabId;
NewEvent->TimeStamp = uint32(time(NULL)); NewEvent.TimeStamp = uint32(time(NULL));
if (NewEvent->isMoneyEvent()) if (NewEvent.isMoneyEvent())
{ {
if (m_GuildBankEventLog_Money.size() > GUILD_BANK_MAX_LOGS) if (m_GuildBankEventLog_Money.size() > GUILD_BANK_MAX_LOGS)
{ {
GuildBankEvent *OldEvent = *(m_GuildBankEventLog_Money.begin()); CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'",
Id, m_GuildBankEventLog_Money.front().LogGuid);
m_GuildBankEventLog_Money.pop_front(); m_GuildBankEventLog_Money.pop_front();
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid);
delete OldEvent;
} }
m_GuildBankEventLog_Money.push_back(NewEvent); m_GuildBankEventLog_Money.push_back(NewEvent);
} }
@ -1655,15 +1622,14 @@ void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint
{ {
if (m_GuildBankEventLog_Item[TabId].size() > GUILD_BANK_MAX_LOGS) if (m_GuildBankEventLog_Item[TabId].size() > GUILD_BANK_MAX_LOGS)
{ {
GuildBankEvent *OldEvent = *(m_GuildBankEventLog_Item[TabId].begin()); CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'",
Id, m_GuildBankEventLog_Item[TabId].front().LogGuid);
m_GuildBankEventLog_Item[TabId].pop_front(); m_GuildBankEventLog_Item[TabId].pop_front();
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u'", Id, OldEvent->LogGuid);
delete OldEvent;
} }
m_GuildBankEventLog_Item[TabId].push_back(NewEvent); m_GuildBankEventLog_Item[TabId].push_back(NewEvent);
} }
CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')", CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')",
Id, NewEvent->LogGuid, uint32(NewEvent->LogEntry), uint32(TabId), NewEvent->PlayerGuid, NewEvent->ItemOrMoney, uint32(NewEvent->ItemStackCount), uint32(NewEvent->DestTabId), NewEvent->TimeStamp); Id, NewEvent.LogGuid, uint32(NewEvent.LogEntry), uint32(TabId), NewEvent.PlayerGuid, NewEvent.ItemOrMoney, uint32(NewEvent.ItemStackCount), uint32(NewEvent.DestTabId), NewEvent.TimeStamp);
} }
// This will renum guids used at load to prevent always going up until infinit // This will renum guids used at load to prevent always going up until infinit

View file

@ -458,8 +458,8 @@ class Guild
TabListMap m_TabListMap; TabListMap m_TabListMap;
/** These are actually ordered lists. The first element is the oldest entry.*/ /** These are actually ordered lists. The first element is the oldest entry.*/
typedef std::list<GuildEventlogEntry*> GuildEventlog; typedef std::list<GuildEventlogEntry> GuildEventlog;
typedef std::list<GuildBankEvent*> GuildBankEventLog; typedef std::list<GuildBankEvent> GuildBankEventLog;
GuildEventlog m_GuildEventlog; GuildEventlog m_GuildEventlog;
GuildBankEventLog m_GuildBankEventLog_Money; GuildBankEventLog m_GuildBankEventLog_Money;
GuildBankEventLog m_GuildBankEventLog_Item[GUILD_BANK_MAX_TABS]; GuildBankEventLog m_GuildBankEventLog_Item[GUILD_BANK_MAX_TABS];

View file

@ -44,7 +44,11 @@ INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex); INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex);
ObjectAccessor::ObjectAccessor() {} ObjectAccessor::ObjectAccessor() {}
ObjectAccessor::~ObjectAccessor() {} ObjectAccessor::~ObjectAccessor()
{
for(Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
delete itr->second;
}
Creature* Creature*
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)

View file

@ -170,6 +170,9 @@ ObjectMgr::~ObjectMgr()
for (GuildMap::iterator itr = mGuildMap.begin(); itr != mGuildMap.end(); ++itr) for (GuildMap::iterator itr = mGuildMap.begin(); itr != mGuildMap.end(); ++itr)
delete itr->second; delete itr->second;
for (ArenaTeamMap::iterator itr = mArenaTeamMap.begin(); itr != mArenaTeamMap.end(); ++itr)
delete itr->second;
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
itr->second.Clear(); itr->second.Clear();

View file

@ -194,9 +194,12 @@ void PetAI::UpdateAI(const uint32 diff)
} }
} }
// Autocast (casted only in combat or persistent spells in any state)
if (m_creature->GetGlobalCooldown() == 0 && !m_creature->IsNonMeleeSpellCasted(false)) if (m_creature->GetGlobalCooldown() == 0 && !m_creature->IsNonMeleeSpellCasted(false))
{ {
//Autocast typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i) for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{ {
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i); uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
@ -210,11 +213,29 @@ void PetAI::UpdateAI(const uint32 diff)
// ignore some combinations of combat state and combat/noncombat spells // ignore some combinations of combat state and combat/noncombat spells
if (!inCombat) if (!inCombat)
{ {
// ignore attacking spells, and allow only self/around spells
if (!IsPositiveSpell(spellInfo->Id)) if (!IsPositiveSpell(spellInfo->Id))
continue; continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this reqs:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
// allow only spell without spell cost or with spell cost but not duration limit
int32 duration = GetSpellDuration(spellInfo);
if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
continue;
// allow only spell without cooldown > duration
int32 cooldown = GetSpellRecoveryTime(spellInfo);
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
continue;
}
} }
else else
{ {
// just ignore non-combat spells
if (IsNonCombatSpell(spellInfo)) if (IsNonCombatSpell(spellInfo))
continue; continue;
} }
@ -223,7 +244,7 @@ void PetAI::UpdateAI(const uint32 diff)
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim())) if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{ {
m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell)); targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue; continue;
} }
else else
@ -239,7 +260,7 @@ void PetAI::UpdateAI(const uint32 diff)
if(spell->CanAutoCast(Target)) if(spell->CanAutoCast(Target))
{ {
m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell));
spellUsed = true; spellUsed = true;
break; break;
} }
@ -250,14 +271,14 @@ void PetAI::UpdateAI(const uint32 diff)
} }
//found units to cast on to //found units to cast on to
if (!m_targetSpellStore.empty()) if (!targetSpellStore.empty())
{ {
uint32 index = urand(0, m_targetSpellStore.size() - 1); uint32 index = urand(0, targetSpellStore.size() - 1);
Spell* spell = m_targetSpellStore[index].second; Spell* spell = targetSpellStore[index].second;
Unit* target = m_targetSpellStore[index].first; Unit* target = targetSpellStore[index].first;
m_targetSpellStore.erase(m_targetSpellStore.begin() + index); targetSpellStore.erase(targetSpellStore.begin() + index);
SpellCastTargets targets; SpellCastTargets targets;
targets.setUnitTarget( target ); targets.setUnitTarget( target );
@ -276,11 +297,10 @@ void PetAI::UpdateAI(const uint32 diff)
spell->prepare(&targets); spell->prepare(&targets);
} }
while (!m_targetSpellStore.empty())
{ // deleted cached Spell objects
delete m_targetSpellStore.begin()->second; for(TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
m_targetSpellStore.erase(m_targetSpellStore.begin()); delete itr->second;
}
} }
} }

View file

@ -52,8 +52,5 @@ class MANGOS_DLL_DECL PetAI : public CreatureAI
bool inCombat; bool inCombat;
std::set<uint64> m_AllySet; std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer; uint32 m_updateAlliesTimer;
typedef std::pair<Unit*, Spell*> TargetSpellPair;
std::vector<TargetSpellPair> m_targetSpellStore;
}; };
#endif #endif

View file

@ -689,14 +689,14 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
switch(iProto->Spells[0].SpellCategory) switch(iProto->Spells[0].SpellCategory)
{ {
case 11: // food case 11: // food
if(iProto->Stackable > 4) count = getClass()==CLASS_DEATH_KNIGHT ? 10 : 4;
count = 4;
break; break;
case 59: // drink case 59: // drink
if(iProto->Stackable > 2)
count = 2; count = 2;
break; break;
} }
if(iProto->Stackable < count)
count = iProto->Stackable;
} }
StoreNewItemInBestSlots(item_id, count); StoreNewItemInBestSlots(item_id, count);
@ -13853,61 +13853,6 @@ void Player::SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, u
/*** LOAD SYSTEM ***/ /*** LOAD SYSTEM ***/
/*********************************************************/ /*********************************************************/
bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
{
bool delete_result = true;
if (!result)
{
// 0 1 2 3 4 5 6 7 8 9 10 11
result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login, zone, level FROM characters WHERE guid = '%u'",guid);
if (!result)
return false;
}
else
delete_result = false;
Field *fields = result->Fetch();
if (!LoadValues( fields[1].GetString()))
{
sLog.outError("Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid));
if (delete_result)
delete result;
return false;
}
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
m_name = fields[2].GetCppString();
Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat());
SetLocationMapId(fields[6].GetUInt32());
// the instance id is not needed at character enum
m_Played_time[PLAYED_TIME_TOTAL] = fields[7].GetUInt32();
m_Played_time[PLAYED_TIME_LEVEL] = fields[8].GetUInt32();
m_atLoginFlags = fields[9].GetUInt32();
// I don't see these used anywhere ..
/*_LoadGroup();
_LoadBoundInstances();*/
if (delete_result)
delete result;
for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i)
m_items[i] = NULL;
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
m_deathState = DEAD;
return true;
}
void Player::_LoadDeclinedNames(QueryResult* result) void Player::_LoadDeclinedNames(QueryResult* result)
{ {
if(!result) if(!result)
@ -14762,7 +14707,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
delete result; delete result;
} }
if(getClass() == CLASS_WARRIOR) if(getClass() == CLASS_WARRIOR && !HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
} }
@ -15564,26 +15509,9 @@ void Player::SaveToDB()
// first save/honor gain after midnight will also update the player's honor fields // first save/honor gain after midnight will also update the player's honor fields
UpdateHonorFields(); UpdateHonorFields();
int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0;
//save, far from tavern/city
//save, but in tavern/city
sLog.outDebug("The value of player %s at save: ", m_name.c_str()); sLog.outDebug("The value of player %s at save: ", m_name.c_str());
outDebugValues(); outDebugValues();
// save state (after auras removing), if aura remove some flags then it must set it back by self)
uint32 tmp_bytes = GetUInt32Value(UNIT_FIELD_BYTES_1);
uint32 tmp_bytes2 = GetUInt32Value(UNIT_FIELD_BYTES_2);
uint32 tmp_flags = GetUInt32Value(UNIT_FIELD_FLAGS);
uint32 tmp_pflags = GetUInt32Value(PLAYER_FLAGS);
uint32 tmp_displayid = GetDisplayId();
// Set player sit state to standing on save, also stealth and shifted form
SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_STAND);
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
bool inworld = IsInWorld();
CharacterDatabase.BeginTransaction(); CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",GetGUIDLow()); CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",GetGUIDLow());
@ -15638,66 +15566,47 @@ void Player::SaveToDB()
ss << "', "; ss << "', ";
ss << m_taxi; // string with TaxiMaskSize numbers ss << m_taxi << ", "; // string with TaxiMaskSize numbers
ss << ", "; ss << (IsInWorld() ? 1 : 0) << ", ";
ss << (inworld ? 1 : 0);
ss << ", "; ss << m_cinematic << ", ";
ss << m_cinematic;
ss << ", "; ss << m_Played_time[PLAYED_TIME_TOTAL] << ", ";
ss << m_Played_time[PLAYED_TIME_TOTAL]; ss << m_Played_time[PLAYED_TIME_LEVEL] << ", ";
ss << ", ";
ss << m_Played_time[PLAYED_TIME_LEVEL];
ss << ", "; ss << finiteAlways(m_rest_bonus) << ", ";
ss << finiteAlways(m_rest_bonus); ss << (uint64)time(NULL) << ", ";
ss << ", "; ss << (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0) << ", ";
ss << (uint64)time(NULL); //save, far from tavern/city
ss << ", "; //save, but in tavern/city
ss << is_save_resting; ss << m_resetTalentsCost << ", ";
ss << ", "; ss << (uint64)m_resetTalentsTime << ", ";
ss << m_resetTalentsCost;
ss << ", ";
ss << (uint64)m_resetTalentsTime;
ss << ", "; ss << finiteAlways(m_movementInfo.t_x) << ", ";
ss << finiteAlways(m_movementInfo.t_x); ss << finiteAlways(m_movementInfo.t_y) << ", ";
ss << ", "; ss << finiteAlways(m_movementInfo.t_z) << ", ";
ss << finiteAlways(m_movementInfo.t_y); ss << finiteAlways(m_movementInfo.t_o) << ", ";
ss << ", ";
ss << finiteAlways(m_movementInfo.t_z);
ss << ", ";
ss << finiteAlways(m_movementInfo.t_o);
ss << ", ";
if (m_transport) if (m_transport)
ss << m_transport->GetGUIDLow(); ss << m_transport->GetGUIDLow();
else else
ss << "0"; ss << "0";
ss << ", ";
ss << ", "; ss << m_ExtraFlags << ", ";
ss << m_ExtraFlags;
ss << ", "; ss << uint32(m_stableSlots) << ", "; // to prevent save uint8 as char
ss << uint32(m_stableSlots); // to prevent save uint8 as char
ss << ", "; ss << uint32(m_atLoginFlags) << ", ";
ss << uint32(m_atLoginFlags);
ss << ", "; ss << GetZoneId() << ", ";
ss << GetZoneId();
ss << ", "; ss << (uint64)m_deathExpireTime << ", '";
ss << (uint64)m_deathExpireTime;
ss << ", '"; ss << m_taxi.SaveTaxiDestinationsToString() << "', ";
ss << m_taxi.SaveTaxiDestinationsToString(); ss << "'0', "; // arena_pending_points
ss << "', '0', "; ss << GetBattleGroundId() << ", ";
ss << GetBattleGroundId(); ss << GetBGTeam() << ", ";
ss << ", ";
ss << GetBGTeam();
ss << ", ";
ss << m_bgEntryPoint.mapid << ", " ss << m_bgEntryPoint.mapid << ", "
<< finiteAlways(m_bgEntryPoint.coord_x) << ", " << finiteAlways(m_bgEntryPoint.coord_x) << ", "
<< finiteAlways(m_bgEntryPoint.coord_y) << ", " << finiteAlways(m_bgEntryPoint.coord_y) << ", "
@ -15724,12 +15633,6 @@ void Player::SaveToDB()
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
// restore state (before aura apply, if aura remove flag then aura must set it ack by self)
SetUInt32Value(UNIT_FIELD_BYTES_1, tmp_bytes);
SetUInt32Value(UNIT_FIELD_BYTES_2, tmp_bytes2);
SetUInt32Value(UNIT_FIELD_FLAGS, tmp_flags);
SetUInt32Value(PLAYER_FLAGS, tmp_pflags);
// save pet (hunter pet level and experience and all type pets health/mana). // save pet (hunter pet level and experience and all type pets health/mana).
if(Pet* pet = GetPet()) if(Pet* pet = GetPet())
pet->SavePetToDB(PET_SAVE_AS_CURRENT); pet->SavePetToDB(PET_SAVE_AS_CURRENT);
@ -15798,27 +15701,14 @@ void Player::_SaveAuras()
SpellEntry const *spellInfo = itr2->second->GetSpellProto(); SpellEntry const *spellInfo = itr2->second->GetSpellProto();
//skip all auras from spells that are passive or need a shapeshift //skip all auras from spells that are passive
if (!(itr2->second->IsPassive() || itr2->second->IsRemovedOnShapeLost()))
{
//do not save single target auras (unless they were cast by the player) //do not save single target auras (unless they were cast by the player)
if (!(itr2->second->GetCasterGUID() != GetGUID() && itr2->second->IsSingleTarget())) if (!itr2->second->IsPassive() && (itr2->second->GetCasterGUID() == GetGUID() || !itr2->second->IsSingleTarget()))
{
uint8 i;
// or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
for (i = 0; i < 3; ++i)
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
break;
if (i == 3)
{ {
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" UI64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')", "VALUES ('%u', '" UI64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')",
GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges())); GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges()));
} }
}
}
if(itr == auras.end()) if(itr == auras.end())
break; break;
@ -18146,11 +18036,6 @@ void Player::SendInitialPacketsBeforeAddToMap()
m_reputationMgr.SendInitialReputations(); m_reputationMgr.SendInitialReputations();
m_achievementMgr.SendAllAchievementData(); m_achievementMgr.SendAllAchievementData();
// update zone
uint32 newzone, newarea;
GetZoneAndAreaId(newzone,newarea);
UpdateZone(newzone,newarea); // also call SendInitWorldStates();
SendEquipmentSetList(); SendEquipmentSetList();
data.Initialize(SMSG_LOGIN_SETTIMESPEED, 4 + 4 + 4); data.Initialize(SMSG_LOGIN_SETTIMESPEED, 4 + 4 + 4);
@ -18160,7 +18045,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
GetSession()->SendPacket( &data ); GetSession()->SendPacket( &data );
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight()) if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_FLY) || isInFlight())
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING2); m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING2);
m_mover = this; m_mover = this;
@ -18168,6 +18053,11 @@ void Player::SendInitialPacketsBeforeAddToMap()
void Player::SendInitialPacketsAfterAddToMap() void Player::SendInitialPacketsAfterAddToMap()
{ {
// update zone
uint32 newzone, newarea;
GetZoneAndAreaId(newzone,newarea);
UpdateZone(newzone,newarea); // also call SendInitWorldStates();
WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
data << uint32(0x00000000); // on blizz it increments periodically data << uint32(0x00000000); // on blizz it increments periodically
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
@ -19103,13 +18993,6 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)
void Player::UpdateZoneDependentAuras( uint32 newZone ) void Player::UpdateZoneDependentAuras( uint32 newZone )
{ {
// remove new continent flight forms
if( !IsAllowUseFlyMountsHere() )
{
RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
RemoveSpellsCausingAura(SPELL_AURA_FLY);
}
// Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update // Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newZone); SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newZone);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
@ -19682,13 +19565,11 @@ uint32 Player::CalculateTalentsPoints() const
return uint32(talentPointsForLevel * sWorld.getRate(RATE_TALENT)); return uint32(talentPointsForLevel * sWorld.getRate(RATE_TALENT));
} }
bool Player::IsAllowUseFlyMountsHere() const bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const
{ {
if (isGameMaster()) // continent checked in SpellMgr::GetSpellAllowedInLocationError at cast and area update
return true; uint32 v_map = GetVirtualMapForMapAndZone(mapid, zone);
return v_map != 571 || HasSpell(54197); // Cold Weather Flying
uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
return v_map == 530 || v_map == 571 && HasSpell(54197);
} }
struct DoPlayerLearnSpell struct DoPlayerLearnSpell

View file

@ -1351,7 +1351,6 @@ class MANGOS_DLL_SPEC Player : public Unit
bool LoadFromDB(uint32 guid, SqlQueryHolder *holder); bool LoadFromDB(uint32 guid, SqlQueryHolder *holder);
bool MinimalLoadFromDB(QueryResult *result, uint32 guid);
static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid); static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid);
static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index); static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index);
static float GetFloatValueFromArray(Tokens const& data, uint16 index); static float GetFloatValueFromArray(Tokens const& data, uint16 index);
@ -2065,7 +2064,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); } bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); }
bool IsAllowUseFlyMountsHere() const; bool IsKnowHowFlyIn(uint32 mapid, uint32 zone) const;
void SetClientControl(Unit* target, uint8 allowMove); void SetClientControl(Unit* target, uint8 allowMove);
void SetMover(Unit* target) { m_mover = target ? target : this; } void SetMover(Unit* target) { m_mover = target ? target : this; }

View file

@ -581,7 +581,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, objmgr.m_ItemTextId)) if(!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, objmgr.m_ItemTextId,true))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 3, vals.c_str())) if(!changenth(line, 3, vals.c_str()))
ROLLBACK(DUMP_FILE_BROKEN); ROLLBACK(DUMP_FILE_BROKEN);

View file

@ -2389,6 +2389,7 @@ enum SummonType
SUMMON_TYPE_UNKNOWN5 = 409, SUMMON_TYPE_UNKNOWN5 = 409,
SUMMON_TYPE_UNKNOWN2 = 427, SUMMON_TYPE_UNKNOWN2 = 427,
SUMMON_TYPE_POSESSED2 = 428, SUMMON_TYPE_POSESSED2 = 428,
SUMMON_TYPE_INFERNO = 711,
SUMMON_TYPE_GUARDIAN2 = 1161, SUMMON_TYPE_GUARDIAN2 = 1161,
SUMMON_TYPE_ELEMENTAL = 1561, SUMMON_TYPE_ELEMENTAL = 1561,
SUMMON_TYPE_FORCE_OF_NATURE = 1562 SUMMON_TYPE_FORCE_OF_NATURE = 1562

View file

@ -1679,12 +1679,19 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
case TARGET_ALL_ENEMY_IN_AREA_INSTANT: case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
{ {
// targets the ground, not the units in the area // targets the ground, not the units in the area
if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) switch(m_spellInfo->Effect[i])
{ {
case SPELL_EFFECT_PERSISTENT_AREA_AURA:
break;
case SPELL_EFFECT_SUMMON:
TagUnitMap.push_back(m_caster);
break;
default:
FillAreaTargets(TagUnitMap,m_targets.m_destX, m_targets.m_destY,radius,PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE); FillAreaTargets(TagUnitMap,m_targets.m_destX, m_targets.m_destY,radius,PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE);
// exclude caster (this can be important if this not original caster) // exclude caster (this can be important if this not original caster)
TagUnitMap.remove(m_caster); TagUnitMap.remove(m_caster);
break;
} }
break; break;
} }
@ -1705,9 +1712,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
case TARGET_ALL_RAID_AROUND_CASTER: case TARGET_ALL_RAID_AROUND_CASTER:
{ {
if(m_spellInfo->Id == 57669) // Replenishment (special target selection) if(m_spellInfo->Id == 57669) // Replenishment (special target selection)
FillRaidOrPartyManaPriorityTargets(TagUnitMap, m_caster, m_caster, radius, 10, true, false, false); FillRaidOrPartyManaPriorityTargets(TagUnitMap, m_caster, m_caster, radius, 10, true, false, true);
else if (m_spellInfo->Id==52759) // Ancestral Awakening (special target selection) else if (m_spellInfo->Id==52759) // Ancestral Awakening (special target selection)
FillRaidOrPartyHealthPriorityTargets(TagUnitMap, m_caster, m_caster, radius, 1, true, false, false); FillRaidOrPartyHealthPriorityTargets(TagUnitMap, m_caster, m_caster, radius, 1, true, false, true);
else else
FillRaidOrPartyTargets(TagUnitMap, m_caster, m_caster, radius, true, true, true); FillRaidOrPartyTargets(TagUnitMap, m_caster, m_caster, radius, true, true, true);
break; break;
@ -4324,6 +4331,7 @@ SpellCastResult Spell::CheckCast(bool strict)
case SUMMON_TYPE_DEMON: case SUMMON_TYPE_DEMON:
case SUMMON_TYPE_SUMMON: case SUMMON_TYPE_SUMMON:
case SUMMON_TYPE_ELEMENTAL: case SUMMON_TYPE_ELEMENTAL:
case SUMMON_TYPE_INFERNO:
{ {
if(m_caster->GetPetGUID()) if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON; return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@ -4547,16 +4555,16 @@ SpellCastResult Spell::CheckCast(bool strict)
break; break;
} }
case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED:
case SPELL_AURA_FLY: case SPELL_AURA_FLY:
case SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED:
{ {
// not allow cast fly spells at old maps by players (all spells is self target) // not allow cast fly spells if not have req. skills (all spells is self target)
if(m_caster->GetTypeId() == TYPEID_PLAYER) // allow always ghost flight spells
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isAlive())
{ {
if( !((Player*)m_caster)->IsAllowUseFlyMountsHere() ) if (!((Player*)m_caster)->IsKnowHowFlyIn(m_caster->GetMapId(),zone))
return SPELL_FAILED_NOT_HERE; return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE;
} }
break; break;
} }
case SPELL_AURA_PERIODIC_MANA_LEECH: case SPELL_AURA_PERIODIC_MANA_LEECH:

View file

@ -1027,7 +1027,7 @@ void Aura::_AddAura()
} }
} }
void Aura::_RemoveAura() bool Aura::_RemoveAura()
{ {
// Remove all triggered by aura spells vs unlimited duration // Remove all triggered by aura spells vs unlimited duration
// except same aura replace case // except same aura replace case
@ -1051,10 +1051,10 @@ void Aura::_RemoveAura()
uint8 slot = GetAuraSlot(); uint8 slot = GetAuraSlot();
if(slot >= MAX_AURAS) // slot not set if(slot >= MAX_AURAS) // slot not set
return; return false;
if(m_target->GetVisibleAura(slot) == 0) if(m_target->GetVisibleAura(slot) == 0)
return; return false;
bool lastaura = true; bool lastaura = true;
@ -1075,8 +1075,9 @@ void Aura::_RemoveAura()
} }
// only remove icon when the last aura of the spell is removed (current aura already removed from list) // only remove icon when the last aura of the spell is removed (current aura already removed from list)
if (lastaura) if (!lastaura)
{ return false;
// unregister aura diminishing (and store last time) // unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE ) if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(), false); m_target->ApplyDiminishingAura(getDiminishGroup(), false);
@ -1164,7 +1165,8 @@ void Aura::_RemoveAura()
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto()); ((Player*)caster)->SendCooldownEvent(GetSpellProto());
} }
}
return true;
} }
void Aura::SendAuraUpdate(bool remove) void Aura::SendAuraUpdate(bool remove)
@ -3314,9 +3316,17 @@ void Aura::HandleModCharm(bool apply, bool Real)
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON) if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{ {
//does not appear to have relevance. Why code added initially? See note below at !apply // creature with pet number expected have class set
//to prevent client crash if(m_target->GetByteValue(UNIT_FIELD_BYTES_0, 1)==0)
//m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048); {
if(cinfo->unit_class==0)
sLog.outErrorDb("Creature (Entry: %u) have unit_class = 0 but used in charmed spell, that will be result client crash.",cinfo->Entry);
else
sLog.outError("Creature (Entry: %u) have unit_class = %u but at charming have class 0!!! that will be result client crash.",cinfo->Entry,cinfo->unit_class);
m_target->SetByteValue(UNIT_FIELD_BYTES_0, 1, CLASS_MAGE);
}
//just to enable stat window //just to enable stat window
charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true); charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
//if charmed two demons the same session, the 2nd gets the 1st one's name //if charmed two demons the same session, the 2nd gets the 1st one's name
@ -3352,13 +3362,8 @@ void Aura::HandleModCharm(bool apply, bool Real)
// restore UNIT_FIELD_BYTES_0 // restore UNIT_FIELD_BYTES_0
if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON) if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
{ {
//does not appear to have relevance. Why code added initially? Class, gender, powertype should be same. // DB must have proper class set in field at loading, not req. restore, including workaround case at apply
//db field removed and replaced with better way to set class, restore using this if problems // m_target->SetByteValue(UNIT_FIELD_BYTES_0, 1, cinfo->unit_class);
/*CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
if(cainfo && cainfo->bytes0 != 0)
m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
else
m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);*/
if(m_target->GetCharmInfo()) if(m_target->GetCharmInfo())
m_target->GetCharmInfo()->SetPetNumber(0, true); m_target->GetCharmInfo()->SetPetNumber(0, true);
@ -5555,6 +5560,107 @@ void Aura::HandleShapeshiftBoosts(bool apply)
m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/ m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
} }
void Aura::HandleSpellSpecificBoosts(bool apply)
{
uint32 spellId1 = 0;
uint32 spellId2 = 0;
uint32 spellId3 = 0;
switch(GetSpellProto()->SpellFamilyName)
{
case SPELLFAMILY_WARRIOR:
{
if(!apply)
{
// Remove Blood Frenzy only if target no longer has any Deep Wound or Rend (applying is handled by procs)
if (GetSpellProto()->Mechanic != MECHANIC_BLEED)
return;
// If target still has one of Warrior's bleeds, do nothing
Unit::AuraList const& PeriodicDamage = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator i = PeriodicDamage.begin(); i != PeriodicDamage.end(); ++i)
if( (*i)->GetCasterGUID() == GetCasterGUID() &&
(*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR &&
(*i)->GetSpellProto()->Mechanic == MECHANIC_BLEED)
return;
spellId1 = 30069;
spellId2 = 30070;
}
break;
}
case SPELLFAMILY_HUNTER:
{
if(GetSpellSpecific(m_spellProto->Id) != SPELL_ASPECT)
return;
// Aspect of the Dragonhawk dodge
if (GetSpellProto()->SpellFamilyFlags2 & 0x00001000)
spellId1 = 61848;
else
return;
break;
}
case SPELLFAMILY_PALADIN:
{
// Only process on player casting paladin aura
// all aura bonuses applied also in aura area effect way to caster
if (GetCasterGUID() != m_target->GetGUID() || !IS_PLAYER_GUID(GetCasterGUID()))
return;
if (GetSpellSpecific(m_spellProto->Id) != SPELL_AURA)
return;
// Sanctified Retribution and Swift Retribution (they share one aura), but not Retribution Aura (already gets modded)
if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000008))==0)
spellId1 = 63531; // placeholder for talent spell mods
// Improved Concentration Aura (auras bonus)
spellId2 = 63510; // placeholder for talent spell mods
// Improved Devotion Aura (auras bonus)
spellId3 = 63514; // placeholder for talent spell mods
break;
}
case SPELLFAMILY_DEATHKNIGHT:
{
if (GetSpellSpecific(m_spellProto->Id) != SPELL_PRESENCE)
return;
// Frost Presence health
if (GetId() == 48263)
spellId1 = 61261;
// Unholy Presence move speed
else if (GetId() == 48265)
spellId1 = 49772;
else
return;
break;
}
default:
return;
}
if (apply)
{
if (spellId1)
m_target->CastSpell(m_target, spellId1, true, NULL, this);
if (spellId2)
m_target->CastSpell(m_target, spellId2, true, NULL, this);
if (spellId3)
m_target->CastSpell(m_target, spellId3, true, NULL, this);
}
else
{
if (spellId1)
m_target->RemoveAurasByCasterSpell(spellId1, GetCasterGUID());
if (spellId2)
m_target->RemoveAurasByCasterSpell(spellId2, GetCasterGUID());
if (spellId3)
m_target->RemoveAurasByCasterSpell(spellId3, GetCasterGUID());
}
}
void Aura::HandleAuraEmpathy(bool apply, bool /*Real*/) void Aura::HandleAuraEmpathy(bool apply, bool /*Real*/)
{ {
if(m_target->GetTypeId() != TYPEID_UNIT) if(m_target->GetTypeId() != TYPEID_UNIT)
@ -5751,14 +5857,6 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
void Aura::CleanupTriggeredSpells() void Aura::CleanupTriggeredSpells()
{ {
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000001000000020)))
{
// Blood Frenzy remove
m_target->RemoveAurasDueToSpell(30069);
m_target->RemoveAurasDueToSpell(30070);
return;
}
uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()]; uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
if(!tSpellId) if(!tSpellId)
return; return;

View file

@ -297,7 +297,7 @@ class MANGOS_DLL_SPEC Aura
void ApplyModifier(bool apply, bool Real = false); void ApplyModifier(bool apply, bool Real = false);
void _AddAura(); void _AddAura();
void _RemoveAura(); bool _RemoveAura();
bool IsUpdated() { return m_updated; } bool IsUpdated() { return m_updated; }
void SetUpdated(bool val) { m_updated = val; } void SetUpdated(bool val) { m_updated = val; }
@ -311,6 +311,7 @@ class MANGOS_DLL_SPEC Aura
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
void HandleShapeshiftBoosts(bool apply); void HandleShapeshiftBoosts(bool apply);
void HandleSpellSpecificBoosts(bool apply);
// Allow Apply Aura Handler to modify and access m_AuraDRGroup // Allow Apply Aura Handler to modify and access m_AuraDRGroup
void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }

View file

@ -1856,6 +1856,28 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 51209, true); m_caster->CastSpell(m_caster, 51209, true);
return; return;
} }
// Death Strike
else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010))
{
uint32 count = 0;
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE &&
itr->second->GetCasterGUID() == m_caster->GetGUID() &&
IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex()))
{
++count;
// max. 15%
if(count == 3)
break;
}
}
int32 bp = count * m_caster->GetMaxHealth() * m_spellInfo->DmgMultiplier[0] / 100;
m_caster->CastCustomSpell(m_caster, 45470, &bp, NULL, NULL, true);
return;
}
break; break;
} }
@ -1942,7 +1964,7 @@ void Spell::EffectTriggerSpell(uint32 i)
// special cases // special cases
switch(triggered_spell_id) switch(triggered_spell_id)
{ {
// Vanish // Vanish (not exist)
case 18461: case 18461:
{ {
m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
@ -1991,7 +2013,8 @@ void Spell::EffectTriggerSpell(uint32 i)
// Brittle Armor - (need add max stack of 24575 Brittle Armor) // Brittle Armor - (need add max stack of 24575 Brittle Armor)
case 29284: case 29284:
{ {
const SpellEntry *spell = sSpellStore.LookupEntry(24575); // Brittle Armor
SpellEntry const* spell = sSpellStore.LookupEntry(24575);
if (!spell) if (!spell)
return; return;
@ -2002,7 +2025,8 @@ void Spell::EffectTriggerSpell(uint32 i)
// Mercurial Shield - (need add max stack of 26464 Mercurial Shield) // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
case 29286: case 29286:
{ {
const SpellEntry *spell = sSpellStore.LookupEntry(26464); // Mercurial Shield
SpellEntry const* spell = sSpellStore.LookupEntry(26464);
if (!spell) if (!spell)
return; return;
@ -2348,7 +2372,7 @@ void Spell::EffectApplyAura(uint32 i)
return; return;
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 && if( !unitTarget->isAlive() && !IsDeathPersistentSpell(m_spellInfo) &&
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
return; return;
@ -2391,7 +2415,7 @@ void Spell::EffectApplyAura(uint32 i)
return; return;
// Prayer of Mending (jump animation), we need formal caster instead original for correct animation // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00002000000000))) if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000002000000000)))
m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID); m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID);
} }
@ -3260,12 +3284,17 @@ void Spell::EffectSummonType(uint32 i)
case SUMMON_TYPE_POSESSED2: case SUMMON_TYPE_POSESSED2:
case SUMMON_TYPE_FORCE_OF_NATURE: case SUMMON_TYPE_FORCE_OF_NATURE:
case SUMMON_TYPE_GUARDIAN2: case SUMMON_TYPE_GUARDIAN2:
// Jewelery statue case (totem like)
if(m_spellInfo->SpellIconID == 2056)
EffectSummonTotem(i);
else
EffectSummonGuardian(i); EffectSummonGuardian(i);
break; break;
case SUMMON_TYPE_WILD: case SUMMON_TYPE_WILD:
EffectSummonWild(i); EffectSummonWild(i);
break; break;
case SUMMON_TYPE_DEMON: case SUMMON_TYPE_DEMON:
case SUMMON_TYPE_INFERNO:
EffectSummonDemon(i); EffectSummonDemon(i);
break; break;
case SUMMON_TYPE_SUMMON: case SUMMON_TYPE_SUMMON:
@ -3311,6 +3340,16 @@ void Spell::EffectSummon(uint32 i)
if(m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry)) if(m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry))
{ {
// Summon in dest location
float x, y, z;
if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
x = m_targets.m_destX;
y = m_targets.m_destY;
z = m_targets.m_destZ;
spawnCreature->Relocate(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, -m_caster->GetOrientation());
}
// set timer for unsummon // set timer for unsummon
int32 duration = GetSpellDuration(m_spellInfo); int32 duration = GetSpellDuration(m_spellInfo);
if(duration > 0) if(duration > 0)
@ -3508,25 +3547,12 @@ void Spell::EffectDispel(uint32 i)
} }
m_caster->SendMessageToSet(&data, true); m_caster->SendMessageToSet(&data, true);
// On succes dispel // On success dispel
// Devour Magic // Devour Magic
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC) if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC)
{ {
uint32 heal_spell = 0; int32 heal_amount = m_spellInfo->CalculateSimpleValue(1);
switch (m_spellInfo->Id) m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
{
case 19505: heal_spell = 19658; break;
case 19731: heal_spell = 19732; break;
case 19734: heal_spell = 19733; break;
case 19736: heal_spell = 19735; break;
case 27276: heal_spell = 27278; break;
case 27277: heal_spell = 27279; break;
default:
sLog.outDebug("Spell for Devour Magic %d not handled in Spell::EffectDispel", m_spellInfo->Id);
break;
}
if (heal_spell)
m_caster->CastSpell(m_caster, heal_spell, true);
} }
} }
// Send fail log to client // Send fail log to client
@ -3699,13 +3725,6 @@ void Spell::EffectSummonGuardian(uint32 i)
if(!pet_entry) if(!pet_entry)
return; return;
// Jewelery statue case (totem like)
if(m_spellInfo->SpellIconID == 2056)
{
EffectSummonTotem(i);
return;
}
// set timer for unsummon // set timer for unsummon
int32 duration = GetSpellDuration(m_spellInfo); int32 duration = GetSpellDuration(m_spellInfo);
@ -4501,6 +4520,38 @@ void Spell::EffectWeaponDmg(uint32 i)
} }
} }
} }
break;
}
case SPELLFAMILY_DEATHKNIGHT:
{
// Blood Strike, Heart Strike, Obliterate
// Blood-Caked Strike, Scourge Strike
if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000001400000) ||
m_spellInfo->SpellIconID == 1736 || m_spellInfo->SpellIconID == 3143)
{
uint32 count = 0;
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE &&
itr->second->GetCasterGUID() == m_caster->GetGUID() &&
IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex()))
++count;
}
if (count)
{
// Effect 1(for Blood-Caked Strike)/3(other) damage is bonus
double bonus = count * CalculateDamage(m_spellInfo->SpellIconID == 1736 ? 0 : 2, unitTarget) / 100.0f;
// Blood Strike, Blood-Caked Strike and Obliterate store bonus*2
if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000000400000) ||
m_spellInfo->SpellIconID == 1736)
bonus /= 2.0f;
totalDamagePercentMod += bonus;
}
}
break;
} }
} }
@ -5173,6 +5224,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
{ {
uint32 spellId = 0; uint32 spellId = 0;
int32 basePoint = 0; int32 basePoint = 0;
Unit* target = unitTarget;
Unit::AuraMap& Auras = unitTarget->GetAuras(); Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{ {
@ -5197,6 +5249,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
{ {
spellId = 53358; // 53358 Chimera Shot - Viper spellId = 53358; // 53358 Chimera Shot - Viper
basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100;
target = m_caster;
} }
// Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
if (familyFlag & UI64LIT(0x0000000000008000)) if (familyFlag & UI64LIT(0x0000000000008000))
@ -5209,7 +5262,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
//} //}
} }
if (spellId) if (spellId)
m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); m_caster->CastCustomSpell(target, spellId, &basePoint, 0, 0, false);
return; return;
} }
default: default:
@ -5219,8 +5272,8 @@ void Spell::EffectScriptEffect(uint32 effIndex)
} }
case SPELLFAMILY_PALADIN: case SPELLFAMILY_PALADIN:
{ {
// Judgement // Judgement (seal trigger)
if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000800000)) if (m_spellInfo->Category == SPELLCATEGORY_JUDGEMENT)
{ {
if(!unitTarget || !unitTarget->isAlive()) if(!unitTarget || !unitTarget->isAlive())
return; return;
@ -5230,12 +5283,12 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Judgement self add switch // Judgement self add switch
switch (m_spellInfo->Id) switch (m_spellInfo->Id)
{ {
case 41467: break; // Judgement
case 53407: spellId1 = 20184; break; // Judgement of Justice case 53407: spellId1 = 20184; break; // Judgement of Justice
case 20271: // Judgement of Light case 20271: // Judgement of Light
case 57774: spellId1 = 20185; break; // Judgement of Light case 57774: spellId1 = 20185; break; // Judgement of Light
case 53408: spellId1 = 20186; break; // Judgement of Wisdom case 53408: spellId1 = 20186; break; // Judgement of Wisdom
default: default:
sLog.outError("Unsupported Judgement (seal trigger) spell (Id: %u) in Spell::EffectScriptEffect",m_spellInfo->Id);
return; return;
} }
// all seals have aura dummy in 2 effect // all seals have aura dummy in 2 effect
@ -6219,7 +6272,7 @@ void Spell::EffectSummonDeadPet(uint32 /*i*/)
pet->AIM_Initialize(); pet->AIM_Initialize();
_player->PetSpellInitialize(); // _player->PetSpellInitialize(); -- action bar not removed at death and not required send at revive
pet->SavePetToDB(PET_SAVE_AS_CURRENT); pet->SavePetToDB(PET_SAVE_AS_CURRENT);
} }
@ -6503,6 +6556,9 @@ void Spell::EffectSummonDemon(uint32 i)
int32 amount = damage > 0 ? damage : 1; int32 amount = damage > 0 ? damage : 1;
if (m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_INFERNO)
amount = 1;
for(int32 count = 0; count < amount; ++count) for(int32 count = 0; count < amount; ++count)
{ {
float px, py, pz; float px, py, pz;
@ -6535,12 +6591,14 @@ void Spell::EffectSummonDemon(uint32 i)
// TODO: Add damage/mana/hp according to level // TODO: Add damage/mana/hp according to level
// Enslave demon effect, without mana cost and cooldown
if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon
{ {
// Enslave demon effect, without mana cost and cooldown // Enslave demon effect, without mana cost and cooldown
m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved
// Inferno effect // Inferno effect for non player calls
if (m_spellInfo->EffectMiscValueB[i]!=SUMMON_TYPE_INFERNO)
Charmed->CastSpell(Charmed, 22703, true, 0); Charmed->CastSpell(Charmed, 22703, true, 0);
} }
} }

View file

@ -188,6 +188,9 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000011010002)) if (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000011010002))
return SPELL_BLESSING; return SPELL_BLESSING;
if (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000002190))
return SPELL_HAND;
if ((spellInfo->SpellFamilyFlags & UI64LIT(0x00000820180400)) && (spellInfo->AttributesEx3 & 0x200)) if ((spellInfo->SpellFamilyFlags & UI64LIT(0x00000820180400)) && (spellInfo->AttributesEx3 & 0x200))
return SPELL_JUDGEMENT; return SPELL_JUDGEMENT;
@ -238,6 +241,7 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
case SPELL_POSITIVE_SHOUT: case SPELL_POSITIVE_SHOUT:
case SPELL_JUDGEMENT: case SPELL_JUDGEMENT:
case SPELL_PRESENCE: case SPELL_PRESENCE:
case SPELL_HAND:
return spellSpec1==spellSpec2; return spellSpec1==spellSpec2;
case SPELL_BATTLE_ELIXIR: case SPELL_BATTLE_ELIXIR:
return spellSpec2==SPELL_BATTLE_ELIXIR return spellSpec2==SPELL_BATTLE_ELIXIR
@ -261,6 +265,7 @@ bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSp
case SPELL_BLESSING: case SPELL_BLESSING:
case SPELL_AURA: case SPELL_AURA:
case SPELL_CURSE: case SPELL_CURSE:
case SPELL_HAND:
return spellId_spec==i_spellId_spec; return spellId_spec==i_spellId_spec;
default: default:
return false; return false;
@ -1465,7 +1470,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
// Paladin Seals // Paladin Seals
if (IsSealSpell(spellInfo_1) && IsSealSpell(spellInfo_2)) if (IsSealSpell(spellInfo_1) && IsSealSpell(spellInfo_2))
return true; return true;
// Swift Retribution / Improved Devotion Aura (talents) and Paladin Auras
if ((spellInfo_1->SpellFamilyFlags2 & 0x00000020) && (spellInfo_2->SpellIconID == 291 || spellInfo_2->SpellIconID == 3028) ||
(spellInfo_2->SpellFamilyFlags2 & 0x00000020) && (spellInfo_1->SpellIconID == 291 || spellInfo_1->SpellIconID == 3028))
return false;
} }
// Combustion and Fire Protection Aura (multi-family check) // Combustion and Fire Protection Aura (multi-family check)
if( spellInfo_2->Id == 11129 && spellInfo_1->SpellIconID == 33 && spellInfo_1->SpellVisual[0] == 321 ) if( spellInfo_2->Id == 11129 && spellInfo_1->SpellIconID == 33 && spellInfo_1->SpellVisual[0] == 321 )
return false; return false;
@ -1494,6 +1505,18 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
if( spellInfo_1->Id == 2825 && spellInfo_2->SpellIconID == 38 && spellInfo_2->SpellVisual[0] == 0 ) if( spellInfo_1->Id == 2825 && spellInfo_2->SpellIconID == 38 && spellInfo_2->SpellVisual[0] == 0 )
return false; return false;
break; break;
case SPELLFAMILY_DEATHKNIGHT:
if (spellInfo_2->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
{
// Frost Presence and Frost Presence (triggered)
if( spellInfo_1->SpellIconID == 2632 && spellInfo_2->SpellIconID == 2632 )
return false;
// Unholy Presence and Unholy Presence (triggered)
if( spellInfo_1->SpellIconID == 2633 && spellInfo_2->SpellIconID == 2633 )
return false;
}
break;
default: default:
break; break;
} }
@ -2529,9 +2552,14 @@ void SpellMgr::LoadSpellAreas()
continue; continue;
} }
if(spellInfo->EffectApplyAuraName[0]!=SPELL_AURA_DUMMY && spellInfo->EffectApplyAuraName[0]!=SPELL_AURA_PHASE) switch(spellInfo->EffectApplyAuraName[0])
{ {
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell requirement (%u) without dummy/phase aura in effect 0", spell,abs(spellArea.auraSpell)); case SPELL_AURA_DUMMY:
case SPELL_AURA_PHASE:
case SPELL_AURA_GHOST:
break;
default:
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell requirement (%u) without dummy/phase/ghost aura in effect 0", spell,abs(spellArea.auraSpell));
continue; continue;
} }
@ -2625,6 +2653,10 @@ void SpellMgr::LoadSpellAreas()
SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player) SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player)
{ {
// allow in GM-mode
if (player && player->isGameMaster())
return SPELL_CAST_OK;
// normal case // normal case
if (spellInfo->AreaGroupId > 0) if (spellInfo->AreaGroupId > 0)
{ {
@ -2645,6 +2677,15 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
return SPELL_FAILED_INCORRECT_AREA; return SPELL_FAILED_INCORRECT_AREA;
} }
// continent limitation (virtual continent)
if (spellInfo->AttributesEx4 & SPELL_ATTR_EX4_CAST_ONLY_IN_OUTLAND)
{
uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
if(!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
return SPELL_FAILED_INCORRECT_AREA;
}
// DB base check (if non empty then must fit at least single for allow) // DB base check (if non empty then must fit at least single for allow)
SpellAreaMapBounds saBounds = spellmgr.GetSpellAreaMapBounds(spellInfo->Id); SpellAreaMapBounds saBounds = spellmgr.GetSpellAreaMapBounds(spellInfo->Id);
if (saBounds.first != saBounds.second) if (saBounds.first != saBounds.second)

View file

@ -40,7 +40,8 @@ struct SpellModifier;
enum SpellCategories enum SpellCategories
{ {
SPELLCATEGORY_HEALTH_MANA_POTIONS = 4, SPELLCATEGORY_HEALTH_MANA_POTIONS = 4,
SPELLCATEGORY_DEVOUR_MAGIC = 12 SPELLCATEGORY_DEVOUR_MAGIC = 12,
SPELLCATEGORY_JUDGEMENT = 1210, // Judgement (seal trigger)
}; };
enum SpellFamilyNames enum SpellFamilyNames
@ -96,7 +97,8 @@ enum SpellSpecific
SPELL_BATTLE_ELIXIR = 14, SPELL_BATTLE_ELIXIR = 14,
SPELL_GUARDIAN_ELIXIR = 15, SPELL_GUARDIAN_ELIXIR = 15,
SPELL_FLASK_ELIXIR = 16, SPELL_FLASK_ELIXIR = 16,
SPELL_PRESENCE = 17 SPELL_PRESENCE = 17,
SPELL_HAND = 18,
}; };
SpellSpecific GetSpellSpecific(uint32 spellId); SpellSpecific GetSpellSpecific(uint32 spellId);
@ -136,6 +138,14 @@ inline bool IsSpellHaveAura(SpellEntry const *spellInfo, AuraType aura)
return false; return false;
} }
inline bool IsSpellLastAuraEffect(SpellEntry const *spellInfo, int effecIdx)
{
for(int i = effecIdx+1; i < 3; ++i)
if(spellInfo->EffectApplyAuraName[i])
return false;
return true;
}
bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
inline bool IsSealSpell(SpellEntry const *spellInfo) inline bool IsSealSpell(SpellEntry const *spellInfo)

View file

@ -647,7 +647,11 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(!cVictim->isPet()) if(!cVictim->isPet())
{ {
cVictim->DeleteThreatList(); cVictim->DeleteThreatList();
// only lootable if it has loot or can drop gold
if(cVictim->GetCreatureInfo()->lootid || cVictim->GetCreatureInfo()->maxgold > 0)
cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
else
cVictim->lootForBody = true; // needed for skinning
} }
// Call creature just died function // Call creature just died function
if (cVictim->AI()) if (cVictim->AI())
@ -3402,8 +3406,10 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_
bool Unit::AddAura(Aura *Aur) bool Unit::AddAura(Aura *Aur)
{ {
SpellEntry const* aurSpellInfo = Aur->GetSpellProto();
// ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
if( !isAlive() && Aur->GetId() != 20584 && Aur->GetId() != 8326 && Aur->GetId() != 2584 && if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) &&
(GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) ) (GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
{ {
delete Aur; delete Aur;
@ -3419,7 +3425,6 @@ bool Unit::AddAura(Aura *Aur)
return false; return false;
} }
SpellEntry const* aurSpellInfo = Aur->GetSpellProto();
AuraType aurName = Aur->GetModifier()->m_auraname; AuraType aurName = Aur->GetModifier()->m_auraname;
spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex()); spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
@ -3531,6 +3536,10 @@ bool Unit::AddAura(Aura *Aur)
Aur->ApplyModifier(true,true); Aur->ApplyModifier(true,true);
sLog.outDebug("Aura %u now is in use", aurName); sLog.outDebug("Aura %u now is in use", aurName);
if(IsSpellLastAuraEffect(aurSpellInfo,Aur->GetEffIndex()))
Aur->HandleSpellSpecificBoosts(true);
return true; return true;
} }
@ -3876,13 +3885,24 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flags)
} }
} }
void Unit::RemoveNotOwnSingleTargetAuras() void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)
{ {
// single target auras from other casters // single target auras from other casters
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
{ {
if (iter->second->GetCasterGUID()!=GetGUID() && IsSingleTargetSpell(iter->second->GetSpellProto())) if (iter->second->GetCasterGUID()!=GetGUID() && IsSingleTargetSpell(iter->second->GetSpellProto()))
{
if(!newPhase)
RemoveAura(iter); RemoveAura(iter);
else
{
Unit* caster = iter->second->GetCaster();
if(!caster || !caster->InSamePhase(newPhase))
RemoveAura(iter);
else
++iter;
}
}
else else
++iter; ++iter;
} }
@ -3892,7 +3912,7 @@ void Unit::RemoveNotOwnSingleTargetAuras()
for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end(); ) for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end(); )
{ {
Aura* aura = *iter; Aura* aura = *iter;
if (aura->GetTarget() != this) if (aura->GetTarget() != this && !aura->GetTarget()->InSamePhase(newPhase))
{ {
scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveAura scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveAura
aura->GetTarget()->RemoveAura(aura); aura->GetTarget()->RemoveAura(aura);
@ -3957,7 +3977,14 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
Aur->ApplyModifier(false,true); Aur->ApplyModifier(false,true);
Aur->_RemoveAura();
if(Aur->_RemoveAura())
{
// last aura in stack removed
if(IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex()))
Aur->HandleSpellSpecificBoosts(false);
}
delete Aur; delete Aur;
if(caster_channeled) if(caster_channeled)
@ -5676,8 +5703,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 40471; triggered_spell_id = 40471;
chance = 15.0f; chance = 15.0f;
} }
// Judgement // Judgement (any)
else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000800000)) else if (GetSpellSpecific(procSpell->Id)==SPELL_JUDGEMENT)
{ {
triggered_spell_id = 40472; triggered_spell_id = 40472;
chance = 50.0f; chance = 50.0f;
@ -5883,6 +5910,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 58879; triggered_spell_id = 58879;
break; break;
} }
// Shaman T8 Elemental 4P Bonus
case 64928:
{
basepoints0 = int32( triggerAmount * damage / 100 );
triggered_spell_id = 64930; // Electrified
break;
}
} }
// Storm, Earth and Fire // Storm, Earth and Fire
if (dummySpell->SpellIconID == 3063) if (dummySpell->SpellIconID == 3063)
@ -6114,6 +6148,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 50526; triggered_spell_id = 50526;
break; break;
} }
// Blood-Caked Blade
if (dummySpell->SpellIconID == 138)
{
triggered_spell_id = dummySpell->EffectTriggerSpell[effIndex];
break;
}
break; break;
} }
default: default:
@ -11821,6 +11861,12 @@ void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
{ {
if(newPhaseMask==GetPhaseMask())
return;
if(IsInWorld())
RemoveNotOwnSingleTargetAuras(newPhaseMask); // we can lost access to caster or target
WorldObject::SetPhaseMask(newPhaseMask,update); WorldObject::SetPhaseMask(newPhaseMask,update);
if(IsInWorld()) if(IsInWorld())

View file

@ -1209,7 +1209,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
void RemoveAurasDueToSpellByCancel(uint32 spellId); void RemoveAurasDueToSpellByCancel(uint32 spellId);
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
void RemoveNotOwnSingleTargetAuras(); void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
void RemoveSpellsCausingAura(AuraType auraType); void RemoveSpellsCausingAura(AuraType auraType);
void RemoveRankAurasDueToSpell(uint32 spellId); void RemoveRankAurasDueToSpell(uint32 spellId);

View file

@ -73,7 +73,7 @@ Tokens StrSplit(const std::string &src, const std::string &sep)
void stripLineInvisibleChars(std::string &str) void stripLineInvisibleChars(std::string &str)
{ {
static std::string invChars = " \t\7"; static std::string invChars = " \t\7\n";
size_t wpos = 0; size_t wpos = 0;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8284" #define REVISION_NR "8315"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__